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 @Override
960 public void handle(String output, boolean newLine, RunMode runMode, Long testRunId, String stack) {
961 called.set(true);
962
963 assertThat(runMode).isEqualTo(this.runMode);
964
965 assertThat(testRunId).isEqualTo(this.testRunId);
966
967 assertThat(output).isEqualTo(this.output);
968
969 assertThat(newLine).isEqualTo(this.newLine);
970 }
971 }
972
973 private static class ReportEventAssertionListener implements ForkedProcessReportEventListener<ReportEntry> {
974 final AtomicBoolean called = new AtomicBoolean();
975 private final ReportEntry reportEntry;
976 private final boolean hasStackTrace;
977
978 ReportEventAssertionListener(ReportEntry reportEntry, boolean hasStackTrace) {
979 this.reportEntry = reportEntry;
980 this.hasStackTrace = hasStackTrace;
981 }
982
983 public void handle(ReportEntry reportEntry) {
984 called.set(true);
985 assertThat(reportEntry.getSourceName()).isEqualTo(this.reportEntry.getSourceName());
986 assertThat(reportEntry.getSourceText()).isEqualTo(this.reportEntry.getSourceText());
987 assertThat(reportEntry.getName()).isEqualTo(this.reportEntry.getName());
988 assertThat(reportEntry.getNameText()).isEqualTo(this.reportEntry.getNameText());
989 assertThat(reportEntry.getGroup()).isEqualTo(this.reportEntry.getGroup());
990 assertThat(reportEntry.getMessage()).isEqualTo(this.reportEntry.getMessage());
991 assertThat(reportEntry.getElapsed()).isEqualTo(this.reportEntry.getElapsed());
992 if (reportEntry.getStackTraceWriter() == null) {
993 assertThat(hasStackTrace).isFalse();
994 assertThat(this.reportEntry.getStackTraceWriter()).isNull();
995 } else {
996 assertThat(hasStackTrace).isTrue();
997 assertThat(this.reportEntry.getStackTraceWriter()).isNotNull();
998
999 assertThat(reportEntry.getStackTraceWriter().getThrowable().getMessage())
1000 .isEqualTo(this.reportEntry
1001 .getStackTraceWriter()
1002 .getThrowable()
1003 .getMessage());
1004
1005 assertThat(reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage())
1006 .isEqualTo(this.reportEntry
1007 .getStackTraceWriter()
1008 .getThrowable()
1009 .getLocalizedMessage());
1010
1011 assertThat(reportEntry.getStackTraceWriter().smartTrimmedStackTrace())
1012 .isEqualTo(this.reportEntry.getStackTraceWriter().smartTrimmedStackTrace());
1013 }
1014 }
1015 }
1016
1017 private static class Stream extends PrintStream {
1018 private final ByteArrayOutputStream out;
1019
1020 Stream(ByteArrayOutputStream out) {
1021 super(out, true);
1022 this.out = out;
1023 }
1024
1025 byte[] toByteArray() {
1026 return out.toByteArray();
1027 }
1028
1029 LineNumberReader newReader(Charset streamCharset) {
1030 return new LineNumberReader(new StringReader(new String(toByteArray(), streamCharset)));
1031 }
1032
1033 static Stream newStream() {
1034 return new Stream(new ByteArrayOutputStream());
1035 }
1036 }
1037
1038 private static class EH implements EventHandler<Event> {
1039 private final BlockingQueue<Event> cache = new LinkedTransferQueue<>();
1040
1041 Event pullEvent() throws InterruptedException {
1042 return cache.poll(1, TimeUnit.MINUTES);
1043 }
1044
1045 @Override
1046 public void handleEvent(@Nonnull Event event) {
1047 cache.add(event);
1048 }
1049 }
1050
1051
1052
1053
1054 private static class ForkNodeArgumentsMock implements ForkNodeArguments {
1055 private final ConcurrentLinkedQueue<String> dumpStreamText = new ConcurrentLinkedQueue<>();
1056 private final ConcurrentLinkedQueue<String> logWarningAtEnd = new ConcurrentLinkedQueue<>();
1057 private final ConsoleLogger logger;
1058 private final File dumpStreamTextFile;
1059
1060 ForkNodeArgumentsMock(ConsoleLogger logger, File dumpStreamTextFile) {
1061 this.logger = logger;
1062 this.dumpStreamTextFile = dumpStreamTextFile;
1063 }
1064
1065 @Nonnull
1066 @Override
1067 public String getSessionId() {
1068 throw new UnsupportedOperationException();
1069 }
1070
1071 @Override
1072 public int getForkChannelId() {
1073 return 0;
1074 }
1075
1076 @Nonnull
1077 @Override
1078 public File dumpStreamText(@Nonnull String text) {
1079 dumpStreamText.add(text);
1080 return dumpStreamTextFile;
1081 }
1082
1083 @Nonnull
1084 @Override
1085 public File dumpStreamException(@Nonnull Throwable t) {
1086 return dumpStreamTextFile;
1087 }
1088
1089 @Override
1090 public void logWarningAtEnd(@Nonnull String text) {
1091 logWarningAtEnd.add(text);
1092 }
1093
1094 @Nonnull
1095 @Override
1096 public ConsoleLogger getConsoleLogger() {
1097 return logger;
1098 }
1099
1100 @Nonnull
1101 @Override
1102 public Object getConsoleLock() {
1103 return logger;
1104 }
1105
1106 boolean isCalled() {
1107 return !dumpStreamText.isEmpty() || !logWarningAtEnd.isEmpty();
1108 }
1109
1110 @Override
1111 public File getEventStreamBinaryFile() {
1112 return null;
1113 }
1114
1115 @Override
1116 public File getCommandStreamBinaryFile() {
1117 return null;
1118 }
1119 }
1120
1121
1122
1123
1124 private static class ConsoleLoggerMock implements ConsoleLogger {
1125 final ConcurrentLinkedQueue<String> debug = new ConcurrentLinkedQueue<>();
1126 final ConcurrentLinkedQueue<String> info = new ConcurrentLinkedQueue<>();
1127 final ConcurrentLinkedQueue<String> warning = new ConcurrentLinkedQueue<>();
1128 final ConcurrentLinkedQueue<String> error = new ConcurrentLinkedQueue<>();
1129 final boolean isDebug;
1130 final boolean isInfo;
1131 final boolean isWarning;
1132 final boolean isError;
1133 private volatile boolean called;
1134 private volatile boolean isDebugEnabledCalled;
1135 private volatile boolean isInfoEnabledCalled;
1136
1137 ConsoleLoggerMock(boolean isDebug, boolean isInfo, boolean isWarning, boolean isError) {
1138 this.isDebug = isDebug;
1139 this.isInfo = isInfo;
1140 this.isWarning = isWarning;
1141 this.isError = isError;
1142 }
1143
1144 @Override
1145 public synchronized boolean isDebugEnabled() {
1146 isDebugEnabledCalled = true;
1147 called = true;
1148 return isDebug;
1149 }
1150
1151 @Override
1152 public synchronized void debug(String message) {
1153 debug.add(message);
1154 called = true;
1155 }
1156
1157 @Override
1158 public synchronized boolean isInfoEnabled() {
1159 isInfoEnabledCalled = true;
1160 called = true;
1161 return isInfo;
1162 }
1163
1164 @Override
1165 public synchronized void info(String message) {
1166 info.add(message);
1167 called = true;
1168 }
1169
1170 @Override
1171 public synchronized boolean isWarnEnabled() {
1172 called = true;
1173 return isWarning;
1174 }
1175
1176 @Override
1177 public synchronized void warning(String message) {
1178 warning.add(message);
1179 called = true;
1180 }
1181
1182 @Override
1183 public synchronized boolean isErrorEnabled() {
1184 called = true;
1185 return isError;
1186 }
1187
1188 @Override
1189 public synchronized void error(String message) {
1190 error.add(message);
1191 called = true;
1192 }
1193
1194 @Override
1195 public synchronized void error(String message, Throwable t) {
1196 called = true;
1197 }
1198
1199 @Override
1200 public synchronized void error(Throwable t) {
1201 called = true;
1202 }
1203
1204 synchronized boolean isCalled() {
1205 return called;
1206 }
1207 }
1208 }