Home Page

Exchange S tress and P erformance
Stress and Performance Tools for Microsoft Exchange 2000
ESP is a highly scalable stress and performance tool developed by the Exchange Test Group to stress Exchange 2000.
Overview Supported Protocols

The Exchange Test Group currently uses ESP to simulate arbitrarily large numbers of client sessions concurrently accessing one or more Exchange 2000 servers.

Test cases are contained in script files which are executed by test modules (DLLs) that contain the logic for communicating with the server. Test modules can connect to a server via Internet protocols or make calls to APIs or interfaces like OLEDB.

Modules can run concurrently on multiple hosts thereby more realistically simulating physically separate client machines. Any NT 4.0 or Windows 2000 machine on the network can host ESP, therefore the load you can apply to an Exchange server is limited only by the available hardware.

The modules are centrally configured and controlled through a single "Admin" console, which uses DCOM to manage the modules running on remote hosts. Depending on the hardware and work load imposed by each script, it's possible to simulate 5,000 or more end users on a single host machine.

ESP is modular and extensible. We currently provide modules for most Internet protocols, and you can easily write modules specific to your backend using the ESP VC++ 6.0 Module Wizard. ESP provides the framework for running your modules and tools to make developing them easier.

ESP provides modules that simulate client sessions over the following Internet protocols/APIs:

  • HTTP-DAV
  • IMAP4
  • LDAP
  • OLEDB
  • NNTP
  • POP3
  • SMTP

Installing ESP

ESP runs on Windows NT 4.0 (Intel) and Windows 2000 only. See README.TXT for system requirements.

To install ESP, run MSETUP.EXE. You will be prompted for an installation directory, and a password for the service account created by setup. Otherwise, installation is automated. See README.TXT for details.

If you plan on running ESP modules remotely on Windows 2000 hosts, you will also have to run DCOMCNFG.EXE to manually configure DCOM settings. See README.TXT for details.

The ESP Module Wizard requires VC++ 6.0 or later, Enterprise or Professional editions.


ESP Administrator Overview

ESP Administrator

A Graphical View of Exchange ComTool clients

Overview

This document will present a summary of what the ESP UI is, what it is used for, the design rationale, its user interface, and a brief user’s guide.

This represents the features and designs that were agreed upon for the milestone 1 of the Exchange ComTools projects.

Introduction

The ESP UI is the graphical interface to manage, configure, and execute the Exchange COM tools components. The interface allows a user to manage groups of remote machines through the use of DCOM. The remote machines must have the Exchange COM tools objects installed before a client is added to the ESP view.

The application was designed as a Single Document Interface (SDI) MFC application. Currently, there is only one type of document that can be created and that is called a workspace. It is possible that more types will be added later.

A workspace is a view of an arbitrary number of remote machines called members, each of which are configured and managed from a central location by the ESP administrator program. Each remote machine can represent a set of clients of some server, e.g. Exchange server. Each member machine is represented by a computer icon in the UI, along with the member’s name. The member name is the actual machine name (not the DNS name) as defined in Control Panel | Network Settings. If a mistake is made entering the machine name, the member must be deleted and then re-added. The program does not allow renaming members.

Managing Members

The graphical representation of the workspace and members is through a tree view. The top-level item is the workspace and the child items represent member machines. Here is a screenshot:

To create a workspace, click File.New Workspace. A new workspace name “Untitled” is created. You will be prompted for a name when you save the workspace. To add a member to the workspace, hilight the workspace icon and right click and select “Add Host” or click File.Add Host. When prompted, enter the new member name. Alternatively, you can use the Browse button to display the standard network computer browser.

To remove a member, simply select the item, right click on it, and select the Delete. You may also use the Control-D or the Delete key. If a members deleted is currently connected, it will be disconnected and all running test modules will be stopped.

Establishing Connections

After adding members to a workspace, the user must manually connect to the client machine before modules can be added and configured to run. Once a connection has been established with the machine, actions can be triggered on the client. Graphically, once the connection is established the tree view item will change its display name from a plain font to a bold font. Bold items represent connected machines.

To connect a to a member, select the machine you wish to connect to, use the menu option Host. Connect or right click on the member and select the Connect option, or click the network cable icon on the toolbar.

Once connected, the connect property sheet comes up. The left pane lists the available modules on this remote host. The right pane contains a list of modules that are to be run from this host. You may add or

delete modules in the current host’s configuration by using the Add, Remove, and Clear buttons

Configuring Members

Each item on the tree view pane has properties. On the member items, the Target Host and Options tabs are used to configure host configuration options that may be altered or reviewed when there is a connection to the remote machine. To view or change a setting. right click the host name in the treeview and select Properties, to bring up the host property sheet. The Target Host tab displays connection information about this host. It includes the Host Name, a network host browse dialog (Hit Browse), whether the test should run for a fixed duration and stop, and if so, for how long. And whether the host should be automatically connected when the workspace is opened. The domain, user name, and password information is passed to represents the security context of the user and is currently ignored.

The options tab represents runtime test configuration properties that apply to all modules running on this host. These include:

  1. The number of ESP transport threads that will be spawned to handle IO requests.
  2. Whether each test run should generate a uniquely named log file or overwrite the existing log.
  3. Whether the results should be logged to disk.
  4. The path of the log file.

To change a value, hilight that item in the listview and double click, the cursor will go to the “Value” field and you may enter a value. You may click the button in the Log File Path to browse to a file, or enter the name directly. Hit the Apply or OK button to save your changes. It is the remote client’s responsibility to accept the new settings and take the necessary steps to put the changes into effect. If a test module is running, the remote machine will automatically determine if it needs to restart the module or not.

Configuring Test Modules

When a connection is established with a remote machine, all installed test modules on that machine are displayed in left pane of the host’s Available Modules Once the module is added you may set per-module configuration data by double clicking the target module in the ESP treeview. This brings up the module properties property sheet. (You can also hilight the module, right click and select Properties.)

The Settings tab gives configurable module options. Again, to configure the module settings, simply double click on the parameter row and start typing in the right column.

After the changes to the different test modules are made, the must be committed (i.e. sent over DCOM to the remote client) by hitting the Apply button. Alternatively, if you start the test module, the changes will be saved before the module is started. Both the Apply Changes and Start Module methods will commit the changes to all test module of the selected member.

The Statistics tab shows the per-module data this module will gather and log and/or send to perfmon counters. Only the polling frequency (how often the data is gathered) and enabling/disabling polling are configurable.

Saving the Workspace

The members and their configuration can be saved to a file so the same view may be restored at a later time. The settings of the different members will be saved to the workspace file only if the machine is currently connected when the save occurs. If a user connects to member A, makes setting changes in the member, disconnects the member, and then saves the workspace, the changes to the settings will not be saved.

Alternatively, you can save the settings of just one member so that the file may be used as a template for other members.

Restoring the Workspace

The workspace may be restored from a saved file. When the workspace if opened, the tree view pane, will be restored so that the same of members is presented as when the file was last saved. Connections that existed during the previous session will not be restored.

The settings of each member of a group are not automatically restored when the file is reopened.

Running Test Modules

To start a test module, simply hilight it and click the Module.Start button, or right click and select “Start” or click the green stop light icon on the tool bar. If the module starts successfully, it may be stopped by clicking the Stop Module button. You may also start and stop all modules on a host with a single click by selecting the host and clicking Host.Start All or by right clicking and selecting “Start All”.

Command Line Parameters

ESP can be started from the command line to allow batch files to run test passes. You can pass a single parameter on the command line: the name of a workspace file. In addition, you can pass the following flags:

Parameter | Flags | Description | Example
<workspace filename> |  | The workspace file. | ESP D:\tools\foo.ini
<workspace filename> | -unattended | Starts ESP automatically running in the workspace given by <workspace filename>. | ESP -unattended D:\Tools\foo.ini
<workspace filename> | -closeonstop | ESP will run until the last module stops. Used when modules use “Fixed Duration” parameter. | ESP -unattended -closeonstop D:\Tools\foo.ini
 | -regserver | Called only by setup to register component categories | ESP -regserver
 | -unregserver | Called only by setup to unregister component categories | ESP -unregserver


HTTP-DAV ESP Module Documentation

HTTP-DAV Module for Exchange COMTOOLS (DAVCOM.DLL)

1.1 Introduction

This module simulates multiple clients using the HTTP-DAV protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, or the port number. Client actions are simulated by executing a script that contains ESP keywords and DAVCOM verbs. This module also supports simple script variables.

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. The events that are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Server | Server name. | Required | Blank | <UNC server name or IP address>
Script Instances | Number of users | Required, > than 0 | 1 | 1-n
Start Time Delay (ms) | Each script instance will be delayed from starting this many milliseconds | Required, > than 0 | 0 | 1-n
Authentication Method | Authentication method. | Required | NONE | NTLM DPA MSN KERBEROS BASIC NONE
Encryption Method | Encryption method to use when doing authentication. | Required | NONE | BASE64 UUENCODE NONE
HTTP Version | HTTP version | Required | HTTP/1.1 | HTTP/1.1 HTTP/0.9 HTTP/1.0
Port Number | Port number to use when connecting to a server. | Required | 80 | <integer port number>
Script File | Script file to run a test. | Required | Blank | <valid path>
Calculate Content Length | Can be one of the following: If yes and there is a second parameter for the script request, I will calculate the content length and will add the "Content-Length" header for you. If yes and you don't have a second parameter for the script request, the content length is not calculated and the "Content-Length" header is not add for you. If yes and the content length of the second parameter is 0 bytes, the "Content-Length" header is not added for you. | Required | Yes | Yes No
Send Notification | If yes, then error and warning notifications are sent to the Medusa UI notification window pane. | Required | No | Yes No
Emulate Wininet | Forces the module to follow wininet’s default behavior when uploading request bodies and using authentication. In this case prior to the request body being uploaded the connection will be reauthenticated | Required | No | Yes No
Close Connection on Wakeup | Closes the connection whenever a user wakes up from a sleep. In the case where the users are doing long sleeps this keeps the user from reporting an error when waking up if the server has timed out the socket | Required | Yes | Yes No
Sleep Duration on Error (ms) | The duration in which each script instance (or user) will be delayed (put to sleep) when an internal error occurs in milliseconds | Required | 1000 | 0-n

1.3 Statistics

The following are the run-time statistics that are reported to the ESP UI and an explanation of each:

Statistic | Description
Active Connections | Current active user connections.
Successful Connections | Total number of active connections
Failed Connections | Total number of failed connections
Authenticated Connections | Total number of successful authenticated connections
Failed Authenticated Connections | Total number of failed authenticated connections
Connections Closed by the Server | Total number of connections that the server closed for no good reason. This is NOT incremented if you get a "Connection: close" header back from the server.
SLEEP Requests | Total number of SLEEP requests
POLL Requests | Total number of POLL requests
SUBSCRIBE Requests | Total number of SUBSCRIBE requests
POST Requests | Total number of POST requests
SEARCH Requests | Total number of SEARCH requests
TRACE Requests | Total number of TRACE requests
PROPPATCH Requests | Total number of PROPPATCH requests
PROPFIND Requests | Total number of PROPFIND requests
PUT Requests | Total number of PUT requests
OPTIONS Requests | Total number of OPTIONS requests
MOVE Requests | Total number of MOVE requests
MKCOL Requests | Total number of MKCOL requests
UNLOCK Requests | Total number of UNLOCK requests
LOCK Requests | Total number of LOCK requests
HEAD Requests | Total number of HEAD requests
DELETE Requests | Total number of DELETE requests
COPY Requests | Total number of COPY requests
GET Requests | Total number of GET requests
Unknown Requests | Total number of unknown requests
100 Level Status | Total number of 100 status level responses received by the server
200 Level Status | Total number of 200 status level responses received by the server
BPROPFIND Requests | Total number of BPROPFIND requests
BPROPPATCH Requests | Total number of BPROPPATCH requests
BMOVE Requests | Total number of BMOVE requests
BCOPY Requests | Total number of BCOPY requests
BDELETE Requests | Total number of BDELETE requests
SUBSCRIBE Requests | Total number of SUBSCRIBE requests
UNSUBSCRIBE Requests | Total number of UNSUBSCRIBE requests
POLL Requests | Total number of POLL requests
300 Level Status | Total number of 300 status level responses received by the server
400 Level Status | Total number of 400 status level responses received by the server
500 Level Status | Total number of 500 status level responses received by the server
Unknown Level Status | Total number of unknown status level responses received by the server
Successful Shutdowns | Total number of script instances (or users) that were successfully shutdown
Failed Shutdowns | Total number of script instances (or users) that were did not successfully shutdown. If this is > 0, then you will have to kill the Medusa UI application and restart…$bug$ in the internet transport that we use.

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Reserved Script Verb

Syntax and Example

Description

ADDHEADER

ADDHEADER <HdrLbl><:> <HdrVal>

ADDHEADER Connection: close

Adds the header to the server request.

DELHEADER

DELHEADER < HdrLbl ><:> [HdrVal]

DELHEADER Connection:

or

DELHEADER Connection: close

Deletes a header so it is not sent with the server request.

SET

SET <$><VarName><$> <$><VarValue><&>

SET $server$ $deanj6$

ADDHEADER host: $server$

Creates a variable that can be used throughout the script.

ADDVROOT

ADDVROOT <VrootName>

ADDVROOT deanj6

Adds a Vroot name so that any request that is sent to the server, the Vroot is pre-pended to the server request.

DELVROOT

DELVROOT <VrootName>

