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