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.

How to use performance center ?

 In this blog post, we will see about how to use Performance Center for Load/Stress Testing. HP Performance Center is a web based application which enables performance test engineers to execute load/stress testing.

The main advantage of Performance Center is any number of users can access, plan, execute and analyze the results.

The knowledge of LoadRunner components such as VuGen, Controller and Analysis is preferable. Now we will see steps involved to conduct load / stress testing using Performance Center. If you noticed, I did not mention any version number of Performance Center. If I mentioned version here, this blog post will be outdated in near future. Here we are going to see core steps to conduct load / stress testing using Performance Center.

Steps involved in Performance Center to conduct Load / Stress Testing

a. Creating scripts using VuGen

b. Uploading scripts to Performance Center

c. Host Machines

d. Creating Scenarios

e. Booking Slots

f. Conducting Load / Stress Testing

g. Analyze Results

a. Creating scripts using VuGen

From Performance Center, VuGen tool can downloaded for creating scripts for the identified critical scenarios. Recording, Playback, enhancing scripts and unit test will yield base lined VuGen script for testing.

b. Uploading scripts to Performance Center

Base lined scripts should be uploaded to Performance Center. Scripts should be uploaded in *.zip format this can be achieved thru File menu in VuGen.

c. Host machines

Before conducting load / stress tests, we will see about host machines which acts as Controller which manages the load / stress test. Load Generator which actually generate traffic by executing Virtual Users (VUsers). Controller + Load Generator which acts as Controller and Load Generator. Above details can be seen at Timeslot page.

d. Creating Scenarios

By clicking on New Load Test in Load Test page, one can create scenarios for Load / Stress testing. Under Design Group, test engineers can specify the number of load generators which can set either by number or by percentage.

Scheduler is used to specify the number of virtual users for the load / stress tests. It allows test engineers to specify the duration, ramp-up, ramp-down, steady state span and run mode. It displays an interactive schedule graph for the test engineers.

e. Booking slots

As I mentioned in first paragraph, Performance Center is a web based application. Test Engineers across geographical location will be able to conduct load / stress testing. It is much important to book the slots, so that no conflict will raise during execution.

Timeslot displays the availability of load generators, controllers and VUsers. Test engineers need to specify the time slot and the required hosts to conduct his/her load / stress test.

f. Conducting Load / Stress Testing

To execute load test, go to Scheduler and click on Start button to execute load / stress test or click on Run button against the load test. Performance Center scans for any errors. If everything is green, we can see the number of VUsers running, passed/failed transactions details, errors etc.

g. Analyzing the results

Once the test gets completed, we can collate and analyze the result. Results will be available in *.html, results.zip and rawresults.zip for analysis. Bottlenecks can be identified using correlating one or more graphs. The results can be downloaded and exported to Analysis tool for detailed analysis.

In next post, we will see about the best practices and the general errors that occurs during load / stress test.


Correlation issue - conversion from hex to string

void convert_hexparam(const char* paramName)
{
	char* src=0;
	char* psrc=0;
	char* dst = 0;
	char* pdst = 0;

	size_t srclen = 0;

	char c;
	char buf[5];

	char enclosedParamName[256];

	sprintf(enclosedParamName, "{%s}", paramName);
	src=lr_eval_string(enclosedParamName);

	srclen = strlen(src);

	dst = (char*)malloc(srclen);
	memset(dst, 0, srclen);

	for(psrc=src, pdst = dst; *psrc != '\0'; pdst++)
	{
		if(*psrc== '\\' && *(psrc + 1) == 'x')
		{
			memset(buf, 0, 5);
			buf[0] = '0';
			buf[1] = 'x';
			buf[2] = *(psrc + 2);
			buf[3] = *(psrc + 3);
			c = (char)strtol(buf, 0, 0 );

			*pdst  = c;
			psrc += 4;
		}
		else
		{
			*pdst = *psrc;
			++psrc;
		}	
	}
	*(pdst+1) = '\0';

	lr_save_string(dst, paramName);

	free(dst);
}

Action()
{
	lr_save_string("tjIAKJprJ\\x2FxoK2GJL\\x2BZMhgUm9Wat4j16dw\\x2B7o4d9Lak\\x3D", "hex_data");

	lr_output_message(lr_eval_string("{hex_data}"));

	convert_hexparam("hex_data");

	lr_output_message(lr_eval_string("{hex_data}"));

	return 0;
}

Random Name Generator

keep in global.sh:


random_alpha(char* param_name, int length) 

char buff[32] = ""; 
int r,i; 
char c; 
srand((unsigned int)time(0)); //Seed number for rand() 

for (i = 0; i < 7; i++) 

// A-Z = 65-90 = rand() % 25 + 65 

