Exam >
On this page

mq-check

Verifies that specified messages exist in queue

Overview

Usage

1. Configure a map of queue aliases to MqTester implementations via MqPlugin.

2. Use e:mq-send tag in specification:

src/test/resources/specs/Specs.html
<e:mq-check name="someQueue">
    <e:message>{"msg" : "1"}</e:message>
    <e:message from="/data/mq/msg2.json"/>
</e:mq-check>

Attributes

attributedescexample
name Key from the map of a queue aliases to MqTester implementations configured in MqPlugin. Required. Default: -
name="myQueue"
from Use content of the specified file as a value instead of the tag body (empty tag can be used) Optional. Default: -
from="/data/file.json"
vars Comma-separated list of name=value pairs to set as variables Optional. Default: -
vars="var1=1, var2={{now}}, var3=' preserved spaces string '"
varsSeparator name=value pairs separator to use in vars attribute Optional. Default: ,
varsSeparator="|"
headers Comma-separated name=value list of headers to pass to the MqTester.send method. Specific implementation of the MqTester may use this list as the message headers. Optional. Default: empty
headers="type=String, contentEncoding=UTF-8"
contains Messages list verifying mode. Supported values: EXACT, EXACT_IN_ANY_ORDER. Optional. Default: EXACT
contains="EXACT_IN_ANY_ORDER"
verifyAs Content verifier to use. Built-in verifiers: json, xml. May be extended by passing addContentVerifiers parameter to MqPlugin constructor. Optional. Default: json
verifyAs="xml"
jsonUnitOptions ";"-separated list of JsonUnit Options to override defaults. Applicable only when verifyAs="json". Optional. Default: -
jsonUnitOptions="IGNORING_EXTRA_FIELDS"
layout How to layout list of messages in report. Supported values: horizontally, vertically. Optional. Default: vertically
layout="horizontally"
collapsable Render message in report as a collapsable block. Optional. Default: false
collapsable="true"
awaitAtMostSec How long to wait in seconds before failing the verification * Optional. Default: 4
awaitAtMostSec="4"
awaitPollDelayMillis How long to wait in millis before starting to verify * Optional. Default: 0
awaitPollDelayMillis="1000"
awaitPollIntervalMillis How long to wait in millis between verification attempts * Optional. Default: 1000
awaitPollIntervalMillis="500"
* Waiting is disabled by default and check will fail immediately in case of mismatch unless at least one of the awaitAtMostSec, awaitPollDelayMillis or awaitPollIntervalMillis attributes are set

Examples

Purging queue before each example:
myQueue purged

Verify single message

Specifying message in tag body

To verify single message short form of the command may be used: expected message template may be specified without nested e:message tag.

Log File
Single message

Given


Queue has a message:
myQueue
{ "date": "2022-03-12" }

Then


Verify that there is the message:
The following markup:
<e:mq-check name="myQueue">{"date" : "{{now 'yyyy-MM-dd'}}"}</e:mq-check>
will be rendered as:
myQueue
{ "date": "2022-03-12" }

Specifying message in file

Expected message template could be specified in file via from attribute. The vars attribute could be used to conveniently provide context variables for message template.

Log File
Single message from file

Given


Queue has the message:
myQueue
{ "date": "2022-03-12", "var1": "2022-03-12", "var2": "Fri Mar 11 00:00:00 MSK 2022", "var3": "str with commas , signs" }
And there is the expected message file template:
/home/runner/work/Exam/Exam/example/build/resources/test/specs/mq/check/
filecontent
msg.json
{
  "date": "{{now 'yyyy-MM-dd'}}",
  "var1": "{{myVar1}}",
  "var2": "{{myVar2}}",
  "var3": "{{myVar3}}"
}

Then


Verify that there is the message:
The following markup:
<e:mq-check name="myQueue" from="/specs/mq/check/msg.json" vars="myVar1={{now 'yyyy-MM-dd'}} | myVar2={{date myVar1 minus='1 d'}} | myVar3=str with commas , signs" varsSeparator="|"/>
will be rendered as:
myQueue
{ "date": "2022-03-12", "var1": "2022-03-12", "var2": "Fri Mar 11 00:00:00 MSK 2022", "var3": "str with commas , signs" }

