Wednesday, February 1, 2012

Loadrunner How To Read a File into a Parameter

Here is a method for reading the contents of a file into a loadrunner parameter.  This can be useful for various situations such as reading XML or JSON requests from file, reading data, etc.

Script



//#include <stdio.h>
#define SEEK_SET 0 /* beginning of file. */
#define SEEK_CUR 1 /* current position. */
#define SEEK_END 2   /* end of file */


Action()
{
long infile; // file pointer
char *buffer; // buffer to read file contents into
char *filename = "test.txt"; // file to read
int fileLen; // file size
int bytesRead; // bytes read from file
// 
// open the file
infile = fopen(filename, "rb");
if (!infile) {
  lr_error_message("Unable to open file %s", filename);
  return;
}


// get the file length
fseek(infile, 0, SEEK_END);
fileLen=ftell(infile);
fseek(infile, 0, SEEK_SET);
lr_log_message("File length is: %9d bytes.", fileLen);


// Allocate memory for buffer to read file
buffer=(char *)malloc(fileLen+1);
if (!buffer) {
  lr_error_message("Could not malloc %10d bytes", fileLen+1);
  fclose(infile);
  return;
}


// Read file contents into buffer
bytesRead = fread(buffer, 1, fileLen, infile);
if (bytesRead != fileLen) 
{
  lr_error_message("File length is %10d bytes but only read %10d bytes", fileLen, bytesRead);
}
else
{
  lr_log_message("Successfully read %9d bytes from file: ", bytesRead);
}
fclose(infile);


// Save the buffer to a loadrunner parameter
lr_save_var( buffer, bytesRead, 0, "fileDataParameter");
free(buffer);
lr_log_message("File contents: %s", lr_eval_string("{fileDataParameter}"));
}




Step by Step Walk Through
Constants needed for fseek calls, also available in stdio.h:

#define SEEK_SET 0 /* beginning of file. */
#define SEEK_CUR 1 /* current position. */
#define SEEK_END 2   /* end of file */


Open file:

infile = fopen(filename, "rb");
if (!infile) {
lr_error_message("Unable to open file %s", filename);
return;
}


Get file length:

        fseek(infile, 0, SEEK_END);
fileLen=ftell(infile);
fseek(infile, 0, SEEK_SET);
lr_log_message("File length is: %9d bytes.", fileLen);


Allocate memory to read file into:

buffer=(char *)malloc(fileLen+1);
if (!buffer) {
lr_error_message("Could not malloc %10d bytes", fileLen+1);
fclose(infile);
return;
}


Read file into memory:

bytesRead = fread(buffer, 1, fileLen, infile);
if (bytesRead != fileLen) 
{
lr_error_message("File length is %10d bytes but only read %10d bytes", fileLen, bytesRead);
}
else
{
lr_log_message("Successfully read %9d bytes from file: ", bytesRead);
}

Close file handle:
fclose(infile);


Save the file to a loadrunner parameter:

lr_save_var( buffer, bytesRead, 0, "fileDataParameter");
free(buffer);
        lr_log_message("File contents: %s", lr_eval_string("{fileDataParameter}"));


File
The following is an example input file "test.txt" which would be located in the script directory (<loadrunner installation directory>/scripts/<scriptname>/test.txt:


First line of file.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Node>Data</Node></soap:Body></soap:Envelope>
Last line of file


Console Output

Running Vuser...
Starting iteration 1.
Starting action Action.
File length is:       168 bytes.
Successfully read       168 bytes from file: 
File contents: First line of file.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><Node>Data</Node></soap:Body></soap:Envelope>
Last line of file
Ending action Action.
Ending iteration 1.
Ending Vuser...

5 comments:

  1. When i run this code, it doesnt print the file contents; Here is the output contents:

    Starting action Action.
    File length is: 1166 bytes.
    Successfully read 1166 bytes from file:
    Action.c(62): Notify: Saving Parameter "fileDataParameter = HTTP/1.1\r\nAccept: text/json; q=0.9, text/xml; q=0.7, text/json\r\nx-vol-site: 0\r\nx-vol-tenant: 0\r\nx-vol-locale: en-US\r\nx-vol-currency: \r\n".
    File contents: {fileDataParameter}
    Ending action Action.
    Ending iteration 1.

    ReplyDelete
  2. I tried copying and pasting the code into a new script and it seems to work correctly. From your log it looks like the file is read into the parameter correctly. However, from the "File contents" message it looks like you could possibly be missing the lr_eval_string method. I was able to repro your behavior by removing lr_eval_string, changing the log message command to:
    lr_log_message("File contents: %s", "{fileDataParameter}");
    It seems to work correctly with lr_eval_string wrapper:
    lr_log_message("File contents: %s", lr_eval_string("{fileDataParameter}"));

    ReplyDelete
  3. Eric, Do i need to declare FileDataParameter as a string?

    ReplyDelete
  4. Hi Eric ,This works fine for one file .Can you please share the code for reading multiple files

    ReplyDelete
  5. Hi, The code worked fine for me but whole file content is passed into script parameter but need to pass file content line by line one after the other for each iteration. Please advise.
    Gopi

    ReplyDelete