r = rand() % 25 + 65; 
c = (char)r; 

buff[i] = c; 
printf("%c", c); 



lr_save_string(buff, param_name); 



random_alpha("P_FirstName", 5);

Capture SAMLResponse dynamic value in loadrunner script

#ifndef _GLOBALS_H
#define _GLOBALS_H

//--------------------------------------------------------------------
// Include Files
#include "lrun.h"
#include "web_api.h"
#include "lrw_custom_body.h"


        void solution (char *strSource, char *strFrom, char *strTo, char *strParam)
       
        {
       
        char strTemp[29999];
       
        char *s = (char*)strSource;
       
        int i=0;
       
        int iLenFrom = strlen (strFrom);
       
        int iLenTo = strlen (strTo );
       
       
        while (*s)
       
        {
       
        if (strncmp (s, strFrom, iLenFrom) == 0)
       
        {
       
        strncpy (&(strTemp[i]), strTo, iLenTo);
       
        i += iLenTo;
       
        s += iLenFrom;
       
        }
       
        else
       
        {
       
        strTemp[i++] = *s;
       
        s++;
       
        }
       
        }
       
        strTemp[i] = 0;
       
       
        lr_save_string (strTemp, strParam);
       
        }

#endif // _GLOBALS_H


Variable declaration in action :

Action ()

{

char *strSource,*strSource1;
   
char *sOut;

    web_set_max_html_param_len("698956");

     web_reg_save_param("samlreq_1","LB=<input name=\"SAMLResponse\" type=\"hidden\" value=\"","RB=\"/>",LAST);

    web_url("sessionCookieRedirect",
        "URL=https://faxxx/login/sessionCookieRedirect?checkAccountSetupComplete=true&token={token}&redirectUrl=https%3A%2F%2m%2Fhome%2_eagentsiteminderperf_1%2F0oaz0twsmBgXpBqpw2p6%2Falnz0yo44UQb1s93c2p6",
        "TargetFrame=",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=https://eagenttl.farmersinsurance.com/login/forms/login.fcc?fromURI=https%3A%2F%2%2Fhome%2Ffinctest_eagentsiteminderperf_1%2F0oaz0twsmBgXpBqpw2p6%2Falnz0yo44UQb1s93c2p6%3FTYPE%3D33554433%26REALMOID%3D06-3e8f9418-cdf1-0093-0000-408000004080%26GUID%3D%26SMAUTHREASON%3D0%26METHOD%3DGET%26SMAGENTNAME%3D-SM-o3pMQdyFKmzLzrop3mcsQBRiC%252fLMGjgA9LYV%252bVhWi%252buwxN1IOW0b2LkK3slO9EtZmT%252b9kLM%252fOjI0KfNunPgfmQKxH0RuraDz%26TARGET%3D-SM-https%253a%252f%252feagenttl%252e%252ecom%252f",
        "Snapshot=t9.inf",
        "Mode=HTML",
        LAST);

    web_url("saml",
        "URL=https://xxxx/app/xxx_eagentsiteminderperf_1/exkz0twslaWHTtbr72p6/sso/saml",
        "TargetFrame=",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t10.inf",
        "Mode=HTML",
        LAST);

   
   
    strSource=lr_eval_string("{samlreq_1}");
       
        //lr_save_string (strSource,"pNewValue0"); 
       
        solution (strSource,"&#x2b;","+","samlreq_1");
       
        strSource=lr_eval_string("{samlreq_1}");
       
        //lr_save_string (strSource,"postValue1"); 
       
        solution (strSource,"&#x3d;","=","C_Samlresponse_Converted");

    web_submit_data("saml2assertionconsumer",
        "Action=https://xxxxx/affwebservices/public/saml2assertionconsumer",
        "Method=POST",
        "TargetFrame=",
        "RecContentType=text/html",
        "Referer=https://xxxx/app/finctest_eagentsiteminderperf_1/exkz0twslaWHTtbr72p6/sso/saml",
        "Snapshot=t11.inf",
        "Mode=HTML",
        ITEMDATA,
        "Name=SAMLResponse""Value={C_Samlresponse_Converted}"ENDITEM,
        "Name=RelayState""Value="ENDITEM,
        LAST);
   

}




Oracle NCA Protocol Example Scripts

In the following example, the user selected an item from a list (nca_list_activate_item), pressed a button (nca_button_press), retrieved a list value (nca_lov_retrieve_items), and performed a click in an edit field (nca_edit_click). The logical names of the objects are the parameters of these functions.

