Skip to content

Commit cc950e9

Browse files
committed
Temp commit.
1 parent 10a202a commit cc950e9

19 files changed

+215
-80
lines changed

src/main/java/org/testng/TestRunner.java

Lines changed: 131 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,10 @@ private void initMethods() {
433433
//
434434
// Calculate groups methods
435435
//
436-
Map<String, List<ITestNGMethod>> beforeGroupMethods= MethodGroupsHelper.findGroupsMethods(m_classMap.values(), true);
437-
Map<String, List<ITestNGMethod>> afterGroupMethods= MethodGroupsHelper.findGroupsMethods(m_classMap.values(), false);
436+
Map<String, List<ITestNGMethod>> beforeGroupMethods =
437+
MethodGroupsHelper.findGroupsMethods(m_classMap.values(), true);
438+
Map<String, List<ITestNGMethod>> afterGroupMethods =
439+
MethodGroupsHelper.findGroupsMethods(m_classMap.values(), false);
438440

439441
//
440442
// Walk through all the TestClasses, store their method
@@ -717,7 +719,8 @@ private void privateRun(XmlTest xmlTest) {
717719
|| XmlSuite.PARALLEL_CLASSES.equals(parallelMode)
718720
|| XmlSuite.PARALLEL_INSTANCES.equals(parallelMode);
719721

720-
if (!parallel) {
722+
// @@@
723+
if (false) { // (!parallel) {
721724
// sequential
722725
computeTestLists(sequentialList, parallelList, sequentialMapList);
723726

@@ -767,27 +770,40 @@ private void privateRun(XmlTest xmlTest) {
767770
}
768771
else {
769772
// parallel
770-
int threadCount = xmlTest.getThreadCount();
773+
int threadCount = parallel ? xmlTest.getThreadCount() : 1;
771774
// Make sure we create a graph based on the intercepted methods, otherwise an interceptor
772775
// removing methods would cause the graph never to terminate (because it would expect
773776
// termination from methods that never get invoked).
774777
DynamicGraph<ITestNGMethod> graph = createDynamicGraph(intercept(m_allTestMethods));
775-
if (graph.getNodeCount() > 0) {
776-
GraphThreadPoolExecutor<ITestNGMethod> executor =
777-
new GraphThreadPoolExecutor<ITestNGMethod>(graph, this,
778-
threadCount, threadCount, 0, TimeUnit.MILLISECONDS,
779-
new LinkedBlockingQueue<Runnable>());
780-
executor.run();
781-
try {
782-
long timeOut = m_xmlTest.getTimeOut(XmlTest.DEFAULT_TIMEOUT_MS);
783-
Utils.log("TestRunner", 2, "Starting executor for test " + m_xmlTest.getName()
784-
+ " with time out:" + timeOut + " milliseconds.");
785-
executor.awaitTermination(timeOut, TimeUnit.MILLISECONDS);
786-
executor.shutdownNow();
787-
} catch (InterruptedException e) {
788-
e.printStackTrace();
778+
// if (parallel) {
779+
if (graph.getNodeCount() > 0) {
780+
GraphThreadPoolExecutor<ITestNGMethod> executor =
781+
new GraphThreadPoolExecutor<ITestNGMethod>(graph, this,
782+
threadCount, threadCount, 0, TimeUnit.MILLISECONDS,
783+
new LinkedBlockingQueue<Runnable>());
784+
executor.run();
785+
// if (parallel) {
786+
try {
787+
long timeOut = m_xmlTest.getTimeOut(XmlTest.DEFAULT_TIMEOUT_MS);
788+
Utils.log("TestRunner", 2, "Starting executor for test " + m_xmlTest.getName()
789+
+ " with time out:" + timeOut + " milliseconds.");
790+
executor.awaitTermination(timeOut, TimeUnit.MILLISECONDS);
791+
executor.shutdownNow();
792+
} catch (InterruptedException e) {
793+
e.printStackTrace();
794+
}
795+
// }
789796
}
790-
}
797+
// } else {
798+
// List<ITestNGMethod> freeNodes = graph.getFreeNodes();
799+
// while (! freeNodes.isEmpty()) {
800+
// List<IWorker<ITestNGMethod>> runnables = createWorkers(freeNodes);
801+
// for (IWorker<ITestNGMethod> r : runnables) {
802+
// r.run();
803+
// }
804+
// freeNodes = graph.getFreeNodes();
805+
// }
806+
// }
791807
}
792808
}
793809

@@ -869,7 +885,7 @@ public int compare(XmlClass arg0, XmlClass arg1) {
869885
* be put in the same worker in order to run in the same thread.
870886
*/
871887
@Override
872-
public List<IWorker<ITestNGMethod>> createWorkers(Set<ITestNGMethod> methods) {
888+
public List<IWorker<ITestNGMethod>> createWorkers(List<ITestNGMethod> methods) {
873889
List<IWorker<ITestNGMethod>> result;
874890
if (XmlSuite.PARALLEL_INSTANCES.equals(m_xmlTest.getParallel())) {
875891
result = createInstanceBasedParallelWorkers(methods);
@@ -882,7 +898,7 @@ public List<IWorker<ITestNGMethod>> createWorkers(Set<ITestNGMethod> methods) {
882898
/**
883899
* Create workers for parallel="classes" and similar cases.
884900
*/
885-
private List<IWorker<ITestNGMethod>> createClassBasedParallelWorkers(Set<ITestNGMethod> methods) {
901+
private List<IWorker<ITestNGMethod>> createClassBasedParallelWorkers(List<ITestNGMethod> methods) {
886902
List<IWorker<ITestNGMethod>> result = Lists.newArrayList();
887903
// Methods that belong to classes with a sequential=true or parallel=classes
888904
// attribute must all be run in the same worker
@@ -949,7 +965,7 @@ private List<IWorker<ITestNGMethod>> createClassBasedParallelWorkers(Set<ITestNG
949965
* Create workers for parallel="instances".
950966
*/
951967
private List<IWorker<ITestNGMethod>>
952-
createInstanceBasedParallelWorkers(Set<ITestNGMethod> methods) {
968+
createInstanceBasedParallelWorkers(List<ITestNGMethod> methods) {
953969
List<IWorker<ITestNGMethod>> result = Lists.newArrayList();
954970
ListMultiMap<Object, ITestNGMethod> lmm = Maps.newListMultiMap();
955971
for (ITestNGMethod m : methods) {
@@ -1273,48 +1289,64 @@ private boolean containsString(Map<String, String> regexps, String group) {
12731289

12741290
private DynamicGraph<ITestNGMethod> createDynamicGraph(ITestNGMethod[] methods) {
12751291
DynamicGraph<ITestNGMethod> result = new DynamicGraph<ITestNGMethod>();
1292+
result.setComparator(new Comparator<ITestNGMethod>() {
1293+
@Override
1294+
public int compare(ITestNGMethod o1, ITestNGMethod o2) {
1295+
return o1.getPriority() - o2.getPriority();
1296+
}
1297+
});
1298+
1299+
// If preserve-order was specified and the class order is A, B
1300+
// create a new set of dependencies where each method of B depends
1301+
// on all the methods of A
1302+
ListMultiMap<ITestNGMethod, ITestNGMethod> classDependencies = null;
1303+
if ("true".equalsIgnoreCase(getCurrentXmlTest().getPreserveOrder())) {
1304+
classDependencies = createClassDependencies(methods, getCurrentXmlTest());
1305+
}
1306+
12761307
Map<String, ITestNGMethod> map = Maps.newHashMap();
12771308
ListMultiMap<String, ITestNGMethod> groups = Maps.newListMultiMap();
12781309

12791310
for (ITestNGMethod m : methods) {
1280-
map.put(m.getTestClass().getName() + "." + m.getMethodName(), m);
1311+
map.put(/* m.getTestClass().getName() + "." + */ m.getMethodName(), m);
12811312
for (String g : m.getGroups()) {
12821313
groups.put(g, m);
12831314
}
12841315
}
12851316

12861317
// A map of each priority and the list of methods that have this priority
1287-
ListMultiMap<Integer, ITestNGMethod> methodsByPriority = Maps.newListMultiMap();
1288-
for (ITestNGMethod m : methods) {
1289-
methodsByPriority.put(m.getPriority(), m);
1290-
}
1318+
// ListMultiMap<Integer, ITestNGMethod> methodsByPriority = Maps.newListMultiMap();
1319+
// for (ITestNGMethod m : methods) {
1320+
// methodsByPriority.put(m.getPriority(), m);
1321+
// }
12911322

12921323
// The priority map will contain at least one entry for all the methods that have
12931324
// a priority of zero (the default). If it has more than one entry, then we know that
12941325
// some test methods specified priorities, so we need to create dependencies
12951326
// that reflect the priority order.
1296-
boolean hasPriorities = methodsByPriority.getSize() > 1;
1327+
// boolean hasPriorities = methodsByPriority.getSize() > 1;
12971328

12981329
for (ITestNGMethod m : methods) {
12991330
result.addNode(m);
13001331

13011332
// Priority
1302-
if (hasPriorities) {
1303-
for (Map.Entry<Integer, List<ITestNGMethod>> e : methodsByPriority.getEntrySet()) {
1304-
if (e.getKey() < m.getPriority()) {
1305-
for (ITestNGMethod dm : e.getValue()) {
1306-
result.addEdge(m, dm);
1307-
}
1308-
}
1309-
}
1310-
}
1333+
// if (hasPriorities) {
1334+
// for (Map.Entry<Integer, List<ITestNGMethod>> e : methodsByPriority.getEntrySet()) {
1335+
// if (e.getKey() < m.getPriority()) {
1336+
// for (ITestNGMethod dm : e.getValue()) {
1337+
// result.addEdge(m, dm);
1338+
// }
1339+
// }
1340+
// }
1341+
// }
13111342

13121343
// Dependent methods
13131344
{
13141345
String[] dependentMethods = m.getMethodsDependedUpon();
13151346
if (dependentMethods != null) {
13161347
for (String d : dependentMethods) {
1317-
ITestNGMethod dm = map.get(d);
1348+
String shortMethodName = d.substring(d.lastIndexOf(".") + 1);
1349+
ITestNGMethod dm = map.get(shortMethodName);
13181350
if (dm == null) {
13191351
throw new TestNGException("Method \"" + m
13201352
+ "\" depends on nonexistent method \"" + d + "\"");
@@ -1339,6 +1371,67 @@ private DynamicGraph<ITestNGMethod> createDynamicGraph(ITestNGMethod[] methods)
13391371
}
13401372
}
13411373

1374+
// Preserve order
1375+
if (classDependencies != null) {
1376+
for (Map.Entry<ITestNGMethod, List<ITestNGMethod>> es : classDependencies.getEntrySet()) {
1377+
for (ITestNGMethod dm : es.getValue()) {
1378+
// System.out.println("@@@ Dep from:" + m + " to " + dm);
1379+
result.addEdge(dm, es.getKey());
1380+
}
1381+
}
1382+
}
1383+
}
1384+
1385+
List<ITestNGMethod> n = result.getFreeNodes();
1386+
return result;
1387+
}
1388+
1389+
private ListMultiMap<ITestNGMethod, ITestNGMethod> createClassDependencies(
1390+
ITestNGMethod[] methods, XmlTest test)
1391+
{
1392+
1393+
Map<String, List<ITestNGMethod>> classes = Maps.newHashMap();
1394+
List<XmlClass> sortedClasses = Lists.newArrayList();
1395+
1396+
for (XmlClass c : test.getXmlClasses()) {
1397+
classes.put(c.getName(), new ArrayList<ITestNGMethod>());
1398+
sortedClasses.add(c);
1399+
}
1400+
1401+
// Sort the classes based on their order of appearance in the XML
1402+
Collections.sort(sortedClasses, new Comparator<XmlClass>() {
1403+
@Override
1404+
public int compare(XmlClass arg0, XmlClass arg1) {
1405+
return arg0.getIndex() - arg1.getIndex();
1406+
}
1407+
});
1408+
1409+
Map<String, Integer> indexedClasses1 = Maps.newHashMap();
1410+
Map<Integer, String> indexedClasses2 = Maps.newHashMap();
1411+
int i = 0;
1412+
for (XmlClass c : sortedClasses) {
1413+
indexedClasses1.put(c.getName(), i);
1414+
indexedClasses2.put(i, c.getName());
1415+
i++;
1416+
}
1417+
1418+
ListMultiMap<String, ITestNGMethod> methodsFromClass = Maps.newListMultiMap();
1419+
for (ITestNGMethod m : methods) {
1420+
methodsFromClass.put(m.getTestClass().getName(), m);
1421+
}
1422+
1423+
ListMultiMap<ITestNGMethod, ITestNGMethod> result = Maps.newListMultiMap();
1424+
for (ITestNGMethod m : methods) {
1425+
int index = indexedClasses1.get(m.getTestClass().getName());
1426+
if (index > 0) {
1427+
// Make this method depend on all the methods of the class in the previous
1428+
// index
1429+
String classDependedUpon = indexedClasses2.get(index - 1);
1430+
List<ITestNGMethod> methodsDependedUpon = methodsFromClass.get(classDependedUpon);
1431+
for (ITestNGMethod mdu : methodsDependedUpon) {
1432+
result.put(mdu, m);
1433+
}
1434+
}
13421435
}
13431436

13441437
return result;

src/main/java/org/testng/internal/BaseTestMethod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,8 @@ protected IClass getIClass() {
491491
* @return
492492
*/
493493
protected String getSignature() {
494-
String cls = m_method.getDeclaringClass().getName();
494+
String classLong = m_method.getDeclaringClass().getName();
495+
String cls = classLong.substring(classLong.lastIndexOf(".") + 1);
495496
StringBuffer result = new StringBuffer(cls + "." + m_method.getName() + "(");
496497
int i = 0;
497498
for (Class<?> p : m_method.getParameterTypes()) {

src/main/java/org/testng/internal/DynamicGraph.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
package org.testng.internal;
22

3+
import com.google.inject.internal.Lists;
4+
35
import org.testng.collections.ListMultiMap;
46
import org.testng.collections.Maps;
57
import org.testng.internal.annotations.Sets;
68

79
import java.util.Collection;
10+
import java.util.Collections;
11+
import java.util.Comparator;
812
import java.util.List;
913
import java.util.Set;
1014

1115
/**
1216
* Representation of the graph of methods.
1317
*/
1418
public class DynamicGraph<T> {
15-
private static final boolean DEBUG = true;
19+
private static final boolean DEBUG = false;
20+
21+
private Set<T> m_nodesReady = Sets.newLinkedHashSet();
22+
private Set<T> m_nodesRunning = Sets.newLinkedHashSet();
23+
private Set<T> m_nodesFinished = Sets.newLinkedHashSet();
1624

17-
private Set<T> m_nodesReady = Sets.newHashSet();
18-
private Set<T> m_nodesRunning = Sets.newHashSet();
19-
private Set<T> m_nodesFinished = Sets.newHashSet();
25+
private Comparator<? super T> m_nodeComparator = null;
2026

2127
private ListMultiMap<T, T> m_dependedUpon = Maps.newListMultiMap();
2228
private ListMultiMap<T, T> m_dependingOn = Maps.newListMultiMap();
@@ -25,6 +31,14 @@ public static enum Status {
2531
READY, RUNNING, FINISHED
2632
}
2733

34+
/**
35+
* Define a comparator for the nodes of this graph, which will be used
36+
* to order the free nodes when they are asked.
37+
*/
38+
public void setComparator(Comparator<? super T> c) {
39+
m_nodeComparator = c;
40+
}
41+
2842
/**
2943
* Add a node to the graph.
3044
*/
@@ -46,8 +60,8 @@ public void addEdge(T from, T to) {
4660
/**
4761
* @return a set of all the nodes that don't depend on any other nodes.
4862
*/
49-
public Set<T> getFreeNodes() {
50-
Set<T> result = Sets.newHashSet();
63+
public List<T> getFreeNodes() {
64+
List<T> result = Lists.newArrayList();
5165
for (T m : m_nodesReady) {
5266
// A node is free if...
5367

@@ -58,6 +72,10 @@ public Set<T> getFreeNodes() {
5872
result.add(m);
5973
}
6074
}
75+
if (result != null && !result.isEmpty() && m_nodeComparator != null) {
76+
Collections.sort(result, m_nodeComparator);
77+
ppp("Nodes after sorting:" + result.get(0));
78+
}
6179
return result;
6280
}
6381

@@ -154,7 +172,7 @@ public String toDot() {
154172
String RUNNING = "[style=filled color=green]";
155173
String FINISHED = "[style=filled color=grey]";
156174
StringBuilder result = new StringBuilder("digraph g {\n");
157-
Set<T> freeNodes = getFreeNodes();
175+
List<T> freeNodes = getFreeNodes();
158176
String color;
159177
for (T n : m_nodesReady) {
160178
color = freeNodes.contains(n) ? FREE : "";
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package org.testng.internal.annotations;
22

33
import java.util.HashSet;
4+
import java.util.LinkedHashSet;
45
import java.util.Set;
56

67
public class Sets {
78

8-
public static <K> Set<K> newHashSet() {
9-
return new HashSet<K>();
9+
public static <T> Set<T> newHashSet() {
10+
return new HashSet<T>();
11+
}
12+
13+
public static <T> Set<T> newLinkedHashSet() {
14+
return new LinkedHashSet<T>();
1015
}
1116

1217
}

0 commit comments

Comments
 (0)