Modify Common Parameters in Multiple Scripts Using Additional Attributes

 Problem statement: Your performance regression scenario contains 20 different Loadrunner scripts. You run this scenario a number of times in a given release. For simplicity, let’s assume that all scripts are developed using web services protocol. There may or may not be any changes to the scripts but version of the service endpoint changes a lot of times. For example, from version R200 to version R300

From http://ServerName:Port/R200/CustomerDataManagement.svc
To http://ServerName:Port/R300/CustomerDataManagement.svc

How to modify all the endpoints to have latest version, possibly without opening the scripts?

Solution 1: One trivial solution which would come to everyone’s mind is to create a parameter, say pEndpointVersion, and use that in the URL as shown below

http://ServerName:Port/{pEndpointVersion}/CustomerDataManagement.svc

Drawback: You will have to update the parameter value every time the endpoint version changes. Thus, you will have to download, open and update the parameter in all the scripts. This activity is very time consuming especially when it comes to VUGEN 11.52 as we all know how slow it is for opening scripts. Have a look a solution 2.

Solution 2 (preferred): In your script, go to RunTime Settings(RTS) under ‘Additional Attributes’, add a new argument name and a argument value. For example: argument name ‘EndpointVersion’ with argument value ‘R300’.

RTS-Additional Attributes Option


Then use the statement lr_get_attrib_string(“<Argument Name>“) to retrieve the argument value. In our example, use lr_get_attrib_string(“EndpointVersion“) to retrieve the value ‘R300’.

You can output the value like this

lr_output_message("*******version: %s"lr_eval_string(lr_get_attrib_string("EndpointVersion")));

OR save it into a parameter via lr_save_string() and access it anywhere in the script using the parameter name. For example,

lr_save_string(lr_get_attrib_string(("EndpointVersion")),"rVersion");

The endpoint will look like http://ServerName:Port/{rVersion}/CustomerDataManagement.svc
Example:

lr_output_message("*******version: %s"lr_eval_string(lr_get_attrib_string("EndpointVersion")));
lr_save_string(lr_get_attrib_string(("EndpointVersion")),"rVersion");

Output
Action.c(25): *******version: R300
Action.c(27): Notify: Saving Parameter “rVersion = R300”.

Benefit: If the endpoint version changes, you can modify the RunTime Settings (RTS) for all the scripts in the scenario in Performance Center itself. You don’t need to open and update it in individual scripts. If all the scripts use same RTS, then it’s even easier. Just modify RTS of one script and duplicate the RTS to rest of the scripts. Following screenshot shows the location of ‘Duplicate Runtime Settings’ option in Performance Center.


Duplicate RTS












In Truclient protocol script, the function is LR.getLRAttr(“<attrib_name>”);

Refer for details: VUGEN help > VuGen > Protocols > Ajax TruClient Protocol > Enhancing Ajax TruClient Scripts > Ajax TruClient Functions

Hope it helps to someone!

Base64 Encode/Decode for LoadRunner

 #include "base64.h"

vuser_init()
{
 int res;
 // ENCODE
 lr_save_string("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789","plain");
 b64_encode_string( lr_eval_string("{plain}"), "b64str" );
 lr_output_message("Encoded: %s", lr_eval_string("{b64str}") );
 
 // DECODE
 b64_decode_string( lr_eval_string("{b64str}"), "plain2" );
 lr_output_message("Decoded: %s", lr_eval_string("{plain2}") );
 
 // Verify decoded matches original plain text
 res = strcmp( lr_eval_string("{plain}"), lr_eval_string("{plain2}") );
 if (res==0) lr_output_message("Decoded matches original plain text");
 
 return 0;
}


And here’s the actual base64.h include file

/*

Base 64 Encode and Decode functions for LoadRunner

==================================================

This include file provides functions to Encode and Decode

LoadRunner variables. It's based on source codes found on the

internet and has been modified to work in LoadRunner.

 

Created by Kim Sandell / Celarius - www.celarius.com

*/

// Encoding lookup table

char base64encode_lut[] = {

'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q',

'R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h',

'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y',

'z','0','1','2','3','4','5','6','7','8','9','+','/','='};

 

// Decode lookup table

char base64decode_lut[] = {

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0,62, 0, 0, 0,63,52,53,54,55,56,57,58,59,60,61, 0, 0,

0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,

15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0, 0,26,27,28,

29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,

49,50,51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };

 

void base64encode(char *src, char *dest, int len)

// Encodes a buffer to base64

{

 int i=0, slen=strlen(src);

 for(i=0;i<slen && i<len;i+=3,src+=3)

 { // Enc next 4 characters

 *(dest++)=base64encode_lut[(*src&0xFC)>>0x2];

 *(dest++)=base64encode_lut[(*src&0x3)<<0x4|(*(src+1)&0xF0)>>0x4];

 *(dest++)=((i+1)<slen)?base64encode_lut[(*(src+1)&0xF)<<0x2|(*(src+2)&0xC0)>>0x6]:'=';

 *(dest++)=((i+2)<slen)?base64encode_lut[*(src+2)&0x3F]:'=';

 }

 *dest='\0'; // Append terminator

}

 

