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 org.apache.maven.surefire.common.junit4.Notifier;
23 import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
24 import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder;
25 import org.apache.maven.surefire.report.ConsoleStream;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.apache.maven.surefire.util.TestsToRun;
28 import org.junit.Ignore;
29 import org.junit.runner.Computer;
30 import org.junit.runner.Description;
31 import org.junit.runner.Request;
32 import org.junit.runner.Result;
33 import org.junit.runner.manipulation.Filter;
34 import org.junit.runner.notification.RunListener;
35 import org.junit.runner.notification.StoppedByUserException;
36
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Iterator;
40 import java.util.Queue;
41
42 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.createDescription;
43 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.createIgnored;
44 import static org.apache.maven.surefire.common.junit4.JUnit4RunListener.rethrowAnyTestMechanismFailures;
45 import static org.junit.runner.Computer.serial;
46 import static org.junit.runner.Request.classes;
47
48
49
50
51
52
53 final class JUnitCoreWrapper
54 {
55 private final Notifier notifier;
56 private final JUnitCoreParameters jUnitCoreParameters;
57 private final ConsoleStream consoleStream;
58
59 JUnitCoreWrapper( Notifier notifier, JUnitCoreParameters jUnitCoreParameters, ConsoleStream consoleStream )
60 {
61 this.notifier = notifier;
62 this.jUnitCoreParameters = jUnitCoreParameters;
63 this.consoleStream = consoleStream;
64 }
65
66 void execute( TestsToRun testsToRun, Filter filter )
67 throws TestSetFailedException
68 {
69 execute( testsToRun, true, Collections.<RunListener>emptyList(), filter );
70 }
71
72 void execute( TestsToRun testsToRun, Collection<RunListener> listeners, Filter filter )
73 throws TestSetFailedException
74 {
75 execute( testsToRun, false, listeners, filter );
76 }
77
78 private void execute( TestsToRun testsToRun, boolean useIterated, Collection<RunListener> listeners, Filter filter )
79 throws TestSetFailedException
80 {
81 if ( testsToRun.allowEagerReading() )
82 {
83 executeEager( testsToRun, filter, listeners );
84 }
85 else
86 {
87 executeLazy( testsToRun, useIterated, filter, listeners );
88 }
89 }
90
91 private JUnitCore createJUnitCore( Notifier notifier, Collection<RunListener> listeners )
92 {
93 JUnitCore junitCore = new JUnitCore();
94
95
96 notifier.addListeners( listeners );
97
98 return junitCore;
99 }
100
101 private void executeEager( TestsToRun testsToRun, Filter filter, Collection<RunListener> listeners )
102 throws TestSetFailedException
103 {
104 JUnitCore junitCore = createJUnitCore( notifier, listeners );
105 Class<?>[] tests = testsToRun.getLocatedClasses();
106 Computer computer = createComputer();
107 createRequestAndRun( filter, computer, junitCore.withReportedTests( tests ), tests );
108 }
109
110 private void executeLazy( TestsToRun testsToRun, boolean useIterated, Filter filter,
111 Collection<RunListener> listeners )
112 throws TestSetFailedException
113 {
114 JUnitCore junitCore = createJUnitCore( notifier, listeners );
115 for ( Iterator<Class<?>> it = useIterated ? testsToRun.iterated() : testsToRun.iterator(); it.hasNext(); )
116 {
117 Class<?> clazz = it.next();
118 Computer computer = createComputer();
119 createRequestAndRun( filter, computer, junitCore.withReportedTests( clazz ), clazz );
120 }
121 }
122
123 private void createRequestAndRun( Filter filter, Computer computer, JUnitCore junitCore, Class<?>... classesToRun )
124 throws TestSetFailedException
125 {
126 Request req = classes( computer, classesToRun );
127 if ( filter != null )
128 {
129 req = new FilteringRequest( req, filter );
130 if ( req.getRunner() == null )
131 {
132
133 return;
134 }
135 }
136
137 Result run = junitCore.run( req.getRunner() );
138 rethrowAnyTestMechanismFailures( run );
139
140 if ( computer instanceof ParallelComputer )
141 {
142 String timeoutMessage = ( (ParallelComputer) computer ).describeElapsedTimeout();
143 if ( !timeoutMessage.isEmpty() )
144 {
145 throw new TestSetFailedException( timeoutMessage );
146 }
147 }
148 }
149
150 private Computer createComputer()
151 {
152 return jUnitCoreParameters.isNoThreading()
153 ? serial()
154 : new ParallelComputerBuilder( consoleStream, jUnitCoreParameters ).buildComputer();
155 }
156
157 private final class JUnitCore
158 extends org.apache.maven.surefire.junitcore.JUnitCore
159 {
160 JUnitCore()
161 {
162 super( JUnitCoreWrapper.this.notifier );
163 }
164
165 JUnitCore withReportedTests( Class<?>... tests )
166 {
167 Queue<String> stoppedTests = JUnitCoreWrapper.this.notifier.getRemainingTestClasses();
168 if ( stoppedTests != null )
169 {
170 for ( Class<?> test : tests )
171 {
172 stoppedTests.add( test.getName() );
173 }
174 }
175 return this;
176 }
177
178 @Override
179 @SuppressWarnings( "checkstyle:innerassignment" )
180 protected void afterException( Throwable e )
181 throws TestSetFailedException
182 {
183 if ( JUnitCoreWrapper.this.notifier.isFailFast() && e instanceof StoppedByUserException )
184 {
185 Queue<String> stoppedTests = JUnitCoreWrapper.this.notifier.getRemainingTestClasses();
186 if ( stoppedTests != null )
187 {
188 String reason = e.getClass().getName();
189 Ignore reasonForSkippedTest = createIgnored( reason );
190 for ( String clazz; ( clazz = stoppedTests.poll() ) != null; )
191 {
192 Description skippedTest = createDescription( clazz, reasonForSkippedTest );
193 JUnitCoreWrapper.this.notifier.fireTestIgnored( skippedTest );
194 }
195 }
196 }
197 else
198 {
199 super.afterException( e );
200 }
201 }
202
203 @Override
204 protected void afterFinished()
205 {
206 Queue<String> stoppedTests = JUnitCoreWrapper.this.notifier.getRemainingTestClasses();
207 if ( stoppedTests != null )
208 {
209 stoppedTests.clear();
210 }
211 }
212 }
213 }