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