Skip to content

Commit ae10477

Browse files
committed
Fixing review comments.
1 parent d6ecc00 commit ae10477

File tree

6 files changed

+122
-101
lines changed

6 files changed

+122
-101
lines changed

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

Lines changed: 16 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.testng.internal.ClassHelper;
3030
import org.testng.internal.Configuration;
3131
import org.testng.internal.DynamicGraph;
32-
import org.testng.internal.ExitCodeListener;
32+
import org.testng.internal.ExitCode;
3333
import org.testng.internal.IConfiguration;
3434
import org.testng.internal.IResultListener2;
3535
import org.testng.internal.OverrideProcessor;
@@ -143,14 +143,10 @@ public class TestNG {
143143
private final Map<Class<? extends IReporter>, IReporter> m_reporters = Maps.newHashMap();
144144
private final Map<Class<? extends IDataProviderListener>, IDataProviderListener> m_dataProviderListeners = Maps.newHashMap();
145145

146-
protected static final int HAS_FAILURE = 1;
147-
protected static final int HAS_SKIPPED = 2;
148-
protected static final int HAS_FSP = 4;
149146
protected static final int HAS_NO_TEST = 8;
150147

151148
public static final Integer DEFAULT_VERBOSE = 1;
152149

153-
private int m_status;
154150
private boolean m_hasTests= false;
155151

156152
// Command line suite parameters
@@ -186,7 +182,8 @@ public class TestNG {
186182
private final Map<Class<? extends IAlterSuiteListener>, IAlterSuiteListener> m_alterSuiteListeners= Maps.newHashMap();
187183

188184
private boolean m_isInitialized = false;
189-
private org.testng.internal.ExitCodeListener m_exitCode;
185+
private org.testng.internal.ExitCodeListener exitCodeListener;
186+
private ExitCode exitCode;
190187

191188
/**
192189
* Default constructor. Setting also usage of default listeners/reporters.
@@ -213,11 +210,10 @@ private void init(boolean useDefaultListeners) {
213210
}
214211

215212
public int getStatus() {
216-
return m_status;
217-
}
218-
219-
private void setStatus(int status) {
220-
m_status = status;
213+
if (m_hasTests) {
214+
return exitCode.getExitCode();
215+
}
216+
return HAS_NO_TEST;
221217
}
222218

223219
/**
@@ -965,8 +961,8 @@ private void addReporter(Class<? extends IReporter> r) {
965961
}
966962

967963
private void initializeDefaultListeners() {
968-
this.m_exitCode = new org.testng.internal.ExitCodeListener();
969-
addListener((ITestNGListener) this.m_exitCode);
964+
this.exitCodeListener = new org.testng.internal.ExitCodeListener();
965+
addListener((ITestNGListener) this.exitCodeListener);
970966
if (m_useDefaultListeners) {
971967
addReporter(SuiteHTMLReporter.class);
972968
addReporter(Main.class);
@@ -1158,11 +1154,10 @@ public void run() {
11581154
}
11591155

11601156
runExecutionListeners(false /* finish */);
1161-
m_hasTests = this.m_exitCode.isHasTests();
1162-
setStatus(this.m_exitCode.getStatus());
1157+
m_hasTests = this.exitCodeListener.hasTests();
1158+
exitCode = this.exitCodeListener.getStatus();
11631159

11641160
if(!m_hasTests) {
1165-
setStatus(HAS_NO_TEST);
11661161
if (TestRunner.getVerbose() > 1) {
11671162
System.err.println("[TestNG] No tests found. Nothing was run");
11681163
usage();
@@ -1248,7 +1243,7 @@ private void generateReports(List<ISuite> suiteRunners) {
12481243
*/
12491244
public List<ISuite> runSuitesLocally() {
12501245
if (m_suites.isEmpty()) {
1251-
setStatus(HAS_NO_TEST);
1246+
this.m_hasTests = false;
12521247
error("No test suite found. Nothing to run");
12531248
usage();
12541249
return Collections.emptyList();
@@ -1495,7 +1490,7 @@ public static TestNG privateMain(String[] argv, ITestListener listener) {
14951490
else {
14961491
error(ex.getMessage());
14971492
}
1498-
result.setStatus(HAS_FAILURE);
1493+
result.exitCode = ExitCode.newExitCodeRepresentingFailure();
14991494
}
15001495

15011496
return result;
@@ -1849,21 +1844,21 @@ protected static void validateCommandLineParameters(CommandLineArgs args) {
18491844
* @return true if at least one test failed.
18501845
*/
18511846
public boolean hasFailure() {
1852-
return (getStatus() & HAS_FAILURE) == HAS_FAILURE;
1847+
return this.exitCode.hasFailure();
18531848
}
18541849

18551850
/**
18561851
* @return true if at least one test failed within success percentage.
18571852
*/
18581853
public boolean hasFailureWithinSuccessPercentage() {
1859-
return (getStatus() & HAS_FSP) == HAS_FSP;
1854+
return this.exitCode.hasFailureWithinSuccessPercentage();
18601855
}
18611856

18621857
/**
18631858
* @return true if at least one test was skipped.
18641859
*/
18651860
public boolean hasSkip() {
1866-
return (getStatus() & HAS_SKIPPED) == HAS_SKIPPED;
1861+
return this.exitCode.hasSkip();
18671862
}
18681863

18691864
static void exitWithError(String msg) {
@@ -1956,30 +1951,6 @@ public static TestNG getDefault() {
19561951
return m_instance;
19571952
}
19581953

1959-
/**
1960-
* @deprecated since 5.1
1961-
*/
1962-
@Deprecated
1963-
public void setHasFailure(boolean hasFailure) {
1964-
m_status |= HAS_FAILURE;
1965-
}
1966-
1967-
/**
1968-
* @deprecated since 5.1
1969-
*/
1970-
@Deprecated
1971-
public void setHasFailureWithinSuccessPercentage(boolean hasFailureWithinSuccessPercentage) {
1972-
m_status |= HAS_FSP;
1973-
}
1974-
1975-
/**
1976-
* @deprecated since 5.1
1977-
*/
1978-
@Deprecated
1979-
public void setHasSkip(boolean hasSkip) {
1980-
m_status |= HAS_SKIPPED;
1981-
}
1982-
19831954
@Deprecated
19841955
/**
19851956
* @deprecated - This class stands deprecated as of TestNG v6.13
@@ -2002,21 +1973,16 @@ public void beforeConfiguration(ITestResult tr) {
20021973
@Override
20031974
public void onTestFailure(ITestResult result) {
20041975
setHasRunTests();
2005-
m_mainRunner.setStatus(HAS_FAILURE);
20061976
}
20071977

20081978
@Override
20091979
public void onTestSkipped(ITestResult result) {
20101980
setHasRunTests();
2011-
if ((m_mainRunner.getStatus() & HAS_FAILURE) != 0) {
2012-
m_mainRunner.setStatus(HAS_SKIPPED);
2013-
}
20141981
}
20151982

20161983
@Override
20171984
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
20181985
setHasRunTests();
2019-
m_mainRunner.setStatus(HAS_FSP);
20201986
}
20211987

20221988
@Override
@@ -2047,15 +2013,13 @@ private void setHasRunTests() {
20472013
*/
20482014
@Override
20492015
public void onConfigurationFailure(ITestResult itr) {
2050-
m_mainRunner.setStatus(HAS_FAILURE);
20512016
}
20522017

20532018
/**
20542019
* @see org.testng.IConfigurationListener#onConfigurationSkip(org.testng.ITestResult)
20552020
*/
20562021
@Override
20572022
public void onConfigurationSkip(ITestResult itr) {
2058-
m_mainRunner.setStatus(HAS_SKIPPED);
20592023
}
20602024

20612025
/**

src/main/java/org/testng/TestNGAntTask.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.apache.tools.ant.types.resources.FileResource;
3737
import org.apache.tools.ant.types.selectors.FilenameSelector;
3838
import org.testng.collections.Lists;
39+
import org.testng.internal.ExitCode;
3940
import org.testng.internal.Utils;
4041
import org.testng.reporters.VerboseReporter;
4142

@@ -738,7 +739,7 @@ protected void actOnResult(int exitValue, boolean wasKilled) {
738739
}
739740
}
740741

741-
boolean failed= ((exitValue & TestNG.HAS_FAILURE) == TestNG.HAS_FAILURE) || wasKilled;
742+
boolean failed= (ExitCode.hasFailure(exitValue)) || wasKilled;
742743
if(failed) {
743744
final String msg= wasKilled ? "The tests timed out and were killed." : "The tests failed.";
744745
if(m_haltOnFailure) {
@@ -754,7 +755,7 @@ protected void actOnResult(int exitValue, boolean wasKilled) {
754755
}
755756
}
756757

757-
if((exitValue & TestNG.HAS_SKIPPED) == TestNG.HAS_SKIPPED) {
758+
if(ExitCode.hasSkipped(exitValue)) {
758759
if(m_haltOnSkipped) {
759760
executeHaltTarget(exitValue);
760761
throw new BuildException("There are TestNG SKIPPED tests");
@@ -768,7 +769,7 @@ protected void actOnResult(int exitValue, boolean wasKilled) {
768769
}
769770
}
770771

771-
if((exitValue & TestNG.HAS_FSP) == TestNG.HAS_FSP) {
772+
if(ExitCode.hasFailureWithinSuccessPercentage(exitValue)) {
772773
if(m_haltOnFSP) {
773774
executeHaltTarget(exitValue);
774775
throw new BuildException("There are TestNG FAILED WITHIN SUCCESS PERCENTAGE tests");
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.testng.internal;
2+
3+
import org.testng.IResultMap;
4+
import org.testng.ITestContext;
5+
6+
import java.util.BitSet;
7+
8+
/**
9+
* |---------------------|---------|--------|-------------|------------------------------------------|
10+
* | FailedWithinSuccess | Skipped | Failed | Status Code | Remarks |
11+
* |---------------------|---------|--------|-------------|------------------------------------------|
12+
* | 0 | 0 | 0 | 0 | Passed tests |
13+
* | 0 | 0 | 1 | 1 | Failed tests |
14+
* | 0 | 1 | 0 | 2 | Skipped tests |
15+
* | 0 | 1 | 1 | 3 | Skipped/Failed tests |
16+
* | 1 | 0 | 0 | 4 | FailedWithinSuccess tests |
17+
* | 1 | 0 | 1 | 5 | FailedWithinSuccess/Failed tests |
18+
* | 1 | 1 | 0 | 6 | FailedWithinSuccess/Skipped tests |
19+
* | 1 | 1 | 1 | 7 | FailedWithinSuccess/Skipped/Failed tests |
20+
* |---------------------|---------|--------|-------------|------------------------------------------|
21+
*/
22+
public class ExitCode {
23+
24+
private final BitSet exitCodeBits;
25+
26+
ExitCode() {
27+
this(new BitSet(3));
28+
}
29+
30+
public static boolean hasFailureWithinSuccessPercentage(int returnCode) {
31+
return (returnCode >= 4 && returnCode <= 7);
32+
}
33+
34+
public static boolean hasSkipped(int returnCode) {
35+
return (returnCode == 2 || returnCode == 3 || returnCode == 6 || returnCode == 7);
36+
}
37+
38+
public static boolean hasFailure(int returnCode) {
39+
return (returnCode == 1 || returnCode == 3);
40+
}
41+
42+
public static ExitCode newExitCodeRepresentingFailure() {
43+
BitSet bitSet = new BitSet(3);
44+
bitSet.set(0, true);
45+
bitSet.set(1, false);
46+
bitSet.set(2, false);
47+
48+
return new ExitCode(bitSet);
49+
}
50+
51+
private ExitCode(BitSet exitCodeBits) {
52+
this.exitCodeBits = exitCodeBits;
53+
}
54+
55+
void computeAndUpdate(ITestContext context) {
56+
computeAndUpdate(0, context.getFailedTests(), context.getFailedConfigurations());
57+
computeAndUpdate(1, context.getSkippedTests(), context.getSkippedConfigurations());
58+
computeAndUpdate(2, context.getFailedButWithinSuccessPercentageTests(), null);
59+
}
60+
61+
private void computeAndUpdate(int index, IResultMap testResults, IResultMap configResults) {
62+
boolean containsResults = testResults.size() != 0;
63+
if (configResults != null) {
64+
containsResults = containsResults || configResults.size() != 0;
65+
}
66+
if (containsResults) {
67+
this.exitCodeBits.set(index);
68+
}
69+
}
70+
71+
public boolean hasFailure() {
72+
return exitCodeBits.get(0);
73+
}
74+
75+
public boolean hasSkip() {
76+
return exitCodeBits.get(1);
77+
}
78+
79+
public boolean hasFailureWithinSuccessPercentage() {
80+
return exitCodeBits.get(2);
81+
}
82+
83+
public int getExitCode() {
84+
int exitCode = 0;
85+
for (int i = 0; i < exitCodeBits.length(); i++) {
86+
if (exitCodeBits.get(i)) {
87+
exitCode = exitCode | (1 << i);
88+
}
89+
}
90+
91+
return exitCode;
92+
}
93+
}

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

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,65 +8,28 @@
88
import org.testng.ITestResult;
99
import org.testng.xml.XmlSuite;
1010

11-
import java.util.BitSet;
1211
import java.util.List;
1312

1413
public class ExitCodeListener implements ITestListener, IReporter {
1514
private boolean hasTests = false;
16-
private int status;
15+
private ExitCode status = new ExitCode();
1716

18-
public int getStatus() {
17+
public ExitCode getStatus() {
1918
return status;
2019
}
2120

22-
public boolean isHasTests() {
21+
public boolean hasTests() {
2322
return hasTests;
2423
}
2524

2625
@Override
2726
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
28-
BitSet initial = new BitSet(3);
29-
initial.set(0, false); // Success bit
30-
initial.set(1, false); // failed bit
31-
initial.set(2, false); // skipped bit
3227
for (ISuite suite : suites) {
3328
for (ISuiteResult suiteResult : suite.getResults().values()) {
3429
ITestContext context = suiteResult.getTestContext();
35-
boolean passed = (context.getPassedTests().size() != 0) ||
36-
(context.getPassedConfigurations().size() != 0);
37-
initial.set(0, passed);
38-
boolean failed = (context.getFailedTests().size() != 0) ||
39-
(context.getFailedConfigurations().size() != 0) ||
40-
(context.getFailedButWithinSuccessPercentageTests().size() !=0);
41-
initial.set(1, failed);
42-
boolean skipped = (context.getSkippedTests().size() != 0) ||
43-
(context.getSkippedConfigurations().size() != 0);
44-
initial.set(2, skipped);
45-
46-
}
47-
}
48-
status = convert(initial);
49-
}
50-
51-
private static int convert(BitSet set) {
52-
int size = set.length() - 1;
53-
int value = 0;
54-
for (int i= size;i >=0;i--) {
55-
int prefix = 0;
56-
if (set.get(i)) {
57-
prefix = 1;
30+
status.computeAndUpdate(context);
5831
}
59-
value += Math.pow(2, i) * prefix;
60-
}
61-
return transform(value);
62-
}
63-
64-
65-
private static int transform(int value) {
66-
if (value ==0 || value == 1) {
67-
return 0;
6832
}
69-
return value;
7033
}
7134

7235
@Override

src/test/java/test/cli/github1517/ExitCodeListenerBehaviorTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ public void testMethod(Class<?> clazz, int expectedStatus) {
1818
@DataProvider
1919
public Object[][] getData() {
2020
return new Object[][]{
21-
{TestClassWithConfigFailureSample.class, 6},
22-
{TestClassWithConfigSkipSample.class, 4},
23-
{TestClassWithConfigSkipAndFailureSample.class, 6}
21+
{TestClassWithConfigFailureSample.class, 3},
22+
{TestClassWithConfigSkipSample.class, 2},
23+
{TestClassWithConfigSkipAndFailureSample.class, 3}
2424
};
2525
}
2626

0 commit comments

Comments
 (0)