load runner correlation

46
Today, I will explain - what is LoadRunner correlation and how to perform it. In my humble opinion, correlation is the key concept of LoadRunner. So, strong understanding of correlation is mandatory requirement for any test engineer, if he plans to be LoadRunner professional or even guru :) Example from a real practice: I recorded LoadRunner script for a web server, which contained two special fields - timestamp and checksum: web_submit_data("rms.jsp", "Action=http://eprumossd0010:8400/RMS/jsp/rms.jsp", "Method=POST", "RecContentType=text/html", "Referer=http://eprumossd0010:8400/RMS/html/testFramewor k.html", "Snapshot=t4.inf", "Mode=HTML", ITEMDATA, "Name=TIMESTAMP", "Value=1192177661211", ENDITEM, "Name=CHECKSUM", "Value=715E19300D670ED77773BBF066DAAAE2866484B8", ENDITEM, // others parameters ... LAST); Every time a client web browser connects to web server, server gets current time stamp, calculates checksum and sends them to client. These two fields are used to identify a current session. In other words, the pair of timestamp+checksum is analog of session ID. The scheme of this interaction is the following:

Upload: graov

Post on 10-Apr-2015

1.568 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Load Runner Correlation

Today, I will explain - what is LoadRunner correlation and how to perform it.In my humble opinion, correlation is the key concept of LoadRunner. So, strong understanding of correlation is mandatory requirement for any test engineer, if he plans to be LoadRunner professional or even guru :)

Example from a real practice:

I recorded LoadRunner script for a web server, which contained two special fields - timestamp and checksum:

web_submit_data("rms.jsp",     "Action=http://eprumossd0010:8400/RMS/jsp/rms.jsp",     "Method=POST",     "RecContentType=text/html",     "Referer=http://eprumossd0010:8400/RMS/html/testFramework.html",     "Snapshot=t4.inf",     "Mode=HTML",     ITEMDATA,     "Name=TIMESTAMP", "Value=1192177661211", ENDITEM,     "Name=CHECKSUM", "Value=715E19300D670ED77773BBF066DAAAE2866484B8", ENDITEM,     // others parameters ...    LAST);

Every time a client web browser connects to web server, server gets current time stamp, calculates checksum and sends them to client. These two fields are used to identify a current session. In other words, the pair of timestamp+checksum is analog of session ID.

The scheme of this interaction is the following:

Page 2: Load Runner Correlation

Where is the problem? Let's replay the recorded LR script.

The problem occurs when I try to execute my recorded script.Web server checks its current time with a time stamp, sent by client. If client's data is out-of-date or incorrect, then server returns an error:

The parameter "CHECKSUM" is not found or has invalid value.

There is the scheme for this interaction:

Client cannot re-use old (i.e. hard-coded) values for times tamp and checksum. It must request new data.So, instead of hard-coded values, LR script should process dynamic data, returned from server. This can be done using a correlation:

The definition of correlation is:Correlation is the capturing of dynamic values passed from the server to the client.

Correlation can be done with 2 ways:1. Automatically2. Manually

Page 3: Load Runner Correlation

I will describe auto-correlation in the future posts. For now, I can say that this is not ideal solution. Sometimes, it does not work, or works incorrectly.

Manual correlation is a choice of real LoadRunner engineer. It's a kind of "must have" knowledge!Well, let's start investigating a manual correlation.

The algorithm of manual correlation is the following:1. Find a dynamic value to capture. 2. Find server's response, containing the dynamic value. 3. Capture the dynamic value.

Special parameter will be used instead of dynamic value. 4. Replace every occurrence of dynamic value in script with the

parameter. 5. Check changes.

Now, I will describe each step in details:

1. Find a dynamic value to captureI recommend to record and save two equal VuGen scripts. After that, open menu item "Tools / Compare with Scripts..." and you can compare both recorded scripts in WDiff:

The differences are highlighted by yellow. This highlighting means that lines (parameters values) change from run to run. So, most probably, these values should be correlated.

Tips: Sometimes, comparing of two scripts cannot detect dynamic values. Imagine, that you recorded this script:    "Name=SessionID", "Value=A38E9002A41", ENDITEM,     "Name=CurrentMonthID", "Value=4", ENDITEM,    ...It's obvious, that SessionID should be correlated. What about CurrentMonthID parameter? Second recorded script can contain "Value=4" too. And it's possible, that your script will work correctly during the April (4th month is April), and will not work from 1st May! So, be careful, my dear reader :)

Tips: Look through the source code of recorded script. Timestamp, CheckSum, SessionID, and different IDs - all of they

Page 4: Load Runner Correlation

are potential candidates to be correlated.

Tips: Check Replay (Execution) log carefully. Errors can be there. The widespread reason of script's errors is an absence of correlations.

