Fields are the smallest building blocks of a Message Template. They are used to mark different values or areas within structured data. Each Field has different characteristics and behaviour. This section of the documentation elaborates on these features.
GUARDARA provides several built-in Fields. These are summarised in the table below. Custom Fields can be implemented using the SDK.
|You can use this field as a child of the Bitfield Field to represent a single bit value. If the field is used outside of a Bitfield, it will render on 8-bits (a byte) as either
|The field can be used to represent arbitrary binary data. The Binary field is useful when describing arbitrary fields within a Message Template where the field’s value is not significant from a testing perspective. Or, when generating test cases without having an understanding the data structure. This use case ultimately leads to Mutation-based testing of a user-provided value. Behind the scenes, the binary field uses Radamsa as its mutation generation algorithm.
|This Field is helpful to describe numeric values. It can be used to represent ASCII numbers or fixed-length binary numbers, such as
unsigned long int or numbers of arbitrary length.
|The field allows describing text-based content. For example, text-based protocols such as HTTP will heavily utilise the String field.
|Represents an ASCII value that acts as a delimiter between two fields. Some examples of such a delimiters are: a JSON object’s or HTTP header’s key-value delimiter:
:, new lines, quotes marking the beginning and end of strings in JSON and XML documents and so on.
|The field represents a numeric value incremented by each test case generated.
|The field allows generating a sequence of entirely random bytes. The field can be used to generate completely random data. As the data generated is random, the field should be used carefully. It is best to use to represent fields that expect random data, or the value represented by the field would likely have no impact, for example, an image’s data field.
|Renders to the time elapsed since the Unix epoch. Various date and time formats can be rendered by applying the
Date Format Transform on the field.
|A Group represents a group of fields. Group fields make it easier to design and understand data. Also, specific support fields operate based on the values of a Group. Such support fields are, for example,
|The field allows to specify multiple fields to iterate through. Ideal for assigning multiple fields to a single field within structured data.
|The field behaves very similarly to the Group field, except it allows specifying how many bits each child field should be represented on and does not support conditional rendering. This Field is helpful to represent fields that are not multiple of 8 bits long.
|As its name implies, it adds padding to the value of a Group Field.
|Allows calculating the hash or checksum of a Group.
|The field allows referring to another field by name and renders to the value of the referenced field.
|The field renders to the actual size of a Group.
|The field can calculate the number of groups within a Group.
You can expose the value of the majority of Fields in a global state called the Session. When exposed, Response Processing Rules, other Fields, Callbacks and Conditional Rendering Rules can refer to the raw and rendered value of the Field by the Field's ID.
The table below summarises the two properties that let us expose the Field value in the Session.
|Expose in Session
|If set to Yes, the field’s value will be exposed in the Session.
|Instead of exposing the Field's value under the Field's ID, it is exposed as the value of a Session Variable defined in the Variable Collection assigned to the Message Template. This property is only visible when the Expose in Session property is set to Yes.
The table below highlights the difference between the Raw and Rendered value of exposed Fields.
|The Raw value of a Field is the actual value the Field algorithms are operating with. For example, the Number field operates with numbers (Python
int). Therefore, the Raw value is always an integer.
|The Rendered value is how the Raw value is displayed/rendered by the Engine after considering the Field Properties configured by the user and applying any Transforms attached to the Field. The Rendered value is always of Python
You may want to check out the following examples on GitLab to see how the use of the properties can help with implementing dynamic test configurations:
While most of the Basic Fields are pretty straightforward to work with, using the Support Fields may need further explanation and examples. In this section, we will discuss these fields in more detail.
We can use the Group field to logically group one or more Fields. Each field configured to be tested within a Group will be mutated as long as the Group was also set up to be tested.
Below we list a few interesting characteristics of a Group:
- The Group field makes it easier to design templates and understand the data modelled.
- You can drag and drop fields onto a Group within the Message Template Designer to make the newly created field the children of the Group.
- If the Group's Test Field property is set to No, none of its children will be tested.
- You can use the Group field to apply transformations (using Transforms) to a group of fields.
- Specific support fields operate based on the values of a Group. Such support fields are, for example, Padding, Hash, Reference and Sizer.
- You can collapse Groups to hide child fields by clicking the Collapse Group button (eye icon). You can expand collapsed Groups by double clicking on them.
- You can assign Conditional Rendering Rules to Groups so they only get processed if the condition evaluates to true. See the Conditional Group Processing example.
- Group fields within a Message Template can be saved into a separate Message Template by right-clicking on them and selecting the "Save as Template" option. This feature can come in handy when working with structured data with multiple sections of identical structure. You only have to implement the structure once and save it as a template. Then, you can drag this newly created template into any Message Template as often as needed.
- Message Templates have a root group called Root. Fields added to the Message Template become direct or indirect children of this group. The Root group is not visible in the Message Template Designer.
The Group Field supports three mutation logics; these are Linear (default), Full and Parallel. By choosing your preferred logic, you can define how the fields within the Group should be processed during test case generation. The table below discusses the behaviour of each logic.
|This logic processes fields in the order of their appearance. Once a field is done generating values, the logic will reset it to its default state and move on to testing the following field in the list.
|Using this logic will result in the generation of all permutations of the values generated by the child fields of the Group. Using this logic significantly improves test coverage and, of course, drastically increases the test run time. As of this, it is recommended only to use the Full logic when necessary.
|This logic mutates all children of the Group simultaneously. Using this logic results in the fastest test execution; however, it yields the worst test coverage.
The field allows specifying multiple fields to iterate through. Ideal for assigning multiple field types for a single data field. In other words, if we think of Fields as a set of algorithms, the Switch field allows the merging of the different algorithms.
The field is helpful in multiple scenarios. These scenarios are discussed below.
Configurable Default Value
The Switch Field allows us to implement a field within our modelled structured data with a user-configurable default value and have the field tested at the same time.
To implement the field mentioned above, we have to use the Switch Field, a Reference Field and a Session Variable:
- Create a Variable Collection with a Session Variable to hold the field's default value.
- Create a new Message Template and assign the previously created Variable Collection in the template configuration. You can do this by selecting the Configuration menu item from the View editor menu and using the Variable Collection dropdown field to specify the Variable Collection.
- Add a Switch Field to your Message Template
- Drag and drop a Reference field onto the newly created Swith Field and configure it to pick its value from the previous Session Variable.
At this point, we have a Switch field that will render the default value we have provided for the Session Variable. You can test this by looking at the message preview. Click the Preview button in the top-right corner of the screen.
We could have achieved the same behaviour using a single Reference Field without a Switch Field. However, if we wanted the field to have a user-configurable default value and test the field during a test run, we need the Switch field. Let's update our Message Template.
- Drag and drop a String field onto the Switch Field.
- Configure the String Field any way you wish. Make sure the field has its Test Field property set to Yes.
- Save the String Field.
If you open up the Preview of the Message Template again, you will not see any difference in the data generated. However, you may have noticed the "Total mutations" section under the field showing the rendered data. Indeed, our field will be mutated during the test run. Move the slider at the bottom of the Preview window to see the different test cases produced by the String Field.
Check out the Configurable Field Default Value example on GitLab that demonstrates what we just discussed.
When working with text-based protocols, we may want to test both the application's parsing and data processing logic. The String Field is the most suitable for identifying bugs affecting the parsing logic, given a text-based protocol. However, the String Field does not perform numeric mutations. Therefore, in this scenario, it is not suitable for testing the data processing logic. The best we can do is to combine a String Field and a Number Field using the Switch Field.
Suppose you followed the previous example; you already know how to set up this scenario. It is important to emphasize that the first child of the Switch field is not tested as it serves as a static default value. Therefore, you will have to add 3 Fields as children. The first one serves as the default value, followed by a String and a Number field.
You can use the Sizer field to calculate the size of a Group. Please note that the Sizer field must always be outside the target Group; otherwise, the Engine will terminate the test due to the circular reference.
Check out the Testable Length Fields example on GitLab that shows a more advanced way of using the Sizer field.
The field calculates the number of Groups within a Group. Some protocols, for example, contain a list of fixed-sized data structures. Before such a list, you can find a numeric field that specifies the number of items in the list. The Count field can represent this field by dynamically counting the number of items in the list.
The Bitfield field behaves very similarly to the Group field, except that it allows specifying how many bits each child should be represented on, and it does not support conditional rendering.
This field is useful to represent fields that are not multiple of 8 bits long. For example, the Link Layer Discovery Protocol (LLDP) starts as:
As can be seen, the Type and Length fields are 16 bits long (Word size) but individually, none has a size of 8 bits or multiple of 8 bits. These fields individually cannot be accurately represented by the built-in Number field. This is where the Bitfield field comes into play. We can accurately represent the above fields by:
- Creating a Bitfield field.
- We add a Number Field as the first child of the Bitfield with the default value of the TLV type. We set the Bit Count property of the field to
- The Length field is more than 8 bits long. We cannot use the Number field because we must dynamically calculate the Length field’s value based on the TLV content. So, we add a Sizer field with its Size property set to
2and other relevant properties configured to calculate the size of the relevant fields. We set the Bit Count property of the field to 9.
To summarise, any fields added as a child of the Bitfield will display an additional property called Bit Count that specifies how many bits the generated values should be represented on.
- If the sum of the length of all bits within the Bitfield is not a multiple of
8, the value generated by the Bitfield Field will be padded with
0bits. For example, if the Type field in the above example were configured to be
5bits long, the bit count for the Type and Length fields would be
14. In that case, the rendered value would still be
16bits long, with the last two bits set to
- If the value generated by a field is greater than what can be represented on the number of bits specified via the Bit Count property, the value is truncated to fit.
The field can be used to pad the rendered value of a Group Field to a certain length. Please note that the Padding Field should never be a child of the targeted Group to avoid issues.
The Hash Field can be used to calculate the hash/checksum of a Group Field's value. The Hash Field should never be a child of the Group the hash/checksum is calculated of.
The field renders the value of a Field or Session Variable it references.
Sessions Variables can be used to define project-specific or target-specific configurations. Such configuration can be, for example, authentication credentials used during the testing. The reference provides a way to include this information within a Message Template.
Please note, if referencing a Group, the Reference Field should not be a child of the referenced Group.
Check out the Configurable Field Default Value example on GitLab that demonstrates a possible use of the Reference Field.