Tuesday, October 23, 2012

Loadrunner Asynchronous Results Polling

Some user action trigger asynchronous server-side operations.  The user can then be forced to check for results periodically by polling the server.   The following script gives an example of how to do this as follows:

  • Define variables to specify polling interval and polling timeout.
  • Each polling interval, make the call to the server and check the results.
  • If the server has returned the finished results, end the polling loop and pass the transaction.
  • Otherwise, wait for the next polling interval and repeat.
  • If the timeout is hit, end the polling loop and fail the transaction.

Script

Action()
{
int done = 0;  
int pollIntervalSec = 1;
int timeoutSec = 3;
int secWaited = 0;
char *response, *expectedResponse; 

expectedResponse = "abc";

        lr_start_transaction("wait_for_data");

        // poll the site until expected response is received or timeout is reached
while (done==0)
{
            // capture response information
    web_reg_save_param("responseParam", 
"LB=Control: ", 
"RB=max", 
LAST ); 

            // hit the page to be polled
    web_url("Test", 
"URL=http://www.google.com", 
"Resource=0", 
"RecContentType=text/html", 
"Snapshot=t1.inf",
LAST);

    // Save respone to string
   response = lr_eval_string(lr_eval_string("{responseParam}"));

   // check string contents to see if done
   if(strcmp(response,expectedResponse)==0)
{
     done=1; // set flag to indicate success
 lr_message("Found expected response=%s", response);
     lr_end_transaction("wait_for_data", LR_PASS);
   }

    // increment time waited
   secWaited = secWaited + pollIntervalSec;

    // check for timeout
   if (secWaited > timeoutSec)
   {
    done = 1;
    lr_end_transaction("wait_for_data", LR_FAIL);
    lr_error_message("Wait for data timed out, took longer than %d seconds", timeoutSec);
   }
   lr_think_time(pollIntervalSec);


return 0;
}


Console Output


Starting action Action.
Action.c(11): Notify: Transaction "wait_for_data" started.
Action.c(15): Registering web_reg_save_param was successful   [MsgId: MMSG-26390]
Action.c(20): Found resource "http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" in HTML "http://www.google.com"   [MsgId: MMSG-26659]
Action.c(20): Warning -26376: Requested parameter "responseParam" found in 2 different pages/frames. Use web_reg_save_param with more restrictive LB/RB/RelFrameId   [MsgId: MWAR-26376]
Action.c(20): Warning -26373: Parameter "responseParam" saved from a resource (URL="http://www.google.com/intl/en_ALL/images/srpr/logo1w.png")   [MsgId: MWAR-26373]
Action.c(20): web_url("Test") highest severity level was "warning", 12282 body bytes, 1071 header bytes   [MsgId: MMSG-26388]
Action.c(48): lr_think_time: 1.00 seconds.
Action.c(15): Registering web_reg_save_param was successful   [MsgId: MMSG-26390]
Action.c(20): Resource "http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" is in the cache already and will not be downloaded again   [MsgId: MMSG-26655]
Action.c(20): web_url("Test") was successful, 4952 body bytes, 400 header bytes   [MsgId: MMSG-26386]
Action.c(48): lr_think_time: 1.00 seconds.
Action.c(15): Registering web_reg_save_param was successful   [MsgId: MMSG-26390]
Action.c(20): Resource "http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" is in the cache already and will not be downloaded again   [MsgId: MMSG-26655]
Action.c(20): web_url("Test") was successful, 4952 body bytes, 224 header bytes   [MsgId: MMSG-26386]
Action.c(48): lr_think_time: 1.00 seconds.
Action.c(15): Registering web_reg_save_param was successful   [MsgId: MMSG-26390]
Action.c(20): Resource "http://www.google.com/intl/en_ALL/images/srpr/logo1w.png" is in the cache already and will not be downloaded again   [MsgId: MMSG-26655]
Action.c(20): web_url("Test") was successful, 4952 body bytes, 224 header bytes   [MsgId: MMSG-26386]
Action.c(45): Notify: Transaction "wait_for_data" ended with "Fail" status (Duration: 4.1903 Think Time: 3.0017 Wasted Time: 0.6545).
Action.c(46): Error: Wait for data timed out, took longer than 3 seconds
Action.c(48): lr_think_time: 1.00 seconds.
Ending action Action.

Monday, October 22, 2012

Virtualization Performance Testing


Virtualization technologies (such as VMware, Parallels, Xen, KVM, Waratek, etc.) have become very popular for good reasons, including but not limited to the following:
  • Application density can be increased
  • Server resource usage can be maximized
  • Hardware costs can be reduced many-fold
  • The number of servers required to run the same load can be reduced
  • Applications become more portable
It is critical to do performance, load, and stress testing of a virtualization solution before rolling it out for several reasons:
  • Different applications behave differently in a virtualized environment and some are more suitable than others
  • Performance or stability could be affected in a virtualized environment
  • Virtual machine sizing can drastically affect application behavior
  • Application configuration can be different when run in a virtualized environment.
This post gives a brief outline of how to do performance, load and stress testing of a virtualization solution.
  1. Include online and batch test cases as well as administrative operations
  2. Test bare metal (physical server) as a baseline to be compared to virtualization results
    1. See how many instance of the application can be run on bare metal
    2. Push bare metal up to server capacity
  3. Test virtualization
    1. Run VMs on the same bare metal server or an equivalent one
    2. Push one VM up to capacity, then two VMs, then three VMs, etc., up to the highest density desired.
    3. Capture hypervisor server resource usage metrics (cpu, memory, disk, network)
    4. Verify that VM performance compares reasonably relative to bare metal
    5. Verify that VM capacity compares reasonably relative to bare metal
    6. Verify that VM application stability compares reasonably relative to bare metal
    7. If performance or stability is not acceptable, see if application tuning is needed or virtual machine tuning is needed.
    8. Include stability tests in which high load is applied for an extended period of time.
    9. Perform administrative operations while system is under high load.
    10. Once performance and stability are acceptable, publish the results and the tuning and configuration needed to achieve acceptable results.


Loadrunner How to Read Parameters From Javascript

Sometimes it is necessary to read data from the contents of a javascript file rather than an html page.  The javascript may have certain variables created at compile time that it is useful to correlate.  Because the javascript file may show up as extra resources in an http call, the contents of the file are not visible to web_reg_save_param, etc.  However, by adding an additional call, the javascript can be read as follows:

  • Get the .js file with a web_url call
  • Set content type to "text/js"
  • Set resource=1

The following gives an example of the method described.

Script


Action()
{
    web_reg_save_param("jsText", 
"LB=", 
"RB=", 
LAST ); 

    web_url("Test-Read-JS-File", 
        "URL=https://test.server.com/scripts/test.js", 
        "Resource=1", 
        "RecContentType=text/js", 
        "Snapshot=t1.inf",
        LAST);

return 0;
}


Console Output


Starting action Action.
Action.c(4): Registering web_reg_save_param was successful   [MsgId: MMSG-26390]
Action.c(9): Notify: Saving Parameter "jsText = HTTP/1.1 200 OK\r\nAccept-Ranges: bytes\r\nCache-Control: max-age=2592000\r\nContent-Type: application/x-javascript; charset=utf-8\r\nDate: Mon, 22 Oct 2012 22:39:40 GMT\r\nExpires: Wed, 21 Nov 2012 22:39:40 GMT\r\nLast-Modified: Fri, 19 Oct 2012
...
Action.c(9): web_url("Test-Read-JS-File") was successful, 614175 body bytes, 321 header bytes   [MsgId: MMSG-26386]
Ending action Action.