1 package org.apache.maven.surefire.junitcore;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.concurrent.ConcurrentHashMap;
27
28 import org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil;
29 import org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory;
30 import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
31 import org.apache.maven.surefire.common.junit48.FilterFactory;
32 import org.apache.maven.surefire.common.junit48.JUnit48Reflector;
33 import org.apache.maven.surefire.common.junit48.JUnit48TestChecker;
34 import org.apache.maven.surefire.providerapi.AbstractProvider;
35 import org.apache.maven.surefire.providerapi.ProviderParameters;
36 import org.apache.maven.surefire.report.ConsoleLogger;
37 import org.apache.maven.surefire.report.ConsoleOutputCapture;
38 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
39 import org.apache.maven.surefire.report.ReporterFactory;
40 import org.apache.maven.surefire.report.RunListener;
41 import org.apache.maven.surefire.suite.RunResult;
42 import org.apache.maven.surefire.testset.TestSetFailedException;
43 import org.apache.maven.surefire.util.RunOrderCalculator;
44 import org.apache.maven.surefire.util.ScanResult;
45 import org.apache.maven.surefire.util.ScannerFilter;
46 import org.apache.maven.surefire.util.TestsToRun;
47 import org.apache.maven.surefire.util.internal.StringUtils;
48 import org.junit.runner.manipulation.Filter;
49
50
51
52
53 @SuppressWarnings( { "UnusedDeclaration" } )
54 public class JUnitCoreProvider
55 extends AbstractProvider
56 {
57 private final ClassLoader testClassLoader;
58
59 private final JUnitCoreParameters jUnitCoreParameters;
60
61 private final ScannerFilter scannerFilter;
62
63 private final List<org.junit.runner.notification.RunListener> customRunListeners;
64
65 private final ProviderParameters providerParameters;
66
67 private final ScanResult scanResult;
68
69 private final int rerunFailingTestsCount;
70
71 private TestsToRun testsToRun;
72
73 private JUnit48Reflector jUnit48Reflector;
74
75 private RunOrderCalculator runOrderCalculator;
76
77 private String requestedTestMethod;
78
79 public JUnitCoreProvider( ProviderParameters providerParameters )
80 {
81 this.providerParameters = providerParameters;
82 testClassLoader = providerParameters.getTestClassLoader();
83 scanResult = providerParameters.getScanResult();
84 runOrderCalculator = providerParameters.getRunOrderCalculator();
85 jUnitCoreParameters = new JUnitCoreParameters( providerParameters.getProviderProperties() );
86 scannerFilter = new JUnit48TestChecker( testClassLoader );
87 requestedTestMethod = providerParameters.getTestRequest().getRequestedTestMethod();
88 rerunFailingTestsCount = providerParameters.getTestRequest().getRerunFailingTestsCount();
89
90 customRunListeners =
91 JUnit4RunListenerFactory.createCustomListeners(
92 providerParameters.getProviderProperties().getProperty( "listener" ) );
93 jUnit48Reflector = new JUnit48Reflector( testClassLoader );
94 }
95
96 public Boolean isRunnable()
97 {
98 return Boolean.TRUE;
99 }
100
101 public Iterator getSuites()
102 {
103 testsToRun = scanClassPath();
104 return testsToRun.iterator();
105 }
106
107 private boolean isSingleThreaded()
108 {
109 return jUnitCoreParameters.isNoThreading();
110 }
111
112 public RunResult invoke( Object forkTestSet )
113 throws TestSetFailedException
114 {
115 final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
116
117 final ConsoleLogger consoleLogger = providerParameters.getConsoleLogger();
118
119 Filter filter = jUnit48Reflector.isJUnit48Available() ? createJUnit48Filter() : null;
120
121 if ( testsToRun == null )
122 {
123 if ( forkTestSet instanceof TestsToRun )
124 {
125 testsToRun = (TestsToRun) forkTestSet;
126 }
127 else if ( forkTestSet instanceof Class )
128 {
129 Class theClass = (Class) forkTestSet;
130 testsToRun = TestsToRun.fromClass( theClass );
131 }
132 else
133 {
134 testsToRun = scanClassPath();
135 }
136 }
137
138 customRunListeners.add( 0, getRunListener( reporterFactory, consoleLogger ) );
139
140
141 JUnitTestFailureListener testFailureListener = new JUnitTestFailureListener();
142 customRunListeners.add( 0, testFailureListener );
143
144 JUnitCoreWrapper.execute( consoleLogger, testsToRun, jUnitCoreParameters, customRunListeners, filter );
145
146
147 if ( rerunFailingTestsCount > 0 )
148 {
149 for ( int i = 0; i < rerunFailingTestsCount && !testFailureListener.getAllFailures().isEmpty(); i++ )
150 {
151 Map<Class<?>, Set<String>> failingTests =
152 JUnit4ProviderUtil.generateFailingTests( testFailureListener.getAllFailures(), testsToRun );
153 testFailureListener.reset();
154 final FilterFactory filterFactory = new FilterFactory( testClassLoader );
155 Filter failingMethodsFilter = filterFactory.createFailingMethodFilter( failingTests );
156 JUnitCoreWrapper.execute( consoleLogger, testsToRun, jUnitCoreParameters, customRunListeners,
157 filterFactory.and( filter, failingMethodsFilter ) );
158 }
159 }
160 return reporterFactory.close();
161 }
162
163 private org.junit.runner.notification.RunListener getRunListener( ReporterFactory reporterFactory,
164 ConsoleLogger consoleLogger )
165 throws TestSetFailedException
166 {
167 org.junit.runner.notification.RunListener jUnit4RunListener;
168 if ( isSingleThreaded() )
169 {
170 NonConcurrentRunListener rm = new NonConcurrentRunListener( reporterFactory.createReporter() );
171 ConsoleOutputCapture.startCapture( rm );
172 jUnit4RunListener = rm;
173 }
174 else
175 {
176 final Map<String, TestSet> testSetMap = new ConcurrentHashMap<String, TestSet>();
177
178 RunListener listener =
179 ConcurrentRunListener.createInstance( testSetMap, reporterFactory,
180 isParallelTypes(),
181 isParallelMethodsAndTypes(), consoleLogger );
182 ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) listener );
183
184 jUnit4RunListener = new JUnitCoreRunListener( listener, testSetMap );
185 }
186 return jUnit4RunListener;
187 }
188
189 private boolean isParallelMethodsAndTypes()
190 {
191 return jUnitCoreParameters.isParallelMethods() && isParallelTypes();
192 }
193
194 private boolean isParallelTypes()
195 {
196 return jUnitCoreParameters.isParallelClasses() || jUnitCoreParameters.isParallelSuites();
197 }
198
199 private Filter createJUnit48Filter()
200 {
201 final FilterFactory filterFactory = new FilterFactory( testClassLoader );
202 Filter groupFilter = filterFactory.createGroupFilter( providerParameters.getProviderProperties() );
203 return isMethodFilterSpecified() ? filterFactory.and( groupFilter,
204 filterFactory.createMethodFilter( requestedTestMethod ) )
205 : groupFilter;
206 }
207
208 private TestsToRun scanClassPath()
209 {
210 final TestsToRun scanned = scanResult.applyFilter( scannerFilter, testClassLoader );
211 return runOrderCalculator.orderTestClasses( scanned );
212 }
213
214 private boolean isMethodFilterSpecified()
215 {
216 return !StringUtils.isBlank( requestedTestMethod );
217 }
218 }