void base64decode(char *src, char *dest, int len)

// Encodes a buffer to base64

{

 int i=0, slen=strlen(src);

 for(i=0;i<slen&&i<len;i+=4,src+=4)

 { // Store next 4 chars in vars for faster access

 char c1=base64decode_lut[*src], c2=base64decode_lut[*(src+1)], c3=base64decode_lut[*(src+2)], c4=base64decode_lut[*(src+3)];

 // Decode to 3 chars

 *(dest++)=(c1&0x3F)<<0x2|(c2&0x30)>>0x4;

 *(dest++)=(c3!=64)?((c2&0xF)<<0x4|(c3&0x3C)>>0x2):'\0';

 *(dest++)=(c4!=64)?((c3&0x3)<<0x6|c4&0x3F):'\0';

 }

 *dest='\0'; // Append terminator

}

 

int b64_encode_string( char *source, char *lrvar )

// ----------------------------------------------------------------------------

// Encodes a string to base64 format

//

// Parameters:

//        source    Pointer to source string to encode

//        lrvar     LR variable where base64 encoded string is stored

//

// Example:

//

//        b64_encode_string( "Encode Me!", "b64" )

// ----------------------------------------------------------------------------

{

 int dest_size;

 int res;

 char *dest;

 // Allocate dest buffer

 dest_size = 1 + ((strlen(source)+2)/3*4);

 dest = (char *)malloc(dest_size);

 memset(dest,0,dest_size);

 // Encode & Save

 base64encode(source, dest, dest_size);

 lr_save_string( dest, lrvar );

 // Free dest buffer

 res = strlen(dest);

 free(dest);

 // Return length of dest string

 return res;

}

 

int b64_decode_string( char *source, char *lrvar )

// ----------------------------------------------------------------------------

// Decodes a base64 string to plaintext

//

// Parameters:

//        source    Pointer to source base64 encoded string

//        lrvar     LR variable where decoded string is stored

//

// Example:

//

//        b64_decode_string( lr_eval_string("{b64}"), "Plain" )

// ----------------------------------------------------------------------------

{

 int dest_size;

 int res;

 char *dest;

 // Allocate dest buffer

 dest_size = strlen(source);

 dest = (char *)malloc(dest_size);

 memset(dest,0,dest_size);

 // Encode & Save

 base64decode(source, dest, dest_size);

 lr_save_string( dest, lrvar );

 // Free dest buffer

 res = strlen(dest);

 free(dest);

 // Return length of dest string

 return res;

}






How to design workload model for stress testing?

  In this blog post, we will see how to design workload model for stress testing. Every person in this world has a breaking point. In short, there is a limit for everything. It applies for everything. Similarly, servers also has a breaking point, beyond a particular limit it will not behave as expected. It is much important to identify the breaking point before application goes live.

See the definition of Stress testing in my earlier post Types of Performance Testing. Stress Testing validates the stability of the system and it identifies the breaking point by overloading the concurrent users.

We will see what the appropriate approach for stress testing is. Following are the entry criteria for stress testing.

  • Hardware configurations
  • Network configurations
  • Number of Concurrent Users derived from Load Testing i.e. peak load
  • Identified critical scenarios

It is best to refer hardware and network configuration, as it will help to plan the stress testing to avoid any disaster.

Consider a web application which publishes your post across social medias; total number of concurrent during peak business hours (from 11:00 to 13:00) per day is 1500. Following are the list of transactions performed by the users.

  1. Login
  2. Click on Write Post link
  3. Write Post (140 characters)
  4. Submit Post
  5. Logout

In order to identify the breaking point of the system, first you load the server with 1500 concurrent users i.e. at A as shown in below figure.

How to design workload model for stress testing - qainsights

Load the server with 1500 concurrent users gradually. Once it reached, increase the concurrent users to 1600 and observe the script execution. Monitor the graphs between Response Time vs. Number of Virtual Users (VUsers), Throughput vs. Number of VUsers, and Errors vs. Number of VUsers. These graphs alerts the breaking point.

If everything goes fine for 1600 VUsers, increase it to 1700 VUsers, 1800 VUsers and so on till you face any abnormal behavior of the server. At some point, i.e. in our scenario at point B say at 2000, there are abnormal behavior such as Error 404, Error 500 errors occurred during the execution.

It is ideal to stop the execution either gradually or immediately. Because further execution give no valid result for analysis. In this case, breaking point of the server is 2000, i.e. 2000 VUsers can login concurrently and access the website. But beyond 2000, server will not be able to handle those many users.

To summarize, first is to gather entry criteria and start loading the server and incrementing it, till it breaks the system.