View Javadoc
1   package org.apache.maven.surefire.booter.spi;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.api.report.ReportEntry;
23  import org.apache.maven.surefire.api.report.SafeThrowable;
24  import org.apache.maven.surefire.api.report.StackTraceWriter;
25  import org.apache.maven.surefire.api.util.internal.ObjectUtils;
26  import org.apache.maven.surefire.api.util.internal.WritableBufferedByteChannel;
27  import org.junit.Test;
28  
29  import java.io.ByteArrayOutputStream;
30  import java.io.IOException;
31  import java.io.LineNumberReader;
32  import java.io.PrintStream;
33  import java.io.StringReader;
34  import java.nio.ByteBuffer;
35  import java.nio.charset.Charset;
36  import java.util.Map;
37  
38  import static java.nio.charset.StandardCharsets.UTF_8;
39  import static java.util.Arrays.copyOfRange;
40  import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedChannel;
41  import static org.apache.maven.surefire.shared.codec.binary.Base64.encodeBase64String;
42  import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encode;
43  import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeHeader;
44  import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeMessage;
45  import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeOpcode;
46  import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.toBase64;
47  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTERCODE_SYSPROPS;
48  import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.MAGIC_NUMBER;
49  import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
50  import static org.fest.assertions.Assertions.assertThat;
51  import static org.mockito.Mockito.mock;
52  import static org.mockito.Mockito.when;
53  
54  /**
55   * Test for {@link LegacyMasterProcessChannelEncoder}.
56   *
57   * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
58   * @since 3.0.0-M4
59   */
60  public class LegacyMasterProcessChannelEncoderTest
61  {
62      private static final int ELAPSED_TIME = 102;
63  
64      @Test
65      public void shouldBeFailSafe()
66      {
67          assertThat( toBase64( null ) ).isEqualTo( "-" );
68          assertThat( toBase64( "" ) ).isEqualTo( "" );
69      }
70  
71      @Test
72      public void shouldHaveSystemProperty()
73      {
74          StringBuilder actualEncoded = encode( BOOTERCODE_SYSPROPS, NORMAL_RUN, "arg1", "arg2" );
75          String expected = ':' + MAGIC_NUMBER + ':' + BOOTERCODE_SYSPROPS.getOpcode()
76              + ":normal-run:UTF-8:YXJnMQ==:YXJnMg==:";
77  
78          assertThat( actualEncoded.toString() )
79                  .isEqualTo( expected );
80      }
81  
82      @Test
83      public void safeThrowableShouldBeEncoded()
84      {
85          final String exceptionMessage = "msg";
86          final String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
87  
88          final String smartStackTrace = "MyTest:86 >> Error";
89          final String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
90  
91          final String stackTrace = "trace line 1\ntrace line 2";
92          final String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
93  
94          final String trimmedStackTrace = "trace line 1\ntrace line 2";
95          final String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
96  
97          SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
98          StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
99          when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
100         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
101         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
102         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
103 
104         StringBuilder encoded = new StringBuilder();
105         encode( encoded, stackTraceWriter, false );
106         assertThat( encoded.toString() )
107                 .isEqualTo( encodedExceptionMsg
108                     + ":" + encodedSmartStackTrace + ":" + encodedStackTrace + ":" );
109 
110         encoded = new StringBuilder();
111         encode( encoded, stackTraceWriter, true );
112         assertThat( encoded.toString() )
113                 .isEqualTo( encodedExceptionMsg
114                     + ":" + encodedSmartStackTrace + ":" + encodedTrimmedStackTrace + ":" );
115     }
116 
117     @Test
118     public void emptySafeThrowable()
119     {
120         SafeThrowable safeThrowable = new SafeThrowable( new Exception( "" ) );
121 
122         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
123         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
124         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "" );
125         when( stackTraceWriter.writeTraceToString() ).thenReturn( "" );
126 
127         StringBuilder encoded = new StringBuilder();
128         encode( encoded, stackTraceWriter, false );
129 
130         assertThat( encoded.toString() )
131                 .isEqualTo( ":::" );
132     }
133 
134     @Test
135     public void nullSafeThrowable()
136     {
137         SafeThrowable safeThrowable = new SafeThrowable( new Exception() );
138 
139         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
140         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
141 
142         StringBuilder encoded = new StringBuilder();
143         encode( encoded, stackTraceWriter, false );
144 
145         assertThat( encoded.toString() )
146                 .isEqualTo( "-:-:-:" );
147     }
148 
149     @Test
150     public void reportEntry() throws IOException
151     {
152         final String exceptionMessage = "msg";
153         final String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
154 
155         final String smartStackTrace = "MyTest:86 >> Error";
156         final String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
157 
158         final String stackTrace = "trace line 1\ntrace line 2";
159         final String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
160 
161         final String trimmedStackTrace = "trace line 1\ntrace line 2";
162         final String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
163 
164         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
165         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
166         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
167         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
168         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
169         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
170 
171 
172         ReportEntry reportEntry = mock( ReportEntry.class );
173         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
174         when( reportEntry.getGroup() ).thenReturn( "this group" );
175         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
176         when( reportEntry.getName() ).thenReturn( "my test" );
177         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
178         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
179         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
180 
181         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
182         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
183         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
184         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
185 
186         StringBuilder encode = encode( "X", "normal-run", reportEntry, false );
187         assertThat( encode.toString() )
188                 .isEqualTo( ":maven-surefire-event:X:normal-run:UTF-8:"
189                                 + encodedSourceName
190                                 + ":"
191                                 + "-"
192                                 + ":"
193                                 + encodedName
194                                 + ":"
195                                 + "-"
196                                 + ":"
197                                 + encodedGroup
198                                 + ":"
199                                 + encodedMessage
200                                 + ":"
201                                 + ELAPSED_TIME
202                                 + ":"
203 
204                                 + encodedExceptionMsg
205                                 + ":"
206                                 + encodedSmartStackTrace
207                                 + ":"
208                                 + encodedStackTrace
209                                 + ":"
210                 );
211 
212         encode = encode( "X", "normal-run", reportEntry, true );
213         assertThat( encode.toString() )
214                 .isEqualTo( ":maven-surefire-event:X:normal-run:UTF-8:"
215                                 + encodedSourceName
216                                 + ":"
217                                 + "-"
218                                 + ":"
219                                 + encodedName
220                                 + ":"
221                                 + "-"
222                                 + ":"
223                                 + encodedGroup
224                                 + ":"
225                                 + encodedMessage
226                                 + ":"
227                                 + ELAPSED_TIME
228                                 + ":"
229 
230                                 + encodedExceptionMsg
231                                 + ":"
232                                 + encodedSmartStackTrace
233                                 + ":"
234                                 + encodedTrimmedStackTrace
235                                 + ":"
236                 );
237 
238         Stream out = Stream.newStream();
239         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
240 
241         encoder.testSetStarting( reportEntry, true );
242         LineNumberReader printedLines = out.newReader( UTF_8 );
243         assertThat( printedLines.readLine() )
244                 .isEqualTo( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
245                                     + encodedSourceName
246                                     + ":"
247                                     + "-"
248                                     + ":"
249                                     + encodedName
250                                     + ":"
251                                     + "-"
252                                     + ":"
253                                     + encodedGroup
254                                     + ":"
255                                     + encodedMessage
256                                     + ":"
257                                     + ELAPSED_TIME
258                                     + ":"
259 
260                                     + encodedExceptionMsg
261                                     + ":"
262                                     + encodedSmartStackTrace
263                                     + ":"
264                                     + encodedTrimmedStackTrace
265                                     + ":"
266                 );
267         assertThat( printedLines.readLine() ).isNull();
268 
269         out = Stream.newStream();
270         encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
271 
272         encoder.testSetStarting( reportEntry, false );
273         printedLines = out.newReader( UTF_8 );
274         assertThat( printedLines.readLine() )
275                 .isEqualTo( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
276                                     + encodedSourceName
277                                     + ":"
278                                     + "-"
279                                     + ":"
280                                     + encodedName
281                                     + ":"
282                                     + "-"
283                                     + ":"
284                                     + encodedGroup
285                                     + ":"
286                                     + encodedMessage
287                                     + ":"
288                                     + ELAPSED_TIME
289                                     + ":"
290 
291                                     + encodedExceptionMsg
292                                     + ":"
293                                     + encodedSmartStackTrace
294                                     + ":"
295                                     + encodedStackTrace
296                                     + ":"
297                 );
298         assertThat( printedLines.readLine() ).isNull();
299     }
300 
301     @Test
302     public void testSetCompleted() throws IOException
303     {
304         String exceptionMessage = "msg";
305         String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
306 
307         String smartStackTrace = "MyTest:86 >> Error";
308         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
309 
310         String stackTrace = "trace line 1\ntrace line 2";
311         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
312 
313         String trimmedStackTrace = "trace line 1\ntrace line 2";
314         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
315 
316         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
317         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
318         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
319         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
320         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
321         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
322 
323         ReportEntry reportEntry = mock( ReportEntry.class );
324         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
325         when( reportEntry.getGroup() ).thenReturn( "this group" );
326         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
327         when( reportEntry.getName() ).thenReturn( "my test" );
328         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
329         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
330         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
331 
332         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
333         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
334         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
335         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
336 
337         Stream out = Stream.newStream();
338         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
339 
340         encoder.testSetCompleted( reportEntry, false );
341         LineNumberReader printedLines = out.newReader( UTF_8 );
342         assertThat( printedLines.readLine() )
343                 .isEqualTo( ":maven-surefire-event:testset-completed:normal-run:UTF-8:"
344                         + encodedSourceName
345                         + ":"
346                         + "-"
347                         + ":"
348                         + encodedName
349                         + ":"
350                         + "-"
351                         + ":"
352                         + encodedGroup
353                         + ":"
354                         + encodedMessage
355                         + ":"
356                         + ELAPSED_TIME
357                         + ":"
358 
359                         + encodedExceptionMsg
360                         + ":"
361                         + encodedSmartStackTrace
362                         + ":"
363                         + encodedStackTrace
364                         + ":"
365                 );
366         assertThat( printedLines.readLine() ).isNull();
367     }
368 
369     @Test
370     public void testStarting() throws IOException
371     {
372         String exceptionMessage = "msg";
373         String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
374 
375         String smartStackTrace = "MyTest:86 >> Error";
376         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
377 
378         String stackTrace = "trace line 1\ntrace line 2";
379         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
380 
381         String trimmedStackTrace = "trace line 1\ntrace line 2";
382         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
383 
384         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
385         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
386         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
387         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
388         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
389         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
390 
391         ReportEntry reportEntry = mock( ReportEntry.class );
392         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
393         when( reportEntry.getGroup() ).thenReturn( "this group" );
394         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
395         when( reportEntry.getName() ).thenReturn( "my test" );
396         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
397         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
398         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
399 
400         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
401         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
402         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
403         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
404 
405         Stream out = Stream.newStream();
406         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
407 
408         encoder.testStarting( reportEntry, true );
409         LineNumberReader printedLines = out.newReader( UTF_8 );
410         assertThat( printedLines.readLine() )
411                 .isEqualTo( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
412                         + encodedSourceName
413                         + ":"
414                         + "-"
415                         + ":"
416                         + encodedName
417                         + ":"
418                         + "-"
419                         + ":"
420                         + encodedGroup
421                         + ":"
422                         + encodedMessage
423                         + ":"
424                         + ELAPSED_TIME
425                         + ":"
426 
427                         + encodedExceptionMsg
428                         + ":"
429                         + encodedSmartStackTrace
430                         + ":"
431                         + encodedTrimmedStackTrace
432                         + ":"
433                 );
434         assertThat( printedLines.readLine() ).isNull();
435     }
436 
437     @Test
438     public void testSuccess() throws IOException
439     {
440         String exceptionMessage = "msg";
441         String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
442 
443         String smartStackTrace = "MyTest:86 >> Error";
444         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
445 
446         String stackTrace = "trace line 1\ntrace line 2";
447         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
448 
449         String trimmedStackTrace = "trace line 1\ntrace line 2";
450         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
451 
452         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
453         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
454         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
455         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
456         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
457         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
458 
459         ReportEntry reportEntry = mock( ReportEntry.class );
460         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
461         when( reportEntry.getGroup() ).thenReturn( "this group" );
462         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
463         when( reportEntry.getName() ).thenReturn( "my test" );
464         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
465         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
466         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
467 
468         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
469         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
470         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
471         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
472 
473         Stream out = Stream.newStream();
474         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
475 
476         encoder.testSucceeded( reportEntry, true );
477         LineNumberReader printedLines = out.newReader( UTF_8 );
478         assertThat( printedLines.readLine() )
479                 .isEqualTo( ":maven-surefire-event:test-succeeded:normal-run:UTF-8:"
480                         + encodedSourceName
481                         + ":"
482                         + "-"
483                         + ":"
484                         + encodedName
485                         + ":"
486                         + "-"
487                         + ":"
488                         + encodedGroup
489                         + ":"
490                         + encodedMessage
491                         + ":"
492                         + ELAPSED_TIME
493                         + ":"
494 
495                         + encodedExceptionMsg
496                         + ":"
497                         + encodedSmartStackTrace
498                         + ":"
499                         + encodedTrimmedStackTrace
500                         + ":"
501                 );
502         assertThat( printedLines.readLine() ).isNull();
503     }
504 
505     @Test
506     public void testFailed() throws IOException
507     {
508         String exceptionMessage = "msg";
509         String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
510 
511         String smartStackTrace = "MyTest:86 >> Error";
512         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
513 
514         String stackTrace = "trace line 1\ntrace line 2";
515         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
516 
517         String trimmedStackTrace = "trace line 1\ntrace line 2";
518         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
519 
520         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
521         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
522         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
523         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
524         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
525         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
526 
527         ReportEntry reportEntry = mock( ReportEntry.class );
528         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
529         when( reportEntry.getGroup() ).thenReturn( "this group" );
530         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
531         when( reportEntry.getName() ).thenReturn( "my test" );
532         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
533         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
534         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
535 
536         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
537         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
538         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
539         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
540 
541         Stream out = Stream.newStream();
542         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
543 
544         encoder.testFailed( reportEntry, false );
545         LineNumberReader printedLines = out.newReader( UTF_8 );
546         assertThat( printedLines.readLine() )
547                 .isEqualTo( ":maven-surefire-event:test-failed:normal-run:UTF-8:"
548                         + encodedSourceName
549                         + ":"
550                         + "-"
551                         + ":"
552                         + encodedName
553                         + ":"
554                         + "-"
555                         + ":"
556                         + encodedGroup
557                         + ":"
558                         + encodedMessage
559                         + ":"
560                         + ELAPSED_TIME
561                         + ":"
562 
563                         + encodedExceptionMsg
564                         + ":"
565                         + encodedSmartStackTrace
566                         + ":"
567                         + encodedStackTrace
568                         + ":"
569                 );
570         assertThat( printedLines.readLine() ).isNull();
571     }
572 
573     @Test
574     public void testSkipped() throws IOException
575     {
576         String encodedExceptionMsg = "-";
577 
578         String smartStackTrace = "MyTest:86 >> Error";
579         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
580 
581         String stackTrace = "trace line 1\ntrace line 2";
582         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
583 
584         String trimmedStackTrace = "trace line 1\ntrace line 2";
585         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
586 
587         SafeThrowable safeThrowable = new SafeThrowable( new Exception() );
588         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
589         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
590         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
591         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
592         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
593 
594         ReportEntry reportEntry = mock( ReportEntry.class );
595         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
596         when( reportEntry.getGroup() ).thenReturn( "this group" );
597         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
598         when( reportEntry.getName() ).thenReturn( "my test" );
599         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
600         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
601         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
602 
603         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
604         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
605         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
606         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
607 
608         Stream out = Stream.newStream();
609         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
610 
611         encoder.testSkipped( reportEntry, false );
612         LineNumberReader printedLines = out.newReader( UTF_8 );
613         assertThat( printedLines.readLine() )
614                 .isEqualTo( ":maven-surefire-event:test-skipped:normal-run:UTF-8:"
615                         + encodedSourceName
616                         + ":"
617                         + "-"
618                         + ":"
619                         + encodedName
620                         + ":"
621                         + "-"
622                         + ":"
623                         + encodedGroup
624                         + ":"
625                         + encodedMessage
626                         + ":"
627                         + ELAPSED_TIME
628                         + ":"
629 
630                         + encodedExceptionMsg
631                         + ":"
632                         + encodedSmartStackTrace
633                         + ":"
634                         + encodedStackTrace
635                         + ":"
636                 );
637         assertThat( printedLines.readLine() ).isNull();
638     }
639 
640     @Test
641     public void testError() throws IOException
642     {
643         String encodedExceptionMsg = "-";
644 
645         String encodedSmartStackTrace = "-";
646 
647         String stackTrace = "trace line 1\ntrace line 2";
648         String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );
649 
650         String trimmedStackTrace = "trace line 1\ntrace line 2";
651         String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );
652 
653         SafeThrowable safeThrowable = new SafeThrowable( new Exception() );
654         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
655         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
656         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( null );
657         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
658         when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );
659 
660         ReportEntry reportEntry = mock( ReportEntry.class );
661         when( reportEntry.getElapsed() ).thenReturn( ELAPSED_TIME );
662         when( reportEntry.getGroup() ).thenReturn( "this group" );
663         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
664         when( reportEntry.getName() ).thenReturn( "my test" );
665         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
666         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
667         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
668 
669         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
670         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
671         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
672         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
673 
674         Stream out = Stream.newStream();
675         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
676 
677         encoder.testError( reportEntry, false );
678         LineNumberReader printedLines = out.newReader( UTF_8 );
679         assertThat( printedLines.readLine() )
680                 .isEqualTo( ":maven-surefire-event:test-error:normal-run:UTF-8:"
681                         + encodedSourceName
682                         + ":"
683                         + "-"
684                         + ":"
685                         + encodedName
686                         + ":"
687                         + "-"
688                         + ":"
689                         + encodedGroup
690                         + ":"
691                         + encodedMessage
692                         + ":"
693                         + ELAPSED_TIME
694                         + ":"
695 
696                         + encodedExceptionMsg
697                         + ":"
698                         + encodedSmartStackTrace
699                         + ":"
700                         + encodedStackTrace
701                         + ":"
702                 );
703         assertThat( printedLines.readLine() ).isNull();
704     }
705 
706     @Test
707     public void testAssumptionFailure() throws IOException
708     {
709         String exceptionMessage = "msg";
710         String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );
711 
712         String smartStackTrace = "MyTest:86 >> Error";
713         String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );
714 
715         String encodedStackTrace = "-";
716 
717         SafeThrowable safeThrowable = new SafeThrowable( new Exception( exceptionMessage ) );
718         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
719         when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
720         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
721         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( null );
722         when( stackTraceWriter.writeTraceToString() ).thenReturn( null );
723 
724         ReportEntry reportEntry = mock( ReportEntry.class );
725         when( reportEntry.getElapsed() ).thenReturn( null );
726         when( reportEntry.getGroup() ).thenReturn( "this group" );
727         when( reportEntry.getMessage() ).thenReturn( "skipped test" );
728         when( reportEntry.getName() ).thenReturn( "my test" );
729         when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
730         when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
731         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
732 
733         String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
734         String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
735         String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
736         String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
737 
738         Stream out = Stream.newStream();
739         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
740 
741         encoder.testAssumptionFailure( reportEntry, false );
742         LineNumberReader printedLines = out.newReader( UTF_8 );
743         assertThat( printedLines.readLine() )
744                 .isEqualTo( ":maven-surefire-event:test-assumption-failure:normal-run:UTF-8:"
745                         + encodedSourceName
746                         + ":"
747                         + "-"
748                         + ":"
749                         + encodedName
750                         + ":"
751                         + "-"
752                         + ":"
753                         + encodedGroup
754                         + ":"
755                         + encodedMessage
756                         + ":"
757                         + "-"
758                         + ":"
759 
760                         + encodedExceptionMsg
761                         + ":"
762                         + encodedSmartStackTrace
763                         + ":"
764                         + encodedStackTrace
765                         + ":"
766                 );
767         assertThat( printedLines.readLine() ).isNull();
768     }
769 
770     @Test
771     public void testBye() throws IOException
772     {
773         Stream out = Stream.newStream();
774         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
775 
776         encoder.bye();
777         LineNumberReader printedLines = out.newReader( UTF_8 );
778         assertThat( printedLines.readLine() )
779                 .isEqualTo( ":maven-surefire-event:bye:" );
780         assertThat( printedLines.readLine() ).isNull();
781     }
782 
783     @Test
784     public void testStopOnNextTest() throws IOException
785     {
786         Stream out = Stream.newStream();
787         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
788 
789         encoder.stopOnNextTest();
790         LineNumberReader printedLines = out.newReader( UTF_8 );
791         assertThat( printedLines.readLine() )
792                 .isEqualTo( ":maven-surefire-event:stop-on-next-test:" );
793         assertThat( printedLines.readLine() ).isNull();
794     }
795 
796     @Test
797     public void testAcquireNextTest() throws IOException
798     {
799         Stream out = Stream.newStream();
800         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
801 
802         encoder.acquireNextTest();
803         LineNumberReader printedLines = out.newReader( UTF_8 );
804         assertThat( printedLines.readLine() )
805                 .isEqualTo( ":maven-surefire-event:next-test:" );
806         assertThat( printedLines.readLine() ).isNull();
807     }
808 
809     @Test
810     public void testSendOpcode()
811     {
812         StringBuilder encoded = encodeOpcode( "some-opcode", "normal-run" );
813         assertThat( encoded.toString() )
814                 .isEqualTo( ":maven-surefire-event:some-opcode:normal-run:" );
815 
816         encoded = encodeHeader( "some-opcode", "normal-run" );
817         assertThat( encoded.toString() )
818                 .isEqualTo( ":maven-surefire-event:some-opcode:normal-run:UTF-8:" );
819 
820         encoded = encodeMessage( "some-opcode", "normal-run", "msg" );
821         assertThat( encoded.toString() )
822                 .isEqualTo( ":maven-surefire-event:some-opcode:normal-run:UTF-8:msg:" );
823 
824         Stream out = Stream.newStream();
825         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
826         encoded = encoder.print( "some-opcode", "msg" );
827         assertThat( encoded.toString() )
828                 .isEqualTo( ":maven-surefire-event:some-opcode:UTF-8:bXNn:" );
829 
830         encoded = encoder.print( "some-opcode", new String[] { null } );
831         assertThat( encoded.toString() )
832                 .isEqualTo( ":maven-surefire-event:some-opcode:UTF-8:-:" );
833     }
834 
835     @Test
836     public void testConsoleInfo()
837     {
838         Stream out = Stream.newStream();
839         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
840 
841         encoder.consoleInfoLog( "msg" );
842 
843         String encoded = new String( out.toByteArray(), UTF_8 );
844 
845         String expected = ":maven-surefire-event:console-info-log:UTF-8:"
846                                   + encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
847                                   + ":"
848                                   + "\n";
849 
850         assertThat( encoded )
851                 .isEqualTo( expected );
852     }
853 
854     @Test
855     public void testConsoleError()
856     {
857         Stream out = Stream.newStream();
858         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
859 
860         encoder.consoleErrorLog( "msg" );
861 
862         String encoded = new String( out.toByteArray(), UTF_8 );
863 
864         String expected = ":maven-surefire-event:console-error-log:UTF-8:"
865                 + encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
866                 + ":-:-:\n";
867 
868         assertThat( encoded )
869                 .isEqualTo( expected );
870     }
871 
872     @Test
873     public void testConsoleErrorLog1() throws IOException
874     {
875         Stream out = Stream.newStream();
876         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
877 
878         encoder.consoleErrorLog( new Exception( "msg" ) );
879         LineNumberReader printedLines = out.newReader( UTF_8 );
880         assertThat( printedLines.readLine() )
881                 .startsWith( ":maven-surefire-event:console-error-log:UTF-8:bXNn:-:" );
882         assertThat( printedLines.readLine() ).isNull();
883     }
884 
885     @Test
886     public void testConsoleErrorLog2() throws IOException
887     {
888         Stream out = Stream.newStream();
889         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
890 
891         encoder.consoleErrorLog( "msg2", new Exception( "msg" ) );
892         LineNumberReader printedLines = out.newReader( UTF_8 );
893         assertThat( printedLines.readLine() )
894                 .startsWith( ":maven-surefire-event:console-error-log:UTF-8:bXNnMg==:-:" );
895         assertThat( printedLines.readLine() ).isNull();
896     }
897 
898     @Test
899     public void testConsoleErrorLog3() throws IOException
900     {
901         Stream out = Stream.newStream();
902         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
903 
904         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
905         when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
906         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
907         when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
908         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
909 
910         encoder.consoleErrorLog( stackTraceWriter, true );
911         LineNumberReader printedLines = out.newReader( UTF_8 );
912         assertThat( printedLines.readLine() )
913                 .startsWith( ":maven-surefire-event:console-error-log:UTF-8:MQ==:Mg==:NA==:" );
914         assertThat( printedLines.readLine() ).isNull();
915     }
916 
917     @Test
918     public void testConsoleDebug()
919     {
920         Stream out = Stream.newStream();
921         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
922 
923         encoder.consoleDebugLog( "msg" );
924 
925         String encoded = new String( out.toByteArray(), UTF_8 );
926 
927         String expected = ":maven-surefire-event:console-debug-log:UTF-8:"
928                                   + encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
929                                   + ":"
930                                   + "\n";
931 
932         assertThat( encoded )
933                 .isEqualTo( expected );
934     }
935 
936     @Test
937     public void testConsoleWarning()
938     {
939         Stream out = Stream.newStream();
940         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
941 
942         encoder.consoleWarningLog( "msg" );
943 
944         String encoded = new String( out.toByteArray(), UTF_8 );
945 
946         String expected = ":maven-surefire-event:console-warning-log:UTF-8:"
947                                   + encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
948                                   + ":"
949                                   + "\n";
950 
951         assertThat( encoded )
952                 .isEqualTo( expected );
953     }
954 
955     @Test
956     public void testStdOutStream() throws IOException
957     {
958         Stream out = Stream.newStream();
959         WritableBufferedByteChannel channel = newBufferedChannel( out );
960         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( channel );
961 
962         encoder.stdOut( "msg", false );
963         channel.close();
964 
965         String expected = ":maven-surefire-event:std-out-stream:normal-run:UTF-8:bXNn:";
966 
967         LineNumberReader printedLines = out.newReader( UTF_8 );
968         assertThat( printedLines.readLine() )
969                 .isEqualTo( expected );
970         assertThat( printedLines.readLine() )
971                 .isNull();
972     }
973 
974     @Test
975     public void testStdOutStreamLn() throws IOException
976     {
977         Stream out = Stream.newStream();
978         WritableBufferedByteChannel channel = newBufferedChannel( out );
979         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( channel );
980 
981         encoder.stdOut( "msg", true );
982         channel.close();
983 
984         String expected = ":maven-surefire-event:std-out-stream-new-line:normal-run:UTF-8:bXNn:";
985 
986         LineNumberReader printedLines = out.newReader( UTF_8 );
987         assertThat( printedLines.readLine() )
988                 .isEqualTo( expected );
989         assertThat( printedLines.readLine() )
990                 .isNull();
991     }
992 
993     @Test
994     public void testStdErrStream() throws IOException
995     {
996         Stream out = Stream.newStream();
997         WritableBufferedByteChannel channel = newBufferedChannel( out );
998         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( channel );
999 
1000         encoder.stdErr( "msg", false );
1001         channel.close();
1002 
1003         String expected = ":maven-surefire-event:std-err-stream:normal-run:UTF-8:bXNn:";
1004 
1005         LineNumberReader printedLines = out.newReader( UTF_8 );
1006         assertThat( printedLines.readLine() )
1007                 .isEqualTo( expected );
1008         assertThat( printedLines.readLine() )
1009                 .isNull();
1010     }
1011 
1012     @Test
1013     public void testStdErrStreamLn() throws IOException
1014     {
1015         Stream out = Stream.newStream();
1016         WritableBufferedByteChannel channel = newBufferedChannel( out );
1017         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( channel );
1018 
1019         encoder.stdErr( "msg", true );
1020         channel.close();
1021 
1022         String expected = ":maven-surefire-event:std-err-stream-new-line:normal-run:UTF-8:bXNn:";
1023 
1024         LineNumberReader printedLines = out.newReader( UTF_8 );
1025         assertThat( printedLines.readLine() )
1026                 .isEqualTo( expected );
1027         assertThat( printedLines.readLine() )
1028                 .isNull();
1029     }
1030 
1031     @Test
1032     @SuppressWarnings( "checkstyle:innerassignment" )
1033     public void shouldCountSameNumberOfSystemProperties() throws IOException
1034     {
1035         Stream out = Stream.newStream();
1036         WritableBufferedByteChannel channel = newBufferedChannel( out );
1037         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( channel );
1038 
1039         Map<String, String> sysProps = ObjectUtils.systemProps();
1040         int expectedSize = sysProps.size();
1041         encoder.sendSystemProperties( sysProps );
1042         channel.close();
1043 
1044         LineNumberReader printedLines = out.newReader( UTF_8 );
1045 
1046         int size = 0;
1047         for ( String line; ( line = printedLines.readLine() ) != null; size++ )
1048         {
1049             assertThat( line )
1050                     .startsWith( ":maven-surefire-event:sys-prop:normal-run:UTF-8:" );
1051         }
1052 
1053         assertThat( size )
1054                 .isEqualTo( expectedSize );
1055     }
1056 
1057     @Test
1058     public void shouldHandleExit() throws IOException
1059     {
1060         Stream out = Stream.newStream();
1061 
1062         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
1063         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
1064         when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
1065         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
1066         when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
1067         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
1068         encoder.sendExitError( stackTraceWriter, false );
1069 
1070         LineNumberReader printedLines = out.newReader( UTF_8 );
1071         assertThat( printedLines.readLine() )
1072                 .startsWith( ":maven-surefire-event:jvm-exit-error:UTF-8:MQ==:Mg==:Mw==:" );
1073     }
1074 
1075     @Test
1076     public void shouldHandleExitWithTrimmedTrace() throws IOException
1077     {
1078         Stream out = Stream.newStream();
1079 
1080         LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
1081         StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
1082         when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
1083         when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
1084         when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
1085         when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
1086         encoder.sendExitError( stackTraceWriter, true );
1087 
1088         LineNumberReader printedLines = out.newReader( UTF_8 );
1089         assertThat( printedLines.readLine() )
1090                 .startsWith( ":maven-surefire-event:jvm-exit-error:UTF-8:MQ==:Mg==:NA==:" );
1091     }
1092 
1093     private static class Stream extends PrintStream
1094     {
1095         private final ByteArrayOutputStream out;
1096 
1097         Stream( ByteArrayOutputStream out )
1098         {
1099             super( out, true );
1100             this.out = out;
1101         }
1102 
1103         byte[] toByteArray()
1104         {
1105             return out.toByteArray();
1106         }
1107 
1108         LineNumberReader newReader( Charset streamCharset )
1109         {
1110             return new LineNumberReader( new StringReader( new String( toByteArray(), streamCharset ) ) );
1111         }
1112 
1113         static Stream newStream()
1114         {
1115             return new Stream( new ByteArrayOutputStream() );
1116         }
1117     }
1118 
1119     private static byte[] toArray( ByteBuffer buffer )
1120     {
1121         return copyOfRange( buffer.array(), buffer.arrayOffset(), buffer.arrayOffset() + buffer.remaining() );
1122     }
1123 
1124 }