package org.testng.remote;
import java.util.List;
import java.util.Map;
import org.testng.IInvokedMethodListener;
import org.testng.ISuite;
import org.testng.ISuiteListener;
import org.testng.ITestRunnerFactory;
import org.testng.TestNG;
import org.testng.TestNGCommandLineArgs;
import org.testng.TestRunner;
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;
/**
* 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;
}
public void configure(Map cmdLineArgs) {
super.configure(cmdLineArgs);
setConnectionParameters((String) cmdLineArgs.get(TestNGCommandLineArgs.HOST_COMMAND_OPT),
Integer.parseInt((String) cmdLineArgs.get(TestNGCommandLineArgs.PORT_COMMAND_OPT)));
}
public void run() {
final StringMessageSenderHelper msh= new StringMessageSenderHelper(m_host, m_port);
try {
if(msh.connect()) {
if(m_suites.size() > 0) {
int testCount= 0;
for(int i= 0; i < m_suites.size(); i++) {
testCount+= ((XmlSuite) m_suites.get(i)).getTests().size();
}
GenericMessage gm= new GenericMessage(MessageHelper.GENERIC_SUITE_COUNT);
gm.addProperty("suiteCount", m_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() {
public TestRunner newTestRunner(ISuite suite, XmlTest xmlTest,
List<IInvokedMethodListener> listeners) {
TestRunner runner =
new TestRunner(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) {
Map commandLineArgs= TestNGCommandLineArgs.parseCommandLine(args);
RemoteTestNG testNG= new RemoteTestNG();
testNG.configure(commandLineArgs);
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;
}
public void onFinish(ISuite suite) {
m_messageSender.sendMessage(new SuiteMessage(suite, false /*start*/));
}
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;
}
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;
}
}
}