1 package org.apache.maven.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.concurrent.LinkedBlockingQueue;
23 import org.apache.maven.surefire.util.internal.ByteBuffer;
24
25
26
27
28
29
30
31 public class AsynchRunListener
32 implements RunListener, ConsoleOutputReceiver, ConsoleLogger
33 {
34 private final LinkedBlockingQueue blockingQueue = new LinkedBlockingQueue();
35
36 private final Processor processor;
37
38 private final RunListener target;
39
40 private final ConsoleOutputReceiver consoleOutputReceiver;
41
42 private final Thread asynchRunListener;
43
44 static class Processor
45 implements Runnable
46 {
47 private final LinkedBlockingQueue blockingQueue;
48
49 private volatile InterruptedException exception;
50
51 Processor( LinkedBlockingQueue blockingQueue )
52 {
53 this.blockingQueue = blockingQueue;
54 }
55
56 public void run()
57 {
58 try
59 {
60 Runnable take;
61 take = (Runnable) blockingQueue.take();
62 while ( take != poison )
63 {
64 take.run();
65 take = (Runnable) blockingQueue.take();
66 }
67 }
68 catch ( InterruptedException e )
69 {
70 this.exception = e;
71 }
72 }
73
74 public InterruptedException getException()
75 {
76 return exception;
77 }
78 }
79
80 public AsynchRunListener( RunListener target, String role )
81 {
82 this.processor = new Processor( blockingQueue );
83 this.target = target;
84 consoleOutputReceiver = (ConsoleOutputReceiver) target;
85 asynchRunListener = new Thread( processor, "AsynchRunListener" + role );
86 asynchRunListener.start();
87 }
88
89 public void testSetStarting( final ReportEntry report )
90 {
91 blockingQueue.add( new Runnable()
92 {
93 public void run()
94 {
95 target.testSetStarting( report );
96 }
97 } );
98 }
99
100 public void testSetCompleted( final ReportEntry report )
101 {
102 blockingQueue.add( new Runnable()
103 {
104 public void run()
105 {
106 target.testSetCompleted( report );
107 }
108 } );
109 }
110
111 public void testStarting( final ReportEntry report )
112 {
113 blockingQueue.add( new Runnable()
114 {
115 public void run()
116 {
117 target.testStarting( report );
118 }
119 } );
120 }
121
122 public void testSucceeded( final ReportEntry report )
123 {
124 blockingQueue.add( new Runnable()
125 {
126 public void run()
127 {
128 target.testSucceeded( report );
129 }
130 } );
131 }
132
133 public void testAssumptionFailure( final ReportEntry report )
134 {
135 blockingQueue.add( new Runnable()
136 {
137 public void run()
138 {
139 target.testAssumptionFailure( report );
140 }
141 } );
142
143 }
144
145 public void testError( final ReportEntry report )
146 {
147 blockingQueue.add( new Runnable()
148 {
149 public void run()
150 {
151 target.testError( report );
152 }
153 } );
154 }
155
156 public void testFailed( final ReportEntry report )
157 {
158 blockingQueue.add( new Runnable()
159 {
160 public void run()
161 {
162 target.testFailed( report );
163 }
164 } );
165 }
166
167 public void testSkipped( final ReportEntry report )
168 {
169 blockingQueue.add( new Runnable()
170 {
171 public void run()
172 {
173 target.testSkipped( report );
174 }
175 } );
176 }
177
178 static class JoinableTestOutput
179 implements Runnable
180 {
181 final byte[] buf;
182
183 final int off;
184
185 final int len;
186
187 final boolean stdout;
188
189 private final ConsoleOutputReceiver consoleOutputReceiver;
190
191 JoinableTestOutput( final byte[] buf, final int off, final int len, final boolean stdout,
192 ConsoleOutputReceiver consoleOutputReceiver )
193 {
194 this.buf = ByteBuffer.copy( buf, off, len );
195 this.off = 0;
196 this.len = len;
197 this.stdout = stdout;
198 this.consoleOutputReceiver = consoleOutputReceiver;
199 }
200
201 public void run()
202 {
203 consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
204 }
205
206 public JoinableTestOutput append( JoinableTestOutput other )
207 {
208 byte[] combined = ByteBuffer.join( buf, this.off, this.len, other.buf, other.off, other.len );
209 return new JoinableTestOutput( combined, 0, combined.length, stdout, consoleOutputReceiver );
210 }
211
212 }
213
214 public void writeTestOutput( final byte[] buf, final int off, final int len, final boolean stdout )
215 {
216 blockingQueue.add( new JoinableTestOutput( buf, off, len, stdout, consoleOutputReceiver ) );
217 }
218
219 public void info( final String message )
220 {
221 blockingQueue.add( new Runnable()
222 {
223 public void run()
224 {
225 ( (ConsoleLogger) consoleOutputReceiver ).info( message );
226 }
227 } );
228 }
229
230 private static final Runnable poison = new Runnable()
231 {
232 public void run()
233 {
234 }
235 };
236
237 public void close()
238 throws ReporterException
239 {
240 try
241 {
242 blockingQueue.add( poison );
243 asynchRunListener.join();
244 final InterruptedException exception = processor.getException();
245 if ( exception != null )
246 {
247 throw exception;
248 }
249 }
250 catch ( InterruptedException e )
251 {
252 throw new ReporterException( "When waiting", e );
253 }
254
255 }
256 }