DELVROOT deanj6

Removes the Vroot name so that the Vroot name is not pre-pended to the server request.

RESHEADER

RESPHEADER(<HdrLbl>)

SET $value$ RESPHEADER(ETag)

SET $host$ host:

SET $trans$ translate:

ADDHEADER $host$ deanj

ADDHEADER $trans$ f

GET /kara/dean.txt

ADDHEADER IF-NONE-MATCH: $value$

GET /kara/dean.txt

SLEEP 1000

This tells me to parse the server's header response and retrieve the header value of the specified header label.

RESPXML

RESPXML(<xml>)

SET $xml$ RESPXML(opaquelocktoken)

SET $host$ host:

SET $trans$ translate:

ADDHEADER $host$ hermit

ADDHEADER $trans$ f

LOCK /fs/dean.txt c:\temp\l.txt

ADDHEADER Lock-Token: <$xml$>

GET /fs/dean.txt

UNLOCK /fs/dean.txt

DELHEADER Lock-Token:

SLEEP 1000

This tells me to parser the server's XML body response. THIS CAN ONLY BE USED TO EXTRACT THE LOCK TOKEN OUT OF THE XML BODY THAT IS RETURNED FROM THE SERVER IN A RESPONSE TO A LOCK COMMAND. SO, IF YOU USE IT FOR OTHER THAN LOCKS, THEN THE RESULT IS UNDEFINED!!

PARSEXML

Example:

SET $xml$ = new XMLList

PROPFIND /foo PARSEXML dav:!displayname

SET $prop$ $xml$.NEXT

SET $nextprop$ $xml$.RND

SET $fifthprop$ $xml$.5

SET $xml$.RESET

SET $xml$.REMOVE

GET /foo/$prop$

DELXMLLIST $xml$

Methods supported by the XMLList object:

.Next – gets the next item

.RND  - gets a random item

.RESET- sets the next item back to the beginning of the list.  This will happen automatically if the end of the list is reached

.REMOVE – removes all of the items in the list

.# - (where # is an integer)get the item at index #

PARSEXML allows you to store property values returned from the server as variables. You do this by adding the following text to the end of the command:

PARSEXML Namespace!propertyname.

The example to the left is doing a PARSEXML for namespace DAV:, property displayname. Note that the PARSEXML option can be specified for any request (PROPFIND, SEARCH, etc) but will only work correctly on requests that return xml (response body w/ a content-type of text/xml). The results of doing a PARSEXML are stored in the last variable that you set as the XMLList. You can have and use multiple XMLList’s in your script, but the results of the PARSEXML will always be stored in the last one SET was called on. Once you create an XMLList object that object is never deleted until the module exits, so it is advisable to reuse the objects as much as possible to keep the working set of the module low.

DELXMLLIST

SET $xml$ = new XMLList

DELXMLLIST $xml$

Frees the memory associated with an xml list object.  Note however that you cannot use an xmllist that has been deleted unless you recreate it again with SET … new XMLList

URIESCAPE

URIESCAPE $variable$

URIESCAPES the value of a given variable.  This makes sure that the variable is safe to use in a URI.

URIUNESCAPE

URIUNESCAPE $variable$

URIUNESCAPES the value of a given variable.  This removes any escaping.

replacevars

PROPPATCH /foo c:\scripts\xml.txt replacevars

Replacevars will open up the file specified and replace any instances of variable names with the corresponding values.  Any variable that you can reference from a scripts as $variablenamehere$ will be replaced if that same string $variablenamehere$ exists in the file.  The actual contents of the file on disk are not changed.

1.4.1 Variables Specific to this Test Module

The following are reserved word variables and an explanation of each

Reserved Variable | Syntax and Example | Description
SET $AUTHORIZATION$ | SET $AUTHORIZATION$ <domain\user> <pwd> SET $AUTHORIZATION$ redmond\deanj TryToGuess! Or SET $AUTHORIZATION$ SEQULIST(c:\userslist.txt) | This is how authentication is done. If you setup your server to do any supported type of authentication the module will send the <domain\user> <pwd> when authenticating the user.
$USER$ | $USER$ SET $AUTHORIZATION$ redmond\deanj TryToGuess! GET /private/$USER$/inbox | In this example, the $USER$ variable is set to and replaced with deanj.
$PWD$ | $PWD$ SET $AUTHORIZATION$ redmond\deanj TryToGuess! GET /private/$USER$/inbox/$PWD$ | In this example, the $USER$ variable is set to and replaced with deanj and the $PWD$ variable is set to and replaced with TryToGuess!

1.5 HTTP/DAV Commands Supported by this Test Module

The following describes the general syntax that is used for any HTTP/DAV command supported by this test module supports.

1.5.1 How to Script an HTTP/DAV Verb

All HTTP/DAV verbs can have at most 2 parameters and at least 0 parameters:

Note: When the syntax is described for each HTTP/DAV verb, anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

<HTTP/DAV_Verb> [parameter1] [parameter2]

Parameter1 is always assumed to be some resource on the server and is optional. Parameter2 is assumed to be a path + filename that can be local or UNC and is optional. Keeping with this convention, it should not be assumed that this test module does not support new HTTP/DAV verbs not discussed in this document.

1.5.2 The HTTP Version

The HTTP Version specified in the HTTP Version parameter is always appended to the HTTP/DAV verb command before submittal to the server. So, never include the HTTP version on any HTTP/DAV verb command in your scripts

1.5.3 HTTP/DAV Headers

Headers are added to a server request by using the ADDHEADER reserved word. If you want to add headers to a server request, add all headers before the request. Any and all headers that are added with an ADDHEADER will be sent with all server requests. To remove headers from a server request, delete the header by using the DELHEADER reserved word.

1.5.4 The Content-Length Header

If the Calculate Content Length is set to yes and there is a second parameter for the script request, I will calculate the content length and will add the "Content-Length" header for you. I will then remove the "Content-Length" header accordingly. If the Calculate Content Length parameter is set to yes and you don't have a second parameter for the script request, the content length is not calculated and the "Content-Length" header is not add for you. If the Calculate Content Length parameter yes and the content length of the second parameter is 0 bytes, the "Content-Length" header is not added for you.

1.5.5 Authentication

Authentication works like this…

1. Specify the authentication method by using the Authentication Method parameter.

2. Specify the encryption method by using the Encryption Method parameter (if applicable).

3. In your script, do this:

SET $AUTHORIZATION$ <domain\user> <pwd>

or

SET $AUTHORIZATION$ SEQULIST(<path/UNC to list of users in a file formed like <domain\user> <pwd>)

Upon parsing the domain\user and pwd, the reserved variable $USER$ will be set to user and the reserved variable $PWD$ will be set to pwd.

4. Then send your HTTP/DAV verb. If the server returns with a "401" status code, then this will prompt me to authenticate the user. Here is an example script:

SET $AUTHORIZATION$ deanj5dc\user1 user1

ADDHEADER Host: deanj5

ADDHEADER Depth: 1

ADDHEADER Content-type: text/xml

PROPFIND /private/$USER$/inbox D:\src\exc\NTX\DBG\USA\pfrt.txt

DELHEADER Depth:

DELHEADER Content-type:

SLEEP 1000

SKIP 1

1.5.6 HTTP/DAV Verbs and How to Script Them

HTTP/DAV | Syntax/Example | Description
GET | GET <url> ADDHEADER host: deanj6 GET /deanj6/file.txt | Retrieves a resource from the server
PUT | PUT <url> <local or UNC path + filename> ADDHEADER host: deanj6 PUT /deanj6/myfile.txt c:\temp\file.txt | Used to put a resource to a server.
POST | POST <url> <local or UNC path + filename> ADDHEADER host: deanj6 POST /deanj6/myfile.txt c:\temp\file.txt | Used to post a resource (or form) to the server
COPY | COPY <source url> ADDHEADER Destination: /deanj6/dir1/dest.txt COPY /deanj6/src.txt | Used to copy a resource.
DELETE | DELETE <url> | Used to delete a resource.
HEAD | HEAD <url> | Is used just like the GET verb, but does not return the body of the resource.
MKCOL | MKCOL <url> | Used to make a collection on the server.
MOVE | MOVE <source url> ADDHEADER Destination: /deanj6/dir1/dest.txt MOVE /deanj6/src.txt | Used to move a resource.
OPTIONS | OPTIONS <url> | Used to see what options the server supports.
TRACE | TRACE <url> | Repeats the command sent to the server.
LOCK | LOCK <urI> <path to xml lock body> SET $host$ host: SET $trans$ translate: ADDHEADER $host$ hermit ADDHEADER $trans$ f LOCK /fs/dean.txt c:\temp\l.txt | Used to lock a resource on the server.
UNLOCK | UNLOCK <urI> SET $xml$ RESPXML(opaquelocktoken) SET $host$ host: SET $trans$ translate: ADDHEADER $host$ hermit ADDHEADER $trans$ f LOCK /fs/dean.txt c:\temp\l.txt ADDHEADER Lock-Token: <$xml$> GET /fs/dean.txt UNLOCK /fs/dean.txt DELHEADER Lock-Token: SLEEP 1000 | Unlocks the resource that is locked
PROPFIND | PROPFIND <urI> or PROPFIND <url> <path to xml propfind body> ADDHEADER host: deanj6 ADDHEADER Content-type: text/xml PROPFIND /deanj6/dir1 c:\temp\xm.txt | Used to find the properties on a resource. If you do a "PROPFIND", with only one parameter, then you will have to add the content length header yourself by using "ADDHEADER."
PROPPATCH | PROPATCH <url> <path to xml propfind body> ADDHEADER host: deanj6 ADDHEADER Content-type: text/xml PROPPATCH /deanj6/dir1 c:\temp\xm.txt | Used to add, delete, or modify properties on resources.
MS-SEARCH | MS-SEARCH <urI> <path to xml body> ADDHEADER host: mana ADDHEADER Content-Type: text/xml MS-SEARCH /httpext c:\temp\srch.txt SLEEP 1000 | Search for a resource.
SEARCH | SEARCH <urI> <path to xml body> ADDHEADER host: mana ADDHEADER Content-Type: text/xml SEARCH /httpext c:\temp\srch.txt SLEEP 1000 | Search for a resource.
POLL | POLL <urI> |
SUBSCRIBE | SUBSCRIPT <urI> |

1.6 Example Scripts

Test Case | Status
SET $file$ c:\temp\file.txt ADDHEADER host: deanj6/ PUT /deanj/putfile.txt $file$ SLEEP 1000 | Pass
ADDHEADER host: deanj6/ GET /default.htm SLEEP 1000 | Pass
ADDHEADER host: deanj6/ GET /defaut.htm SLEEP 1000 | Pass
ADDHEADER Connection: close ADDHEADER host: deanj6/ GET /default.htm SLEEP 1000 | Pass
ADDHEADER connection: close ADDHEADER host: deanj6/ GET /default.htm SLEEP 1000 | Pass
ADDHEADER host: deanj6 OPTIONS /deanj6 SLEEP 1000 | Pass
SET $file$ c:\temp\file.txt ADDHEADER host: deanj6 OPTIONS /deanj6 PUT /deanj/putfile.txt $file$ SLEEP 1000 | Pass
SET $file$ c:\temp\file.txt ADDHEADER host: deanj6 OPTIONS PUT /deanj/putfile.txt $file$ SLEEP 10000 | Pass
SET $trans$ translation: f ADDHEADER $trans$ ADDHEADER host: deanj GET /deanj/d.txt DELHEADER $trans$ PUT /deanj/dj.txt c:\temp\file.txt SLEEP 10000 | Pass
SET $s$ RANDNUMBER(1,1000) ADDHEADER host: deanj6/ ADDVROOT /deanj PUT /$s$.tmp RANDLIST(c:\temp\files.txt) SLEEP 10000 | Pass
SET $s$ RANDNUMBER(1,1000) ADDHEADER host: deanj6/ ADDVROOT /deanj PUT /$s$.tmp RANDLIST(c:\temp\files.txt) DELVROOT /deanj GET /deanj/d.txt SLEEP 10000 | Pass
SET $s$ RANDNUMBER(1,1000) ADDHEADER host: deanj6/ ADDHEADER translation: f ADDVROOT /deanj DELETE /$s$.tmp SLEEP 500 | Pass
ADDHEADER host: deanj6 ADDVROOT /deanj ADDHEADER translation: f HEAD /n.txt SLEEP 1000 | Pass
ADDHEADER host: deanj6 ADDHEADER translation: f TRACE /deanj SLEEP 1000 | Pass
ADDHEADER host: mana ADDHEADER Content-Type: text/xml MS-SEARCH /httpext c:\temp\srch.txt SLEEP 1000 | Pass
SET $value$ RESPHEADER(ETag) SET $host$ host: SET $trans$ translate: ADDHEADER $host$ deanj ADDHEADER $trans$ f GET /kara/dean.txt ADDHEADER IF-NONE-MATCH: $value$ GET /kara/dean.txt SLEEP 1000 | Pass
SET $xml$ RESPXML(opaquelocktoken) SET $host$ host: SET $trans$ translate: ADDHEADER $host$ hermit ADDHEADER $trans$ f LOCK /fs/dean.txt c:\temp\l.txt ADDHEADER Lock-Token: <$xml$> GET /fs/dean.txt UNLOCK /fs/dean.txt DELHEADER Lock-Token: SLEEP 1000 | Pass


IMAP4 ESP Module Documentation

IMAP4 Module For Exchange COMTOOLS (IMAP4COM.DLL)

