Standard
WEBDAV Test Suite
Documentation
Abstract
This document describes a general and extensible, open source based, WebDAV server testing environment. The testing environment consists of a test suite, containing a series of XML test cases, and the necessary Java programs to execute the test suite and display the results.
Each test case is mainly made up of WebDAV commands and is expressed in XML. The syntax of the tests is fully described within this document.
Currently, the test suite allows for the testing of the standard behavior of a WebDAV class 2 server. The test suite covers the areas of functional, performance and multi-user behavior. Each test suite execution generates an XML protocol report file to allow for error checking and evaluation.
The ‘Ant’ tool controls the test suite and is able to create a deployable, ready to use, zipped file. Further test suite extensions will cover the ACL, Delta-V and DASL standards. This testing environment could be the basis of automated interoperability tests and standard conformance.
This testing environment was originally developed by Software AG and is now donated to the Jakarta-Slide project.
Contents
Structure of Test With Repeater
Diagram of Specification Element
The WebDAV Test Suite consists of a series of test cases distributed within a directory tree.
All test cases are written as well-formed and valid XML documents, they all conform to a specified DTD. An explanation of well formed and valid can be found here: http://www.xml.com/pub/a/98/10/guide3.html.
Each test case consists of several steps, with each step containing one WebDAV command. The XML files are passed into a T-Processor (Explained fully later). The T-Processor program picks up the WebDAV requests from the XML document and sends them to the server. The server will carry out this request and return a response. This is picked up by T-Processor and compared against the expected response defined in the XML document. A rough example of an XML test case is shown further down.
![]()
test.xml
<test>
<request>
<command> Put
/location/document.html </command> <!-- A put command is
sent to the server to put a document at this location. T-Processor sends this
request to the server. -->
</request>
<response>
<command> 200 OK </command>
<!-- The expected response is
declared here. T-Processor will check the response code from the server against
this to see if they match. If they do, it means the test has been successful.
-->
</response>
</test>
NOTE: This example does NOT accurately show the syntax required and is a simplified version for ease of explanation.
The test above will cause the T-Processor to issue a put command to the specified location. The expected response is shown in this test case as being a “200 OK” Response Code.
To summarize; T-Processor passes the requests outlined in the XML document to the server, the servers response is checked by T-Processor against the expected response given in the XML test case. If these match, the T-Processor will pass the test as successful.
All the test cases require a DTD specified. The DTD describes how the test case should be structured.
For example, it declares that within a ‘request’ element, there must be a ‘command’, and that there may be ‘header’s and a ‘body’. If either of these does not exist within a request element, TProcessor will throw an error.
All test cases have a declaration at the start giving the location of the DTD that TProcessor will use to ensure that the structure of the test case is correct. A test will not run without this declaration.
Request For Example, a
Put command
A test is made up of many step elements.
Within each of these step elements there is a request and a response defined.
As an XML document the layout is as follows:
<test> <step> <request> </request> <response> </response> </step> </test>
The XML test cases may also contain control statements. These are ‘Repeat’ and ‘Thread’.
The repeat control allows a step to be executed n times. The thread control allows a step to be threaded to the server. This simulates multiple users.
|

As an XML document the layout is as follows:
<test> <repeater
repeatCount="n”> <step>
<!--
Step will iterate n times --> <request> </request> <response> </response> </step> </repeater> </test>
As an XML document the layout is as follows:
<test> <thread> <repeater
repeatCount="n”> <!-- Repeater element is optional --> <step>
<!--
Step will iterate n times --> <request> </request> <response> </response> </step> </repeater> </thread> </test>
The current directory structure is as follows:

· All: This is the default, compiles the suite and prepares a deployable zipped file. (It calls the targets make and dist).
· make: compiles all Java sources.
· dist: Creates a deployable zipped file.
Usage:
tprocessor [options]
Options:
-davhost <webdavserver_host> (default: localhost)
-davport <webdavserver_port> (default: 8080)
-davname <webdavserver_name> (default: slide)
-store <store_to_operate_on> (default: files)
-users <number_of_users> (default: 10)
-iterations <number_of_iterations>
(default: 10)
-testcase <xmltestcase_path> (relative to the home directory)
-pattern <xmltestcase_pattern> (wildard is *, file separator is \\)
If
both, -testcase and -pattern are omitted, all testcases are executed.
Examples:
(1) Execute all testcases
tprocessor
(2) Execute one specific testcase
tprocessor -testcase
\testsuite\junit\xmltestcases\copy\code\copy201.xml
(3) Execute all XML testcases which start
with 'copy'
tprocessor -pattern *\\copy*.xml
(4) Execute all XML testcases which are
bellow \testsuite\junit\xmltestcases\copy
tprocessor -pattern *\\copy\\*.xml
Usage:
terrorsreport [options]
Options:
-infile <testsuite_result_xml> (default:
..\testsuite\junit\testcasesresults.xml)
-outfile <errors_report> (default:
..\testsuite\junit\errors.txt; also
allowed: stdout, stderr)
Contains all the sources needed to execute
the test suite (mainly T-Processor)
This folder contains all the XML test cases in nested self-descriptive folders. For example, ‘Copy’ contains all the XML test cases that test the WebDAV Copy command. This directory is structured mainly into 4 sub-directories:
· Functional: The test cases for the functional tests for a class 2 WebDAV server.
· Multi-user: Multi user tests with a simulated load (per default 10 Users).
· Performance: Performance tests (.e.g. a Put is tested with different content size).
· ContentDirectory: This folder contains all resource files that are used within the test suite. The Put and Get commands all use a file reference to point to the location of these resources. A Put command will ‘Put’ one of these files to the server. Therefore, if the files in here are changed but the names kept the same, all test programs will run using these new resources. This means it is possible to run the test suite with large files, simply by replacing the current files with larger equivalents. For example, to use a larger HTML file, copy the new resource into this directory and give it the name of the already existing HTML file.
The T-Processor is at the heart of the XML Test Suite. T-Processor takes an XML test case as an argument and parses it to ensure it is valid. The client request is extracted and passed to the server. The server’s response is picked up by T-Processor and compared with the expected server response contained in the XML test document. T-Processor will output to the console window, or to an XML file, all executed steps. This details the method, the URL, the result, and the time taken for the step. The result of the entire test is shown at the end. The overall result, cumulative time, number of steps executed and the number of errors are all shown.
Starting test case: C:\test.xml <!-- Name of
test case with full path.-->
<testCase>
<fileName>test.xml </fileName> <!-- Name of test
case. -->
<exceuteStep> <!-- This test case has only one step.
-->
<method>PUT</method>
<!-- It puts a file, -->
<url> server/test.html </url> <!-- To this
location. --> <result>Success</result>
<!-- The T-Processor receives the response code from the server and
compares it against the one defined in the XML test case. If they match,
‘Success’ is returned. -->
<time>100</time> <!-- Total time taken for step.
-->
</exceuteStep>
<result>Success</result> <!-- The overall result
was a success. -->
<time>120</time> <!-- How long the entire test
took. --> <testElementCount>1</testElementCount>
<!-- How many steps were executed. --> <testElementErrors>0</testElementErrors>
<!-- How many errors occurred. -->
</testCase>
Following class can be used in conjunction with the “Junit” tool:
This class will execute the complete WebDAV test suite.
The DTD defines how each XML test case must be structured. It declares the order in which the elements must appear within the test case. The DTD is located at: Jakarta-slide/testsuite/testsuite/JUNIT/Tprocessor.dtd. It looks as follows:
<?xml
version='1.0' encoding='UTF-8' ?> <!--Generated
by XML Authority--> <!ELEMENT
test (specification? , (step | repeater | thread)+ , cleanup? )> <!ELEMENT
cleanup (step | repeater)+> <!ELEMENT
thread (step | repeater)+> <!ELEMENT
repeater (step | repeater | thread)+> <!ATTLIST
repeater repeatCount CDATA
'1' varDefinition
CDATA '' varUsage
CDATA '' > <!ELEMENT
assign (#PCDATA)> <!ATTLIST
assign varDefinition CDATA '' varUsage CDATA '' > <!ELEMENT
step (assign*, user? , password? , request , response)> <!ATTLIST
step executeIn CDATA '' > <!ELEMENT
request (command , header* , body?)> <!ELEMENT
response (command , header* , body?)> <!ELEMENT
specification (abstract+ , pre-Requisite? , description+ , expectedResult+
, exception?)> <!ELEMENT
header (#PCDATA)> <!ATTLIST
header varDefinition CDATA '' varUsage CDATA '' > <!ELEMENT
command (#PCDATA)> <!ATTLIST
command varDefinition CDATA '' varUsage CDATA '' > <!ELEMENT
body (#PCDATA)> <!ATTLIST
body varDefinition CDATA '' varUsage CDATA '' fileReference CDATA '' > <!ELEMENT
abstract (#PCDATA)> <!ELEMENT
pre-Requisite (#PCDATA)> <!ELEMENT
description (#PCDATA)> <!ELEMENT
expectedResult (#PCDATA)> <!ELEMENT
exception (#PCDATA)> <!ELEMENT
user (#PCDATA)> <!ATTLIST
user varDefinition CDATA '' varUsage CDATA '' > <!ELEMENT
password (#PCDATA)> <!ATTLIST
password varDefinition CDATA '' varUsage
CDATA '' >
KEY:
REQUIRED
OPTIONAL
Arrows indicate which element may be used after its closure.
Bold parts in the XML layouts indicate the sections that have just been shown in the corresponding diagram.

<test>
<Specification>
</Specification>
<Step
or Repeater or Thread>
</Step
or Repeater or Thread>
<Cleanup>
</Cleanup>
</test>
<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected
Result></Expected Result>
<Exception></Exception>
</Specification>
<Step or Repeater or Thread>
</Step or Repeater or Thread>
<Cleanup>
</Cleanup>
</test>

<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected Result></Expected Result>
<Exception></Exception>
</Specification>
<Step>
<assign></assign>
<user></user>
<password></password>
<request></request>
<response></response>
</Step>
<Cleanup>
</Cleanup>
</test>
<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected Result></Expected Result>
<Exception></Exception>
</Specification>
<Repeater>
<step></step>
OR
<repeater></repeater>
OR
<thread></thread>
</Repeater>
<Cleanup>
</Cleanup>
</test>
<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected Result></Expected Result>
<Exception></Exception>
</Specification>
<Thread>
<step></step>
OR
<repeater></repeater>
</Thread>
<Cleanup>
</Cleanup>
</test>

<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected
Result></Expected Result>
<Exception></Exception>
</Specification>
<Step>
<assign></assign>
<user></user>
<password></password>
<request></request>
<response></response>
</Step>
OR
<Thread>
<step></step>
OR
<repeater></repeater>
</Thread>
OR
<Repeater>
<step></step>
OR
<repeater></repeater>
OR
<thread></thread>
</Repeater>
<Cleanup>
<step></step>
OR
<repeater></repeater>
</Cleanup>
</test>

<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected Result></Expected Result>
<Exception></Exception>
</Specification>
<Step>
<assign></assign>
<user></user>
<password></password>
<request>
<command></command>
<header></header>
<body></body>
</request>
<response>
</response>
</Step>
<Cleanup>
</Cleanup>
</test>

![]()
<test>
<Specification>
<Abstract></Abstract>
<Pre-Requisite></Pre-Requisite>
<Description></Description>
<Expected Result></Expected Result>
<Exception></Exception>
</Specification>
<Step>
<assign></assign>
<user></user>
<password></password>
<request>
<command></command>
<header></header>
<body></body>
</request>
<response>
<command></command>
<header></header>
<body></body>
</response>
</Step>
<Cleanup>
</Cleanup>
</test>
As explained earlier, when TProcessor receives a response from the server, it is compared against the expected response defined within the XML test case. By using the TProcessor.xml file, it is possible to exclude some of the returned headers from being compared. For example, the last modified header that is returned will be different each time the test case is run. It would be impossible to define an expected value for this element. Therefore, TProcessor is configured to exclude it. No matter what the response is for “last modified” the test will pass.
The TProcessor.xml document also allows for exclusion of XML elements. For example, PropFind response elements.
When a JUNIT test is run, the results are output to a console window and also to an XML file. The XML file is located at: Jakarta-slide/testsuite/testsuite/junit/testcasesresults.xml. It contains the name of each test case that has been run and the details of each step executed within it. It also indicates whether the step has been successful. If the step has failed, TProcessor will indicate both what was expected and what was actually received.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE testSuite SYSTEM "testCasesResults.dtd"> <testSuite>
<excecutionDate>DD.MM.YY HH:MM</excecutionDate>
<resultFileName>testCasesResults.xml</resultFileName> <testCase>
<fileName>test.xml</fileName> <!-- Name of test
case. --> <exceuteStep>
<method>PUT</method>
<url>/server/files/test.html</url>
<result>Success</result>
<time>100</time> </exceuteStep>
<result>Success</result>
<time>100</time>
<testElementCount>5</testElementCount>
<testElementErrors>0</testElementErrors> </testCase>
The syntax for T-Processor is very simple. The current test cases and DTD example above should give you a rough idea as to the layout and syntax.
However, there are a few parts that need to be explained.
NOTE: Some of these code examples are not complete, XML definitions, DTD definitions, specification, header and body for request, response and cleanup have been left out for ease of explanation.
Variables are used to store and carry information from one step to another (E.g. a lock token) or to hold values throughout the test case (E.g. control of parallel threads). Variables can be used or declared within a step, or passed into the test suite via the Java command line.
Before an already existing variable can be used its name must be specified within the element that requires the variable:
<command
varUsage=”varName”>………</command The variable varName is being
declared for use within the command attribute. This is done with the
varUsage command.
The variable varName can now be accessed within the attribute:
<command
varUsage=”varName”>
%varName% </command> <!-- Note the use of
“%” around the varName showing that the value of the variable is used.
-->
It is possible to define new “user defined” variables via the “assign” XML
element:
<assign varDefinition = “varName“> initialvalue
</assign> <!--
A new variable has been created with the value of “initialvalue”. -->
These user variables are explained more below.
There are four type of variables used by Tprocessor:
1. User Defined;
2. Global Variables;
3. Repeat Variables;
4. Automated Variables.
A user-defined variable can be declared and assigned a value within a step. The following piece of code defines and uses a variable called “aVar”.
<assign varDefinition = “aVar”> initialValue</assign> <!-- A variable
called “aVar” is declared and assigned the string “initialValue” --> <assign varUsage = “aVar”, varDefinition=”aVar”> %aVar% - -
Next</assign> <!-- varUsage used to declare that variable is to be used with
this element. To use the variable, it must be enclosed by “%”. -->
After the execution of the above statements the value of “aVar” would be “initialValue - - Next”. It should be noted that before “aVar” can be used (with the syntax “%aVar%”), its use must be declared in the tag of the element wishing to use the variable.
All Global Variables are initialized during TProcessor start-up. They are assigned a value when TProcessor is called on the Java command line. The following code is used to assign a global variable.
-Dxdav.globalVariable<nameOfGlobalVariable>=<value> <!-- For example, -Dxdav.globalVariableServerName=slide
-->
The global variable can then be used as follows:
<element
varUsage="globalVariable<name>">..%globalVariable<name>%..</element>
<!--
For example, <element
varUsage=”globalVariableServerName” > %globalVariableServerName%
<element> -->
There are five global variables used in the WebDAV test suite. globalVariableServerName, globalVariableCollection, globalVariableUsers, globalVariableIterationCount, and globalVariableIterationCountSmall.
GlobalVariableServerName is passed in by the T-Processor script. This is the name of your server that the command will be carried out upon. For example, if “slide” is passed in, a Put command would put to the location http://localhost/slide/…..
GlobalVariableCollection is passed in by the T-Processor script. This is the collection on the server that the XML tests use as a root directory.
For example, if ‘files’ is passed
in, ‘files’ will be used as root and all Mkcols, Puts ETC will be derived from
this. EG, http://localhost/slide/files/
So to use the two together the entire statement looks as follows:
<command varUsage="
globalVariableServer,globalVariableCollection "> <!-- Defines
that globalVariableCollection and
globalVariableServer are used within this command. --> MKCOL /%globalVariableServer%/%globalVariableCollection%/test
HTTP/1.1 <!--
Using the example above, assuming ‘slide’ has been passed in as
globalVariableServer and ‘files’ has been passed in as
globalVariableCollection, this command will resolve to: MKCOL
/slide/files/test/. A collection test is created at the location
slide/files. --> </command> <!-- Command closed -->
GlobalVariableUsers is passed in by the T-Processor script. This is the amount of parallel users that the tester wishes to simulate using the server.
The variable is used in conjunction with the repeat counter to determine how many user threads are opened. Most of the multi-user test cases, within the XML test suite, use this variable to control how many threads are generated. Therefore, it is possible to run the test suite with as many simulated users as required. For example, with the code below, if ‘5’ is passed in as ‘globalVariableUsers’, 5 threads are opened simulating 5 users. They will all then try to put at the same time. If ‘100’ is passed in, 100 users will try to put at the same time.
Another example is shown in the Repeat Counter section.
<repeater
varUsage="globalVariableUsers"
repeatCount="%globalVariableUsers%"> <!--
GlobalVariableUsers is declared as being used. The value of it is then
assigned to the repeat counter.--> <thread> <!--
Threads equal to the repeatCount, which has the same value as
globalVariableUsers, are opened.
--> <step> <command PUT ……> .. </command> </step> </thread> </repeater>
GlobalVariableIterationCount is passed in by the Tprocessor script. This can be used to control repeat counters. Within the test suite there are tests that repeat an individual step, sometimes within a thread. This iteration is controlled by the value of GlobalVariableIterationCount. An explanation of the repeater is given later. Most of the Multi User test cases within the XML test suite use repeat counters controlled by GlobalVariableIterationCount. This means that it is possible to have greater control of the test cases. It is possible to test a server by only passing in ‘5’ as an iteration count. Steps using the variable will only be iterated 5 times. This would mean, in the example below, that “globalVaribleUsers” attempt to Put 5 times. However, it would also be possible to put a high load onto a server by setting this variable to 100. This would mean, in the example below, that “globalVaribleUsers” attempt to Put 100 times.
<repeater
varUsage="globalVariableUsers"
repeatCount="%globalVariableUsers%"> <thread> <repeater varUsage="globalVariableIterationCount"
repeatCount="%globalVariableIterationCount%"> <step> <!-- The step is
iterated an amount of times equal to %GlobalVariableIterationCount%. --> ….. </step> </repeater> </thread> </repeater>
GlobalVariableIterationCountSmall is passed in by the Tprocessor script. This has a similar function to the GlobalVariableIterationCount. Within the XML Test Suite, it is used when repeating copy and move commands. These test programs normally copy or move from a-b then b-a. These two steps only need to iterate half as many times to create the same amount of load as other tests. For example, if 10 is passed in as GlobalVariableIterationCountSmall, the code below will cause the 2 copy commands to be executed 10 times by %globalVariableUsers%. This means that each user sends 20 separate copy commands to the server.
<repeater
varUsage="globalVariableUsers"
repeatCount="%globalVariableUsers%"> <thread> <repeater
varUsage="globalVariableIterationCountSmall"
repeatCount="%globalVariableIterationCountSmall%"> <!--
GlobalVariableIterationCountSmall is declared as being used. The value of
it is then assigned to the repeat counter. --> <step> <!-- The step is
iterated an amount of times equal to %GlobalVariableIterationCountSmall%.
--> <command>Copy
/server/files/a/test.html <destination>server/files/b/test.html </step>
<step> <command>Copy
/server/files/b/test.html <destination>server/files/a/test.html </step> </repeater> </thread> </repeater>
A repeat variable is defined within the repeat element. At each iteration, the variable is assigned the current value of the repeat counter (repeatCount). The repeatCount starts at 1 and increments by 1 after each iteration.
<repeater
varDefinition="i" repeatCount=”10”> <!-- The variable “i” will run alongside the
repeatCount holding the same value. It will be incremented, by one, at the
same time.--> <step> <!-- The step is
iterated 10 times. --> <command>PUT
/server/files/test/%I%.html</command> <!-- “i” will increment along with the
repeat counter meaning this statement will Put files 1.html - 10.html
inclusive.--> </step> </repeater>
Currently there is only one type of automatic variable defined. This is used to store the value of a lock token. When a successful lock is issued, a new automatic variable will be created with the name “automaticVariable<n>”, where <n> is the current number of variables already defined plus one. For example, the first lock command would result in the generation of a variable named “automaticVariable1”, the next lock command will use “automaticVariable2” and so on. It should be noted that at each repeat iteration, the automated variables created in the previous iteration are removed again.
At the start of each test case, it must be declared that the file is XML. This should be defined with the following line:
|
Following the XML declaration, a DTD needs to be defined at the beginning of each test case. This allows TProcessor to validate the test to ensure it is valid XML. A DTD is defined as follows:
<!DOCTYPE test SYSTEM
"c:\Tprocessor.dtd">
With the XML test suite the DTD is located at:
Jakarta-slide/testsuite/testsuite/JUNIT/Tprocessor.dtd. All test cases reference this. It is possible to use relative paths to point to the DTD. All test cases within the XML test suite use a relative path. Therefore, the DTD should not be moved.
The thread command allows simulation of several commands being issued to the server at once. The steps specified in the first thread are executed in parallel to those specified in the second thread. Within each thread, the steps are executed in the same order as specified in the test case. Thread tags can be placed around a step or a repeater.
|
Because the thread is normally used with the repeater, it is explained fully below.
The repeater allows steps to be iterated. Anything within repeater tags will be executed the specified number of times. The repeater can be placed around a step, a thread or, to allow for nesting, a repeater.
NOTE: In the following examples some of the exact coding has been omitted and replaced with ‘….’. This is for ease of explanation.
For example, to loop a series of steps ‘n’ times, the following code would be used.
Example 1 <repeater repeatCount="n"> <!--
repeat n times. Change this value to the number of iterations required.
Everything within the repeater tags will iterate n times. --> <step>….</step> <step>….</step> . . <step>….</step> <step>….</step> </repeater>
The repeater can be linked to the global variable “GlobalVariableIterationCount”. This causes all commands within the repeat tags to iterate to the value of “GlobalVariableIterationCount”.
For example to loop a step “GlobalVariableIterationCount” times the following piece of code would be used:
Example 2 <repeater
varUsage="globalVariableIterationCount"
repeatCount="%globalVariableIterationCount%"> <!-- This declares that the command uses
globalVariableCount and assigns the value to the repeatCount. Note the use
of % around the variable when it is being used. --> <step> … </step> </repeater>
The repeater can be linked to the thread command allowing simulation of multiple users sending requests to the server.
For example, to allow ten users to simultaneously create a collection, the following piece of code would be used. In this example, 10 Threads are opened. Each thread then executes, in parallel, the steps specified, in the same order as they appear within the test case.
Example 3 <repeater repeatCount="10"> <thread> <step> <command MKCOL.....>
- This command is threaded 10 times simulating 10 users all issuing a mkcol
command at once. </step> </thread> </repeater>
More than one step can be placed within a repeater:
Example 4 <repeater repeatCount="5"> <thread> <step> <command
MKCOL.....> - This command is threaded 5 times simulating 5 users
all issuing a mkcol command at once. </step> <step> <command PUT.....>
- This command is threaded 5 times simulating 5 users all issuing a put
command at once. </step> </thread> </repeater>
Many threads can be used, allowing for the simulation of many users issuing many commands.
For example, 1 user could carry out a MKCOL whilst another Puts a resource.
Example 5 <thread> <step> <command MKCOL.....> </step> </thread> <thread> <step> <command PUT.....> </step> </thread> <!--
Both commands are threaded meaning one user performs a MKCOL whilst another
PUTs. -->
As well as simulating n users issuing a command once (Example 4 and 5), it is also possible to simulate n users carrying out a command n times.
For example, this piece of code simulates 5 users doing 10 Puts. The Put commands are threaded, so it would be correct to think of this test case as showing 5 users all putting at the same time, then repeating 10 times.
<repeater repeatCount="5" > <thread> <repeater
repeatCount="10"> <step> <request>
<command>PUT…</command> </request> </step> </repeater> </thread> </repeater>
The only limitation with the above pieces of code is that as only one Put command is issued, only one URL can be specified. This, in itself, is a useful test; many users issuing commands to the same resource. If n users are performing a put on to the same resource, either a response code of “200 OK” or “409 Conflict” is normally expected. To pick up multiple response codes, all expected codes should be enclosed in brackets, separated by a comma, with no whitespace.
<response> <command>HTTP/1.0 (200,409) OK</command> <!--A 200 OK and 409
are expected. If either of these response codes are received, they will be
passed. -->
However, sometimes it is useful to test a server by simulating many users issuing commands to separate resources. If this is required, separate collections or resources need to be created and then the commands issued against those.
<test> <step> <command>
MKCOL /server/test/new HTTP/1.1</command> …. </step> <!-- Because so
many files are going to exist at the end, it is easier to have one
containing collection that can be deleted at cleanup, rather than having
to use a repeater and delete each individual file. --> <repeater
varUsage="globalVariableUsers"
varDefinition="userNumber" repeatCount= "%globalVariableUsers%"> <!-- Declarations and setting of
variables for repeater. GlobalVariableUsers is declared as being
used. The value is then assigned
to repeatCount. -->
<step>
<request> <command
varUsage="userNumber”> MKCOL /server/test/new/user%userNumber%
HTTP/1.1</command> <!-- The variable userNumber is
incremented with each repeat loop. It is set to 1 to start with and will
create /user1, /user2, /user3 and so on until the repeater stops. --> ….
</step> </repeater> <repeater
varUsage="globalVariableUsers"
varDefinition="userNumber"
repeatCount="%globalVariableUsers%">
<thread>
<repeater repeatCount="50">
<step> <request> <command
varUsage="userNumber">PUT /server/test/new/user%userNumber%/file.html
HTTP/1.1</command> <!-- %userNumber% is resolved to
point to the users individual collections. --> …..
</step>
</repeater>
</thread> </repeater> <!-- %globalVariableUsers%
number of threads are created, one for each user. The Put command is
issued 50 times by each user. Care should be taken with the placing of the
thread tags. If not, in the case of this test, User 1 would put 50 times,
then user 2, then user 3 and so on. --> <cleanup> <step> <command>
DELETE /server/test/new HTTP/1.1</command> ….. <step> </cleanup> </test>
A step is essentially a WebDAV command. It is made up of 2 parts, a request and a response. The ‘request’ is the part picked up by T-Processor and sent to the server. Within the request is a command (containing the WebDAV command and URI) and several headers. The response is the part compared with the actual received response from the server. Within the response is a command (containing the expected response code) and several headers. The structure of a step is exactly the same as the corresponding WebDAV request. The only difference being that variables may be used and certain headers can be left out.
For example, the following code would send a Put command to the server.
<step> <request> <command>PUT
/server/test/put.html HTTP/1.1</command> <!-- The Command
contains: The command to be sent, then the URL for the command to be
carried out upon. --> <header>Translate:
f</header> <header>Connection:
Keep-Alive</header> <!--All standard headers
required for a put command. --> <body> <!--
The entire HTML document is entered. --> </body> </request> <response> <!-- This
response must match the received response to result in a successful test
--> <command>HTTP/1.0
200 OK</command> <!--This is the major part that T-Processor checks
for a match. The Response Code. --> <header>Date: </header> <!-- The date header can contain any date.
T-Processor does not check for an exact match. --> <header>Content-Language:
en</header> </response> </step>
The requests and response headers within the steps are unique to each command. Most are self explanatory but a few need explaining.
A put command requires the document that is to be ‘put’, declared within the body.
<step>
<request>
<command>PUT /server/test/resource1.html
HTTP/1.1</command>
<header>Translate: f</header>
<header>Connection: Keep-Alive</header>
<body><![CDATA[<html><head></head><body><FONT
SIZE="+1">This is a Test html
Document</FONT></br></body></html>]]></body>
<!-- This is the actual HTML document that will be uploaded.
-->
</request>
<response>
<command>HTTP/1.0 200 OK</command>
<header>Date: </header>
<header>Content-Language: en</header>
</response> </step>
For example, this command puts an HTML document.
Sometimes it is required for large documents to be put onto the server. It is impractical to include an HTML document of a large size into the body of a put statement. To assist with this, it is possible to define a path within the put statement, pointing to the location of the file to be ‘put’. To achieve this, a “fileReference” is defined within the body of the request and given the path of the file. For example, this piece of code would put the document test.html stored in C:\testprograms to the location specified.
<step>
<request>
<command>PUT /server/test/test.html HTTP/1.1</command>
<header>Accept-Language: en-us</header>
<header>Translate: f</header>
<header>User-Agent: Microsoft Data Access Internet Publishing
Provider
DAV</header>
<header>Connection: Keep-Alive</header> <body
fileReference="C:\testprograms\test.html "></body> <!--
The file at the
fileReference location will be uploaded to the server. Any data in the body
tags will be ignored. -->
</request>
<response>
<command>HTTP/1.0 200 OK</command>
<header>Content-Language: en</header>
</response> </step>
Using this option, it is possible to upload any file including image and audio files.
All test cases within the XML test suite currently use this upload option with the Put and Get commands. The individual files used are stored in the ContentDirectory. This option enables the test suite to be more flexible and powerful. It means that the entire test suite can be run with large or small files. All that is needed is for the files in this directory to be changed. As long as the name and location remains the same, the new resources will be used. It is also possible to use a relative path to specify the location of the resource that will be ‘put’. All test cases within the XML test suite use relative paths, therefore the contentDirectory folder, or its contents, should not be moved. Otherwise the test cases will not function correctly.
Within the body of the Get response statement, the expected content is defined. TProcessor compares this against the body received from the server, to check that the resource has been correctly returned.
<step> <request>
<command>GET /server/test/file.html HTTP/1.1</command> <!-- The location of
the file that is being sought. --> <header>Accept: */*</header> <header>Accept-Encoding: gzip,
deflate</header> <header>Connection: Keep-Alive</header> </request> <response> <command>HTTP/1.0 200 OK</command> <header>Content-Type:
text/html</header> <body> <![CDATA[<html><head></head><body><FONT
SIZE="+1">This is a Test html
Document</FONT></br></body></html>]]> <!-- The exact html that is
expected back is defined within the body. --> </body> </response> </step>
Instead of hard coding the expected response, it is possible to enter the location of a file that TProcessor will compare the received body against.
<step> <request>
<command>GET /server/test/file.html HTTP/1.1</command> <!-- The location of
the file that is being sought. --> <header>Accept:
*/*</header> <header>Accept-Encoding: gzip,
deflate</header> <header>Connection: Keep-Alive</header> </request> <response> <command>HTTP/1.0 200 OK</command> <header>Content-Type:
text/html</header> <body fileReference="C:\test.html">
<!-- The location of the file that will be
compared against the received response from the server. Any text within the
body tags is ignored, the file always takes priority. -->
</body> </response> </step>
All Gets within the XML Test Suite use this file reference. This means that the test suite can be more powerful as it is possible to easily change the content of these resources. All the files used by the file reference commands are located in the ContentDirectory folder. If any new resource is placed in this directory and given the name of an already existing one, this new resource will be used in its place. All test cases using the previous file will then automatically use this new resource for PUTS and GETS.
It also means the test cases are kept as small as possible. For example, if 50 files are to be put at different locations, 50 separate put statements are needed. Without file references, the file to be put would need to be hard coded into the body of each put command. If the same file is being put each time, this means a lot of replicated code. Using a file reference, only one line is needed in each statement to put the same resource. It is also possible to use relative paths to reference the file. All test cases within the XML test suite use file references. Therefore it is important that the contentDirectory folder, or the files within it, is not moved. Otherwise the tests will not function correctly.
When a lock is placed upon a resource, a lock token is issued. This is a unique key that must be sent again to unlock the resource.
This lock token is stored by the T-Processor in an automated variable. The variable is used again in the unlock command.
<step> <request> <command>LOCK
/server/test/file.html HTTP/1.1</command> <!-- Command
to lock resource at specified URI. --> <header>Connection: Keep-Alive,
TE</header> <header>TE: trailers, deflate, gzip,
compress</header> <header>Timeout: Second-604800</header> <header>Accept-Encoding: deflate, gzip,
x-gzip, compress, x-compress</header> <header>Content-type:
text/html</header> <!--
All standard headers needed for lock. --> <body><![CDATA[<?xml
version="1.0"?><A:lockinfo
xmlns:A="DAV:"><A:locktype><A:write/></A:locktype><A:lockscope><A:exclusive/></A:lockscope><A:owner><A:href></A:href></A:owner></A:lockinfo>]]></body>
<!--
The contents of the lockscope tags, in this case ‘exclusive’, allow control
of the scope of the lock. --> </request> <response> <co