Unattended Playback of APPC Scripts (MF User)
Using unattended playback
Unattended playback processing works through coded batch statements run by the Performance Test EHSBATCH program. Unattended mode processing allows you to perform stress, regression, and concurrent testing easily and without intervention. Play back multiple scripts against one or more applications, simultaneously or serially.
Step 1. Review storage requirements for unattended mode processing
Ensure your virtual and caching storage are sufficient for your processing needs. The Performance Test Installation-and-Configuration-Guide lists MVS storage requirements for unattended processing.
Step 2. Record the scripts
Unattended playback executes the activity in the APPC script. If Global Record was used previously for APPC recording, usable scripts already exist. Locate the PDSs where the scripts reside and define them to unattended playback through the SYSLIB DD statement.
Step 3. Identify the application
The ALLOCATE and ACCEPT statements identify the conversations for a particular APPC LU name.
Step 4. Identify the scripts to run
The SCRIPT statement identifies the names of the scripts to run and the number of times to repeat each script.
Step 5. Submit the batch job
Performance Test for Mainframe Servers requires JCL to identify the program to run, the data sets where the scripts reside, an output message data set, and the input data set containing the Performance Test for Mainframe Servers control statements. The JCL statements required for unattended playback include:
EXEC
The program name (PGM=EHSBATCH). Set the region to about 4096 KB to test 50 simultaneous conversations.
SYSPRINT
Message data set for output for unattended playback. The logical record length of the SYSPRINT data set is 133.
SYSLIB
Identifies the data sets containing the scripts to run.
SYSCNTL
Identifies the input control data set containing the Performance Test for Mainframe Servers control statements. The record length of this data set (LRECL) must be 80. Use this data set to contain CONTROL and COMPANY statements defined during installation. This allows the systems programmer to set up a procedure with this information already defined.
SYSIN
Identifies the input data set containing the Performance Test for Mainframe Servers control statements.
Playing back APPC datastreams
To play back a recorded APPC datastream, submit a batch job using unattended playback. Using information taken from the conversation log to control playback, Performance Test for Mainframe Servers reads the previously recorded script, connects to a real application, and plays back the APPC data. During playback, Performance Test for Mainframe Servers assumes the role of one side of the APPC conversation.
As long as expected responses such as SENDs and ALLOCATEs are received, playback continues. However, if the application sends unexpected commands or data, playback terminates.
Performance Test for Mainframe Servers displays an informational message when the length of the data received from the partner application is different from the expected length. However, it does not examine the content of the data received from the partner application to report comparison information. Add REXX variables to the script to generate data comparison reports. See APPC REXX Variables.
Before you begin testing, determine whether the application expects to initiate APPC conversations or expects to receive conversations initiated by other applications.
If the application expects to receive APPC conversations, the conversation log that you play back should contain ALLOCATE statements. However, if the application expects to initiate APPC conversations, the conversation log that you play back should contain ACCEPT statements.
An ALLOCATE statement in the conversation log tells Performance Test for Mainframe Servers to initiate conversations with the application named in the RECEIVER keyword.
An ACCEPT statement in the conversation log prepares Performance Test for Mainframe Servers to accept conversations initiated by the application named in the SENDER keyword. An ACCEPT statement in the conversation log requires you to initiate an APPC conversation between an application and Performance Test for Mainframe Servers. Otherwise, Performance Test for Mainframe Servers waits (not running any scripts) until an application initiates an APPC conversation. After Performance Test for Mainframe Servers receives a request for an APPC conversation from an application, the ACCEPT and SCRIPT statements that match the incoming conversation start. The match is based on logical unit names, logmode name, and TP name.
Timing issues
Performance Test for Mainframe Servers offers a number of options for controlling the various timing aspects of playback. If you do not choose any of these options, the playback proceeds as quickly as possible.
Think-time parameters
Three think-time keyword parameters are available: THINK, THOPT, and THPCT. These parameters let you control the release of data to the application. Using these parameters, you can tell Performance Test for Mainframe Servers to send data to the partner application:
- As fast as possible (the default)
- At the same time intervals as during recording
- At a set fixed time interval
- At a percentage of the time intervals as during recording (for example, halve the playback time by entering 50%, double the playback time by entering 200%).
Refer to ALLOCATE and ACCEPT Statements for a more detailed description of these parameters and their usage.
Control and timing parameters
Four other parameters provide control over the start of conversations and the timing of the data sent from each conversation: USESTIME, TIMESYNC, LOGD, and STARTDLY.
LOGD
If you start multiple conversations under a single ALLOCATE statement by supplying the COUNT parameter, all conversations start at the same time, by default. You can, delay the start of each conversation by supplying the LOGD parameter. LOGD sets the number of seconds to elapse between the start of each conversation defined on the COUNT keyword. For more information, refer to LOGD(ss).
STARTDLY
If you want an ALLOCATE statement to become active only after a set time has elapsed during the playback job, use the STARTDLY parameter. STARTDLY sets the number of seconds to elapse during playback before the associated ALLOCATE is activated. For more information, refer to STARTDLY(ss).
STIME
If USESTIME is specified, the STIME date and time value controls the activation of the ALLOCATE statement. STIME is ignored if USESTIME is not on the CONTROL statement.
TIMESYNC
The TIMESYNC parameter on more than one ALLOCATE or ACCEPT statement tells Performance Test for Mainframe Servers to send the data in all scripts controlled by the TIMESYNC parameter in the order of the time stamps found within the scripts. The time stamps are treated as sequencing instructions to determine which data to send to the partner applications next. For more information, refer to TIMESYNC.
USESTIME
The USESTIME parameter on the CONTROL statement specifies that ALLOCATE statements start at the time interval set on their respective STIME keywords, rather than at the beginning of the playback job. If the USESTIME parameter is not present on the CONTROL statement, all ALLOCATE statements start when the playback job begins. See SCRIPT Statement for details on USESTIME.
Unattended playback
When Performance Test for Mainframe Servers plays back APPC conversations, it can use a single VTAM LU for one side of each APPC conversation. This logical unit is defined to VTAM with an APPL statement, typically in a member of the SYS1.VTAMLST data set. SQQFSAMP member APPC100 provides a sample definition.
Editing APPC scripts
At playback time, you can add to, replicate, or merge recording scripts by changing the keywords within the recording script and conversation log. The keywords identify the recording scripts used in the playback and the number of times a recording script is repeated. The conversation log can be in the batch job stream as a SYSIN data set. However, it is typically a PDS member, although it does not have to be in the same PDS where the recording scripts reside.
APPC statement descriptions
APPC input control statements control the number of conversations and the recording scripts to run.
APPC control script tags
You can opt to have Global Record automatically create scripts, or you can write them from scratch. A script contains a symbolic representation of all traffic that occurred between two APPC TPs. Performance Test for Mainframe Servers uses the following script tags.
<VERSION> tag
Identifies the version of the Performance Test for Mainframe Servers script creation program that created the script.
The VERSION tag appears only once in a script.
<CONTENT> tag
Identifies detail data associated with a previous CMDEAL, CMSEND, CMSNDX, CMSERR, PIU, or UNKNOWN tag.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
The CONTENT tag appears as many times as necessary to contain all of the detail data associated with the previous tag. The number of times the CONTENT tag appears depends on the record length of the file that contains the detail data. For example, if detail data is being written to a separate detail file and that file has a large LRECL, only a single CONTENT tag might be needed.
Writing a long detail value to a file with a small LRECL requires the use of multiple CONTENT tags. Each subsequent CONTENT tag is a continuation of the previous CONTENT tag.
<DETAIL> tag
Specifies where detail data is located. If the DETAIL tag is not in a script before a tag that has associated content, all tag contents are in the recording script rather than in a separate detail file.
COMBINED
Forces both inbound and outbound data to be contained in a single PDS member.
INBOUND
Identifies the data set where inbound data is stored.
OUTBOUND
Identifies the data set where outbound data is stored.
Each of these attributes can have a value of either an asterisk (*) or ddname(member). The * value specifies that the detail data is contained in the current script member. The ddname(member) value specifies that the detail data is contained within an external file with the defined DDname and data set member name.
If the ddname(member) value is present, the data set identified by ddname must be a data set with no member defined in the JCL. For example:
//DATA01 DD DISP=SHR,DSN=USR2503.PDS (where DSORG=PO)
<ERROR> tag
Indicates that an error was detected during datastream evaluation or during script generation. This tag is followed by an error message describing the problem that Performance Test for Mainframe Servers encountered.
<EXTDATA> tag
Specifies which record, in a detail file, the next CONTENT tag should retrieve. This tag does not have any associated content.
RETRIEVE=NEXT
Tells Performance Test for Mainframe Servers to retrieve the next sequential record from the external file.
RETRIEVE=PREV
Tells Performance Test for Mainframe Servers to reuse the most recently retrieved record.
<INBOUND> tag
Identifies a collection of data that was sent from the ALLOCATE receiver to the ALLOCATE sender. This tag needs an associated end tag.
<OUTBOUND> tag
Identifies a collection of data that was sent from the ALLOCATE sender to the ALLOCATE receiver. This tag needs an associated end tag.
<PIU> tag
Tells Performance Test for Mainframe Servers to ignore certain APPC traffic during playback. The traffic is either a
- VTAM BIND,
- CINIT,
- RSP(BIND),
- RSP(CINIT) PIU,
- VTAM FMH5 PIU,
- or a PIU produced as a result of an:
- APPC Send_Data,
- Send_Error,
- Send_Expedited_Data,
- Prepare_to_Receive,
- Confirm,
- Confirmed,
- Request_to_Send,
- or Deallocate verb.
The PIU tag represents a complete PIU, which consists of a transmission header (TH), a request header (RH), and a request unit (RU). PIU tags are present if the Write all traffic as script comments and interpreted values debugging options were selected. All request and response PIUs are included before the <CMxxxx> (for the CPIC forms) tag they apply to.
The content of this tag (contained in subsequent CONTENT tags) is a complete PIU.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
<REPLACE> tag
The REPLACE tag replaces the information within the APPC data streams during playback. Use this tag to supply new data, such as account numbers, user names, etc.
The REPLACE tag may be applied to the CONTENT of a single CMSEND, CMSNDX, CMSERR, or CMDEAL tag or to a range of tags. If applied to a range, the REPLACE tag acts on all of the CMSEND, CMSNDX, CMSERR, and CMDAL tags within the range.
Insert the REPLACE tag before the CMSEND, CMSNDX, CMSERR, or CMDEAL tag or group of tags it applies to. To establish a range, specify ALL on the TYPE parameter of the REPLACE tag and insert another REPLACE tag at the end of the range. Specify DELETE on the TYPE parameter of the closing REPLACE tag to terminate the action of the previous REPLACE tag.
FIELD
Identifies the byte offset and new value of a field within the datastream that will be replaced at playback time. (The field value is not changed within the script or detail file.)
The offset value is zero-based and applies to the entire “traffic” portion of a detail data record. The offset value does not consider the length, type, or label portions of a detail file record. For example, <REPLACE FIELD=(0,‘CAT’)> specifies that the first byte following the label portion of a detail file record is the start of three bytes to be replaced with the character string ‘CAT’.
Specify one or more FIELD attributes on a given REPLACE tag as shown below:
If a playback table entry is used instead of a literal value or REXX variable, add an ampersand (&) as a prefix to the value and define the playback table with TABLE statements having appropriate ID parameters. If the appropriate table is not defined, the value after the ampersand (&) will be treated as a literal. For example, if TABLE1 is not defined, &TABLE1 will be considered a literal. The table ID is prefixed with an ampersand (&) and may be enclosed in single quotes ('), but the quotes are not required. For example,
<REPLACE FIELD=(0,‘&IFBRACCT’)>and
<REPLACE FIELD=(0,&IFBRACCT)>are both valid.
The table data will be retrieved using the current PORT and GRPCYCLE information.
Assume TABLEDEF and TABLE are stated as follows:
TABLEDEF PORTS(p) DATADSN(USERID.APPC.TABLE.DATA) TABLE ID(TABLE1) REPEATS(r) DATALEN(d)The cell index will be calculated with the formula:
index = ((GRPCYCLE - 1)//r) * p + PORTwhere // represents mod (the remainder of the amount divided by r).
TYPE
Specifies how to apply the data replacement.
- TYPE=ONE applies the data replacement to the next CMSEND, CMSNDX, CMSERR, or CMDEAL message. This is the default.
- TYPE=ALL applies the data replacement to all subsequent CMSEND, CMSNDX, CMSERR, or CMDEAL messages. This is a global data replacement.
- TYPE=DELETE disables the global data replacement established by a previous replace tag with the TYPE=ALL parameter.
LENGTH
Sets the length of the replacement data stream. LENGTH=n, where n specifies the number of bytes. If n is greater than the value defined on the FIELD parameter, Performance Test for Mainframe Servers pads the value with binary zeros (X'00'). If the replacement value is shorter than the original message content, use the LENGTH parameter to ensure the entire message is replaced. For example, if you are replacing 'ABC Corporation' with 'Smith Inc.' and you do not specify a length, the result of the replacement is 'Smith Inc.ation'.
<EXTRACT> tag
The EXTRACT tag extracts the information within the APPC data streams during playback.
Insert the EXTRACT tag before the CMSEND, CMSNDX, CMSERR, or CMDEAL tag or group of tags it applies to. To establish a range, specify ALL on the TYPE parameter of the EXTRACT tag and insert another EXTRACT tag at the end of the range. Specify DELETE on the TYPE parameter of the closing EXTRACT tag to terminate the action of the previous EXTRACT tag.
FIELD
Identifies the byte offset and playback table identification (TABLE ID(member_name)). The offset value is zero-based and applies to the entire inbound data record. Since the EXTRACT tag does not have a length parameter, the length will be determined by the TABLE DATALEN(n).
The table ID is prefixed with an ampersand (&) and may be enclosed in single quotes ('), but the quotes are not required.
If table ID is not defined during playback, EXTRACT will not be performed and no error message will be produced.
The extracted data will be stored in the table using PORT and GRPCYCLE information.
Assume TABLEDEF and TABLE are stated as follows:
TABLEDEF PORTS(p) DATADSN(USR2503.APPC.TABLE.DATA) TABLE ID(TABLE1) REPEATS(r)The cell index will be calculated with the formula:
index = ((GRPCYCLE - 1)//r) * p + PORTwhere // represents mod (the remainder of the amount divided by r).
Specify one or more FIELD attributes on a given EXTRACT tag:
<TIME> tag
Provides a time stamp for the immediately following tag. You can use the TIME tag during playback for script synchronization.
The content of this tag is a time stamp with the format: YYYY/MM/DD_HH:MM:SS.SSSSS. For example: <TIME>2006/07/28_13:02:42.246413.
<UNKNOWN> tag
Identifies data that Performance Test for Mainframe Servers did not understand and was unable to interpret. The content of this tag (contained in subsequent CONTENT tags) is the portion of the VTAM Request Unit (RU) that was not understood.
You cannot play back a script containing the UNKNOWN tag. Script execution ends if Performance Test for Mainframe Servers encounters an UNKNOWN tag during playback.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
APPC Verb Script tags
You can use the tags in this section either via their APPC form, which is given in the individual headings, or via their CPIC form. CPIC forms are shown under the APPC forms in the syntax diagrams.
<CONFIRM> tag
Represents a confirm request from a TP. It has a CPIC form of CMCFM. This tag does not have any associated content.
<CONFIRMED> tag
Represents a confirmed response from a TP. It has a CPIC form of CMCFMD. This tag does not have any associated content.
<ALLOCATE> tag
For a description of this tag, refer to ALLOCATE and ACCEPT Statements.
<DEALLOCATE> tag
Represents a deallocate request from a TP. It has a CPIC form of CMDEAL. The content of this tag (contained in subsequent CONTENT tags) is any LOGDATA that is present.
TYPE
Identifies the type of deallocation request made by the TP. Valid values are FLUSH, CONFIRM, and ABEND.
SENSE
The four-byte SNA sense data produced by the deallocation request.
LOGDATA
Indicates whether error log data is present.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
<FLUSH> tag
Represents a flush request. Accumulated data not yet sent is sent immediately. It has a CPIC form of CMFLUS.
<PREPARE_TO_RECEIVE> tag
Represents a Prepare_to_Receive request from a TP. It has a CPIC form of CMPTR. This tag does not have any associated content.
TYPE
Identifies the type of Prepare_to_Receive request made by the TP. Valid values are FLUSH and CONFIRM.
LOCKS
Identifies the TP value for the LOCKS parameter. Valid values are SHORT and LONG.
<REQUEST_TO_SEND> tag
Represents a Request_to_Send request from a TP. It has a CPIC form of CMCRTS. This tag does not have any associated content.
<SEND_DATA> tag
Indicates that the TP sent some type of application data. The TP can send normal data, user control data, error data, and presentation services data. This tag has a CPIC form of CMSEND. The content of this tag (contained in subsequent CONTENT tags) is the data that was sent.
DATATYPE
APPLDATA:
Indicates that normal data was sent.
PSDATA:
Indicates whether presentation services data was sent. Presentation services data is the form used for PREPARE, COMMIT, and ROLLBACK synchpoint requests.
UCDATA:
Indicates whether user control data was sent.
ERDATA:
Indicates whether error data was sent.
MAPNAME
Specifies the name of any map that was sent along with the data.
ENCRYPT
Indicates whether the data is encrypted.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
<SEND_ERROR> Tag
Indicates that the TP sent an error response to the other side of the conversation. This tag has a CPIC form of CMSERR. The content of this tag (contained in subsequent CONTENT tags) is any LOGDATA that is present.
SENSE
The four-byte SNA sense data associated with the CMSERR request.
LOGDATA
Indicates whether error log data is present.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
<SEND_EXPEDITED_DATA> tag
Indicates that the TP sent expedited data. It has a CPIC form of CMSNDX. The content of this tag (contained in subsequent CONTENT tags) is the expedited data that was sent.
LABEL
If a detail file is used by this script, LABEL identifies the record in the detail file that is associated with this occurrence of the tag.
Contents of APPC detail data
This section describes the contents associated with the following Performance Test for Mainframe Servers detail data script tags:
- CMSEND,
- CMSERR,
- CMSNDX,
- CMDEAL,
- PIU, and
- UNKNOWN.
This information can follow either the CONTENT tag delimiter ( > ), or it can be contained in a file separate from the tag. The content of a tag is typically application-defined data sent by a transaction program. The content can also be error log data, user control data, complete PIUs, and so on.
Syntax
Whether the detail data is contained within a script or in a separate detail file, the record format of the detail data is the same:
Fields: L L T T C C C C C C C C V ...
Offset: 0 1 2 3 4 5 6 7 8 9 A B C ...There are four fields within the detail data structure:
Length (LL)
The first field (LL) is at offset 0 and is two bytes in length. The high-order bit is always set to zero and the remaining bits indicate the length of the record, which includes the length of the LL, TT, and CCCCCCCC fields.
The LL value can be from x‘000C’ to x‘7FF8’ (12 to 32760, decimal). These limits are reduced if the customer uses a record format of V or VB or if an LRECL of less than 32760 is supplied for the data set.
The LL field is usually equal to the current logical record length (LRECL) of the record as recognized by the access method, and as stored in the RDW for RECFM=V data sets. However, if you use a text editor such as ISPF/PDF, which removes trailing blanks from RECFM=V records, to edit and save the detail data data set, the LL field can be different than the record’s LRECL. Performance Test for Mainframe Servers assumes that the LL field is correct: if LL is less than the LRECL, only the LL portion is used; if LL is larger than the LRECL, Performance Test for Mainframe Servers pads the record with blanks to reach the LL value.
Padding the record with blanks eliminates the problem introduced by the ISPF/PDF editor for RECFM=V data sets. This padding process does not actually alter the detail data data set, the padding takes place within Performance Test for Mainframe Servers buffers at playback time.
Type (TT)
The second field (TT) is at offset two and is two bytes in length. This field indicates the format of the fields that follow. The values are assigned as follows:
B’xxxx 1xxx xxxx xxxx’ - 1 = First in chain, 0 = Not first in chain
B’xxxx x1xx xxxx xxxx’ - 1 = Last in chain, 0 = Not last in chain
B’xxxx xx0x xxxx xxxx’ - Reserved, must be zero
B’xxxx xxx1 xxxx xxxx’ - 1 = Data is inbound, 0 = Data is outbound
B’xxxx xxxx 0000 0001’ - Basic conversation application data (1)
B’xxxx xxxx 0000 0010’ - Mapped conversation application data (2)
B’xxxx xxxx 0000 0011’ - Presentation services data (3)
B’xxxx xxxx 0000 0100’ - User control data (4)
B’xxxx xxxx 0000 0101’ - Error log data (5)
B’xxxx xxxx 0000 0110’ - Error data (6)
B’xxxx xxxx 0000 0111’ - Null data (7)
B’xxxx xxxx 0000 1000’ - Expedited data (8)
B’xxxx xxxx 0000 1001’ - Unknown data (9)
B’xxxx xxxx 0000 1010’ - PIU (10)
B’xxxx xxxx 0000 1011’ - FMH5+PIP PIU (11)
B’xxxx xxxx 0000 1100’ - BIND PIU (12)
B’xxxx xxxx 0000 1101’ - BIND response PIU (13)
B’xxxx xxxx 0000 1110’ - CINIT PIU (14)
B’xxxx xxxx 0000 1111’ - CINIT response PIU (15)
Label (CCCCCCCC)
The third field (CCCCCCCC) is at offset four and is eight bytes in length. This field is a character format label that matches a label found within the associated script. If the detail data is included in the recording script rather than in a separate detail file, no “LABEL=label” attribute is contained on any of the script tags. This label field contains human-readable numbers (as opposed to hex), starting with c‘00000001’ (x‘F0F0F0F0F0F0F0F1’) and incrementing by one for each new record.
Value (V)
The fourth field is at offset 12 and is from 0 through 32748 bytes in length (or less if the LRECL is more restrictive). If the field is of 0 length (an LL value of x‘000C’) a transaction program issued a Send_Data with a 0 length data value.
For each of the 15 types of data (B‘xxxx xxxx 0000 0001’ through B‘xxxx xxxx 0000 1111’) indicated in the TT field, this fourth field contains the following, where ll represents a field length byte and xx represents an arbitrary data byte:
x’xx ...’ - Mapped conversation (No GDS prefix)
x’00 01 ...’ - Presentation services (Complete RU)
x’xx ...’ - User control data (No GDS prefix)
x’ll ll 12 E1 xx ...’ - Error log data (GDS prefix)
x’ll ll 12 F4 xx ...’ - Error data (GDS prefix)
x’ll ll 12 F1’ - Null data (GDS prefix)
x’03 xx ll ll xx ...’ - Expedited data (Complete RU)
x’xx ...’ - Unknown data (Portion of RU)
x’xx ...’ - PIU (Complete PIU)
x’xx ...’ - FMH5+PIP PIU (Complete PIU)
x’xx ...’ - BIND PIU (Complete PIU)
x’xx ...’ - BIND response PIU (Complete PIU)
x’xx ...’ - CINIT PIU (Complete PIU)
x’xx ...’ - CINIT response PIU (Complete PIU)
APPC Unattended Playback statements
APPC Unattended Playback statements provide processing rules and define what conversations (scripts) to play back.
Following introductory information on the sequencing of statements for APPC testing, the statements are presented in hierarchal order.
Statement sequence
Enter statements into your JCL in the sequence shown in the following figure.
APPC Unattended Playback Statement Sequence screen
ALLOCATE STATEMENT
SCRIPT STATEMENT
SCRIPT STATEMENT
…
ACCEPT STATEMENT
SCRIPT STATEMENT
SCRIPT STATEMENT
…
There is no limit to the number of ALLOCATE, ACCEPT, or APPCGRP statements or the number of SCRIPT statements that can follow. The statements have no column dependence. Continue statements on multiple lines by using the continuation character: a dash (–). However, the continuation character cannot be used to separate a keyword and its operand value.
Insert a comment after the continuation character as long as the dash and comment are separated by at least one blank space.
APPC Unattended Playback statement summary
CONTROL: Defines environmental data to Performance Test for Mainframe Servers. See SCRIPT Statement for APPC-specific information.
CACHINCL: Identifies which scripts Performance Test for Mainframe Servers loads into memory during initialization. See CACHINCL Statement for information.
CACHEXCL: Identifies which scripts Performance Test for Mainframe Servers will not store in memory. See CACHEXCL Statement for more information.
COMPANY: Defines an alternative company name to use in the title of the batch Performance Test for Mainframe Servers reports. See COMPANY Statement for information.
TABLEDEF: Defines the playback table using the following parameters: PORTS, DATADSN, and LOGDSN. See TABLEDEF Statement for more information.
TABLE: Specifies the playback table name to be read in and/or written out. It defines the data length and number of cells in the table. See TABLE Statement for more information.
ALLOCATE and ACCEPT: Identify a number of conversations connected to a particular APPC LU name. See ALLOCATE and ACCEPT Statements for information.
APPCGRP: Similar to the ALLOCATE statement, APPCGRP allows multiple SCRIPT statements containing the <ALLOCATE> tag. See APPCGRP Statement for information.
SCRIPT: Identifies a script to run for the conversations defined on the preceding ALLOCATE or ACCEPT statement. One or more SCRIPT statements follow an ALLOCATE or ACCEPT statement. See SCRIPT Statement for more information.
* (asterisk): Identifies a comment statement.
CONTROL statement
The CONTROL statement sets the options that control the operation of all subsequent ALLOCATE and ACCEPT statements.
CACHEOFF
When used, Performance Test for Mainframe Servers does not store scripts in memory. Eliminating this type of processing results in higher I/O for scripts that are run more than once.
DEFER
When used, Performance Test for Mainframe Servers forces report consolidation for less than 50 reports to be written onto DASD by a CONTROL parameter. Report consolidation saves memory during playbacks where a large number of terminals are used and memory might be an issue.
LU62PFX(hs62|n)
The one to seven character prefix used to define Performance Test for Mainframe Servers APPC APPLIDs during installation. The default prefix value is HS62. Only change this variable if your site changed the node names during installation. Otherwise, the default value is acceptable.
LU62SFX(4|n)
The length of the suffix used to define Performance Test for Mainframe Servers APPC APPLIDs during installation. The default suffix value is four. Only change this variable if your site changed the node names during installation; otherwise, the default value is acceptable.
LUALIAS(USERVAR|GENERIC|NONE)
Prepares Performance Test for Mainframe Servers to send and expect to receive alias LU names. An LU has a real name and may have an alias name. The real name is defined to VTAM with an APPL statement in SYS1.VTAMLST. Performance Test for Mainframe Servers creates the alias name dynamically using the VTAM USERVAR or generic resource.
The default value is LUALIAS(USERVAR), which indicates that Performance Test for Mainframe Servers uses any values on the SNDALIAS and RCVALIAS parameters as VTAM USERVARS. For more information on these options, see the SNA Programmer’s LU 6.2 Guide, IBM document number SC31-8811.
MSGFORM
When used, Performance Test for Mainframe Servers time stamps messages in the SYSPRINT data set. The default is no time stamps.
NODEFER
When used, Performance Test for Mainframe Servers suppresses report consolidation. Report consolidation is programmatically turned on when 50 or more reports are to be written onto DASD. Report consolidation saves memory during playbacks where a large number of terminals are used and memory could be an issue.
NOFMH5TO(300|sss)
(No FMH5 Time Out) The number of seconds for Performance Test for Mainframe Servers to wait for an FMH5 from the APPC partner. This is measured in whole seconds, with a 300 seconds (5 minutes) default. If the conversation log has ACCEPT statements and the partner applications might not initiate all conversations within the default amount of time, make this value larger than the default.
NORESPTO(45|sss)
(No Response Time Out) The number of seconds for Performance Test for Mainframe Servers to wait for a response from the APPC partner. This is measured in whole seconds, with a 45 second default. If the partner application normally takes more than 45 seconds to respond, make this value larger than the default.
If the time expires without a response from the partner, Performance Test for Mainframe Servers issues an informational message and the play process continues.
REXXOFF
When used, Performance Test for Mainframe Servers does not preprocess scripts using REXX. Eliminating this preprocessing results in more efficient (CPU and memory) running of scripts. Only use this parameter if your scripts do not contain REXX.
TRACE(sysout_class|dataset)
If this keyword is present, Performance Test for Mainframe Servers prints internal information. The amount of material printed can be substantial, and the trace material format is not documented.
USDATE(YES|NO)
The format of the date field. Enter YES (default) for MM/DD/YY. Enter NO for YY/MM/DD.
USESTIME
(Use Start Time) If present, each ALLOCATE statement containing an STIME parameter starts at a time interval after the start of the playback job, rather than immediately. If the USESTIME parameter is not supplied, or if an ALLOCATE statement does not contain an STIME parameter, the ALLOCATE statements start when the playback job begins.
With USESTIME supplied, the ALLOCATE statement containing the earliest STIME value starts when the playback job begins. The ALLOCATE statement with the next chronological STIME value then starts only after the amount of time indicated by the difference in STIME values has elapsed. For example, assume the following playback job begins at exactly 9:00 AM:
CONTROL USESTIME
*
ALLOCATE ... STIME(‘2006/07/19_12:05:00.000000’)
SCRIPT(AAA)
*
ALLOCATE ... STIME(‘2006/07/19_12:00:00.000000’)
SCRIPT(BBB)Script BBB starts at 9:00 AM and script AAA starts at 9:05 AM.
UNIT(unit)
The unit on which Performance Test dynamically allocates the journal or log data sets.
VOL(volume)
The DASD volume on which Performance Test dynamically allocates the journal or log data sets.
CACHEXCL statement
The CACHEXCL statement identifies scripts to not store in memory. You can use one or more CACHEXCL statements.
ddname(script)
The script not to store in memory.
CACHINCL statement
The CACHINCL statement identifies the scripts that Performance Test for Mainframe Servers preloads into memory at initialization. You can use one or more CACHINCL statements.
ddname(script)
The script name and location. If you do not enter a ddname, Performance Test for Mainframe Servers assumes SYSLIB is the ddname.
COMPANY statement
A COMPANY statement identifies a company name for all of the batch reports.
companyname
Identifies a company name up to 40 bytes long. The default is Compuware Corporation. If the company name includes dashes or blanks, enclose the name in single quotes.
TABLEDEF statement
The TABLEDEF statement defines the number of ports that will be used with your playback tables and specifies the data set names for the input (DATADSN) and output (LOGDSN) files.
PORTS(n)
Specifies the total number of ports that will be used in the playback. This is the total number of APPC ALLOCATES. A port is assigned to each ALLOCATE/APPCGRP in the playback, but a playback table cannot be assigned to a specific ALLOCATE/APPCGRP. Therefore, a table must contain all possible ports that will be assigned during playback. This parameter is required.
DATADSN(datasetname)
Specifies the data set name of your input table. Input data is used to import external data into a table that will be used with the <REPLACE> tag. The maximum length is 260 (256 bytes of data plus four bytes for the RDW (record descriptor word)). DATADSN must be a PDSE file. This parameter is required.
LOGDSN(datasetname)
Specifies the data set name of the log file where your output data will be put. The maximum length for log data is the length specified in DATADSN plus 50 or 310 (256 bytes of data plus four bytes for the RDW plus 50). LOGDSN must be a PDSE file. This parameter is required.
TABLE statement
The table specified using the TABLE statement.
ID(membername)
Specifies the table’s name, which is a member name of DATADSN and/or LOGDSN. This parameter is required.
REPEATS(n)
This value is used in conjunction with the PORTS parameter in the TABLEDEF statement to define the number of entries in the table. REPEATS is a required parameter since there is no default number of repeats. This parameter is required.
DATALEN(n)
Sets the length of the replacement data stream. The maximum length is 256 bytes. This parameter is required.
DATAIN
This reads the DATADSN member into the playback table.
LOG
Writes the contents of the table into the LOGDSN member.
INIT(NULL|SPACE|ZERO)
Initializes the playback table. Sets the table entry’s default to a null value (x‘00’), a space (x‘40’), or a zero (x‘F0’). NULL is the default.
ALLOCATE and ACCEPT statements
The ALLOCATE and ACCEPT statements set APPC control and conversation-specific values. ALLOCATE sends an APPC allocation. ACCEPT receives an APPC allocation.
Control-specific values must appear on ALLOCATE and ACCEPT statements in the conversation log. They are not valid in the script.
ALLOCATE conversation-specific values can appear in either the conversation log or the script. ACCEPT conversation-specific values must appear in the conversation log. The ALLOCATE statement (with or without conversation-specific values) must always be present in the conversation log, since its subparameter SCRIPT contains the script name. The script can then contain an ALLOCATE statement with additional conversation-specific values.
Before running playback, the conversation log must be changed so that each ALLOCATE statement names a Performance Test for Mainframe Servers LU. This name is different from the LU name originally recorded in the conversation log (in most situations).
Replace the ALLOCATE keyword in the conversation log with the ACCEPT statement if Performance Test for Mainframe Servers is to receive rather than send an APPC allocation.
Data defined in the conversation log overrides any data defined in the script.
Control and conversation-specific values of the ALLOCATE and ACCEPT statements are shown in the following syntax diagram. Parameter values are described after the diagram. The following parameters are valid in the conversation log, but are invalid in the script:
ALLSYNCH | SYNCH |
COUNT | THINK |
LOGD | THOPT |
RLOG | THPCT |
SERIAL | TIMESYNC |
STARTDLY | TRACE |
SUMMARY | VTAMTRCE |
Required parameters
LOGMODE(modename)
Identifies the VTAM session logmode used for this conversation. When you use the ACCEPT statement, you must enter a LOGMODE value.
RECEIVER(luname)
On an ALLOCATE statement, RECEIVER identifies the logical unit (LU) to which Performance Test sends the ALLOCATE request (an FMH5). On an ACCEPT statement, RECEIVER identifies the LU name representing Performance Test for Mainframe Servers.
TPNAME(tpname)
Identifies the transaction program being invoked. When you use the ACCEPT statement, you must enter a TPNAME value.
Optional parameters
ALLSYNCH
Tells Performance Test for Mainframe Servers to send each new APPC verb in unison for every ALLOCATE and ACCEPT statement containing the ALLSYNCH parameter. That is, for each script controlled by an ALLOCATE or ACCEPT statement containing the ALLSYNCH parameter, Performance Test for Mainframe Servers waits for all required responses from the partner applications before sending any new data.
With this technique, all scripts controlled by the ALLSYNCH parameter are played using the speed of the “slowest” application. New data is not sent to any application until all applications have responded.
Portions of a script that require no response from the application (for example, two SEND_DATA verbs back-to-back) cause Performance Test for Mainframe Servers to issue the next APPC verb in each script without delay.
ALLSYNCH must be supplied on more than one ALLOCATE or ACCEPT statement in a conversation log. Use ALLSYNCH when the scripts being played back on the ALLOCATE and ACCEPT statements in a conversation log are identical.
Using ALLSYNCH to keep multiple-identical scripts in unison is a useful way to stress the communications network, not your applications.
Use the SYNCH parameter, instead of ALLSYNCH, to run conversations on a single ALLOCATE or ACCEPT statement in a synchronized manner.
COUNT(nnn)
Sets the number of conversations to be started or accepted by the ALLOCATE or ACCEPT statement. The maximum number of conversations that can be run depends on the amount of virtual storage available to the playback job. If the COUNT parameter is not supplied, a single conversation is started. COUNT is similar to the TERM(nn) parameter on the GROUP statement, which starts multiple sessions.
Use the COUNT parameter to run several identical conversations under a single ALLOCATE or ACCEPT statement. By default, all conversations defined on an ALLOCATE statement with the COUNT parameter are started at the same instant. To start each of the conversations with a time interval, use the LOGD parameter in conjunction with the COUNT parameter.
The COUNT and REPEAT parameters can appear on the same statement. The total number of conversations that run reflects the product of the COUNT and REPEAT values.
FTIME(timestamp)
(Finish Time). Sets the end-date and end-time of the originally recorded conversation. The FTIME value is not used during playback.
LOGD(ss)
(Logon Delay). Sets the number of seconds between the start of each new conversation defined by the COUNT parameter. If LOGD is not supplied on an ALLOCATE statement that contains a COUNT parameter, all conversations are started as soon as the ALLOCATE statement becomes active (after STARTDLY or STIME processing, if any).
LOGD enables the start of identical conversations over a period of time, rather than all at once. Supplying the LOGD parameter on an ALLOCATE statement that does not contain a COUNT parameter has no effect.
LUWINST(instance_no)
Sets the logical unit of work instance number (6 bytes) for this conversation.
LUWNAME(luwname)
Defines the logical unit of work name for this conversation. The LUWNAME is not the same entity as the LUs used in the conversation. A logical unit of work represents a resource that is recoverable by an application such as CICS, IMS, or Db2.
LUWSEQ(sequence_no)
Sets the logical unit of work sequence number (2 bytes) for this conversation.
PIP(pip_value)
Supplies program initialization parameters. You can supply multiple PIP parameters. PIP data is used by some APPC applications to send initialization parameters to a partner application.
RCVALIAS(lualias)
Identifies an alias name for the RECEIVER LU name.
REPEAT(1|nnn)
Sets the number of times to start the conversations controlled by the ALLOCATE statement. The scripts controlled by an ALLOCATE statement that contains the REPEAT parameter runs n times sequentially. The default is 1 (one). There is no maximum limit.
REPEAT starts a new conversation after the previous conversation on the same ALLOCATE statement has finished. The COUNT parameter, in contrast, starts new conversations all at once (unless modified by the LOGD parameter).
Both the REPEAT and COUNT parameters can appear on the same statement. The total number of conversations that run is the product of the REPEAT and COUNT values.
RLOG(sysout_class|dataset)
Indicates that Performance Test for Mainframe Servers allocates a REXX log for each APPC conversation in the group. If the value is a single character, Performance Test for Mainframe Servers allocates the REXX log to SYSOUT in the class set by that single character. If the value is more than one character, Performance Test for Mainframe Servers allocates the REXX log to a permanent file. By default, the REXX output is directed to the SYSPRINT data set.
The data set value can be either a data set name by itself or a data set name with a member name:
RLOG(dataset)
RLOG(dataset(member))The data set or member or both can contain wildcard characters (* or ?).
If a data set name is supplied with no member and no wildcards, a data set is created with the name dsn.Pnnnn, where nnnn is the port number assigned to the conversation.
SECPROF(sec_profile)
The security profile for this conversation.
SECPSWD(password|DECRYPT(password))
The password for the supplied user ID. Use DECRYPT to decrypt the password in the script. If users change the password, they have the option of editing the script and putting the password in plain text (omitting the DECRYPT()).
SECURITY(NONE|SAME|PGM|PRST|SAMEPRST)
The type of conversation level security in use by this conversation:
- NONE: No security is in use.
- SAME: A user has already been verified.
- PGM: Verify the user ID and password using a security program.
- PRST: Implement persistent verification and require user signon.
- SAMEPRST: Implement persistent verification and do not require user signon.
SECUSER(userid)
The security user ID for this conversation.
SENDER(luname)
The LU name that Performance Test for Mainframe Servers uses as the sender of the ALLOCATE request. Some transaction programs that receive an ALLOCATE may be sensitive to the LU the ALLOCATE originated from. This parameter lets you control the originating LU (the ALLOCATE sender).
When SENDER appears on an ALLOCATE statement, the value is the LU name that Performance Test for Mainframe Servers uses to represent itself. This LU name must not be in use by any other application while the playback job is running. This LU name must be defined to VTAM on the MVS system where the playback job runs, and the logical unit must be activated, which is done automatically at some sites or can be done manually with the MVS VARY command.
Before running playback, the conversation log must be changed so that each ALLOCATE statement names a Performance Test for Mainframe Servers LU. This name is different from the LU name originally recorded in the conversation log (in most situations).
When the SENDER parameter appears on an ACCEPT statement, the value is the LU name in use by the partner application (the application that initiates the APPC conversation with Performance Test for Mainframe Servers).
SERIAL
If this keyword is present, all requests made to VTAM are serialized. Each request finishes before the next starts. SERIAL ensures, on a job-wide basis, that no two ports have an APPC verb in progress at the same time.
SINGLE
Allows support for single session APPC devices.
SNDALIAS(lualias)
An alias name for the SENDER LU name.
STARTDLY(ss)
Sets the number of seconds between the start of the playback job and the start of the ALLOCATE statement containing this STARTDLY parameter. If the USESTIME parameter is not supplied on the CONTROL statement, all conversations defined on an ALLOCATE statement begin when the playback job begins. STARTDLY delays the start of an ALLOCATE statement until the set number of seconds has elapsed.
The STIME parameter on an ALLOCATE statement used in conjunction with the USESTIME parameter on the CONTROL statement provides a similar activity.
If defined by the LOGD parameter, the conversation starts after the sum of LOGD and STARTDLY expires.
STIME(‘timestamp’)
Indicates the date and time when Performance Test for Mainframe Servers recorded the ALLOCATE request (unless you have edited the STIME value directly). When you use USESTIME on the CONTROL statement, an STIME value can be used to control the activation of an ALLOCATE statement.
The STIME value is ignored if the USESTIME parameter is not supplied on the CONTROL statement.
SUMMARY(sysout_class|dataset)
Tells Performance Test for Mainframe Servers to generate a summary report for the group. If the value is a single character, Performance Test for Mainframe Servers allocates the summary report to SYSOUT in the class set by that single character. If the value is more than one character, Performance Test for Mainframe Servers allocates the summary report to a permanent file. By default, no summary report is produced.
The data set value can be either a data set name by itself or a data set name with a member name:
SUMMARY(dataset)
SUMMARY(dataset(member))To allocate a PDSE at the same time, use the format:
SUMMARY(dataset*(member*))The data set must be either a sequential file or a PDSE. You cannot use a PDS as a summary report file because playback can write multiple members at the same time, a function not supported by PDSs.
The data set or member or both can contain wildcard characters (* or ?).
If a data set name is supplied with no wildcards, no suffix is added to the data set name.
SYNCH
Controls when data is sent by Performance Test for Mainframe Servers to the partner application for all conversations running under the current ALLOCATE or ACCEPT statement. To run multiple conversations in parallel, use the COUNT parameter along with SYNCH.
SYNCH tells Performance Test for Mainframe Servers to send each new APPC verb for this ALLOCATE or ACCEPT statement in unison. For each conversation running under this ALLOCATE or ACCEPT statement, Performance Test for Mainframe Servers waits for all required responses from the partner applications before sending any new data.
With this technique, the playback of conversations under the ALLOCATE or ACCEPT statement is at the speed of the “slowest” application. New data is not sent to any application until all applications have responded.
For portions of a script that do not require a response from the application (for example, two SEND_DATA verbs back-to-back), Performance Test for Mainframe Servers has nothing to wait for from the application; it issues the next APPC verb in each script without waiting.
The ALLSYNCH parameter can be used instead of SYNCH to run conversations under several ALLOCATE and ACCEPT statements in this synchronized manner.
SYNCLVL(NONE|CONFIRM|SYNCPT)
Indicates the type of synchpoint protocol used in the conversation. For more information on the NONE, CONFIRM, and SYNCPT options, see the SNA Programmer’s LU 6.2 Guide, IBM document number SC31-8811.
THINK(mm,ss)
Sets a think time, which is the amount of time that Performance Test for Mainframe Servers waits before sending the next APPC verb. This parameter is only valid in conjunction with THOPT(3). For example, the statement: ALLOCATE... THOPT(3) THINK(0,1) play back a script with one second between each APPC verb that Performance Test for Mainframe Servers sends to the partner.
THOPT(1|2|3)
Controls the speed at which APPC conversations are played.
- Play at full speed. The data is played back as fast as the system can run. This is the default.
- Think time recorded in the script. Think time is represented by the <TIME> tag recorded in the script.
- User-specified think time. Tells Performance Test for Mainframe Servers to use the think time set by the THINK(minutes,seconds) parameter.
THPCT(nnn)
Sets a think time percentage. This parameter is only valid in conjunction with THOPT(2|3). For example, the statement: ALLOCATE … THOPT(2) THPCT(25) plays back the script at 25 percent of the original think time recorded in the script. The APPC data sent to the partner by Performance Test for Mainframe Servers is sent after waiting for 25 percent of the amount of time recorded in the script.
THPCT values of less than 100 cause the script to be played back with a think time less than originally recorded. THPCT values greater than 100 cause the script to be played back with a think time greater than originally recorded.
TIMESYNC
When supplied on more than one ALLOCATE or ACCEPT statement, indicates that the data in all scripts controlled by the TIMESYNC parameter is sent in the order of the time stamps found on the APPC verbs within the scripts. The time stamps are treated as sequencing instructions to decide which data to send to the partner applications next.
TIMESYNC single-threads the sending of data to the partner applications and guarantees that the data is sent in the same sequence as originally recorded.
TIMESYNC, by itself, does not control how “fast” the playback takes place, only the order of data sent among several conversations. Use the THOPT, THINK, and THPCT parameters to control the speed of the playback.
Supplying the TIMESYNC parameter on only a single ALLOCATE or ACCEPT statement has no effect.
TRACE(sysout_class|dataset)
This option traces internal Performance Test for Mainframe Servers information. Do not use TRACE without guidance from Performance Test for Mainframe Servers Customer Support.
If used, Performance Test for Mainframe Servers allocates a trace for each APPC conversation. Trace contains the actual APPC datastreams that flowed between the application and the Performance Test for Mainframe Servers transaction program. If the value is a single character, the trace is allocated to SYSOUT in the class set by that single character. If the value is more than one character, the trace is allocated to a permanent file.
By default, no trace is allocated.
The data set value can be either a data set name by itself or a data set name with a member name:
TRACE(dataset)
TRACE(dataset(member))The data set or member or both can contain wildcard characters (* or ?).
If a data set name is supplied with no member and no wildcards, a data set is created with the name dsn.Pnnnn, where nnnn is the port number assigned to the conversation.
TYPE(MAPPED|BASIC|FDMAPPED|FDBASIC)
Indicates whether the conversation uses the MAPPED, BASIC, full-duplex MAPPED, or full-duplex BASIC protocol. For more information on these options, see the SNA Programmer’s LU 6.2 Guide, IBM document number SC31-8811.
VTAMTRCE
Tells Performance Test for Mainframe Servers that the trace contains additional VTAM data such as the bind, RPLs, and response and bracket conditions.
APPCGRP statement
The APPCGRP statement is similar to the ALLOCATE statement, but it allows multiple SCRIPT statements containing the <ALLOCATE> tag. While the APPCGRP statement can use all of the keywords and parameters listed for the ALLOCATE/ACCEPT statements, it is recommended that special care be given when using keywords not shown on the APPCGRP syntax diagram.
APPCGRP starts conversations specified in script statements in sequence. As a result, only one conversation is active at any one time. Each APPCGRP statement uses one parallel session. Multiple script statements within APPCGRP run in serial, one at a time.
Required parameters
RECEIVER (luname)
RECEIVER identifies the logical unit (LU) to which Performance Test sends the APPCGRP request (an FMH5), most likely the same receiver the original ALLOCATE statement contained.
SENDER (luname)
The LU name that Performance Test for Mainframe Servers uses as the sender of the ALLOCATE request. Some transaction programs that receive an ALLOCATE request may be sensitive to the LU the ALLOCATE originated from. This parameter lets you control the originating LU (the ALLOCATE sender).
The value is the LU name that Performance Test for Mainframe Servers uses to represent itself. This LU name must not be in use by any other application while the playback job is running. This LU name must be defined to VTAM on the MVS system where the playback job runs, and the logical unit must be activated, which is done automatically at some sites, or can be done manually with the MVS VARY command.
Optional parameters
COUNT(nnn)
Sets the number of instances for the APPCGRP statement. The maximum number of APPCGRP statements that can be run depends on the amount of virtual storage available to the playback job. If the COUNT parameter is not supplied, a single conversation is started.
Use the COUNT parameter to run several identical series of conversations under a single APPCGRP statement. The first conversations defined on an APPCGRP statement with the COUNT parameter are started at the same instant, and subsequent conversations run serially. To start each of the APPCGRP statements with a time interval, use the LOGD parameter in conjunction with the COUNT parameter.
The COUNT and REPEAT parameters can appear on the same statement. The total number of APPCGRP statements or instances of the APPCGRP statement that run reflects the product of the COUNT and REPEAT values.
LOGD(ss)
(Logon Delay). Sets the number of seconds between the start of each new APPCGRP statement set by the COUNT parameter. If LOGD is not supplied on an APPCGRP statement that contains a COUNT parameter, all instances of the APPCGRP statement started immediately (after any STARTDL processing).
LOGD enables the start of all instances of the APPCGRP parameter over a period of time, rather than all at once. Supplying the LOGD parameter on an APPCGRP statement that does not contain a COUNT parameter has no effect.
REPEAT (1|nnn)
Sets the number of times to start the APPCGRP statements. The scripts, controlled by an APPCGRP statement that contains the REPEAT parameter, run n times sequentially. The default is 1 (one). There is no maximum limit.
REPEAT starts a new conversation after the previous conversation on the same APPCGRP statement has finished. The COUNT parameter, in contrast, starts new conversations all at once (unless modified by the LOGD parameter.
Both the REPEAT and COUNT parameters can appear on the same statement. The total number of APPCGRP statements that run is the product of the REPEAT and COUNT values.
SKIPPERR
Continues playback at the next script within an APPCGRP if an APPC process error occurs. This means that processing does not stop if an APPC processing error occurs, only the script containing the error is not processed. The return code will be set with the highest return code within the APPCGRP. The REPEAT count for the APPCGRP will be executed as long as the last script does not get any error. An empty script will execute without an error and, therefore, it can be used as the last script for proper APPCGRP REPEAT(nn).
STARTDLY(ss)
Sets the number of seconds between the start of the playback job and the start of the APPCGRP statement containing the STARTDLY parameter. STARTDLY delays the start of an APPCGRP statement until the set number of seconds elapses. If defined by the LOGD parameter, the APPCGRP statement starts after the sum of LOGD and STARTDLY expires.
SUMMARY (sysout_class|dataset)
Tells Performance Test for Mainframe Servers to generate a summary report for the group. If the value is a single character, Performance Test for Mainframe Servers allocates the summary report to SYSOUT in the class set by that single character. If the value is more than one character, Performance Test for Mainframe Servers allocates the summary report to a permanent file. By default, no summary report is produced.
The data set value can be either a data set name by itself, or a data set name with a member name:
SUMMARY(dataset)
SUMMARY(dataset(member))To allocate a PDSE at the same time, use the format:
SUMMARY(dataset*(member*))The data set must be either a sequential file or PDSE. You cannot use a PDS as a summary report file because playback can write multiple members at the same time, a function not supported by PDSs.
The data set or member or both can contain wildcard characters (* or ?).
If a data set name is supplied with no wildcards, no suffix is added to the data set name.
SCRIPT Statement
A SCRIPT statement identifies a script to be played back, and optionally indicates the number of times to run the script.
Required Parameter
scriptname
Identifies the SCRIPT (member name from the SYSLIB) to be played back.
Optional Parameters
REPEAT(1|nnn)
Identifies the number of times a script plays back. The default is 1 (one).
STOPON(n)
Tells Performance Test for Mainframe Servers to stop processing when it reaches the specified number (n) of mismatches for that run. If there are fewer than the set number of mismatches, script processing continues to the end.
Script Not Found messages
It is possible that when Performance Test for Mainframe Servers issues message EMTRM016: SCRIPT SPECIFIED DOES NOT EXIST, REXX may issue the following messages:
IRX0554E
Explanation: The EXEC load file DDname is not allocated. The REXX EXEC cannot be loaded.
User Response: Verify that the script name is correct. Check the SYSLIB to see if it defines the correct data set. Verify that inappropriate REXX CALL statements have not run.
IRX0110I
Explanation: The REXX EXEC cannot be interpreted.
User Response: Verify that the script name is correct. Check the SYSLIB to ensure that it defines the correct data set. Verify that inappropriate REXX CALL statements have not run.
IRX0112I
Explanation: The REXX EXEC cannot be loaded.
User Response: Verify that the script name is correct. Check the SYSLIB to ensure that it defines the correct data set. Verify that inappropriate REXX CALL statements have not run.
Unattended playback return codes
Performance Test for Mainframe Servers reports an MVS return code for each step of a playback job. The return code is a numeric value that indicates whether the job step completed successfully and to what degree. See APPC Playback Return Codes for a complete list of APPC return codes.
The location of your return codes is dependent on your system configuration. On some systems, with the correct job statement parameter, return codes display in the user’s TSO session. On others, return codes are written to a job log. If you need help locating your return codes, see your systems administrator.
Performance Test for Mainframe Servers also writes the following informational messages to the SYSPRINT upon job completion:
EHSB098I MAXIMUM SCRIPT RC=rc, INTERNAL RC=rc
This message, in most cases, reports the highest script and internal return code values. The larger of these two values is returned as the job step completion code.
If the GROUP statement has multiple scripts, Performance Test for Mainframe Servers returns the value set by the last script processed. For example, Performance Test for Mainframe Servers reports the return code from the LOGOFF script in the following GROUP.
GROUP
SCRIPT(LOGON)
SCRIPT(TEST)
SCRIPT(LOGOFF)Due to this processing rule, the EHSB098I message may not report the highest return code value for this type of playback job. For example, if the TEST script returned an internal return code value of 4, and the LOGOFF script returned a value of 0, EHSB098I reports and a value of 0 for the INTERNAL RC.
If the GROUP statement has a COUNT parameter, which initiates concurrent playback sessions, or a REPEAT parameter, which initiates consecutive playback sessions, Performance Test for Mainframe Servers returns the highest value of all of the sessions. For example, a GROUP statement with COUNT(2) and REPEAT(3) invokes two concurrent playback sessions, repeated three times consecutively. If the first repeat returns a code of 0 for one playback session and 12 for the other, the second repeat yields 4 and 0, and the third repeat yields 0 and 0, as shown in the table below, Performance Test for Mainframe Servers returns 12 for the job step completion code.
REPEAT | Session 1 | Session 2 | ||
---|---|---|---|---|
Scripts in GROUP | RC | Scripts in GROUP | RC | |
1 | Script | 0 | Script | 12 |
2 | Script | 4 | Script | 0 |
3 | Script | 0 | Script | 0 |
If a GROUP statement contains multiple SCRIPT statements, and has a COUNT parameter, Performance Test for Mainframe Servers compares the return code set by the last script processed in each session and returns the highest value. For example, the following playback statements result in two concurrent playback sessions in which LOGON, TEST and LOGOFF are played consecutively.
GROUP COUNT(2)
SCRIPT(LOGON)
SCRIPT(TEST)
SCRIPT(LOGOFF)If the last script processed in the first session yields a code of 4, and the last script processed in the second session yields a code of 12, as shown in the table below, Performance Test for Mainframe Servers returns a job step completion code of 12.
Session 1 | Session 2 | ||
---|---|---|---|
Scripts in GROUP | RC | Scripts in GROUP | RC |
LOGON | 0 | LOGON | 0 |
TEST | 0 | TEST | 4 |
LOGOFF | 4 | LOGOFF | 12 |
In addition to the EHSB098I message, Performance Test for Mainframe Servers writes status, error, and warning messages to SYSPRINT. If the playback job step returns a non-zero code, review the return code description provided in APPC Playback Return Codes. Then review the warning and error messages to determine the cause of the problem. Refer to the Performance Test Messages-and-Codes for help with error resolution.
APPC Playback Return Codes
Code | Description |
---|---|
0 | All scripts ran successfully. |
4 | Warning: Any miscomparison caused by APPC processing. This includes: •Expected and actual record data lengths not equal •Expected and actual log data lengths not equal •Expected and actual sense data values not equal •An ACCEPT did not receive an ALLOCATE by the time the NOFMH5TO expired •A conversation log statement was rejected. |
12 | Error: APPC unattended playback process contains exceptions at the record level. For example: •One or more corresponding record lengths not equal •Sense data not equal on one or more records •Log data not the same length for corresponding records. |
16 | Error: Invalid script statement found. |
20 | Serious Error: •Port could not be started because APPC application is not valid or active •Port started, but could not be initialized •REXX EXEC/script not found. |
24 | Serious Error: The first port to start could not get started — the unattended playback process is terminated. |
28 | SEVERE ERROR: Port subtask could not be started. •SYSPRINT could not be opened or error processing SYSPRINT •SYSIN could not be opened or error processing SYSIN •SYSCNTL could not be opened or error processing SYSCNTL •User failed security authorization •APPC pool names could not be built from the provided prefix and suffix values •Product is not licensed for APPC unattended mode processing •APPC is not supported for APPC scripts •Trace could not be initialized •No terminals found to be played back •VTAM initialization error •A syntax error exists on the JOURNAL, LOG, XLOG, RLOG, AUTODOC, SUMMARY, or TRACE keywords on the CONTROL, GROUP, ALLOCATE, or COMPARE statements. |
32 | SERIOUS ERROR: A print file is full or could not be processed. The print files are the JOURNAL, LOG, XLOG, RLOG, AUTODOC, SUMMARY, and TRACE files. |
36 | Playback Error: Any playback table related error will set return code 36. |
40 | SEVERE ERROR: Performance Test for Mainframe Servers is about to expire or has expired. Contact Performance Test for Mainframe Servers Customer Support for a date extension and new release availability information. |
44 | SECURITY ERROR: Performance Test for Mainframe Servers detected an unauthorized default parameter table. Contact your systems programmer. |
APPC REXX variables
Performance Test for Mainframe Servers provides several predefined REXX variables that return information during playback. Incorporate the variables into REXX logic that you can optionally add to your scripts. The following sections provide definitions for the REXX variables.
To learn more about using the variables, including detailed examples, refer to the Performance Test Scripting-Reference.
APPC error determination REXX variables
The following variables provide information pertaining to an error encountered during script processing. During playback, Performance Test for Mainframe Servers issues VTAM macros to perform operations indicated in the script. Return codes from these macros are placed into the following REXX variables.
Many of these variables provide data from the Request Parameter List (RPL). These values are the character representations of binary values.
REXX Variables | Description |
---|---|
Cpicrc | Contains the equivalent CPIC return code for the error. If there is no error, the CPICRC is zero. |
Errmsgno | Contains the Performance Test for Mainframe Servers error message number of the error condition. |
Rplfbk2 | Contains the feedback code from the previous APPC operation. It is the register 0 value. |
Rplrtncd | Contains the return code from the previous APPC operation. It is the register 15 value. |
Rpl6ccst | Contains the conversation state from the VTAM RPL of the previous APPC operation. |
Rpl6rcpr | Contains the primary reason code from the VTAM RPL of the previous APPC operation. |
Rpl6rcsc | Contains the secondary reason code from the VTAM RPL of the previous APPC operation. |
Rpl6snsi | Contains the sense data from the VTAM RPL of the previous APPC operation. |
Rpl6what | Contains the “what received” value from the VTAM RPL of the previous APPC operation. |
APPC environment data REXX variables
The following variables provide information pertaining to the APPC conversation. These variables cannot be used to set their corresponding conversation values. These are read-only informational variables available for review while a script is running.
REXX Variables | Description |
---|---|
Convcorr | Contains the conversation correlator. |
Logmode | Contains the name of the logmode. |
Luwinst | Contains the logical unit of work instance number for the conversation. |
Luwname | Contains the logical unit of work name for the conversation. |
Luwseq | Contains the logical unit of work sequence number for the conversation. |
Opnrcdes | Contains the feedback code from the CNOS. |
Opnrtncd | Contains the return code from the CNOS. |
Receiver | Contains the LU name receiving the ALLOCATE. |
Secuser | Contains the userID used for security purposes. |
Sender | Contains the LU name sending the ALLOCATE. |
Tpname | Contains the transaction program name. |
APPC application data REXX variables
The following variables provide values for both the expected and the actual data received from an application during playback. The variables are read-only and are set after normal or expedited data is received from the partner application. The values are usable only immediately after the set of <CONTENT> tags associated with the <SEND_DATA> or <SEND_EXPEDITED_DATA> verb.
The variables represent the data received from the partner application. They must be examined in the context of an <INBOUND> group of verbs in a Performance Test for Mainframe Servers-allocated conversation, or in an <OUTBOUND> group of verbs in a Performance Test for Mainframe Servers-accepted conversation.
For example, an ALLOCATE statement in the conversation log runs the script shown in the following figure. In this example, the first REXX SAY statement lists a null value (0 length string) because Performance Test for Mainframe Servers has not received data from the partner application. However, the four REXX SAY statements in the <INBOUND> group produce meaningful output.
Sample Script Using APPC Application Data REXX Variables
<ALLOCATE>
<OUTBOUND>
<SEND_DATA>
<CONTENT>....00000001This is outbound data
say appc_actual /* This is not meaningful, a null value is displayed. */
<PREPARE_TO_RECEIVE>
</OUTBOUND>
<INBOUND>
<SEND_DATA>
<CONTENT>....00000002This is inbound data
say appc_actual /* The actual data received (up to 2048 bytes). */
say appc_expected /* The data we expect to receive (complete). */
say appc_actual_length /* Length of the actual data (may be more than 2048). */
say appc_expected_length /* The length of data we expect to receive (complete). */
<PREPARE_TO_RECEIVE>
</INBOUND>
<OUTBOUND>
<DEALLOCATE>
</OUTBOUND>
APPC_ACTUAL
The APPC_ACTUAL variable contains the data most recently received from the partner application. This data can either be normal data from a <SEND_DATA> verb or expedited data from a <SEND_EXPEDITED_DATA> verb. If the application sends more than 2048 bytes of data, only the first 2048 bytes are available in this variable.
The variable contains only a relevant value immediately after the set of <CONTENT> tags associated with <SEND_DATA> or <SEND_EXPEDITED_DATA> verbs. This value is reset as soon as another script tag is encountered. Likewise, the variable is only meaningful following APPC verbs that represent data received by Performance Test for Mainframe Servers. Examining the variable in a section of the script where Performance Test for Mainframe Servers is sending data is not meaningful.
The example below shows the APPC_ACTUAL variable used to produce meaningful data after the set of a <CONTENT> tag that is associated with a <SEND_DATA> verb.
Sample Script Containing the APPC_ACTUAL Variable
<SEND_DATA>
<CONTENT>....00000002This is inbound data
say appc_actual /* The actual data received (up to 2048 bytes). */
<PREPARE_TO_RECEIVE>
say appc_actual /* A 0 length string is displayed. */
</INBOUND>
APPC_EXPECTED
The APPC_EXPECTED variable contains the data that Performance Test for Mainframe Servers expects to receive from the partner application as a result of the most recently issued <SEND_DATA> or <SEND_EXPEDITED_DATA> verb. The value represents the data contained in the script or the associated detail file. The complete expected value is placed in the variable, even if it exceeds 2048 bytes (in contrast to the APPC_ACTUAL variable).
The variable contains a relevant value only immediately following the set of <CONTENT> tags that is associated with the <SEND_DATA> or <SEND_EXPEDITED_DATA> verb, and its value is reset when the next script tag is encountered. The variable generates useful data only when it is set after APPC verbs that represent data received by Performance Test for Mainframe Servers. Consequently, using the variable in a section of the script where Performance Test for Mainframe Servers is sending data will not produce meaningful data.
The example below shows the APPC_EXPECTED variable used to produce meaningful data after the <CONTENT> tag associated with the <SEND_DATA> verb.
Sample Script Containing the APPC_EXPECTED Variable
<SEND_DATA>
<CONTENT>....00000002This is inbound data
say appc_actual /* The actual data received (up to 2048 bytes). */
<PREPARE_TO_RECEIVE>
say appc_actual /* A 0 length string is displayed. */
</INBOUND>
APPC_ACTUAL_LENGTH
The APPC_ACTUAL_LENGTH variable contains the length of the data most recently received from the partner application. This value can be obtained from either the normal data from a <SEND_DATA> verb or from expedited data from a <SEND_EXPEDITED_DATA> verb. This variable contains the exact length of the data received from the partner, even if it exceeds 2048 bytes. Consequently, this value may be larger than the result of the REXX built-in: LENGTH(APPC_ACTUAL).
The APPC_ACTUAL_LENGTH variable contains a relevant value only immediately following the set of <CONTENT> tags that is associated with the <SEND_DATA> or the <SEND_EXPEDITED_DATA> verb, and its value is reset when the next script tag is encountered. The variable generates useful data only when it is set after APPC verbs that represent data received by Performance Test for Mainframe Servers. As a result, using the variable in a section of the script where Performance Test for Mainframe Servers is sending data will not produce meaningful data.
The example below shows the APPC_ACTUAL_LENGTH variable used to produce meaningful data after the <CONTENT> tag associated with the <SEND_DATA> verb.
Sample Script Containing the APPC_ACTUAL_LENGTH Variable
<SEND_DATA>
<CONTENT>....00000002This is inbound data
say appc_actual /* The actual data received (up to 2048 bytes). */
<PREPARE_TO_RECEIVE>
say appc_actual /* A 0 length string is displayed. */
</INBOUND>
APPC_EXPECTED_LENGTH
The APPC_EXPECTED_LENGTH variable contains the length of the data that Performance Test for Mainframe Servers expects to receive from the partner application. This can either be normal data from a <SEND_DATA> verb or expedited data from a <SEND_EXPEDITED_DATA> verb. The value is the length of the data contained in the script or associated detail file. The length does not include any of the Performance Test for Mainframe Servers header information that appears on <CONTENT> tags (the first 12 bytes).
This variable contains a relevant value only immediately following the set of <CONTENT> tags associated with the <SEND_DATA> or the <SEND_EXPEDITED_DATA> verb. Its value is reset when the next script tag is encountered. The variable generates useful data when it is set after APPC verbs that represent data received by Performance Test for Mainframe Servers. Consequently, using the variable in a section of the script where Performance Test for Mainframe Servers is sending data will not produce meaningful data.
The example below shows the APPC_EXPECTED_LENGTH variable used to produce meaningful data after the set of a <CONTENT> tag associated with a <SEND_DATA> verb.
Sample Script Containing the ACCP_EXPECTED_LENGTH Variable
<SEND_DATA>
<CONTENT>....00000002This is inbound data
say appc_expected_length /* The length of data expcted to receve (20 bytes). */
<PREPARE_TO_RECEIVE>
say appc_expected_length /* A 0 value is displayed. */
</INBOUND>
APPC general REXX variables
The following variables return general playback information.
CYCLE
Returns the repeat value of the script. This value is set to one when a script begins execution.
GRPCYCLE
Returns the repeat value of the ALLOCATE or APPCGRP statement. This value is set to one when an ALLOCATE or APPCGRP statement begins execution.
The variable is increased by one each time an ALLOCATE or APPCGRP statement finishes all of its scripts. You can use the REPEAT keyword on the ALLOCATE or APPCGRP statement in batch processing.
The GRPCYCLE variable can be used to provide a unique value during each iteration of an ALLOCATE or APPCGRP statement’s execution.
PORT
Returns a value listing the port assigned to each ALLOCATE or APPCGRP statement. The variable is increased by one for each ALLOCATE or APPCGRP statement. You can use the COUNT keyword on an ALLOCATE or APPCGRP statement in batch processing.
APPC summary report
The APPC summary report lists performance and mismatch information from the execution of scripts using unattended playback.
APPC Summary Report Example
SUMMARY REPORT TERMINAL ID: ** NA ** TPF NAME: H01APPCI TIME: 15:35:37 DATE: 06/06/27 PAGE: 000
-------------OUTBOUND---------------- ---------------- INBOUND ---------------
SCRIPT PORT NUMBER MINIMUM AVERAGE MAXIMUM NUMBER MINIMUM AVERAGE MAXIMUM ELAPS
ED
---------------------------------------------------------------------------------------------------------------
---
SCR1003 3 1 00:00.298 00:00.298 00:00.298 1 00:00.095 00:00.095 00:00.095 00:00:06.
007
SCR1003 3 1 00:00.007 00:00.007 00:00.007 1 00:00.017 00:00.017 00:00.017 00:00:06.
692
General Information
Script
The script being run. Two special script names, *SCR-TOT and *GRP-TOT, denote script and group totals, respectively.
Port
Each terminal is assigned a port ID. A port ID is associated with the script.
Outbound Performance Information
Number
Number of SENDs or ALLOCATEs processed by the terminal for the script.
Minimum
Minimum response time for the SENDs or ALLOCATEs processed by the terminal for the script.
Average
Outbound average is calculated from the sum of all response times for the port, divided by the number of outbound transactions for that port.
Maximum
Maximum response time for the SENDs and ALLOCATEs processed by the terminal for the script.
Inbound Performance Information
Number
Number of RECEIVEs or ACCEPTs processed by the terminal for the script.
Minimum
Minimum response time for the RECEIVEs or ACCEPTs processed by the terminal for the script.
Average
Inbound average is calculated from the sum of all think times for the port, divided by the number of inbound transactions for that port.
Maximum
Maximum response time for the RECEIVEs and ACCEPTs processed by the terminal for the script.
Elapsed Time
Elapsed
Elapsed time is calculated based on the total amount of time it took the port and the application to process the total number of transactions. For *SCR-TOT, this is the maximum elapsed time of the individual scripts. For *GRP-TOT this is the sum of the *SCR-TOT elapsed times.
APPC unattended playback example jobs
This section contains several example setups that illustrate how to play Performance Test for Mainframe Servers APPC scripts using unattended playback.
Example 1: Play back 100 APPC conversations all at once
This example is designed to stress test a CICS region by playing a previously recorded APPC conversation 100 times, with all conversations starting simultaneously. The COUNT(100) parameter starts multiple conversations with an application, all started when the ALLOCATE statement becomes active.
In this example, the ALLOCATE statement becomes active at the start of the playback job. Activating the ALLOCATE statement can be delayed using the USESTIME parameter on the CONTROL statement or the STARTDLY parameter on the ALLOCATE statement.
JCL to Play Back 100 APPC Conversations, All at Once
//STEPLIB DD DSN=HIPER.LOAD,DISP=SHR
//SYSLIB DD DSN=MY.SCRIPTS,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
CONTROL
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) COUNT(100)
SCRIPT(CICS10)
Example 2: Play back 100 APPC conversations started every 3 seconds
This example is designed to stress test a CICS region by using one previously recorded APPC conversation and playing it back 100 times. This time, however, rather than starting all of the conversations at once, Performance Test for Mainframe Servers starts one every 3 seconds (perhaps to represent 100 users starting transactions at different times). The COUNT(100) parameter causes Performance Test for Mainframe Servers to start multiple conversations, and the LOGD(3) parameter tells Performance Test for Mainframe Servers to let three seconds elapse between the start of each conversation.
JCL to Play Back 100 APPC Conversations, One Started Every 3 Seconds
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) COUNT(100) LOGD(3)
SCRIPT(CICS10)
Example 3: Play back 100 APPC conversations started at intervals
This example is designed to simulate a load on the CICS region similar to what existed at recording time. The USESTIME parameter on the CONTROL statement tells Performance Test for Mainframe Servers to start these conversations at the same relative time intervals as originally recorded.
The ALLOCATE statement with the earliest STIME value is started when the playback job begins. The conversation that begins next is the one with the next higher STIME value. Because the STIME values cover a period from 7:00 AM through 11:30 AM, the playback job runs for 4.5 hours.
The USESTIME parameter only controls the start of a conversation; after a conversation has started, it runs at full speed, waiting only for any responses from the partner application found in the script. Using the THOPT(2) parameter on an ALLOCATE statement causes Performance Test for Mainframe Servers to run its side of the conversation at the same speed as at recording time, rather than at full speed.
JCL to Play Back 100 Different APPC Conversations
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) -
STIME(‘2007/01/01_07:00:00.000000’)
SCRIPT(CICS0001)
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) -
STIME(‘2007/01/01_07:01:22.000000’)
SCRIPT(CICS0002)
.
. (more ALLOCATE statements)
.
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) -
STIME(‘2007/01/01_11:30:00.000000’)
SCRIPT(CICS0100)
Example 4: Play back one lengthened APPC conversation
This example is designed to take a single APPC conversation and make it “longer” than the original recording. The purpose of this test is to see if the partner application in the CICS region can handle a high rate of inquiries contained within a single conversation.
An editor was used to create three scripts from the one script that was originally recorded.
- The START script contains only the <VERSION> and <ALLOCATE> tags.
- The BIGDATA script contains the <VERSION> tag, and the APPC verb tags are repeatedly sent to the application.
- The FINISH script contains only the <VERSION>, <OUTBOUND>, <DEALLOCATE>, and </OUTBOUND> tags.
This example causes the contents of the BIGDATA script to be sent to the CICSA application 1000 times. To successfully accomplish this, the BIGDATA script must contain APPC verbs in a sequence that the application can understand and process repeatedly.
JCL to Play Back One Lengthened APPC Conversation
SCRIPT(START)
SCRIPT(BIGDATA) REPEAT(1000)
SCRIPT(FINISH)
Example 5: Play back two related APPC conversations
This example is designed to test an application that uses two physical APPC conversations to support a single, “logical” conversation. Each partner in the application uses one of the conversations as a “SEND” side and the other conversation as a “RECEIVE” side. This technique simulates a “full-duplex” conversation, where each side of the conversation is always able to send information without waiting for permission from the other side.
Because two physical conversations (the two scripts) are related by logic within the partner application, Performance Test for Mainframe Servers must adhere to the time stamps in each script so that one participant of the logical conversation does not get ahead of the other. The TIMESYNC parameter on the ALLOCATE statements tells Performance Test for Mainframe Servers to send data from the scripts in the order shown by the time stamps. The TIMESYNC parameter must appear on each ALLOCATE (or ACCEPT) statement that participates in this cross-script sequencing.
JCL to Play Back Two Related APPC Conversations
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) TIMESYNC
SCRIPT(CICSSND)
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) TIMESYNC
SCRIPT(CICSRCV)
Example 6: Play back APPC conversations started in various ways
This example is designed to demonstrate many of the timing parameters available for APPC scripts and to explain the effects. The parameters we describe are:
- USESTIME
- COUNT
- REPEAT
- SYNCH
- STIME
- LOGD
- STARTDLY
- THOPT.
The USESTIME parameter on the CONTROL statement causes Performance Test for Mainframe Servers to start the ALLOCATE statements at the time interval indicated by the STIME parameter, which is on the ALLOCATE statement.
The ALLOCATE statement with the lowest STIME value is started when the playback job is started. The ALLOCATE statement that has the next higher STIME value is started after waiting the amount of time indicated by the difference in STIME values. An ALLOCATE statement without an STIME parameter is started as soon as the playback job starts.
A description of each ALLOCATE statement follows the following example.
JCL to Play Back Several APPC Conversations Started in Various Ways
*
* Allocate 1
*
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) COUNT(10) SYNCH -
STIME(‘2006/07/19_12:00:00.000000’)
SCRIPT(CICS1)
*
* Allocate 2
*
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) COUNT(10) LOGD(3) -
STIME(‘2006/07/19_12:05:00.000000’)
SCRIPT(CICS1)
*
* Allocate 3
*
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) REPEAT(5) THOPT(2)
SCRIPT(CICS1)
*
* Allocate 4
*
ALLOCATE SENDER(HS620001) RECEIVER(CICSA) COUNT(100) REPEAT(5) STARTDLY(30)
SCRIPT(CICS1)
Allocate 1
The COUNT(10) parameter on ALLOCATE 1 causes ten conversations to start at once, as soon as the STIME value permits. Because the SYNCH parameter is supplied, those ten conversations do not run at full speed, but instead run at the speed of the “slowest” conversation.
Performance Test for Mainframe Servers sends the first SEND_DATA verb in each of the ten conversations at the same instant. If a response is expected from the application, the second SEND_DATA verb in each conversation is not issued until the application issues its response to all ten conversations. Each subsequent verb that Performance Test for Mainframe Servers issues is sent at the same instant for all ten conversations (after waiting for the ten responses from the application).
This technique for keeping all data sent from Performance Test for Mainframe Servers in step across multiple conversations is most useful in stress testing individual parts of an application program. The SYNCH parameter ensures that the ten running application instances all receive their data from Performance Test for Mainframe Servers at the same time.
Allocate 2
This ALLOCATE statement starts five minutes after the first ALLOCATE statement because its STIME value is five minutes later. The COUNT(10) parameter specifies that ten conversations are to start and the LOGD(3) parameter tells Performance Test to start them three seconds apart. After the conversations start, they run at full speed.
Allocate 3
This ALLOCATE statement starts as soon as the playback job is started because no STIME parameter is present. The REPEAT(5) parameter tells Performance Test for Mainframe Servers to start the five conversations one at a time, each new conversation starting after the previous one has ended.
After a conversation starts, the THOPT(2) parameter tells Performance Test for Mainframe Servers to send data at the same time intervals as the original recording. This is controlled by the time stamps found within the script.
Performance Test for Mainframe Servers does not have control over the speed of the partner application’s response, only the speed that the data is sent to the partner.
Allocate 4
This ALLOCATE statement starts thirty seconds after the playback job is started due to the presence of the STARTDLY(30) parameter. The COUNT(100) parameter indicates that 100 conversations start simultaneously. Those conversations run at full speed, affected by system resources. As soon as one conversation ends, a new conversation starts in its place, a total of five times. This ALLOCATE statement causes 500 conversations to run.
APPC data-driven testing example using REXX
This section illustrates data-driven testing with a series of APPC conversations that together form a complete “business transaction”. The transaction in this example includes three APPC conversations. The first, generates a unique record key that the subsequent conversations use to retrieve and process data. To ensure a successful testing:
- The conversations must be played back in the correct sequence and each conversation must be completed before the next begins.
- The record key recorded in the scripts must be replaced with the key that is generated by the server during playback.
Review the scripts for a thorough understanding of the business transaction’s data flow (next), then learn how to:
- Extract the information generated by the server that is used in all of the conversations, Extract the Key.
- Share the extracted information with all of the scripts. This requires passing the information to and retrieving it from shared storage, Share the Key.
- Replace the recorded information with the stored information during each iteration of the playback, Replace the Key.
- Alter the initial request string during each iteration of playback to exercise the application with unique requests, Alter the Request String.
- Play back the script serially to ensure a successful playback, and play back the script multiple times to stress or volume test the application, Play Scripts Serially and Concurrently.
Review the scripts
The business transaction sited in this example is comprised of three APPC conversations, each using information from the previous conversation.
Performance Test for Mainframe Servers creates a separate script for each recorded APPC conversation. It gives each script a unique name based on prefix and suffix specified on the APPC - Script Datasets screen. However, following the example is easier if the scripts have meaningful names. Therefore, the scripts are referred to as:
- REQUEST shown in Recorded REQUEST Script
The client sends a request string to a CICS server. The CICS server transaction stores the request internally and returns a unique key to the client. - ADDDATA shown in Recorded ADDDATA Script
The client sends the key returned by the REQUEST conversation to a second CICS server transaction, which uses the key to retrieve the stored request and add a timestamp to the request. The server returns the modified request to the client and stores a copy of the request internally for future processing. - PROCESS shown in Recorded PROCESS Script
The client sends the same key to a third CICS server transaction. The server uses the passed key to retrieve the request string (signon ID+timestamp). It then destroys the internal store, processes the request, and delivers the results to the client. Processing results in a reversed request string.
The activity was recorded from the client perspective. Therefore, “Outbound” represents flows from the client to the CICS server transactions. “Inbound” represents flows into the client from the server.
Recorded REQUEST Script
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.523225' FTIME='2006/07/21_09:51:00.614087',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
<CONTENT> 00000004 shows the initial request coming from the client.
<CONTENT> 00000006 shows the unique key that the server generated and returned (HPER045C).
Recorded ADDDATA Script
<DETAIL COMBINED='*'>
<ALLOCATE TPNAME=H4M SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.617627' FTIME='2006/07/21_09:51:00.763590',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.617627
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.617627
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.763590
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER000109:51:01
<TIME>2006/07/21_09:51:00.763590
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
<CONTENT> 00000002 shows the key, which was initially returned from the server in the REQUEST transaction, being sent by the client to the CICS server to retrieve the request record.
<CONTENT> 00000004 shows the server’s response, which is the initial request string concatenated with a timestamp suffix.
Recorded PROCESS Script
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.768107
<ALLOCATE TPNAME=H4T SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.768107' FTIME='2006/07/21_09:51:00.921482',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.768107
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.768107
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.921482
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 0000000410:15:901000REVEROF NOTREVE
<TIME>2006/07/21_09:51:00.921482
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
<CONTENT> 00000002 shows the REQUEST key again being forwarded to the CICS server by the client to request processing.
<CONTENT> 00000004 shows the processed data being returned from the server, that is, the reversed concatenated request string.
Extract the key
Playing back the testing scripts initiates a new business transaction, which causes the server to generate a new key. Propagate the newly generated key through all of the scripts, for each iteration of playback, to prevent the application from producing an error and playback from failing.
Use the following Performance Test for Mainframe Servers REXX variables to extract the newly generated key:
- APPC_ACTUAL — Returns the content of received APPC data.
- APPC_ACTUAL_LENGTH — Returns the length of the received APPC data.
Performance Test for Mainframe Servers destroys the contents of these variables when the conversation terminates (indicated with the <DEALLOCATE> tag), so create your own variables that assume the values of the REXX variables. For example, actual_data = APPC_ACTUAL.
In the <INBOUND> section of the REQUEST script, after the <SEND_DATA> and its associated <CONTENT> tag, insert the REXX APPC variable assignments and a “SAY” instruction to present the actual data and the actual data length in the job log.
The following figure shows the modified REQUEST script. Additions are indicated with bold text.
REQUEST Script with Performance Test for Mainframe Servers REXX Variables
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.523225' FTIME='2006/07/21_09:51:00.614087',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
actual_data = APPC_ACTUAL
actual_data_length = APPC_ACTUAL_LENGTH
say “APPC actual data is:” APPC_ACTUAL “Length:” APPC_ACTUAL_LENGTH
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Share the key
Sharing the extracted key is the next step in replacing the key that is recorded in the scripts with the newly generated key. This requires:
- Adding logic to the REQUEST script to pass the extracted key to a common storage area.
- Adding logic to the ADDDATA and PROCESS scripts to retrieve the key from the shared area.
To share the key:
- Add the USERDATA DD statement to the JCL to define the amount of shared storage. For example,
//USERDATA DD DUMMY,BUFNO=1,BUFL=800BUFNO is the number of buffers. BUFL is the length of each buffer. BUFNO multiplied by BUFL equals the total bytes of storage defined.
- Copy the HSGET and HSPUT routines from the Performance Test samples library, SQQFSAMP, into the data set containing the APPC scripts.
- Insert an HSPUT() call, without parameters, into the beginning of the REQUEST script, just after the <VERSION> and <DETAIL> tags, to initialize the shared area. Include an IF statement to validate successful completion of the call based on the return code. A return code of 1 indicates success. Use the REXX EXIT instruction to terminate playback if the call fails.
The bold text at the top of REQUEST Script with Key Sharing Logic shows this logic.
- Insert another HSPUT call at the end of the REQUEST script, after the closing </INBOUND> tag, to copy the extracted key to the stored area. This time include the following parameters:
- actual_data — Returns the extracted key value.
- offset — Defines where in the shared area to begin writing the key value. These scripts can be played back multiple times concurrently. If the offset is defined as a static value, the routine overwrites the key each time the group of scripts plays back. Use the Performance Test PORT variable to define a unique offset. Performance Test for Mainframe Servers assigns a unique port number to each thread in an APPCGRP replay. For example, if three instances of the group of scripts play back concurrently (COUNT(3)), the port in the first instance is one, the second is two, and the third is three. Since the key is eight bytes, set the offset=PORT*8. This also preserves the first eight bytes for Performance Test for Mainframe Servers internal use.
Again, include an IF statement to validate successful completion of the HSPUT call. Remember, all successful HSPUT calls that occur after initialization produce a return code of zero, so set the IF condition to RETC>0. Use the EXIT instruction to terminate playback if the call fails. The bold text at the bottom as displayed in the following figure shows this logic.
REQUEST Script with Key Sharing Logic
<DETAIL COMBINED='*'>
RETC = HSPUT()
IF RETC>1 THEN
DO
SAY “Initial HSPUT failed with return code:” retc
EXIT
END
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.523225' FTIME='2006/07/21_09:51:00.614087',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
actual_data = APPC_ACTUAL
actual_data_length = APPC_ACTUAL_LENGTH
say “APPC actual data is:” APPC_ACTUAL “Length:” APPC_ACTUAL_LENGTH
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
offset = PORT*8
RETC = HSPUT(actual_data,offset)
IF retc>0 THEN
DO
SAY “HSPUT storage of data on port” PORT “failed. Return code:” RETC
EXIT
END
- Insert an HSPUT() call, without parameters, into the beginning of the ADDDATA and PROCESS scripts, just after the <VERSION> and <DETAIL> tags, to verify that the shared area exists. Include an IF statement to validate successful completion of the call based on a return code of zero. Use the REXX EXIT instruction to terminate playback if the call fails.
The bold text at the top of ADDDATA Script with Key Sharing Logic and PROCESS Script with Key Sharing Logic shows this logic.
- Below the HSPUT() call in the ADDDATA and PROCESS scripts, insert HSGET(offset,8) to retrieve the key from shared storage.
- “offset” indicates where to find the key in the storage area. Provide the same definition for offset here as was defined in storing the key (offset=PORT*8).
- “8” indicates the length of the data to retrieve.
Assign a variable to the HSGET(offset,8) value to use for validation. HSGET returns a null string if the call fails. Using the variable assigned to the HSGET value, create an IF statement that compares the length of the returned key to zero. Include a SAY instruction:
- To print a failure message in the job log if the length is zero. Terminate the playback with the REXX EXIT instruction.
- To print the returned key value and length in the job log if the length is not zero.
Finally, use the REXX substring instruction to ensure the returned key is eight characters long.
The bold text beneath the second asterisk (*) in the following figures shows this logic.
ADDDATA Script with Key Sharing Logic
<DETAIL COMBINED='*'>
*
RETC = HSPUT()
IF RETC>0 THEN
DO
SAY “ADDDATA initialization of HSPUT failed with return code:” RETC
EXIT
END
*
offset = PORT*8
key_field = HSGET(offset,8)
IF LENGTH(key_field) = 0 THEN
DO
SAY “ADDDATA HSGET retrieval of data failed”
EXIT
END
ELSE
SAY “Retrieved HSGET data is:” key_field “Length:” LENGTH(key_field)
key=substr(key_field,1,8)
<ALLOCATE TPNAME=H4M SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.617627' FTIME='2006/07/21_09:51:00.763590',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.617627
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.617627
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.763590
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER000109:51:01
<TIME>2006/07/21_09:51:00.763590
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
PROCESS Script with Key Sharing Logic
<DETAIL COMBINED='*'>
*
RETC = HSPUT()
IF RETC>0 THEN
DO
SAY “ADDDATA initialization of HSPUT failed with return code:” RETC
EXIT
END
*
offset = PORT*8
key_field = HSGET(offset,8)
IF LENGTH(key_field) = 0 THEN
DO
SAY “ADDDATA HSGET retrieval of data failed”
EXIT
END
ELSE
SAY “Retrieved HSGET data is:” key_field “Length:” LENGTH(key_field)
key=substr(key_field,1,8)
<ALLOCATE TPNAME=H4M SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.617627' FTIME='2006/07/21_09:51:00.763590',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.617627
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.617627
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.763590
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER000109:51:01
<TIME>2006/07/21_09:51:00.763590
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Replace the key
Now it is time to add logic to replace the recorded key with the newly generated key. Insert the Performance Test REPLACE verb in the <OUTBOUND> section of the ADDDATA and PROCESS scripts, after the <TIME> tag and before the <SEND_DATA> tag. This verb has two parameters:
- FIELD(offset,data) — “offset” indicates where to begin replacing data. Since the only data being sent is the key, set “offset” to 0 (zero) to replace data starting with the first byte. The “data” value is the string or REXX variable that replaces the specified information. In this case, set “data” to “key” as that is the variable assigned to the retrieved key by the substring instruction.
- TYPE — Stipulates alteration of next or all subsequent <SEND_DATA> <CONTENT> values. In this example, the next <SEND_DATA> is the only value requiring data replacement, so set TYPE=ONE.
See <REPLACE> Tag for more information. The following figure show this logic in bold text.
ADDDATA Script with Key Replacement Logic
<DETAIL COMBINED='*'>
*
RETC = HSPUT()
IF RETC>0 THEN
DO
SAY “ADDDATA initialization of HSPUT failed with return code:” RETC
EXIT
END
*
offset = PORT*8
key_field = HSGET(offset,8)
IF LENGTH(key_field) = 0 THEN
DO
SAY “ADDDATA HSGET retrieval of data failed”
EXIT
END
ELSE
SAY “Retrieved HSGET data is:” key_field “Length:” LENGTH(key_field)
key=substr(key_field,1,8)
<ALLOCATE TPNAME=H4M SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.617627' FTIME='2006/07/21_09:51:00.763590',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.617627
<REPLACE FIELD=(0,key) TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.617627
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.763590
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER000109:51:01
<TIME>2006/07/21_09:51:00.763590
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
PROCESS Script with Key Replacement Logic
<DETAIL COMBINED='*'>
*
RETC = HSPUT()
IF RETC>0 THEN
DO
SAY “PROCESS initialization of HSPUT failed with return code:” RETC
EXIT
END
*
offset = PORT*8
key_field = HSGET(offset,8)
IF LENGTH(key_field) = 0 THEN
DO
SAY “PROCESS HSGET retrieval of data failed”
EXIT
END
ELSE
SAY “Retrieved HSGET data is:” key_field “Length:” LENGTH(key_field)
key=substr(key_field,1,8)
<TIME>2006/07/21_09:51:00.768107
<ALLOCATE TPNAME=H4T SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.768107' FTIME='2006/07/21_09:51:00.921482',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.768107
<REPLACE FIELD(0,key) TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000002HPER045C
<TIME>2006/07/21_09:51:00.768107
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.921482
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 0000000410:15:901000REVEROF NOTREVE
<TIME>2006/07/21_09:51:00.921482
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Alter the request string
The group of scripts forming the business transaction plays back successfully at this point. However, the scripts, as they exist, repeatedly execute the same request: EVERTON FOREVER0000.
Use the Performance Test:
- REPLACE verb to modify the request string each time the group of scripts play back.
- REXX variables PORT and GRPCYCLE to provide a unique value for request string data replacement. As previously discussed, PORT returns the value of the COUNT playback parameter — that is, the unique number assigned to each thread in the APPCGRP replay. GRPCYCLE returns the value of the REPEAT playback parameter, which denotes the iteration of playback.
In the REQUEST script:
- Just above the <OUTBOUND> block, insert a variable assignment based on the PORT and GRPCYCLE variables. Use standard REXX functions to identify the portion of the PORT and GRPCYCLE counts to return. In this case, the two digits from the right of each count. Indicate a character to pad the returned value with if the value is not two digits. This example pads the value on the left with zeros. Concatenate the returned values with the REXX concatenation operator || to create a unique four-digit value.
- In the <OUTBOUND> block, after the <TIME> tag, insert the Performance Test REPLACE verb with an “offset” value of 15 and “data” value of the variable assigned to the PORT||GRPCYCLE concatenation.
This results in a unique request string for each instance and iteration of the playback. For example, if you play back the script twice concurrently and repeat the playback three times, the request string increments as follows:
- EVERTON FOREVER0101
- EVERTON FOREVER0201
- EVERTON FOREVER0102
- EVERTON FOREVER0202
- EVERTON FOREVER0103
- EVERTON FOREVER0203
The bold text in the following figure shows this logic.
REQUEST Script with Request Modification Logic
<DETAIL COMBINED='*'>
RETC = HSPUT()
IF RETC>1 THEN
DO
SAY “Initial HSPUT failed with return code:” retc
EXIT
END
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127,
LOGMODE=#INTER TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE,
STIME='2006/07/21_09:51:00.523225' FTIME='2006/07/21_09:51:00.614087',
CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567 LUWINST=,
'0AB30B1787D5'X LUWSEQ='0001'X>
newiter=right(PORT,2,’0’)||right(GRPCYCLE,2,’0’)
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<REPLACE FIELD=(15,newiter) TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
actual_data = APPC_ACTUAL
actual_data_length = APPC_ACTUAL_LENGTH
say “APPC actual data is:” APPC_ACTUAL “Length:” APPC_ACTUAL_LENGTH
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
offset = PORT*8
RETC = HSPUT(actual_data,offset)
IF retc>0 THEN
DO
SAY “HSPUT storage of data on port” PORT “failed. Return code:” RETC
EXIT
END
Play scripts serially and concurrently
Performance Test for Mainframe Servers offers three input statements for designating which scripts (conversations) to play back and how to play them back:
- ALLOCATE — Use this statement to play back a single APPC conversation with Performance Test for Mainframe Servers initiating the conversation.
- ACCEPT — Use this statement to play back a single APPC conversation with Performance Test for Mainframe Servers receiving the conversation.
- APPCGRP — Use this statement to play multiple APPC conversations back.
See APPC Unattended Playback Statements, for more information.
All three of these statements offer the COUNT and REPEAT parameters to play the scripts back multiple times for stress or volume testing.
- COUNT(n) plays back the scripts within the ALLOCATE/ACCEPT/APPCGRP n times concurrently.
- REPEAT(n) plays the scripts within the ALLOCATE/ACCEPT/APPCGRP n times, one after the other.
Use them together to play multiple threads repeatedly. For example, COUNT(2) REPEAT(3), plays back two instances of the script at the same time, three times in a row. Couple this with the APPCGRP statement to repeatedly play back multiple threads of a series of APPC conversations, such as the business transaction described in this example.
The rest of this discussion provides an example of the playback control statements and JCL necessary to repeatedly play back multiple threads of this business transaction. It also shows the resulting job logs.
Create playback control statements for the business transaction
Manually build playback control statements or generate a conversation log during script creation to use as the SYSIN for the job.
In the conversation log, Performance Test for Mainframe Servers creates a separate ALLOCATE statement for each APPC conversation. Generating the log is the easiest method if you need to play the conversations back concurrently. However, if you need to play multiple conversations back serially, manually building the statements is less work than modifying the log.
APPC Conversation Log for Example Scripts shows the conversation log generated for the scripts in this example. Control Statements to Play Scripts Back Serially shows the playback control statements necessary to play the scripts back serially, which is required to complete the business transaction successfully.
In this example, SENDER and RECEIVER are the only common parameters between the APPCGRP statement and the generated ALLOCATE statements. This is due to the statement hierarchy. That is, the parameters defined on the ALLOCATE or APPCGRP statement override the parameters recorded in the scripts under the given statement. Since the scripts within the APPCGRP statement contain information from different conversations, the control parameters may be different from script to script. For example, the TPNAME for each conversation is different. Performance Test retrieves the necessary information from the scripts during playback.
In the conversation log:
- The SENDER and RECEIVER values reflect the client and server VTAM LU names. During playback, Performance Test assumes the role of the sender or the receiver depending on the selected playback control statement and the SENDER and RECEIVER parameters. For example, if you want Performance Test to initiate the conversation, use the ALLOCATE or APPCGRP statement and specify Performance Test’ VTAM LU name on the SENDER parameter. If you want Performance Test to receive the conversation, use the ACCEPT or APPCGRP statement and specify the appropriate LU name on the RECEIVER parameter.
- The script names reflect the names generated by Performance Test. In this example, the script members were renamed for easy recognition. Make sure the values specified in the SCRIPT statements reflect the actual member names as shown in manually built control statements (Control Statements to Play Scripts Back Serially).
The manually built playback control information (Control Statements to Play Scripts Back Serially) also includes a:
- CONTROL statement with the MSGFORM parameter, which prints timestamps in the job log.
- COUNT parameter with a value of 2 on the APPCGRP statement. This initiates two threads of the business transaction. That is, it plays the same group of scripts twice concurrently.
- REPEAT parameter with a value of 2 on the APPCGRP statement. This causes playback of the two threads to repeat a second time.
APPC Conversation Log for Example Scripts
* LOG STARTED ON 2006/12/18 AT 17:05:10
* DESC:
*
* ALLOCATE NUMBER(1)
*
ALLOCATE TPNAME(H4S) SENDER(USCWXN01.H01AC079) RECEIVER(USCWXN01.H01AC127)-
LOGMODE(#INTER) TYPE(MAPPED) SYNCLVL(NONE) SECURITY(NONE)-
STIME('2006/09/18_08:50:59.713241') FTIME('2006/09/18_08:50:59.804103')-
CONVCORR('-AD1') LUWNAME(USCWXN01.TCW00567) LUWINST('0AB30B1787D5'X)-
LUWSEQ('0001'X)
SCRIPT(TST00002)
*
* ALLOCATE NUMBER(2)
*
*
ALLOCATE TPNAME(H4M) SENDER(USCWXN01.H01AC079) RECEIVER(USCWXN01.H01AC127)-
LOGMODE(#INTER) TYPE(MAPPED) SYNCLVL(NONE) SECURITY(NONE)-
STIME('2006/09/18_08:50:59.807643') FTIME('2006/09/18_08:50:59.953606')-
CONVCORR('-AD1') LUWNAME(USCWXN01.TCW00567) LUWINST('0AB30B1787D5'X)-
LUWSEQ('0001'X)
SCRIPT(TST00003)
*
* ALLOCATE NUMBER(3)
*
*
ALLOCATE TPNAME(H4T) SENDER(USCWXN01.H01AC079) RECEIVER(USCWXN01.H01AC127)-
LOGMODE(#INTER) TYPE(MAPPED) SYNCLVL(NONE) SECURITY(NONE)-
STIME('2006/09/18_08:50:59.958123') FTIME('2006/09/18_08:51:00.111498') -
CONVCORR('-AD1')LUWNAME(USCWXN01.TCW00567) LUWINST('0AB30B1787D5'X)-
LUWSEQ('0001'X)
SCRIPT(TST00004)
*
* LOG FINISHED ON 2006/12/18 AT 17:05:11
*
******************************** Bottom of Data ********************************
Control Statements to Play Scripts Back Serially
CONTROL MSGFORM
APPCGRP SENDER(UXCWXN01.H01APPCP) RECEIVER(USCWXN01.H01AC127) COUNT(2) REPEAT(2)
SCRIPT(REQUEST)
SCRIPT(ADDDATA)
SCRIPT(PROCESS)
******************************** Bottom of Data ********************************
Create JCL to play back the business transaction
The following illustration shows standard Performance Test for Mainframe Servers playback JCL with the addition of the USERDATA DD defining the shared storage area for the key replacement logic depicted in this example. See Step 5. Submit the Batch Job, for all other DD statement definitions. This sample also shows in-line control statements. You can store them in a data set, if you like, and reference the data set name on the SYSIN DD.
JCL for the Example Business Transaction
//STEPLIB DD DSN=SYS2.COMPWARE.QQF800.SQQFLOAD,DISP=SHR
//SYSLIB DD DSN=USR2503.APPC.SCRIPT,DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//USERDATA DD DUMMY,BUFNO=1,BUFL=800
//SYSIN DD *
CONTROL MSGFORM
*
* ALLOCATE NUMBER(1)
*
APPCGRP SENDER(USCWXN01.H01APPCP) RECEIVER(USCWXN01.H01AC127)-
COUNT(1)
SCRIPT(REQUEST)
SCRIPT(ADDDATA)
SCRIPT(PROCESS)
Review the playback job logs
This section shows the job logs resulting from a single thread, single iteration playback; a multiple thread, single iteration playback; and a multiple thread, multiple iteration playback.
Job Log for a Single Thread, Single Iteration Playback shows the job log for a single thread, single iteration playback of the example business transaction.
The REXX SAY statements generated by the REQUEST script show the key (HPER055C) generated by the CICS Server at replay time.
The SAY statements generated by the ADDDATA script show that the:
- Correct key value was retrieved by HSGET.
- Original request was returned with the timestamp concatenation, which verifies that the second CICS Server transaction completed successfully.
- Original request string was successfully updated with the concatenated, two-digit PORT and GRPCYCLE values (0101). If you recall, the first two digits reflect the count value (thread) and the last two reflect the repeat value (iteration).
The SAY statements generated by the PROCESS script show that the:
- HSGET correctly retrieved the replay key.
- Request string was returned in reverse, which verifies that the third CICS server transaction completed successfully.
Job Log for a Single Thread, Single Iteration Playback
10:21:25 GROUP MSTR PORT MSTR EHSB910I REPLAY STARTING: 09/18/06 AT 10:21:25
10:21:25 GROUP MSTR PORT MSTR EHSB000I ALL PORTS ATTACHED
10:21:25 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:21:26 GROUP 0001 PORT 0001 APPC actual data is: HPER055C Length: 8
10:21:26 GROUP 0001 PORT 0001 Actual data is: HPER055C Length: 8
10:21:26 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT REQUEST
10:21:26 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:21:26 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER055C Length: 8
10:21:26 GROUP 0001 PORT 0001 APPC actual data: EVERTON FOREVER010110:21:27 Length: 27
10:21:26 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT ADDDATA
10:21:26 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:21:26 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER055C Length: 8
10:21:26 GROUP 0001 PORT 0001 PROCESS data returned: 72:12:011010REVEROF NOTREVE Lengt
h: 27
10:21:26 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT PROCESS
10:21:26 GROUP 0001 PORT 0001 EHSB024I BEING TERMINATED
10:21:26 GROUP 0001 PORT 0001 EHSB003I PORT TERMINATED
10:21:26 GROUP MSTR PORT MSTR EHSB004I GROUP 0001 TERMINATED
10:21:26 GROUP MSTR PORT MSTR EHSB020I ALL PORTS TERMINATED
Now examine the following figure to see how initiating a second thread (increasing the COUNT parameter value to two) impacts the job log. Notice that the first two digits of the request string suffix reflect the playback thread. See how they match the reported PORT number.
Job Log for a Multiple Thread, Single Iteration Playback
10:24:24 GROUP MSTR PORT MSTR EHSB910I REPLAY STARTING: 09/18/06 AT 10:24:24
10:24:24 GROUP MSTR PORT MSTR EHSB000I ALL PORTS ATTACHED
10:24:24 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0002 APPC actual data is: HPER062C Length: 8
10:24:24 GROUP 0001 PORT 0002 Actual data is: HPER062C Length: 8
10:24:24 GROUP 0001 PORT 0001 APPC actual data is: HPER063C Length: 8
10:24:24 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT REQUEST
10:24:24 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0001 Actual data is: HPER063C Length: 8
10:24:24 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT REQUEST
10:24:24 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER062C Length: 8
10:24:24 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER063C Length: 8
10:24:24 GROUP 0001 PORT 0001 APPC actual data: EVERTON FOREVER010110:24:25 Length: 27
10:24:24 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT ADDDATA
10:24:24 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0002 APPC actual data: EVERTON FOREVER020110:24:25 Length: 27
10:24:24 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT ADDDATA
10:24:24 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:24:24 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER063C Length: 8
10:24:24 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER062C Length: 8
10:24:24 GROUP 0001 PORT 0001 PROCESS data returned: 52:42:011010REVEROF NOTREVE Lengt
h: 27
10:24:24 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT PROCESS
10:24:24 GROUP 0001 PORT 0001 EHSB024I BEING TERMINATED
10:24:24 GROUP 0001 PORT 0002 PROCESS data returned: 52:42:011020REVEROF NOTREVE Lengt
h: 27
10:24:24 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT PROCESS
10:24:24 GROUP 0001 PORT 0002 EHSB024I BEING TERMINATED
10:24:24 GROUP 0001 PORT 0001 EHSB003I PORT TERMINATED
10:24:24 GROUP 0001 PORT 0002 EHSB003I PORT TERMINATED
10:24:24 GROUP MSTR PORT MSTR EHSB004I GROUP 0001 TERMINATED
10:24:24 GROUP MSTR PORT MSTR EHSB020I ALL PORTS TERMINATED
The following figure shows a truncated job log from a multiple thread, multiple iteration playback. Each iteration of the APPCGRP REPEAT increments the supplied GRPCYCLE REXX variable, starting at 1 on the first iteration. Examine the job log to see how using GRPCYCLE makes each request unique across business transaction iterations.
This time, the LOGD, or Logon Delay, parameter was added to the APPCGRP statement to offset the start time of each thread. In this case, the parameter is LOGD(1), or one second. The job log shows that port (Thread) two started one second after port (Thread) one.
Job Log for a Multiple Thread, Multiple Iteration Playback
10:27:41 GROUP MSTR PORT MSTR EHSB910I REPLAY STARTING: 09/18/06 AT 10:27:41
10:27:41 GROUP 0001 PORT 0002 EHSB054I START SYNCHRONIZATION AND/OR DELAY REQUESTED
10:27:41 GROUP MSTR PORT MSTR EHSB000I ALL PORTS ATTACHED
10:27:41 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:27:41 GROUP 0001 PORT 0001 APPC actual data is: HPER072C Length: 8
10:27:41 GROUP 0001 PORT 0001 Actual data is: HPER072C Length: 8
10:27:41 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT REQUEST
10:27:41 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:27:41 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER072C Length: 8
10:27:41 GROUP 0001 PORT 0001 APPC actual data: EVERTON FOREVER010110:27:42 Length: 27
10:27:41 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT ADDDATA
10:27:41 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER072C Length: 8
10:27:42 GROUP 0001 PORT 0001 PROCESS data returned: 24:72:011010REVEROF NOTREVE Length: 27
10:27:42 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT PROCESS
10:27:42 GROUP 0001 PORT 0001 EHSB024I BEING TERMINATED
10:27:42 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0001 APPC actual data is: HPER075C Length: 8
10:27:42 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT REQUEST
10:27:42 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER075C Length: 8
10:27:42 GROUP 0001 PORT 0001 APPC actual data: EVERTON FOREVER010210:27:42 Length: 27
10:27:42 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT ADDDATA
10:27:42 GROUP 0001 PORT 0001 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0001 retrieved HSGET data is: HPER075C Length: 8
10:27:42 GROUP 0001 PORT 0001 PROCESS data returned: 24:72:012010REVEROF NOTREVE Length: 27
10:27:42 GROUP 0001 PORT 0001 EHSB019I COMPLETED SCRIPT PROCESS
10:27:42 GROUP 0001 PORT 0001 EHSB024I BEING TERMINATED
10:27:42 GROUP 0001 PORT 0001 EHSB003I PORT TERMINATED
10:27:42 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0002 APPC actual data is: HPER078C Length: 8
10:27:42 GROUP 0001 PORT 0002 Actual data is: HPER078C Length: 8
10:27:42 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT REQUEST
10:27:42 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER078C Length: 8
10:27:42 GROUP 0001 PORT 0002 APPC actual data: EVERTON FOREVER020110:27:43 Length: 27
10:27:42 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT ADDDATA
10:27:42 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER078C Length: 8
10:27:42 GROUP 0001 PORT 0002 PROCESS data returned: 34:72:011020REVEROF NOTREVE Length: 27
Job Log for a Multiple Thread, Multiple Iteration Playback (Continued)
10:27:42 GROUP 0001 PORT 0002 EHSB024I BEING TERMINATED
10:27:42 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT REQUEST PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0002 APPC actual data is: HPER081C Length: 8
10:27:42 GROUP 0001 PORT 0002 Actual data is: HPER081C Length: 8
10:27:42 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT REQUEST
10:27:42 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT ADDDATA PLAY OUTBOUND
10:27:42 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER081C Length: 8
10:27:43 GROUP 0001 PORT 0002 APPC actual data: EVERTON FOREVER020210:27:43 Length: 27
10:27:43 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT ADDDATA
10:27:43 GROUP 0001 PORT 0002 EHSB011I BEGINNING SCRIPT PROCESS PLAY OUTBOUND
10:27:43 GROUP 0001 PORT 0002 retrieved HSGET data is: HPER081C Length: 8
10:27:43 GROUP 0001 PORT 0002 PROCESS data returned: 34:72:012020REVEROF NOTREVE Length: 27
10:27:43 GROUP 0001 PORT 0002 EHSB019I COMPLETED SCRIPT PROCESS
10:27:43 GROUP 0001 PORT 0002 EHSB024I BEING TERMINATED
10:27:43 GROUP 0001 PORT 0002 EHSB003I PORT TERMINATED
10:27:43 GROUP MSTR PORT MSTR EHSB004I GROUP 0001 TERMINATED
APPC data-driven testing example using playback tables
This section illustrates data-driven testing with a series of APPC conversations described in the previous section, APPC Data-Driven Testing Example Using REXX.
However, this section will describe using playback tables instead of using REXX code within the APPC. The benefit of using Playback tables over REXX is much faster processing time.
Playback tables
Playback tables are defined as follows:
TABLEDEF PORTS(n) DATADSN(dataset_name) LOGDSN(dataset_name)
TABLE ID(member_name) REPEATS(n) DATALEN(n) DATAIN LOG INIT(NULL|SPACE|ZERO)
TABLE ID(member_name) REPEATS(n) DATALEN(n) DATAIN
TABLE ID(member_name) REPEATS(n) DATALEN(n) LOG
TABLE ID(member_name) REPEATS(n) DATALEN(n)
For a description of the parameters for TABLEDEF and TABLE see TABLEDEF Statement and TABLE Statement.
Extract the key
When using playback tables, both the <EXTRACT> tag and the <REPLACE> tag are used.
<EXTRACT> Tag
<EXTRACT FIELD=(0,'&SHAREKEY') TYPE=ONE>
<REPLACE> Tag
See <REPLACE> Tag and <EXTRACT> Tag for a description of these tags and their parameters.
Store a shared key
The following figure is an example showing how to store a shared key.
Store a Shared Key
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127, LOGMODE=#INTER
TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE, STIME='2006/07/21_09:51:00.523225'
FTIME='2006/07/21_09:51:00.614087', CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567
LUWINST=, '0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<EXTRACT FIELD=(0,'&SHAREKEY') TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Retrieve a shared key
Store a Shared Key is an example showing how to retrieve a shared key and use the key in a playback.
Retrieve a Shared Key
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.768107
<ALLOCATE TPNAME=H4T SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127, LOGMODE=#INTER
TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE, STIME='2006/07/21_09:51:00.768107'
FTIME='2006/07/21_09:51:00.921482', CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567
LUWINST=, '0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.768107
<REPLACE FIELD=(0,'&SHAREKEY') TYPE=ONE> <== Note '=' missing after FIELD
<SEND_DATA DATATYPE=APPLDATA> and extra space before '&SHAREKEY'
<CONTENT> 00000002HPER045C above errors were corrected.
<TIME>2006/07/21_09:51:00.768107
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.921482
<EXTRACT FIELD=(0,'&REVERSED') TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 0000000410:15:901000REVEROF NOTREVE
<TIME>2006/07/21_09:51:00.921482
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Alter the request string
In the previous section using REXX, REXX code is used in the script.
When using tables, the request string is prepared in the TABLEDSN using the DATAIN keyword. Script Being Played Back is an example of how to prepare a request string.
Request String Using Tables
/* YOU MAY REASSIGN HLQ with SOMETHING OTHER THAN SYSUID */
DDN_04CHAR = HLQ || '.BOC.TABLE.DATA(REQUEST)'
DDN_19CHAR = HLQ || '.BOC.TABLE.DATA(REQUESTX)'
ADDRESS TSO
'ALLOCATE DATASET('''DDN_04CHAR''') SHR FILE(RDM04)'
'ALLOCATE DATASET('''DDN_19CHAR''') SHR FILE(RDM19)'
Ports = 2
Repeats = 05
i=0
DO GRPCYCLE = 1 to Repeats
DO PORT = 1 TO Ports
i = i + 1
A.i = right(PORT,2,'0')||right(GRPCYCLE,2,'0')
B.i = 'EVERTON FOREVER' || A.i
END
END
"EXECIO * DISKW RDM04 (stem A. FINIS)"
"EXECIO * DISKW RDM19 (stem B. FINIS)"
'FREE FILE(RDM04)'
'FREE FILE(RDM19)'
RETURN 0
VIEW USR2503.BOC.TABLE.DATA(REQUEST) - 01.00
Command ===>
****** ******************************* Top of Data *
000001 0101
000002 0201
000003 0102
000004 0202
000005 0103
000006 0203
000007 0104
000008 0204
000009 0105
000010 0215
VIEW USR2503.BOC.TABLE.DATA(REQUESTX) - 01.00
Command ===>
****** ******************************* Top of Data **
000001 EVERTON FOREVER0101
000002 EVERTON FOREVER0201
000003 EVERTON FOREVER0102
000004 EVERTON FOREVER0202
000005 EVERTON FOREVER0103
000006 EVERTON FOREVER0203
000007 EVERTON FOREVER0104
000008 EVERTON FOREVER0204
000009 EVERTON FOREVER0105
000010 EVERTON FOREVER0215
With these files prepared before the APPC playback, the script in the following figure will be played back.
Script Being Played Back
<DETAIL COMBINED='*'>
<TIME>2006/07/21_09:51:00.523225
<ALLOCATE TPNAME=H4S SENDER=USCWXN01.H01AC079, RECEIVER=USCWXN01.H01AC127, LOGMODE=#INTER
TYPE=MAPPED SYNCLVL=NONE SECURITY=NONE, STIME='2006/07/21_09:51:00.523225'
FTIME='2006/07/21_09:51:00.614087', CONVCORR='-AD1' LUWNAME=USCWXN01.TCW00567
LUWINST=, '0AB30B1787D5'X LUWSEQ='0001'X>
<OUTBOUND>
<TIME>2006/07/21_09:51:00.523225
<REPLACE FIELD=(15,'&REQUEST') TYPE=ONE> or This is same as REXX example
<REPLACE FIELD=(0,'&REQUESTX') TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000004EVERTON FOREVER0001
<TIME>2006/07/21_09:51:00.523225
<PREPARE_TO_RECEIVE TYPE=FLUSH>
</OUTBOUND>
<INBOUND>
<TIME>2006/07/21_09:51:00.614087
<EXTRACT FIELD=(0,'&SHAREKEY') TYPE=ONE>
<SEND_DATA DATATYPE=APPLDATA>
<CONTENT> 00000006HPER045C
<TIME>2006/07/21_09:51:00.614087
<DEALLOCATE TYPE=FLUSH LOGDATA=NO>
</INBOUND>
Getting playback information
Variable Data Read from the Table
Command ===>
****** ******************************* Top of Data *
000001 0101
000002 0201
000003 0102
000004 0202
000005 0103
000006 0203
000007 0104
000008 0204
000009 0105
000010 0215
VIEW USR2503.BOC.TABLE.DATA(REQUESTX) - 01.00
Command ===>
****** ******************************* Top of Data **
000001 EVERTON FOREVER0101
000002 EVERTON FOREVER0201
000003 EVERTON FOREVER0102
000004 EVERTON FOREVER0202
000005 EVERTON FOREVER0103
000006 EVERTON FOREVER0203
000007 EVERTON FOREVER0104
000008 EVERTON FOREVER0204
000009 EVERTON FOREVER0105
000010 EVERTON FOREVER0215
In Variable Data Read from the Table, C= refers to the reference counter, which tells how many times it has been used for <REPLACE> and <EXTRACT>. L= refers to the data length for the table. REQUESTX, SHAREKEY, RESPTIME, and REVERSED are table names.
When using tables, key information is written using the LOG keyword. See the following figure for an example of the table definition.
Table Definition Using LOG Keyword
DATADSN(USR2503.BOC.TABLE.DATA) -
LOGDSN(USR2503.BOC.TABLE.LOG)
TABLE ID(REQUEST) REPEATS(05) DATALEN(04) DATAIN LOG
TABLE ID(SHAREKEY) REPEATS(05) DATALEN(08) LOG
TABLE ID(RESPTIME) REPEATS(05) DATALEN(27) LOG
TABLE ID(REVERSED) REPEATS(05) DATALEN(27) LOG
Use the JCL in the following figure to merge and sort three LOG file.
JCL to Merge and Sort Three LOG Files
//SYSOUT DD SYSOUT=*
//*SORTOUT DD SYSOUT=*,DCB=(RECFM=VB,LRECL=130)
//SORTOUT DD DISP=SHR,DSN=USR2503.BOC.TABLE.LOG(SAMPLE1)
//SORTIN DD DISP=SHR,DSN=USR2503.BOC.TABLE.LOG(REQUEST)
// DD DISP=SHR,DSN=USR2503.BOC.TABLE.LOG(SHAREKEY)
// DD DISP=SHR,DSN=USR2503.BOC.TABLE.LOG(RESPTIME)
// DD DISP=SHR,DSN=USR2503.BOC.TABLE.LOG(REVERSED)
//* LOG DATASET IS VARIABLE RECORD
//* THEREFORE, SORT CONTROL LOCATION STARTS AT 5
//* ADD 5 TO REAL DATA LOCATION FOR SORT CONTROL
//SYSIN DD *
SORT FIELDS=(5,26,CH,A)
//
Sample output
The following figure shows sample output from a Sort job after your Playback.
Sample Output
000002 PORT=00001,GRPCYCLE=000001,C=003,L=008,SHAREKEY='HPER117C'
000003 PORT=00001,GRPCYCLE=000001,C=001,L=027,RESPTIME='EVERTON FOREVER010114:31:44'
000004 PORT=00001,GRPCYCLE=000001,C=001,L=027,REVERSED='44:13:411010REVEROF NOTREVE'
000005 PORT=00001,GRPCYCLE=000002,C=001,L=019,REQUESTX='EVERTON FOREVER0102'
000006 PORT=00001,GRPCYCLE=000002,C=003,L=008,SHAREKEY='HPER126C'
000007 PORT=00001,GRPCYCLE=000002,C=001,L=027,RESPTIME='EVERTON FOREVER010214:31:45'
000008 PORT=00001,GRPCYCLE=000002,C=001,L=027,REVERSED='54:13:412010REVEROF NOTREVE'
000009 PORT=00001,GRPCYCLE=000003,C=001,L=019,REQUESTX='EVERTON FOREVER0103'
000010 PORT=00001,GRPCYCLE=000003,C=003,L=008,SHAREKEY='HPER132C'
000011 PORT=00001,GRPCYCLE=000003,C=001,L=027,RESPTIME='EVERTON FOREVER010314:31:48'
000012 PORT=00001,GRPCYCLE=000003,C=001,L=027,REVERSED='84:13:413010REVEROF NOTREVE'
000013 PORT=00001,GRPCYCLE=000004,C=001,L=019,REQUESTX='EVERTON FOREVER0104'
000014 PORT=00001,GRPCYCLE=000004,C=003,L=008,SHAREKEY='HPER138C'
000015 PORT=00001,GRPCYCLE=000004,C=001,L=027,RESPTIME='EVERTON FOREVER010414:31:48'
000016 PORT=00001,GRPCYCLE=000004,C=001,L=027,REVERSED='84:13:414010REVEROF NOTREVE'
000017 PORT=00001,GRPCYCLE=000005,C=001,L=019,REQUESTX='EVERTON FOREVER0105'
000018 PORT=00001,GRPCYCLE=000005,C=003,L=008,SHAREKEY='HPER144C'
000019 PORT=00001,GRPCYCLE=000005,C=001,L=027,RESPTIME='EVERTON FOREVER010514:31:48'
000020 PORT=00001,GRPCYCLE=000005,C=001,L=027,REVERSED='84:13:415010REVEROF NOTREVE'
000021 PORT=00002,GRPCYCLE=000001,C=001,L=019,REQUESTX='EVERTON FOREVER0201'
000022 PORT=00002,GRPCYCLE=000001,C=003,L=008,SHAREKEY='HPER116C'
000023 PORT=00002,GRPCYCLE=000001,C=001,L=027,RESPTIME='EVERTON FOREVER020114:31:44'
000024 PORT=00002,GRPCYCLE=000001,C=001,L=027,REVERSED='44:13:411020REVEROF NOTREVE'
000025 PORT=00002,GRPCYCLE=000002,C=001,L=019,REQUESTX='EVERTON FOREVER0202'
000026 PORT=00002,GRPCYCLE=000002,C=003,L=008,SHAREKEY='HPER125C'
000027 PORT=00002,GRPCYCLE=000002,C=001,L=027,RESPTIME='EVERTON FOREVER020214:31:45'
000028 PORT=00002,GRPCYCLE=000002,C=001,L=027,REVERSED='54:13:412020REVEROF NOTREVE'
000029 PORT=00002,GRPCYCLE=000003,C=001,L=019,REQUESTX='EVERTON FOREVER0203'
000030 PORT=00002,GRPCYCLE=000003,C=003,L=008,SHAREKEY='HPER131C'
000031 PORT=00002,GRPCYCLE=000003,C=001,L=027,RESPTIME='EVERTON FOREVER020314:31:48'
000032 PORT=00002,GRPCYCLE=000003,C=001,L=027,REVERSED='84:13:413020REVEROF NOTREVE'
000033 PORT=00002,GRPCYCLE=000004,C=001,L=019,REQUESTX='EVERTON FOREVER0204'
000034 PORT=00002,GRPCYCLE=000004,C=003,L=008,SHAREKEY='HPER137C'
000035 PORT=00002,GRPCYCLE=000004,C=001,L=027,RESPTIME='EVERTON FOREVER020414:31:48'
000036 PORT=00002,GRPCYCLE=000004,C=001,L=027,REVERSED='84:13:414020REVEROF NOTREVE'
000037 PORT=00002,GRPCYCLE=000005,C=001,L=019,REQUESTX='EVERTON FOREVER0205'
000038 PORT=00002,GRPCYCLE=000005,C=003,L=008,SHAREKEY='HPER143C'
000039 PORT=00002,GRPCYCLE=000005,C=001,L=027,RESPTIME='EVERTON FOREVER020514:31:48'
000040 PORT=00002,GRPCYCLE=000005,C=001,L=027,REVERSED='84:13:415020REVEROF NOTREVE'