/* JTestServer is a client/server framework for testing any JVM implementation. Copyright (C) 2008 Fabien DUMINY (fduminy@jnode.org) JTestServer is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. JTestServer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.jtestserver.client; import gnu.testlet.runner.ClassResult; import gnu.testlet.runner.HTMLGenerator; import gnu.testlet.runner.PackageResult; import gnu.testlet.runner.RunResult; import gnu.testlet.runner.TestResult; import gnu.testlet.runner.XMLReportParser; import gnu.testlet.runner.XMLReportWriter; import gnu.testlet.runner.compare.ComparisonWriter; import gnu.testlet.runner.compare.HTMLComparisonWriter; import gnu.testlet.runner.compare.ReportComparator; import gnu.testlet.runner.compare.RunComparison; import gnu.testlet.runner.compare.TextComparisonWriter; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import net.sourceforge.nanoxml.XMLParseException; import org.jtestserver.client.TestManager.Result; import org.jtestserver.client.process.ServerProcessManager; import org.jtestserver.client.utils.ConfigurationUtils; import org.jtestserver.client.utils.TestListRW; import org.jtestserver.common.protocol.Client; import org.jtestserver.common.protocol.Protocol; import org.jtestserver.common.protocol.ProtocolException; import org.jtestserver.common.protocol.udp.UDPProtocol; public class TestDriver { private static final Logger LOGGER = Logger.getLogger(TestDriver.class.getName()); public static void main(String[] args) { ConfigurationUtils.init(); TestDriver testDriver = null; try { testDriver = createUDPTestDriver(); testDriver.start(); } catch (Exception e) { LOGGER.log(Level.SEVERE, "protocol error", e); } } private static TestDriver createUDPTestDriver() throws ProtocolException, IOException { Config config = new ConfigReader().read(ConfigurationUtils.getConfigurationFile()); InetAddress serverAddress = InetAddress.getByName(config.getServerName()); int serverPort = config.getServerPort(); Protocol<?> protocol = new UDPProtocol(); //TODO create protocol from a config parameter Client<?, ?> client = protocol.createClient(serverAddress, serverPort); client.setTimeout(config.getClientTimeout()); return new TestDriver(config, client); } private final Config config; private final TestListRW testListRW; private final TestManager testManager; private final ServerProcessManager processManager; private final String vmType; private TestDriver(Config config, Client<?, ?> client) { this.config = config; testListRW = new TestListRW(config); testManager = new TestManager(client); processManager = new ServerProcessManager(config); vmType = config.getVMConfig().getVmType(); } public void start() throws Exception { processManager.startAll(); try { Run latestRun = Run.getLatest(config); Run newRun = Run.create(config); List<String> workingList = new ArrayList<String>(); List<String> crashingList = new ArrayList<String>(); RunResult runResult; if (latestRun == null) { LOGGER.info("running list of all tests"); runResult = runTests(null, true, workingList, crashingList, newRun.getTimestampString()); runResult.setSystemProperty("jtestserver.process", vmType); } else { LOGGER.info("running list of working tests"); File workingTests = latestRun.getWorkingTests(); runResult = runTests(workingTests, true, workingList, crashingList, newRun.getTimestampString()); runResult.setSystemProperty("jtestserver.process", vmType); LOGGER.info("running list of crashing tests"); File crashingTests = latestRun.getCrashingTests(); RunResult rr = runTests(crashingTests, false, workingList, crashingList, newRun.getTimestampString()); mergeResults(runResult, rr); } LOGGER.info("writing crashing & working tests lists"); testListRW.writeList(newRun.getWorkingTests(), workingList); testListRW.writeList(newRun.getCrashingTests(), crashingList); writeReports(runResult, newRun.getReportXml()); compareRuns(latestRun, newRun, runResult); } finally { processManager.stopAll(); } } private void compareRuns(Run latestRun, Run newRun, RunResult newRunResult) throws XMLParseException, IOException { if ((latestRun != null) && latestRun.getReportXml().exists()) { // there was a previous run, let do the comparison ! RunResult latestRunResult = new XMLReportParser().parse(latestRun.getReportXml()); ReportComparator comparator = new ReportComparator(latestRunResult, newRunResult); RunComparison comparison = comparator.compare(); // write comparison in html format ComparisonWriter writer = new HTMLComparisonWriter(); writer.write(comparison, new File(newRun.getReportXml().getParentFile(), "comparison.html")); // write comparison in text format writer = new TextComparisonWriter(); writer.write(comparison, new File(newRun.getReportXml().getParentFile(), "comparison.txt")); } } private void writeReports(RunResult result, File reportXml) throws IOException { XMLReportWriter rw = new XMLReportWriter(false); rw.write(result, reportXml); HTMLGenerator.createReport(result, reportXml.getParentFile()); } private RunResult runTests(File listFile, boolean useCompleteListAsDefault, List<String> workingList, List<String> crashingList, String timestamp) throws Exception { final List<String> list; if ((listFile != null) && listFile.exists()) { list = testListRW.readList(listFile); } else { if (useCompleteListAsDefault) { // not yet a list of working/crashing tests => starts with the // default one list = testListRW.readCompleteList(); } else { list = new ArrayList<String>(); } } int i = 0; // TODO for debug only, remove that for (String test : list) { if (i++ > 100) { // TODO for debug only, remove that break; } LOGGER.info("adding test " + test); testManager.runTest(test); } RunResult result = new RunResult(timestamp); boolean firstTest = true; while (testManager.hasPendingTests()) { boolean working = false; RunResult delta = null; String test = null; try { LOGGER.info("getting a result"); Result runnerResult = testManager.getResult(); delta = runnerResult.getRunResult(); test = runnerResult.getTest(); LOGGER.info("got a result for " + test); mergeResults(result, delta); working = true; } finally { if (working) { workingList.add(test); } else { crashingList.add(test); } if (firstTest && (delta != null)) { for (String name : delta.getSystemPropertyNames()) { result.setSystemProperty(name, delta.getSystemProperty(name)); } firstTest = false; } } } return result; } private void mergeResults(RunResult target, RunResult source) { for (Iterator<?> itSourcePackage = source.getPackageIterator(); itSourcePackage.hasNext(); ) { PackageResult sourcePackage = (PackageResult) itSourcePackage.next(); PackageResult targetPackage = target.getPackageResult(sourcePackage.getName()); if (targetPackage == null) { target.add(sourcePackage); } else { for (Iterator<?> itSourceClass = sourcePackage.getClassIterator(); itSourceClass.hasNext(); ) { ClassResult sourceClass = (ClassResult) itSourceClass.next(); ClassResult targetClass = targetPackage.getClassResult(sourceClass.getName()); if (targetClass == null) { targetPackage.add(sourceClass); } else { for (Iterator<?> itSourceTest = sourceClass.getTestIterator(); itSourceTest.hasNext(); ) { TestResult sourceTest = (TestResult) itSourceTest.next(); boolean hasTest = false; for (Iterator<?> it = targetClass.getTestIterator(); it.hasNext(); ) { TestResult tr = (TestResult) it.next(); if (tr.getName().equals(sourceTest.getName())) { hasTest = true; break; } } if (!hasTest) { targetClass.add(sourceTest); } } } } } } } }