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.nio.ByteBuffer;
25  import java.nio.channels.ReadableByteChannel;
26  import java.util.Map;
27  
28  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
29  import org.apache.maven.surefire.api.booter.ForkedProcessEventType;
30  import org.apache.maven.surefire.api.event.ConsoleDebugEvent;
31  import org.apache.maven.surefire.api.event.ConsoleErrorEvent;
32  import org.apache.maven.surefire.api.event.ConsoleInfoEvent;
33  import org.apache.maven.surefire.api.event.ConsoleWarningEvent;
34  import org.apache.maven.surefire.api.event.ControlByeEvent;
35  import org.apache.maven.surefire.api.event.ControlNextTestEvent;
36  import org.apache.maven.surefire.api.event.ControlStopOnNextTestEvent;
37  import org.apache.maven.surefire.api.event.Event;
38  import org.apache.maven.surefire.api.event.JvmExitErrorEvent;
39  import org.apache.maven.surefire.api.event.StandardStreamErrEvent;
40  import org.apache.maven.surefire.api.event.StandardStreamErrWithNewLineEvent;
41  import org.apache.maven.surefire.api.event.StandardStreamOutEvent;
42  import org.apache.maven.surefire.api.event.StandardStreamOutWithNewLineEvent;
43  import org.apache.maven.surefire.api.event.SystemPropertyEvent;
44  import org.apache.maven.surefire.api.event.TestAssumptionFailureEvent;
45  import org.apache.maven.surefire.api.event.TestErrorEvent;
46  import org.apache.maven.surefire.api.event.TestFailedEvent;
47  import org.apache.maven.surefire.api.event.TestSkippedEvent;
48  import org.apache.maven.surefire.api.event.TestStartingEvent;
49  import org.apache.maven.surefire.api.event.TestSucceededEvent;
50  import org.apache.maven.surefire.api.event.TestsetCompletedEvent;
51  import org.apache.maven.surefire.api.event.TestsetStartingEvent;
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.stream.AbstractStreamDecoder.Memento;
58  import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Segment;
59  import org.apache.maven.surefire.api.stream.SegmentType;
60  import org.junit.Test;
61  
62  import static java.lang.Math.min;
63  import static java.nio.charset.StandardCharsets.US_ASCII;
64  import static java.util.Arrays.asList;
65  import static java.util.Collections.singletonList;
66  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_BYE;
67  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_DEBUG;
68  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_ERROR;
69  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_INFO;
70  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_CONSOLE_WARNING;
71  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_JVM_EXIT_ERROR;
72  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_NEXT_TEST;
73  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR;
74  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE;
75  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT;
76  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE;
77  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_STOP_ON_NEXT_TEST;
78  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_SYSPROPS;
79  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_COMPLETED;
80  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TESTSET_STARTING;
81  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ASSUMPTIONFAILURE;
82  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_ERROR;
83  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_FAILED;
84  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SKIPPED;
85  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_STARTING;
86  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_TEST_SUCCEEDED;
87  import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
88  import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE;
89  import static org.apache.maven.surefire.api.stream.SegmentType.DATA_INTEGER;
90  import static org.apache.maven.surefire.api.stream.SegmentType.DATA_STRING;
91  import static org.apache.maven.surefire.api.stream.SegmentType.END_OF_FRAME;
92  import static org.apache.maven.surefire.api.stream.SegmentType.RUN_MODE;
93  import static org.apache.maven.surefire.api.stream.SegmentType.STRING_ENCODING;
94  import static org.apache.maven.surefire.api.stream.SegmentType.TEST_RUN_ID;
95  import static org.apache.maven.surefire.stream.EventDecoder.newReportEntry;
96  import static org.assertj.core.api.Assertions.assertThat;
97  import static org.powermock.api.mockito.PowerMockito.mock;
98  import static org.powermock.api.mockito.PowerMockito.when;
99  import static org.powermock.reflect.Whitebox.invokeMethod;
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)
162                 .hasSize(5)
163                 .isEqualTo(new SegmentType[] {RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, END_OF_FRAME});
164 
165         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDOUT_NEW_LINE);
166         assertThat(segmentTypes)
167                 .hasSize(5)
168                 .isEqualTo(new SegmentType[] {RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, END_OF_FRAME});
169 
170         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDERR);
171         assertThat(segmentTypes)
172                 .hasSize(5)
173                 .isEqualTo(new SegmentType[] {RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, END_OF_FRAME});
174 
175         segmentTypes = decoder.nextSegmentType(ForkedProcessEventType.BOOTERCODE_STDERR_NEW_LINE);
176         assertThat(segmentTypes)
177                 .hasSize(5)
178                 .isEqualTo(new SegmentType[] {RUN_MODE, TEST_RUN_ID, STRING_ENCODING, DATA_STRING, END_OF_FRAME});
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"));
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 
407         memento = decoder.new Memento();
408         memento.getData().addAll(asList(RERUN_TEST_AFTER_FAILURE, 1L, null));
409         event = decoder.toMessage(BOOTERCODE_STDOUT_NEW_LINE, memento);
410         assertThat(event).isInstanceOf(StandardStreamOutWithNewLineEvent.class);
411         assertThat(((StandardStreamOutWithNewLineEvent) event).getMessage()).isNull();
412         assertThat(((StandardStreamOutWithNewLineEvent) event).getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
413         assertThat(((StandardStreamOutWithNewLineEvent) event).getTestRunId()).isEqualTo(1L);
414 
415         memento = decoder.new Memento();
416         memento.getData().addAll(asList(RERUN_TEST_AFTER_FAILURE, 1L, null));
417         event = decoder.toMessage(BOOTERCODE_STDERR, memento);
418         assertThat(event).isInstanceOf(StandardStreamErrEvent.class);
419         assertThat(((StandardStreamErrEvent) event).getMessage()).isNull();
420         assertThat(((StandardStreamErrEvent) event).getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
421         assertThat(((StandardStreamErrEvent) event).getTestRunId()).isEqualTo(1L);
422 
423         memento = decoder.new Memento();
424         memento.getData().addAll(asList(NORMAL_RUN, 1L, "abc"));
425         event = decoder.toMessage(BOOTERCODE_STDERR_NEW_LINE, memento);
426         assertThat(event).isInstanceOf(StandardStreamErrWithNewLineEvent.class);
427         assertThat(((StandardStreamErrWithNewLineEvent) event).getMessage()).isEqualTo("abc");
428         assertThat(((StandardStreamErrWithNewLineEvent) event).getRunMode()).isEqualTo(NORMAL_RUN);
429         assertThat(((StandardStreamErrWithNewLineEvent) event).getTestRunId()).isEqualTo(1L);
430 
431         memento = decoder.new Memento();
432         memento.getData().addAll(asList(NORMAL_RUN, 1L, "key", "value"));
433         event = decoder.toMessage(BOOTERCODE_SYSPROPS, memento);
434         assertThat(event).isInstanceOf(SystemPropertyEvent.class);
435         assertThat(((SystemPropertyEvent) event).getRunMode()).isEqualTo(NORMAL_RUN);
436         assertThat(((SystemPropertyEvent) event).getTestRunId()).isEqualTo(1L);
437         assertThat(((SystemPropertyEvent) event).getKey()).isEqualTo("key");
438         assertThat(((SystemPropertyEvent) event).getValue()).isEqualTo("value");
439 
440         memento = decoder.new Memento();
441         memento.getData()
442                 .addAll(asList(
443                         NORMAL_RUN,
444                         1L,
445                         "source",
446                         "sourceText",
447                         "name",
448                         "nameText",
449                         "group",
450                         "message",
451                         5,
452                         "traceMessage",
453                         "smartTrimmedStackTrace",
454                         "stackTrace"));
455         event = decoder.toMessage(BOOTERCODE_TESTSET_STARTING, memento);
456         assertThat(event).isInstanceOf(TestsetStartingEvent.class);
457         assertThat(((TestsetStartingEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
458         assertThat(((TestsetStartingEvent) event).getReportEntry().getTestRunId())
459                 .isEqualTo(1L);
460         assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceName())
461                 .isEqualTo("source");
462         assertThat(((TestsetStartingEvent) event).getReportEntry().getSourceText())
463                 .isEqualTo("sourceText");
464         assertThat(((TestsetStartingEvent) event).getReportEntry().getName()).isEqualTo("name");
465         assertThat(((TestsetStartingEvent) event).getReportEntry().getNameText())
466                 .isEqualTo("nameText");
467         assertThat(((TestsetStartingEvent) event).getReportEntry().getGroup()).isEqualTo("group");
468         assertThat(((TestsetStartingEvent) event).getReportEntry().getMessage()).isEqualTo("message");
469         assertThat(((TestsetStartingEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
470         assertThat(((TestsetStartingEvent) event)
471                         .getReportEntry()
472                         .getStackTraceWriter()
473                         .getThrowable()
474                         .getLocalizedMessage())
475                 .isEqualTo("traceMessage");
476         assertThat(((TestsetStartingEvent) event)
477                         .getReportEntry()
478                         .getStackTraceWriter()
479                         .smartTrimmedStackTrace())
480                 .isEqualTo("smartTrimmedStackTrace");
481         assertThat(((TestsetStartingEvent) event)
482                         .getReportEntry()
483                         .getStackTraceWriter()
484                         .writeTraceToString())
485                 .isEqualTo("stackTrace");
486 
487         memento = decoder.new Memento();
488         memento.getData()
489                 .addAll(asList(
490                         NORMAL_RUN,
491                         1L,
492                         "source",
493                         "sourceText",
494                         "name",
495                         "nameText",
496                         "group",
497                         null,
498                         5,
499                         "traceMessage",
500                         "smartTrimmedStackTrace",
501                         "stackTrace"));
502         event = decoder.toMessage(BOOTERCODE_TESTSET_COMPLETED, memento);
503         assertThat(event).isInstanceOf(TestsetCompletedEvent.class);
504         assertThat(((TestsetCompletedEvent) event).getReportEntry().getRunMode())
505                 .isEqualTo(NORMAL_RUN);
506         assertThat(((TestsetCompletedEvent) event).getReportEntry().getTestRunId())
507                 .isEqualTo(1L);
508         assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceName())
509                 .isEqualTo("source");
510         assertThat(((TestsetCompletedEvent) event).getReportEntry().getSourceText())
511                 .isEqualTo("sourceText");
512         assertThat(((TestsetCompletedEvent) event).getReportEntry().getName()).isEqualTo("name");
513         assertThat(((TestsetCompletedEvent) event).getReportEntry().getNameText())
514                 .isEqualTo("nameText");
515         assertThat(((TestsetCompletedEvent) event).getReportEntry().getGroup()).isEqualTo("group");
516         assertThat(((TestsetCompletedEvent) event).getReportEntry().getMessage())
517                 .isNull();
518         assertThat(((TestsetCompletedEvent) event).getReportEntry().getElapsed())
519                 .isEqualTo(5);
520         assertThat(((TestsetCompletedEvent) event)
521                         .getReportEntry()
522                         .getStackTraceWriter()
523                         .getThrowable()
524                         .getLocalizedMessage())
525                 .isEqualTo("traceMessage");
526         assertThat(((TestsetCompletedEvent) event)
527                         .getReportEntry()
528                         .getStackTraceWriter()
529                         .smartTrimmedStackTrace())
530                 .isEqualTo("smartTrimmedStackTrace");
531         assertThat(((TestsetCompletedEvent) event)
532                         .getReportEntry()
533                         .getStackTraceWriter()
534                         .writeTraceToString())
535                 .isEqualTo("stackTrace");
536 
537         memento = decoder.new Memento();
538         memento.getData()
539                 .addAll(asList(
540                         NORMAL_RUN,
541                         1L,
542                         "source",
543                         "sourceText",
544                         "name",
545                         "nameText",
546                         "group",
547                         "message",
548                         5,
549                         null,
550                         "smartTrimmedStackTrace",
551                         "stackTrace"));
552         event = decoder.toMessage(BOOTERCODE_TEST_STARTING, memento);
553         assertThat(event).isInstanceOf(TestStartingEvent.class);
554         assertThat(((TestStartingEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
555         assertThat(((TestStartingEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
556         assertThat(((TestStartingEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
557         assertThat(((TestStartingEvent) event).getReportEntry().getSourceText()).isEqualTo("sourceText");
558         assertThat(((TestStartingEvent) event).getReportEntry().getName()).isEqualTo("name");
559         assertThat(((TestStartingEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
560         assertThat(((TestStartingEvent) event).getReportEntry().getGroup()).isEqualTo("group");
561         assertThat(((TestStartingEvent) event).getReportEntry().getMessage()).isEqualTo("message");
562         assertThat(((TestStartingEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
563         assertThat(((TestStartingEvent) event)
564                         .getReportEntry()
565                         .getStackTraceWriter()
566                         .getThrowable()
567                         .getLocalizedMessage())
568                 .isNull();
569         assertThat(((TestStartingEvent) event)
570                         .getReportEntry()
571                         .getStackTraceWriter()
572                         .smartTrimmedStackTrace())
573                 .isEqualTo("smartTrimmedStackTrace");
574         assertThat(((TestStartingEvent) event)
575                         .getReportEntry()
576                         .getStackTraceWriter()
577                         .writeTraceToString())
578                 .isEqualTo("stackTrace");
579 
580         memento = decoder.new Memento();
581         memento.getData()
582                 .addAll(asList(
583                         NORMAL_RUN,
584                         1L,
585                         "source",
586                         "sourceText",
587                         "name",
588                         "nameText",
589                         "group",
590                         "message",
591                         5,
592                         null,
593                         null,
594                         null));
595         event = decoder.toMessage(BOOTERCODE_TEST_SUCCEEDED, memento);
596         assertThat(event).isInstanceOf(TestSucceededEvent.class);
597         assertThat(((TestSucceededEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
598         assertThat(((TestSucceededEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
599         assertThat(((TestSucceededEvent) event).getReportEntry().getSourceName())
600                 .isEqualTo("source");
601         assertThat(((TestSucceededEvent) event).getReportEntry().getSourceText())
602                 .isEqualTo("sourceText");
603         assertThat(((TestSucceededEvent) event).getReportEntry().getName()).isEqualTo("name");
604         assertThat(((TestSucceededEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
605         assertThat(((TestSucceededEvent) event).getReportEntry().getGroup()).isEqualTo("group");
606         assertThat(((TestSucceededEvent) event).getReportEntry().getMessage()).isEqualTo("message");
607         assertThat(((TestSucceededEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
608         assertThat(((TestSucceededEvent) event).getReportEntry().getStackTraceWriter())
609                 .isNull();
610 
611         memento = decoder.new Memento();
612         memento.getData()
613                 .addAll(asList(
614                         RERUN_TEST_AFTER_FAILURE,
615                         1L,
616                         "source",
617                         null,
618                         "name",
619                         null,
620                         "group",
621                         null,
622                         5,
623                         "traceMessage",
624                         "smartTrimmedStackTrace",
625                         "stackTrace"));
626         event = decoder.toMessage(BOOTERCODE_TEST_FAILED, memento);
627         assertThat(event).isInstanceOf(TestFailedEvent.class);
628         assertThat(((TestFailedEvent) event).getReportEntry().getRunMode()).isEqualTo(RERUN_TEST_AFTER_FAILURE);
629         assertThat(((TestFailedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
630         assertThat(((TestFailedEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
631         assertThat(((TestFailedEvent) event).getReportEntry().getSourceText()).isNull();
632         assertThat(((TestFailedEvent) event).getReportEntry().getName()).isEqualTo("name");
633         assertThat(((TestFailedEvent) event).getReportEntry().getNameText()).isNull();
634         assertThat(((TestFailedEvent) event).getReportEntry().getGroup()).isEqualTo("group");
635         assertThat(((TestFailedEvent) event).getReportEntry().getMessage()).isNull();
636         assertThat(((TestFailedEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
637         assertThat(((TestFailedEvent) event)
638                         .getReportEntry()
639                         .getStackTraceWriter()
640                         .getThrowable()
641                         .getLocalizedMessage())
642                 .isEqualTo("traceMessage");
643         assertThat(((TestFailedEvent) event)
644                         .getReportEntry()
645                         .getStackTraceWriter()
646                         .smartTrimmedStackTrace())
647                 .isEqualTo("smartTrimmedStackTrace");
648         assertThat(((TestFailedEvent) event)
649                         .getReportEntry()
650                         .getStackTraceWriter()
651                         .writeTraceToString())
652                 .isEqualTo("stackTrace");
653 
654         memento = decoder.new Memento();
655         memento.getData()
656                 .addAll(asList(NORMAL_RUN, 1L, "source", null, "name", null, null, null, 5, null, null, "stackTrace"));
657         event = decoder.toMessage(BOOTERCODE_TEST_SKIPPED, memento);
658         assertThat(event).isInstanceOf(TestSkippedEvent.class);
659         assertThat(((TestSkippedEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
660         assertThat(((TestSkippedEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
661         assertThat(((TestSkippedEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
662         assertThat(((TestSkippedEvent) event).getReportEntry().getSourceText()).isNull();
663         assertThat(((TestSkippedEvent) event).getReportEntry().getName()).isEqualTo("name");
664         assertThat(((TestSkippedEvent) event).getReportEntry().getNameText()).isNull();
665         assertThat(((TestSkippedEvent) event).getReportEntry().getGroup()).isNull();
666         assertThat(((TestSkippedEvent) event).getReportEntry().getMessage()).isNull();
667         assertThat(((TestSkippedEvent) event).getReportEntry().getElapsed()).isEqualTo(5);
668         assertThat(((TestSkippedEvent) event)
669                         .getReportEntry()
670                         .getStackTraceWriter()
671                         .getThrowable()
672                         .getLocalizedMessage())
673                 .isNull();
674         assertThat(((TestSkippedEvent) event)
675                         .getReportEntry()
676                         .getStackTraceWriter()
677                         .smartTrimmedStackTrace())
678                 .isNull();
679         assertThat(((TestSkippedEvent) event)
680                         .getReportEntry()
681                         .getStackTraceWriter()
682                         .writeTraceToString())
683                 .isEqualTo("stackTrace");
684 
685         memento = decoder.new Memento();
686         memento.getData()
687                 .addAll(asList(
688                         NORMAL_RUN, 1L, "source", null, "name", "nameText", null, null, 0, null, null, "stackTrace"));
689         event = decoder.toMessage(BOOTERCODE_TEST_ERROR, memento);
690         assertThat(event).isInstanceOf(TestErrorEvent.class);
691         assertThat(((TestErrorEvent) event).getReportEntry().getRunMode()).isEqualTo(NORMAL_RUN);
692         assertThat(((TestErrorEvent) event).getReportEntry().getTestRunId()).isEqualTo(1L);
693         assertThat(((TestErrorEvent) event).getReportEntry().getSourceName()).isEqualTo("source");
694         assertThat(((TestErrorEvent) event).getReportEntry().getSourceText()).isNull();
695         assertThat(((TestErrorEvent) event).getReportEntry().getName()).isEqualTo("name");
696         assertThat(((TestErrorEvent) event).getReportEntry().getNameText()).isEqualTo("nameText");
697         assertThat(((TestErrorEvent) event).getReportEntry().getGroup()).isNull();
698         assertThat(((TestErrorEvent) event).getReportEntry().getMessage()).isNull();
699         assertThat(((TestErrorEvent) event).getReportEntry().getElapsed()).isZero();
700         assertThat(((TestErrorEvent) event)
701                         .getReportEntry()
702                         .getStackTraceWriter()
703                         .getThrowable()
704                         .getLocalizedMessage())
705                 .isNull();
706         assertThat(((TestErrorEvent) event)
707                         .getReportEntry()
708                         .getStackTraceWriter()
709                         .smartTrimmedStackTrace())
710                 .isNull();
711         assertThat(((TestErrorEvent) event)
712                         .getReportEntry()
713                         .getStackTraceWriter()
714                         .writeTraceToString())
715                 .isEqualTo("stackTrace");
716 
717         memento = decoder.new Memento();
718         memento.getData()
719                 .addAll(asList(
720                         NORMAL_RUN, 1L, "source", null, "name", null, "group", null, 5, null, null, "stackTrace"));
721         event = decoder.toMessage(BOOTERCODE_TEST_ASSUMPTIONFAILURE, memento);
722         assertThat(event).isInstanceOf(TestAssumptionFailureEvent.class);
723         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getRunMode())
724                 .isEqualTo(NORMAL_RUN);
725         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getTestRunId())
726                 .isEqualTo(1L);
727         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceName())
728                 .isEqualTo("source");
729         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getSourceText())
730                 .isNull();
731         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getName())
732                 .isEqualTo("name");
733         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getNameText())
734                 .isNull();
735         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getGroup())
736                 .isEqualTo("group");
737         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getMessage())
738                 .isNull();
739         assertThat(((TestAssumptionFailureEvent) event).getReportEntry().getElapsed())
740                 .isEqualTo(5);
741         assertThat(((TestAssumptionFailureEvent) event)
742                         .getReportEntry()
743                         .getStackTraceWriter()
744                         .getThrowable()
745                         .getLocalizedMessage())
746                 .isNull();
747         assertThat(((TestAssumptionFailureEvent) event)
748                         .getReportEntry()
749                         .getStackTraceWriter()
750                         .smartTrimmedStackTrace())
751                 .isNull();
752         assertThat(((TestAssumptionFailureEvent) event)
753                         .getReportEntry()
754                         .getStackTraceWriter()
755                         .writeTraceToString())
756                 .isEqualTo("stackTrace");
757     }
758 
759     @Test
760     public void shouldRecognizeEmptyStream4ReportEntry() {
761         ReportEntry reportEntry = newReportEntry(NORMAL_RUN, 1L, "", "", "", "", "", "", null, "", "", "");
762         assertThat(reportEntry).isNotNull();
763         assertThat(reportEntry.getRunMode()).isEqualTo(NORMAL_RUN);
764         assertThat(reportEntry.getTestRunId()).isEqualTo(1L);
765         assertThat(reportEntry.getStackTraceWriter()).isNotNull();
766         assertThat(reportEntry.getStackTraceWriter().smartTrimmedStackTrace()).isEmpty();
767         assertThat(reportEntry.getStackTraceWriter().writeTraceToString()).isEmpty();
768         assertThat(reportEntry.getStackTraceWriter().writeTrimmedTraceToString())
769                 .isEmpty();
770         assertThat(reportEntry.getSourceName()).isEmpty();
771         assertThat(reportEntry.getSourceText()).isEmpty();
772         assertThat(reportEntry.getName()).isEmpty();
773         assertThat(reportEntry.getNameText()).isEmpty();
774         assertThat(reportEntry.getGroup()).isEmpty();
775         assertThat(reportEntry.getNameWithGroup()).isEmpty();
776         assertThat(reportEntry.getMessage()).isEmpty();
777         assertThat(reportEntry.getElapsed()).isNull();
778     }
779 
780     @Test
781     @SuppressWarnings("checkstyle:magicnumber")
782     public void testCreatingReportEntry() {
783         final String exceptionMessage = "msg";
784         final String smartStackTrace = "MyTest:86 >> Error";
785         final String stackTrace = "Exception: msg\ntrace line 1\ntrace line 2";
786         final String trimmedStackTrace = "trace line 1\ntrace line 2";
787 
788         SafeThrowable safeThrowable = new SafeThrowable(exceptionMessage);
789         StackTraceWriter stackTraceWriter = mock(StackTraceWriter.class);
790         when(stackTraceWriter.getThrowable()).thenReturn(safeThrowable);
791         when(stackTraceWriter.smartTrimmedStackTrace()).thenReturn(smartStackTrace);
792         when(stackTraceWriter.writeTrimmedTraceToString()).thenReturn(trimmedStackTrace);
793         when(stackTraceWriter.writeTraceToString()).thenReturn(stackTrace);
794 
795         ReportEntry reportEntry = mock(ReportEntry.class);
796         when(reportEntry.getElapsed()).thenReturn(102);
797         when(reportEntry.getGroup()).thenReturn("this group");
798         when(reportEntry.getMessage()).thenReturn("skipped test");
799         when(reportEntry.getName()).thenReturn("my test");
800         when(reportEntry.getNameText()).thenReturn("my display name");
801         when(reportEntry.getNameWithGroup()).thenReturn("name with group");
802         when(reportEntry.getSourceName()).thenReturn("pkg.MyTest");
803         when(reportEntry.getSourceText()).thenReturn("test class display name");
804         when(reportEntry.getStackTraceWriter()).thenReturn(stackTraceWriter);
805 
806         ReportEntry decodedReportEntry = newReportEntry(
807                 NORMAL_RUN,
808                 1L,
809                 reportEntry.getSourceName(),
810                 reportEntry.getSourceText(),
811                 reportEntry.getName(),
812                 reportEntry.getNameText(),
813                 reportEntry.getGroup(),
814                 reportEntry.getMessage(),
815                 null,
816                 null,
817                 null,
818                 null);
819 
820         assertThat(decodedReportEntry).isNotNull();
821         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
822         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
823         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
824         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
825         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
826         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
827         assertThat(decodedReportEntry.getStackTraceWriter()).isNull();
828 
829         decodedReportEntry = newReportEntry(
830                 NORMAL_RUN,
831                 1L,
832                 reportEntry.getSourceName(),
833                 reportEntry.getSourceText(),
834                 reportEntry.getName(),
835                 reportEntry.getNameText(),
836                 reportEntry.getGroup(),
837                 reportEntry.getMessage(),
838                 null,
839                 exceptionMessage,
840                 smartStackTrace,
841                 null);
842 
843         assertThat(decodedReportEntry).isNotNull();
844         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
845         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
846         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
847         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
848         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
849         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
850         assertThat(decodedReportEntry.getElapsed()).isNull();
851         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
852         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
853                 .isEqualTo(exceptionMessage);
854         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
855                 .isEqualTo(smartStackTrace);
856         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
857                 .isNull();
858 
859         decodedReportEntry = newReportEntry(
860                 NORMAL_RUN,
861                 1L,
862                 reportEntry.getSourceName(),
863                 reportEntry.getSourceText(),
864                 reportEntry.getName(),
865                 reportEntry.getNameText(),
866                 reportEntry.getGroup(),
867                 reportEntry.getMessage(),
868                 1003,
869                 exceptionMessage,
870                 smartStackTrace,
871                 null);
872 
873         assertThat(decodedReportEntry).isNotNull();
874         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
875         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
876         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
877         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
878         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
879         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
880         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
881         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
882         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
883                 .isEqualTo(exceptionMessage);
884         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
885                 .isEqualTo(smartStackTrace);
886         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
887                 .isNull();
888 
889         decodedReportEntry = newReportEntry(
890                 NORMAL_RUN,
891                 1L,
892                 reportEntry.getSourceName(),
893                 reportEntry.getSourceText(),
894                 reportEntry.getName(),
895                 reportEntry.getNameText(),
896                 reportEntry.getGroup(),
897                 reportEntry.getMessage(),
898                 1003,
899                 exceptionMessage,
900                 smartStackTrace,
901                 stackTrace);
902 
903         assertThat(decodedReportEntry).isNotNull();
904         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
905         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
906         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
907         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
908         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
909         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
910         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
911         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
912         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
913                 .isNotNull();
914         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
915                 .isEqualTo(exceptionMessage);
916         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
917                 .isEqualTo(smartStackTrace);
918         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
919                 .isEqualTo(stackTrace);
920         assertThat(decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString())
921                 .isEqualTo(stackTrace);
922 
923         decodedReportEntry = newReportEntry(
924                 NORMAL_RUN,
925                 1L,
926                 reportEntry.getSourceName(),
927                 reportEntry.getSourceText(),
928                 reportEntry.getName(),
929                 reportEntry.getNameText(),
930                 reportEntry.getGroup(),
931                 reportEntry.getMessage(),
932                 1003,
933                 exceptionMessage,
934                 smartStackTrace,
935                 trimmedStackTrace);
936 
937         assertThat(decodedReportEntry).isNotNull();
938         assertThat(decodedReportEntry.getSourceName()).isEqualTo(reportEntry.getSourceName());
939         assertThat(decodedReportEntry.getSourceText()).isEqualTo(reportEntry.getSourceText());
940         assertThat(decodedReportEntry.getName()).isEqualTo(reportEntry.getName());
941         assertThat(decodedReportEntry.getNameText()).isEqualTo(reportEntry.getNameText());
942         assertThat(decodedReportEntry.getGroup()).isEqualTo(reportEntry.getGroup());
943         assertThat(decodedReportEntry.getMessage()).isEqualTo(reportEntry.getMessage());
944         assertThat(decodedReportEntry.getElapsed()).isEqualTo(1003);
945         assertThat(decodedReportEntry.getStackTraceWriter()).isNotNull();
946         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
947                 .isNotNull();
948         assertThat(decodedReportEntry.getStackTraceWriter().getThrowable().getMessage())
949                 .isEqualTo(exceptionMessage);
950         assertThat(decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace())
951                 .isEqualTo(smartStackTrace);
952         assertThat(decodedReportEntry.getStackTraceWriter().writeTraceToString())
953                 .isEqualTo(trimmedStackTrace);
954         assertThat(decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString())
955                 .isEqualTo(trimmedStackTrace);
956     }
957 
958     private static class Channel implements ReadableByteChannel {
959         private final byte[] bytes;
960         private final int chunkSize;
961         protected int i;
962 
963         Channel(byte[] bytes, int chunkSize) {
964             this.bytes = bytes;
965             this.chunkSize = chunkSize;
966         }
967 
968         @Override
969         public int read(ByteBuffer dst) {
970             if (i == bytes.length) {
971                 return -1;
972             } else if (dst.hasRemaining()) {
973                 int length = min(min(chunkSize, bytes.length - i), dst.remaining());
974                 dst.put(bytes, i, length);
975                 i += length;
976                 return length;
977             } else {
978                 return 0;
979             }
980         }
981 
982         @Override
983         public boolean isOpen() {
984             return false;
985         }
986 
987         @Override
988         public void close() {}
989     }
990 
991     private static class MockForkNodeArguments implements ForkNodeArguments {
992         @Nonnull
993         @Override
994         public String getSessionId() {
995             return null;
996         }
997 
998         @Override
999         public int getForkChannelId() {
1000             return 0;
1001         }
1002 
1003         @Nonnull
1004         @Override
1005         public File dumpStreamText(@Nonnull String text) {
1006             return null;
1007         }
1008 
1009         @Nonnull
1010         @Override
1011         public File dumpStreamException(@Nonnull Throwable t) {
1012             return null;
1013         }
1014 
1015         @Override
1016         public void logWarningAtEnd(@Nonnull String text) {}
1017 
1018         @Nonnull
1019         @Override
1020         public ConsoleLogger getConsoleLogger() {
1021             return null;
1022         }
1023 
1024         @Nonnull
1025         @Override
1026         public Object getConsoleLock() {
1027             return new Object();
1028         }
1029 
1030         @Override
1031         public File getEventStreamBinaryFile() {
1032             return null;
1033         }
1034 
1035         @Override
1036         public File getCommandStreamBinaryFile() {
1037             return null;
1038         }
1039     }
1040 }