Tips: Execute your script with enabled run-time viewer (menu "Tools / General Options.. / Display"). Any shown errors ("Page not found", "Session timeout", etc) indicate about potential correlations.

2. Find server's response, containing the dynamic valueBefore script executing, please enable extended logging from "Vuser / Run-Time Settings...":

Then execute script.Open Replay (Execution) log and find server's response, which contains dynamic values of TIMESTAMP and CHECKSUM:

Great! Now we know, where server sends both dynamic values.And we found the step, that returns these values. This is 13th line - Action.c (13). Double click the line, containing timstamp's and checksum's values, 13th line of script will be opened:web_submit_data("generateChecksum.jsp",

Page 5: Load Runner Correlation

"Action=http://eprumossd0010:8400/RMS/jsp/generateChecksum.jsp",     "Method=POST",    "RecContentType=text/html",    ...This means that server's response for generateChecksum.jsp page contains dynamic values which should be correlated.

3. Capture the dynamic valueI will show two ways how to capture a dynamic value:

o Automatic capturing from Tree-view o Manual from Script-view

These ways are similar enough. Also, they use the same function - web_reg_save_param.

I start from:

o Automatic capturing from Tree-view.Open Tree view (menu "View / Tree view"):

Then: click "View recording snapshot only" btn (2); select generateChecksum.jsp page from tree view

(3); select "Body" to view body of server's response (4).

As result, you will see recorded values of CHECKSUM and TIMESTAMP (5).

Now, select value of first dynamic value (checksum), right-click, and select "Create parameter":

After that you will see the message box:

Page 6: Load Runner Correlation

You can create parameter for dynamic value.If you want to replace all occurrences of dynamic value ("715E19...") in script, press "Yes" btn.To not replace all occurrences, press "No" btn.

Tips: I recommend to not replace all occurrences of dynamic value. It can lead to incorrect results. It's more preferable to replace occurrences one by one with "Search and Replace" dlg.

OK, I click "No" btn.

Return to Script-view ("View / Script View") and see changes. There are new lines, inserted before generateChecksum.jsp page:

// [WCSPARAM WCSParam_Text1 40 715E19300D670ED77773BBF066DAAAE2866484B8] Parameter {WCSParam_Text1} created by Correlation Studio web_reg_save_param("WCSParam_Text1",    "LB=window.parent.setChecksum(\"",    "RB=\"",     "Ord=1",     "RelFrameId=1",     "Search=Body",     "IgnoreRedirections=Yes",    LAST);

web_reg_save_param function finds and saves a text string from the next server's response. In other words, it captures a dynamic value.

In this example, web_reg_save_param function will save the captured value into WCSParam_Text1 parameter. The function finds the left boundary (window.parent.setChecksum(") and after that it finds the right boundary ("). The string, found between left and right boundaries, will be saved to WCSParam_Text1 parameter.Ord attribute indicates the ordinal position of captured

Page 7: Load Runner Correlation

value. In the example (Ord=1), we capture the value between first left boundary and left one.Easy to guess, that "Search=Body" means search in a body of server's response.I recommend to study Help on web_reg_save_param function. It's very interesting :)

Note: the capturing of TIMESTAMP parameter is similar. It generates the following code:

// [WCSPARAM WCSParam_Text2 13 1192177661211] Parameter {WCSParam_Text2} created by Correlation Studioweb_reg_save_param("WCSParam_Text2",    "LB=, ",     "RB=)",     "Ord=1",     "RelFrameId=1",     "Search=Body",     "IgnoreRedirections=Yes",    LAST);

o Manual capturing from Script-view.Actually, this method consists in a manual writing of web_reg_save_param function. It requires strong knowledge on this function and its parameters. There are many attributes of web_reg_save_param function, and I do not want to duplicate HP's Help :)

Tips: I recommend to rename default parameter (WCSParam_Text1, 2, 3, etc) to something sensible. For example, in my example - I would prefer prmCheckSum and prmTimeStamp to WCSParam_Text1 and WCSParam_Text2.

4. Replace every occurrence of dynamic value in script with the parameterThis is not difficult step.Open "Search and Replace" dlg ("Edit / Replace..."). And replace one-by-one hard-coded values with a parameter.

Why it is important?Imagine, that you have the following code:

web_submit_data("somepage",     ...

Page 8: Load Runner Correlation

    "Name=OrderNumber", "Value=125", ENDITEM,     "Name=UserID", "Value=125",

If you create parameter for UserID, and perform replacing of all occurrences of its value ("125"), then it will produce the code:

web_submit_data("somepage",     ...    "Name=OrderNumber", "Value={WCSParam_Text1}", ENDITEM,     "Name=UserID", "Value={WCSParam_Text1}",

It may be wrong! OrderNumber can be static value and be equal to 125, while UserID may change.

Now, I assume that you replace all needed occurrences of hard-coded values. We have to perform last step:

5. Check changesAfter above manipulations, our script will look like:

web_submit_data("rms.jsp",     "Action=http://eprumossd0010:8400/RMS/jsp/rms.jsp",     "Method=POST",     "RecContentType=text/html",     "Referer=http://eprumossd0010:8400/RMS/html/testFramework.html",     "Snapshot=t4.inf",     "Mode=HTML",     ITEMDATA,     "Name=TIMESTAMP", "Value={WCSParam_Text2}", ENDITEM,     "Name=CHECKSUM", "Value={WCSParam_Text1}", ENDITEM,     // others parameters ...    LAST);

The statement "{WCSParam_Text1}" means "get value of WCSParam_Text1 parameter".So, current algorithm is:

o when server returns different values of CheckSum and TimeStamp

o then web_submit_data captures and places them into WCSParam_Text1 and WCSParam_Text2 parameters

o after that we use {WCSParam_Text1} and {WCSParam_Text2} get current values of parameters and use them in scripts

Page 9: Load Runner Correlation

Let's run our modified script and see results of capturing from server's response:

These are values, which are sent to a server by a client:

You can see that dynamic values are saved to parameters and their values are substituted instead of parameters in scripts. Great! We have just correlated our script and it is working now!

Tips: To get/debug a captured value of parameter, use the following statements:lr_output_message("Value of WCSParam_Text1: %s", lr_eval_string("{WCSParam_Text1}"));lr_output_message("Value of WCSParam_Text2: %s", lr_eval_string("{WCSParam_Text2}"));

Execute script again, he result is:

Regular Expression in load RunnerI'm going to show and explain how to use Regular Expressions in LoadRunner.

Introduction:The present article is a summarizing of the LoadRunner Regular Expressions challenge and its results. Also, I added code for RegExp patterns/subpatterns matching.All LoadRunner Regular Expressions functions are shown with examples.

Page 10: Load Runner Correlation

Outline: 1. How to check - whether RegExp pattern matches against a

text or not2. How to get a matched strings (RegExp patterns and

subpatterns)

How to check - Whether RegExp pattern matches against a text or not

I thanks Charlie Weiblen and Tim Koopmans for the solution. I modified it slightly.So, here it is:

1. Download and unpack Binaries and Developer files for PCRE (Perl Compatible Regular Expressions).These and others files are available on Pcre for Windows page.

2. Unzip downloaded archives into c:\pcre

3. Сomment out the include for stdlib.h file in:o C:\pcre\include\pcre.h o C:\pcre\include\pcreposix.h

Page 11: Load Runner Correlation

4. In your LoadRunner script, add to globals.h:o #include "c:\\pcre\\include\\pcre.h" o #include "c:\\pcre\\include\\pcreposix.h"

5. Add the match() function to vuser_init section:

///////////////////////////////////////////////////////////////////////////// 'match' function matches a 'pattern' against a given 'subject'/// It returns 1 for a match, or 0 for a non-match / errorint match(const char *subject, const char *pattern){int rc; // Returned coderegex_t re; // Compiled regexp pattern

lr_load_dll("c:\\pcre\\bin\\pcre3.dll");

if (regcomp(&re, pattern, 0) != 0)return 0; // Report error

rc = regexec(&re, subject, 0, NULL, 0);regfree(&re);

if (rc != 0)return 0; // Report errorelsereturn 1;}

Page 12: Load Runner Correlation

6. Let's run sample LoadRunner script and check the result:

As you can see, match() function works correctly. Using match() function, you can check - whether RegExp pattern matches against a text or not.

It can be helpful, when you verify in LoadRunner that the text (RegExp pattern) matches the text on a downloaded page.

I tested the match() function with different patterns and subject strings:

# Subject string PatternsResult ofmatch()

Is correctresult?

1 abcdef b(c(.*))e 1 Yes

2 abcdef b(z(.*))e 0 Yes

3 2008 \\d{2,5} 1 Yes

4 2008 \\d{5} 0 Yes

5 abc 1st of May 2008xyz \\d.*\\d 1 Yes

7. Note: Since LoadRunner uses ANSI C language, please do not forget to double backslashes (\\). For example, to match any digit character (0-9), use pattern "\\d".

match() function is simple enough. But it searches only and it cannot extract matched subpatterns from the text. For example, we have to extract the name of month from these strings:

o "abc 1st of May 2008xyz"

Page 13: Load Runner Correlation

o "abc 25th of February 2031" o etc

We can use the following pattern:

o \d.+([A-Z]\w+)\s+\d{4}

The name of month will be matches by subpattern ([A-Z]\w+). How to extract the found text? You can use matchex() function for that. Let's discuss it in details...

How to get a matched strings (RegExp patterns and subpatterns)

To get a matched (found) strings, we have to update our match() function.That's why I created matchex() ('match' EXtended) function.

1. Add the matchex() function to vuser_init section

///////////////////////////////////////////////////////////////////////////// 'matchex' (EXtended) function matches a 'pattern' against a given 'subject'/// It returns number of matches:/// 0 - for a non-match or error/// 1 and more - for successful matchesint matchex(const char *subject, const char *pattern, int nmatch, regmatch_t *pmatch){int rc; // Returned coderegex_t re; // Compiled regexp pattern

lr_load_dll("c:\\pcre\\bin\\pcre3.dll");

if (regcomp(&re, pattern, 0) != 0)return 0; // Report error

rc = regexec(&re, subject, nmatch, pmatch, 0);pcre_free(&re); // Release memory used for the compiled pattern

if (rc < 0)return 0; // Report error

// Get total number of matched patterns and subpatternsfor (rc = 0; rc < nmatch; rc++)

Page 14: Load Runner Correlation

if (pmatch[rc].rm_so == -1)break;

return rc;}

2. Let's run sample LoadRunner script and check the result:

matchex() function returns a number of matched patterns/subpatterns and fill an array in with information about each matched substring.

What is an information about each matched substring?

This info contains the offset (rm_so) to the first character of each substring and the offset (rm_eo) to the first character after the end of each substring, respectively.

Note1: The 0th element of the array relates to the entire portion of string that was matched.Note2: Subsequent elements of the array relate to the capturing subpatterns of the regular expression.Note3: Unused entries in the array have both structure members set to -1.

Let's investigate it with the example. This is our subject string:

Page 15: Load Runner Correlation

The replay log shows offsets for matched substrings:

o Action.c(7): Matched 3 patterns o Action.c(10): Start offset: 1, End offset: 6 o Action.c(10): Start offset: 2, End offset: 5 o Action.c(10): Start offset: 3, End offset: 5

Start offset: 1 and End offset: 6 match substring "bcdef".Note4: End offset is the first character after the end the current substring. That's why character "g" (with index 6) is not a part of matched string.

As I've written in Note1, "bcdef" is the entire portion of string that was matched.Others items from an array relate to matched subpatterns.

What is a subpattern in Regular Expression?

It is a part of the RegExp pattern surrounded with parenthesis - "(" and ")".

It's easy to get out the order of subpatterns. Just look through your pattern from left to right. When you find an open parenthes, this is a start of the current subpattern.Subpattern can be embedded.

So, others captured subpatterns are:

o Start offset: 2, End offset: 5 matches substring "cde".Note: current subpattern is "([acqz](.*))".

o Start offset: 3, End offset: 5 match substring "de".Note: current subpattern is "(.*)".

As you can see - this is not so difficult. :)Regular Expressions can be very powerful and useful in LoadRunner.

Page 16: Load Runner Correlation

Another example:

Let's practise with an example I mentioned early:For example, we have to extract the name of month from these strings:

"abc 1st of May 2008xyz" "abc 25th of February 2031" etc

We can use the following pattern: \d.+([A-Z]\w+)\s+\d{4}

The name of month will be matches by subpattern ([A-Z]\w+).

Please, see LoadRunner script, which captures and prints name of months:

Note: Pay attention that I use arr[1] to get info about substring.As you remember, arr[0] contains info about the entire matched pattern, arr[1], arr[2], and so on contain info about matched subpattern.

Summary:I've explained, shown and demonstrated how to use Regular Expressions (RegExp) in LoadRunner.I hope, this knowledge will help you to create advanced LoadRunner scripts.

Related articles:

Page 17: Load Runner Correlation

How to perform basic operations on LoadRunner parameters? Using Correlation in LoadRunner scripts - visual tutorial Boundaries for web_reg_save_param LoadRunner function LoadRunner Correlation - How to capture an array of dynamic

data with web_reg_save_param function All LoadRunner visual tutorials

3……Memory Leaks

Today, I plan to share my experience on the memory leaks detecting. This article is a step-by-step instruction on how to use HP/Mercury LoadRunner to perform load testing for the purpose of memory leaks discovering.

The task:It needs perform testing of Web server to discover memory leaks.

The solution:1. Create LoadRunner VuGen script for your application (Web

server in my script)Let's suppose, we have done it:

Actually, I will explain different tricks and features of VuGen scripts in the further posts.

2. Create LoadRunner Controller scenario for your application using the VuGen scripts.

Page 18: Load Runner Correlation

Here it is:

3. The next step is to add measurement monitors which are quantitative indicators of resources being monitored (for example, memory usage, CPU usage, handle and thread count, and so on).For that, on "Run" tab in the LoadRunner Controller, drag "Windows Resources" item from the "Available Graphs" tree and drop it to graphs area.See the screenshot:

Then right-click on the just added graph ("Windows Resources") and select "Add Measurements" from the pop-up menu."Windows Resources" dialog will be shown:

Page 19: Load Runner Correlation

The following actions are easy. I will add the name of server where the application (Web server in my case) will be run. This server can be a remote one. In this case, you have to make sure that LoadRunner will have an access to get info from the remote computer. Usually, I provide administrator rights for user which executes LR scripts.After that I select counters I want to measure during the load testing:

So, "Windows Resources" dialog looks like:

Page 20: Load Runner Correlation

I selected the following counters:o % User Time for two processes (RService & tomcat5) and

the whole system (_Total) o Available bytes in the system o Handle counts o Thread countso Working Sets

Also you may wish to add "Private Bytes" counter. Description for each counter is available on "Windows Resources" dialog. Obviously that the set of counters depends on the requirements and software to be tested.

Pay attention... If you select the "Windows Resources" graph, the list of counters will be shown in the lower part of the

Page 21: Load Runner Correlation

LoadRunner Controller:

4. Our mission is almost complete :) We have to run the scenario against a number of concurrent users (I user 30 users) and observe the graph displaying info on memory, CPU, handles and so on...I will show the result graph after 4 hrs of execution:

Pay attention to the yellow dotted line (memory usage of "RService" process) and the brown dotted line (habdle count counsumed by "RService" process) trends. They grow constantly during ~ 4.5 hours. I marked them out with red lines.So, this graph provides proofs that the application, I tested,

Page 22: Load Runner Correlation

contains memory leaks in the "RService" process.

Several words about useful tricks and hints, connected to measurements ans graphs:

o It is possible to export graphs to HTML from the LR. For that, right-click on the graph and select "Export to HTML...". It will generate HTML report containing the graph and a legenda for it. Very useful feature :)

