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.Collection; |
23 | |
import java.util.Collections; |
24 | |
import java.util.List; |
25 | |
import java.util.TreeSet; |
26 | |
import java.util.concurrent.Future; |
27 | |
import java.util.concurrent.TimeUnit; |
28 | |
|
29 | |
import org.apache.maven.surefire.common.junit4.JUnit4RunListener; |
30 | |
import org.apache.maven.surefire.junitcore.pc.ParallelComputer; |
31 | |
import org.apache.maven.surefire.testset.TestSetFailedException; |
32 | |
import org.apache.maven.surefire.util.TestsToRun; |
33 | |
|
34 | |
import org.junit.runner.Computer; |
35 | |
import org.junit.runner.Description; |
36 | |
import org.junit.runner.JUnitCore; |
37 | |
import org.junit.runner.Request; |
38 | |
import org.junit.runner.Result; |
39 | |
import org.junit.runner.Runner; |
40 | |
import org.junit.runner.manipulation.Filter; |
41 | |
import org.junit.runner.manipulation.NoTestsRemainException; |
42 | |
import org.junit.runner.notification.RunListener; |
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | 0 | class JUnitCoreWrapper |
51 | |
{ |
52 | |
private static class FilteringRequest |
53 | |
extends Request |
54 | |
{ |
55 | |
private Runner filteredRunner; |
56 | |
|
57 | |
public FilteringRequest( Request req, Filter filter ) |
58 | 0 | { |
59 | |
try |
60 | |
{ |
61 | 0 | Runner runner = req.getRunner(); |
62 | 0 | filter.apply( runner ); |
63 | 0 | filteredRunner = runner; |
64 | |
} |
65 | 0 | catch ( NoTestsRemainException e ) |
66 | |
{ |
67 | 0 | filteredRunner = null; |
68 | 0 | } |
69 | 0 | } |
70 | |
|
71 | |
@Override |
72 | |
public Runner getRunner() |
73 | |
{ |
74 | 0 | return filteredRunner; |
75 | |
} |
76 | |
} |
77 | |
|
78 | |
public static void execute( TestsToRun testsToRun, JUnitCoreParameters jUnitCoreParameters, |
79 | |
List<RunListener> listeners, Filter filter ) |
80 | |
throws TestSetFailedException |
81 | |
{ |
82 | 1 | ComputerWrapper computerWrapper = createComputer( jUnitCoreParameters ); |
83 | 1 | JUnitCore junitCore = createJUnitCore( listeners ); |
84 | 1 | if ( testsToRun.allowEagerReading() ) |
85 | |
{ |
86 | 1 | executeEager( testsToRun, filter, computerWrapper.getComputer(), junitCore ); |
87 | |
} |
88 | |
else |
89 | |
{ |
90 | 0 | exeuteLazy( testsToRun, filter, computerWrapper.getComputer(), junitCore ); |
91 | |
} |
92 | |
|
93 | 0 | String timeoutMessage = computerWrapper.describeElapsedTimeout(); |
94 | 0 | if ( timeoutMessage.length() != 0 ) |
95 | |
{ |
96 | 0 | throw new TestSetFailedException( timeoutMessage ); |
97 | |
} |
98 | 0 | } |
99 | |
|
100 | |
private static JUnitCore createJUnitCore( List<RunListener> listeners ) |
101 | |
{ |
102 | 1 | JUnitCore junitCore = new JUnitCore(); |
103 | 1 | for ( RunListener runListener : listeners ) |
104 | |
{ |
105 | 1 | junitCore.addListener( runListener ); |
106 | 1 | } |
107 | 1 | return junitCore; |
108 | |
} |
109 | |
|
110 | |
private static void executeEager(TestsToRun testsToRun, Filter filter, Computer computer, JUnitCore junitCore) |
111 | |
throws TestSetFailedException |
112 | |
{ |
113 | 1 | Class[] tests = testsToRun.getLocatedClasses(); |
114 | 1 | createRequestAndRun( filter, computer, junitCore, tests ); |
115 | 0 | } |
116 | |
|
117 | |
private static void exeuteLazy(TestsToRun testsToRun, Filter filter, Computer computer, JUnitCore junitCore) |
118 | |
throws TestSetFailedException |
119 | |
{ |
120 | |
|
121 | 0 | for ( Class clazz : testsToRun ) |
122 | |
{ |
123 | 0 | createRequestAndRun( filter, computer, junitCore, clazz ); |
124 | 0 | } |
125 | 0 | } |
126 | |
|
127 | |
private static void createRequestAndRun( Filter filter, Computer computer, JUnitCore junitCore, Class<?>... classesToRun ) |
128 | |
throws TestSetFailedException |
129 | |
{ |
130 | 1 | Request req = Request.classes( computer, classesToRun ); |
131 | 1 | if ( filter != null ) |
132 | |
{ |
133 | 0 | req = new FilteringRequest( req, filter ); |
134 | 0 | if ( req.getRunner() == null ) |
135 | |
{ |
136 | |
|
137 | 0 | return; |
138 | |
} |
139 | |
} |
140 | |
|
141 | 1 | final Result run = junitCore.run( req ); |
142 | 1 | JUnit4RunListener.rethrowAnyTestMechanismFailures( run ); |
143 | 0 | } |
144 | |
|
145 | |
private static ComputerWrapper createComputer( JUnitCoreParameters parameters ) |
146 | |
throws TestSetFailedException |
147 | |
{ |
148 | 1 | return parameters.isNoThreading() ? new ComputerWrapper( Computer.serial() ) : createParallelComputer( parameters ); |
149 | |
} |
150 | |
|
151 | |
private static ComputerWrapper createParallelComputer( JUnitCoreParameters parameters ) |
152 | |
throws TestSetFailedException |
153 | |
{ |
154 | 0 | ParallelComputer pc = ParallelComputerFactory.createParallelComputer( parameters ); |
155 | |
|
156 | 0 | int timeout = parameters.getParallelTestsTimeoutInSeconds(); |
157 | |
|
158 | 0 | int timeoutForced = parameters.getParallelTestsTimeoutForcedInSeconds(); |
159 | |
|
160 | 0 | Future<Collection<Description>> testsBeforeShutdown = |
161 | |
timeout > 0 ? pc.scheduleShutdown( timeout, TimeUnit.SECONDS ) : null; |
162 | |
|
163 | 0 | Future<Collection<Description>> testsBeforeForcedShutdown = |
164 | |
timeoutForced > 0 ? pc.scheduleForcedShutdown( timeoutForced, TimeUnit.SECONDS ) : null; |
165 | |
|
166 | 0 | return new ComputerWrapper( pc, timeout, testsBeforeShutdown, timeoutForced, testsBeforeForcedShutdown ); |
167 | |
} |
168 | |
|
169 | 0 | private static class ComputerWrapper |
170 | |
{ |
171 | |
private final Computer computer; |
172 | |
private final int timeout; |
173 | |
private final int timeoutForced; |
174 | |
private final Future<Collection<Description>> testsBeforeShutdown; |
175 | |
private final Future<Collection<Description>> testsBeforeForcedShutdown; |
176 | |
|
177 | |
ComputerWrapper( Computer computer ) |
178 | |
{ |
179 | 1 | this( computer, 0, null, 0, null ); |
180 | 1 | } |
181 | |
|
182 | |
ComputerWrapper( Computer computer, |
183 | |
int timeout, Future<Collection<Description>> testsBeforeShutdown, |
184 | |
int timeoutForced, Future<Collection<Description>> testsBeforeForcedShutdown ) |
185 | 1 | { |
186 | 1 | this.computer = computer; |
187 | 1 | this.timeout = timeout; |
188 | 1 | this.testsBeforeShutdown = testsBeforeShutdown; |
189 | 1 | this.timeoutForced = timeoutForced; |
190 | 1 | this.testsBeforeForcedShutdown = testsBeforeForcedShutdown; |
191 | 1 | } |
192 | |
|
193 | |
Computer getComputer() |
194 | |
{ |
195 | 1 | return computer; |
196 | |
} |
197 | |
|
198 | |
String describeElapsedTimeout() throws TestSetFailedException |
199 | |
{ |
200 | 0 | TreeSet<String> executedTests = new TreeSet<String>(); |
201 | 0 | if ( timeout > 0 ) |
202 | |
{ |
203 | 0 | executedTests.addAll( printShutdownHook( testsBeforeShutdown ) ); |
204 | |
} |
205 | |
|
206 | 0 | if ( timeoutForced > 0 ) |
207 | |
{ |
208 | 0 | executedTests.addAll( printShutdownHook( testsBeforeForcedShutdown ) ); |
209 | |
} |
210 | |
|
211 | 0 | StringBuilder msg = new StringBuilder(); |
212 | 0 | if ( !executedTests.isEmpty() ) |
213 | |
{ |
214 | 0 | msg.append( "The test run has finished abruptly after timeout of " ); |
215 | 0 | msg.append( Math.min( timeout, timeoutForced ) ); |
216 | 0 | msg.append( " seconds.\n" ); |
217 | 0 | msg.append( "These tests were executed in prior of the shutdown operation:\n" ); |
218 | 0 | for ( String executedTest : executedTests ) |
219 | |
{ |
220 | 0 | msg.append( executedTest ).append( "\n" ); |
221 | 0 | } |
222 | |
} |
223 | 0 | return msg.toString(); |
224 | |
} |
225 | |
|
226 | |
static Collection<String> printShutdownHook( Future<Collection<Description>> future ) |
227 | |
throws TestSetFailedException |
228 | |
{ |
229 | 0 | if ( !future.isCancelled() && future.isDone() ) |
230 | |
{ |
231 | |
try |
232 | |
{ |
233 | 0 | TreeSet<String> executedTests = new TreeSet<String>(); |
234 | 0 | for ( Description executedTest : future.get() ) |
235 | |
{ |
236 | 0 | if ( executedTest != null && executedTest.getDisplayName() != null ) |
237 | |
{ |
238 | 0 | executedTests.add( executedTest.getDisplayName() ); |
239 | |
} |
240 | 0 | } |
241 | 0 | return executedTests; |
242 | |
} |
243 | 0 | catch ( Exception e ) |
244 | |
{ |
245 | 0 | throw new TestSetFailedException( e ); |
246 | |
} |
247 | |
} |
248 | 0 | return Collections.emptySet(); |
249 | |
} |
250 | |
} |
251 | |
} |