1 package org.apache.maven.surefire.testng;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.booter.Command;
23 import org.apache.maven.surefire.booter.CommandListener;
24 import org.apache.maven.surefire.booter.CommandReader;
25 import org.apache.maven.surefire.cli.CommandLineOption;
26 import org.apache.maven.surefire.providerapi.AbstractProvider;
27 import org.apache.maven.surefire.providerapi.ProviderParameters;
28 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
29 import org.apache.maven.surefire.report.ReporterConfiguration;
30 import org.apache.maven.surefire.report.ReporterFactory;
31 import org.apache.maven.surefire.report.RunListener;
32 import org.apache.maven.surefire.suite.RunResult;
33 import org.apache.maven.surefire.testng.utils.FailFastEventsSingleton;
34 import org.apache.maven.surefire.testset.TestListResolver;
35 import org.apache.maven.surefire.testset.TestRequest;
36 import org.apache.maven.surefire.testset.TestSetFailedException;
37 import org.apache.maven.surefire.util.RunOrderCalculator;
38 import org.apache.maven.surefire.util.ScanResult;
39 import org.apache.maven.surefire.util.TestsToRun;
40
41 import java.io.File;
42 import java.util.Collection;
43 import java.util.List;
44 import java.util.Map;
45
46 import static org.apache.maven.surefire.booter.CommandReader.getReader;
47 import static org.apache.maven.surefire.report.ConsoleOutputCapture.startCapture;
48 import static org.apache.maven.surefire.testset.TestListResolver.getEmptyTestListResolver;
49 import static org.apache.maven.surefire.testset.TestListResolver.optionallyWildcardFilter;
50 import static org.apache.maven.surefire.util.TestsToRun.fromClass;
51
52
53
54
55 public class TestNGProvider
56 extends AbstractProvider
57 {
58 private final Map<String, String> providerProperties;
59
60 private final ReporterConfiguration reporterConfiguration;
61
62 private final ClassLoader testClassLoader;
63
64 private final ScanResult scanResult;
65
66 private final TestRequest testRequest;
67
68 private final ProviderParameters providerParameters;
69
70 private final RunOrderCalculator runOrderCalculator;
71
72 private final List<CommandLineOption> mainCliOptions;
73
74 private final CommandReader commandsReader;
75
76 private TestsToRun testsToRun;
77
78 public TestNGProvider( ProviderParameters bootParams )
79 {
80
81 commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
82 providerParameters = bootParams;
83 testClassLoader = bootParams.getTestClassLoader();
84 runOrderCalculator = bootParams.getRunOrderCalculator();
85 providerProperties = bootParams.getProviderProperties();
86 testRequest = bootParams.getTestRequest();
87 reporterConfiguration = bootParams.getReporterConfiguration();
88 scanResult = bootParams.getScanResult();
89 mainCliOptions = bootParams.getMainCliOptions();
90 }
91
92 @Override
93 public RunResult invoke( Object forkTestSet )
94 throws TestSetFailedException
95 {
96 if ( isFailFast() && commandsReader != null )
97 {
98 registerPleaseStopListener();
99 }
100
101 final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
102 final RunListener reporter = reporterFactory.createReporter();
103
104
105
106
107 startCapture( (ConsoleOutputReceiver) reporter );
108
109 RunResult runResult;
110 try
111 {
112 if ( isTestNGXmlTestSuite( testRequest ) )
113 {
114 if ( commandsReader != null )
115 {
116 commandsReader.awaitStarted();
117 }
118 TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite();
119 testNGXmlTestSuite.locateTestSets();
120 testNGXmlTestSuite.execute( reporter );
121 }
122 else
123 {
124 if ( testsToRun == null )
125 {
126 if ( forkTestSet instanceof TestsToRun )
127 {
128 testsToRun = (TestsToRun) forkTestSet;
129 }
130 else if ( forkTestSet instanceof Class )
131 {
132 testsToRun = fromClass( (Class<?>) forkTestSet );
133 }
134 else
135 {
136 testsToRun = scanClassPath();
137 }
138 }
139
140 if ( commandsReader != null )
141 {
142 registerShutdownListener( testsToRun );
143 commandsReader.awaitStarted();
144 }
145 TestNGDirectoryTestSuite suite = newDirectorySuite();
146 suite.execute( testsToRun, reporter );
147 }
148 }
149 finally
150 {
151 runResult = reporterFactory.close();
152 }
153 return runResult;
154 }
155
156 boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
157 {
158 Collection<File> suiteXmlFiles = testSuiteDefinition.getSuiteXmlFiles();
159 return !suiteXmlFiles.isEmpty() && !hasSpecificTests();
160 }
161
162 private boolean isFailFast()
163 {
164 return providerParameters.getSkipAfterFailureCount() > 0;
165 }
166
167 private int getSkipAfterFailureCount()
168 {
169 return isFailFast() ? providerParameters.getSkipAfterFailureCount() : 0;
170 }
171
172 private void registerShutdownListener( final TestsToRun testsToRun )
173 {
174 commandsReader.addShutdownListener( new CommandListener()
175 {
176 @Override
177 public void update( Command command )
178 {
179 testsToRun.markTestSetFinished();
180 }
181 } );
182 }
183
184 private void registerPleaseStopListener()
185 {
186 commandsReader.addSkipNextTestsListener( new CommandListener()
187 {
188 @Override
189 public void update( Command command )
190 {
191 FailFastEventsSingleton.getInstance().setSkipOnNextTest();
192 }
193 } );
194 }
195
196 private TestNGDirectoryTestSuite newDirectorySuite()
197 {
198 return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
199 reporterConfiguration.getReportsDirectory(), getTestFilter(),
200 mainCliOptions, getSkipAfterFailureCount() );
201 }
202
203 private TestNGXmlTestSuite newXmlSuite()
204 {
205 return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(),
206 testRequest.getTestSourceDirectory().toString(),
207 providerProperties,
208 reporterConfiguration.getReportsDirectory(), getSkipAfterFailureCount() );
209 }
210
211 @Override
212 @SuppressWarnings( "unchecked" )
213 public Iterable<Class<?>> getSuites()
214 {
215 if ( isTestNGXmlTestSuite( testRequest ) )
216 {
217 try
218 {
219 return newXmlSuite().locateTestSets();
220 }
221 catch ( TestSetFailedException e )
222 {
223 throw new RuntimeException( e );
224 }
225 }
226 else
227 {
228 testsToRun = scanClassPath();
229 return testsToRun;
230 }
231 }
232
233 private TestsToRun scanClassPath()
234 {
235 final TestsToRun scanned = scanResult.applyFilter( null, testClassLoader );
236 return runOrderCalculator.orderTestClasses( scanned );
237 }
238
239 private boolean hasSpecificTests()
240 {
241 TestListResolver specificTestPatterns = testRequest.getTestListResolver();
242 return !specificTestPatterns.isEmpty() && !specificTestPatterns.isWildcard();
243 }
244
245 private TestListResolver getTestFilter()
246 {
247 TestListResolver filter = optionallyWildcardFilter( testRequest.getTestListResolver() );
248 return filter.isWildcard() ? getEmptyTestListResolver() : filter;
249 }
250 }