Verify empty queue

To verify that queue is empty the e:check command with empty tag body could be used.

empty

Then


Verify that queue is empty:
The following markup:
<e:mq-check name="myQueue"/>
will be rendered as:
myQueue
EMPTY

Overriding verification configuration for specific check

To override global JsonUnit configuration for specific check the jsonUnitOptions attribute could be used.

Log File
jsonUnitOptions

Given


Queue has the message:
myQueue
{ "param1": "1", "extra": "ignore", "arr": [{ "param3": "3", "extra": "ignore" }, { "extra": "ignore", "param4": "4" }] }

Then


Verify ignoring extra fields:
The following markup:
<e:mq-check name="myQueue" verifyAs="jsonIgnoreExtraFields"> { "param1": "1", "arr": [{ "param3": "3" }, { "param4": "4"}] } </e:mq-check>
will be rendered as:
myQueue
{ "param1": "1", "arr": [{ "param3": "3" }, { "param4": "4"}] }

Verifying message list

Overview

Expected message list may be specified via nestede:message tags. Each message template may be specified either as e:message tag body or in a file via from attribute. The vars attribute could be used to conveniently provide context variables for message template.

Log File
Message list

Given


Queue has messages:
myQueue
{ "msg": "1" }
myQueue
{ "date": "2022-03-12", "var1": "2022-03-12", "var2": "Fri Mar 11 00:00:00 MSK 2022", "var3": "str with commas , signs" }
myQueue
{ "msg": "3" }

Then


Verify that there is the exact message list:
The following markup:
<e:mq-check name="myQueue">
  <e:message>{"msg" : "1"}</e:message>
  <e:message from="/specs/mq/check/msg.json" vars="myVar1={{now 'yyyy-MM-dd'}} | myVar2={{date myVar1 minus='1 d'}} | myVar3=str with commas , signs" varsSeparator="|"/>
  <e:message>{"msg" : "3"}</e:message>
</e:mq-check>
will be rendered as:
myQueue
{ "msg": "1" }
{ "date": "2022-03-12", "var1": "2022-03-12", "var2": "Fri Mar 11 00:00:00 MSK 2022", "var3": "str with commas , signs" }
{ "msg": "3" }

Message order

contains attribute could be used to specify message order restriction.

By default e:mq-checkcommand waits until exact specified message list will appear in a queue in exact provided order. To ignore order set contains="EXACT_IN_ANY_ORDER".

Log File
Ignore order

Given


Queue has messages:
myQueue
{ "msg": "1" }
myQueue
{ "msg": "2" }
myQueue
{ "msg": "3" }

Then


Verify that there is the exact message list but ignoring order:
The following markup:
<e:mq-check name="myQueue" contains="EXACT_IN_ANY_ORDER">
  <e:message>{"msg" : "3"}</e:message>
  <e:message>{"msg" : "2"}</e:message>
  <e:message>{"msg" : "1"}</e:message>
</e:mq-check>
will be rendered as:
myQueue
{ "msg": "3" }
{ "msg": "2" }
{ "msg": "1" }

Verifying message headers

The headers attribute could be used for message headers verification. Extracting actual headers from the message is the MqTester implementation responsibility.

Log File
Single message with headers

Given


Queue has the message with headers id = some-id and contentEncoding = UTF-8:
myQueue
Headers
idsome-id
contentEncodingUTF-8
{}

Then


Verify the message and its headers:
The following markup:
<e:mq-check name="myQueue" headers="id={{id}}, contentEncoding=UTF-8">{}</e:mq-check>
will be rendered as:
myQueue
Headers
idsome-id
contentEncodingUTF-8
{}

In case of message list verifying the headers attribute may be applicable to e:message tag.

Log File
Message list with headers

Given


Queue has the messages with headers:
myQueue
Headers
id1
date2000-01-31T23:59:59
{}
myQueue
Headers
id2
date2022-03-13T00:00:00
{}

