Skip to content

Commit 2e5d8bf

Browse files
committed
Minor refactoring around RunOrder enum
Renamed and re-organised some internal classes The run order based on instances was using Hash codes to determine execution order. Now that we have Unique identity aware test class object containers, we should be first trying to use that and if it’s not available only then fall Back to using object hash codes (This is for instance aware comparators)
1 parent e5218ab commit 2e5d8bf

File tree

9 files changed

+121
-134
lines changed

9 files changed

+121
-134
lines changed

testng-core-api/src/main/java/org/testng/internal/RuntimeBehavior.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public static boolean useStrictParameterMatching() {
9393
}
9494

9595
public static String orderMethodsBasedOn() {
96-
return System.getProperty("testng.order", Systematiser.Order.INSTANCES.getValue());
96+
return System.getProperty("testng.order");
9797
}
9898

9999
public static String getTestClasspath() {

testng-core-api/src/main/java/org/testng/internal/Systematiser.java

Lines changed: 0 additions & 123 deletions
This file was deleted.

testng-core/src/main/java/org/testng/TestNG.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
import org.testng.internal.ExitCode;
3434
import org.testng.internal.IConfiguration;
3535
import org.testng.internal.ListenerOrderDeterminer;
36+
import org.testng.internal.MethodSorting;
3637
import org.testng.internal.ObjectBag;
3738
import org.testng.internal.OverrideProcessor;
3839
import org.testng.internal.ReporterConfig;
3940
import org.testng.internal.RuntimeBehavior;
40-
import org.testng.internal.Systematiser;
4141
import org.testng.internal.Utils;
4242
import org.testng.internal.Version;
4343
import org.testng.internal.annotations.DefaultAnnotationTransformer;
@@ -1362,7 +1362,7 @@ private SuiteRunner createSuiteRunner(XmlSuite xmlSuite) {
13621362
container,
13631363
m_classListeners.values(),
13641364
holder,
1365-
Systematiser.getComparator());
1365+
MethodSorting.basedOn());
13661366