1.1 Introduction

This module simulates multiple clients using the IMAP4 protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, or the port number. Client actions are simulated by executing a script that contains ESP keywords and IMAP4 command verbs.

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. The events that are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Enable Local Logging | Enables/Disables creating a per-module log file | Optional | NO | YES NO
Local Logfile Path | Full path to local logfile | Required if above is YES |  | <Valid path>
Script Path | Full path to script | Required |  | <Valid path>
Encryption Method | Method used to encrypt network transmissions | Required | NONE | NONE SSL BASE64
Authentication Method | Method used to authenticate users to the server | Required | BASIC | BASIC NTLM DPA Kerberos Negotiate
Server Name | Target server | Required |  | <server name string or IP address>
Timeout | Period in minutes to wait for a server response before closing connection. 0 (the default) means wait indefinitely. | Optional | 0 | <0-n>
Fast Shutdown | Reserved for future use | Optional | 0 |
Port Number | Server port to connect to | Required | 143 | <integer port number>
Start Delay Time | Interval in ms to wait between the start of each user instance | Required | 200 | <0-n>
User Instances | Number of client sessions to simulate | Required | 1 | <1-n>

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description
Errors | Number of errors
Connections | Number of active connections established so far
Disconnected | Number of connections that have been terminated
Timeouts | Number of timeouts on server responses
APPEND | Number of commands
AUTHENTICATE | Number of APPEND commands
CAPABILITY | Number of AUTHENTICATE commands
CHECK | Number of CAPABILITY commands
CLOSE | Number of CHECK commands
COPY | Number of CLOSE commands
CREATE | Number of COPY commands
DELETE | Number of CREATE commands
EXAMINE | Number of DELETE commands
EXPUNGE | Number of EXAMINE commands
FETCH | Number of EXPUNGE commands
FETCHUID | Number of FETCH commands
IDLE | Number of FETCHUID commands
LIST | Number of IDLE commands
LOGOUT | Number of LIST commands
LSUB | Number of LOGOUT commands
NOOP | Number of LSUB commands
RENAME | Number of NOOP commands
SEARCH | Number of RENAME commands
STATUS | Number of SEARCH commands
SELECT | Number of STATUS commands
STORE | Number of SELECT commands
SUBSCRIBE | Number of STORE commands
UIDCOPY | Number of SUBSCRIBE commands
UIDFETCH | Number of UIDCOPY commands
UIDSEARCH | Number of UIDFETCH commands
UIDSTORE | Number of UIDSEARCH commands
UNSUBSCRIBE | Number of UIDSTORE commands
Errors | Number of UNSUBSCRIBE commands
Connections | Number of APPEND commands
Disconnected | Number of AUTHENTICATE commands
Timeouts | Number of CAPABILITY commands
APPEND | Number of CHECK commands
AUTHENTICATE | Number of CLOSE commands
CAPABILITY | Number of COPY commands
CHECK | Number of CREATE commands
CLOSE | Number of DELETE commands

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Reserved Script Verb | Description
CONNECT | Open a TCP/IP connection to the IMAP4 Server
NOOP | Same as IMAP4 NOOP
LOGOUT | Same as IMAP4 LOGOUT
CLOSE | Same as IMAP4 CLOSE
EXPUNGE | Same as IMAP4 EXPUNGE
CAPABILITY | Same as IMAP4 CAPABILITY
CHECK | Same as IMAP4 CHECK
UNSUBSCRIBE | Same as IMAP4 UNSUBSCRIBE
CREATE <mailbox name> | Create a specified mailbox name
SELECT <mailbox name> | Select a specified mailbox name
DELETE <mailbox name> | Delete a specified mailbox name
EXAMINE <mailbox name> | Examine a specified mailbox name
STATUS <mailbox name> | Same as IMAP4 STATUS
LSUB <string> | Whatever is in <string> is the argument
AUTHENTICATE <username> <password> | If BASIC authentication is specified, translates to LOGIN
APPEND <”folder”> <file name> | Append the content in the specified file to the specified folder. The folder name must be quoted
LIST <string> | The results are save for uses with rename,select,delete.

1.5 IMAP4 Commands Supported by this Test Module

SELECT Command:

SELECT <folder> Select the specified folder.

SELECT RANDOM LIST command must be issued before this. Randomly pick a folder from the folder list.

SELECT FIRST Pick first folder from the list.

SELECT LAST Pick last folder from the list.

SELECT NEXT Pick the next folder in the list.

SELECT SAME Pick the previous folder.

RENAME Command:

RENAME <original folder> <new folder> Rename the original folder to the new folder name.

RENAME RANDOM <new folder> LIST command must be issue before this.

Randomly pick a folder from the folder list.

RENAME FIRST <new folder> Pick first folder from list to rename.

RENAME LAST <new folder> pick last folder from list to rename.

RENAME NEXT <new folder> pick next folder in the list to rename.

RENAME SAME <new folder> pick previous folder to rename.

DELETE Command:

DELETE <folder> Delete the specified folder.

DELETE RANDOM LIST command must be issue before this.

Randomly pick a folder from list.

DELETE FIRST Pick first folder from list

DELETE LAST Pick last folder from list

DELETE NEXT pick next folder from list

DELETE SAME Pick previous folder.

FETCH Command:

FETCH RANDOM <msg data item string> The fetch command fetches the items defined in

The Message data items string ( RFC format ) for the range of articles chosen from the last search command. FETCH command will fetch message using message sequence number.

RANDOM – a single article from range

FETCH FIRST (num) <msg data item string> FIRST (num) chooses first num messages

FETCH LAST (num) <msg data item string> LAST (num) chooses last num messages

FETCH ALL <msg data items string> ALL chooses all messages

FETCH NEXT <msg data items string> NEXT choose the next msg number.

FETCH SAME <msg data items string> SAME choose the previous msg

UID FETCH command:

FETCHUID this command will translate into “UID FETCH 1:* UID”. The UID return will be cached for further uses. All command that uses UID must issue this command first.

UIDFETCH RANDOM <msg data item string> UIDFETCH will fetch messages using UID.

RANDOM – randomly pick a uid from the UID cache.

UIDFETCH FIRST (num) <msg data item> FIRST (num) chooses the first num of UID from the UID cache.

UIDFETCH LAST (num) <msg data item> LAST (num) chooses the last num of UID from the UID cache.

UIDFETCH ALL <msg data item> ALL chooses all UID from the UID cache.

UIDFETCH SAME <msg data item> SAME chooses the the previous UID.

UIDFETCH NEXT <msg data item> NEXT choose the next UID in the cache.

STORE Command:

STORE RANDOM <string> string is RFC format message data item name

Flags list. The Rest is same as in Fetch.

STORE FIRST (num) <string>

STORE LAST (num) <string>

STORE ALL <string>

STORE SAME <string>

STORE NEXT <string>

UID STORE Command:

UIDSTORE RANDOM <string> The FETCHUID command must be issue before

You can use these UIDSTORE command. The rest is same as UIDFETCH.

UIDSTORE FIRST (num) <string>

UIDSTORE LAST (num) <string>

UIDSTORE ALL <string>

UIDSTORE SAME <string>

UIDSTORE NEXT <string>

COPY command:

COPY RANDOM <folder> folder is the destination folder to copy.

Everything else is same as fetch.

COPY FIRST (num) <folder>

COPY LAST (num) <folder>

COPY ALL <folder>

COPY SAME <folder>

COPY NEXT <folder>

UID COPY Command:

UIDCOPY RANDOM <folder> The FETCHUID command must be issue before you can use these UIDCOPY commands. The rest is same as UIDFETCH

UIDCOPY FIRST (num) <folder>

UIDCOPY LAST (num) <folder>

UIDCOPY ALL <folder>

UIDCOPY SAME <folder>

UIDCOPY NEXT <folder>

1.6 Example Scripts

CONNECT

CAPABILITY

AUTHENTICATE USER1 USER1

LIST "" "*"

SELECT "INBOX"

FETCHUID

UIDFETCH 1:* (FLAGS)

UIDFETCH UIDALL (UID RFC822.SIZE rfc822.header)

NOOP

