package com.occamlab.te.spi.ctl; import com.occamlab.te.Engine; import com.occamlab.te.Generator; import com.occamlab.te.RuntimeOptions; import com.occamlab.te.SetupOptions; import com.occamlab.te.TEClassLoader; import com.occamlab.te.TECore; import com.occamlab.te.index.Index; import com.occamlab.te.index.SuiteEntry; import com.occamlab.te.spi.executors.TestRunExecutor; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * Executes a CTL test suite using the given test run arguments. */ public class CtlExecutor implements TestRunExecutor { private final SetupOptions setupOpts; private String iut = null; /** * Constructs a new CtlExecutor using the given set of configuration * settings. * * @param config The configuration settings for the test run. */ public CtlExecutor(SetupOptions config) { this.setupOpts = config; } /** * Executes a test suite. * * @param testRunArgs An XML properties file that supplies the test run * arguments. * @return A Source representing the test results. */ @Override public Source execute(Document testRunArgs) { RuntimeOptions runOpts = extractTestRunArguments(testRunArgs); runOpts.setLogDir(new File(System.getProperty("java.io.tmpdir"))); if (null == runOpts.getSessionId()) { runOpts.setSessionId(UUID.randomUUID().toString()); } String suiteName = null; try { Index masterIndex = Generator.generateXsl(this.setupOpts); SuiteEntry se = null; if (suiteName == null) { Iterator<String> it = masterIndex.getSuiteKeys().iterator(); if (!it.hasNext()) { throw new Exception("Error: No suites in sources."); } se = masterIndex.getSuite(it.next()); } suiteName = se.getTitle(); TEClassLoader defaultLoader = new TEClassLoader(null); Engine engine = new Engine(masterIndex, setupOpts.getSourcesName(), defaultLoader); TECore ctlRunner = new TECore(engine, masterIndex, runOpts); ctlRunner.execute(); } catch (Exception ex) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Failed to execute test suite.", ex); throw new RuntimeException(ex); } File resultsDir = new File(runOpts.getLogDir(), runOpts.getSessionId()); File testLog = new File(resultsDir, "report_logs.xml"); CtlEarlReporter report = new CtlEarlReporter(); try{ report.generateEarlReport (resultsDir, testLog, suiteName, this.iut); } catch (IOException iox) { throw new RuntimeException("Failed to serialize EARL results to " + resultsDir.getAbsolutePath(), iox); } // NOTE: Final result should be transformed to EARL report (RDF/XML) // resolve xinclude directives in CTL results DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); docFactory.setNamespaceAware(true); docFactory.setXIncludeAware(true); Source results = null; try { Document resultsDoc = docFactory.newDocumentBuilder().parse(testLog); results = new DOMSource(resultsDoc, testLog.toURI().toString()); //results = new StreamSource(new FileInputStream(testLog), testLog.toURI().toString()); } catch (IOException | SAXException | ParserConfigurationException e) { throw new RuntimeException(e); } Logger.getLogger(getClass().getName()).log(Level.INFO, "Test results: {0}", results.getSystemId()); return results; } /** * Extracts test run arguments from an XML properties file. The arguments * are added to the resulting <code>RuntimeOptions</code> object as * key-value pairs represented as a string: "{key}={value}". * * @param testRunArgs An XML representation of a properties file containing * an {@literal <entry>} element for each supplied argument. * @return The configuration settings for a test run, including a list of * parameters (which may be empty). * * @see * <a target="_blank" href="https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html">Properties</a> */ RuntimeOptions extractTestRunArguments(Document testRunArgs) { RuntimeOptions runOpts = new RuntimeOptions(); if (null != testRunArgs) { NodeList entries = testRunArgs.getElementsByTagName("entry"); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element) entries.item(i); String kvp = String.format("%s=%s", entry.getAttribute("key"), entry.getTextContent().trim()); runOpts.addParam(kvp); if(entry.getAttribute("key").contains("iut") || entry.getAttribute("key").contains("capabilities-url")){ this.iut = entry.getTextContent().trim(); } } } return runOpts; } }