13671367
for (ISuiteListener isl : m_suiteListeners.values()) {
13681368
result.addListener(isl);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
import org.testng.internal.ListenerOrderDeterminer;
4040
import org.testng.internal.MethodGroupsHelper;
4141
import org.testng.internal.MethodHelper;
42+
import org.testng.internal.MethodSorting;
4243
import org.testng.internal.ResultMap;
4344
import org.testng.internal.RunInfo;
4445
import org.testng.internal.RuntimeBehavior;
45-
import org.testng.internal.Systematiser;
4646
import org.testng.internal.TestListenerHelper;
4747
import org.testng.internal.TestMethodComparator;
4848
import org.testng.internal.TestMethodContainer;
@@ -217,7 +217,7 @@ public TestRunner(
217217
Collection<IInvokedMethodListener> invokedMethodListeners,
218218
List<IClassListener> classListeners,
219219
ISuiteRunnerListener suiteRunner) {
220-
this.comparator = Systematiser.getComparator();
220+
this.comparator = MethodSorting.basedOn();
221221
this.holder = new DataProviderHolder(configuration);
222222
init(
223223
configuration,

testng-core/src/main/java/org/testng/internal/IInstanceIdentity.java

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

3+
import java.util.Arrays;
4+
import java.util.Objects;
35
import java.util.UUID;
46

57
public interface IInstanceIdentity {
@@ -16,4 +18,13 @@ static Object getInstanceId(Object object) {
1618
}
1719
return object;
1820
}
21+
22+
/**
23+
* @param objects - The objects to inspect
24+
* @return - <code>true</code> if all the objects passed are of type {@link IInstanceIdentity}
25+
*/
26+
static boolean isIdentityAware(Object... objects) {
27+
return Arrays.stream(Objects.requireNonNull(objects))
28+
.allMatch(it -> it instanceof IInstanceIdentity);
29+
}
1930
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.testng.internal;
2+
3+
import java.util.Comparator;
4+
import org.testng.ITestNGMethod;
5+
6+
/**
7+
* Helps produce a {@link Comparator} that can be used to determine order of execution for a bunch
8+
* of {@link ITestNGMethod} methods.
9+
*/
10+
@FunctionalInterface
11+
public interface IOrderMethods {
12+
13+
/** @return - The {@link Comparator} to be used. */
14+
Comparator<ITestNGMethod> comparator();
15+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.testng.internal;
2+
3+
import java.util.Arrays;
4+
import java.util.Comparator;
5+
import java.util.Objects;
6+
import java.util.Optional;
7+
import java.util.UUID;
8+
import org.testng.ITestNGMethod;
9+
10+
public enum MethodSorting implements Comparator<ITestNGMethod> {
11+
METHOD_NAMES("methods") {
12+
@Override
13+
public int compare(ITestNGMethod o1, ITestNGMethod o2) {
14+
String n1 = o1.getMethodName();
15+
String n2 = o2.getMethodName();
16+
return n1.compareTo(n2);
17+
}
18+
19+
@Override
20+
public String toString() {
21+
return "Method_Names";
22+
}
23+
},
24+
INSTANCES("instances") {
25+
@Override
26+
public int compare(ITestNGMethod o1, ITestNGMethod o2) {
27+
Comparator<ITestNGMethod> comparator =
28+
Comparator.comparingInt(ITestNGMethod::getPriority)
29+
.thenComparing(method -> method.getRealClass().getName())
30+
.thenComparing(ITestNGMethod::getMethodName)
31+
.thenComparing(Object::toString)
32+
.thenComparing(
33+
method ->
34+
Optional.ofNullable(method.getFactoryMethodParamsInfo())
35+
.map(it -> Arrays.toString(it.getParameters()))
36+
.orElse(""))
37+
.thenComparing(this::objectEquality);
38+
return comparator.compare(o1, o2);
39+
}
40+
41+
private int objectEquality(ITestNGMethod a, ITestNGMethod b) {
42+
Object one = IInstanceIdentity.getInstanceId(a.getInstance());
43+
Object two = IInstanceIdentity.getInstanceId(b.getInstance());
44+
if (IInstanceIdentity.isIdentityAware(one, two)) {
45+
return ((UUID) one).compareTo((UUID) two);
46+
}
47+
return Integer.compare(Objects.hashCode(one), Objects.hashCode(two));
48+
}
49+
50+
@Override
51+
public String toString() {
52+
return "Instance_Names";
53+
}
54+
},
55+
NONE("none") {
56+
@Override
57+
public int compare(ITestNGMethod o1, ITestNGMethod o2) {
58+
return 0;
59+
}
60+
61+
@Override
62+
public String toString() {
63+
return "No_Sorting";
64+
}
65+
};
66+
67+
MethodSorting(String value) {
68+
this.value = value;
69+
}
70+
71+
private final String value;
72+
73+
public static Comparator<ITestNGMethod> basedOn() {
74+
String text = RuntimeBehavior.orderMethodsBasedOn();
75+
return MethodSorting.parse(text);
76+
}
77+
78+
private static MethodSorting parse(String input) {
79+
String text = Optional.ofNullable(input).orElse("");
80+
return Arrays.stream(values())
81+
.filter(it -> it.value.equalsIgnoreCase(text))
82+
.findFirst()
83+
.orElse(INSTANCES);
84+
}
85+
}

testng-core/src/main/java/org/testng/reporters/FailedReporter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import org.testng.internal.ConstructorOrMethod;
2525
import org.testng.internal.LiteWeightTestNGMethod;
2626
import org.testng.internal.MethodHelper;
27+
import org.testng.internal.MethodSorting;
2728
import org.testng.internal.RuntimeBehavior;
28-
import org.testng.internal.Systematiser;
2929
import org.testng.internal.Utils;
3030
import org.testng.xml.XmlClass;
3131
import org.testng.xml.XmlInclude;
@@ -111,8 +111,7 @@ private void generateXmlTest(
111111
}
112112
methodsToReRun.add(current);
113113
List<ITestNGMethod> methodsDependedUpon =
114-
MethodHelper.getMethodsDependedUpon(
115-
current, allTestMethods, Systematiser.getComparator());
114+
MethodHelper.getMethodsDependedUpon(current, allTestMethods, MethodSorting.basedOn());
116115

117116
for (ITestNGMethod m : methodsDependedUpon) {
118117
if (m.isTest()) {

testng-core/src/test/java/test/BaseTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import org.testng.collections.Maps;
2424
import org.testng.internal.Configuration;
2525
import org.testng.internal.IConfiguration;
26-
import org.testng.internal.Systematiser;
26+
import org.testng.internal.MethodSorting;
2727
import org.testng.reporters.JUnitXMLReporter;
2828
import org.testng.reporters.TestHTMLReporter;
2929
import org.testng.xml.XmlClass;
@@ -168,7 +168,7 @@ protected void run() {
168168
m_suite,
169169
m_outputDirectory,
170170
m_testRunnerFactory,
171-
Systematiser.getComparator());
171+
MethodSorting.basedOn());
172172

173173
suiteRunner.run();
174174
}
@@ -346,7 +346,7 @@ public TestRunner newTestRunner(
346346
false,
347347
listeners,
348348
classListeners,
349-
Systematiser.getComparator(),
349+
MethodSorting.basedOn(),
350350
m_baseTest.suiteRunner);
351351

352352
testRunner.addListener(new TestHTMLReporter());

0 commit comments

Comments
 (0)