Message Broker Test coverage using tracing

Unit Test Code Coverage

Unit test coverage in Message Broker works similarly to what developers are used to in other languages such as Java.

The “tracing” coverage works by using the inbuilt functionality in WMB/IIB that allows a user to “Trace” the code executed in a Node.
This trace information can then be converted into a coverage report and consumed in SonarQube.

Currently we support test coverage for:

  • ESQL
  • Msgflows

A standard BAR file is deployed to a running environment.
The tracing on the Node is started (and the previous trace cleared).
Then the test cases are run.
Once the tests are finished, turn off the tracing.
Extract the trace file from the Node (as XML).
Convert the XML file to a text file.
Consume the the text and produce a “generic code coverage report” in Sonarqube.

How is this different to instrumentation

The instrumentation method is a lot more invasion, and it can be slow. The Bar being tested with the instrumentation process is not valid for use in any other environment.
The Bar tested with tracing can be placed inside a repository (Nexus for example) and then used in your build pipe line.
The instrumented Bar cannot.
Coverage using tracing can only test ESQL (and indirectly some msgflows), instrumentation can cover ESQL, Msgflows, XSL and Java.

Coverage includesWHILE .. DO

IF … THEN
ELSEIF … THEN
ELSE
END IF;

X : LOOP

END LOOP X;

X : REPEAT

END REPEAT X;

All message flows executed (view able in the coverage report in Sonar or in the generated flow diagrams)


Coverage example

Coverage example

An example ANT script might look like the following

<?xml version=”1.0″?>
<project name=”project” default=”run”>
<property name=”IIB.DEPLOYBAR” value=”C:/Program Files/IBM/IIB/10.0.0.5/server/bin” /><property name=”IIB.EG” value=”CN_EG2″ />
<property name=”IIB.RUNTIME” value=”CoverageNode” />
<property name=”BUILD.NUMBER” value=”0.01″ />
<target name=”init” description=”">
<path id=”project.classpath”>
<pathelement location=”C:\utils\bct\MB-precise-sonarplugin-3.21.jar” />
<pathelement location=”C:\utils\bct\commons-io-2.0.1.jar”/>
<pathelement location=”C:\utils\bct\slf4j-api-1.7.5.jar”/>
<pathelement location=”C:\utils\bct\slf4j-jdk14-1.7.7.jar”/>
<pathelement location=”C:\utils\bct\commons-lang-2.6.jar”/>
<pathelement location=”C:\utils\bct\xstream-1.4.7.jar”/>
<pathelement location=”C:\utils\bct\plexus-utils-3.0.21.jar”/>
<pathelement location=”C:\utils\bct\xmlpull-1.1.3.1.jar”/>
<pathelement location=”C:\utils\bct\xpp3-1.1.3.3.jar”/>
<pathelement location=”C:\utils\bct\javassist-3.12.1.GA.jar”/>
<pathelement location=”C:\utils\bct\com.ibm.mqjms.jar”/>

<pathelement location=”C:\utils\bct\javaparser-1.0.11.jar”/>

</path>
<typedef name=”consumeTrace”
classname=”au.com.bettercodingtools.sonar.messagebrokersonar.anttasks.ConsumeTraceTask” >
<classpath refid=”project.classpath” />
</typedef>

<typedef name=”urlTest”
classname=”au.com.bettercodingtools.sonar.messagebrokersonar.anttasks.HttpTestTask” >
<classpath refid=”project.classpath” />
</typedef>

<typedef name=”mqTest”
classname=”au.com.bettercodingtools.sonar.messagebrokersonar.anttasks.SendMQMessageTask” >
<classpath refid=”project.classpath” />
</typedef>

<property environment=”env” />

</target>

<target name=”mqsideploybar” depends=”init”>

<property environment=”env”/>

<echo message=”==============================================” />
<echo message=”MQSI_WORKPATH = ${env.MQSI_WORKPATH}” />
<echo message=”==============================================” />

