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 final RunListener reporterManager = getRunListener();
82 for ( TestSet testSet : classMethodCounts.values() )
83 {
84 testSet.replay( reporterManager );
85 }
86 reporterManagerThreadLocal.remove();
87 }
88
89 @Override
90 public void testFailed( ReportEntry failure )
91 {
92 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
93 if ( testMethod != null )
94 {
95 testMethod.testFailure( failure );
96 testMethod.detachFromCurrentThread();
97 }
98 }
99
100 @Override
101 public void testError( ReportEntry failure )
102 {
103 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
104 if ( testMethod != null )
105 {
106 testMethod.testError( failure );
107 testMethod.detachFromCurrentThread();
108 }
109 }
110
111 @Override
112 public void testSkipped( ReportEntry description )
113 {
114 TestSet testSet = getTestSet( description );
115 TestMethod testMethod = testSet.createThreadAttachedTestMethod( description );
116 testMethod.testIgnored( description );
117 testSet.incrementFinishedTests( getRunListener(), reportImmediately );
118 testMethod.detachFromCurrentThread();
119 }
120
121 @Override
122 public void testExecutionSkippedByUser()
123 {
124
125 reporterManagerThreadLocal.get().testExecutionSkippedByUser();
126 }
127
128 @Override
129 public void testAssumptionFailure( ReportEntry failure )
130 {
131 final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure );
132 if ( testMethod != null )
133 {
134 testMethod.testAssumption( failure );
135 testMethod.detachFromCurrentThread();
136 }
137 }
138
139 @Override
140 public void testStarting( ReportEntry description )
141 {
142 TestSet testSet = getTestSet( description );
143 testSet.createThreadAttachedTestMethod( description );
144
145 checkIfTestSetCanBeReported( testSet );
146 testSet.attachToThread();
147 }
148
149 @Override
150 public void testSucceeded( ReportEntry report )
151 {
152 TestMethod testMethod = getThreadTestMethod();
153 if ( testMethod != null )
154 {
155 testMethod.testFinished();
156 testMethod.getTestSet().incrementFinishedTests( getRunListener(), reportImmediately );
157 testMethod.detachFromCurrentThread();
158 }
159 }
160
161 private TestMethod getOrCreateThreadAttachedTestMethod( ReportEntry description )
162 {
163 TestMethod threadTestMethod = getThreadTestMethod();
164 if ( threadTestMethod != null )
165 {
166 return threadTestMethod;
167 }
168 TestSet testSet = getTestSet( description );
169 if ( testSet == null )
170 {
171 consoleStream.println( description.getName() );
172 StackTraceWriter writer = description.getStackTraceWriter();
173 if ( writer != null )
174 {
175 consoleStream.println( writer.writeTraceToString() );
176 }
177 return null;
178 }
179 else
180 {
181 return testSet.createThreadAttachedTestMethod( description );
182 }
183 }
184
185 protected abstract void checkIfTestSetCanBeReported( TestSet testSetForTest );
186
187 private TestSet getTestSet( ReportEntry description )
188 {
189 return classMethodCounts.get( description.getSourceName() );
190 }
191
192 RunListener getRunListener()
193 {
194 return reporterManagerThreadLocal.get();
195 }
196
197 public static ConcurrentRunListener createInstance( Map<String, TestSet> classMethodCounts,
198 ReporterFactory reporterFactory,
199 boolean parallelClasses, boolean parallelBoth,
200 ConsoleStream consoleStream )
201 throws TestSetFailedException
202 {
203 return parallelClasses
204 ? new ClassesParallelRunListener( classMethodCounts, reporterFactory, consoleStream )
205 : new MethodsParallelRunListener( classMethodCounts, reporterFactory, !parallelBoth, consoleStream );
206 }
207
208
209 @Override
210 public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
211 {
212 TestMethod threadTestMethod = getThreadTestMethod();
213 if ( threadTestMethod != null )
214 {
215 LogicalStream logicalStream = threadTestMethod.getLogicalStream();
216 logicalStream.write( stdout, buf, off, len );
217 }
218 else
219 {
220
221 consoleStream.println( buf, off, len );
222 }
223 }
224 }