o I recommend to set the range of time to be shown on the graph, to "Relative to scenario start". To perform this, right-click on the graph and select "Configure...". That allow to display statistics for the whole execution, but the latest N minutes.

o Sometimes, it is convenient to show more detailed graph. For that, double click on the graph - one big graph will be shown. To revert, double-click again. Also, you can change the number of graphs displayed - open menu View/View Graphs and set the required number.

5. So, now Dev team has to fix the problem in the "RService" process.. The last graph shows the results of load testing perfomed on the fixed application:

No any memory leaks found during 10 hrs.

Memory leaks fixed! Isn't it a progress? :)

Identifying Broken Links ………Load Runner

Today, I will describe how to use LoadRunner for broken links detection.

Page 23: Load Runner Correlation

'Broken' link is 'not valid' link. This link usually returns 404 Error - "Page not found". Another side of broken links is that images other resources are not displayed.

Using LoadRunner for broken links detection can be helpful, when you perform load testing of a site and you have to be sure, that all pages, images, applets, and other resources are available during the high server loading.

LoadRunner allows broken links detection during:1. Script recording 2. Script execution

1. Broken links detection during LoadRunner script recordingYou have to set appropriate recording options. For that, click 'Options...' button from 'Star Recording' dialog:

'Recording Options' dialog opens. Here, set 'Add comment to script for HTTP errors while recording' option:

Page 24: Load Runner Correlation

Please, note that you can see a description of the 'Add comment to script for HTTP errors while recording' option.

Now, you are ready to record your script. Click 'OK' button on 'Recording Options' dialog and start recording.

If LoadRunner find any HTTP errors, it will include comment into VuGen script.My application had some problems - there were several broken links for images there. So, LoadRunner generated the following script (click the image to view enlarged):

As you see, my application had several broken links to images and LoadRunner detected it successfully. Also, you can find the point, where these broken links were used. This is previous function - web_url.

LoadRunner inserted comments, which describe all occurred HTTP errors. Comments contain URL and server response.Since you have server responses, you can determine reasons of HTTP errors.

Page 25: Load Runner Correlation

Tips: For detailed info on HTTP status codes read this article from wikipedia and this one from w3.org.Tips: Read about the most 'popular' HTTP status code - 404.

2. Broken links detection during LoadRunner script executionLoadRunner can check broken links during the script execution too.You have to turn off one LoadRunner run-time option - 'Non-critical resource errors as warnings':

Uncheck the 'Non-critical resource errors as warnings' option and execute previous script again.The result is:

Please, note that LoadRunner's Replay Log contains errors about images we mentioned before. Their links were broken, that's why LoadRunner generated errors.

Page 26: Load Runner Correlation

