Tuesday, February 11, 2014

Creating a custom .DLL file in LoadRunner

Sometimes LoadRunner does not provide all the needed features that one needs when doing performance testing. One option is to write DLL’s to handle the needed stuff and writing your own custom DLL’s is really easy once you get the hang of it!

I needed to do a few HTTP calls “under the radar” from a script so using Delphi 2009 I wrote my own HTTPClient DLL that allows me to do a HTTP GET to a specific URL without adding to the statistics (Pages and Hits/Sec stats).

Creating DLL’s in Delphi is really simple. One of the things I had to keep in mind was that D2009 uses unicode internally so I had to take care to convert any internal strings to non-unicode before returning them to LR. I opted for using the Indy 10 component TIdHTTP as the base HTTP client, adding some Cookie handling and Compression support (gzip,deflate) and making sure the DLL was thread safe (as many client threads/process would be using it). I also soon realized I needed HTTP Proxy Support so in the end I added that too.

Finally had a DLL that exported the following methods:
http_Initialize( VUserID: Integer )
http_WebProxy( VUser: Integer; Host:PAnsiChar; Port: Integer )
http_WebGet( VUserID: Integer; URL: PAnsiChar; DestBuf: PAnsiChar; BufSize: Integer )
http_Finalize( VUserID: Integer )

The VUserID is the identifier for the connection since the DLL supports keep-alive. Calling Finalize() will destroy all cookies and disconnect the client from the server.

 Sample script:

vuser_init()
{
int ret, VUserID;
char buf[10240];

// Get VUserID
VUserID = atoi(lr_eval_string("{VUserID"));

// Load the DLL
lr_load_dll("HTTPClient.dll");

// Initialize the VUser object inside the DLL
http_Initialize( VUserID );

// Set the HTTP Proxy
http_WebProxy( VUserID, "127.0.0.1", 8080);

// Clear buffer, and get the URL's response
memset(buf,0,sizeof(buf));
ret = http_WebGet( VUserID, "http://www.google.com", buf, sizeof(buf) );

// Check for error
// Returns
// 0 != Insufficient Buffer (Returned value is needed size)
if (ret != 0) lr_error_message("Error: RetCode=%d", ret)
else lr_output_message("%s", buf);

// Finalize the VUser (free the VUser object inside the DLL)
http_Finalize( VUserID );

return 0;
}


An additional good thing with this is that the DLL can be loaded under ANY protocol, so now HTTP calls can be made in any script type!

Tuesday, February 4, 2014

The recorded application becomes unresponsive during the recording


This could be caused by VuGen’s recording mechanism not being able to connect to the application’s server. Network connection errors can be seen in the Recording Log:

[Net An. Warning (1068:197c)] Request Connection: Remote Server @ 123.123.123.123 - 5222 (Service=) Failed attempt #1. Unable to connect to remote server: rc = -1 , le = 10060) [Net An. Warning (1068:197c)] Request Connection: Remote Server @ 123.123.123.123 - 5222 (Service=) Failed attempt #2. Unable to connect to remote server: rc = -1 , le = 10060)




Note: the Recording log is in the ‘Output’ pane. Make sure ‘Recording’ is selected in the combo-box on the left:





In order to fix this problem, the Port mapping for the specific IP and port should be added to the Port Mapping dialog (under the Record > Recording Options… menu), and the entry should be unchecked. That will ensure that the above IP and port are not recorded – that application simply connects to them without any LoadRunner involvement. For the messages above the correct setting would be:





This workaround can be done in case the communication to 123.123.123.123:5222 is not important for the business process and can be omitted. If that’s not the case, the same entry should still be added, but left as checked. That will ensure correct traffic capture to this address.