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   */
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          // don't start a thread in CommandReader while we are in in-plugin process
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          * {@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             @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 }