Then


Verify the message list and their headers:
The following markup:
<e:mq-check name="myQueue">
  <e:message headers="id=1, date={{ignore}}">{}</e:message>
  <e:message headers="id=2, date={{after (today)}}">{}</e:message>
</e:mq-check>
will be rendered as:
myQueue
Headers
id1
date${text-unit.ignore}
{}
Headers
id2
date${text-unit.matches:after}2022-03-12T00:00+03:00[Europe/Moscow]
{}

Verifying different message formats

An implementation of io.github.adven27.concordion.extensions.exam.core.ContentVerifier interface is responsible for actual message body verifying. There are following built-in implementation:

ContentVerifier.Json

Enabled by default or by verifyAs="json"

Uses JsonAssert.assertJsonEquals for verification.

ContentVerifier.Xml

Enabled by verifyAs="xml".

Uses DiffBuilder.compare for verification.

ContentVerifier.Default

Fallback verifier. Enabled if no verifier are found for specified verifyAs attribute.

Uses jUnit Assert.assertEquals for verification.

Additional verifier implementations may be provided by addContentVerifiers parameter of MqPlugin constructor.

Log File
verify different formats

When


Queue has the message in xml format:
myQueue
<data> <date>2022-03-12</date> </data>

Then


Verify the message as xml:
The following markup:
<e:mq-check name="myQueue" from="/data/mq/some.xml" verifyAs="xml"/>
will be rendered as:
myQueue
<data> <date>2022-03-12</date> </data>

When


Queue has the message in some custom format:
myQueue
date 2022-03-12

Then


Verify the message as customFormat:
The following markup:
<e:mq-check name="myQueue">
  <e:message from="/data/mq/some.txt" verifyAs="customFormat"/>
</e:mq-check>
will be rendered as:
myQueue
date 2022-03-12

When


Queue has the messages in xml and some custom format:
myQueue
<data> <date>2022-03-12</date> </data>
myQueue
date 2022-03-12

Then


Verify the first message as xml and the second as customFormat:
The following markup:
<e:mq-check name="myQueue">
  <e:message from="/data/mq/some.xml" verifyAs="xml"/>
  <e:message from="/data/mq/some.txt" verifyAs="customFormat"/>
</e:mq-check>
will be rendered as:
myQueue
<data> <date>2022-03-12</date> </data>
date 2022-03-12

Pretty-printing

Collapsable view

Big messages may be collapsed in report via the collapsable attribute.

Log File
collapsable messages

Given


Queue has some big message:
myQueue
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]

Then


Verified message may be hide in a collapsable block:
The following markup:
<e:mq-check name="myQueue" from="/data/mq/big.json" collapsable="true"/>
will be rendered as:
myQueue
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]

Layout

Layout of the message list in report may be changed via the layout attribute.

Log File
layout

Given


Queue has messages:
myQueue
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]
myQueue
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]

Then


Verify and print in horizontal layout:
The following markup:
<e:mq-check name="myQueue" collapsable="true" layout="horizontally">
  <e:message from="/data/mq/big.json"/>
  <e:message from="/data/mq/big.json"/>
</e:mq-check>
will be rendered as:
myQueue
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]
[{ "index": 0, "isActive": false, "age": 28, "name": "LongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLong" }, { "index": 1, "isActive": true, "age": 29, "name": "Kasey Burris" }, { "index": 2, "isActive": false, "age": 40, "name": "Antoinette Morse" }, { "index": 3, "isActive": true, "age": 32, "name": "Lilia Ramirez" }, { "index": 4, "isActive": true, "age": 35, "name": "Lily Joyner" }, { "index": 5, "isActive": false, "age": 22, "name": "Ronda Norton" }, { "index": 6, "isActive": false, "age": 31, "name": "Tiffany Davidson" }, { "index": 7, "isActive": false, "age": 40, "name": "Allie Wise" }, { "index": 8, "isActive": true, "age": 40, "name": "Giles Lopez" }, { "index": 9, "isActive": false, "age": 25, "name": "Ramsey Cain" }]

More