nca_lov_select_item("Responsibilities","General Ledger, Vision Operations");
nca_list_activate_item("FNDSCSGN.NAVIGATOR.LIST.0","+ Journals"); 
nca_list_activate_item("FNDSCSGN.NAVIGATOR.LIST.0"," Enter"); 
nca_button_press("GLXJEENT.TOOLBAR.LIST.0"); 
nca_lov_find_value("Batches",""); 
nca_lov_retrieve_items("Batches",1,9); 
nca_lov_select_item("Batches","AR 1020 Receivables 2537: A 1020"); 
nca_edit_click("GLXJEENT.FOLDER_QF.BATCH_NAME.0");

In certain tests, such as those performed on Oracle Configurator applications, information returned by one function is required throughout the session. VuGen automatically saves the dynamic information to a parameter by inserting a web_reg_save_param function into the script.
In the following example, the connection information is saved to a parameter called NCAJServSessionID. The right boundary is \r. The actual right boundary may differ between systems.
web_reg_save_param ("NCAJServSessionId", "LB=\r\n\r\n", "RB=\r",
       LAST);
web_url("f60servlet",         
         "URL=http://usscifforms05.sfb.na/servlet/f60servlet\?config=mult",
         LAST);

Oracle NCA Protocol Example Scripts


In the following example, the user selected an item from a list (nca_list_activate_item), pressed a button (nca_button_press), retrieved a list value (nca_lov_retrieve_items), and performed a click in an edit field (nca_edit_click). The logical names of the objects are the parameters of these functions.
... 
nca_lov_select_item("Responsibilities","General Ledger, Vision Operations");
nca_list_activate_item("FNDSCSGN.NAVIGATOR.LIST.0","+ Journals");
nca_list_activate_item("FNDSCSGN.NAVIGATOR.LIST.0","       Enter");
nca_button_press("GLXJEENT.TOOLBAR.LIST.0");
nca_lov_find_value("Batches","");
nca_lov_retrieve_items("Batches",1,9);
nca_lov_select_item("Batches","AR 1020 Receivables 2537: A 1020");
nca_edit_click("GLXJEENT.FOLDER_QF.BATCH_NAME.0");
...
In certain tests, such as those performed on Oracle Configurator applications, information returned by one function is required throughout the session. VuGen automatically saves the dynamic information to a parameter, by inserting a web_reg_save_param function into the script. In the following example, the connection information is saved to a parameter called NCAJServSessionID.
web_reg_save_param ("NCAJServSessionId", "LB=\r\n\r\n", "RB=\r",
       LAST);