I hope, this LoadRunner tutorial was helpful.As you can see, the initial task - broken links detection with LoadRunner - can be resolved in two ways.

You have to set appropriate option only. LoadRunner will do the rest :)

Load Runner Analysis Html Reports ………

Introductory words about LoadRunner Analysis HTML reports:

I like watching on how my LoadRunner scripts work without my intervention. The plan is simple:

I start LoadRunner Controller from command line Controller performs load testing After Controller finishes, it opens Analysis LoadRunner Analysis analyses :) and interprets results of load

tests I create and export customized HTML report

Default HTML report looks like the following one:

The task I faced:

After Analysis completed working, custom HTML report should be created and exported automatically and be sent with email. After that, next load test can be started from bat-file. So, there are no any pauses for tester's intervention should be.

My custom HTML report should contain new graph - "Windows Resources". Also, several default pages should be removed - "Running Vusers", "Throughput", and "Transaction Summary". So, new HTML report should look like:

Page 27: Load Runner Correlation

And the main condition is: this custom report should be generated automatically every

time I started my production LoadRunner scripts

How I created custom reports before:

Actually, any custom report can be created manually... I added manually new graph ("Windows Resources"), deleted unnecessary pages, generated HTML report, saved it, attached to email and sent it.

Why I had to automate the creation of reports:

Above process requires tester's time (= mine). I'm lazy man and don't like wasting my time for such routine actions.

Another important reason to generate these custom reports automatically is that I created something like a framework, which:

1. restarts test server 2. configures and starts services of my application to be tested3. starts LoadRunner tests 4. performs load testing 5. gathers and analyses results from automated tests 6. creates custom reports7. attaches these reports to email and send to appropriate

addressees

Page 28: Load Runner Correlation

8. repeats the above actions for next automated LoadRunner test

I plan to share this framework in the nearest future, if anyone asks it :)

Well, let's start working on the current topic...

I will show how to edit a default report and save it as a template. After that, we will learn how to start LR Analisys from command line and how to work with a saved template.

How to create custom report:

I recommend to customize a default report and save it as a template.To delete "Running Vusers", "Throughput", and "Transaction Summary" pages, select them in Session Explorer, right-click and select "Delete Item":

The new graph ("Windows Resources") adding is also intuitive. Just right-click on "Graphs" item and select "Add New Item / Add New Graph":

Page 29: Load Runner Correlation

After that you can select new graph to added. In my case, I selected "Windows Resources" graph:

Note: if you want to add "Windows Resources" graph, it must be added to LR Controller. Please, read my previous post to see how add and process "Windows Resources" graph:How to detect memory leaks with LoadRunner - visual tutorial

After that I rearrange the current list of graphs. For that just drag any item (graph) and drop it to required place. It's easy, really :)After these manipulations, the list will be the same I wished:

Great! The finish is not far :)Now I select menu "Reports / HTML Reprot..." and get the report I

Page 30: Load Runner Correlation

dreamt :)

The next step is saving of the current report as a template:

Select menu item "Tools / Templates / Save As Template...".As a result, "Save As Template" dlg will be shown:

I perform the following:

Uncheck "Automatically apply this template to a new session" checkbox.This will allow to load default template when I start LoadRunner Analysis. Unchecked option suits me.

Check "Generate the following automatic HTML report" checkbox.If checked, the HTML report will be generated automatically. This is what I need.

Check "Automatically save the session as" checkbox.It should be checked to correctly automatically close Analysis.

Check "Automatically close Analysis after saving session" checkbox.I recommend to enable this option. It will be irreplaceable, if you plan a batch processing - that's our case.

Page 31: Load Runner Correlation

So, prepared "Save As Template" dialog is shown on the screen shot:

Click OK btn to save new template.Close LoadRunner Analysis. Now we are ready to perform last action.

Start LoadRunner Analysis from command line: To start only Analysys, execute the following command:

path_to_AnalysisUI.exe

To open *.lrr file (LoadRunner result file) or *.lra file (LoadRunner Analysis file), execute:path_to_AnalysisUI.exe -RESULTPATH path_to_lrr_or_lra_file

To open *.lrr or *.lra file and apply a specified template, execute:path_to_AnalysisUI.exe -RESULTPATH path_to_lrr_or_lra_file -TEMPLATENAME name_of_template

There is an example for my template ("WinResTemplate"):"c:\Program Files\Mercury\LoadRunner\bin\AnalysisUI.exe" -RESULTPATH C:\Temp\30users\30users.lrr -TEMPLATENAME WinResTemplate

