1package test.distributed;
2
3import org.testng.Assert;
4import org.testng.ITestResult;
5import org.testng.TestListenerAdapter;
6import org.testng.TestNG;
7import org.testng.annotations.Test;
8import org.testng.remote.SuiteDispatcher;
9import org.testng.xml.XmlClass;
10import org.testng.xml.XmlSuite;
11import org.testng.xml.XmlTest;
12
13import test.BaseDistributedTest;
14import testhelper.OutputDirectoryPatch;
15
16import java.io.File;
17import java.io.FileOutputStream;
18import java.io.IOException;
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.HashMap;
22import java.util.List;
23import java.util.Map;
24import java.util.Properties;
25import java.util.Random;
26
27public class DistributedTest extends BaseDistributedTest {
28
29  private List<Thread> m_hostThreads = new ArrayList<>();
30
31  protected Thread startSlave(final String filename) {
32    Thread result = new Thread(new Runnable() {
33      @Override
34      public void run() {
35        TestNG.main(new String[] { "-slave", filename, "-d", OutputDirectoryPatch.getOutputDirectory() });
36      }
37    });
38    result.setName("Slave-" + filename);
39    result.start();
40    m_hostThreads.add(result);
41    return result;
42  }
43
44  private File createMasterProperties(String strategy)
45  throws IOException
46  {
47    String fileName = "remote";
48
49    File result = File.createTempFile(fileName, ".properties");
50    result.deleteOnExit();
51    Properties p = new Properties();
52    p.setProperty("testng.hosts", "localhost:" + m_ports[0] + " localhost:" + m_ports[1]);
53    p.setProperty("testng.master.strategy", strategy);
54    p.setProperty("testng.verbose", "0");
55    p.setProperty("testng.master.adpter", "org.testng.remote.adapter.DefaultMastertAdapter");
56    FileOutputStream fos = new FileOutputStream(result);
57    p.store(fos, "Automatically generated by tests");
58    fos.close();
59
60    return result;
61  }
62
63  private File createSlaveProperties(String port)
64  throws IOException
65  {
66    String fileName = "remote";
67
68    File result = File.createTempFile(fileName, ".properties");
69    result.deleteOnExit();
70    Properties p = new Properties();
71    p.setProperty("testng.verbose", "0");
72    p.setProperty("slave.port", port);
73    p.setProperty("testng.slave.adpter", "org.testng.remote.adapter.DefaultWorkerAdapter");
74    FileOutputStream fos = new FileOutputStream(result);
75    p.store(fos, "Automatically generated by tests");
76    fos.close();
77
78    return result;
79  }
80
81  private XmlSuite createSuite(String name, Class[] classes) {
82    XmlSuite result = new XmlSuite();
83    result.setName(name);
84
85    for (Class c : classes) {
86      XmlTest test1 = new XmlTest(result);
87      test1.setName(c.getName());
88      XmlClass class1 = new XmlClass(c);
89      test1.getXmlClasses().add(class1);
90    }
91
92    return result;
93  }
94
95//  @ Configuration(beforeTestClass = true)
96  private void startSlaves() throws IOException{
97	  int port = new Random().nextInt(50000) + 2000;
98	  m_ports = new String[] { Integer.toString(port), Integer.toString(port+1)};
99
100	  File slaveFile = createSlaveProperties(m_ports[0]);
101	  startSlave( slaveFile.getCanonicalPath());
102
103	  slaveFile = createSlaveProperties(m_ports[1]);
104	  startSlave( slaveFile.getCanonicalPath());
105  }
106
107  private String[] m_ports = new String[2];
108
109  public TestListenerAdapter twoHosts(String strategy) throws IOException {
110    TestNG tng = new TestNG();
111    tng.setOutputDirectory(OutputDirectoryPatch.getOutputDirectory());
112
113    File masterFile = createMasterProperties(strategy);
114    tng.setMaster(masterFile.getAbsolutePath());
115
116    XmlSuite suite = createSuite("DistributedSuite1", new Class[] { Test1.class, Test2.class });
117    tng.setXmlSuites(Arrays.asList(new XmlSuite[] { suite }));
118
119    TestListenerAdapter result = new TestListenerAdapter();
120    tng.addListener(result);
121    tng.run();
122
123    String[] passed = {
124        "f1", "f2"
125    };
126    String[] failed = {};
127    String[] skipped = {};
128
129    verifyTests("Passed", passed, toMap(result.getPassedTests()));
130    verifyTests("Failed", failed, toMap(result.getFailedTests()));
131    verifyTests("Skipped", skipped, toMap(result.getSkippedTests()));
132
133    return result;
134  }
135
136  @Test
137  public void twoHostsWithTestStrategy() throws IOException {
138    startSlaves();
139    TestListenerAdapter listener = twoHosts(SuiteDispatcher.STRATEGY_TEST);
140
141    boolean found1 = false;
142    boolean found2 = false;
143    for (ITestResult tr : listener.getPassedTests()) {
144      String host = tr.getHost();
145      if (! found1) {
146        found1 = host.contains(m_ports[0]);
147      }
148      if (! found2) {
149        found2 = host.contains(m_ports[1]);
150      }
151    }
152    Assert.assertTrue(found1, "No tests ran on port " + m_ports[0]);
153    Assert.assertTrue(found2, "No tests ran on port " + m_ports[1]);
154  }
155
156  @Test
157  public void twoHostsWithSuiteStrategy() throws IOException {
158    startSlaves();
159    twoHosts(SuiteDispatcher.STRATEGY_SUITE);
160  }
161
162  private Map<String, ITestResult> toMap(List<ITestResult> results) {
163    Map<String, ITestResult> result = new HashMap<>();
164    for (ITestResult tr : results) {
165      result.put(tr.getName(), tr);
166    }
167
168    return result;
169  }
170  private void ppp(String string) {
171    System.out.println("[DistributedTest] " + string);
172  }
173}
174
175