package com.buglabs.osgi.tester; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Calendar; import java.util.Enumeration; import java.util.Map; import junit.framework.Test; import junit.framework.TestFailure; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.textui.TestRunner; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import com.buglabs.util.xml.XmlNode; public class BundleTestRunnerThread extends Thread { private static final long SETTLE_MILLIS = 5000; private final BundleContext context; private final File outputDir; private boolean errorOccurred = false; private final int shutdownTimeout; public BundleTestRunnerThread(BundleContext context, final File outputDir, int shutdownTimeout) { this.context = context; this.outputDir = outputDir; this.shutdownTimeout = shutdownTimeout; } @Override public void run() { try { System.out.println("Waiting " + SETTLE_MILLIS + " millis for OSGi instance to settle..."); Thread.sleep(SETTLE_MILLIS); System.out.println("System properties:"); for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) System.out.println("Property: " + entry.getKey().toString() + " Value: " + entry.getValue()); ServiceReference[] srefs = context.getServiceReferences(TestSuite.class.getName(), null); if (srefs != null && srefs.length > 0) { for (ServiceReference sr : srefs) { TestSuite ts = (TestSuite) context.getService(sr); if (ts != null) try { runTest(ts); } catch (IOException e) { e.printStackTrace(); } } } else { System.out.println("No " + TestSuite.class.getName() + " tests were found in the service registry."); } } catch (InvalidSyntaxException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { } try { Thread.sleep(shutdownTimeout); } catch (InterruptedException e) { } //Shutdown all the bundles for (Bundle bundle : context.getBundles()) { if (bundle.getBundleId() != 0) { try { bundle.stop(); } catch (Exception e) { //Ignore errors } } } try { Thread.sleep(1000); } catch (InterruptedException e) { } // Test execution complete, now forcibly shutdown the JVM. if (errorOccurred) System.exit(1); else System.exit(0); } protected void runTest(TestSuite tc) throws IOException { XmlNode out = new XmlNode("testsuite"); writeProperties(out); ByteArrayOutputStream outbuf = new ByteArrayOutputStream(); TestRunner tr = new TestRunner(new PrintStream(outbuf)); System.out.println("Running Test Suite: " + tc.getName()); long time = System.currentTimeMillis(); TestResult result = tr.doRun(tc); time = (System.currentTimeMillis() - time) / 1000; Enumeration<Test> te = tc.tests(); while (te.hasMoreElements()) { Test test = te.nextElement(); XmlNode testNode = new XmlNode(out, "testcase").addAttribute("classname", tc.getName()).addAttribute("name", test.toString()).addAttribute("time", "" + time); for (Enumeration<TestFailure> fenum = result.failures(); fenum.hasMoreElements();) { TestFailure f = fenum.nextElement(); testNode.addChild(new XmlNode("failure", f.trace()).addAttribute("type", f.exceptionMessage())); } for (Enumeration<TestFailure> fenum = result.errors(); fenum.hasMoreElements();) { TestFailure f = fenum.nextElement(); testNode.addChild(new XmlNode("error", f.trace()).addAttribute("type", f.exceptionMessage())); } } out.addAttribute("errors", "" + result.errorCount()); out.addAttribute("failures", "" + result.failureCount()); out.addAttribute("hostname", getHostName()); out.addAttribute("name", tc.getName()); out.addAttribute("tests", "" + tc.testCount()); out.addAttribute("time", "" + time); out.addAttribute("timestamp", getDateStamp()); out.addChild(new XmlNode("system-out", outbuf.toString())); File outFile = new File(outputDir, "TEST-" + tc.getName() + ".xml"); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outFile)); bos.write(out.toString().getBytes()); bos.flush(); bos.close(); System.out.print("Test Suite Complete: " + tc.getName()); System.out.println(" Results ~ Errors: " + result.errorCount() + " Failures: " + result.failureCount()); if (result.errorCount() > 0 || result.failureCount() > 0) errorOccurred = true; } private String getDateStamp() { Calendar cal = Calendar.getInstance(); //2011-05-11T06:20:03 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); return sdf.format(cal.getTime()); } private String getHostName() { return "t410s"; } private String wrapCdata(String in) { return "<![CDATA[" + in + "]]>"; } private void writeProperties(XmlNode out) { for (Object key : System.getProperties().keySet()) out.addChild(new XmlNode("property").addAttribute("name", key.toString()).addAttribute("value", System.getProperty(key.toString()))); } }