Tips on the example:1. Since path to AnalysisUI.exe contains spaces, use quotes (") 2. You have to specify name of template, not path!

That's all! Execute the example command from command line.You will see that:

1. Analysis will be loaded

Page 32: Load Runner Correlation

2. It will start processing lrr-file, which was produced by LoadRunner Controller.

3. After it precesses lrr-file, Analysis will apply template. That means, needed graphs only will be created. We have specified these graphs above.

4. Analysis will create HTML report 5. HTML report will be saved in specified path (I used - %ResultDir

%\Windows_Resources_Report.html) 6. At the end, Analysis will be closed.

So, custom HTML report is ready without tester's intervention! Next LoadRunner test can be started from command line.

6. Running Load Runner from Command …….

Today I will explain how to open and run LoadRunner Controller scripts from command line.This feature can decrease tester's manual efforts and thereby to increase your effectiveness and performance.

You can open LoadRunner Controller scenario with:

LoadRunner\bin\Wlrun.exe -Run -TestPath scenario.lrs -ResultName res_folder

For example:

(note: click the image to enlarge it)

As a result of above command, LoadRunner Controller: starts opens Controller scenario executes it saves results to folder 'C:\Temp\LR_Res\result_0'

After that, Controller finishes working and closes.Please, see files from created 'C:\Temp\LR_Res\result_0' folder:

Page 33: Load Runner Correlation

Tips: As you see, there is LoadRunner Result file (result_0.lrr). You can pass it automatically to LoadRunner Analysis for further processing.Refer for detailed information: Custom HTML report in LoadRunner Analysis from command line.

Actually, Wlrun.exe can have several settings. There are their descriptions from HP LoadRunner Controller User's Guide (© HP/Mercury Interactive):

TestPath

Path to the scenario.For example, C:\LoadRunner\scenario\

Scenario.lrsIf the path includes blank spaces, use quotation

marks.

RunRuns the scenario, dumps all output messages into res_dir\output.txt and closes Controller

InvokeAnalysis

Instructs LoadRunner to invoke Analysis upon scenario termination. If this argument is not

specified, LoadRunner uses the scenario default setting.

ResultNameFull results path. For example, "C:\Temp\

Res_01"

ResultCleanName

Results name. For example, "Res_01"

ResultLocation

Results directory. For example, "C:\Temp"

Note: ResultName (full path) = ResultLocation (directory) + ResultCleanName (name)

Well, let's see different variants of how to open and run LoadRunner Controller script:

Page 34: Load Runner Correlation

Open LoadRunner Controller:Wlrun.exe

Open LoadRunner Controller scenario 'scenario.lrs' and do not execute it:Wlrun.exe -TestPath scenario.lrs

Open LoadRunner Controller scenario 'scenario.lrs', execute it, and save results to default folder ('C:\Documents and Settings\user_login\Local Settings\Temp\res'):Wlrun.exe -Run -TestPath scenario.lrs

Open LoadRunner Controller scenario 'scenario.lrs', execute it, and save results to 'res_folder' folder:Wlrun.exe -Run -TestPath scenario.lrs -ResultName res_folder

Open LoadRunner Controller scenario 'scenario.lrs', execute it, save results to 'res_folder' folder, and after that start Analysis on created results with default template:Wlrun.exe -Run -TestPath scenario.lrs -ResultName res_folder -InvokeAnalysis

And please see more complex example for desert :)

Open LoadRunner Controller scenario 'scenario.lrs', execute it, save results to 'res_folder' folder, and after that start Analysis on created results with default template. Repeat all these steps 10 times:set LR_HOME=C:\Program Files\Mercury\LoadRunnerfor /L %%i in (1,1,10) do "%LR_HOME%\bin\Wlrun.exe" -Run -TestPath "%LR_HOME%\scenario\memory_leak_crash.lrs" -ResultName C:\Temp\LR_Res\result%%iResult is:

Page 35: Load Runner Correlation

Well, where to use execution from a command line?It can be very useful in some cases, when you plain to:

run LoadRunner Controller and pass its results to LoadRunner Analysis

run LoadRunner scripts by schedule

7. Recording A File Saving in Load Runner

The problem:This is a frequently asked question - why file downloading from a browser page (right mouse click, then "Save Target As...") was not recorded in LoadRunner VuGen script?

The difference between functional and load testing:Actually, LoadRunner records a file transferring only, not downloading!This is the principal difference between functional and load testing! I will describe it.

Functional testing is done from a user's viewpoint.What does a user see? It sees windows, dialogs, UI cotrols.For example, user can see downloaded html-page in a browser, or as plain text in a telnet session.In this case, data transferring is the same (HTTP protocol), while data representation varies (browser or telnet session).

