18d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormpackage org.testng.remote;
28d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
33e72adb9019ffef6cd2308b85608207b71188407Stefan Birknerimport static org.testng.internal.Utils.defaultIfStringEmpty;
48d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
5aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beustimport com.beust.jcommander.JCommander;
6aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beustimport com.beust.jcommander.ParameterException;
7aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
855cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport org.testng.CommandLineArgs;
9f325d9aa7a9505526a2ec933349aaf227ac23b43Julien Herrimport org.testng.IClassListener;
10e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beustimport org.testng.IInvokedMethodListener;
118d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ISuite;
128d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ISuiteListener;
138d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.ITestRunnerFactory;
148d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.TestNG;
153eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beustimport org.testng.TestNGException;
168d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.TestRunner;
175ef553dae8833427c9d438e70a9758d04fa44697Cédric Beustimport org.testng.collections.Lists;
188d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.GenericMessage;
19754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beustimport org.testng.remote.strprotocol.IMessageSender;
208d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.MessageHelper;
21ed626ea7464c25db7ea754177f36b344195da158Cédric Beustimport org.testng.remote.strprotocol.MessageHub;
22795610a036b5a220b591664d7791b59e7b84315bCédric Beustimport org.testng.remote.strprotocol.RemoteTestListener;
23754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beustimport org.testng.remote.strprotocol.SerializedMessageSender;
243eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beustimport org.testng.remote.strprotocol.StringMessageSender;
258d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.remote.strprotocol.SuiteMessage;
268d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.reporters.JUnitXMLReporter;
278d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.reporters.TestHTMLReporter;
285ef553dae8833427c9d438e70a9758d04fa44697Cédric Beustimport org.testng.xml.XmlSuite;
298d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormimport org.testng.xml.XmlTest;
308d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
31aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beustimport java.util.Arrays;
320643910fcfd637e5b30f0719a6085ae8f1829785Julien Herrimport java.util.Collection;
3355cd8fe791efec01c80a0199de9d187d2c836801Cédric Beustimport java.util.List;
3455cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust
358d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm/**
368d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm * Extension of TestNG registering a remote TestListener.
3710da6505324aa9a0cff9e4831169e31463bbc642Cédric Beust *
3810da6505324aa9a0cff9e4831169e31463bbc642Cédric Beust * @author Cedric Beust <cedric@beust.com>
398d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm */
408d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstormpublic class RemoteTestNG extends TestNG {
4154c45175326b6cda1d4da7780f906871632de1d5Cédric Beust  private static final String LOCALHOST = "localhost";
428d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
43aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  // The following constants are referenced by the Eclipse plug-in, make sure you
44aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  // modify the plug-in as well if you change any of them.
45aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static final String DEBUG_PORT = "12345";
46aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static final String DEBUG_SUITE_FILE = "testng-customsuite.xml";
47aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static final String DEBUG_SUITE_DIRECTORY = System.getProperty("java.io.tmpdir");
48aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static final String PROPERTY_DEBUG = "testng.eclipse.debug";
49aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static final String PROPERTY_VERBOSE = "testng.eclipse.verbose";
50aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  // End of Eclipse constants.
51aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
528d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private ITestRunnerFactory m_customTestRunnerFactory;
537d239aabc611adf9baa78d919b6ce9f7a14c680cnullin  private String m_host;
548d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
55754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  /** Port used for the string protocol */
56754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  private Integer m_port = null;
57754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust
58754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  /** Port used for the serialized protocol */
59754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  private static Integer m_serPort = null;
60754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust
61754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  private static boolean m_debug;
62ed626ea7464c25db7ea754177f36b344195da158Cédric Beust
63eef8b450b4b6fbef21bbba14184dfea4e4ddc167Cédric Beust  private static boolean m_dontExit;
64eef8b450b4b6fbef21bbba14184dfea4e4ddc167Cédric Beust
655c2da9a4d95f922a413b8502f4ddc3ab0f13c9d3Cédric Beust  private static boolean m_ack;
665c2da9a4d95f922a413b8502f4ddc3ab0f13c9d3Cédric Beust
67754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust  public void setHost(String host) {
683e72adb9019ffef6cd2308b85608207b71188407Stefan Birkner    m_host = defaultIfStringEmpty(host, LOCALHOST);
698d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
708d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
715ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust  private void calculateAllSuites(List<XmlSuite> suites, List<XmlSuite> outSuites) {
725ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust    for (XmlSuite s : suites) {
735ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust      outSuites.add(s);
74a3e90669ba97abc7d6f9e4b5aa0c29735d57b109Cédric Beust//      calculateAllSuites(s.getChildSuites(), outSuites);
755ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust    }
765ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust  }
775ef553dae8833427c9d438e70a9758d04fa44697Cédric Beust
7855cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  @Override
798d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  public void run() {
803eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust    IMessageSender sender = m_serPort != null
815c2da9a4d95f922a413b8502f4ddc3ab0f13c9d3Cédric Beust        ? new SerializedMessageSender(m_host, m_serPort, m_ack)
823eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust        : new StringMessageSender(m_host, m_port);
833eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust    final MessageHub msh = new MessageHub(sender);
84aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    msh.setDebug(isDebug());
858d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    try {
86754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      msh.connect();
87754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      // We couldn't do this until now in debug mode since the .xml file didn't exist yet.
88754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      // Now that we have connected with the Eclipse client, we know that it created the .xml
89754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      // file so we can proceed with the initialization
90754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      initializeSuitesAndJarFile();
91aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
92754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      List<XmlSuite> suites = Lists.newArrayList();
93754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      calculateAllSuites(m_suites, suites);
94a3e90669ba97abc7d6f9e4b5aa0c29735d57b109Cédric Beust//      System.out.println("Suites: " + m_suites.get(0).getChildSuites().size()
95a3e90669ba97abc7d6f9e4b5aa0c29735d57b109Cédric Beust//          + " and:" + suites.get(0).getChildSuites().size());
96754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust      if(suites.size() > 0) {
978d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
98754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        int testCount= 0;
998d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
100d46142454fa19e07df3851321c2d35df0f52a7daRyan Schmitt        for (XmlSuite suite : suites) {
101d46142454fa19e07df3851321c2d35df0f52a7daRyan Schmitt          testCount += suite.getTests().size();
102754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        }
1038d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
104754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        GenericMessage gm= new GenericMessage(MessageHelper.GENERIC_SUITE_COUNT);
10554c45175326b6cda1d4da7780f906871632de1d5Cédric Beust        gm.setSuiteCount(suites.size());
10654c45175326b6cda1d4da7780f906871632de1d5Cédric Beust        gm.setTestCount(testCount);
107754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        msh.sendMessage(gm);
1088d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
109754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        addListener(new RemoteSuiteListener(msh));
110754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        setTestRunnerFactory(new DelegatingTestRunnerFactory(buildTestRunnerFactory(), msh));
1118d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1125aee7dbb587db62913167a8193f4a719c5428895Cédric Beust//        System.out.println("RemoteTestNG starting");
113754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        super.run();
1148d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      }
1158d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      else {
116754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust        System.err.println("No test suite found. Nothing to run");
1178d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      }
1188d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1198d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    catch(Throwable cause) {
1208d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      cause.printStackTrace(System.err);
1218d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1228d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    finally {
1235aee7dbb587db62913167a8193f4a719c5428895Cédric Beust//      System.out.println("RemoteTestNG finishing: " + (getEnd() - getStart()) + " ms");
1248d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      msh.shutDown();
125eef8b450b4b6fbef21bbba14184dfea4e4ddc167Cédric Beust      if (! m_debug && ! m_dontExit) {
126aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust        System.exit(0);
127aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      }
1288d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1298d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1308d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1318d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  /**
1328d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * Override by the plugin if you need to configure differently the <code>TestRunner</code>
1338d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * (usually this is needed if different listeners/reporters are needed).
1348d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * <b>Note</b>: you don't need to worry about the wiring listener, because it is added
1358d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   * automatically.
1368d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm   */
1378d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  protected ITestRunnerFactory buildTestRunnerFactory() {
1388d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    if(null == m_customTestRunnerFactory) {
1398d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_customTestRunnerFactory= new ITestRunnerFactory() {
14055cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust          @Override
141e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust          public TestRunner newTestRunner(ISuite suite, XmlTest xmlTest,
142f325d9aa7a9505526a2ec933349aaf227ac23b43Julien Herr              Collection<IInvokedMethodListener> listeners, List<IClassListener> classListeners) {
1436cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust            TestRunner runner =
1443297414dee4e2372259dd538dd359e0b65e9d305Cédric Beust              new TestRunner(getConfiguration(), suite, xmlTest,
1453297414dee4e2372259dd538dd359e0b65e9d305Cédric Beust                  false /*skipFailedInvocationCounts */,
146f325d9aa7a9505526a2ec933349aaf227ac23b43Julien Herr                  listeners, classListeners);
1476cf2e96a6b18fe7eecc44cac44bb0690a162f416Cédric Beust            if (m_useDefaultListeners) {
1489a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm              runner.addListener(new TestHTMLReporter());
1499a1482542f224166248c1821ddeb70c7dbc5415athe.mindstorm              runner.addListener(new JUnitXMLReporter());
1508d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm            }
1518d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1528d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm            return runner;
1538d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm          }
1548d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm        };
1558d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
1568d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
1578d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    return m_customTestRunnerFactory;
1588d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
1598d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
16055cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust  public static void main(String[] args) throws ParameterException {
16155cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    CommandLineArgs cla = new CommandLineArgs();
162ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    RemoteArgs ra = new RemoteArgs();
163ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    new JCommander(Arrays.asList(cla, ra), args);
164eef8b450b4b6fbef21bbba14184dfea4e4ddc167Cédric Beust    m_dontExit = ra.dontExit;
1653eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust    if (cla.port != null && ra.serPort != null) {
1663eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust      throw new TestNGException("Can only specify one of " + CommandLineArgs.PORT
1673eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust          + " and " + RemoteArgs.PORT);
1683eb34813b24377dd042c9e85b8a7854af34e3b81Cédric Beust    }
169aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    m_debug = cla.debug;
1705c2da9a4d95f922a413b8502f4ddc3ab0f13c9d3Cédric Beust    m_ack = ra.ack;
171aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    if (m_debug) {
17254c45175326b6cda1d4da7780f906871632de1d5Cédric Beust//      while (true) {
173ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust        initAndRun(args, cla, ra);
17454c45175326b6cda1d4da7780f906871632de1d5Cédric Beust//      }
175ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    }
176ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    else {
177ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust      initAndRun(args, cla, ra);
178ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    }
179ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust  }
180ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust
181ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust  private static void initAndRun(String[] args, CommandLineArgs cla, RemoteArgs ra) {
182ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    RemoteTestNG remoteTestNg = new RemoteTestNG();
183ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    if (m_debug) {
184aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      // In debug mode, override the port and the XML file to a fixed location
185aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      cla.port = Integer.parseInt(DEBUG_PORT);
18654c45175326b6cda1d4da7780f906871632de1d5Cédric Beust      ra.serPort = cla.port;
187aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      cla.suiteFiles = Arrays.asList(new String[] {
188aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust          DEBUG_SUITE_DIRECTORY + DEBUG_SUITE_FILE
189aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      });
190aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    }
191ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    remoteTestNg.configure(cla);
192754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust    remoteTestNg.setHost(cla.host);
193ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    m_serPort = ra.serPort;
194754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust    remoteTestNg.m_port = cla.port;
195aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    if (isVerbose()) {
196aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      StringBuilder sb = new StringBuilder("Invoked with ");
197aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      for (String s : args) {
198aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust        sb.append(s).append(" ");
199aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      }
200aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      p(sb.toString());
201fe2ca5f751564d7bf8552318d2656fa212060c26Cédric Beust//      remoteTestNg.setVerbose(1);
202fe2ca5f751564d7bf8552318d2656fa212060c26Cédric Beust//    } else {
203fe2ca5f751564d7bf8552318d2656fa212060c26Cédric Beust//      remoteTestNg.setVerbose(0);
204aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    }
205aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    validateCommandLineParameters(cla);
206ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust    remoteTestNg.run();
207ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//    if (m_debug) {
208ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//      // Run in a loop if in debug mode so it is possible to run several launches
209ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//      // without having to relauch RemoteTestNG.
210ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//      while (true) {
211ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//        remoteTestNg.run();
212ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//        remoteTestNg.configure(cla);
213ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//      }
214ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//    } else {
215ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//      remoteTestNg.run();
216ab96c48086fd0dc4e6c6e69648be8ee283c0bd0eCédric Beust//    }
217aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  }
218aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
219aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  private static void p(String s) {
220aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    if (isVerbose()) {
221aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust      System.out.println("[RemoteTestNG] " + s);
222aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    }
223aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  }
224aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
225aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static boolean isVerbose() {
226aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    boolean result = System.getProperty(PROPERTY_VERBOSE) != null || isDebug();
227aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    return result;
228aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  }
229aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
230aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  public static boolean isDebug() {
231754256e4b1acba1555bcb1892a2627fd34f594c6Cédric Beust    return m_debug || System.getProperty(PROPERTY_DEBUG) != null;
232aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  }
233aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
234aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  private String getHost() {
235aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    return m_host;
236aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  }
237aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust
238aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust  private int getPort() {
239aae11d5eb8df906691ce4517a6c59a6bc388be00Cédric Beust    return m_port;
2408d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
2418d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
2428d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  /** A ISuiteListener wiring the results using the internal string-based protocol. */
2438d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private static class RemoteSuiteListener implements ISuiteListener {
244ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    private final MessageHub m_messageSender;
2458d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
246ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    RemoteSuiteListener(MessageHub smsh) {
2478d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender= smsh;
2488d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
2498d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
25055cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
2518d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    public void onFinish(ISuite suite) {
2528d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender.sendMessage(new SuiteMessage(suite, false /*start*/));
2538d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
2548d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
25555cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
2568d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    public void onStart(ISuite suite) {
2578d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender.sendMessage(new SuiteMessage(suite, true /*start*/));
2588d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
2598d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
2608d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
2618d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  private static class DelegatingTestRunnerFactory implements ITestRunnerFactory {
262e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust    private final ITestRunnerFactory m_delegateFactory;
263ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    private final MessageHub m_messageSender;
2648d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
265ed626ea7464c25db7ea754177f36b344195da158Cédric Beust    DelegatingTestRunnerFactory(ITestRunnerFactory trf, MessageHub smsh) {
266e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust      m_delegateFactory= trf;
2678d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      m_messageSender= smsh;
2688d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
2698d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm
27055cd8fe791efec01c80a0199de9d187d2c836801Cédric Beust    @Override
271e02a82be3cd1f43cb767fd87912ce2e713cb327eCédric Beust    public TestRunner newTestRunner(ISuite suite, XmlTest test,
272f325d9aa7a9505526a2ec933349aaf227ac23b43Julien Herr        Collection<IInvokedMethodListener> listeners, List<IClassListener> classListeners) {
273f325d9aa7a9505526a2ec933349aaf227ac23b43Julien Herr      TestRunner tr = m_delegateFactory.newTestRunner(suite, test, listeners, classListeners);
274ed626ea7464c25db7ea754177f36b344195da158Cédric Beust      tr.addListener(new RemoteTestListener(suite, test, m_messageSender));
2758d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm      return tr;
2768d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm    }
2778d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm  }
2788d7d2ad3cabc1fa21475f2ebbfc166f2d27a18b1the.mindstorm}
279