TQL Code Coverage
Introduction
Domain Specific Languages are languages created to support a particular set of tasks, as they are performed in a specific domain. Atomiton's TQL is a collection of number of DSL's each supporting specific function. Just like any GPL, in order for DSL to be successful, it must to have advanced tooling support around it. Ideally we want all all sort of simulators, debuggers, tools to analyze code coverage. Everything built on one platform.
In this section we describe the simple reporting that A-Stack (runtime for TQL) offers to deduce your TQL Code coverage. The advantage of finding the TQL Code coverage is to avoid or minimize all runtime errors
Enabling Code Coverage
In order to enable code coverage report in A-Stack runtime following steps needs to be performed.
Steps to enable code coverage
Step Number | Step Name | Description |
---|---|---|
1 | Add a configuration parameter in sff.local.config.xml file - <sff.report.FsCoverage>512</sff.report.FsCoverage> |
|
2 | Auto deploy your TQL Code by specifying the package files or directories in <sff.local.deploy/> |
|
3 | Start the A-Stack runtime using -ea flag |
|
4 | Run your automation / manual tests against the deployed TQL code |
|
5 | Gracefully shutdown the A-Stack runtime |
|
6 | Gather the code coverage matrix data from log file |
Sample data format: { Each array element (an integer value) will contain number of hits for the corresponding line of code so array element with index 1 will contain count of all executions of line 1, index 2 will contain hit counter for line 2 etc. Described in detail below. |
Format description of code coverage Matrix Data
Code Coverage Matrix Data will be written to your configured log file in the log folder. Please note that all the deployed package file names along with each and every included filename within the package file will be reported as a single JSON object.
{
"filename": [0,1,1,0,0],
"Bundle: tqlenginemanager/macros/executeRemoteQuery.mc.xml":[0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
...
}
Example of Code Coverage Data
In this section we cover generating the code coverage data for sample HelloTQL Project.
- Download and install A-StackPrime runtime - Version 1.3.1 and beyond.
- Download and unzip this test project in the A-Stack
- Add
<sff.local.deploy>resources/hellotql/deploy</sff.local.deploy> to sff.local.config.xml file
- Let's run two sample queries : Endpoint; ws://{host}:{port}/fid-MYGIDI2UAAAH6AAAAEXDEUQIWS
# Query: DeleteAll: TempSensor: sensorId(ne: "") Save(format="version, current"): #This will read TempSensor: Simulation: true PerifMsg: $Null() Peripheral: serial Baudrate: 9600 InterfacePort: "/dev/cu.usbmodem1411" Interface: serial Format: ascii Operation: receive UniqueId: 76522 Payload: $Null() TempValue: $Null() Query(Storage: "TqlSubscription"): Save: TqlSubscription(Label: "TempSensor", sid: "20"): Topic: *Atomiton.Sensors.TempSensor.TempValue*
The output will be in this format
{ "Bundle: tqlenginemanager/facets/nwChangeDetectionFacets.fs.xml":[0,0,0,0,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,2,1,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1], "resources/atomiton/AStackDevManagment/macros/devmanagmacros.xml":[0,0,2,2,2,2,2], "Bundle: tqlenginemanager/facets/macroFacet.fs.xml":[0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1], "SffFacetAgentFacet.xml":[0,0,0,1,1], "Bundle: tqlenginemanager/macros/getEngineSettings.mc.xml":[0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], "Bundle: tqlenginemanager/facets/networkStatus.af.xml":[0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], "Bundle: tqlenginemanager/macros/executeSffFacetAgentQuery.mc.xml":[0,0,0,0,0,0,0,2,2], "SffTqlFacet.xml":[0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,1], "Resource SffTqlFacet.xml":[0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,38,19,0,0,38,19,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,38,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,11,0,0,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,10,0,0,10,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,20,10], "resources/hellotql/facets//tempfacetserial.tf.xml":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1], "resources/hellotql/macros/executequery.mc.xml":[0,0,0,0,0,0,0,0,36,0,0,0,18], "Bundle: tqlenginemanager/facets/logSearchFacet.fs.xml":[0,0,0,0,1], "Bundle: tqlenginemanager/macros/checkForInternetAvailability.mc.xml":[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1], "Bundle: tqlenginemanager/macros/getMemoryInfo.mc.xml":[0,0,0,0,0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], "/Users/baseerkhan/iot/atomiton/development/latest/prime/resources/hellotql/deploy/GenericTQLInterface.mqp.xml":[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1], "Bundle: tqlenginemanager/macros/executeQuery.mc.xml":[0,0,0,0,0,0,0,0,20,10], "Bundle: tqlenginemanager/facets/upgradeService.fs.xml":[0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1], "Inline":[0,2], "Bundle: tqlenginemanager/macros/executeRemoteQuery.mc.xml":[0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2], "/sff/tqlenginemanager/deploy/tqlenginemanager.mqp.xml":[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1], "SffTqlPolicyFacet.xml":[0,0,0,0,0,0,0,0,0,2], "Bundle: tqlenginemanager/macros/scheduleJob.mc.xml":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2], "resources/hellotql/macros/setsimulatedtemp.mc.xml":[0,0,0,0,9,0,0,0,9], "/sff/tqlenginemanager/facets/appStartupInitialization.fs.xml":[0,1,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,1,1,1], "Bundle: tqlenginemanager/facets/loggerFacet.fs.xml":[0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1], "Bundle: tqlenginemanager/facets/engineActivationFacet.fs.xml":[0,0,0,0,0,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], "Bundle: tqlenginemanager/macros/checkForEngineUpgrade.mc.xml":[0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1], "resources/hellotql/macros/schedulejob.mc.xml":[0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,9], "Bundle: tqlenginemanager/facets/engineMonitoringActivation.fs.xml":[0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1] }
Determine TQL Code Coverage
Prerequisites
One of the prerequisite is to determine the number of source files, executable code line number for each of the source file. It would be ideal to generate the source code line numbers in a same array format as reported by A-Stack code coverage.
Pseudo code to generate source file line number array
- Input to the pre-processing code can be parent directory name under which all the source code files are present
- Make a list of all the source code file names
- Iterate through each file in the list from (2) and create a array whose index is the line number and value is 1 if the line is a TQL instruction (example, Process, JavaScript, Workflow, Invoke, etc)
- Output the array in the format [ 0,0,0,1,1,1,0,1 ]
Calculating code coverage
Once you have prerequisite data, you can take the code coverage data generated by A-Stack and determine the coverage. The table below will help you give examples -
Source File | Lines # of executable instruction (Found from prerequisite) | Line Number reported in array with value > 0 | Number of non-zero value source lines (say, sl) | Number of lines covered by tests (say, cl) | Code Coverage cc = (100*cl)/sl |
---|---|---|---|---|---|
resources/hellotql/macros/executequery.mc.xml | [0,0,0,0,0,0,0,0,1,0,0,0,1] | [0,0,0,0,0,0,0,0,36,0,0,0,18] | 2 | 2 | 100% |
list all your files here | .. | .. | .. | ||
TOTAL | . | .. | Total coverage value |