web_url("f60servlet",         
         "URL=http://usscifforms05.sfb.na/servlet/f60servlet\?config
         =mult",         LAST);
In the above example, the right boundary is \r. The actual right boundary may differ between systems.

Loadrunner And Oracle Part1

Introduction

This is part 1 of an article which discusses some of the mechanisms for performance testing Oracle Applications / Oracle Forms using LoadRunner. This is far from an in-depth article but will, we hope, help performance testers get started with testing Oracle Applications and act as a reference resource. The article as a whole covers two key areas that seem to present the most issues, Object Names and Connect issues, as well as some other issues that we at Testing Performance have come across when delivering our Performance Testing Services. Part 1 covers Object Names issues.

Object Names

One of the first issues you will come across when recording an Oracle Application is that Oracle objects are recorded by a number rather than a name. These numbers are dynamic and cannot be relied upon when playing back a script, i.e. the object cannot be found by LoadRunner as its “number” has changed.

Here is an example of objects recorded by their object number (this is part of a login script that was recorded using Oracle Applications 11i protocol against an Oracle Forms application):

nca_edit_set(“31”, ”USERNAME”);
nca_obj_type(“31”, ‘\t’, 0);
nca_edit_set(“32”, (”PASSWORD”));
nca_obj_type(“32”, ‘\t’, 0);
nca_edit_set(“33”, ”TRAINING”);
nca_button_press(“34”);

This script refers to four objects 31, 32, 33 and 34. If these objects do not change their number between recording and execution then the script should run OK. However these numbers are subject to change for example if a new field is added on the form between object 33 and object 34 then the nca_button_press(“34”) would fail as would now probably known as 35. To get round this issue Oracle offers the “RECORD=NAMES” method which associates a name to each object rather than a number. The name is very much more likely to remain static.

Here is the same example as above except the objects were recorded by their object name (this is part of a login script that was recorded using Oracle Applications 11i protocol against an Oracle Forms application):

nca_edit_set(“LOGON_INFO_USER_NAME”, ”USERNAME”);
nca_obj_type(“LOGON_INFO_USER_NAME”, ‘\t’, 0);
nca_edit_set(“LOGON_INFO_USER_PASSWORD”,(”PASSWORD”));
nca_obj_type(“LOGON_INFO_USER_PASSWORD”,(””, ‘\t’, 0);
nca_edit_set(“LOGON_INFO_USER_DATABASE”,(””,”TRAINING”);
nca_button_press(“LOGON_INFO_CONNECT_BUTTON”);

By default, in all the engagements that I have been involved in at least, Record=Names is not enabled. So how do you enable Record=Names? Here are four methods for achieving this, three of which require a configuration change and one which is very simple. I have found that finding the correct method is very much a “suck it and see” methodology.

Before trying the following just make sure that your installation records numbers instead of names by recording a simple logon script.

Method 1: Append to URL

This is very much the simplest method and should be tried first.

Below is the Start Recording dialog presented when recording using the Oracle Applications 11i protocol. The URL in this case is:

http://apps.acme.co.uk:7778/forms/frmservlet?config=2001

Figure 1

Try appending record=names to the end of the URL, for example:

http://apps.acme.co.uk:7778/forms/frmservlet?config=2001&record=names

Figure 2

Note if record=names is the first parameter to be added to the url then you will need a question mark before it eg:

http://apps.acme.co.uk:7778/forms/frmservlet?record=names

If however there are one or more parameters already in the url then you will need the ampersand prefix eg:

http://apps.acme.co.uk:7778/forms/frmservlet?config=2001&record=names

Now try and record a simple login script, if the object numbers are replaced by object names then you are in business. You should also notice that the record=names flag is appended to the connect_server statement.

Note: This method worked with the following configuration:

Oracle Forms version: 1012002
LR Protocol: Oracle Applications 11i
LR Version: 9.5
Jinitiator version: 1.3.1.28 (not overly important)

Method 2: Set record=names in startup file

This method requires a change to the HTML startup file on the forms server. Tracking which file to change can be a bit tricky if someone has renamed the appropriate file, which they are quite entitled to do. The file you are looking for is the one that is called when the forms applet starts. This file holds configuration details for the forms applet. By default the name of the file is basejini.htm.

The file contains a number of configuration entries.  The line you are interested in is something like this:

<PARAM name="serverArgs ... ... ... fndnam=APPS">

[param name="”serverArgs" fndnam="APPS”" /] Note there may be a number of entries which replace the ellipses (…) above.

Append record=names as the last argument i.e.: [param name="”serverArgs" fndnam="APPS" record="names”" /]

<PARAM name="serverArgs ... ... ... fndnam=APPS record=names">

Note: there is a space between the fndnam=APPS argument and record=names.

Now try and record a simple login script, if the object numbers are replaced by object names then you are in business. Note: This method worked with the following configuration:

Oracle Forms version: 60824
LR Protocol: Oracle Applications 11i
LR Version: 9.5
Jinitiator version: 1.1.8.16 (not overly important)

Method 3: Set value in formsweb file and HTML start-up file

I have had to use this method less often than the previous two methods. This method should be used if the HTML start-up file references the Forms CGI configuration file.  This method requires two files to be changed.

The Forms CGI configuration file in question is formsweb.cfg (it may have been renamed but probably not).

You will need to add a new entry in this file under the USER PARAMETERS in the section: “Values for Forms applet parameters”. Add the following as the last entry in this section:

xrecord=names

Your file should look something like this:

connectMode=socket
serverHost=serv1.acme.co.uk
xrecord=names

;4) Parameters fo Jinitiator

In the HTML start-up file basejini.htm (or whatever its name has been changed to) there are a number of configuration entries.  The lines you are interested in go something like this:

<PARAM name="serverArgs ... ... ... fndnam=APPS">

[param name="”serverArgs" fndnam="APPS”" /] Note there may be a number of entries which replace the ellipses (…) above.

Append record=%xrecord% as the last argument i.e.: [param name="”serverArgs" fndnam="APPS" record="%xrecord%”" /]

<PARAM name="serverArgs ... ... ... fndnam=APPS record=%xrecord%">

Note 1: there is a space between the fndnam=APPS argument and record=%xrecord%.
Note 2: there may be more than one entry in the HTML start-up file that needs to be changed

Method 4: Oracle Applications record=names flag

If you can access the Oracle Applications System administrator then you can change the profile of the users via the Profile System Values panel and appending ?play=&record=names to the ICX:Forms Launcher. At this time I have no screen shots for this process but please feel free to contact Testing Performance ( info@testingperformance.co.uk) should you need assistance and we will do our best to provide a more indepth procedure.
 

Part 2 coming soon!

Part 2 of this article covers Connect issues and other issues that you may encounter when doing performance testing with Oracle NCA– look out for it!
Remember if you need help with any Performance Testing Services please feel free to contact us.

Multi-Protocol (Oracle NCA/Web) Tips & Tricks