Editor's note: This article is part of a library of custom VuC functions developed by performance test engineers to handle special situations encountered in scripting applications. For an overview of the library and links to other custom functions, see "A library of custom VuC functions."
The CHECK_FIND_RESULT macro, which is defined in the vu.h
header file provided with IBM® Rational Robot®, is used to report
data correlation errors during execution of HTTP test scripts. The enhanced
version of that macro described in this article provides additional error-reporting
options, making it easier to detect and diagnose certain types of playback problems.
When recording an HTTP VU script, Robot automatically generates code to populate "correlation variables" with values found in HTTP headers and HTML pages, and uses those variables as part of subsequent HTTP requests.
By default, if a test script fails to find a value for a correlation variable at runtime, it sets the variable to the value seen at recording time and writes an error to the virtual tester error file. In many cases using this default value will be sufficient to allow the script to continue. However, failure to find a correlation variable can be a strong indication that something isn't working correctly in the test, so you'll probably want to know about it when this happens. But errors written to the virtual tester error file are easily missed -- you have to remember to go looking for them since they don't show up as red failures in the error log.
This article describes a modified version of the standard code used for correlation error checking and reporting. The modified version provides some extra options for how this type of failure is reported, including an option to report any such errors as failed test cases in the test log. This option means that any failures are immediately obvious and is generally the most useful.
Reporting of correlation errors
An HTTP VU script uses the CHECK_FIND_RESULT
macro to validate that each correlation variable has been found successfully
at runtime. Calls of this macro are automatically included in the generated
VU script. There are two versions of this macro defined in the standard vu.h header file.
By default, CHECK_FIND_RESULT
detects if a value has been found and if not logs an error to the virtual tester
error file, sets the correlation variable to the value seen at recording time,
and continues script execution. Alternatively, if the token ABORT_IF_FIND_VALUES_FAILS
is set through a #define
statement in the script or through the VU Compilation tab in Robot or TestManager,
the macro does nothing and the script aborts when the undefined correlation
variable is accessed.
The enhanced version of CHECK_FIND_RESULT described here provides
some additional options for reporting such failures. These can improve the visibility
of playback errors and simplify the diagnosis of problems. As with vu.h,
tokens to control conditional compilation of the VU script determine which option
is used.
The error-reporting options (conditional compilation tokens and actions on failure to find a value) are as follows:
- No conditional compilation token -- Retains the default Robot behavior (that is, reports errors in the virtual user error file, sets the correlation variable to a default value, and continues execution of the script).
-
ERROR_IF_FIND_VALUES_FAILS-- Reports a failed test case (in red) in the test log, sets the correlation variable to a default value, and continues execution of the script. -
EXIT_IF_FIND_VALUES_FAILS-- Exits the virtual user emulation with an abnormal exit status, reporting the error to the user error file. -
ABORT_IF_FIND_VALUES_FAILS-- As withvu.h, does nothing, causing the script to abort when the undefined correlation variable is referenced.
Probably the most useful option is the ERROR level of reporting.
This highlights any correlation failures clearly through red Fail entries in
the test log.
Reasons for correlation errors
A VU script may fail to find correlation variables for various possible reasons. It's often an indication that the script isn't behaving correctly and the HTML page returned at playback time isn't the same as was seen at recording time. This is why highlighting these cases as red failures in the test log is so useful. If such cases occur each time the script is played back, even at low user volumes, it generally indicates a problem in the script. Alternatively, if such cases only occur at high volume, it generally indicates a problem with the application when it's under stress.
Sometimes the script may fail to find correlation variables even though the correct HTML page has been returned. Two particular cases like this are worth mentioning:
- A form field in an HTML page (defined with a
NAME=clause in the HTML) may result in anHTTP_FORM_DATAcorrelation variable being defined. However, if the form field has no associatedVALUE=clause in the HTML page,http_find_valueswill fail at playback time. In this case, if correcting the HTML isn't an option, you can simply assign a null string to the relevant correlation variable instead of calling theCHECK_FIND_RESULTmacro, in order to avoid an error being logged each time the page is displayed. -
hreffields in a URL string sometimes include randomly generated names in order to avoid the response being serviced from cache by the Web server. In this case, the field searched for byhttp_find_valueswon't be found, because the field name seen at recording time won't be the same as that seen at playback time. In this case, you need to decide whether correct emulation of this "cache busting" behavior is material to the outcome of the test. If it is, you'll probably need to handle the correlation manually, viastrstrormatchstatement calls. If it isn't, the correlation variable can either be removed or set to a default value manually rather than calling theCHECK_FIND_RESULTmacro.
A real example of the correlation code generated in the latter type of case is shown below. The field name in this case provides a strong clue that something significant may be happening.
{
SgenRes_053 = http_find_values("MagicNo1537538175",
                HTTP_href_DATA,
                1);
 CHECK_FIND_RESULT(SgenRes_053,
         "MagicNo1537538175",
         "1068443701984")
} |
The field name MagicNo1537538175
was randomly generated by the server each time the page was displayed, so the
name seen at recording time was never found in the response data during playback.
Investigation showed that the target of the subsequent request ignored the MagicNo <nnn>
field. Because the "cache busting" made no difference at all to the behavior
of the system, the reported errors could be safely suppressed by setting the
correlation variable to the value seen at recording time, as follows:
{
 SgenRes_053[0] = "1068443701984";
} |
Note that making the change in this way minimizes the script changes required, since there's no need to search for all subsequent references to the correlation variable.
There are no external requirements to use this enhanced macro.
Here's the enhanced version of the definitions in the CHECK_FIND_RESULT macro,
to replace the standard definitions in the CHECK_FIND_RESULT
macro in a copy of the vu.h
header file:
                                   /* Check http_find_values() result   */
                                   /* and take appropriate action,      */
                                   /* depending on #defined settings    */
