View Javadoc
1   package org.apache.maven.surefire.testng;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * @author Kristian Rosenvold
54   * @noinspection UnusedDeclaration
55   */
56  public class TestNGProvider
57      extends AbstractProvider
58  {
59      private final Map<String, String> providerProperties;
60  
61      private final ReporterConfiguration reporterConfiguration;
62  
63      private final ClassLoader testClassLoader;
64  
65      private final ScanResult scanResult;
66  
67      private final TestRequest testRequest;
68  
69      private final ProviderParameters providerParameters;
70  
71      private final RunOrderCalculator runOrderCalculator;
72  
73      private final List<CommandLineOption> mainCliOptions;
74  
75      private final CommandReader commandsReader;
76  
77      private TestsToRun testsToRun;
78  
79      public TestNGProvider( ProviderParameters bootParams )
80      {
81          // don't start a thread in CommandReader while we are in in-plugin process
82          commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
83          providerParameters = bootParams;
84          testClassLoader = bootParams.getTestClassLoader();
85          runOrderCalculator = bootParams.getRunOrderCalculator();
86          providerProperties = bootParams.getProviderProperties();
87          testRequest = bootParams.getTestRequest();
88          reporterConfiguration = bootParams.getReporterConfiguration();
89          scanResult = bootParams.getScanResult();
90          mainCliOptions = bootParams.getMainCliOptions();
91      }
92  
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          * {@link org.apache.maven.surefire.report.ConsoleOutputCapture#startCapture(ConsoleOutputReceiver)}
105          * called in prior to initializing variable {@link #testsToRun}
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             public void update( Command command )
177             {
178                 testsToRun.markTestSetFinished();
179             }
180         } );
181     }
182 
183     private void registerPleaseStopListener()
184     {
185         commandsReader.addSkipNextTestsListener( new CommandListener()
186         {
187             public void update( Command command )
188             {
189                 FailFastEventsSingleton.getInstance().setSkipOnNextTest();
190             }
191         } );
192     }
193 
194     private TestNGDirectoryTestSuite newDirectorySuite()
195     {
196         return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
197                                              reporterConfiguration.getReportsDirectory(), getTestFilter(),
198                                              mainCliOptions, getSkipAfterFailureCount() );
199     }
200 
201     private TestNGXmlTestSuite newXmlSuite()
202     {
203         return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(),
204                                        testRequest.getTestSourceDirectory().toString(),
205                                        providerProperties,
206                                        reporterConfiguration.getReportsDirectory(), getSkipAfterFailureCount() );
207     }
208 
209     @SuppressWarnings( "unchecked" )
210     public Iterable<Class<?>> getSuites()
211     {
212         if ( isTestNGXmlTestSuite( testRequest ) )
213         {
214             try
215             {
216                 return newXmlSuite().locateTestSets();
217             }
218             catch ( TestSetFailedException e )
219             {
220                 throw new RuntimeException( e );
221             }
222         }
223         else
224         {
225             testsToRun = scanClassPath();
226             return testsToRun;
227         }
228     }
229 
230     private TestsToRun scanClassPath()
231     {
232         final TestsToRun scanned = scanResult.applyFilter( null, testClassLoader );
233         return runOrderCalculator.orderTestClasses( scanned );
234     }
235 
236     private boolean hasSpecificTests()
237     {
238         TestListResolver specificTestPatterns = testRequest.getTestListResolver();
239         return !specificTestPatterns.isEmpty() && !specificTestPatterns.isWildcard();
240     }
241 
242     private TestListResolver getTestFilter()
243     {
244         TestListResolver filter = optionallyWildcardFilter( testRequest.getTestListResolver() );
245         return filter.isWildcard() ? getEmptyTestListResolver() : filter;
246     }
247 }