package net.jsunit; import junit.extensions.ActiveTestSuite; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import net.jsunit.configuration.Configuration; import net.jsunit.configuration.ConfigurationSource; import net.jsunit.model.Browser; import net.jsunit.model.DistributedTestRunResult; import net.jsunit.utility.XmlUtility; import org.mortbay.util.MultiException; import java.net.BindException; import java.util.List; public class DistributedTest extends TestCase { protected DistributedTestRunManager manager; private static JsUnitStandardServer temporaryStandardServer; private static Object blocker = new Object(); private static int serverCount = 0; public DistributedTest(ConfigurationSource serverSource, ConfigurationSource farmSource) { super(farmSource.remoteMachineURLs()); ensureTemporaryStandardServerIsCreated(serverSource); manager = DistributedTestRunManager.forConfiguration(new Configuration(farmSource)); } private void ensureTemporaryStandardServerIsCreated(ConfigurationSource serverSource) { //noinspection SynchronizeOnNonFinalField synchronized (blocker) { if (temporaryStandardServer == null) { temporaryStandardServer = new JsUnitStandardServer(new Configuration(serverSource), true); } } } public void setUp() throws Exception { super.setUp(); startServerIfNecessary(); } private void startServerIfNecessary() throws Exception { serverCount ++; //noinspection SynchronizeOnNonFinalField synchronized (blocker) { if (!temporaryStandardServer.isAlive()) { try { temporaryStandardServer.start(); } catch (MultiException e) { if (!isMultiExceptionASingleBindException(e)) throw e; //if a temporaryStandardServer is already running, fine - //we only need it to serve content to remove machines } } } } private boolean isMultiExceptionASingleBindException(MultiException e) { List exceptions = e.getExceptions(); return exceptions.size() == 1 && exceptions.get(0) instanceof BindException; } public void tearDown() throws Exception { serverCount --; if (serverCount == 0) { if (temporaryStandardServer != null && temporaryStandardServer.isAlive()) { temporaryStandardServer.dispose(); temporaryStandardServer = null; } } super.tearDown(); } public static Test suite(ConfigurationSource source) { TestSuite suite = new ActiveTestSuite(); new DistributedTestSuiteBuilder(source).addTestsTo(suite); return suite; } public static Test suite() { return suite(Configuration.resolveSource()); } protected void runTest() throws Throwable { manager.runTests(); DistributedTestRunResult result = manager.getDistributedTestRunResult(); temporaryStandardServer.logStatus(XmlUtility.asPrettyString(result.asXml())); if (!result.wasSuccessful()) fail(result.displayString()); } public DistributedTestRunManager getDistributedTestRunManager() { return manager; } public JsUnitStandardServer getTemporaryStandardServer() { return temporaryStandardServer; } public void limitToBrowser(Browser remoteBrowser) { manager.limitToBrowser(remoteBrowser); setName(remoteBrowser.getFileName()); } }