LoadRunner performs Load testing, i.e. it records and emulates data transferring between client and server. Data transferring only, not data displaying for user!For the above example, html-page can be downloaded directly from web-server. Another variant - page can be downloaded from FTP-server (even using Secured FTP protocol - FTPS), and then data will be passed to browser. User will see the same page.In this case, data representation is the same (browser page), while data transferring varies (HTTP or FTPS protocols).

So, remember the simple rule:

LoadRunner does not record client side activities!

Tips: That's why LoadRunner does not show browser windows during load testing.Note: Please, do not tell me, that VuGen shows Run-Time Viewer

Page 36: Load Runner Correlation

during replay :)The run-time viewer was developed specifically for script debugging. There is no dependency between data representations in Run-Time Viewer and in a real browser (for detailed info read Mercury Support Knowledge Base (http://kb-web.mercury.com, requires login), topic 14094 "What are the limitations of the Run-Time Viewer").

And that's why it is impossible to record a mentioned file downloading (right mouse click, then menu item "Save Target As...") . The answer is simple - this is not a load testing :)To perform this action, use functional testing tools - QTP, SilkTest, Selenium, and others.

7. Down load file from server and save it to disk

In my previous article, "How to record a file saving, performed by user from browser page?", I shown that user's activities are not recorded by LoadRunner. This is a rule!

LoadRunner records file transferring from server and does not record file saving.

What to do, if you have to save transferred file to local disk?Continue reading, and you will get the solution :)

So, Let's start.You can download file from a server with the web_url function.See an example:

Image downloading: 1. web_url("logo.gif", 2.     "URL=http://www.google.com/intl/en_ALL/images/logo.gif", 3.     "Resource=1", 4.     "RecContentType=image/gif", 5.     "Snapshot=t1.inf", 6.     LAST);

This code downloads Google's logo image:

Page 37: Load Runner Correlation

To save this image as file to local disk, we have to perform these steps:

1. Capture image from server's response 2. Save captured data to local disk

How to capture image from server's response?

Use web_reg_save_param function with the following boundaries - "LB=\r\n\r\n", "RB=". These boundaries allows to capture the whole data from a body of server's response. Function will look like:    web_reg_save_param("prmLogoImage", "LB=\r\n\r\n", "RB=", LAST);

This function should be placed before web_url function. After execution, prmLogoImage parameter will contain GIF-file.

I will clarify briefly the meaning of boundaries - "LB=\r\n\r\n" and "RB=".Please, read the basic concepts of HTTP protocol, read Request message section:

HTTP response consists of the following: Headers, such as HTTP/1.1 200 OK or Content-Length: 3473 An empty line A message body, containg text of requested page or file

So, Header and Message body should be separated by empty line.First CRLF (that is, a carriage return (CR = "\r") followed by a line feed (LF = "\n")) ends last header, and second CRLF ( = "\r\n") creates empty line. All data, followed by second CRLF, are treated as message body.To summurize - "LB=\r\n\r\n" says "start capturing from the beginning of message body", empty right boundary "RB=" says "capture data till the end of message".

Open LoadRunner and enable logging of data, returned by server:

Page 38: Load Runner Correlation

Then execute script containing initial web_url function, and open Replay log:

As you see, Replay log contains "\r\n\r\n" at the end of server's response.Also, pay attention, that server returns the length of file to be downloaded (Content-Length: 8558).

Save captured data to local diskSaving captured binary data (in our case, GIF file) requires additional step - we have to determine the length (= size) of captured data.

Tips: The simplest way - strlen function - is not correct. Imagine, that that captured data contains embedded NULL characters ('\0'):"123\0qwe"The real size of captured data = 7 bytes ('1', '2', '3', '\0', 'q', 'w', 'e').But strlen function will return value 3, because it counts bytes before the first NULL character ('\0').

To calculate size of captured data use lr_eval_string_ext function:    lr_eval_string_ext ("{prmLogoImage}", strlen("{prmLogoImage}") /* = 14*/, &szBuf, &nLength, 0, 0,-1);

Page 39: Load Runner Correlation

lr_eval_string_ext function copies captured data into szBuf array and places a size of captured data into nLength variable. That's easy, I hope :) If not, Help will help :)

Tips: There is another way to get known the size of file to be downloaded. Remember, that server returned the length of file (Content-Length: 8558). So, you can extract this value using Correlation.

And the last action is to save binary data from szBuf array into a local file. I used standard fwrite function from C programming language:    fwrite(szBuf, len, 1, hFile);

Well, please see the whole source code:

Click the block to expand the source code: 1. int WriteDataToFile(char *szFileName, const char *szBuf, int

len) 2. { 3.     int hFile; 4.5.     hFile = fopen(szFileName,"wb"); 6. .....

1.

Execute the source code, and you will see, that new file will be created and saved automatically - "C:\LogoImage.gif". And this is what we needed - Google's logo image.