RemoteTestNG.java revision 55cd8fe791efec01c80a0199de9d187d2c836801
18d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormpackage org.testng.remote;
28d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
38d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport com.beust.jcommander.JCommander;
555cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport com.beust.jcommander.ParameterException;
68d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport org.testng.CommandLineArgs;
8e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beustimport org.testng.IInvokedMethodListener;
98d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ISuite;
108d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ISuiteListener;
118d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ITestRunnerFactory;
128d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.TestNG;
138d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.TestRunner;
148d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.GenericMessage;
158d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.MessageHelper;
168d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.RemoteMessageSenderTestListener;
178d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.StringMessageSenderHelper;
188d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.SuiteMessage;
198d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.reporters.JUnitXMLReporter;
208d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.reporters.TestHTMLReporter;
218d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.xml.XmlTest;
228d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
2355cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport java.util.List;
2455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust
258d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm/**
268d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm * Extension of TestNG registering a remote TestListener.
2743f615be8605a0686342e4cb39821da9bfd61adathe.mindstorm * <p>
2843f615be8605a0686342e4cb39821da9bfd61adathe.mindstorm * <i>Developer note</i>: be aware that a copy of this source is distributed along with the
2943f615be8605a0686342e4cb39821da9bfd61adathe.mindstorm * Eclipse plugin to assure backward compatibility.
3043f615be8605a0686342e4cb39821da9bfd61adathe.mindstorm * </p>
318d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm * @author <a href='mailto:the_mindstorm@evolva.ro'>Alexandru Popescu</a>
328d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm */
338d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormpublic class RemoteTestNG extends TestNG {
348d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private static final String LOCALHOST= "127.0.0.1";
358d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
368d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private ITestRunnerFactory m_customTestRunnerFactory;
378d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  protected String m_host;
388d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  protected int m_port;
398d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
408d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  public void setConnectionParameters(String host, int port) {
418d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    if((null == host) || "".equals(host)) {
428d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_host= LOCALHOST;
438d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
448d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    else {
458d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_host= host;
468d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
478d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
488d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    m_port= port;
498d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
508d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
5155cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  @Override
5255cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  public void configure(CommandLineArgs args) {
5355cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    super.configure(args);
5455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    setConnectionParameters(args.host, args.port);
558d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
568d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
5755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  @Override
588d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  public void run() {
598d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    final StringMessageSenderHelper msh= new StringMessageSenderHelper(m_host, m_port);
608d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    try {
618d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      if(msh.connect()) {
628d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        if(m_suites.size() > 0) {
638d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
648d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          int testCount= 0;
658d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
668d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          for(int i= 0; i < m_suites.size(); i++) {
6755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust            testCount+= (m_suites.get(i)).getTests().size();
688d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          }
698d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
708d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          GenericMessage gm= new GenericMessage(MessageHelper.GENERIC_SUITE_COUNT);
718d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          gm.addProperty("suiteCount", m_suites.size()).addProperty("testCount", testCount);
728d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          msh.sendMessage(gm);
738d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
748d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          addListener(new RemoteSuiteListener(msh));
758d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          setTestRunnerFactory(new DelegatingTestRunnerFactory(buildTestRunnerFactory(), msh));
768d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
778d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          super.run();
788d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        }
798d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        else {
80227a263da108cd1b632a2379694f8f73a35fb159Cédric Beust          System.err.println("No test suite found.  Nothing to run");
818d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        }
828d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      }
838d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      else {
848d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        System.err.println("Cannot connect to " + m_host + " on " + m_port);
858d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      }
868d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
878d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    catch(Throwable cause) {
888d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      cause.printStackTrace(System.err);
898d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
908d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    finally {
918d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      msh.shutDown();
928d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      System.exit(0);
938d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
948d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
958d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
968d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  /**
978d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * Override by the plugin if you need to configure differently the <code>TestRunner</code>
988d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * (usually this is needed if different listeners/reporters are needed).
998d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * <b>Note</b>: you don't need to worry about the wiring listener, because it is added
1008d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * automatically.
1018d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   */
1028d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  protected ITestRunnerFactory buildTestRunnerFactory() {
1038d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    if(null == m_customTestRunnerFactory) {
1048d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_customTestRunnerFactory= new ITestRunnerFactory() {
10555cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust          @Override
106e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust          public TestRunner newTestRunner(ISuite suite, XmlTest xmlTest,
107e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust              List<IInvokedMethodListener> listeners) {
1086cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust            TestRunner runner =
109e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust              new TestRunner(suite, xmlTest, false /*skipFailedInvocationCounts */,
110e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust              listeners);
1116cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust            if (m_useDefaultListeners) {
1129a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm              runner.addListener(new TestHTMLReporter());
1139a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm              runner.addListener(new JUnitXMLReporter());
1148d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm            }
1158d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1168d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm            return runner;
1178d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          }
1188d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        };
1198d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1208d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1218d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    return m_customTestRunnerFactory;
1228d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1238d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
12455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  public static void main(String[] args) throws ParameterException {
12555cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    CommandLineArgs cla = new CommandLineArgs();
12655cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    new JCommander(cla, args);
12755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    validateCommandLineParameters(cla);
1288d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    RemoteTestNG testNG= new RemoteTestNG();
12955cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    testNG.configure(cla);
1308d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    testNG.run();
13155cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//    Map commandLineArgs= TestNGCommandLineArgs.parseCommandLine(args);
13255cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//
13355cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//    RemoteTestNG testNG= new RemoteTestNG();
13455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//    testNG.configure(commandLineArgs);
13555cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//    testNG.initializeSuitesAndJarFile();
13655cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust//    testNG.run();
1378d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1388d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1398d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  /** A ISuiteListener wiring the results using the internal string-based protocol. */
1408d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private static class RemoteSuiteListener implements ISuiteListener {
1418d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    private final StringMessageSenderHelper m_messageSender;
1428d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1438d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    RemoteSuiteListener(StringMessageSenderHelper smsh) {
1448d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender= smsh;
1458d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1468d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
14755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
1488d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    public void onFinish(ISuite suite) {
1498d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender.sendMessage(new SuiteMessage(suite, false /*start*/));
1508d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1518d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
15255cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
1538d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    public void onStart(ISuite suite) {
1548d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender.sendMessage(new SuiteMessage(suite, true /*start*/));
1558d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1568d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1578d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1588d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private static class DelegatingTestRunnerFactory implements ITestRunnerFactory {
159e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust    private final ITestRunnerFactory m_delegateFactory;
1608d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    private final StringMessageSenderHelper m_messageSender;
1618d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1628d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    DelegatingTestRunnerFactory(ITestRunnerFactory trf, StringMessageSenderHelper smsh) {
163e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust      m_delegateFactory= trf;
1648d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender= smsh;
1658d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1668d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
16755cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
168e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust    public TestRunner newTestRunner(ISuite suite, XmlTest test,
169e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust        List<IInvokedMethodListener> listeners) {
170e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust      TestRunner tr = m_delegateFactory.newTestRunner(suite, test, listeners);
1719a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm      tr.addListener(new RemoteMessageSenderTestListener(suite, test, m_messageSender));
1728d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      return tr;
1738d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1748d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1758d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm}
176