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.Map;
23 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
24 import org.apache.maven.surefire.api.report.ConsoleStream;
25 import org.apache.maven.surefire.api.report.ReportEntry;
26 import org.apache.maven.surefire.api.report.ReporterFactory;
27 import org.apache.maven.surefire.api.report.RunListener;
28 import org.apache.maven.surefire.api.report.RunMode;
29 import org.apache.maven.surefire.api.report.StackTraceWriter;
30 import org.apache.maven.surefire.api.report.TestSetReportEntry;
31 import org.apache.maven.surefire.api.testset.TestSetFailedException;
32
33 import static org.apache.maven.surefire.junitcore.TestMethod.getThreadTestMethod;
34
35
36
37
38
39
40
41
42
43
44
45
46 public abstract class ConcurrentRunListener
47 implements RunListener, ConsoleOutputReceiver
48 {
49 private final Map<String, TestSet> classMethodCounts;
50
51 private final ThreadLocal<RunListener> reporterManagerThreadLocal;
52
53 private final boolean reportImmediately;
54
55 private final ConsoleStream consoleStream;
56
57 ConcurrentRunListener( final ReporterFactory reporterFactory, ConsoleStream consoleStream,
58 boolean reportImmediately, Map<String, TestSet> classMethodCounts )
59 throws TestSetFailedException
60 {
61 this.reportImmediately = reportImmediately;
62 this.classMethodCounts = classMethodCounts;
63 this.consoleStream = consoleStream;
64 reporterManagerThreadLocal = new ThreadLocal<RunListener>()
65 {
66 @Override
67 protected RunListener initialValue()
68 {
69 return reporterFactory.createReporter();
70 }
71 };
72 }
73
74 @Override
75 public void testSetStarting( TestSetReportEntry description )
76 {
77 }
78
79 @Override
80 public void testSetCompleted( TestSetReportEntry result )
81 {
82 try
83 {
84 final RunListener reporterManager = getRunListener();
85 for ( TestSet testSet : classMethodCounts.values() )
86 {
87 testSet.replay( reporterManager );
88 }
89 }
90 finally
91 {
92 reporterManagerThreadLocal.remove();
93 }
94 }
95
96 @Override
97 public void testFailed( ReportEntry failure )
98 {
99 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
100 if ( testMethod != null )
101 {
102 testMethod.testFailure( failure );
103 testMethod.detachFromCurrentThread();
104 }
105 }
106
107 @Override
108 public void testError( ReportEntry failure )
109 {
110 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
111 if ( testMethod != null )
112 {
113 testMethod.testError( failure );
114 testMethod.detachFromCurrentThread();
115 }
116 }
117
118 @Override
119 public void testSkipped( ReportEntry description )
120 {
121 TestSet testSet = getTestSet( description );
122 TestMethod testMethod = testSet.createThreadAttachedTestMethod( description );
123 testMethod.testIgnored( description );
124 testSet.incrementFinishedTests( getRunListener(), reportImmediately );
125 testMethod.detachFromCurrentThread();
126 }
127
128 @Override
129 public void testExecutionSkippedByUser()
130 {
131
132 getRunListener().testExecutionSkippedByUser();
133 }
134
135 public RunMode markAs( RunMode currentRunMode )
136 {
137 return reporterManagerThreadLocal.get().markAs( currentRunMode );
138 }
139
140 @Override
141 public void testAssumptionFailure( ReportEntry failure )
142 {
143 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
144 if ( testMethod != null )
145 {
146 testMethod.testAssumption( failure );
147 testMethod.detachFromCurrentThread();
148 }
149 }
150
151 @Override
152 public void testStarting( ReportEntry description )
153 {
154 TestSet testSet = getTestSet( description );
155 testSet.createThreadAttachedTestMethod( description );
156
157 checkIfTestSetCanBeReported( testSet );
158 testSet.attachToThread();
159 }
160
161 @Override
162 public void testSucceeded( ReportEntry report )
163 {
164 TestMethod testMethod = getThreadTestMethod();
165 if ( testMethod != null )
166 {
167 testMethod.testFinished();
168 testMethod.getTestSet().incrementFinishedTests( getRunListener(), reportImmediately );
169 testMethod.detachFromCurrentThread();
170 }
171 }
172
173 private TestMethod getOrCreateThreadAttachedTestMethod( ReportEntry description )
174 {
175 TestMethod threadTestMethod = getThreadTestMethod();
176 if ( threadTestMethod != null )
177 {
178 return threadTestMethod;
179 }
180 TestSet testSet = getTestSet( description );
181 if ( testSet == null )
182 {
183 consoleStream.println( description.getName() );
184 StackTraceWriter writer = description.getStackTraceWriter();
185 if ( writer != null )
186 {
187 consoleStream.println( writer.writeTraceToString() );
188 }
189 return null;
190 }
191 else
192 {
193 return testSet.createThreadAttachedTestMethod( description );
194 }
195 }
196
197 protected abstract void checkIfTestSetCanBeReported( TestSet testSetForTest );
198
199 private TestSet getTestSet( ReportEntry description )
200 {
201 return classMethodCounts.get( description.getSourceName() );
202 }
203
204 RunListener getRunListener()
205 {
206 return reporterManagerThreadLocal.get();
207 }
208
209 public static ConcurrentRunListener createInstance( Map<String, TestSet> classMethodCounts,
210 ReporterFactory reporterFactory,
211 boolean parallelClasses, boolean parallelBoth,
212 ConsoleStream consoleStream )
213 throws TestSetFailedException
214 {
215 return parallelClasses
216 ? new ClassesParallelRunListener( classMethodCounts, reporterFactory, consoleStream )
217 : new MethodsParallelRunListener( classMethodCounts, reporterFactory, !parallelBoth, consoleStream );
218 }
219
220
221 @Override
222 public void writeTestOutput( String output, boolean newLine, boolean stdout )
223 {
224 TestMethod threadTestMethod = getThreadTestMethod();
225 if ( threadTestMethod != null )
226 {
227 LogicalStream logicalStream = threadTestMethod.getLogicalStream();
228 logicalStream.write( stdout, output, newLine );
229 }
230 else
231 {
232
233 consoleStream.println( output );
234 }
235 }
236 }