package runner;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Attr;
import java.io.File;
import java.util.LinkedList;
import tests.Tests;
public class Main {
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: Main /path/to/tests/xml");
System.exit(1);
}
File xmlFile = new File(args[0]);
if (!xmlFile.isFile()) {
System.err.printf("[ERROR] Unable to open file <%s>\n", args[0]);
System.exit(1);
}
LinkedList< LinkedList<String> > tests = new LinkedList< LinkedList<String> >();
// prepare test arguments
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
// parse XML in case when root element is TestCase
if (doc.getDocumentElement().getNodeName().equals("TestSuite")) {
// get all <test>...</test> blocks
NodeList xTests = doc.getElementsByTagName("test");
for (int nTest =0; nTest < xTests.getLength(); ++nTest) {
// prepare list for test name and its arguments
LinkedList<String> test = new LinkedList<String>();
Node xTest = xTests.item(nTest);
// assume that there is the only <command> in <test>
NodeList xCmds = ((Element) xTest).getElementsByTagName("command");
if (xCmds.getLength() > 0) {
Node xCmd = xCmds.item(0);
test.add( xCmd.getChildNodes().item(0).getNodeValue() );
}
// add arguments
NodeList xArgs = ((Element) xTest).getElementsByTagName("args");
for (int nArg = 0; nArg < xArgs.getLength(); ++nArg) {
// get <args>...</args> block
Node xArg = xArgs.item(nArg);
NodeList xParams = xArg.getChildNodes();
// get all nodes inside <args>...</args>
for (int nParam = 0; nParam < xParams.getLength(); ++nParam) {
Node xParam = xParams.item(nParam);
// skip all nodes but elements
if (xParam.getNodeType() == Node.ELEMENT_NODE) {
test.add(xParam.getChildNodes().item(0).getNodeValue());
}
}
}
tests.add(test);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
// run tests and gather results
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element xTests = doc.createElement("tests");
doc.appendChild(xTests);
Tests exec = new Tests();
long totalTime = 0;
float avgTime = 0;
int totalTests = 0;
int passedTests = 0;
int failedTests = 0;
for (LinkedList<String> test : tests) {
// copy list contents to arguments' array
String[] testArgs = new String[ test.size() ];
for(int i = 0; i < test.size(); ++i) testArgs[i] = test.get(i);
// run test
Tests.TestResult r = exec.executeCommand(testArgs);
totalTime += r.time;
totalTests += 1;
if (r.ok) passedTests += 1; else failedTests += 1;
// add test result to xml tree
Element xTest = doc.createElement("test");
Element xTestCmd = doc.createElement("cmd");
StringBuilder sb = new StringBuilder(test.size());
for (int i = 0; i < test.size(); ++i) {
sb.append(test.get(i));
if (i != test.size()-1) sb.append(" ");
}
xTestCmd.appendChild(doc.createTextNode(sb.toString()));
Element xTestResult = doc.createElement("result");
xTestResult.appendChild(doc.createTextNode( r.ok? "pass":"fail" ));
Element xTestTime = doc.createElement("time");
xTestTime.appendChild(doc.createTextNode(String.format("%04d", r.time)));
xTest.appendChild(xTestCmd);
xTest.appendChild(xTestResult);
xTest.appendChild(xTestTime);
xTests.appendChild(xTest);
}
if (totalTests > 0) avgTime = totalTime / (float) totalTests;
// add global test results to root element as attributes
Attr xTotalTime = doc.createAttribute("totalTime");
xTotalTime.setValue(String.format("%04d", totalTime));
xTests.setAttributeNode(xTotalTime);
Attr xAvgTime = doc.createAttribute("avgTime");
xAvgTime.setValue(String.format("%.2f", avgTime));
xTests.setAttributeNode(xAvgTime);
Attr xTotalTests = doc.createAttribute("totalTests");
xTotalTests.setValue(String.format("%d", totalTests));
xTests.setAttributeNode(xTotalTests);
Attr xPassedTests = doc.createAttribute("passedTests");
xPassedTests.setValue(String.format("%d", passedTests));
xTests.setAttributeNode(xPassedTests);
Attr xFailedTests = doc.createAttribute("failedTests");
xFailedTests.setValue(String.format("%d", failedTests));
xTests.setAttributeNode(xFailedTests);
// write xml results to file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("results.xml"));
transformer.transform(source, result);
}
catch (Exception e) {
e.printStackTrace();
}
}
}