User Sequences in Test Suites
Defensics offers testing solutions for a broad range of protocols. Many of these protocols, such as TCP or SIP, can involve complex messaging sequences or structures. In Defensics, these types of exchanges are defined in user sequences. By customizing user sequences, you can gain more granular control in testing such protocols.
This solution note describes the basics of how to edit user sequences and accompanying messages used in Defensics test suites in general. You can find protocol-specific instructions on using user sequences in the relevant test suite documentation.
Overview
Each Defensics test suite targets a specific protocol implementation, such as HTTP Server or HTTP Client. A test suite is built around a suite-specific data model, which is an internal representation of all of the target protocol's methods, fields, and acceptable value types, lengths, and ranges. If the target protocol allows message exchanging, then those exchanges are supported by the data model and exposed through the test suite as user sequences.
Sequence Structure
A sequence comprises a set of incoming and outgoing messages. The incoming messages are received from the test target. The outgoing messages are managed by the Defensics test runner. A sequence provides a conversational structure between Defensics and the test target. Defensics uses the sequence to generate an anomalized outgoing message in each test case; for a given test run, the same sequence can be used for hundreds or thousands of test cases, with each test case anomalized in a slightly different way.
A sequence will have a name, and optionally a description.
This example, taken from the HTTP Server test suite, depicts a relatively simple sequence, composed of a request followed by a response:
<sequence name="http-diag">
<description name="HTTP request and response">
Send an HTTP request and wait for an HTTP response.
</description>
<send name="request" type="http-request"
description="HTTP Request">
<content file="request.txt" format="text"/>
</send>
<recv name="response" type="http-response"
description="HTTP Response">
</recv>
</sequence>
For more complex protocols such as SIP, in which transactions are stateful and message passing often resembles a conversation, we need a way to "remember" select data from outgoing messages in order to anticipate its presence in incoming messages. For this purpose, we can use the <store> and <match> element blocks.
With a <store> element block, you can store some chunk of data from an outgoing message. Later in the same sequence, you can use a <match> element block to retrieve the stored data. Any number of <store> elements can appear within a <send> block; likewise, any number of <match> elements can appear within a <recv> block. You can see this in the following sequence, which is from the SIP UAS test suite:
<sequence name="used-dialog" setting="user-sequence-file">
<description name="MESSAGE request">
A sequence sending a MESSAGE request and
expecting a success response.
</description>
<send name="message-request" type="sip-message"
description="MESSAGE request">
<content file="sip-message.txx" format="text"/>
<store attribute="request-uri" setting="callee-uri"/>
<store attribute="to-uri" setting="callee-uri"/>
<store attribute="from-uri" setting="caller-uri"/>
<store attribute="call-id">!sip:call-id . . .
<!-- rule definition redacted for clarity -->
</store>
<store attribute="contact">sip-tel-uri</store>
<store attribute="cseq">$cseq-number</store>
<store attribute="from-tag">
$from-tag-number '-Test-' !casenumber '0'
</store>
</send>
<recv name="message-response-ok" type="sip-message"
description="OK response">
<match attribute="call-id">!sip:call-id $message-request:call-id</match>
<match attribute="response-code">success</match>
</recv>
</sequence>
The outgoing message is defined in a <send> block that contains a number of <store> elements used to store data. The incoming message, defined in the <recv> block, contains a <match> element for call-id, which retrieves the call ID data that was stored in the outgoing message.
Concepts
User sequences are formatted as XML, and can be accessed through the Defensics sequence editor. At heart, a user sequence represents a sequence of messages:
- Sequences refer to a set of messages to be exchanged in a specific sequential order. These definitions are notated in sequence files (
.seq). Sequences can support dynamic message-handling behavior. - Messages refer to incoming or outgoing protocol data units within a sequence. Messages can be defined using message types, message attributes, or message fields, and their content may be included via message content files.
Messages are either incoming or outgoing, relative to the Defensics test suite and its relation to the test target. Outgoing messages are generated by the test suite and sent to the target, and incoming messages are received by the test suite from the target. In a sequence, outgoing messages are defined by <send> element blocks, and incoming messages are defined by <recv> element blocks.
- Message types refer to the types of messages that can be sent with the protocol, as defined in the test suite data model. Message types are derived from protocol specification, and can be assigned to the
typeattribute of incoming or outgoing message elements in a sequence.
http-request, which represents a message sent with the GET method in the HTTP protocol:<!-- The message type is indicated by the `type` attribute -->
<send description="HTTP Request" name="request" type="http-request">
. . .
</send>
Within a message element block, protocol fields can be referenced by <store> or <match> elements. When a protocol field value is stored, the value is saved and can later be matched (that is, the value is retrieved) in subsequent messages in the sequence.
Protocol fields and acceptable values are defined in the data model and exposed within messages as either message attributes or message fields, depending on the test suite.
- Message attributes are referenced via
attributeattributes in<store>or<match>elements. - Message fields are referenced through field masks applied to
fieldattributes in<store>or<match>elements.
Additionally, the data model may support values that are typically defined outside of sequences or messages. Such values are exposed through identifiers or settings:
- Identifiers can refer to communication methods, response codes, address-related content, or other statically defined data. For example, the TCP for IPv4 Server test suite has
source-port-numberandtcp-destination-portidentifiers. - Settings refer to values that are often defined in test configuration. For example, the HTTP Server test suite has
uri,userid, andpasswordsettings.
In the following example, taken from the SIP Server test suite, we apply the value of the callee-uri setting to the to-uri message attribute:
<send name="request-invite" type="sip-message"
description="INVITE request">
<!-- Using a setting to provide a value -->
<store attribute="to-uri" setting="callee-uri"/>
. . .
</send>
notifym identifier (indicating the NOTIFY method) in the method message attribute:<recv name="in-request-notify" type="sip-message"
description="NOTIFY request">
<!-- Using an identifier to provide a value -->
<match attribute="method">
notifym
</match>
. . .
</recv>
In some cases, it is possible to obtain values using rules.
- Rules refer to predefined triggers in a test suite that can be invoked to get or set a value for a message attribute or message field.
In the following example, taken from the TCP for IPv4 Server test suite, the tcp-controller:ack rule is invoked to assign a value between 0x00000000 and 0xffffffff to the *.tcp-packet.*.ack-number message field:
<send name="TCP-Data" type="out-tcp-data" description="TCP Data">
<store field="*.tcp-packet.*.ack-number">
!tcp-controller:ack 0x00000000-0xffffffff
</store>
. . .
</send>
Each test suite defines its own message types, message attributes, message fields, identifiers, settings, and rules. You can refer to these definitions in the test suite documentation.