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