package com.github.dynamicextensionsalfresco.testrunner.webscript;
import com.github.dynamicextensionsalfresco.testrunner.BundleTest;
import com.github.dynamicextensionsalfresco.testrunner.TestScanner;
import com.github.dynamicextensionsalfresco.webscripts.annotations.HttpMethod;
import com.github.dynamicextensionsalfresco.webscripts.annotations.Transaction;
import com.github.dynamicextensionsalfresco.webscripts.annotations.TransactionType;
import com.github.dynamicextensionsalfresco.webscripts.annotations.Uri;
import com.github.dynamicextensionsalfresco.webscripts.annotations.WebScript;
import com.google.common.collect.ImmutableMap;
import org.json.JSONObject;
import org.json.JSONWriter;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.WebScriptResponse;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
/**
* Webscript for test listing and reporting.
*
* @author Laurent Van der Linden
*/
@Component
@WebScript(families = "testrunner", defaultFormat = "json")
@Transaction(TransactionType.NONE)
public class TestRunnerWebscript {
private final static Logger logger = LoggerFactory.getLogger(TestRunnerWebscript.class);
@Autowired
TestScanner testFinder;
@Autowired
BundleContext bundleContext;
@Uri(value = "/testrunner/", defaultFormat = "html")
public Map<String,Object> index(WebScriptResponse response) {
// force IE to Edge mode
response.setHeader("X-UA-Compatible", "edge");
return ImmutableMap.<String,Object>of("version", bundleContext.getBundle().getHeaders().get("Bnd-LastModified"));
}
@Uri(value = "/testrunner/tests")
public void listTests(final WebScriptResponse response) throws Exception {
final JSONWriter json = new JSONWriter(response.getWriter());
json.array();
final Set<BundleTest> tests = testFinder.getTests();
if (tests != null) {
for (BundleTest test : tests) {
json.object()
.key("className").value(test.getClassName())
.key("bundleId").value(test.getBundleId())
.key("bundleName").value(test.getBundleName())
.endObject();
}
}
json.endArray();
}
@Uri(value = "/testrunner/run", method = HttpMethod.POST)
public void launch(final WebScriptRequest request, final WebScriptResponse response) throws Exception {
final JSONObject testFilter = new JSONObject(request.getContent().getContent());
final JSONWriter jr = new JSONWriter(response.getWriter());
jr.array();
JUnitCore core = new JUnitCore();
core.addListener(new RunListener() {
@Override
public void testRunStarted(Description description) throws Exception {
}
@Override
public void testFinished(Description description) throws Exception {
logger.info("testFinished(" + description.getDisplayName() + ")");
jr.endArray(); // end failure array
jr.endObject(); // end test object
}
@Override
public void testRunFinished(Result result) throws Exception {
logger.info("testRunFinished: failures: " + result.getFailureCount() + " runcount: " + result.getRunCount() + " ran for " + result.getRunTime());
jr.endArray(); // end methods
jr.key("summary").object()
.key("failurecount").value(result.getFailureCount())
.key("runcount").value(result.getRunCount())
.key("runtime").value(result.getRunTime())
.key("ignorecount").value(result.getIgnoreCount())
.endObject();
}
@Override
public void testAssumptionFailure(Failure failure) {
logger.info("testAssumptionFailure(" + failure + ")");
}
@Override
public void testStarted(Description description) throws Exception {
logger.info("testStarted(" + description.getClassName() + " - " + description.getDisplayName() + " " + description.getMethodName() + ")");
jr.object()
.key("method").value(description.getMethodName())
.key("failures").array()
;
}
@Override
public void testFailure(Failure failure) throws Exception {
logger.error("testFailure(" + failure + ")", failure.getException());
jr.object()
.key("message").value(failure.getMessage())
.key("trace").value(failure.getTrace())
.endObject();
}
@Override
public void testIgnored(Description description) throws Exception {
logger.info("testIgnored(" + description + ")");
}
});
final Set<BundleTest> tests = testFinder.getTests();
if (tests != null) {
final String classNameFilter = testFilter.has("className") ? testFilter.getString("className") : null;
final String bundleNameFilter = testFilter.has("bundleName") ? testFilter.getString("bundleName") : null;
for (BundleTest bundleTest : tests) {
if (
(classNameFilter == null || bundleTest.getClassName().toLowerCase().contains(classNameFilter.toLowerCase())) &&
(bundleNameFilter == null || bundleTest.getBundleName().toLowerCase().contains(bundleNameFilter))
) {
jr.object()
.key("bundleName").value(bundleTest.getBundleName())
.key("className").value(bundleTest.getClassName())
.key("methods").array();
logger.info("testing <{}>", bundleTest);
final Bundle bundle = bundleContext.getBundle(bundleTest.getBundleId());
core.run(bundle.loadClass(bundleTest.getClassName()));
jr.endObject();
}
}
}
jr.endArray();
}
}