<java classname=”com.ibm.broker.config.util.Deploy” failonerror=”true” fork=”true”>
<arg value=”${IIB.RUNTIME}” />
<arg value=”-e” />
<arg value=”${IIB.EG}” />
<arg value=”-a” />
<arg value=”BARfiles\TestCoverage.bar” />
<classpath>
<fileset dir=”C:/Program Files/IBM/IIB/10.0.0.5/tools/plugins/com.ibm.etools.mft.config_10.0.500″>
<include name=”**/*.jar”/>
</fileset>
</classpath>
</java>

<echo message=”Completed building Broker Archive file – ${APP.NAME}-${BUILD.NUMBER}.bar ” />
</target>

<target name=”run” description=”" depends=”mqsideploybar”>
<!–
mqsichangetrace CoverageTraceNode -u -e CN_EG1 -l none -c 20000 –r

mqsichangetrace CoverageTraceNode -u -e CN_EG1 -f PG1 -l none -c 20000 –r
–>

<!–
mqsichangetrace CoverageTraceNode -u -e CN_EG1 -f <flow_name> -l debug -c 20000 –r
mqsichangetrace CoverageTraceNode -u -e CN_EG1 -l debug -c 20000 -r
–>

<!–
mqsireadlog CoverageTraceNode -u -e CN_EG1 -o usertrace.xml
mqsiformatlog -i usertrace.xml -o usertrace.txt

mqsichangetrace <broker_name> -u -e <eg_name> -f <flow_name> -l none -c 20000 –r
–>

<echo message=”================================” />
<echo message=”turn on tracing” />
<echo message=”================================” />

<exec executable=”mqsichangetrace”>
<arg value=”CoverageNode”/>
<arg value=”-u”/>
<arg value=”-e”/>
<arg value=”CN_EG2″/>
<arg value=”-l”/>
<arg value=”debug”/>
<arg value=”-c”/>
<arg value=”20000″/>
<arg value=”-r”/>
</exec>

<echo message=”================================” />
<echo message=”running tests” />
<echo message=”================================” />

<parallel>
<antcall target=”runtests” />
</parallel>

<sleep seconds=”2″/>

<echo message=”================================” />
<echo message=”Generate logs (xml)” />
<echo message=”================================” />

<exec executable=”mqsireadlog”>
<arg value=”CoverageNode”/>
<arg value=”-u”/>
<arg value=”-e”/>
<arg value=”CN_EG2″/>
<arg value=”-o”/>
<arg value=”trace_file\usertrace.xml”/>
</exec>

<echo message=”================================” />
<echo message=”Generate logs (txt)” />
<echo message=”================================” />

<exec executable=”mqsiformatlog”>
<arg value=”-i”/>
<arg value=”trace_file\usertrace.xml”/>
<arg value=”-o”/>
<arg value=”trace_file\usertrace.txt”/>
</exec>

<echo message=”================================” />
<echo message=”Turn off tracing” />
<echo message=”================================” />

<exec executable=”mqsichangetrace”>
<arg value=”CoverageNode”/>
<arg value=”-u”/>
<arg value=”-e”/>
<arg value=”CN_EG2″/>
<arg value=”-l”/>
<arg value=”none”/>
<arg value=”-c”/>
<arg value=”20000″/>
<arg value=”-r”/>
</exec>

<echo message=”================================” />
<echo message=”Consume trace file” />
<echo message=”================================” />

<antcall target=”consumeTraceFile” />

</target>
<target name=”consumeTraceFile” depends=”init”>

<echo message=”===============================================” />
<echo message=”consume Trace bar file ” />
<echo message=”===============================================” />

<consumeTrace
sourceCode=”TestCoverage”
traceFilePath=”trace_file/usertrace.txt”
keepCoverage=”No”
coverageFilePath=”coveragetemp” />

</target>

<target name=”runtests” >

<echo message=”Sleeping at start of test…” />
<sleep seconds=”2″/>
<echo message=”Sleeping at start of test…done” />

<parallel>

<sleep seconds=”1″/>
<echo message=”Running test: http://localhost:7800/Test1″ />
<urlTest url=”http://localhost:7800/Test1″ />

<mqTest queueName=”Q1″ queueManagerName=”testqm1″ channelName=”test.channel” port=”1414″ logMessage=”FALSE” fileName=”testdata\test1.txt” />
<mqTest queueName=”Q2″ queueManagerName=”testqm1″ channelName=”test.channel” port=”1414″ logMessage=”FALSE” fileName=”testdata\test2.txt” />

<echo message=”Running test: http://localhost:7800/Test1″ />
<urlTest url=”http://localhost:7800/Test1″ />
</parallel>

<sleep seconds=”2″/>

</target>

</project>