#ifdef ABORT_IF_FIND_VALUES_FAILSÂ Â /* Let script fail with runtime error */
 #define CHECK_FIND_RESULT(VAR,ITEM,VALUE)
#else
 #ifdef EXIT_IF_FIND_VALUES_FAILS /* Exit user session
*/
   #define CHECK_FIND_RESULT(VAR,ITEM,VALUE) \
   if (limitof VAR < 0) { \
     VAR[0] = VALUE; \
    user_exit( \
      -1, \
       "*** http_find_values() could not find the value for " + ITEM + \
       " at Line " + itoa(_lineno) + " ***"); \
   }
 #else
   #ifdef ERROR_IF_FIND_VALUES_FAILS  /* Log error in error log */
     #define CHECK_FIND_RESULT(VAR,ITEM,VALUE) \
     if (limitof VAR < 0) { \
       VAR[0] = VALUE; \
       testcase \
         ["http_find_values-Error"] \
          0, \
          "*** http_find_values() could not find the value for " + ITEM + \
          " at Line " + itoa(_lineno) + " ***"; \
     }
   #else                      /* Just print warning in user error file */
     #define CHECK_FIND_RESULT(VAR,ITEM,VALUE) \
     if (limitof VAR < 0) { \
       VAR[0] = VALUE; \
       fprintf(stderr, "*** http_find_values() could not find the value for
       \"%s\" at Line %d ***\n", ITEM, _lineno); \
     }
   #endif /* ERROR_IF_FIND_VALUES_FAILS */
 #endif /* EXIT_IF_FIND_VALUES_FAILS */
#endif |
The code segment above should replace the definitions of CHECK_FIND_RESULT
near the bottom of vu.h.
Replace the lines from
/* Check http_find_values() result */ #ifndef ABORT_IF_FIND_VALUES_FAILS |
through
#endif /* ABORT_IF_FIND_VALUES_FAILS */ |
The safest way to replace the definitions is to make a copy
of the vu.h file, save it with
a different name (for example, vu_mod.h
to indicate a modified version), and edit it to include the modified code. The
vu.h file can be found
under the Rational Test installation directory, at the following location:
[drive:]\Program Files\Rational\Rational Test\include\vu.h |
The modified vu.h
file can be saved either in the same location as the original or in the script
include directory of each repository where it's required. All test scripts should
then be changed to reference the modified header file instead of the standard
vu.h.
Simply change the include statement at the top of the script from
#include <VU.h> |
to
#include <VU_mod.h> |
Note that it's possible that new releases of Robot will include modifications
to the vu.h
file (although it's been stable for a long time). It's important to check for
modifications after installing a new release of Robot, and if necessary reapply
these changes to a copy of the new version.
To use the enhanced macro, you'll need to select the required error-reporting
level by defining the appropriate token to control the conditional compilation
of the test script. The token can be defined in the test script before the #include
line. For example:
#define ERROR_IF_FIND_VALUES_FAILS |
#include <VU_mod.h> |
Alternatively, the token can be defined through the VU Compilation tab of the Test Script Properties Window in Robot (shown below) or the equivalent VU Compilation tab of the Options window in TestManager (which applies to all scripts in the project).
Richard Leeke is one of the founding partners of Equinox Ltd., a software architecture consulting company based in Wellington, New Zealand. Richard specializes in the areas of performance testing and the diagnosis and resolution of application, database, and infrastructure related performance issues. He's a fairly regular contributor (of both questions and answers) to various performance testing related forums and can be contacted by e-mail.
Comments (Undergoing maintenance)





