View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.surefire.stream;
20  
21  import javax.annotation.Nonnull;
22  
23  import java.io.File;
24  import java.lang.reflect.Method;
25  import java.nio.ByteBuffer;
26  import java.nio.channels.ReadableByteChannel;
27  import java.util.Map;
28  
29  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
30  import org.apache.maven.surefire.api.booter.ForkedProcessEventType;
31  import org.apache.maven.surefire.api.event.ConsoleDebugEvent;
32  import org.apache.maven.surefire.api.event.ConsoleErrorEvent;
33  import org.apache.maven.surefire.api.event.ConsoleInfoEvent;
34  import org.apache.maven.surefire.api.event.ConsoleWarningEvent;
35  import org.apache.maven.surefire.api.event.ControlByeEvent;
36  import org.apache.maven.surefire.api.event.ControlNextTestEvent;
37  import org.apache.maven.surefire.api.event.ControlStopOnNextTestEvent;
38  import org.apache.maven.surefire.api.event.Event;
39  import org.apache.maven.surefire.api.event.JvmExitErrorEvent;
40  import org.apache.maven.surefire.api.event.StandardStreamErrEvent;
41  import org.apache.maven.surefire.api.event.StandardStreamErrWithNewLineEvent;
42  import org.apache.maven.surefire.api.event.StandardStreamOutEvent;
43  import org.apache.maven.surefire.api.event.StandardStreamOutWithNewLineEvent;
44  import org.apache.maven.surefire.api.event.SystemPropertyEvent;
45  import org.apache.maven.surefire.api.event.TestAssumptionFailureEvent;
46  import org.apache.maven.surefire.api.event.TestErrorEvent;
47  import org.apache.maven.surefire.api.event.TestFailedEvent;
48  import org.apache.maven.surefire.api.event.TestSkippedEvent;
49  import org.apache.maven.surefire.api.event.TestStartingEvent;
50  import org.apache.maven.surefire.api.event.TestSucceededEvent;
51  import org.apache.maven.surefire.api.event.TestsetCompletedEvent;
52  import org.apache.maven.surefire.api.event.TestsetStartingEvent;
53  import org.apache.maven.surefire.api.fork.ForkNodeArguments;
54  import org.apache.maven.surefire.api.report.ReportEntry;
55  import org.apache.maven.surefire.api.report.RunMode;
56  import org.apache.maven.surefire.api.report.SafeThrowable;
57  import org.apache.maven.surefire.api.report.StackTraceWriter;
58  import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Memento;
59  import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Segment;
60  import org.apache.maven.surefire.api.stream.SegmentType;
61  import org.junit.jupiter.api.Test;
62  
63  import static java.lang.Math.min;
64  import static java.nio.charset.StandardCharsets.US_ASCII;
65  import static java.util.Arrays.asList;
66  import static java.util.Collections.singletonList;
67  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_BYE;
68  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_DEBUG;
69  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_ERROR;
70  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_INFO;
71  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_WARNING;
72  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_JVM_EXIT_ERROR;
73  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_NEXT_TEST;
74  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR;
75  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE;
76  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT;
77  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE;
78  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STOP_ON_NEXT_TEST;
79  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_SYSPROPS;
80  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED;
81  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_STARTING;
82  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE;
83  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ERROR;
84  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_FAILED;
85  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED;
86  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_STARTING;
87  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SUCCEEDED;
88  import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
89  import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE;
90  import static org.apache.maven.surefire.api.stream.SegmentType.DATA_INTEGER;
91  import static org.apache.maven.surefire.api.stream.SegmentType.DATA_STRING;
92  import static org.apache.maven.surefire.api.stream.SegmentType.END_OF_FRAME;
93  import static org.apache.maven.surefire.api.stream.SegmentType.RUN_MODE;
94  import static org.apache.maven.surefire.api.stream.SegmentType.STRING_ENCODING;
95  import static org.apache.maven.surefire.api.stream.SegmentType.TEST_RUN_ID;
96  import static org.apache.maven.surefire.stream.EventDecoder.newReportEntry;
97  import static org.assertj.core.api.Assertions.assertThat;
98  import static org.mockito.Mockito.mock;
99  import static org.mockito.Mockito.when;
100 
101 /**
102  *
103  */
104 public class EventDecoderTest {
105     @Test
106     public void shouldMapEventTypes() throws Exception {
107         Map<Segment, ForkedProcessEventType> eventTypes = invokeMethod(EventDecoder.class, "segmentsToEvents");
108         assertThat(eventTypes).hasSize(ForkedProcessEventType.values().length);
109     }
110 
111     @Test
112     public void shouldMapRunModes() throws Exception {
113         Map<Segment, RunMode> map = invokeMethod(EventDecoder.class, "segmentsToRunModes");
114 
115         assertThat(map).hasSize(2);
116 
117         byte[] stream = "normal-run".getBytes(US_ASCII);
118         Segment segment = new Segment(stream, 0, stream.length);
119         assertThat(map.get(segment)).isEqualTo(NORMAL_RUN);
120 
121         stream = "rerun-test-after-failure".getBytes(US_ASCII);
122         segment = new Segment(stream, 0, stream.length);
123         assertThat(map.get(segment)).isEqualTo(RERUN_TEST_AFTER_FAILURE);
124     }
125 
126     @Test
127     public void shouldMapEventTypeToSegmentType() {
128         byte[] stream = {};
129         Channel channel = new Channel(stream, 1);
130         EventDecoder decoder = new EventDecoder(channel, new MockForkNodeArguments());
131 
132         SegmentType[] segmentTypes = decoder.nextSegmentType(BOOTERCODE_BYE);
133         assertThat(segmentTypes).hasSize(1).containsOnly(END_OF_FRAME);
134 
135         segmentTypes = decoder.nextSegmentType(BOOTERCODE_STOP_ON_NEXT_TEST);
136         assertThat(segmentTypes).hasSize(1).containsOnly(END_OF_FRAME);
137 
138         segmentTypes = decoder.nextSegmentType(BOOTERCODE_NEXT_TEST);
139         assertThat(segmentTypes).hasSize(1).containsOnly(END_OF_FRAME);
140 
141         segmentTypes = decoder.nextSegmentType(BOOTERCODE_CONSOLE_ERROR);
142         assertThat(segmentTypes)
143                 .hasSize(5)
144                 .isEqualTo(new SegmentType[] {STRING_ENCODING, DATA_STRING, DATA_STRING, DATA_STRING, END_OF_FRAME});
145 
146         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_JVM_EXIT_ERROR);
147         assertThat(segmentTypes)
148                 .hasSize(5)
149                 .isEqualTo(new SegmentType[] {STRING_ENCODING, DATA_STRING, DATA_STRING, DATA_STRING, END_OF_FRAME});
150 
151         segmentTypes = decoder.nextSegmentType(BOOTERCODE_CONSOLE_INFO);
152         assertThat(segmentTypes).hasSize(3).isEqualTo(new SegmentType[] {STRING_ENCODING, DATA_STRING, END_OF_FRAME});
153 
154         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_CONSOLE_DEBUG);
155         assertThat(segmentTypes).hasSize(3).isEqualTo(new SegmentType[] {STRING_ENCODING, DATA_STRING, END_OF_FRAME});
156 
157         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_CONSOLE_WARNING);
158         assertThat(segmentTypes).hasSize(3).isEqualTo(new SegmentType[] {STRING_ENCODING, DATA_STRING, END_OF_FRAME});
159 
160         segmentTypes = decoder.nextSegmentType(BOOTERCODE_STDOUT);
161         assertThat(segmentTypes).hasSize(6).isEqualTo(new SegmentType[] {
162             RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, DATA_STRING, END_OF_FRAME
163         });
164 
165         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE);
166         assertThat(segmentTypes).hasSize(6).isEqualTo(new SegmentType[] {
167             RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, DATA_STRING, END_OF_FRAME
168         });
169 
170         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDERR);
171         assertThat(segmentTypes).hasSize(6).isEqualTo(new SegmentType[] {
172             RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, DATA_STRING, END_OF_FRAME
173         });
174 
175         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE);
176         assertThat(segmentTypes).hasSize(6).isEqualTo(new SegmentType[] {
177             RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, DATA_STRING, END_OF_FRAME
178         });
179 
180         segmentTypes = decoder.nextSegmentType(BOOTERCODE_SYSPROPS);
181         assertThat(segmentTypes).hasSize(6).isEqualTo(new SegmentType[] {
182             RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, DATA_STRING, END_OF_FRAME
183         });
184 
185         segmentTypes = decoder.nextSegmentType(BOOTERCODE_TESTSET_STARTING);
186         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
187             RUN_MODE,
188             TEST_RUN_ID,
189             STRING_ENCODING,
190             DATA_STRING,
191             DATA_STRING,
192             DATA_STRING,
193             DATA_STRING,
194             DATA_STRING,
195             DATA_STRING,
196             DATA_INTEGER,
197             DATA_STRING,
198             DATA_STRING,
199             DATA_STRING,
200             END_OF_FRAME
201         });
202 
203         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED);
204         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
205             RUN_MODE,
206             TEST_RUN_ID,
207             STRING_ENCODING,
208             DATA_STRING,
209             DATA_STRING,
210             DATA_STRING,
211             DATA_STRING,
212             DATA_STRING,
213             DATA_STRING,
214             DATA_INTEGER,
215             DATA_STRING,
216             DATA_STRING,
217             DATA_STRING,
218             END_OF_FRAME
219         });
220 
221         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_STARTING);
222         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
223             RUN_MODE,
224             TEST_RUN_ID,
225             STRING_ENCODING,
226             DATA_STRING,
227             DATA_STRING,
228             DATA_STRING,
229             DATA_STRING,
230             DATA_STRING,
231             DATA_STRING,
232             DATA_INTEGER,
233             DATA_STRING,
234             DATA_STRING,
235             DATA_STRING,
236             END_OF_FRAME
237         });
238 
239         segmentTypes = decoder.nextSegmentType(BOOTERCODE_TEST_SUCCEEDED);
240         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
241             RUN_MODE,
242             TEST_RUN_ID,
243             STRING_ENCODING,
244             DATA_STRING,
245             DATA_STRING,
246             DATA_STRING,
247             DATA_STRING,
248             DATA_STRING,
249             DATA_STRING,
250             DATA_INTEGER,
251             DATA_STRING,
252             DATA_STRING,
253             DATA_STRING,
254             END_OF_FRAME
255         });
256 
257         segmentTypes = decoder.nextSegmentType(BOOTERCODE_TEST_FAILED);
258         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
259             RUN_MODE,
260             TEST_RUN_ID,
261             STRING_ENCODING,
262             DATA_STRING,
263             DATA_STRING,
264             DATA_STRING,
265             DATA_STRING,
266             DATA_STRING,
267             DATA_STRING,
268             DATA_INTEGER,
269             DATA_STRING,
270             DATA_STRING,
271             DATA_STRING,
272             END_OF_FRAME
273         });
274 
275         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED);
276         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
277             RUN_MODE,
278             TEST_RUN_ID,
279             STRING_ENCODING,
280             DATA_STRING,
281             DATA_STRING,
282             DATA_STRING,
283             DATA_STRING,
284             DATA_STRING,
285             DATA_STRING,
286             DATA_INTEGER,
287             DATA_STRING,
288             DATA_STRING,
289             DATA_STRING,
290             END_OF_FRAME
291         });
292 
293         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_ERROR);
294         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
295             RUN_MODE,
296             TEST_RUN_ID,
297             STRING_ENCODING,
298             DATA_STRING,
299             DATA_STRING,
300             DATA_STRING,
301             DATA_STRING,
302             DATA_STRING,
303             DATA_STRING,
304             DATA_INTEGER,
305             DATA_STRING,
306             DATA_STRING,
307             DATA_STRING,
308             END_OF_FRAME
309         });
310 
311         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE);
312         assertThat(segmentTypes).hasSize(14).isEqualTo(new SegmentType[] {
313             RUN_MODE,
314             TEST_RUN_ID,
315             STRING_ENCODING,
316             DATA_STRING,
317             DATA_STRING,
318             DATA_STRING,
319             DATA_STRING,
320             DATA_STRING,
321             DATA_STRING,
322             DATA_INTEGER,
323             DATA_STRING,
324             DATA_STRING,
325             DATA_STRING,
326             END_OF_FRAME
327         });
328     }
329 
330     @Test
331     public void shouldCreateEvent() throws Exception {
332         byte[] stream = {};
333         Channel channel = new Channel(stream, 1);
334         EventDecoder decoder = new EventDecoder(channel, new MockForkNodeArguments());
335 
336         Event event = decoder.toMessage(BOOTERCODE_BYE, decoder.new Memento());
337         assertThat(event).isInstanceOf(ControlByeEvent.class);
338 
339         event = decoder.toMessage(BOOTERCODE_STOP_ON_NEXT_TEST, decoder.new Memento());
340         assertThat(event).isInstanceOf(ControlStopOnNextTestEvent.class);
341 
342         event = decoder.toMessage(BOOTERCODE_NEXT_TEST, decoder.new Memento());
343         assertThat(event).isInstanceOf(ControlNextTestEvent.class);
344 
345         Memento memento = decoder.new Memento();
346         memento.getData().addAll(asList("1", "2", "3"));
347         event = decoder.toMessage(BOOTERCODE_CONSOLE_ERROR, memento);
348         assertThat(event).isInstanceOf(ConsoleErrorEvent.class);
349         ConsoleErrorEvent consoleErrorEvent = (ConsoleErrorEvent) event;
350         assertThat(consoleErrorEvent.getStackTraceWriter().getThrowable().getLocalizedMessage())
351                 .isEqualTo("1");
352         assertThat(consoleErrorEvent.getStackTraceWriter().smartTrimmedStackTrace())
353                 .isEqualTo("2");
354         assertThat(consoleErrorEvent.getStackTraceWriter().writeTraceToString()).isEqualTo("3");
355 
356         memento = decoder.new Memento();
357         memento.getData().addAll(asList(null, null, null));
358         event = decoder.toMessage(BOOTERCODE_CONSOLE_ERROR, memento);
359         assertThat(event).isInstanceOf(ConsoleErrorEvent.class);
360         consoleErrorEvent = (ConsoleErrorEvent) event;
361         assertThat(consoleErrorEvent.getStackTraceWriter()).isNull();
362 
363         memento = decoder.new Memento();
364         memento.getData().addAll(asList("1", "2", "3"));
365         event = decoder.toMessage(BOOTERCODE_JVM_EXIT_ERROR, memento);
366         assertThat(event).isInstanceOf(JvmExitErrorEvent.class);
367         JvmExitErrorEvent jvmExitErrorEvent = (JvmExitErrorEvent) event;
368         assertThat(jvmExitErrorEvent.getStackTraceWriter().getThrowable().getLocalizedMessage())
369                 .isEqualTo("1");
370         assertThat(jvmExitErrorEvent.getStackTraceWriter().smartTrimmedStackTrace())
371                 .isEqualTo("2");
372         assertThat(jvmExitErrorEvent.getStackTraceWriter().writeTraceToString()).isEqualTo("3");
373 
374         memento = decoder.new Memento();
375         memento.getData().addAll(asList(null, null, null));
376         event = decoder.toMessage(BOOTERCODE_JVM_EXIT_ERROR, memento);
377         assertThat(event).isInstanceOf(JvmExitErrorEvent.class);
378         jvmExitErrorEvent = (JvmExitErrorEvent) event;
379         assertThat(jvmExitErrorEvent.getStackTraceWriter()).isNull();
380 
381         memento = decoder.new Memento();
382         memento.getData().addAll(singletonList("m"));
383         event = decoder.toMessage(BOOTERCODE_CONSOLE_INFO, memento);
384         assertThat(event).isInstanceOf(ConsoleInfoEvent.class);
385         assertThat(((ConsoleInfoEvent) event).getMessage()).isEqualTo("m");
386 
387         memento = decoder.new Memento();
388         memento.getData().addAll(singletonList(""));
389         event = decoder.toMessage(BOOTERCODE_CONSOLE_WARNING, memento);
390         assertThat(event).isInstanceOf(ConsoleWarningEvent.class);
391         assertThat(((ConsoleWarningEvent) event).getMessage()).isEmpty();
392 
393         memento = decoder.new Memento();
394         memento.getData().addAll(singletonList(null));
395         event = decoder.toMessage(BOOTERCODE_CONSOLE_DEBUG, memento);
396         assertThat(event).isInstanceOf(ConsoleDebugEvent.class);
397         assertThat(((ConsoleDebugEvent) event).getMessage()).isNull();
398 
399         memento = decoder.new Memento();
400         memento.getData().addAll(asList(NORMAL_RUN, 1L, "m", "stack"));
401         event = decoder.toMessage(BOOTERCODE_STDOUT, memento);
402         assertThat(event).isInstanceOf(StandardStreamOutEvent.class);
403         assertThat(((StandardStreamOutEvent) event).getMessage()).isEqualTo("m");
404         assertThat(((StandardStreamOutEvent) event).getRunMode()).isEqualTo(NORMAL_RUN);
405         assertThat(((StandardStreamOutEvent) event).getTestRunId()).isEqualTo(1L);
406         assertThat(((StandardStreamOutEvent) event).getStack()).isEqualTo("stack");
407 
408         memento = decoder.new Memento();
409         memento.getData().addAll(asList(RERUN_TEST_AFTER_FAILURE, 1L, null, null));
410         event = decoder.toMessage(BOOTERCODE_STDOUT_NEW_LINE, memento);
411         assertThat(event).isInstanceOf(StandardStreamOutWithNewLineEvent.class);
412         assertThat(((StandardStreamOutWithNewLineEvent) event).getMessage()).isNull();
413         assertThat(((StandardStreamOutWithNewLineEvent) event).getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
414         assertThat(((StandardStreamOutWithNewLineEvent) event).getTestRunId()).isEqualTo(1L);
415         assertThat(((StandardStreamOutWithNewLineEvent) event).getStack()).isNull();
416 
417         memento = decoder.new Memento();
418         memento.getData().addAll(asList(RERUN_TEST_AFTER_FAILURE, 1L, null, null));
419         event = decoder.toMessage(BOOTERCODE_STDERR, memento);
420         assertThat(event).isInstanceOf(StandardStreamErrEvent.class);
421         assertThat(((StandardStreamErrEvent) event).getMessage()).isNull();
422         assertThat(((StandardStreamErrEvent) event).getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
423         assertThat(((StandardStreamErrEvent) event).getTestRunId()).isEqualTo(1L);
424         assertThat(((StandardStreamErrEvent) event).getStack()).isNull();
425 
426         memento = decoder.new Memento();
427         memento.getData().addAll(asList(NORMAL_RUN, 1L, "abc", "stacktrace"));
428         event = decoder.toMessage(BOOTERCODE_STDERR_NEW_LINE, memento);
429         assertThat(event).isInstanceOf(StandardStreamErrWithNewLineEvent.class);
430         assertThat(((StandardStreamErrWithNewLineEvent) event).getMessage()).isEqualTo("abc");
431         assertThat(((StandardStreamErrWithNewLineEvent) event).getRunMode()).isEqualTo(NORMAL_RUN);
432         assertThat(((StandardStreamErrWithNewLineEvent) event).getTestRunId()).isEqualTo(1L);
433         assertThat(((StandardStreamErrWithNewLineEvent) event).getStack()).isEqualTo("stacktrace");
434 
435         memento = decoder.new Memento();
436         memento.getData().addAll(asList(NORMAL_RUN, 1L, "key", "value"));
437         event = decoder.toMessage(BOOTERCODE_SYSPROPS, memento);
438         assertThat(event).isInstanceOf(SystemPropertyEvent.class);
439         assertThat(((SystemPropertyEvent) event).getRunMode()).isEqualTo(NORMAL_RUN);
440         assertThat(((SystemPropertyEvent) event).getTestRunId()).isEqualTo(1L);
441         assertThat(((SystemPropertyEvent) event).getKey()).isEqualTo("key");
442         assertThat(((SystemPropertyEvent) event).getValue()).isEqualTo("value");
443 
444         memento = decoder.new Memento();
445         memento.getData()
446                 .addAll(asList(
447                         NORMAL_RUN,
448                         1L,
449                         "source",
450                         "sourceText",
451                         "name",
452                         "nameText",
453                         "group",
454                         "message",
455                         5,
456                         "traceMessage",
457                         "smartTrimmedStackTrace",
458                         "stackTrace"));
459         event = decoder.toMessage(BOOTERCODE_TESTSET_STARTING, memento);
460         assertThat(event).isInstanceOf(TestsetStartingEvent.class);
461         assertThat(((TestsetStartingEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
462         assertThat(((TestsetStartingEvent) event).getReportEntry().getTestRunId())
463                 .isEqualTo(1L);
464         assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceName())
465                 .isEqualTo("source");
466         assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceText())
467                 .isEqualTo("sourceText");
468         assertThat(((TestsetStartingEvent) event).getReportEntry().getName()).isEqualTo("name");
469         assertThat(((TestsetStartingEvent) event).getReportEntry().getNameText())
470                 .isEqualTo("nameText");
471         assertThat(((TestsetStartingEvent) event).getReportEntry().getGroup()).isEqualTo("group");
472         assertThat(((TestsetStartingEvent) event).getReportEntry().getMessage()).isEqualTo("message");
473         assertThat(((TestsetStartingEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
474         assertThat(((TestsetStartingEvent) event)
475                         .getReportEntry()
476                         .getStackTraceWriter()
477                         .getThrowable()
478                         .getLocalizedMessage())
479                 .isEqualTo("traceMessage");
480         assertThat(((TestsetStartingEvent) event)
481                         .getReportEntry()
482                         .getStackTraceWriter()
483                         .smartTrimmedStackTrace())
484                 .isEqualTo("smartTrimmedStackTrace");
485         assertThat(((TestsetStartingEvent) event)
486                         .getReportEntry()
487                         .getStackTraceWriter()
488                         .writeTraceToString())
489                 .isEqualTo("stackTrace");
490 
491         memento = decoder.new Memento();
492         memento.getData()
493                 .addAll(asList(
494                         NORMAL_RUN,
495                         1L,
496                         "source",
497                         "sourceText",
498                         "name",
499                         "nameText",
500                         "group",
501                         null,
502                         5,
503                         "traceMessage",
504                         "smartTrimmedStackTrace",
505                         "stackTrace"));
506         event = decoder.toMessage(BOOTERCODE_TESTSET_COMPLETED, memento);
507         assertThat(event).isInstanceOf(TestsetCompletedEvent.class);
508         assertThat(((TestsetCompletedEvent) event).getReportEntry().getRunMode())
509                 .isEqualTo(NORMAL_RUN);
510         assertThat(((TestsetCompletedEvent) event).getReportEntry().getTestRunId())
511                 .isEqualTo(1L);
512         assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceName())
513                 .isEqualTo("source");
514         assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceText())
515                 .isEqualTo("sourceText");
516         assertThat(((TestsetCompletedEvent) event).getReportEntry().getName()).isEqualTo("name");
517         assertThat(((TestsetCompletedEvent) event).getReportEntry().getNameText())
518                 .isEqualTo("nameText");
519         assertThat(((TestsetCompletedEvent) event).getReportEntry().getGroup()).isEqualTo("group");
520         assertThat(((TestsetCompletedEvent) event).getReportEntry().getMessage())
521                 .isNull();
522         assertThat(((TestsetCompletedEvent) event).getReportEntry().getElapsed())
523                 .isEqualTo(5);
524         assertThat(((TestsetCompletedEvent) event)
525                         .getReportEntry()
526                         .getStackTraceWriter()
527                         .getThrowable()
528                         .getLocalizedMessage())
529                 .isEqualTo("traceMessage");
530         assertThat(((TestsetCompletedEvent) event)
531                         .getReportEntry()
532                         .getStackTraceWriter()
533                         .smartTrimmedStackTrace())
534                 .isEqualTo("smartTrimmedStackTrace");
535         assertThat(((TestsetCompletedEvent) event)
536                         .getReportEntry()
537                         .getStackTraceWriter()
538                         .writeTraceToString())
539                 .isEqualTo("stackTrace");
540 
541         memento = decoder.new Memento();
542         memento.getData()
543                 .addAll(asList(
544                         NORMAL_RUN,
545                         1L,
546                         "source",
547                         "sourceText",
548                         "name",
549                         "nameText",
550                         "group",
551                         "message",
552                         5,
553                         null,
554                         "smartTrimmedStackTrace",
555                         "stackTrace"));
556         event = decoder.toMessage(BOOTERCODE_TEST_STARTING, memento);
557         assertThat(event).isInstanceOf(TestStartingEvent.class);
558         assertThat(((TestStartingEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
559         assertThat(((TestStartingEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
560         assertThat(((TestStartingEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
561         assertThat(((TestStartingEvent) event).getReportEntry().getSourceText()).isEqualTo("sourceText");
562         assertThat(((TestStartingEvent) event).getReportEntry().getName()).isEqualTo("name");
563         assertThat(((TestStartingEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
564         assertThat(((TestStartingEvent) event).getReportEntry().getGroup()).isEqualTo("group");
565         assertThat(((TestStartingEvent) event).getReportEntry().getMessage()).isEqualTo("message");
566         assertThat(((TestStartingEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
567         assertThat(((TestStartingEvent) event)
568                         .getReportEntry()
569                         .getStackTraceWriter()
570                         .getThrowable()
571                         .getLocalizedMessage())
572                 .isNull();
573         assertThat(((TestStartingEvent) event)
574                         .getReportEntry()
575                         .getStackTraceWriter()
576                         .smartTrimmedStackTrace())
577                 .isEqualTo("smartTrimmedStackTrace");
578         assertThat(((TestStartingEvent) event)
579                         .getReportEntry()
580                         .getStackTraceWriter()
581                         .writeTraceToString())
582                 .isEqualTo("stackTrace");
583 
584         memento = decoder.new Memento();
585         memento.getData()
586                 .addAll(asList(
587                         NORMAL_RUN,
588                         1L,
589                         "source",
590                         "sourceText",
591                         "name",
592                         "nameText",
593                         "group",
594                         "message",
595                         5,
596                         null,
597                         null,
598                         null));
599         event = decoder.toMessage(BOOTERCODE_TEST_SUCCEEDED, memento);
600         assertThat(event).isInstanceOf(TestSucceededEvent.class);
601         assertThat(((TestSucceededEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
602         assertThat(((TestSucceededEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
603         assertThat(((TestSucceededEvent) event).getReportEntry().getSourceName())
604                 .isEqualTo("source");
605         assertThat(((TestSucceededEvent) event).getReportEntry().getSourceText())
606                 .isEqualTo("sourceText");
607         assertThat(((TestSucceededEvent) event).getReportEntry().getName()).isEqualTo("name");
608         assertThat(((TestSucceededEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
609         assertThat(((TestSucceededEvent) event).getReportEntry().getGroup()).isEqualTo("group");
610         assertThat(((TestSucceededEvent) event).getReportEntry().getMessage()).isEqualTo("message");
611         assertThat(((TestSucceededEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
612         assertThat(((TestSucceededEvent) event).getReportEntry().getStackTraceWriter())
613                 .isNull();
614 
615         memento = decoder.new Memento();
616         memento.getData()
617                 .addAll(asList(
618                         RERUN_TEST_AFTER_FAILURE,
619                         1L,
620                         "source",
621                         null,
622                         "name",
623                         null,
624                         "group",
625                         null,
626                         5,
627                         "traceMessage",
628                         "smartTrimmedStackTrace",
629                         "stackTrace"));
630         event = decoder.toMessage(BOOTERCODE_TEST_FAILED, memento);
631         assertThat(event).isInstanceOf(TestFailedEvent.class);
632         assertThat(((TestFailedEvent) event).getReportEntry().getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
633         assertThat(((TestFailedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
634         assertThat(((TestFailedEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
635         assertThat(((TestFailedEvent) event).getReportEntry().getSourceText()).isNull();
636         assertThat(((TestFailedEvent) event).getReportEntry().getName()).isEqualTo("name");
637         assertThat(((TestFailedEvent) event).getReportEntry().getNameText()).isNull();
638         assertThat(((TestFailedEvent) event).getReportEntry().getGroup()).isEqualTo("group");
639         assertThat(((TestFailedEvent) event).getReportEntry().getMessage()).isNull();
640         assertThat(((TestFailedEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
641         assertThat(((TestFailedEvent) event)
642                         .getReportEntry()
643                         .getStackTraceWriter()
644                         .getThrowable()
645                         .getLocalizedMessage())
646                 .isEqualTo("traceMessage");
647         assertThat(((TestFailedEvent) event)
648                         .getReportEntry()
649                         .getStackTraceWriter()
650                         .smartTrimmedStackTrace())
651                 .isEqualTo("smartTrimmedStackTrace");
652         assertThat(((TestFailedEvent) event)
653                         .getReportEntry()
654                         .getStackTraceWriter()
655                         .writeTraceToString())
656                 .isEqualTo("stackTrace");
657 
658         memento = decoder.new Memento();
659         memento.getData()
660                 .addAll(asList(NORMAL_RUN, 1L, "source", null, "name", null, null, null, 5, null, null, "stackTrace"));
661         event = decoder.toMessage(BOOTERCODE_TEST_SKIPPED, memento);
662         assertThat(event).isInstanceOf(TestSkippedEvent.class);
663         assertThat(((TestSkippedEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
664         assertThat(((TestSkippedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
665         assertThat(((TestSkippedEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
666         assertThat(((TestSkippedEvent) event).getReportEntry().getSourceText()).isNull();
667         assertThat(((TestSkippedEvent) event).getReportEntry().getName()).isEqualTo("name");
668         assertThat(((TestSkippedEvent) event).getReportEntry().getNameText()).isNull();
669         assertThat(((TestSkippedEvent) event).getReportEntry().getGroup()).isNull();
670         assertThat(((TestSkippedEvent) event).getReportEntry().getMessage()).isNull();
671         assertThat(((TestSkippedEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
672         assertThat(((TestSkippedEvent) event)
673                         .getReportEntry()
674                         .getStackTraceWriter()
675                         .getThrowable()
676                         .getLocalizedMessage())
677                 .isNull();
678         assertThat(((TestSkippedEvent) event)
679                         .getReportEntry()
680                         .getStackTraceWriter()
681                         .smartTrimmedStackTrace())
682                 .isNull();
683         assertThat(((TestSkippedEvent) event)
684                         .getReportEntry()
685                         .getStackTraceWriter()
686                         .writeTraceToString())
687                 .isEqualTo("stackTrace");
688 
689         memento = decoder.new Memento();
690         memento.getData()
691                 .addAll(asList(
692                         NORMAL_RUN, 1L, "source", null, "name", "nameText", null, null, 0, null, null, "stackTrace"));
693         event = decoder.toMessage(BOOTERCODE_TEST_ERROR, memento);
694         assertThat(event).isInstanceOf(TestErrorEvent.class);
695         assertThat(((TestErrorEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
696         assertThat(((TestErrorEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
697         assertThat(((TestErrorEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
698         assertThat(((TestErrorEvent) event).getReportEntry().getSourceText()).isNull();
699         assertThat(((TestErrorEvent) event).getReportEntry().getName()).isEqualTo("name");
700         assertThat(((TestErrorEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
701         assertThat(((TestErrorEvent) event).getReportEntry().getGroup()).isNull();
702         assertThat(((TestErrorEvent) event).getReportEntry().getMessage()).isNull();
703         assertThat(((TestErrorEvent) event).getReportEntry().getElapsed()).isZero();
704         assertThat(((TestErrorEvent) event)
705                         .getReportEntry()
706                         .getStackTraceWriter()
707                         .getThrowable()
708                         .getLocalizedMessage())
709                 .isNull();
710         assertThat(((TestErrorEvent) event)
711                         .getReportEntry()
712                         .getStackTraceWriter()
713                         .smartTrimmedStackTrace())
714                 .isNull();
715         assertThat(((TestErrorEvent) event)
716                         .getReportEntry()
717                         .getStackTraceWriter()
718                         .writeTraceToString())
719                 .isEqualTo("stackTrace");
720 
721         memento = decoder.new Memento();
722         memento.getData()
723                 .addAll(asList(
724                         NORMAL_RUN, 1L, "source", null, "name", null, "group", null, 5, null, null, "stackTrace"));
725         event = decoder.toMessage(BOOTERCODE_TEST_ASSUMPTIONFAILURE, memento);
726         assertThat(event).isInstanceOf(TestAssumptionFailureEvent.class);
727         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getRunMode())
728                 .isEqualTo(NORMAL_RUN);
729         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getTestRunId())
730                 .isEqualTo(1L);
731         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceName())
732                 .isEqualTo("source");
733         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceText())
734                 .isNull();
735         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getName())
736                 .isEqualTo("name");
737         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getNameText())
738                 .isNull();
739         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getGroup())
740                 .isEqualTo("group");
741         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getMessage())
742                 .isNull();
743         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getElapsed())
744                 .isEqualTo(5);
745         assertThat(((TestAssumptionFailureEvent) event)
746                         .getReportEntry()
747                         .getStackTraceWriter()
748                         .getThrowable()
749                         .getLocalizedMessage())
750                 .isNull();
751         assertThat(((TestAssumptionFailureEvent) event)
752                         .getReportEntry()
753                         .getStackTraceWriter()
754                         .smartTrimmedStackTrace())
755                 .isNull();
756         assertThat(((TestAssumptionFailureEvent) event)
757                         .getReportEntry()
758                         .getStackTraceWriter()
759                         .writeTraceToString())
760                 .isEqualTo("stackTrace");
761     }
762 
763     @Test
764     public void shouldRecognizeEmptyStream4ReportEntry() {
765         ReportEntry reportEntry = newReportEntry(NORMAL_RUN, 1L, "", "", "", "", "", "", null, "", "", "");
766         assertThat(reportEntry).isNotNull();
767         assertThat(reportEntry.getRunMode()).isEqualTo(NORMAL_RUN);
768         assertThat(reportEntry.getTestRunId()).isEqualTo(1L);
769         assertThat(reportEntry.getStackTraceWriter()).isNotNull();
770         assertThat(reportEntry.getStackTraceWriter().smartTrimmedStackTrace()).isEmpty();
771         assertThat(reportEntry.getStackTraceWriter().writeTraceToString()).isEmpty();
772         assertThat(reportEntry.getStackTraceWriter().writeTrimmedTraceToString())
773                 .isEmpty();
774         assertThat(reportEntry.getSourceName()).isEmpty();
775         assertThat(reportEntry.getSourceText()).isEmpty();
776         assertThat(reportEntry.getName()).isEmpty();
777         assertThat(reportEntry.getNameText()).isEmpty();
778         assertThat(reportEntry.getGroup()).isEmpty();
779         assertThat(reportEntry.getNameWithGroup()).isEmpty();
780         assertThat(reportEntry.getMessage()).isEmpty();
781         assertThat(reportEntry.getElapsed()).isNull();
782     }
783 
784     @Test
785     @SuppressWarnings("checkstyle:magicnumber")
786     public void testCreatingReportEntry() {
787         final String exceptionMessage = "msg";
788         final String smartStackTrace = "MyTest:86 >> Error";
789         final String stackTrace = "Exception: msg\ntrace line 1\ntrace line 2";
790         final String trimmedStackTrace = "trace line 1\ntrace line 2";
791 
792         SafeThrowable safeThrowable = new SafeThrowable(exceptionMessage);
793         StackTraceWriter stackTraceWriter = mock(StackTraceWriter.class);
794         when(stackTraceWriter.getThrowable()).thenReturn(safeThrowable);
795         when(stackTraceWriter.smartTrimmedStackTrace()).thenReturn(smartStackTrace);
796         when(stackTraceWriter.writeTrimmedTraceToString()).thenReturn(trimmedStackTrace);
797         when(stackTraceWriter.writeTraceToString()).thenReturn(stackTrace);
798 
799         ReportEntry reportEntry = mock(ReportEntry.class);
800         when(reportEntry.getElapsed()).thenReturn(102);
801         when(reportEntry.getGroup()).thenReturn("this group");
802         when(reportEntry.getMessage()).thenReturn("skipped test");
803         when(reportEntry.getName()).thenReturn("my test");
804         when(reportEntry.getNameText()).thenReturn("my display name");
805         when(reportEntry.getNameWithGroup()).thenReturn("name with group");
806         when(reportEntry.getSourceName()).thenReturn("pkg.MyTest");
807         when(reportEntry.getSourceText()).thenReturn("test class display name");
808         when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter);
809 
810         ReportEntry decodedReportEntry = newReportEntry(
811                 NORMAL_RUN,
812                 1L,
813                 reportEntry.getSourceName(),
814                 reportEntry.getSourceText(),
815                 reportEntry.getName(),
816                 reportEntry.getNameText(),
817                 reportEntry.getGroup(),
818                 reportEntry.getMessage(),
819                 null,
820                 null,
821                 null,
822                 null);
823 
824         assertThat(decodedReportEntry).isNotNull();
825         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
826         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
827         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
828         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
829         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
830         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
831         assertThat(decodedReportEntry.getStackTraceWriter()).isNull();
832 
833         decodedReportEntry = newReportEntry(
834                 NORMAL_RUN,
835                 1L,
836                 reportEntry.getSourceName(),
837                 reportEntry.getSourceText(),
838                 reportEntry.getName(),
839                 reportEntry.getNameText(),
840                 reportEntry.getGroup(),
841                 reportEntry.getMessage(),
842                 null,
843                 exceptionMessage,
844                 smartStackTrace,
845                 null);
846 
847         assertThat(decodedReportEntry).isNotNull();
848         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
849         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
850         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
851         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
852         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
853         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
854         assertThat(decodedReportEntry.getElapsed()).isNull();
855         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
856         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
857                 .isEqualTo(exceptionMessage);
858         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
859                 .isEqualTo(smartStackTrace);
860         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
861                 .isNull();
862 
863         decodedReportEntry = newReportEntry(
864                 NORMAL_RUN,
865                 1L,
866                 reportEntry.getSourceName(),
867                 reportEntry.getSourceText(),
868                 reportEntry.getName(),
869                 reportEntry.getNameText(),
870                 reportEntry.getGroup(),
871                 reportEntry.getMessage(),
872                 1003,
873                 exceptionMessage,
874                 smartStackTrace,
875                 null);
876 
877         assertThat(decodedReportEntry).isNotNull();
878         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
879         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
880         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
881         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
882         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
883         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
884         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
885         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
886         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
887                 .isEqualTo(exceptionMessage);
888         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
889                 .isEqualTo(smartStackTrace);
890         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
891                 .isNull();
892 
893         decodedReportEntry = newReportEntry(
894                 NORMAL_RUN,
895                 1L,
896                 reportEntry.getSourceName(),
897                 reportEntry.getSourceText(),
898                 reportEntry.getName(),
899                 reportEntry.getNameText(),
900                 reportEntry.getGroup(),
901                 reportEntry.getMessage(),
902                 1003,
903                 exceptionMessage,
904                 smartStackTrace,
905                 stackTrace);
906 
907         assertThat(decodedReportEntry).isNotNull();
908         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
909         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
910         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
911         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
912         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
913         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
914         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
915         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
916         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
917                 .isNotNull();
918         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
919                 .isEqualTo(exceptionMessage);
920         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
921                 .isEqualTo(smartStackTrace);
922         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
923                 .isEqualTo(stackTrace);
924         assertThat(decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString())
925                 .isEqualTo(stackTrace);
926 
927         decodedReportEntry = newReportEntry(
928                 NORMAL_RUN,
929                 1L,
930                 reportEntry.getSourceName(),
931                 reportEntry.getSourceText(),
932                 reportEntry.getName(),
933                 reportEntry.getNameText(),
934                 reportEntry.getGroup(),
935                 reportEntry.getMessage(),
936                 1003,
937                 exceptionMessage,
938                 smartStackTrace,
939                 trimmedStackTrace);
940 
941         assertThat(decodedReportEntry).isNotNull();
942         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
943         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
944         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
945         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
946         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
947         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
948         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
949         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
950         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
951                 .isNotNull();
952         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
953                 .isEqualTo(exceptionMessage);
954         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
955                 .isEqualTo(smartStackTrace);
956         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
957                 .isEqualTo(trimmedStackTrace);
958         assertThat(decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString())
959                 .isEqualTo(trimmedStackTrace);
960     }
961 
962     @SuppressWarnings("unchecked")
963     private static <T> T invokeMethod(Object target, String methodName, Object... args) throws Exception {
964         Class<?> clazz = target instanceof Class ? (Class<?>) target : target.getClass();
965         for (Method method : clazz.getDeclaredMethods()) {
966             if (method.getName().equals(methodName) && method.getParameterCount() == args.length) {
967                 method.setAccessible(true);
968                 return (T) method.invoke(target instanceof Class ? null : target, args);
969             }
970         }
971         throw new NoSuchMethodException(methodName);
972     }
973 
974     private static class Channel implements ReadableByteChannel {
975         private final byte[] bytes;
976         private final int chunkSize;
977         protected int i;
978 
979         Channel(byte[] bytes, int chunkSize) {
980             this.bytes = bytes;
981             this.chunkSize = chunkSize;
982         }
983 
984         @Override
985         public int read(ByteBuffer dst) {
986             if (i == bytes.length) {
987                 return -1;
988             } else if (dst.hasRemaining()) {
989                 int length = min(min(chunkSize, bytes.length - i), dst.remaining());
990                 dst.put(bytes, i, length);
991                 i += length;
992                 return length;
993             } else {
994                 return 0;
995             }
996         }
997 
998         @Override
999         public boolean isOpen() {
1000             return false;
1001         }
1002 
1003         @Override
1004         public void close() {}
1005     }
1006 
1007     private static class MockForkNodeArguments implements ForkNodeArguments {
1008         @Nonnull
1009         @Override
1010         public String getSessionId() {
1011             return null;
1012         }
1013 
1014         @Override
1015         public int getForkChannelId() {
1016             return 0;
1017         }
1018 
1019         @Nonnull
1020         @Override
1021         public File dumpStreamText(@Nonnull String text) {
1022             return null;
1023         }
1024 
1025         @Nonnull
1026         @Override
1027         public File dumpStreamException(@Nonnull Throwable t) {
1028             return null;
1029         }
1030 
1031         @Override
1032         public void logWarningAtEnd(@Nonnull String text) {}
1033 
1034         @Nonnull
1035         @Override
1036         public ConsoleLogger getConsoleLogger() {
1037             return null;
1038         }
1039 
1040         @Nonnull
1041         @Override
1042         public Object getConsoleLock() {
1043             return new Object();
1044         }
1045 
1046         @Override
1047         public File getEventStreamBinaryFile() {
1048             return null;
1049         }
1050 
1051         @Override
1052         public File getCommandStreamBinaryFile() {
1053             return null;
1054         }
1055     }
1056 }