1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.surefire.extensions;
20
21 import javax.annotation.Nonnull;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.Closeable;
26 import java.io.File;
27 import java.io.LineNumberReader;
28 import java.io.PrintStream;
29 import java.io.StringReader;
30 import java.nio.channels.ReadableByteChannel;
31 import java.nio.charset.Charset;
32 import java.util.Map;
33 import java.util.concurrent.BlockingQueue;
34 import java.util.concurrent.ConcurrentLinkedQueue;
35 import java.util.concurrent.LinkedTransferQueue;
36 import java.util.concurrent.TimeUnit;
37 import java.util.concurrent.atomic.AtomicBoolean;
38 import java.util.concurrent.atomic.AtomicInteger;
39
40 import org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
41 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessEventListener;
42 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessEventNotifier;
43 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessExitErrorListener;
44 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessPropertyEventListener;
45 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessReportEventListener;
46 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStackTraceEventListener;
47 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStandardOutErrEventListener;
48 import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStringEventListener;
49 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
50 import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerUtils;
51 import org.apache.maven.surefire.api.event.Event;
52 import org.apache.maven.surefire.api.fork.ForkNodeArguments;
53 import org.apache.maven.surefire.api.report.ReportEntry;
54 import org.apache.maven.surefire.api.report.RunMode;
55 import org.apache.maven.surefire.api.report.SafeThrowable;
56 import org.apache.maven.surefire.api.report.StackTraceWriter;
57 import org.apache.maven.surefire.api.report.TestOutputReportEntry;
58 import org.apache.maven.surefire.api.report.TestSetReportEntry;
59 import org.apache.maven.surefire.api.util.internal.WritableBufferedByteChannel;
60 import org.apache.maven.surefire.booter.spi.EventChannelEncoder;
61 import org.apache.maven.surefire.extensions.EventHandler;
62 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
63 import org.junit.Rule;
64 import org.junit.Test;
65 import org.junit.experimental.runners.Enclosed;
66 import org.junit.experimental.theories.DataPoints;
67 import org.junit.experimental.theories.FromDataPoints;
68 import org.junit.experimental.theories.Theories;
69 import org.junit.experimental.theories.Theory;
70 import org.junit.rules.ExpectedException;
71 import org.junit.runner.RunWith;
72 import org.powermock.core.classloader.annotations.PowerMockIgnore;
73 import org.powermock.modules.junit4.PowerMockRunner;
74
75 import static java.lang.String.format;
76 import static java.nio.charset.StandardCharsets.UTF_8;
77 import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
78 import static org.apache.maven.surefire.api.report.TestOutputReportEntry.stdErr;
79 import static org.apache.maven.surefire.api.report.TestOutputReportEntry.stdOut;
80 import static org.apache.maven.surefire.api.report.TestOutputReportEntry.stdOutln;
81 import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedChannel;
82 import static org.apache.maven.surefire.api.util.internal.Channels.newChannel;
83 import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;
84 import static org.assertj.core.api.Assertions.assertThat;
85 import static org.junit.Assert.assertTrue;
86 import static org.junit.rules.ExpectedException.none;
87 import static org.powermock.api.mockito.PowerMockito.mock;
88 import static org.powermock.api.mockito.PowerMockito.when;
89
90
91
92
93
94
95
96 @RunWith(Enclosed.class)
97 public class ForkedProcessEventNotifierTest {
98
99
100
101 @RunWith(PowerMockRunner.class)
102 @PowerMockIgnore({"org.jacoco.agent.rt.*", "com.vladium.emma.rt.*"})
103 public static class DecoderOperationsTest {
104 @Rule
105 public final ExpectedException rule = none();
106
107 @Test
108 public void shouldSendByeEvent() throws Exception {
109 Stream out = Stream.newStream();
110 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
111 encoder.bye();
112 String read = new String(out.toByteArray(), UTF_8);
113
114 assertThat(read).isEqualTo(":maven-surefire-event:\u0003:bye:");
115
116 LineNumberReader lines = out.newReader(UTF_8);
117
118 final String cmd = lines.readLine();
119 assertThat(cmd).isNotNull();
120
121 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
122
123 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
124 EventAssertionListener listener = new EventAssertionListener();
125 notifier.setByeListener(listener);
126
127 EH eventHandler = new EH();
128 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
129 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
130 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
131 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
132 t.start();
133 notifier.notifyEvent(eventHandler.pullEvent());
134 }
135
136 assertThat(logger.error).isEmpty();
137 assertThat(logger.warning).isEmpty();
138 assertThat(logger.info).isEmpty();
139 assertThat(logger.debug).isEmpty();
140
141 assertThat(logger.isCalled()).isFalse();
142 assertThat(arguments.isCalled()).isFalse();
143 assertThat(listener.called.get()).isTrue();
144 }
145
146 @Test
147 public void shouldSendStopOnNextTestEvent() throws Exception {
148 Stream out = Stream.newStream();
149 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
150 encoder.stopOnNextTest();
151 String read = new String(out.toByteArray(), UTF_8);
152
153 assertThat(read).isEqualTo(":maven-surefire-event:\u0011:stop-on-next-test:");
154
155 LineNumberReader lines = out.newReader(UTF_8);
156
157 final String cmd = lines.readLine();
158 assertThat(cmd).isNotNull();
159
160 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
161
162 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
163 EventAssertionListener listener = new EventAssertionListener();
164 notifier.setStopOnNextTestListener(listener);
165
166 EH eventHandler = new EH();
167 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
168 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
169 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
170 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
171 t.start();
172 notifier.notifyEvent(eventHandler.pullEvent());
173 }
174
175 assertThat(logger.error).isEmpty();
176 assertThat(logger.warning).isEmpty();
177 assertThat(logger.info).isEmpty();
178 assertThat(logger.debug).isEmpty();
179
180 assertThat(logger.isCalled()).isFalse();
181 assertThat(arguments.dumpStreamText).isEmpty();
182 assertThat(arguments.isCalled()).isFalse();
183 assertThat(listener.called.get()).isTrue();
184 }
185
186 @Test
187 public void shouldCorrectlyDecodeStackTracesWithEmptyStringTraceMessages() throws Exception {
188 String exceptionMessage = "";
189 String smartStackTrace = "JUnit5Test.failWithEmptyString:16";
190 String exceptionStackTrace = "org.opentest4j.AssertionFailedError: \n"
191 + "\tat JUnit5Test.failWithEmptyString(JUnit5Test.java:16)\n";
192
193 StackTraceWriter stackTraceWriter = mock(StackTraceWriter.class);
194 SafeThrowable safeThrowable = new SafeThrowable(exceptionMessage);
195 when(stackTraceWriter.getThrowable()).thenReturn(safeThrowable);
196 when(stackTraceWriter.smartTrimmedStackTrace()).thenReturn(smartStackTrace);
197 when(stackTraceWriter.writeTrimmedTraceToString()).thenReturn(exceptionStackTrace);
198 when(stackTraceWriter.writeTraceToString()).thenReturn(exceptionStackTrace);
199
200 ReportEntry reportEntry = mock(ReportEntry.class);
201 when(reportEntry.getRunMode()).thenReturn(NORMAL_RUN);
202 when(reportEntry.getTestRunId()).thenReturn(1L);
203 when(reportEntry.getElapsed()).thenReturn(7);
204 when(reportEntry.getGroup()).thenReturn(null);
205 when(reportEntry.getMessage()).thenReturn(null);
206 when(reportEntry.getName()).thenReturn("failWithEmptyString");
207 when(reportEntry.getNameWithGroup()).thenReturn("JUnit5Test");
208 when(reportEntry.getSourceName()).thenReturn("JUnit5Test");
209 when(reportEntry.getSourceText()).thenReturn(null);
210 when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter);
211
212 final Stream out = Stream.newStream();
213 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
214 encoder.testFailed(reportEntry, true);
215
216 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
217
218 final ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
219 ReportEventAssertionListener listener = new ReportEventAssertionListener(reportEntry, true);
220 notifier.setTestFailedListener(listener);
221
222 EH eventHandler = new EH();
223 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
224 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
225 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
226 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
227 t.start();
228 notifier.notifyEvent(eventHandler.pullEvent());
229 }
230
231 assertThat(logger.error).isEmpty();
232 assertThat(logger.warning).isEmpty();
233 assertThat(logger.info).isEmpty();
234 assertThat(logger.debug).isEmpty();
235
236 assertThat(logger.isCalled()).isFalse();
237 assertThat(arguments.isCalled()).isFalse();
238 assertThat(listener.called.get()).isTrue();
239 }
240
241 @Test
242 public void shouldSendNextTestEvent() throws Exception {
243 final Stream out = Stream.newStream();
244 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
245 encoder.acquireNextTest();
246 String read = new String(out.toByteArray(), UTF_8);
247
248 assertThat(read).isEqualTo(":maven-surefire-event:\u0009:next-test:");
249
250 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
251
252 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
253 EventAssertionListener listener = new EventAssertionListener();
254 notifier.setAcquireNextTestListener(listener);
255
256 EH eventHandler = new EH();
257 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
258 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
259 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
260 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
261 t.start();
262 notifier.notifyEvent(eventHandler.pullEvent());
263 }
264
265 assertThat(logger.error).isEmpty();
266 assertThat(logger.warning).isEmpty();
267 assertThat(logger.info).isEmpty();
268 assertThat(logger.debug).isEmpty();
269
270 assertThat(logger.isCalled()).isFalse();
271 assertThat(arguments.isCalled()).isFalse();
272 assertThat(listener.called.get()).isTrue();
273 }
274
275 @Test
276 public void testConsole() throws Exception {
277 final Stream out = Stream.newStream();
278 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
279 encoder.consoleInfoLog("msg");
280
281 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
282
283 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
284 StringEventAssertionListener listener = new StringEventAssertionListener("msg");
285 notifier.setConsoleInfoListener(listener);
286
287 EH eventHandler = new EH();
288 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
289 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
290 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
291 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
292 t.start();
293 notifier.notifyEvent(eventHandler.pullEvent());
294 }
295
296 assertThat(logger.error).isEmpty();
297 assertThat(logger.warning).isEmpty();
298 assertThat(logger.info).isEmpty();
299 assertThat(logger.debug).isEmpty();
300
301 assertThat(logger.isCalled()).isFalse();
302 assertThat(arguments.isCalled()).isFalse();
303 assertThat(listener.called.get()).isTrue();
304 }
305
306 @Test
307 public void testError() throws Exception {
308 final Stream out = Stream.newStream();
309 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
310 encoder.consoleErrorLog("msg");
311
312 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
313
314 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
315 StackTraceEventListener listener = new StackTraceEventListener("msg", null, null);
316 notifier.setConsoleErrorListener(listener);
317
318 EH eventHandler = new EH();
319 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
320 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
321 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
322 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
323 t.start();
324 notifier.notifyEvent(eventHandler.pullEvent());
325 }
326
327 assertThat(logger.error).isEmpty();
328 assertThat(logger.warning).isEmpty();
329 assertThat(logger.info).isEmpty();
330 assertThat(logger.debug).isEmpty();
331
332 assertThat(logger.isCalled()).isFalse();
333 assertThat(arguments.isCalled()).isFalse();
334 assertThat(listener.called.get()).isTrue();
335 }
336
337 @Test
338 public void testErrorWithException() throws Exception {
339 final Stream out = Stream.newStream();
340 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
341 Throwable throwable = new Throwable("msg");
342 encoder.consoleErrorLog(throwable);
343
344 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
345
346 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
347 String stackTrace = ConsoleLoggerUtils.toString(throwable);
348 StackTraceEventListener listener = new StackTraceEventListener("msg", null, stackTrace);
349 notifier.setConsoleErrorListener(listener);
350
351 EH eventHandler = new EH();
352 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 1);
353 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
354 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
355 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
356 t.start();
357 notifier.notifyEvent(eventHandler.pullEvent());
358 }
359
360 assertThat(logger.error).isEmpty();
361 assertThat(logger.warning).isEmpty();
362 assertThat(logger.info).isEmpty();
363 assertThat(logger.debug).isEmpty();
364
365 assertThat(logger.isCalled()).isFalse();
366 assertThat(arguments.isCalled()).isFalse();
367 assertThat(listener.called.get()).isTrue();
368 }
369
370 @Test
371 public void testErrorWithStackTraceWriter() throws Exception {
372 final Stream out = Stream.newStream();
373
374 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
375 StackTraceWriter stackTraceWriter = new DeserializedStacktraceWriter("1", "2", "3");
376 encoder.consoleErrorLog(stackTraceWriter, false);
377
378 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
379
380 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
381 StackTraceEventListener listener = new StackTraceEventListener("1", "2", "3");
382 notifier.setConsoleErrorListener(listener);
383
384 EH eventHandler = new EH();
385 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
386 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
387 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
388 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
389 t.start();
390 notifier.notifyEvent(eventHandler.pullEvent());
391 }
392
393 assertThat(logger.error).isEmpty();
394 assertThat(logger.warning).isEmpty();
395 assertThat(logger.info).isEmpty();
396 assertThat(logger.debug).isEmpty();
397
398 assertThat(logger.isCalled()).isFalse();
399 assertThat(arguments.isCalled()).isFalse();
400 assertThat(listener.called.get()).isTrue();
401 }
402
403 @Test
404 public void testDebug() throws Exception {
405 final Stream out = Stream.newStream();
406
407 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
408 encoder.consoleDebugLog("msg");
409
410 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
411
412 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
413 StringEventAssertionListener listener = new StringEventAssertionListener("msg");
414 notifier.setConsoleDebugListener(listener);
415
416 EH eventHandler = new EH();
417 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
418 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
419 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
420 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
421 t.start();
422 notifier.notifyEvent(eventHandler.pullEvent());
423 }
424
425 assertThat(logger.error).isEmpty();
426 assertThat(logger.warning).isEmpty();
427 assertThat(logger.info).isEmpty();
428 assertThat(logger.debug).isEmpty();
429
430 assertThat(logger.isCalled()).isFalse();
431
432 assertThat(arguments.isCalled()).isFalse();
433
434 assertThat(listener.called.get()).isTrue();
435
436 assertThat(listener.msg).isEqualTo("msg");
437 }
438
439 @Test
440 public void testWarning() throws Exception {
441 final Stream out = Stream.newStream();
442
443 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
444 encoder.consoleWarningLog("msg");
445
446 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
447
448 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
449 StringEventAssertionListener listener = new StringEventAssertionListener("msg");
450 notifier.setConsoleWarningListener(listener);
451
452 EH eventHandler = new EH();
453 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
454 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
455 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
456 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
457 t.start();
458 notifier.notifyEvent(eventHandler.pullEvent());
459 }
460
461 assertThat(logger.error).isEmpty();
462 assertThat(logger.warning).isEmpty();
463 assertThat(logger.info).isEmpty();
464 assertThat(logger.debug).isEmpty();
465
466 assertThat(logger.isCalled()).isFalse();
467 assertThat(arguments.isCalled()).isFalse();
468 assertThat(listener.called.get()).isTrue();
469 }
470
471 @Test
472 public void testStdOutStream() throws Exception {
473 final Stream out = Stream.newStream();
474 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
475 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
476 encoder.testOutput(new TestOutputReportEntry(stdOut("msg"), NORMAL_RUN, 1L));
477 wChannel.close();
478
479 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
480
481 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
482 StandardOutErrEventAssertionListener listener =
483 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, "msg", false);
484 notifier.setStdOutListener(listener);
485
486 EH eventHandler = new EH();
487 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
488 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
489 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
490 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
491 t.start();
492 notifier.notifyEvent(eventHandler.pullEvent());
493 }
494
495 assertThat(logger.error).isEmpty();
496 assertThat(logger.warning).isEmpty();
497 assertThat(logger.info).isEmpty();
498 assertThat(logger.debug).isEmpty();
499
500 assertThat(logger.isCalled()).isFalse();
501 assertThat(arguments.isCalled()).isFalse();
502 assertThat(listener.called.get()).isTrue();
503 }
504
505 @Test
506 public void testStdOutStreamPrint() throws Exception {
507 final Stream out = Stream.newStream();
508 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
509 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
510 encoder.testOutput(new TestOutputReportEntry(stdOut(""), NORMAL_RUN, 1L));
511 wChannel.close();
512
513 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
514
515 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
516 StandardOutErrEventAssertionListener listener =
517 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, "", false);
518 notifier.setStdOutListener(listener);
519
520 EH eventHandler = new EH();
521 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
522 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
523 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
524 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
525 t.start();
526 notifier.notifyEvent(eventHandler.pullEvent());
527 }
528
529 assertThat(logger.error).isEmpty();
530 assertThat(logger.warning).isEmpty();
531 assertThat(logger.info).isEmpty();
532 assertThat(logger.debug).isEmpty();
533
534 assertThat(logger.isCalled()).isFalse();
535 assertThat(arguments.isCalled()).isFalse();
536 assertThat(listener.called.get()).isTrue();
537 }
538
539 @Test
540 public void testStdOutStreamPrintWithNull() throws Exception {
541 final Stream out = Stream.newStream();
542 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
543 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
544 encoder.testOutput(new TestOutputReportEntry(stdOut(null), NORMAL_RUN, 1L));
545 wChannel.close();
546
547 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
548
549 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
550 StandardOutErrEventAssertionListener listener =
551 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, null, false);
552 notifier.setStdOutListener(listener);
553
554 EH eventHandler = new EH();
555 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
556 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
557 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
558 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
559 t.start();
560 notifier.notifyEvent(eventHandler.pullEvent());
561 }
562
563 assertThat(logger.error).isEmpty();
564 assertThat(logger.warning).isEmpty();
565 assertThat(logger.info).isEmpty();
566 assertThat(logger.debug).isEmpty();
567
568 assertThat(logger.isCalled()).isFalse();
569 assertThat(arguments.isCalled()).isFalse();
570 assertThat(listener.called.get()).isTrue();
571 }
572
573 @Test
574 public void testStdOutStreamPrintln() throws Exception {
575 final Stream out = Stream.newStream();
576 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
577 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
578 encoder.testOutput(new TestOutputReportEntry(stdOutln(""), NORMAL_RUN, 1L));
579 wChannel.close();
580
581 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
582
583 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
584 StandardOutErrEventAssertionListener listener =
585 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, "", true);
586 notifier.setStdOutListener(listener);
587
588 EH eventHandler = new EH();
589 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
590 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
591 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
592 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
593 t.start();
594 notifier.notifyEvent(eventHandler.pullEvent());
595 }
596
597 assertThat(logger.error).isEmpty();
598 assertThat(logger.warning).isEmpty();
599 assertThat(logger.info).isEmpty();
600 assertThat(logger.debug).isEmpty();
601
602 assertThat(logger.isCalled()).isFalse();
603 assertThat(arguments.isCalled()).isFalse();
604 assertThat(listener.called.get()).isTrue();
605 }
606
607 @Test
608 public void testStdOutStreamPrintlnWithNull() throws Exception {
609 final Stream out = Stream.newStream();
610 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
611 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
612 encoder.testOutput(new TestOutputReportEntry(stdOutln(null), NORMAL_RUN, 1L));
613 wChannel.close();
614
615 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
616
617 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
618 StandardOutErrEventAssertionListener listener =
619 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, null, true);
620 notifier.setStdOutListener(listener);
621
622 EH eventHandler = new EH();
623 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
624 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
625 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
626 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
627 t.start();
628 notifier.notifyEvent(eventHandler.pullEvent());
629 }
630
631 assertThat(logger.error).isEmpty();
632 assertThat(logger.warning).isEmpty();
633 assertThat(logger.info).isEmpty();
634 assertThat(logger.debug).isEmpty();
635
636 assertThat(logger.isCalled()).isFalse();
637 assertThat(arguments.isCalled()).isFalse();
638 assertThat(listener.called.get()).isTrue();
639 }
640
641 @Test
642 public void testStdErrStream() throws Exception {
643 final Stream out = Stream.newStream();
644 WritableBufferedByteChannel wChannel = newBufferedChannel(out);
645 EventChannelEncoder encoder = new EventChannelEncoder(wChannel);
646 encoder.testOutput(new TestOutputReportEntry(stdErr("msg"), NORMAL_RUN, 1L));
647 wChannel.close();
648
649 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
650
651 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
652 StandardOutErrEventAssertionListener listener =
653 new StandardOutErrEventAssertionListener(NORMAL_RUN, 1L, "msg", false);
654 notifier.setStdErrListener(listener);
655
656 EH eventHandler = new EH();
657 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
658 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
659 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
660 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
661 t.start();
662 notifier.notifyEvent(eventHandler.pullEvent());
663 }
664
665 assertThat(logger.error).isEmpty();
666 assertThat(logger.warning).isEmpty();
667 assertThat(logger.info).isEmpty();
668 assertThat(logger.debug).isEmpty();
669
670 assertThat(logger.isCalled()).isFalse();
671 assertThat(arguments.isCalled()).isFalse();
672 assertThat(listener.called.get()).isTrue();
673 }
674
675 @Test
676 public void shouldHandleErrorAfterNullLine() {
677 ForkedProcessEventNotifier decoder = new ForkedProcessEventNotifier();
678 decoder.setSystemPropertiesListener(new PropertyEventAssertionListener());
679 rule.expect(NullPointerException.class);
680 decoder.notifyEvent(null);
681 }
682
683 @Test
684 public void shouldHandleErrorAfterUnknownOperation() throws Exception {
685 String cmd = ":maven-surefire-event:\u000c:abnormal-run:-:\n";
686
687 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(cmd.getBytes()));
688
689 EH eventHandler = new EH();
690 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 1);
691 ConsoleLoggerMock logger = new ConsoleLoggerMock(true, true, true, true);
692 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
693 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
694 t.start();
695 countdown.awaitClosed();
696 }
697
698 assertThat(arguments.isCalled()).isTrue();
699
700 assertThat(logger.isCalled()).isTrue();
701
702 assertThat(logger.debug).hasSize(1);
703
704 assertThat(logger.debug.peek()).contains(":maven-surefire-event:\u000c:abnormal-run:-:");
705
706 String dump = "Corrupted channel by directly writing to native stream in forked JVM 0.";
707 assertThat(arguments.dumpStreamText)
708 .hasSize(1)
709 .contains(format(dump + " Stream '%s'.", ":maven-surefire-event:\u000c:abnormal-run:-:"));
710
711 dump += " See FAQ web page and the dump file ";
712 assertThat(arguments.logWarningAtEnd).hasSize(1);
713 assertThat(arguments.logWarningAtEnd.peek()).startsWith(dump);
714 }
715
716 @Test
717 public void shouldHandleExit() throws Exception {
718 final Stream out = Stream.newStream();
719 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
720
721 StackTraceWriter stackTraceWriter = mock(StackTraceWriter.class);
722 when(stackTraceWriter.getThrowable()).thenReturn(new SafeThrowable("1"));
723 when(stackTraceWriter.smartTrimmedStackTrace()).thenReturn("2");
724 when(stackTraceWriter.writeTraceToString()).thenReturn("3");
725 when(stackTraceWriter.writeTrimmedTraceToString()).thenReturn("4");
726 encoder.sendExitError(stackTraceWriter, false);
727
728 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
729
730 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
731 ProcessExitErrorListener listener = new ProcessExitErrorListener();
732 notifier.setExitErrorEventListener(listener);
733
734 EH eventHandler = new EH();
735 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
736 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
737 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
738 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
739 t.start();
740 notifier.notifyEvent(eventHandler.pullEvent());
741 }
742
743 assertThat(logger.error).isEmpty();
744 assertThat(logger.warning).isEmpty();
745 assertThat(logger.info).isEmpty();
746 assertThat(logger.debug).isEmpty();
747
748 assertThat(logger.isCalled()).isFalse();
749 assertThat(arguments.isCalled()).isFalse();
750 assertThat(listener.called.get()).isTrue();
751 }
752 }
753
754
755
756
757 @RunWith(Theories.class)
758 public static class ReportEntryTest {
759 @DataPoints(value = "operation")
760 @SuppressWarnings("checkstyle:visibilitymodifier")
761 public static String[][] operations = {
762 {"testSetStarting", "setTestSetStartingListener"},
763 {"testSetCompleted", "setTestSetCompletedListener"},
764 {"testStarting", "setTestStartingListener"},
765 {"testSucceeded", "setTestSucceededListener"},
766 {"testFailed", "setTestFailedListener"},
767 {"testSkipped", "setTestSkippedListener"},
768 {"testError", "setTestErrorListener"},
769 {"testAssumptionFailure", "setTestAssumptionFailureListener"}
770 };
771
772 @DataPoints(value = "reportedMessage")
773 @SuppressWarnings("checkstyle:visibilitymodifier")
774 public static String[] reportedMessage = {null, "skipped test"};
775
776 @DataPoints(value = "elapsed")
777 @SuppressWarnings({"checkstyle:visibilitymodifier", "checkstyle:magicnumber"})
778 public static Integer[] elapsed = {null, 102};
779
780 @DataPoints(value = "trim")
781 @SuppressWarnings("checkstyle:visibilitymodifier")
782 public static boolean[] trim = {false, true};
783
784 @DataPoints(value = "msg")
785 @SuppressWarnings("checkstyle:visibilitymodifier")
786 public static boolean[] msg = {false, true};
787
788 @DataPoints(value = "smart")
789 @SuppressWarnings("checkstyle:visibilitymodifier")
790 public static boolean[] smart = {false, true};
791
792 @DataPoints(value = "trace")
793 @SuppressWarnings("checkstyle:visibilitymodifier")
794 public static boolean[] trace = {false, true};
795
796 @Theory
797 public void testReportEntryOperations(
798 @FromDataPoints("operation") String[] operation,
799 @FromDataPoints("reportedMessage") String reportedMessage,
800 @FromDataPoints("elapsed") Integer elapsed,
801 @FromDataPoints("trim") boolean trim,
802 @FromDataPoints("msg") boolean msg,
803 @FromDataPoints("smart") boolean smart,
804 @FromDataPoints("trace") boolean trace)
805 throws Exception {
806 String exceptionMessage = msg ? "msg" : null;
807 String smartStackTrace = smart ? "MyTest:86 >> Error" : null;
808 String exceptionStackTrace =
809 trace ? (trim ? "trace line 1\ntrace line 2" : "Exception: msg\ntrace line 1\ntrace line 2") : null;
810
811 StackTraceWriter stackTraceWriter = null;
812 if (exceptionStackTrace != null) {
813 SafeThrowable safeThrowable = new SafeThrowable(exceptionMessage);
814 stackTraceWriter = mock(StackTraceWriter.class);
815 when(stackTraceWriter.getThrowable()).thenReturn(safeThrowable);
816 when(stackTraceWriter.smartTrimmedStackTrace()).thenReturn(smartStackTrace);
817 when(stackTraceWriter.writeTrimmedTraceToString()).thenReturn(exceptionStackTrace);
818 when(stackTraceWriter.writeTraceToString()).thenReturn(exceptionStackTrace);
819 }
820
821 TestSetReportEntry reportEntry = mock(TestSetReportEntry.class);
822 when(reportEntry.getRunMode()).thenReturn(NORMAL_RUN);
823 when(reportEntry.getTestRunId()).thenReturn(1L);
824 when(reportEntry.getElapsed()).thenReturn(elapsed);
825 when(reportEntry.getGroup()).thenReturn("this group");
826 when(reportEntry.getMessage()).thenReturn(reportedMessage);
827 when(reportEntry.getName()).thenReturn("my test");
828 when(reportEntry.getName()).thenReturn("display name of test");
829 when(reportEntry.getNameWithGroup()).thenReturn("name with group");
830 when(reportEntry.getSourceName()).thenReturn("pkg.MyTest");
831 when(reportEntry.getSourceText()).thenReturn("test class display name");
832 when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter);
833 when(reportEntry.getSystemProperties()).thenReturn(systemProps());
834
835 final Stream out = Stream.newStream();
836
837 EventChannelEncoder encoder = new EventChannelEncoder(newBufferedChannel(out));
838
839 Class<?> reportType = operation[0].startsWith("testSet") ? TestSetReportEntry.class : ReportEntry.class;
840 EventChannelEncoder.class
841 .getMethod(operation[0], reportType, boolean.class)
842 .invoke(encoder, reportEntry, trim);
843
844 ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
845
846 ForkedProcessEventNotifier.class
847 .getMethod(operation[1], ForkedProcessReportEventListener.class)
848 .invoke(notifier, new ReportEventAssertionListener(reportEntry, stackTraceWriter != null));
849
850 ReadableByteChannel channel = newChannel(new ByteArrayInputStream(out.toByteArray()));
851
852 EH eventHandler = new EH();
853 CountdownCloseable countdown = new CountdownCloseable(mock(Closeable.class), 0);
854 ConsoleLoggerMock logger = new ConsoleLoggerMock(false, false, false, false);
855 ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock(logger, new File(""));
856 try (EventConsumerThread t = new EventConsumerThread("t", channel, eventHandler, countdown, arguments)) {
857 t.start();
858 notifier.notifyEvent(eventHandler.pullEvent());
859 }
860
861 assertThat(logger.error).isEmpty();
862 assertThat(logger.warning).isEmpty();
863 assertThat(logger.info).isEmpty();
864 assertThat(logger.debug).isEmpty();
865
866 assertThat(logger.isCalled()).isFalse();
867
868 assertThat(arguments.isCalled()).isFalse();
869 }
870 }
871
872 private static class ProcessExitErrorListener implements ForkedProcessExitErrorListener {
873 final AtomicBoolean called = new AtomicBoolean();
874
875 @Override
876 public void handle(StackTraceWriter stackTrace) {
877 called.set(true);
878 assertThat(stackTrace.getThrowable().getMessage()).isEqualTo("1");
879 assertThat(stackTrace.smartTrimmedStackTrace()).isEqualTo("2");
880 assertThat(stackTrace.writeTraceToString()).isEqualTo("3");
881 }
882 }
883
884 private static class PropertyEventAssertionListener implements ForkedProcessPropertyEventListener {
885 final AtomicBoolean called = new AtomicBoolean();
886 private final Map<?, ?> sysProps = System.getProperties();
887 private final AtomicInteger counter = new AtomicInteger();
888
889 public void handle(String key, String value, RunMode runMode, Long testRunId) {
890 called.set(true);
891 counter.incrementAndGet();
892 assertThat(runMode).isEqualTo(NORMAL_RUN);
893 assertThat(testRunId).isEqualTo(1L);
894 assertTrue(sysProps.containsKey(key));
895 assertThat(sysProps.get(key)).isEqualTo(value);
896 }
897 }
898
899 private static class EventAssertionListener implements ForkedProcessEventListener {
900 final AtomicBoolean called = new AtomicBoolean();
901
902 public void handle() {
903 called.set(true);
904 }
905 }
906
907 private static class StringEventAssertionListener implements ForkedProcessStringEventListener {
908 final AtomicBoolean called = new AtomicBoolean();
909 private final String msg;
910
911 StringEventAssertionListener(String msg) {
912 this.msg = msg;
913 }
914
915 public void handle(String msg) {
916 called.set(true);
917 assertThat(msg).isEqualTo(this.msg);
918 }
919 }
920
921 private static class StackTraceEventListener implements ForkedProcessStackTraceEventListener {
922 final AtomicBoolean called = new AtomicBoolean();
923 private final String msg;
924 private final String smartStackTrace;
925 private final String stackTrace;
926
927 StackTraceEventListener(String msg, String smartStackTrace, String stackTrace) {
928 this.msg = msg;
929 this.smartStackTrace = smartStackTrace;
930 this.stackTrace = stackTrace;
931 }
932
933 @Override
934 public void handle(@Nonnull StackTraceWriter stackTrace) {
935 called.set(true);
936
937 assertThat(stackTrace.getThrowable().getMessage()).isEqualTo(msg);
938
939 assertThat(stackTrace.smartTrimmedStackTrace()).isEqualTo(smartStackTrace);
940
941 assertThat(stackTrace.writeTraceToString()).isEqualTo(this.stackTrace);
942 }
943 }
944
945 private static class StandardOutErrEventAssertionListener implements ForkedProcessStandardOutErrEventListener {
946 final AtomicBoolean called = new AtomicBoolean();
947 private final RunMode runMode;
948 private final long testRunId;
949 private final String output;
950 private final boolean newLine;
951
952 StandardOutErrEventAssertionListener(RunMode runMode, long testRunId, String output, boolean newLine) {
953 this.runMode = runMode;
954 this.testRunId = testRunId;
955 this.output = output;
956 this.newLine = newLine;
957 }
958
959 public void handle(String output, boolean newLine, RunMode runMode, Long testRunId) {
960 called.set(true);
961
962 assertThat(runMode).isEqualTo(this.runMode);
963
964 assertThat(testRunId).isEqualTo(this.testRunId);
965
966 assertThat(output).isEqualTo(this.output);
967
968 assertThat(newLine).isEqualTo(this.newLine);
969 }
970 }
971
972 private static class ReportEventAssertionListener implements ForkedProcessReportEventListener<ReportEntry> {
973 final AtomicBoolean called = new AtomicBoolean();
974 private final ReportEntry reportEntry;
975 private final boolean hasStackTrace;
976
977 ReportEventAssertionListener(ReportEntry reportEntry, boolean hasStackTrace) {
978 this.reportEntry = reportEntry;
979 this.hasStackTrace = hasStackTrace;
980 }
981
982 public void handle(ReportEntry reportEntry) {
983 called.set(true);
984 assertThat(reportEntry.getSourceName()).isEqualTo(this.reportEntry.getSourceName());
985 assertThat(reportEntry.getSourceText()).isEqualTo(this.reportEntry.getSourceText());
986 assertThat(reportEntry.getName()).isEqualTo(this.reportEntry.getName());
987 assertThat(reportEntry.getNameText()).isEqualTo(this.reportEntry.getNameText());
988 assertThat(reportEntry.getGroup()).isEqualTo(this.reportEntry.getGroup());
989 assertThat(reportEntry.getMessage()).isEqualTo(this.reportEntry.getMessage());
990 assertThat(reportEntry.getElapsed()).isEqualTo(this.reportEntry.getElapsed());
991 if (reportEntry.getStackTraceWriter() == null) {
992 assertThat(hasStackTrace).isFalse();
993 assertThat(this.reportEntry.getStackTraceWriter()).isNull();
994 } else {
995 assertThat(hasStackTrace).isTrue();
996 assertThat(this.reportEntry.getStackTraceWriter()).isNotNull();
997
998 assertThat(reportEntry.getStackTraceWriter().getThrowable().getMessage())
999 .isEqualTo(this.reportEntry
1000 .getStackTraceWriter()
1001 .getThrowable()
1002 .getMessage());
1003
1004 assertThat(reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage())
1005 .isEqualTo(this.reportEntry
1006 .getStackTraceWriter()
1007 .getThrowable()
1008 .getLocalizedMessage());
1009
1010 assertThat(reportEntry.getStackTraceWriter().smartTrimmedStackTrace())
1011 .isEqualTo(this.reportEntry.getStackTraceWriter().smartTrimmedStackTrace());
1012 }
1013 }
1014 }
1015
1016 private static class Stream extends PrintStream {
1017 private final ByteArrayOutputStream out;
1018
1019 Stream(ByteArrayOutputStream out) {
1020 super(out, true);
1021 this.out = out;
1022 }
1023
1024 byte[] toByteArray() {
1025 return out.toByteArray();
1026 }
1027
1028 LineNumberReader newReader(Charset streamCharset) {
1029 return new LineNumberReader(new StringReader(new String(toByteArray(), streamCharset)));
1030 }
1031
1032 static Stream newStream() {
1033 return new Stream(new ByteArrayOutputStream());
1034 }
1035 }
1036
1037 private static class EH implements EventHandler<Event> {
1038 private final BlockingQueue<Event> cache = new LinkedTransferQueue<>();
1039
1040 Event pullEvent() throws InterruptedException {
1041 return cache.poll(1, TimeUnit.MINUTES);
1042 }
1043
1044 @Override
1045 public void handleEvent(@Nonnull Event event) {
1046 cache.add(event);
1047 }
1048 }
1049
1050
1051
1052
1053 private static class ForkNodeArgumentsMock implements ForkNodeArguments {
1054 private final ConcurrentLinkedQueue<String> dumpStreamText = new ConcurrentLinkedQueue<>();
1055 private final ConcurrentLinkedQueue<String> logWarningAtEnd = new ConcurrentLinkedQueue<>();
1056 private final ConsoleLogger logger;
1057 private final File dumpStreamTextFile;
1058
1059 ForkNodeArgumentsMock(ConsoleLogger logger, File dumpStreamTextFile) {
1060 this.logger = logger;
1061 this.dumpStreamTextFile = dumpStreamTextFile;
1062 }
1063
1064 @Nonnull
1065 @Override
1066 public String getSessionId() {
1067 throw new UnsupportedOperationException();
1068 }
1069
1070 @Override
1071 public int getForkChannelId() {
1072 return 0;
1073 }
1074
1075 @Nonnull
1076 @Override
1077 public File dumpStreamText(@Nonnull String text) {
1078 dumpStreamText.add(text);
1079 return dumpStreamTextFile;
1080 }
1081
1082 @Nonnull
1083 @Override
1084 public File dumpStreamException(@Nonnull Throwable t) {
1085 return dumpStreamTextFile;
1086 }
1087
1088 @Override
1089 public void logWarningAtEnd(@Nonnull String text) {
1090 logWarningAtEnd.add(text);
1091 }
1092
1093 @Nonnull
1094 @Override
1095 public ConsoleLogger getConsoleLogger() {
1096 return logger;
1097 }
1098
1099 @Nonnull
1100 @Override
1101 public Object getConsoleLock() {
1102 return logger;
1103 }
1104
1105 boolean isCalled() {
1106 return !dumpStreamText.isEmpty() || !logWarningAtEnd.isEmpty();
1107 }
1108
1109 @Override
1110 public File getEventStreamBinaryFile() {
1111 return null;
1112 }
1113
1114 @Override
1115 public File getCommandStreamBinaryFile() {
1116 return null;
1117 }
1118 }
1119
1120
1121
1122
1123 private static class ConsoleLoggerMock implements ConsoleLogger {
1124 final ConcurrentLinkedQueue<String> debug = new ConcurrentLinkedQueue<>();
1125 final ConcurrentLinkedQueue<String> info = new ConcurrentLinkedQueue<>();
1126 final ConcurrentLinkedQueue<String> warning = new ConcurrentLinkedQueue<>();
1127 final ConcurrentLinkedQueue<String> error = new ConcurrentLinkedQueue<>();
1128 final boolean isDebug;
1129 final boolean isInfo;
1130 final boolean isWarning;
1131 final boolean isError;
1132 private volatile boolean called;
1133 private volatile boolean isDebugEnabledCalled;
1134 private volatile boolean isInfoEnabledCalled;
1135
1136 ConsoleLoggerMock(boolean isDebug, boolean isInfo, boolean isWarning, boolean isError) {
1137 this.isDebug = isDebug;
1138 this.isInfo = isInfo;
1139 this.isWarning = isWarning;
1140 this.isError = isError;
1141 }
1142
1143 @Override
1144 public synchronized boolean isDebugEnabled() {
1145 isDebugEnabledCalled = true;
1146 called = true;
1147 return isDebug;
1148 }
1149
1150 @Override
1151 public synchronized void debug(String message) {
1152 debug.add(message);
1153 called = true;
1154 }
1155
1156 @Override
1157 public synchronized boolean isInfoEnabled() {
1158 isInfoEnabledCalled = true;
1159 called = true;
1160 return isInfo;
1161 }
1162
1163 @Override
1164 public synchronized void info(String message) {
1165 info.add(message);
1166 called = true;
1167 }
1168
1169 @Override
1170 public synchronized boolean isWarnEnabled() {
1171 called = true;
1172 return isWarning;
1173 }
1174
1175 @Override
1176 public synchronized void warning(String message) {
1177 warning.add(message);
1178 called = true;
1179 }
1180
1181 @Override
1182 public synchronized boolean isErrorEnabled() {
1183 called = true;
1184 return isError;
1185 }
1186
1187 @Override
1188 public synchronized void error(String message) {
1189 error.add(message);
1190 called = true;
1191 }
1192
1193 @Override
1194 public synchronized void error(String message, Throwable t) {
1195 called = true;
1196 }
1197
1198 @Override
1199 public synchronized void error(Throwable t) {
1200 called = true;
1201 }
1202
1203 synchronized boolean isCalled() {
1204 return called;
1205 }
1206 }
1207 }