package org.testng.remote; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; import org.testng.CommandLineArgs; import org.testng.IInvokedMethodListener; import org.testng.ISuite; import org.testng.ISuiteListener; import org.testng.ITestRunnerFactory; import org.testng.TestNG; import org.testng.TestRunner; import org.testng.collections.Lists; import org.testng.remote.strprotocol.GenericMessage; import org.testng.remote.strprotocol.MessageHelper; import org.testng.remote.strprotocol.RemoteMessageSenderTestListener; import org.testng.remote.strprotocol.StringMessageSenderHelper; import org.testng.remote.strprotocol.SuiteMessage; import org.testng.reporters.JUnitXMLReporter; import org.testng.reporters.TestHTMLReporter; import org.testng.xml.XmlSuite; import org.testng.xml.XmlTest; import java.util.List; /** * Extension of TestNG registering a remote TestListener. * <p> * <i>Developer note</i>: be aware that a copy of this source is distributed along with the * Eclipse plugin to assure backward compatibility. * </p> * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a> */ public class RemoteTestNG extends TestNG { private static final String LOCALHOST= "127.0.0.1"; private ITestRunnerFactory m_customTestRunnerFactory; protected String m_host; protected int m_port; public void setConnectionParameters(String host, int port) { if((null == host) || "".equals(host)) { m_host= LOCALHOST; } else { m_host= host; } m_port= port; } @Override public void configure(CommandLineArgs args) { super.configure(args); setConnectionParameters(args.host, args.port); System.out.println("Setting connection parameters:" + m_host + ":" + m_port); } private void calculateAllSuites(List<XmlSuite> suites, List<XmlSuite> outSuites) { for (XmlSuite s : suites) { outSuites.add(s); calculateAllSuites(s.getChildSuites(), outSuites); } } @Override public void run() { final StringMessageSenderHelper msh= new StringMessageSenderHelper(m_host, m_port); try { if(msh.connect()) { List<XmlSuite> suites = Lists.newArrayList(); calculateAllSuites(m_suites, suites); if(suites.size() > 0) { int testCount= 0; for(int i= 0; i < suites.size(); i++) { testCount+= (suites.get(i)).getTests().size(); } GenericMessage gm= new GenericMessage(MessageHelper.GENERIC_SUITE_COUNT); gm.addProperty("suiteCount", suites.size()).addProperty("testCount", testCount); msh.sendMessage(gm); addListener(new RemoteSuiteListener(msh)); setTestRunnerFactory(new DelegatingTestRunnerFactory(buildTestRunnerFactory(), msh)); super.run(); } else { System.err.println("No test suite found. Nothing to run"); } } else { System.err.println("Cannot connect to " + m_host + " on " + m_port); } } catch(Throwable cause) { cause.printStackTrace(System.err); } finally { msh.shutDown(); System.exit(0); } } /** * Override by the plugin if you need to configure differently the <code>TestRunner</code> * (usually this is needed if different listeners/reporters are needed). * <b>Note</b>: you don't need to worry about the wiring listener, because it is added * automatically. */ protected ITestRunnerFactory buildTestRunnerFactory() { if(null == m_customTestRunnerFactory) { m_customTestRunnerFactory= new ITestRunnerFactory() { @Override public TestRunner newTestRunner(ISuite suite, XmlTest xmlTest, List<IInvokedMethodListener> listeners) { TestRunner runner = new TestRunner(getConfiguration(), suite, xmlTest, false /*skipFailedInvocationCounts */, listeners); if (m_useDefaultListeners) { runner.addListener(new TestHTMLReporter()); runner.addListener(new JUnitXMLReporter()); } return runner; } }; } return m_customTestRunnerFactory; } public static void main(String[] args) throws ParameterException { CommandLineArgs cla = new CommandLineArgs(); new JCommander(cla, args); validateCommandLineParameters(cla); RemoteTestNG testNG = new RemoteTestNG(); testNG.configure(cla); testNG.initializeSuitesAndJarFile(); testNG.run(); } /** A ISuiteListener wiring the results using the internal string-based protocol. */ private static class RemoteSuiteListener implements ISuiteListener { private final StringMessageSenderHelper m_messageSender; RemoteSuiteListener(StringMessageSenderHelper smsh) { m_messageSender= smsh; } @Override public void onFinish(ISuite suite) { m_messageSender.sendMessage(new SuiteMessage(suite, false /*start*/)); } @Override public void onStart(ISuite suite) { m_messageSender.sendMessage(new SuiteMessage(suite, true /*start*/)); } } private static class DelegatingTestRunnerFactory implements ITestRunnerFactory { private final ITestRunnerFactory m_delegateFactory; private final StringMessageSenderHelper m_messageSender; DelegatingTestRunnerFactory(ITestRunnerFactory trf, StringMessageSenderHelper smsh) { m_delegateFactory= trf; m_messageSender= smsh; } @Override public TestRunner newTestRunner(ISuite suite, XmlTest test, List<IInvokedMethodListener> listeners) { TestRunner tr = m_delegateFactory.newTestRunner(suite, test, listeners); tr.addListener(new RemoteMessageSenderTestListener(suite, test, m_messageSender)); return tr; } } }