Squore Toolkit

Groovy Toolkit

When writing Data Providers in Groovy language, the toolkit can help you generate the input-data.xml file and/or retrieve references to artifacts.

This section will help you get started with the Groovy toolkit, by describing first steps and common use cases. When using the toolkit, the below workflow must be followed:

  • Initializing the toolkit

  • Processing the data, creating artefacts, metrics and such

  • Generating the input-data.xml file

You can find the list of available methods and classes for the Groovy toolkit in the Groovydoc documentation.

In order to use the Groovy toolkit, your exec element must use the java language. As an example, here is a sample exec-phase to get you started:

File form.xml for Data Provider JUnit
<?xml version="1.0" encoding="UTF-8"?>
<tags needSources="false" image="JUnit.png">
	<tag type="directory" required="true" key="resultDir" />
	<tag type="text" required="true" key="filePattern" defaultValue="TEST-*.xml" />
	<tag type="text" required="true" key="root"  defaultValue="tests[type=TEST_FOLDER]/junit[type=TEST_FOLDER]" />

	<exec-phase id="add-data">
		<exec name="java">
			<arg value="${javaClasspath(groovy)}"/>
			<arg value="groovy.lang.GroovyShell" />
			<arg value="${getToolConfigDir(junit.groovy)}" />
			<arg tag="resultDir" />
			<arg value="${outputDirectory}" />
			<arg value="${squanOutputDirectory}" />
			<arg tag="root" />
			<arg tag="filePattern" />
		</exec>
	</exec-phase>
</tags>

Below is the Groovy file associated to the form.xml file. Where you can find the descriptions of toolkit operations in the comments:

Script junit.groovy executed by Data Provider JUnit
package tools

import com.squoring.squore.groovy.dp.utils.AbstractDPEngine
import com.squoring.squore.groovy.toolkit.bean.Artifact

class JUnit {
    static void main(String[] args) {
        println("Start of JUnit process")
        def xmlRegex = args.size() == 5 ? args[4] : "*.xml\$"
        //Initializing the toolkit via initDPContext method of the AbstractDPEngine toolkit class
        new JUnitEngine(args[3]).initDPContext(args[0], args[1], args[2], xmlRegex).generateResult();
        println("End of JUnit process")
    }
}

//Extending toolkit class AbstractDPEngine to have access to its methods and attributes
class JUnitEngine extends AbstractDPEngine {
    String rootPath
    Artifact junitRootArt

    JUnitEngine(rootPath) {
        this.rootPath = rootPath
    }

    void generateResult() {
        //Retrieving root parent artefact under which all created artefact will be attached
        junitRootArt = getRootParent(toolkitEngine.rootArtifact, rootPath)
        //Processing files for artefact and metrics creation
        filesToBeParsed.each {
            println("Processing for file ${it}")
            def xmlMap = getXmlMapData(it, "testsuite")
            def xmlMapFiles = xmlMap?.get('testsuite')
            if (xmlMapFiles != null && !xmlMapFiles.isEmpty()) {
                xmlMapFiles.each {
                    def testCases = it.testcase
                    if (testCases instanceof List) {
                        testCases.each { tC ->
                            addMetrics(tC)
                        }
                    } else {
                        if (testCases) {
                            addMetrics(testCases)
                        }
                    }
                }
            }
        }
        //Generating final input-data.xml file
        toolkitEngine.generateFinalInputFile(fileOut)
    }


    def addMetrics(line) {
        Artifact rootArtFolder
        def testClassName = line.classname
        def testVariantName
        def variantMatcher = (testClassName =~ '(.*)\\((.*)\\)')
        ...
        //Creating artefact
        def art = rootArtFolder.makeArtifact(line.name, "UNIT_TEST")

        def className = testClassName.replaceAll('Test(\\(.*\\))?$', '')
        //Searching for existing artefact by its class name
        def artClass = rootArtifact.getByClassName(className)
        if (artClass) {
            artClass.addLinkToByArt('TESTED', art)
        } else {
            rootArtifact.addLinkToByArt('TESTED', art)
        }

        def leaftArt
        if (testVariantName) {
          //Creating artefact
          leaftArt = art.makeArtifact(line.name + " (" + testVariantName + ")", "TEST_EXECUTION")
          leaftArt.putInfo("VARIANT", testVariantName)
          addVariant(testVariantName, leaftArt)
        } else {
          leaftArt = art
        }

        //Adding metric to artefact
        leaftArt.putMetric("EXECUTION_TIME", Double.valueOf(line.time.replaceAll(',', '')) * 1000)

        //Adding metric to artefact
        if (line.failure != null) {
            leaftArt.putMetric("STATUS", 2)
        } else if (line.error != null || line.skipped != null) {
            leaftArt.putMetric("STATUS",  1)
        } else {
            leaftArt.putMetric("STATUS",  0)
        }

    }

    def addVariant(variantName, targetArt) {
      //Creating artefact under root parent artefact
      Artifact variantRootArt = getRootParent(toolkitEngine.rootArtifact, rootPath).makeArtifact("variants", "VARIANT_FOLDER")
      ...
    }

    def getArtFolder(artParent, className) {
        def classNameSplit = className.split('\\.(?![^(]*\\))')
        def firsElement = classNameSplit.first()
        //Searching for artefacts by type
        def artFound = artParent.findByArtifactType("TEST_FOLDER", false).find {
            it.name == firsElement
        }
        if (artFound == null) {
            //Creating artefact under artParent
            artFound = artParent.makeArtifact(firsElement, "TEST_FOLDER")
        }
        if (classNameSplit.size() > 1) {
            def newRootPath = classNameSplit[1..<classNameSplit.size()].join(".")
            def artChildTmp = getArtFolder(artFound, newRootPath)
            artFound = artChildTmp
        }
        return artFound
    }

}

In this use case, toolkit functions like makeArtifact, findByArtifactType, putMetric, generateFinalInputFile and others are used.

You can find the list of available methods and classes for the Groovy toolkit in the Groovydoc documentation.

TCL Toolkit

The TCL toolkit is deprecated, please consider using the Groovy Toolkit.

If you want your Data Provider to use the Squore toolkit to retrieve references to artefacts, the following variables are available (in the add-data and repo-add-data phases only):

  • ${tclToolkitDirectory}: the directory of the toolkit tcl code to execute

  • ${squanOutputDirectory}: the directory of containing the results of the execution of Squore Analyzer

In order to use the toolkit, your exec must use the tcl language. As an example, here is a sample exec-phase and associated tcl file to get you started:

 <!-- form.xml -->
<exec-phase id="repo-add-data">
	<exec name="tcl">
		<arg value="${getAddonsFile(repo-add-data.tcl)}" />
		<arg value="${tclToolkitFile}" />
		<arg value="${squanOutputDirectory}" />
		<arg value="${outputDirectory}" />
		<arg tag="xxx" />
	</exec>
</exec-phase>
#repo-add-data.tcl:
set toolkitFile [lindex $argv 0]
set sqOutputDir [lindex $argv 1]
set outputDir [lindex $argv 2]
set xxx [lindex $argv 3]

# Initialise the toolkit
puts "Initializing toolkit"
source $toolkitFile
toolkit::initialize $sqOutputDir $outputDir

# Execute your code
puts "Main execution"
# yout code here
# ...

# Generate xml files (artefacts)
puts "Generating xml files"
toolkit::generate $outputDir {artefacts}