UIDFETCH FIRST 1 (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDCOPY 1 "Trash"

UIDSTORE 1 +FLAGS (\Deleted)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDCOPY 2 RANDLIST(RLOTHERMAILBOX.TXT)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDCOPY 1 "Trash"

UIDSTORE 1 +FLAGS (\Deleted)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDCOPY 2 RANDLIST(RLOTHERMAILBOX.TXT)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDCOPY 1 "Trash"

UIDSTORE 1 +FLAGS (\Deleted)

CHECK

SLEEP RANDNUMBER(0,300000)

NOOP

FETCH LAST 1 (UID)

UIDCOPY LAST 2 RANDLIST(RLOTHERMAILBOX.TXT)

UIDSTORE LAST 2 +FLAGS (\Deleted)

CLOSE

SELECT RANDLIST(RLOTHERMAILBOX.TXT)

FETCHUID

UIDFETCH 1:* (FLAGS)

UIDFETCH UIDALL (UID RFC822.SIZE rfc822.header)

NOOP

UIDFETCH FIRST 1 (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,120000)

UIDFETCH NEXT (UID RFC822.SIZE RFC822)

SLEEP RANDNUMBER(0,240000)

FETCHUID

UIDCOPY LAST 4 "Trash"

UIDSTORE LAST 4 +FLAGS (\Deleted)

SLEEP RANDNUMBER(15000,45000)

CLOSE

SELECT "INBOX"

FETCHUID

UIDFETCH 1:* (FLAGS)

UIDFETCH UIDALL (UID RFC822.SIZE rfc822.header)

NOOP

SLEEP RANDNUMBER(15000,45000)

UIDCOPY LAST 5 "Trash"

UIDSTORE LAST 5 +FLAGS (\Deleted)

expunge

close

SELECT "TRASH"

STORE ALL +FLAGS (\DELETED)

EXPUNGE

LIST "TRASH" "*"

LOGOUT


LDAP ESP Module Documentation

LDAP Module for Exchange COMTOOLS (LDAPCOM.DLL)

1.1 Introduction

This module simulates multiple clients using the LDAP protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, the port number and LDAP version. A script that contains ESP keywords and LDAP script commands specifies the client actions.

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run. Client actions and server responses can also be logged during a test run. The events that are logged is not configurable.

This document describes the commands that are specific to the LDAP test module as well as the parameters required by the module. Since the scripting engine used by ESP is the same as that used by Inetload, all script language facilities recognized by Inetload (e.g. LOOP…ENDLOOP, SEQULIST(), RANDNUMBER(), SKIP, REM) are also recognized by ESP, and these are briefly described. A set of example scripts for the module is also presented.

Note for users of Inetload/InetMonitor: The syntax for some of the LDAP module commands is somewhat different than it was in Inetload and InetMonitor. In particular, ADD and MODIFY attribute=value lists are now separated by a ‘&&’ (and multi-valued attribute values are separated by an ‘||’) rather than by a ‘;’ (and ‘\’). This was done so that attribute values with special characters (;, &, |, \) can be specified.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Script name | The name of the LDAP script to process. | Required |  | <valid path>
Encryption method | Currently unsupported (change Port Number to 636 or 3269 to use SSL, although this is currently untested). | Required | NONE |
Authentication method | Method used by server to authenticate client sessions. The server may not support these methods, however. | Required | NTLM | SIMPLE DPA NTLM NEGOTIATE MSN SICILY
Server Name | The server to connect to. | Required |  | <valid UNC or IP address>
Client Timeout | Duration in ms before abandoning a pending LDAP operation (0=never abandon). Independent of LDAP Time limit (see below). | Required | 120000 | 0-n
LDAP Version | LDAP version (2 or 3). | Required | 3 | 2 3
LDAP Deref | LDAP connection ld_deref value (0=Never, 1=Searching, 2=Finding, 3=Always). | Required | 0 | 0 1 2 3
LDAP Referrals | LDAP referrals value (0 = off, 1=on, 32=chase subordinate referrals, 64=chase external referrals). | Required | 0 | 0 1 32 64
LDAP Time Limit | LDAP connection ld_timelimit value (0=no limit). | Required | 60000 | 0-n
LDAP Size Limit | LDAP connection ld_sizelimit value (0=no limit). | Required | 0 | 0-n
LDAP Port Number | Port number for LDAP to use (389, 636, 3268, 3269). | Required | 389 | 389 636 3268 3269
Start time delay (ms) | Delay in ms between starting virtual users. | Required | 200 | 0-n
User Instances | Number of connections/virtual users to use. | Required | 1 | 1-n

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description
Connections | Number of current LDAP connections
Connect Commands | Number of ldap_open calls
Bind Commands | Number of ldap_bind calls
Search Commands | Number of ldap_search_ext calls
Modify Commands | Number of ldap_modify_ext calls
Add Commands | Number of ldap_add_ext calls
Delete Commands | Number of ldap_delete_ext calls
Compare Commands | Number of ldap_compare_ext calls
Rename Commands | Number of ldap_rename_ext calls
Quit Commands | Number of ldap_unbind calls
Errors | Number of errors

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional. Anything specified with “{}” is user specified. The script verbs and syntax is case insensitive.

Reserved Script Verb | Syntax and Example | Description
CONNECT | CONNECT | Connect to the server (via ldap_open API) whose name is specified in the “Server name” parameter of the LDAP test module via the port specified in the “LDAP Port Number” parameter of the LDAP test module. The “LDAP Deref”, “LDAP Options”, “LDAP Time Limit”, “LDAP Size Limit” and “LDAP Version” parameters of the LDAP test module are set on this connection if it is successful, and errors are emitted to the log if any of them fail to succeed (usually due to an invalid parameter value).
BINDSIMPLE | BINDSIMPLE <DN={dn};> [username={name};] [password={passwd};] [domain={domain};]” BINDSIMPLE ANONYMOUS | Does an LDAP ldap_bind (not ldap_simple_bind despite the name) to the {dn} or “” if ANONYMOUS. Credentials are constructed based on the username, password, and domain specified. If any are omitted empty strings are substituted. Authentication is done based on the “Authentication method” parameter of the LDAP test module.
SEARCH | SEARCH <SUBTREE|ONELEVEL|BASE> RETURN <ALL|SUBSET|attrib1,attrib2,…> DN=<dn>; FILTER=<filter>; | Search the directory (via ldap_search) for the records matching the <filter>, starting from base DN={dn} with scope equal to SUBTREE, ONELEVEL or BASE, returning all the attributes (ALL), a hard-coded subset (sn, givenName), or a specified subset (comma-separated list of attributes (no spaces). Refer to RFC’s 1960/2254 (A String Representation of LDAP Search Filters) and the examples for the format of a filter, although this implementation requires at least one level of parenthesis (e.g. use FILTER=(objectClass=*);, not FILTER=objectClass=*;).
MODIFY | MODIFY DN={dn}; {attrib1}={value11||value12||…:R|A|D} [&& {attrib2}={value21||value22||…:R|A|D} [&& …]] | Calls the LDAP API ldap_modify to modify the record DN={dn} with the attributes and values specified (&& separates the attributes. Appended to each value can be a :R, a :A or a :D to specify replace, add or delete. If this is omitted, it will default to add. A value can be a string (trailing whitespace is ignored, leading whitespace is not), a HEX: sequence (e.g. attrib=HEX:80000000) or a FILE containing the data (e.g. attrib=FILE:c:\ldapdata.txt)
ADD | ADD DN={dn}; {attrib1}={value11||value12||…:R|A|D} [&& {attrib2}={value21||value22||…:R|A|D} [&& …]] | Calls the LDAP API ldap_add to add the record DN={dn} with the attributes and values specified. Appended to each value can be a :R, a :A or a :D to specify replace, add or delete (although these can be specified, the behavior is undefined if they aren’t add). If this is omitted, it will be set to add. A value can be a string (trailing whitespace is ignored, leading whitespace is not), a HEX: sequence (e.g. attrib=HEX:80000000) or a FILE containing the data (e.g. attrib=FILE:c:\ldapdata.txt).
DELETE | DELETE DN={dn}; | Calls the LDAP API ldap_delete to delete the record {dn} from the directory.
COMPARE | COMPARE DN={dnsrc}; {attrib}={value} | Calls the LDAP API ldap_compare, which compares the attribute {attrib} on the {dn}. It returns true if the values are the same.
RENAME | RENAME DN={olddn}; DN={rdn}; DN={parent}; {TRUE|FALSE}” | Calls the LDAP API ldap_rename, which moves/renames {olddn} to {rdn},{parent}. The final boolean specifies whether to delete the attributes on the existing DN while renaming it.
IF | IF DN={dn}; FILTER={filter}; COMMAND | Calls the LDAP API ldap_search_s with scope=LDAP_SCOPE_BASE, baseDN={dn} and filter={filter}. If the search returns the DN (i.e. the filter evaluates to TRUE), proceed with the LDAP script COMMAND, otherwise do nothing.
QUIT | QUIT | Closes the LDAP connection by issuing an LDAP API ldap_unbind call.

1.5 LDAP Commands Supported by this Test Module

Here are the specific LDAP APIs (as specified in MSDN or winldap.h) invoked as a result of the various SCRIPT module verbs. Ldap_open and ldap_bind_s are synchronous API calls, the rest are asynchronous, although the module waits for the response (via ldap_result) before proceeding to the next script verb.

1.5.1    m_pLdapClient = ldap_open(m_pszServer, m_dwPort);

Invoked by the script command CONNECT, where m_pszServer is the pointer to the “Server name” parameter, and m_dwPort is the “Port number” parameter.

1.5.2    ldap_bind_s(m_pLdapClient, szDN, m_ulLdapMethod == LDAP_AUTH_SIMPLE ? (PCHAR)szPasswd : (PCHAR)&AuthIdentity, m_ulLdapMethod);

Invoked by the script command BINDSIMPLE, where m_pLdapClient is the LDAP connection pointer from ldap_open, szDN is a pointer to a string containing the base DN, AuthIdentity is a SEC_WINNT_AUTH_IDENTITY structure constructed from the username, domain and password, szPassword is a pointer to the string containing the password, and m_ulLdapMethod is the “Authentication Method” parameter.

1.5.3    ldap_search_ext(m_pLdapClient, szDNBase, ulScope, szFilter, rgszAttribList, FALSE, NULL, NULL, m_ld_timelimit, m_ld_sizelimit, &m_msgid);

Invoked by the script command SEARCH, where m_pLdapClient is the LDAP connection pointer from ldap_open, szDNBase is a pointer to a string containing the base DN of the search, ulScope is the scope specified (LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL or LDAP_SCOPE_SUBTREE), szFilter is the pointer to the filter string, rgszAttribList is a NULL terminated array of string pointers enumerating the attributes to return, and m_ld_timelimit and m_ld_sizelimit are the “Time Limit” and “Size Limit” parameters.

1.5.4    ldap_modify_ext(m_pLdapClient, szDN, ppMods, NULL, NULL, &m_msgid);

Invoked by the script command MODIFY, where m_pLdapClient is the LDAP connection pointer from ldap_open, szDN is a pointer to the string containing the DN to modify, and ppMods is a pointer to an LDAPMod structure (containing data about the modification to perform).

1.5.5    ldap_add_ext(m_pLdapClient, szDN, ppMods, NULL, NULL, &m_msgid);

Invoked by the script command ADD, where m_pLdapClient is the LDAP connection pointer from ldap_open, szDN is a pointer to the string containing the DN to add, and ppMods is a pointer to an LDAPMod structure (containing data about the attributes to add).

1.5.6    ldap_rename_ext(  m_pLdapClient, szOldDN, szNewRDN, szNewParent, (int)fDelete, NULL, NULL, &m_msgid);

Invoked by the script command RENAME, where m_pLdapClient is the LDAP connection pointer from ldap_open, szOldDN is a pointer to the string containing the original DN, szNewRDN a pointer to the string containing the new RDN, szNewParent a pointer to the string containing the new parent, fDelete equal to 1 or 0 depending on whether deleting the attributes is specified or not.

1.5.7    ldap_compare_ext( m_pLdapClient, szDN, szAttrib, szValue, NULL, NULL, NULL, &m_msgid);

Invoked by the script command COMPARE, where m_pLdapClient is the LDAP connection pointer from ldap_open, szDN is a pointer to the string containing the DN, szAttrib a pointer to the string containing the attribute name, szValue a pointer to the string containing the attribute value.

1.5.8    ldap_delete_ext(m_pLdapClient, szDN, NULL, NULL, &m_msgid);

Invoked by the script command DELETE, where m_pLdapClient is the LDAP connection pointer from ldap_open and szDN is a pointer to the string containing the DN to be deleted.

1.5.9    ldap_unbind(m_pLdapClient);

Invoked by the script command QUIT, where m_pLdapClient is the LDAP connection pointer from ldap_open.

1.6 Script Engine Facilities

1.6.1 Loops and skips

A loop is defined by:

LOOP <no_of_iterations>

1*(<command>) // one or more commands

ENDLOOP

Each command must appear on a separate line.

Nested loops are not allowed.

SKIP <n> skips the next n lines of the script. For example, this is useful at the end of a script to skip over the initialization part of the script, eg.

CONNECT

BINDSIMPLE …

SEARCH …

SKIP 2

1.6.2 Random generators

A random generator can refer either to a number or to a line from a file. The constructs are:

RANDALPHA(<#characters>) // random alphabetic characters

RANDNUMERIC(<#digits>) // random numeric digits

RANDNUMBER(<low>, <high>) // random no. in the range <low> - <high>

RANDLIST(<filename>) // random line from file “filename”

1.6.3 Sequence generators

A sequence generator can refer either to a number or to a line from a file. The constructs are:

SEQULIST(<filename>)

First evaluation of construct will return first line from file “filename”. Second evaluation will return second line from file, etc. This is done in a circular manner.

SAMESEQULIST(<filename>)

Returns the same string as the previous SEQULIST(<filename>) call.

SEQUNUMBER(<n1>, <n2>, ID)

Each evaluation returns a sequential number in the range <n1> - <n2>. The range is associated with an ID.

SAMESEQUNUMBER(<n1>, <n2>, ID)

Returns the same number as the previous SEQUNUMBER call with the same ID

Notes:

· Depending on whether n2 > n1 or n2 < n1, you will have an ascending or descending sequence.

· First evaluation of SEQUNUMBER will associate the range with the ID. In subsequent calls, <n1> and <n2> have only a syntactic role. The returned value will be entirely based on the ID e.g.

SEQUNUMBER(20, 10, 2) // returns 20 and associates ID 2 with range 20-10

SEQUNUMBER(5, 15, 2) // returns 19. First two arguments are ignored.
// Only the ID counts.

However, it is not recommended to use this “feature”.

Example:

The following sequence evaluates as shown below:

SEQULIST(list1.txt) // first line from list1.txt

SEQULIST(list2.txt) // first line from list2.txt

SAMESEQULIST(list1.txt) // same line as previous SEQULIST(list1.txt)

SEQUNUMBER(10, 20, 100) // returns 10 - first no. for ID 100

SEQUNUMBER(10, 20, 200) // returns 10 - first no. for ID 200

SEQUNUMBER(10, 20, 100) // returns 11 - next no. for ID 100

SAMESEQUNUMBER(10, 20, 200) // returns 10 - same no. for ID 200

SEQUNUMBER(10, 20, 200) // returns 11 - next no. for ID 200

1.6.4 Sleep

The sleep command is: SLEEP <no_of_milseconds>

The virtual user executing the command is put to sleep for the specified duration.

1.6.5 Probabilistic execution

Any script line can begin with %<n> with n from 0-100, indicating that that script line should be run only probabilistically n% of the time. E.g.

%50 SKIP 2

1.6.6 Remarks

Comments can be added to the script by prepending the command REM to the beginning of the line.

1.7 Example Scripts

1.7.1 Example 1

REM

REM Conduct 1000 searches for users against a DS.

REM

CONNECT

BINDSIMPLE ANONYMOUS

LOOP 1000

SEARCH SUBTREE RETURN cn,mailNickName,objectGuid DN=dc=server,dc=com; FILTER=(&(displayName=userRANDNUMBER(1,1000))(objectClass=user));

SLEEP 100

ENDLOOP

QUIT

1.7.2 Example 2

REM

REM Modify a users data

REM

CONNECT

BINDSIMPLE dn=cn=administrator,cn=users,dc=server,dc=com; username=administrator; password=; domain=mydomain;

MODIFY DN=CN=user1,CN=Users,dc=server,dc=com; sn=RANDALPHA(10):R && phone=555-1212:R

QUIT

1.7.3 Example 3

REM

REM Delete a DN

REM

CONNECT

BINDSIMPLE dn=cn=administrator,cn=users,dc=server,dc=com; username=administrator; password=; domain=mydomain;

DELETE DN=CN=User1,CN=Users,dc=server,dc=com;

QUIT

1.7.4 Example 4

REM

REM Conditionally modify a set of DNs

REM

CONNECT

BINDSIMPLE dn=cn=administrator,cn=users,dc=server,dc=com; username=administrator; password=; domain=mydomain;

LOOP 100

IF DN=CN=userSEQUNUMBER(1,100,1),CN=Users,dc=server,dc=com;
FILTER=(objectClass=contact);  MODIFY
DN=CN=userSAMESEQUNUMBER(1,100,1),CN=Users,dc=server,dc=com; sn=RANDALPHA(10):R
&& phone=555-1212:R

QUIT


NNTP ESP Module Documentation

NNTP Module for Exchange COMTOOLS (NNTPCOM.DLL)

1.1 Introduction

This module simulates multiple clients using the NNTP protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, or the port number. Client actions are simulated by executing a script that contains ESP keywords and NNTP module verbs.

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. Which events are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Server | The NNTP server the tests will run against | Required | Blank | <UNC server name or IP address>
Newsgroups File for Group | Required for the group random script command This file must contain one group per line | Required | Blank | <valid path>
Newsgroups File for Post | Required for the post script command This file must contain one group per line | Required | Blank | <valid path>
Authentication method | Method to authenticate client | Required | BASIC | NTLM BASIC
Encryption | Method used to encrypt network traffic | Required | NONE | SSL NONE
Script file | The script file name | Required | Blank | <valid path>
Start Delay Time | The number of milliseconds between each script instance starting | Required | 0 | 0-n
Script instances | The number of script instances to create and run. | Required | Blank | 1-n

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description
Number of Article successful connections | Number of successful connections
Number of failed connections | Number of failed connections
Number of current connections | Number of active connections
Number of errors | Number of unsuccessful commands
Number of xover commands issued | Number of xover commands issued
Number of group commands issued | Number of group commands issued
Number of post commands issued | Number of post commands issued
Number of article commands issued | Number of article commands issued
Number of auth commands issued | Number of auth commands issued
Number of sleep commands executed | Number of sleep commands executed

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Reserved Script Verb

Syntax and Example

Description

Connect

Connect

Connects to the server (required for all commands except sleep)

Group

Group RANDOM

Group newsgroup

Picks a random newsgroup from the newsgroups file specified in the module parameters (RANDOM must be in all caps)

Picks the newsgroup given by newsgroup

Note: the watermarks of the group are stored and used by the special syntaxes of the xover command

Xover

Xover ALL

Xover RAND(number)

Xover FIRST(number)

Xover LAST(number)

Xover range

does an xover on the entire article range

picks a random range of number articles

picks a random range of number articles

does an xover on the last number articles

standard NNTP syntax for xover where you specify your own range.

Post

Post article-file #newsgroups

Post an article to a number of one or more newsgroups

The article-file should be the body of the article only (without crlf.crlf). Headers are created when the articles is sent

Path: news.nntpcomp.com!news

From: NNTP Component nntpcomp@microsoft.com

Newsgroups: list of newsgroups

Subject: Just a test

Date: current time and date

(blank line)

The newsgroups list includes the current newsgroup (set by a group command) and #newsgroups from the newsgroups for post file specified in the module parameters.

Article

Article FIRST

Article LAST

Article RAND

Article NEXT

Article number

Article message-id

FIRST/LAST/RAND/NEXT must be in caps and require a successful xover command to be performed first.
Article FIRST returns the first article in the xover range (from the last successful xover command in the current connection)

returns the last article in the xover range (from the last successful xover command in the current connection)

returns a random article in the xover range (from the last successful xover command in the current connection)

returns the next article after the last article command

Article number and Article message-id are the standard NNTP usage of the article command and do not require an xover command.

Auth

Auth user [password]

Authenticates using the specified user and password. If a password is not specified, the username is used.

Sleep

Sleep msec

Sleeps for the specified number of milliseconds.

Exit

Exit

Stop execution of the script instance.

Any other NNTP command

Any other NNTP command is sent as a single line and expects a single line response.

1.5 NNTP Commands Supported by this Test Module

All commands are supported.

1.6 Example Scripts

Here is a very simple sample script. It connects to the machine, does a group command on a random group. Then it issues an xover on the entire article range, before cross-posting an article in the current and two additional random newsgroups. After that it sleeps for a time between 100 and 600 ms. Then it retrieves a random article, and finally sleeps for 10 ms.

Connect

group RANDOM

xover ALL

post c:\esp\scripts\post.txt 2

sleep RANDNUMBER(100,600)

article RAND

sleep 10

To execute this script successfully you will need

  • A file containing a list of newsgroups for the group RANDOM command to choose from. The path to this file must be entered in the module’s properties as the newsgroup file for post.
  • A file containing a list of newsgroups for the post command to choose from. The path to this file must be entered in the module’s properties as the newsgroup file for post (You can use the same file for both the post and group command.)
  • A file named post.txt containing the body of the message you wish to post


OLEDB ESP Module Documentation

OLEDB Module for Exchange COMTOOLS (OLEDBMOD.DLL)

1.1 Introduction

This module simulates multiple clients using the OLEDB COM interfaces. The module supports parameters for configuring different OLEDB-specific options, options for how the test executes. Examples would be the server this client is targeting. Client actions are simulated by executing a script that contains ESP keywords and OLEDB specific verbs. Some simple environment variables and flow control constructs are also supported

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. Which events are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Script File | Script file to run a test. | Required | Blank | <valid path>
Server | Server name. | Required | Blank | <UNC server name or IP address>
Start Time Delay (ms) | Each script instance will be delayed from starting this many milliseconds | Required, > than 0 | 0 | 1-n
Script Instances | Number of users | Required, > than 0 | 1 | 1-n
Script File | Script file to run a test. | Required | Blank | <valid path>
Server | Server name. | Required | Blank | <UNC server name or IP address>

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Reserved Script Verb | Syntax and Example | Description
COPYOBJ | See below | See below
CREATECOLLECTION |  |
CREATERESOURCE |  |
DELETEOBJ |  |
DELETEPROP |  |
GETMESSAGE |  |
GETPROP |  |
GETPROVIDER |  |
GOTO |  |
IF...THEN |  |
ITERATE |  |
LAUNCHPROCESS |  |
LOGLEVEL |  |
MOVEOBJ |  |
MSGBOX |  |
SAVEROWSET |  |
SELECT |  |
SETBINDFLAGS |  |
SETCREATEFLAGS |  |
SETSCOPEFLAGS |  |
SETPROP |  |
SETMULTIPROP |  |
SETPENDINGTRANS |  |
SETROWSTOFETCH |  |
SETTRANS |  |
SETVAR |  |
SETVERSIONCMD |  |
SYSTEM VARIABLES |  |
TRANSSTART |  |
TRANSCOMMIT |  |
TRANSABORT |  |

1.5 OLEDB Commands Supported by this Test Module

COPYOBJ - Copies tree or sub-trees of rows designated by a source URL to a location specified by a destination URL.

Usage: COPYOBJ {Source URL} {Resource} {Destination URL}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
COPYOBJ %PrivateURL%/Inbox/ SrcFooMsg %PrivateURL%/Inbox/DestFoomsg

CREATECOLLECTION – Create a folder object in the store.

Usage: CREATECOLLECTION {URL/FolderObjectName}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
CREATECOLLECTION %PrivateURL%/Inbox/FooFolder1

CREATERESOURCE – Create a resource object in the store.

Usage: CREATERESOURCE {URL/ResourceName} {optional file to stream in}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
CREATERESOURCE %PrivateURL%/FooMessage1
CREATERESOURCE %PrivateURL%/FooMessage2 MessageBody.Txt

DELETEOBJ – Delete the trees or sub-trees specified by the source URL.

Usage: DELETEOBJ {Source URL} {Resource}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
DELETEOBJ %PrivateURL%/Inbox/ FooMessage1
DELETEOBJ %PrivateURL%/Inbox/ FooFolder1

DELETEPROP – Delete a property from a row.

Usage: DELETEPROP {URL} {Property Name}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
DELETEPROP %PrivateURL%/Inbox/FooMessage2 mapi:0x0037001f

GETMESSAGE – Bind to a specified resource and retrieve the resource from a stream object.

Usage: GETMESSAGE {URL/Message} {Optional Output File}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
GETMESSAGE %PrivateURL%/Inbox/FooMessage2
GETMESSAGE %PrivateURL%/Inbox/FooMessage2 C:\TEMP\MsgOutput.Txt

GETPROP – Read a property from a row

Usage: GETPROP {URL} {Property Name} {Property Type} {Output file}

Sample:

SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
GETPROP %PrivateURL%/Inbox/FooMessage3 mapi:0x0037001f STRING
GETPROP %PrivateURL%/Inbox/FooMessage3 mapi:0x00170003 INT
GETPROP %PrivateURL%/Inbox/FooMessage3 DAV:displayname STRING D:\Property1.Txt
MSGBOX $$The name of the message is %PROPVALUE%$$
GETPROP %PrivateURL%/Inbox/FooMessage3 DAV:getcontentlength INT D:\Property2.Txt
MSGBOX $$The size of the message is %PROPVALUE%$$

Note: Property Type can be [STRING | INT | BINARY]

Properties that are INT and STRING types are stored in the system variable PROPVALUE. Each call to GETPROP replaces the last value stored in the variable "PROPVALUE"

See Also: SYSTEM VARIABLES

GETPROVIDER – Start and initialize the Exchange OLEDB provider via a Binder or Datasource

Usage: GETPROVIDER {BINDER | DATASOURCE | DSOBIND} {ProgID} {Binding URL}

Sample:

REM *** Set a variable for the username
SETVAR UserName = User1
REM *** Create a session via a binder object
GETPROVIDER BINDER EXOLEDB.BINDER File://./BackOfficeStorage/%USERDNSDOMAIN%/MBX/%UserName%
REM *** Create a session by creating a datasource object
GETPROVIDER DATASOURCE EXOLEDB.DATASOURCE File://./BackOfficeStorage/%USERDNSDOMAIN%/Public Folders
REM ***

See Also: USERDNSDOMAIN, COMPUTERNAME

GOTO - Forces script code to unconditionally branch to another part of the script.

Usage: GOTO {label}

Sample:

SETVAR Case = 1
IF %Case% = 3 Then GOTO CASE3
IF %Case% = 2 Then GOTO CASE2
IF %Case% = 1 Then GOTO CASE1
GOTO END
:CASE3
MSGBOX $$Running Test Case 3$$
GOTO END
:CASE2
MSGBOX $$Running Test Case 2$$
GOTO END
:CASE1
MSGBOX $$Running Test Case 1$$
GOTO END
:END
MSGBOX $$End of Test Suite$$
STOP

Note: When executing a GOTO script command. A label is required somewhere in the script otherwise an error will occur. A label is designated by a leading colon and then the name of the label (see example above).

IF...THEN – Allows conditional processing to be performed in the OLEDB medusa script

Usage: IF {expression} {= | < | > | != } {expression} THEN {Command}

Sample:

IF 123 = 123 THEN MSGBOX $$This expression is true$$

IF 123 = 456 THEN MSGBOX $$This expression is not true$$

SETVAR X = 1

IF %X% = 1 THEN MSGBOX $$This expression is true$$

SETVAR Y = 1

IF %X% = %Y% THEN MSGBOX $$The expression %X% equals %Y% is a true statement$$

IF %X% > %Y% THEN MSGBOX $$This statement won't get executed$$

IF %X% < %Y% THEN CREATERESOURCE Exstore://LocalHost/Private/User/Inbox/SomeMsg%Y%

IF %X% != %Y% THEN CREATECOLLECTION Exstore://LocalHost/Private/User/Inbox/FooFolder%X%

ITERATE – Iterates through a rowset a specified number of times after issuing a SELECT statement.

Usage: ITERATE {number of iterations}

Sample:

SAVEROWSET ON
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
SELECT $$SELECT "DAV:displayname" FROM SCOPE('SHALLOW TRAVERSAL OF "%PrivateURL%/INBOX/"')$$
ITERATE 100

Note: SAVEROWSET must be turned on before using this feature.

See Also: SAVEROWSET, SELECT

LAUNCHPROCESS – Launches a specified execute and optionally waits for the program to finish execution before proceeding

Usage: LAUNCHPROCESS {Filename} {Argument 1, Argument 2, ...} {NOWAIT | WAIT}

Sample:

REM *** Launch Notepad.Exe and wait for the program to finish execution before continuing to execute commands in Medusa

LAUNCHPROCESS NOTEPAD.EXE D:\Medusa_Log.Txt WAIT

REM *** Launch Notepad.Exe and dont wait for the program to finish execution before continuing to execute commands in Medusa

LAUNCHPROCESS NOTEPAD.EXE D:\Medusa_Log.Txt NOWAIT

LOGLEVEL – Log all commands and the status of the commands to the log file (regardless of error).

Usage: LOGLEVEL {ERRORS | ALL}

Sample:

LOGLEVEL ERRORS

LOGLEVEL ALL

MOVEOBJ – Move the trees or sub-trees specified by the source URL to a location specified by a destination URL.

Usage: MOVEOBJ {Source URL} {Resource} {Destination URL}

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
MOVEOBJ %PrivateURL%/Inbox/ SrcFooMessage1 %PrivateURL%/Inbox/DestFooMessage1

MSGBOX – Temporarily suspend execution of the medusa test script and display a dialog box with the specified text.

Usage: MSGBOX {Message Text} {Optional caption for dialog box}

Sample:

MSGBOX $$This is some text to be displayed$$ $$Exchange Rocks$$

SETVAR FooVar = Hello World!

MSGBOX $$%FooVar%$$

SETVAR X = Hi

MSGBOX %X%

Note: Any text that includes spaces must be enclosed in ‘$$’. This also includes variables where the value has spaces in it.

SAVEROWSET – Turns ON or OFF the persistence of an IRowset object.

Usage: SAVEROWSET { ON | OFF}

Sample:

SAVEROWSET ON
SELECT $$SELECT "DAV:displayname" FROM SCOPE('SHALLOW TRAVERSAL OF "%PrivateURL%/INBOX/"')$$
ITERATE 100

Note: Used in conjunction with ITERATE

See Also: ITERATE, SELECT

SELECT – Executes the specified SQL Select statement against the exchange store.

Usage: SELECT {SQL Select} {Optional output file | NULL}

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
SELECT $$SELECT mapi:0x0037001f FROM SCOPE(‘SHALLOW TRAVERSAL OF "%PrivateURL%/Inbox/"’)$$

Note:

SQL command has to be surrounded by $$.

If NULL is specified as the argument for the OUTPUT file then the SELECT will only traverse the entire rowset. This is different from not specifying an OUTPUT file which the rowset NOT not to be traversed before being released. This give us a way of figuring out how much time it spend creating the rowset and how much time is spent traversing it

PRE - PT 3751 you had to specify a URL to bind to for the SELECT statement as "SELECT File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1/Inbox/Testmsg $$SELECT "DAV:displayname" FROM SCOPE('SHALLOW TRAVERSAL OF "File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1/Inbox/"')". THIS IS NO LONGER THE CASE AFTER BUILD OF 3751. Now you just need to specify the SQL SELECT statement.

SETBINDFLAGS – Set a system (OLEDB Module) variable used during all of the calls to IBindResource::Bind for the "DBBINDURLFLAG" parameter.

Usage: SETBINDFLAGS { DBBINDURLFLAG_READ |

DBBINDURLFLAG_WRITE |

DBBINDURLFLAG_READWRITE | DBBINDURLFLAG_SHARE_DENY_READ | DBBINDURLFLAG_SHARE_DENY_WRITE | DBBINDURLFLAG_SHARE_EXCLUSIVE | DBBINDURLFLAG_SHARE_DENY_NONE | DBBINDURLFLAG_RECURSIVE |

DBBINDURLFLAG_OUTPUT |

DBBINDURLFLAG_ASYNC |

DBBINDURLFLAG_COLLECTION |

DBBINDURLFLAG_OPENIFEXISTS |

DBBINDURLFLAG_OVERWRITE |

DBBINDURLFLAG_ISSTRUCTUREDDOCUMENT |

NULL }

Sample:

SETBINDFLAGS DBBINDURLFLAG_READ DBBINDURLFLAG_WRITE

SETBINDFLAGS DBBINDURLFLAG_READWRITE DBBINDURLFLAG_OVERWRITE

SETBINDFLAGS NULL

Note: NULL Sets the value of the flag to zero

Default Value: 0

SETCREATEFLAGS – Set a system (OLEDB Module) variable used during all of the calls to ICreateRow::CreateRow for the "DBBINDURLFLAG" parameter.

Usage: SETCREATEFLAGS { DBBINDURLFLAG_READ |

DBBINDURLFLAG_WRITE |

DBBINDURLFLAG_READWRITE | DBBINDURLFLAG_SHARE_DENY_READ | DBBINDURLFLAG_SHARE_DENY_WRITE | DBBINDURLFLAG_SHARE_EXCLUSIVE | DBBINDURLFLAG_SHARE_DENY_NONE | DBBINDURLFLAG_RECURSIVE |

DBBINDURLFLAG_OUTPUT |

DBBINDURLFLAG_ASYNC |

DBBINDURLFLAG_COLLECTION |

DBBINDURLFLAG_OPENIFEXISTS |

DBBINDURLFLAG_OVERWRITE |

DBBINDURLFLAG_ISSTRUCTUREDDOCUMENT |

NULL }

Sample:

SETCREATEFLAGS DBBINDURLFLAG_READWRITE
SETCREATEFLAGS DBBINDURLFLAG_READWRITE DBBINDURLFLAG_OPENIFEXISTS
SETCREATEFLAGS NULL

Note: NULL Sets the value of the flag to zero

Default Value: 0

SETSCOPEFLAGS – Set a system (OLEDB Module) variable used during all of the calls to IScopedOperations::[Copy | Move | Delete] for the "dw[Copy | Move | Delete]Flags" parameter.

Usage: SETSCOPEFLAGS {Scope Type } { DBMOVE_REPLACE_EXISTING |

DBMOVE_DONT_UPDATE_LINKS |

DBMOVE_ASYNC |

DBMOVE_ALLOW_EMULATION |

DBMOVE_ATOMIC |

DBDELETE_ASYNC |

DBDELETE_ATOMIC |

DBCOPY_REPLACE_EXISTING |

DBCOPY_ASYNC |

DBCOPY_ALLOW_EMULATION |

DBCOPY_NON_RECURSIVE |

DBCOPY_ATOMIC |

NULL }

Scope Type can be MOVE, COPY, or DELETE

Sample:

SETSCOPEFLAGS MOVE DBMOVE_ALLOW_EMULATION
SETSCOPEFLAGS DELETE DBDELETE_ATOMIC
SETSCOPEFLAGS COPY DBCOPY_ASYNC DBCOPY_ATOMIC
SETSCOPEFLAGS MOVE NULL
SETSCOPEFLAGS MOVE DBMOVE_REPLACE_EXISTING DBCOPY_REPLACE_EXISTING

Note: NULL Sets the value of the flag to zero. It is possible to set the COPY, MOVE and DELETE flags with ANY of the flags (e.g., DBDELETE_ASYNC & DBMOVE_REPLACE_EXISTING)

Default Values:

    • MOVE = DBMOVE_REPLACE_EXISTING
    • COPY = DBCOPY_REPLACE_EXISTING
    • DELETE = 0

SETPROP – Set the value of a specified column in a row.

Usage: SETPROP {URL} {Property Name} {Property Type} {Memory Size in bytes}

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** The line below will set the subject (PR_SUBJECT = mapi:0x0037001f)
SETPROP %PrivateURL%/Inbox/NewMessage mapi:0x0037001f STRING $$Hello World$$
REM *** The line below will set the body (PR_BODY = mapi:0x1000001e). It will then fill in the body of the message
REM *** with as many iterations of "HelloWord" as will fit into 1024 bytes.
SETPROP %PrivateURL%/Inbox/NewMessage mapi:0x1000001e STRING HelloWord 1024

Notes:

Property Type can be [STRING | INT | BINARY]

Memory Size (in bytes) is the amount of memory allocated each time a property is SET.

!!!! When specifying amount of memory for a STRING data type it stores the characters as UNICODE which actually take up two bytes. !!!!

The "Memory Size (in bytes) has no effect on an "INT" data type.

See Also: PROBBUFFSIZE (system variable), GETPROP

SETMULTIPROP - Set multiple properties for a specified column in a row

Usage: SETMULTIPROP {URL} {Property Count} {Property Name} {Property Type}

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** Set multiple properties for a resource in the store
REM *** This particular call below will set the the PR_IMPORTANCE, PR_PRIORITY, and DAV:displayname for the resource
SETPROP %PrivateURL%/Inbox/NewMessage 3 mapi:0x170003 INT 0 mapi:0x360003 INT 0 DAV:displayname STRING $$This is a test$$

SETPENDINGTRANS - Turns ON or OFF pending (or retaining transactions).

Usage: SETPENDINGTRANS {ON | OFF}

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** Do not start a new transaction until the next EXOLEDB script command
SETPENDINGTRANS OFF
REM *** This command will not start a transaction because it doesn't execute any EXOLEDB specific provider code
SETCREATEFLAGS DBBINDURLFLAG_READWRITE
REM *** The two commands below will behave by starting a transaction, creating the resource,
REM *** and then commit the transaction
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE1
REM *** By default at this point a pending or retaining transaction would be in effect
REM *** But since pending transactions are OFF, a transaction is not started until the point immediately before the resource is created
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE2
REM *** Let's turn back on Pending Transactions
SETPENDINGTRANS ON

Note: By default, after each EXOLEDB script command is executed, everything is committed that was inside of the transaction. Immediately after committing the transaction, a new one is started. If the value for this command is set to OFF, a transaction is not started until the next EXOLEDB script command is executed.

Default Value: ON

See Also: TRANSSTART, TRANSCOMMIT, TRANSABORT

SETROWSTOFETCH - Set the number of rows that will be fetch on each call that is made to IRowset::GetNextRows.

Usage: SETROWSTOFETCH {number of rows}

Sample:

SETVAR BASEURL=FILE://./BACKOFFICESTORAGE/%USERDNSDOMAIN%/MBX/TESTUSER1
REM *** Initialize the provider
SETBINDFLAGS DBBINDURLFLAG_READ
GETPROVIDER DATASOURCE EXOLEDB.DATASOURCE %BASEURL%
REM *** Set the number of rows to fetch when retrieving data
SETROWSTOFETCH 10
REM *** Issue a query. As the data is retrieved 10 rows will be retrieved at a time
REM *** If there are less than 10 rows to be retrieved, the remaining number will be retrieved
SELECT $$SELECT "DAV:displayname","DAV:isfolder" FROM "%BASEURL%/Inbox"$$ E:\MEDUSA\SCRIPTS\SELECT1.TXT
REM *** Stop the script
STOP

See Also: SELECT, ITERATE

Note: Once the number of rows is set via SETROWSTOFETCH, all subsequent calls to ::GetNextRows will use that value. To reset the number of rows fetched for each call to 1 (the default value), another call must be made to SETROWSTOFETCH with the value of 1 (e.g., SETROWSTOFETCH 1).

SETTRANS - Turns wrapping commands in a transaction ON or OFF

Usage: SETTRANS { ON | OFF }

Note: COPYOBJ and MOVEOBJ operations are never wrapped in a transaction.

See Also: TRANSSTART, TRANSCOMMIT, TRANSABORT, SETPENDINGTRANS

SETVAR – Set a user-defined or system variable.

Usage: SETVAR {User Variable Name | System Variable Name} = {Value | Expression}

Sample:

REM
*** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
SETVAR MessageNum = 1
SETVAR MessageNum = MessageNum + 1
SETVAR MessageNum = MessageNum * 5
SETVAR MessageNum = MessageNum – 4
SETVAR MessageNum = MessageNum / 2
MSGBOX MessageNum = %MessageNum%
CREATERESOURCE %PrivateURL%/Inbox/Message%MessageNum%
CREATECOLLECTION %PrivateURL%/Inbox/Folder%MesssageNum%

SETVERSIONCMD - Set Version CMD for an object to be manipulated

Usage: SETVERSIONCMD { ALL | LATEST | VID } URL VersionCommand

ALL Getting everything (Not getting versioned object)

LATEST Getting the latest version

VID Getting the specified VID

Sample:

SETVERSIONCMD ALL File://./BackOfficeStorage/%Userdnsdomain%/Public%20Folders/user/msg

SETVERSIONCMD LATEST File://./BackOfficeStorage/%Userdnsdomain%/Public%20Folders/user/msg DESTROY

SETVERSIONCMD 09e8475a91e340012 File://./BackOfficeStorage/%Userdnsdomain%/Public%20Folders/user/msg PIN

TRANSSTART – Manually start a transaction

Usage: TRANSSTART

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** Turn off automatic transactions
SETTRANS OFF
REM *** Start a new transaction
TRANSSTART
REM *** Wrap the next two commands in a transaction
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE1
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE2
REM *** Now, since automatic transactions are off, we need to manually commit the transactions
TRANSCOMMIT
REM *** Turn back on automatic transactions
SETTRANS ON

Notes: Automatic transactions must be turned off in order to use this feature.

See Also: TRANSCOMMIT, TRANSABORT, SETTRANS, SETPENDINGTRANS

TRANSCOMMIT – Manually commit an active transaction

Usage: TRANSCOMMIT

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** Turn off automatic transactions
SETTRANS OFF
REM *** Start a new transaction
TRANSSTART
REM *** Wrap the next two commands in a transaction
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE1
CREATERESOURCE %PrivateURL%/INBOX/TESTMESSAGE2
REM *** Now, since automatic transactions are off, we need to manually commit the transactions
TRANSCOMMIT
REM *** Turn back on automatic transactions
SETTRANS ON

Notes: Automatic transactions must be turned off in order to use this feature.

See Also: TRANSSTART, TRANSABORT, SETTRANS, SETPENDINGTRANS

TRANSABORT – Manually abort an active transaction

Usage: TRANSABORT

Sample:

REM *** Set a variable for the URL
SETVAR PrivateURL=File://./BackofficeStorage/%UserDNSDomain%/MBX/TestUser1
REM *** Turn off automatic transactions
SETTRANS OFF
REM *** Start a new transaction
TRANSSTART
REM *** Wrap the next two commands in a transaction
CREATERESOURCE %PrivateURL%/TESTMESSAGE1
CREATERESOURCE %PrivateURL%/TESTMESSAGE2
REM *** Now, abort the last transaction, thus rolling back the creation of messages 'TestMessage1' & 'TestMessage2'
TRANSABORT
REM *** Turn back on automatic transactions
SETTRANS ON

Notes: Automatic transactions must be turned off in order to use this feature.

See Also: TRANSSTART, TRANSCOMMIT, SETTRANS, SETPENDINGTRANS

1.6 System Variables

This module supports some simple global variables you can use in your scripts:

SLEEPCOMMIT - Causes the OLEDB medusa module to wait the specified number of milliseconds before committing the current transaction

SETVAR SLEEPCOMMIT=5000 *** This will cause the module to wait 5 seconds before committing

SETVAR SLEEPCOMMIT=0 *** This will cause the module to not wait at all

SETVAR SLEEPCOMMIT=250 *** This will cause the module to wait 1/4 second before committing

PROBBUFFSIZE -- Sets the amount of memory allocated each time a property is set or get via SETPROP or GETPROP

SETVAR PROBBUFFSIZE=1024 *** Allocates 1024 bytes for SETing/GETing properties

SETVAR PROBBUFFSIZE=10000 *** Allocates 10000 bytes for SETing/GETing properties

COMPUTERNAME -- System variable that contains the same value as the environment variable COMPUTERNAME

USERDNSDOMAIN -- System variable that contains the same value as the environment variable USERDNSDOMAIN

HRESULT -- System variable that contains the last HRESULT return value from an OLEDB API call

PROPVALUE -- Contains the value of the last property retrieved via GETPROP

1.7 Example Scripts

Test Case | Status


POP3 ESP Module Documentation

POP3 Module for Exchange COMTOOLS (POP3COM.DLL)

1.1 Introduction

This module simulates multiple clients using the POP3 protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, or the port number. Client actions are simulated by executing a script that contains ESP keywords and POP3 commands.

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. Which events are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Script Path | Script file to run a test. | Required | Blank | <valid path>
Server Name | Server name. | Required | Blank | <UNC server name or IP address>
Start Time Delay (ms) | Each script instance will be delayed from starting this many milliseconds | Required | 0 | 1-n
User Instances | Number of users | Required | 1 | 1-n
Port Number | Port to connect to | Required | 110 | <valid POP3 port number>
Timeout | How long in minutes to wait for server response before closing connection. 0 means wait indefinitely. | Optional | 0 | 0-n
Authentication Method | Authentication method | Optional | BASIC | NTLM BASIC DPA Kerberos Negotiate
Encryption Method | How network traffic is encrypted. | Optional | NONE | NONE SSL BASE64
Start Delay Time (ms) | Interval in ms between starting each user instance | Required | 200 | 0-n
Enable Local Logging | Enables/Disables per module logging | Optional | NO | YES NO
Local Log Path | Path to local logfile | Required if local logging is enabled |  | <valid path>

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description
Connections | Number of connections completed
Disconnected | Number of connections terminated
Errors | Number of errors
Timeouts | Number of timeout expirations
AUTH Commands | Number of AUTH commands
DELE Commands | Number of DELE Commands
LIST Commands | Number of LIST Commands
NOOP Commands | Number of NOOP Commands
PASS Commands | Number of PASS Commands
QUIT Commands | Number of QUIT Commands
RETR Commands | Number of RETR Commands
RSET Commands | Number of RSET Commands
STAT Commands | Number of STAT Commands
TOP Commands | Number of TOP Commands
UIDL Commands | Number of UIDL Commands
USER Commands | Number of USER Commands

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Reserved Script Verb | Description
CONNECT | Open a TCP/IP connection to the POP3 Server.
QUIT | Close the TCP/IP connection
MAILBOX <username> <password> | Expands into three POP3 commands: USER <username> PASS <password> STAT The inbox info return from STAT will be cache for use with RETR and DELE.
STAT | Same as POP3 STAT command. The inbox info returned from STAT is cached for use with RETR and DELE.
RSET | Same as POP3
NOOP | Same as POP3
LIST | Same as POP3
TOP | Same as POP3
UIDL | Same as POP3
RETR | Same as POP3
DELE | Same as POP3

1.5 POP3 Commands Supported by this Test Module

USER

PASS

STAT

NOOP

LIST

TOP

UIDL

RETR

DELE

RETR and DELE Command:

RETR <num> num is the message sequence number.

RETR ALL retrieve all messages in inbox.

DELE <num> num is the message sequence number.

DELE ALL delete all messages in inbox.

1.6 Example Scripts

1.6.1 This script logs on as user stardog1, with password “stardog1”, list the mailbox contents, retrieves all items, then deletes them.

connect

mailbox mtbf\stardog1 stardog1

SLEEP RANDNUMBER(200,200)

list

retr all

dele all

quit


SMTP ESP Module Documentation

SMTP Module for Exchange COMTOOLS (SMTP.DLL)

1.1 Introduction

This module simulates multiple clients using the SMTP protocol. The module supports parameters for configuring different protocol-specific options, options for how the test executes, and security. Examples would be the server this client is targeting, or the port number. Client actions are simulated by executing a script that contains ESP keywords and SMTP module verbs.

Since the scripting engine used by Medusa is the same as that used by Inetload, all script language constructs recognized by Inetload (e.g. LOOP…ENDLOOP, SEQULIST(), RANDNUMBER()) are also recognized by ESP.

It is outside the scope of this document to explain these constructs. However, a brief presentation of some commonly used constructs is given in section 2

This module also reports a number of statistics during runtime. Statistics give counts of the number of module or protocol specific events (e.g. errors, successful or failed connection attempts, etc.) occurring during the course of a test run.

Client actions and server responses can also be logged during a test run. Which events are logged is not configurable.

1.2 Parameters

The following are the run-time parameters shown in ESP UI and an explanation of each:

Parameter | Description | Optional/Required | Default | Legal Values
Script path | Path to the script file. Can be UNC path | Required | N/A | <valid path>
Server name | The name of the server to connect to | Required | N/A | <UNC server name or IP address>
Port number | The port number to connect to | Required | 25 | 1-n
Authentication method | Method used to authenticate client session | Required | Login | Login NTLM
Encryption method | Method used to encrypt network traffic | Required | None | None SSL
Sleep on error (ms) | Duration in ms to sleep after an error e.g. connection failure, dropped connection | Required | 1000 | 0-n
Send Notifications | If “Yes”, notification messages will be sent to the Medusa UI (right upper pane). Currently not recommended due to active bugs. All notification messages are logged (if logging is enabled). | Required | No | Yes No
Start time delay (ms) | Delay in ms between starting virtual users | Required | 0 | 0-n
Script Instances | Number of virtual users |  | 100 | 1-n

1.3 Statistics

The following are the run-time statistics that are revealed by the Medusa UI and an explanation of each:

Statistic | Description
Sleep on error (ms) | Number of milliseconds to sleep after an error condition
Total Successful connections | Total Successful connections
Total Failed Connections | Total Failed Connections
Current Active Users | Number of active client sessions
Total HELO Commands | Total HELO Commands
Total EHLO Commands | Total EHLO Commands
Total MAIL Commands | Total MAIL Commands
Total RCPT Commands | Total RCPT Commands
Total DATA Commands | Total DATA Commands
Total DATA Errors | Total DATA Errors
Total Message Bodies | Total Message Bodies
Total Message Body Errors | Total Message Body Errors

1.4 Script Verbs Specific to this Test Module

The following are the reserved word script verbs that are specific to this test module and a description of each. Anything specified with the delimiters "<>" is required. Anything specified with the delimiters "[]" is optional.

Script Verb

Syntax and Example

Description

CONNECT

CONNECT

connect to the server whose name is specified in the “Server name” parameter of the SMTP module.

DATA

DATA <filename>
DATA

(<DATASTRING command> | <DATAFILE command>)

<ENDDATA command>

Sends a message. See comments below.

DATASTRING

DATASTRING <string>

Sends <string> as part of the message body. No server response is expected.
If <string> contains “\n”, it will be substituted with CRLF before sending

DATAFILE

DATAFILE <filename>

Sends the contents of <filename> as part of the message body. No server response is expected.

ENDDATA

ENDDATA

Specifies that all message chunks have been sent. Waits for the server response.

BDAT

BDAT <filename>

Sends the contents of <filename> as the message body. A server response is expected after message is sent.

See comments below.

AUTHENTICATE

AUTHENTICATE <user name> <password>

Authenticates using the method specified in the “Authentication method” parameter of the module. Currently, the only supported methods are “LOGIN” and “NTLM”.

<user name> and <password> are the user name and password used to authenticate. They must be given in the script as clear text.

STARTTLS

STARTTLS

Starts a TLS session. This command is processed only if the “Encryption method” parameter of the module is set to “SSL”. Otherwise the command is ignored.

Comments:

DATA

Syntax: “DATA” <filename>

or

“DATA”

*(<DATASTRING command> | <DATAFILE command>)

<ENDDATA command>

where <filename> represents the file containing the message to be sent. This file must contain the CRLF.CRLF which is to be sent at the end of the message.

DATSTRING, DATAFILE and ENDDATA commands are described below.

Description: if <filename> is specified the command translates into the following SMTP exchange:

C: DATA

S: 354 …

C: <contents of file “filename”> // only if server has given the Ok

S: 250 …

In case the response to “DATA” is an error, the module will not attempt to send the message body.

If <filename> is not specified it is assumed that the message is sent in several chunks and that the ENDDATA command specifies the end of the message. Between “DATA” and the ENDDATA command there can be any combination of DATASTRING and DATAFILE commands.

The SMTP exchange is going to be:

C: DATA

S: 354 …

C: <send body chunk>

C: <send body chunk>

…

C: <send last body chunk>

S: 250 …

where a body chunk is described by a DATASTRING or a DATAFILE command

BDAT

Syntax: “BDAT” <filename>

Description: Sends the contents of <filename> as the message body. A server response is expected after message is sent.
The SMTP exchange is:

C: BDAT <no_of_bytes_in_filename> LAST

C: <send contents of file “filename”>

S: 250 …

1.5 SMTP Commands Supported by this Test Module

The following SMTP commands are described in RFC 821 (see http://www.ietf.org) :

HELO

EHLO

QUIT

DATA

BDAT

MAIL

RCPT

AUTH

STARTTLS

VRFY

RSET

The following script commands are defined by this module :

CONNECT. Attempt to establish an SMTP socket connection

DATASTRING. Indicates the given argument should be interpreted as a literal string and transmitted (during the DATA command). May be used to transmit message headers.

DATAFILE. Indicates the given argument should be interpreted as the name of a file, and the contents of the file should be transmitted (during the DATA command).

DATAEND. Indicates that all contents of the message have now been transmitted, and a response from the server is to be expected. Example Scripts

1.5.1.1 Example 1

Send a message with 1 recipient, message body is in file body.txt. Sleep between 3 and 5 seconds afterwards.

CONNECT

EHLO

MAIL FROM: <me>

RCPT TO: someone@somewhere

DATA body.txt

QUIT

SLEEP RANDNUMBER(3000, 5000)

body.txt ends with CRLF.CRLF. Could also use BDAT instead of DATA

1.5.1.2 Example 2

Send a message with a random number of recipients. Each recipient has a random name and a random domain. Each message has a random body file.

CONNECT

EHLO

MAIL FROM: <me>

LOOP RANDNUMBER(100, 1000)

RCPT TO: rcptRANDNUMBER(1, 20)@RANDLIST(domains.txt)

ENDLOOP

DATA RANDLIST(bodies.txt)

QUIT

where “domains.txt” contains the domains to chose from (one domain per line) and “bodies.txt” contains the file names to chose from (one line name per line). Each file listed in bodies.txt ends with CRLF.CRLF.

Could also use BDAT instead of DATA. Each recipient name is in the form: rcptX were X is a number between 1 and 20.

1.5.1.3 Example 3

Send a message with headers generated programmatically.

CONNECT

EHLO

MAIL FROM: <me>

RCPT TO: <you>

DATA

DATASTRING From: me\nTo: you\n

DATASTRING Subject: test message #SEQUNUMBER(1, 100000, 10)\n

DATASTRING X-MsgId: SAMESEQUNUMBER(1, 100000, 10)\n\n

DATAFILE <chunk1.txt>

DATAFILE <chunk2.txt>

DATASTRING \n.\n

ENDDATA

QUIT

Neither chunk1.txt nor chunk2.txt contains the sequence CRLF.CRLF. In this example the ending sequence is sent explicitly. BDAT does not support this format.

1.5.1.4 Example 4

Send a message on a secure line and authenticate.

CONNECT

EHLO

STARTTLS

AUTHENTICATE user “password”

MAIL FROM: <me>

RCPT TO: <you>

DATA body.txt

QUIT

The user name and password can be unquoted (only if they consist of a single word). An empty password is represented as “”.

2 Inetload constructs

A.1. Loops

A loop is defined by:

LOOP <no_of_iterations>

1*(<command>) // one or more commands

ENDLOOP

Each command must appear on a separate line.

Nested loops are allowed.

A.2 Random generators

A random generator can refer either to a number or to a line from a file. The two constructs are:

RANDNUMBER(<low>, <high>) // random no. in the range <low> - <high>

RANDLIST(<filename>) // random line from file “filename”

A.3. Sequence generators

A sequence generator can refer either to a number or to a line from a file. The constructs are:

SEQULIST(<filename>)

First evaluation of construct will return first line from file “filename”. Second evaluation will return second line from file, etc. This is done in a circular manner.

SAMESEQULIST(<filename>)

Returns the same string as the previous SEQULIST(<filename>) call.

SEQUNUMBER(<n1>, <n2>, ID)

Each evaluation returns a sequential number in the range <n1> - <n2>. The range is associated with an ID.

SAMESEQUNUMBER(<n1>, <n2>, ID)

Returns the same number as the previous SEQUNUMBER call with the same ID

Notes:

· Depending on whether n2 > n1 or n2 < n1, you will have an ascending or descending sequence.

· First evaluation of SEQUNUMBER will associate the range with the ID. In subsequent calls, <n1> and <n2> have only a syntactic role. The returned value will be entirely based on the ID e.g.

SEQUNUMBER(20, 10, 2) // returns 20 and associates ID 2 with range 20-10

SEQUNUMBER(5, 15, 2) // returns 19. First two arguments are ignored.
// Only the ID counts.

However, it is not recommended to use this “feature”. It looks too much like a bug and may be fixed in the futureJ

Example:

The following sequence evaluates as shown below:

SEQULIST(list1.txt) // first line from list1.txt

SEQULIST(list2.txt) // first line from list2.txt

SAMESEQULIST(list1.txt) // same line as previous SEQULIST(list1.txt)

SEQUNUMBER(10, 20, 100) // returns 10 - first no. for ID 100

SEQUNUMBER(10, 20, 200) // returns 10 - first no. for ID 200

SEQUNUMBER(10, 20, 100) // returns 11 - next no. for ID 100

SAMESEQUNUMBER(10, 20, 200) // returns 10 - same no. for ID 200

SEQUNUMBER(10, 20, 200) // returns 11 - next no. for ID 200

A.4. Sleep

The sleep command is: SLEEP <no_of_milseconds>

The virtual user executing the command is put to sleep for the specified duration.


ESP Module Wizard

The ESP Module Wizard lets you create custom ESP modules in the VC++ 6.0 and later development environment. You must have VC++ Enterprise or Professional edition installed to use the module wizard. When you run the module wizard, it generates a VC++ 6.0 workspace and project that compiles in the VC++ 6.0 environment. The resulting source files implement a 'skeleton' ESP module that implements most of the functionality common to all ESP modules, including:

  • Compiling in the VC++ 6.0 Development Environment
  • Interfacing with the ESP framework
  • Sockets and SSL support
  • Script parsing support
  • Perfmon counters
  • Per host logging
  • Per module (local) logging
  • Reporting statistics and events
  • Automation compatibility

Using the Module Wizard

The following is a step-by-step guide to using the ESP Module Wizard.

Installation:

1. Run setup.exe. Setup will try to determine the correct directories for your VC++ build environment. You will be prompted for the include, lib, and wizard directories. If the default values are incorrect, enter the correct paths. ESP headers and libs are copied into your VC++ 6.0 build directories and the wizard DLL is added to the build environment.

NOTE: Custom application wizards are currently supported only in VC++ Professional and Enterprise editions. Consult your VC++ documentation for details and path information.

Creating an ESP Module

1. Start VC++ 6.0,
2. click File.New.Projects
3. select ESP Module Wizard

4. Enter the project name and path, click OK
5. Step 1 of 5:

  • Module Display Name:
    What the module user will see in ESP's "Add Module" dialog
  • Module ProgID :
    Prefix of your module's ProgID to be added to the registry. No spaces or weird characters allowed, e.g. if you enter "MyMod", "MyMod.MyMod" and "MyMod.MyMod.1" get generated in the RGS file.
  • Transport Support:
    Select "Protocol based" if you need built-in sockets, SSL support, "API based" if your module makes method calls (no sockets, SSL support included.)

6. Step 2 of 5:
Add each of your module command verbs. These are the strings specific to your module's scripting language, e.g. for POP3 you could add "USER", "PASS", and "LIST" commands. An OnXXX() method is generated for each verb you enter and a case-insensitive copy is added to the parsing logic.

If your module is protocol based, OnConnect, and OnXXXResponse() methods are also generated.

7. Step 3 of 5:
Add additional keywords from your script language. These are added to the script parsing logic, but don't cause OnXXX() methods to be generated. You can use this for adding hardcoded command arguments, e.g. the script line "LIST ALL" would yield a "OnList()" and OnListResponse() methods in step 2, and the parser would recognize the token "ALL".

NOTE: Step 2, 3: the parser only recognizes tokens composed from the alphabet 'a'-'z'...'A'...'Z'. email "lest@microsoft.com" if this is a problem for you.

8. Step 4 of 5:
Add the statistics you want your module to report. You add the friendly names, which can contain spaces, otherwise follow C identifier syntax or you'll get compiler errors.

Typically, you'll gather statistics for each command or response you send to the server, e.g. for POP3, you might have a "LIST" command and a "Number of LIST Commands" statistic that counts the number of successful "LIST" responses.

The Wizard will generate a C enum of all your statistics and code to dynamically create perfmon counters for each one. You increment each counter by calling the IncrementStat() method, passing the C enum of the desired counter, e.g. "IncrementStat(STAT_LIST_CMDS)". This call is typically made in the command's OnXXXResponse() method for protocol-driven modules.

9. Step 5 of 5:
Add any additional implementation-specific module parameters. Default implementations of the common ones (e.g. path to the script, number of user instances, etc.) are provided for you.

Enter a friendly name--C syntax + spaces are OK.select a data type, and enter a default value:

10. The summary page shows you what gets generated:

11. A VC++ 6.0 compatible project is created. Project settings are adjusted automatically to build in the default environment.

NOTE: if you get compiler errors, check your Tools.Options.Directories tab in VC++ and make sure the include and lib paths match those you entered in setup.

12. Build All, to confirm your project settings.

13. Add code in your OnXXX() and OnXXXResponse() handlers. Most CTestModuleUser methods can be overridden if the generated code or base implementation (CModUser) doesn't do what you want. For example, you may want to call LogPerfRecord() and/or IncrementStat() in your OnXXXResponse handler.

14. To test, install your module on a machine with an ESP installation. You must regsvr32 your module. The module must be in the ESP directory, or ESP must be in a directory on your path. Run ESP. Your module should appear in the 'Available Modules' list after you connect the host.

Class Overrides

The ESP module wizard creates several base classes for your module implementation. The most important of these is CTestModule (TestModule.cpp, TestModule.h), which implements the ITestModule interface which is responsible for talking to the ITestManager interface, which is called by the Administration console to start and stop your module. CTestModule contains code for initializing your module, creating user instances, logging, reporting statistics and Perfmon counters, parsing your module-specific script verbs, and setting module-wide parameters. It is usually not necessary to override members of this class.

The CModUsers class (ModUsers.cpp, ModUsers.h) implements the base functionality of ITestModuleUser, the interface that represents a single instance of a client session. Your module specific implementation of ITestModuleUser is derived from CModUsers, and will include overrides of CModUser methods as well as methods specific to your implementation, command handlers for your module's script verbs, for example.

CModUsers interfaces with the ESP transport layer, and provides default implementations of the OnError and OnConnect handlers. The ESP Module Wizard generates your module-specific implementation by deriving from CModUsers and emitting the results in CTestModuleUsers (TestModuleUsers.cpp, TestModuleUsers.h). CTestModuleUsers will contain stub handler methods for each of your script verbs called On<YourScriptVerb> and On<YourScriptVerb>Response. You add the logic specific to your protocol or API to these stubs. The base class (CModUsers) manages internal data structures such as command buffers, latency timers, etc., and provides the framework for routing calls to your On<YourScriptVerb> and On<YourScriptVerb>Response handlers. On<YourScriptVerb> is called when 'YourScriptVerb' is recognized in your script.

OnYourScriptVerb() Handler
STDMETHODIMP CTestModuleUsers::OnXXX(LPSTR szCmd);

You must provide an implementation of each OnXXX handler which is called from CTestModuleUsers::ParseSendCommand. Each OnXXX handler can return 1 of 5 possible return values:

Return Value | Effect | Notes
S_SENDNOW | Send the command to the connected server using the ESP transport | Applies to protocol modules only
S_NEXTCMD | Advance the script cursor to the next script line, read and parse the next script line | All modules
S_RECEIVENOW | Wait for a response from the server.When the response comes back from the server, CModUsers will call your implementation of CModuleUsers::HandleResponse. | Applies to protocol modules only
S_DONOTHING | ParseSendCommand returns without doing any work. | The framework returns this value when a SLEEP command is encountered in your script. Your handler should not ordinarily return this value, as your module instance will then stop pending IOs and will appear to hang. You should never do IO on a sleeping user instance, as this can cause multiple threads to reenter the same user instance resulting in unpredictable results.
an error HRESULT | Calls your OnError handler. | The base class' default OnError logs an error message, closes the connection (protocol modules), and resets the script cursor to the first line of script.

OnYourScriptVerbResponse() Handler
 STDMETHODIMP CTestModuleUsers::OnYourScriptVerbResponse(LPBYTE pbResp);

You must provide an implementation of OnXXXResponse if your module is protocol (sockets) driven and you want to process the message the server sends back in response to your XXX command. This method is called by the framework from the default implementation of CTestModuleUsers::HandleResponse, which is called by the framework when a pending Read operation completes. The response buffer is in pbResp. Typically, you will examine the response to decide what to do next: read the next script line, format and send a counterresponse on the fly (override the FormatCommand() method to help with this), or pend another Read operation. The framework decides which action to take depending on the value you return from this method:

Return Value | Effect | Notes
S_SENDNOW | Send the command to the connected server using the ESP transport | Applies to protocol modules only. You must compose the command string using FormatCommand before returning.
S_NEXTCMD | Advance the script cursor to the next script line, read and parse the next script line | All modules. This is the default.
S_RECEIVENOW | Wait for a response from the server.When the response comes back from the server, CModUsers will call your implementation of CModuleUsers::HandleResponse. | Applies to protocol modules only

FormatCommand()
 STDMETHODIMP CTestModuleUsers::FormatCommand(LPSTR szCommand);

Use this method to format a command string that is to be sent to the server. szCommand is an in/out caller supplied buffer of sufficient size to contain the command. The base implementation just appends a CRLF to szCommand. You override this method to add protocol specific characters to the outgoing command string. The resulting string must be saved in CModUsers::m_szLastCmd, as the framework calls SendBuffer(m_szLastCmd) to send command strings to the server.


1

10


ESP ReadMe.txt
Last Modified: 7-25-00

=================================
I.  ESP System Requirements
=================================
1. i386 machine
2. NT4 SP4, or Win2000
3. Internet Explorer E 5.0

=================================
II. Installation Notes for ESP
=================================

1. You must install ESP from an account that has Admin privileges
on the local machine.

2. ESP setup creates a dedicated NT user account for running modules remotely.
The account is:
    Account Name - _ESPUser
    Domain       - local machine, (or domain if machine is a DC)
    Password     - set by the user running setup

The account ESP creates has very limited user rights, specifically
"Logon As Batch Job", "Profile Single Process". It does, however, have
permissions to write to specific keys in the registry. All permissions
apply *only* to the local machine. ESP setup will try to clean the installation
before installing. As part of this process, setup deletes the service account.
If you happen to have an existing user account named "_ESPUser" on the local
machine,this account will be deleted and recreated by setup.

All modules activated from a different machine will run in the security
context of this account You should keep this in mind if you install ESP
on machines that need to be secure.

3. Error message "Unable to create service account or set DCOM security"
When setup creates the service account, it will prompt the user for a
password. For Win2k systems that are part of a domain, this password may have
to conform to the domain policy, depending on whether domain security policy
overrides local system policy. For example, the domain policy may require a minimum
password length. If the user enters a password that doesn't conform, setup will
fail with this warning.

Other causes of this warning are:
-the account setup is run in doesn't have Admin privileges
-setup couldn't open or update registry keys
-the machine is a domain controller (Win2k) and the user isn't a domain admin

4. To enable remoting on Win2K remote hosts, you must run DCOMCNFG and add "allow launch"
default launch permissions for "Everyone". Run DCOMCNFG, select the "Default Security"
tab, under "Default Launch Permissions" click "edit default". Add "Everyone" with "allow launch"
permissions. The users with "allow launch" permissions should now include "Everyone", SYSTEM,
and Interactive, and the local administrators. Note that setting enables any user to launch
DCOM servers on this host.

=================================
III. Known Issues
=================================
Date        Issue
--------    ------------------------------------------------------------
09-01-99    The start/stop logic can't always determine the state of
            modules that hang when starting or stopping. If the module's
            icon is yellow for long periods after stopping, you may have
            to kill the Admin program to stop the module.

            If the module is running remotely, you may have to kill
            DLLHOST.EXE to stop the module.

            If a module enters this state, menu items may not be properly
            enabled/disabled

09-09-99    Setup doesn't set DCOM persmissions correctly on NT5 for
            Launching User. See #4 above.

09-09-99    The UI has dependencies on NT 5 builds of some system DLLs,
            (COMCTL32.DLL) (v 5.80.xx.xxxx). Weird behavior in common
            dialogs, file open, etc., or crashes can result if this
            DLL is the wrong version. The version IE 5.0 installs
            seems to work OK.

09-14-99    Setup sometimes will fail because PERFAPI.DLL can't be initialized.
        Workaround:
        1. Make sure you're installing from an account that has
        Admin privileges on the local machine (or domain admin if target is
        a DC)
        2. Run REGEDT32. For each of the following keys:
            HKLM\SYSTEM\CurrentControlSet\Services\PerfApiCounters
                HKLM\SYSTEM\CurrentControlSet\Services\PerfApiCounters\Performance
                HKLM\Software\Microsoft\Windows NT\CurrentVersion\Perflib
        make sure the Admin account you're installing from has "Full Access"
        rights. Use the "Security" menu item to view/set these.

04-04-00    "DCOM Remoting may not work" warning on NT5 boxes.
        This is because setup creates a service account on the local machine that
        may not meet the domain (or local machine's) password security criteria.
        There is no way in general for ESP to know the domain requirements a priori.
        Note that for NT5, the domain criteria override local machine criteria. The
            password for the service account entered by the installing user must conform
            to the applicable security policy.

=================================
IV. Troubleshooting Remoting
=================================
If you have trouble getting remoting to work, check the following:

1. Verify that the ESP service account was successfully created. Go to User Admin
for the local machine  (NT4) or Computer Management.Local Users and Groups (Win2k)
and verify the account exists.

2. NT5 ONLY-You may have to add "Everyone" to the Default launch permissions.
   Use DCOMCNFG, go to "Default Security.Default Launch Permissions".
   Hit "Edit" and add "Everone". Hit Apply.

3. Go to user manager for local machine, select User Rights

4. Check Advanced under User rights.Verfiy  "Logon as batch job" and "Profile Single
   Process" rights are added for the _ESPUser account.

5. Start DCOMCNFG
    a. Click "testman"
    b. On the Security tab, check "Use custom access permissions"
       Hit edit and add "Everyone" with "Allow Access".
    c. Hit Apply
    d. Repeat from step a) for "Use custom launch permissions"
    e. Go to the Identiy tab, select "This User". Add the account
       name and password for the ESP service account from step 1.
    f. Hit Apply

6. Run regedt32
7. Verfiy the ESP service account (from step 1) has "Full Control"
   access to the following keys:

       HKLM\SYSTEM\CurrentControlSet\Services\PerfApiCounters
       HKLM\SYSTEM\CurrentControlSet\Services\PerfApiCounters\Performance
       HKLM\Software\Microsoft\Windows NT\CurrentVersion\Perflib

   Use the "Security.Permissions" menu of regedt32 to check these. Add
   the ESP service account if necessary.