package org.apache.maven.plugin.surefire.extensions;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.maven.plugin.surefire.booterclient.output.DeserializedStacktraceWriter;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessEventListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessEventNotifier;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessExitErrorListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessPropertyEventListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessReportEventListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStackTraceEventListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStandardOutErrEventListener;
import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStringEventListener;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerUtils;
import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
import org.apache.maven.surefire.api.event.Event;
import org.apache.maven.surefire.extensions.EventHandler;
import org.apache.maven.surefire.extensions.ForkNodeArguments;
import org.apache.maven.surefire.extensions.util.CountdownCloseable;
import org.apache.maven.surefire.api.report.ReportEntry;
import org.apache.maven.surefire.api.report.RunMode;
import org.apache.maven.surefire.api.report.SafeThrowable;
import org.apache.maven.surefire.api.report.StackTraceWriter;
import org.apache.maven.surefire.api.util.internal.ObjectUtils;
import org.apache.maven.surefire.api.util.internal.WritableBufferedByteChannel;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.FromDataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;

import javax.annotation.Nonnull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.copyOfRange;
import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
import static org.apache.maven.surefire.shared.codec.binary.Base64.encodeBase64String;
import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedChannel;
import static org.apache.maven.surefire.api.util.internal.Channels.newChannel;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Index.atIndex;
import static org.junit.Assert.assertTrue;
import static org.junit.rules.ExpectedException.none;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * Test for {@link ForkedProcessEventNotifier}.
 *
 * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
 * @since 3.0.0-M4
 */
@RunWith( Enclosed.class )
public class ForkedProcessEventNotifierTest
{
    /**
     *
     */
    @RunWith( PowerMockRunner.class )
    @PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
    public static class DecoderOperationsTest
    {
        @Rule
        public final ExpectedException rule = none();

        @Test
        public void shouldBeFailSafe()
        {
            assertThat( EventConsumerThread.decode( null, UTF_8 ) ).isNull();
            assertThat( EventConsumerThread.decode( "-", UTF_8 ) ).isNull();
            assertThat( EventConsumerThread.decodeToInteger( null ) ).isNull();
            assertThat( EventConsumerThread.decodeToInteger( "-" ) ).isNull();
        }

        @Test
        public void shouldHaveSystemProperty() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            Map<String, String> props = ObjectUtils.systemProps();
            encoder.sendSystemProperties( props );
            wChannel.close();

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            PropertyEventAssertionListener listener = new PropertyEventAssertionListener();
            notifier.setSystemPropertiesListener( listener );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                for ( int i = 0; i < props.size(); i++ )
                {
                    notifier.notifyEvent( eventHandler.pullEvent() );
                }
            }

            assertThat( listener.counter.get() )
                .isEqualTo( props.size() );
        }

        @Test
        public void shouldRecognizeEmptyStream4ReportEntry()
        {
            ReportEntry reportEntry = EventConsumerThread.decodeReportEntry( null, null, null, "", "", null, null, "",
                    "", "", null );
            assertThat( reportEntry ).isNull();

            reportEntry = EventConsumerThread.decodeReportEntry( UTF_8, "", "", "", "", "", "", "-", "", "", "" );
            assertThat( reportEntry ).isNotNull();
            assertThat( reportEntry.getStackTraceWriter() ).isNotNull();
            assertThat( reportEntry.getStackTraceWriter().smartTrimmedStackTrace() ).isEmpty();
            assertThat( reportEntry.getStackTraceWriter().writeTraceToString() ).isEmpty();
            assertThat( reportEntry.getStackTraceWriter().writeTrimmedTraceToString() ).isEmpty();
            assertThat( reportEntry.getSourceName() ).isEmpty();
            assertThat( reportEntry.getSourceText() ).isEmpty();
            assertThat( reportEntry.getName() ).isEmpty();
            assertThat( reportEntry.getNameText() ).isEmpty();
            assertThat( reportEntry.getGroup() ).isEmpty();
            assertThat( reportEntry.getNameWithGroup() ).isEmpty();
            assertThat( reportEntry.getMessage() ).isEmpty();
            assertThat( reportEntry.getElapsed() ).isNull();

            rule.expect( NumberFormatException.class );
            EventConsumerThread.decodeReportEntry( UTF_8, "", "", "", "", "", "", "", "", "", "" );
        }

        @Test
        @SuppressWarnings( "checkstyle:magicnumber" )
        public void testCreatingReportEntry()
        {
            final String exceptionMessage = "msg";
            final String encodedExceptionMsg = encodeBase64String( toArray( UTF_8.encode( exceptionMessage ) ) );

            final String smartStackTrace = "MyTest:86 >> Error";
            final String encodedSmartStackTrace = encodeBase64String( toArray( UTF_8.encode( smartStackTrace ) ) );

            final String stackTrace = "Exception: msg\ntrace line 1\ntrace line 2";
            final String encodedStackTrace = encodeBase64String( toArray( UTF_8.encode( stackTrace ) ) );

            final String trimmedStackTrace = "trace line 1\ntrace line 2";
            final String encodedTrimmedStackTrace = encodeBase64String( toArray( UTF_8.encode( trimmedStackTrace ) ) );

            SafeThrowable safeThrowable = new SafeThrowable( exceptionMessage );
            StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
            when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
            when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
            when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace );
            when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace );

            ReportEntry reportEntry = mock( ReportEntry.class );
            when( reportEntry.getElapsed() ).thenReturn( 102 );
            when( reportEntry.getGroup() ).thenReturn( "this group" );
            when( reportEntry.getMessage() ).thenReturn( "skipped test" );
            when( reportEntry.getName() ).thenReturn( "my test" );
            when( reportEntry.getNameText() ).thenReturn( "my display name" );
            when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
            when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
            when( reportEntry.getSourceText() ).thenReturn( "test class display name" );
            when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );

            String encodedSourceName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceName() ) ) );
            String encodedSourceText = encodeBase64String( toArray( UTF_8.encode( reportEntry.getSourceText() ) ) );
            String encodedName = encodeBase64String( toArray( UTF_8.encode( reportEntry.getName() ) ) );
            String encodedText = encodeBase64String( toArray( UTF_8.encode( reportEntry.getNameText() ) ) );
            String encodedGroup = encodeBase64String( toArray( UTF_8.encode( reportEntry.getGroup() ) ) );
            String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );

            ReportEntry decodedReportEntry = EventConsumerThread.decodeReportEntry( UTF_8, encodedSourceName,
                encodedSourceText, encodedName, encodedText, encodedGroup, encodedMessage, "-", null, null, null );

            assertThat( decodedReportEntry ).isNotNull();
            assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() );
            assertThat( decodedReportEntry.getSourceText() ).isEqualTo( reportEntry.getSourceText() );
            assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() );
            assertThat( decodedReportEntry.getNameText() ).isEqualTo( reportEntry.getNameText() );
            assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() );
            assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() );
            assertThat( decodedReportEntry.getStackTraceWriter() ).isNull();

            decodedReportEntry = EventConsumerThread.decodeReportEntry( UTF_8, encodedSourceName, encodedSourceText,
                encodedName, encodedText, encodedGroup, encodedMessage, "-", encodedExceptionMsg,
                encodedSmartStackTrace, null );

            assertThat( decodedReportEntry ).isNotNull();
            assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() );
            assertThat( decodedReportEntry.getSourceText() ).isEqualTo( reportEntry.getSourceText() );
            assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() );
            assertThat( decodedReportEntry.getNameText() ).isEqualTo( reportEntry.getNameText() );
            assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() );
            assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() );
            assertThat( decodedReportEntry.getElapsed() ).isNull();
            assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() )
                .isEqualTo( exceptionMessage );
            assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() )
                .isEqualTo( smartStackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() )
                .isNull();

            decodedReportEntry = EventConsumerThread.decodeReportEntry( UTF_8, encodedSourceName, encodedSourceText,
                encodedName, encodedText, encodedGroup, encodedMessage, "1003", encodedExceptionMsg,
                encodedSmartStackTrace, null );

            assertThat( decodedReportEntry ).isNotNull();
            assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() );
            assertThat( decodedReportEntry.getSourceText() ).isEqualTo( reportEntry.getSourceText() );
            assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() );
            assertThat( decodedReportEntry.getNameText() ).isEqualTo( reportEntry.getNameText() );
            assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() );
            assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() );
            assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 );
            assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() )
                .isEqualTo( exceptionMessage );
            assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() )
                .isEqualTo( smartStackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() )
                .isNull();

            decodedReportEntry = EventConsumerThread.decodeReportEntry( UTF_8, encodedSourceName, encodedSourceText,
                encodedName, encodedText, encodedGroup, encodedMessage, "1003", encodedExceptionMsg,
                encodedSmartStackTrace, encodedStackTrace );

            assertThat( decodedReportEntry ).isNotNull();
            assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() );
            assertThat( decodedReportEntry.getSourceText() ).isEqualTo( reportEntry.getSourceText() );
            assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() );
            assertThat( decodedReportEntry.getNameText() ).isEqualTo( reportEntry.getNameText() );
            assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() );
            assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() );
            assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 );
            assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() )
                    .isEqualTo( exceptionMessage );
            assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() )
                    .isEqualTo( smartStackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() ).isEqualTo( stackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString() ).isEqualTo( stackTrace );

            decodedReportEntry = EventConsumerThread.decodeReportEntry( UTF_8, encodedSourceName, encodedSourceText,
                encodedName, encodedText, encodedGroup, encodedMessage, "1003", encodedExceptionMsg,
                encodedSmartStackTrace, encodedTrimmedStackTrace );

            assertThat( decodedReportEntry ).isNotNull();
            assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() );
            assertThat( decodedReportEntry.getSourceText() ).isEqualTo( reportEntry.getSourceText() );
            assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() );
            assertThat( decodedReportEntry.getNameText() ).isEqualTo( reportEntry.getNameText() );
            assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() );
            assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() );
            assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 );
            assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ).isNotNull();
            assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() )
                    .isEqualTo( exceptionMessage );
            assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() )
                    .isEqualTo( smartStackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() ).isEqualTo( trimmedStackTrace );
            assertThat( decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString() )
                    .isEqualTo( trimmedStackTrace );
        }

        @Test
        public void shouldSendByeEvent() throws Exception
        {
            Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.bye();
            String read = new String( out.toByteArray(), UTF_8 );

            assertThat( read )
                    .isEqualTo( ":maven-surefire-event:bye:\n" );

            LineNumberReader lines = out.newReader( UTF_8 );

            final String cmd = lines.readLine();
            assertThat( cmd )
                    .isNotNull();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            EventAssertionListener listener = new EventAssertionListener();
            notifier.setByeListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void shouldSendStopOnNextTestEvent() throws Exception
        {
            Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.stopOnNextTest();
            String read = new String( out.toByteArray(), UTF_8 );

            assertThat( read )
                    .isEqualTo( ":maven-surefire-event:stop-on-next-test:\n" );

            LineNumberReader lines = out.newReader( UTF_8 );

            final String cmd = lines.readLine();
            assertThat( cmd )
                .isNotNull();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            EventAssertionListener listener = new EventAssertionListener();
            notifier.setStopOnNextTestListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void shouldCorrectlyDecodeStackTracesWithEmptyStringTraceMessages() throws Exception
        {
            String exceptionMessage = "";
            String smartStackTrace = "JUnit5Test.failWithEmptyString:16";
            String exceptionStackTrace = "org.opentest4j.AssertionFailedError: \n"
                    + "\tat JUnit5Test.failWithEmptyString(JUnit5Test.java:16)\n";

            StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
            SafeThrowable safeThrowable = new SafeThrowable( exceptionMessage );
            when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
            when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
            when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( exceptionStackTrace );
            when( stackTraceWriter.writeTraceToString() ).thenReturn( exceptionStackTrace );

            ReportEntry reportEntry = mock( ReportEntry.class );
            when( reportEntry.getElapsed() ).thenReturn( 7 );
            when( reportEntry.getGroup() ).thenReturn( null );
            when( reportEntry.getMessage() ).thenReturn( null );
            when( reportEntry.getName() ).thenReturn( "failWithEmptyString" );
            when( reportEntry.getNameWithGroup() ).thenReturn( "JUnit5Test" );
            when( reportEntry.getSourceName() ).thenReturn( "JUnit5Test" );
            when( reportEntry.getSourceText() ).thenReturn( null );
            when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );

            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.testFailed( reportEntry, true );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            final ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            ReportEventAssertionListener listener = new ReportEventAssertionListener( reportEntry, true );
            notifier.setTestFailedListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void shouldSendNextTestEvent() throws Exception
        {
            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.acquireNextTest();
            String read = new String( out.toByteArray(), UTF_8 );

            assertThat( read )
                    .isEqualTo( ":maven-surefire-event:next-test:\n" );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            EventAssertionListener listener = new EventAssertionListener();
            notifier.setAcquireNextTestListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testConsole() throws Exception
        {
            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.consoleInfoLog( "msg" );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StringEventAssertionListener listener = new StringEventAssertionListener( "msg" );
            notifier.setConsoleInfoListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testError() throws Exception
        {
            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.consoleErrorLog( "msg" );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StackTraceEventListener listener = new StackTraceEventListener( "msg", null, null );
            notifier.setConsoleErrorListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testErrorWithException() throws Exception
        {
            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            Throwable throwable = new Throwable( "msg" );
            encoder.consoleErrorLog( throwable );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            String stackTrace = ConsoleLoggerUtils.toString( throwable );
            StackTraceEventListener listener = new StackTraceEventListener( "msg", null, stackTrace );
            notifier.setConsoleErrorListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testErrorWithStackTraceWriter() throws Exception
        {
            final Stream out = Stream.newStream();

            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            StackTraceWriter stackTraceWriter = new DeserializedStacktraceWriter( "1", "2", "3" );
            encoder.consoleErrorLog( stackTraceWriter, false );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StackTraceEventListener listener = new StackTraceEventListener( "1", "2", "3" );
            notifier.setConsoleErrorListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testDebug() throws Exception
        {
            final Stream out = Stream.newStream();

            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.consoleDebugLog( "msg" );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StringEventAssertionListener listener = new StringEventAssertionListener( "msg" );
            notifier.setConsoleDebugListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();

            assertThat( listener.msg )
                .isEqualTo( "msg" );
        }

        @Test
        public void testWarning() throws Exception
        {
            final Stream out = Stream.newStream();

            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );
            encoder.consoleWarningLog( "msg" );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StringEventAssertionListener listener = new StringEventAssertionListener( "msg" );
            notifier.setConsoleWarningListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdOutStream() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdOut( "msg", false );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, "msg", false );
            notifier.setStdOutListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdOutStreamPrint() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdOut( "", false );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, "", false );
            notifier.setStdOutListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdOutStreamPrintWithNull() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdOut( null, false );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, null, false );
            notifier.setStdOutListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdOutStreamPrintln() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdOut( "", true );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, "", true );
            notifier.setStdOutListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdOutStreamPrintlnWithNull() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdOut( null, true );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, null, true );
            notifier.setStdOutListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void testStdErrStream() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.stdErr( "msg", false );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            StandardOutErrEventAssertionListener listener =
                new StandardOutErrEventAssertionListener( NORMAL_RUN, "msg", false );
            notifier.setStdErrListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void shouldCountSameNumberOfSystemProperties() throws Exception
        {
            final Stream out = Stream.newStream();
            WritableBufferedByteChannel wChannel = newBufferedChannel( out );
            LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( wChannel );
            encoder.sendSystemProperties( ObjectUtils.systemProps() );
            wChannel.close();

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            PropertyEventAssertionListener listener = new PropertyEventAssertionListener();
            notifier.setSystemPropertiesListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }

        @Test
        public void shouldHandleErrorAfterNullLine()
        {
            ForkedProcessEventNotifier decoder = new ForkedProcessEventNotifier();
            decoder.setSystemPropertiesListener( new PropertyEventAssertionListener() );
            rule.expect( NullPointerException.class );
            decoder.notifyEvent( null );
        }

        @Test
        public void shouldHandleErrorAfterUnknownOperation() throws Exception
        {
            String cmd = ":maven-surefire-event:abnormal-run:-:\n";

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( cmd.getBytes() ) );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            when( logger.isDebugEnabled() ).thenReturn( true );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                countdown.awaitClosed();
            }

            ArgumentCaptor<String> dumpLine = ArgumentCaptor.forClass( String.class );
            verify( logger, times( 2 ) ).debug( dumpLine.capture() );
            assertThat( dumpLine.getAllValues() )
                .hasSize( 2 )
                .contains( ":maven-surefire-event:abnormal-run:", atIndex( 0 ) )
                .contains( "-:", atIndex( 1 ) );

            ArgumentCaptor<String> dumpText = ArgumentCaptor.forClass( String.class );
            verify( arguments, times( 2 ) ).dumpStreamText( dumpText.capture() );
            String dump = "Corrupted STDOUT by directly writing to native stream in forked JVM 0.";
            assertThat( dumpText.getAllValues() )
                .hasSize( 2 )
                .contains( format( dump + " Stream '%s'.", ":maven-surefire-event:abnormal-run:" ), atIndex( 0 ) )
                .contains( format( dump + " Stream '%s'.", "-:" ), atIndex( 1 ) );

            ArgumentCaptor<String> warning = ArgumentCaptor.forClass( String.class );
            verify( arguments, times( 2 ) ).logWarningAtEnd( warning.capture() );
            dump += " See FAQ web page and the dump file ";
            assertThat( warning.getAllValues() )
                .hasSize( 2 );
            assertThat( warning.getAllValues().get( 0 ) )
                .startsWith( dump );
            assertThat( warning.getAllValues().get( 1 ) )
                .startsWith( dump );
        }

        @Test
        public void shouldHandleExit() throws Exception
        {
            final Stream out = Stream.newStream();
            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );

            StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
            when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
            when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
            when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
            when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
            encoder.sendExitError( stackTraceWriter, false );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();
            ProcessExitErrorListener listener = new ProcessExitErrorListener();
            notifier.setExitErrorEventListener( listener );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }

            assertThat( listener.called.get() )
                .isTrue();
        }
    }

    /**
     *
     */
    @RunWith( Theories.class )
    public static class ReportEntryTest
    {
        @DataPoints( value = "operation" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static String[][] operations = { { "testSetStarting", "setTestSetStartingListener" },
                                                { "testSetCompleted", "setTestSetCompletedListener" },
                                                { "testStarting", "setTestStartingListener" },
                                                { "testSucceeded", "setTestSucceededListener" },
                                                { "testFailed", "setTestFailedListener" },
                                                { "testSkipped", "setTestSkippedListener" },
                                                { "testError", "setTestErrorListener" },
                                                { "testAssumptionFailure", "setTestAssumptionFailureListener" }
        };

        @DataPoints( value = "reportedMessage" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static String[] reportedMessage = { null, "skipped test" };

        @DataPoints( value = "elapsed" )
        @SuppressWarnings( { "checkstyle:visibilitymodifier", "checkstyle:magicnumber" } )
        public static Integer[] elapsed = { null, 102 };

        @DataPoints( value = "trim" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static boolean[] trim = { false, true };

        @DataPoints( value = "msg" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static boolean[] msg = { false, true };

        @DataPoints( value = "smart" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static boolean[] smart = { false, true };

        @DataPoints( value = "trace" )
        @SuppressWarnings( "checkstyle:visibilitymodifier" )
        public static boolean[] trace = { false, true };

        @Theory
        public void testReportEntryOperations( @FromDataPoints( "operation" ) String[] operation,
                                               @FromDataPoints( "reportedMessage" ) String reportedMessage,
                                               @FromDataPoints( "elapsed" ) Integer elapsed,
                                               @FromDataPoints( "trim" ) boolean trim,
                                               @FromDataPoints( "msg" ) boolean msg,
                                               @FromDataPoints( "smart" ) boolean smart,
                                               @FromDataPoints( "trace" ) boolean trace )
                throws Exception
        {
            String exceptionMessage = msg ? "msg" : null;
            String smartStackTrace = smart ? "MyTest:86 >> Error" : null;
            String exceptionStackTrace =
                    trace ? ( trim ? "trace line 1\ntrace line 2" : "Exception: msg\ntrace line 1\ntrace line 2" )
                            : null;

            StackTraceWriter stackTraceWriter = null;
            if ( exceptionStackTrace != null )
            {
                SafeThrowable safeThrowable = new SafeThrowable( exceptionMessage );
                stackTraceWriter = mock( StackTraceWriter.class );
                when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable );
                when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace );
                when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( exceptionStackTrace );
                when( stackTraceWriter.writeTraceToString() ).thenReturn( exceptionStackTrace );
            }

            ReportEntry reportEntry = mock( ReportEntry.class );
            when( reportEntry.getElapsed() ).thenReturn( elapsed );
            when( reportEntry.getGroup() ).thenReturn( "this group" );
            when( reportEntry.getMessage() ).thenReturn( reportedMessage );
            when( reportEntry.getName() ).thenReturn( "my test" );
            when( reportEntry.getName() ).thenReturn( "display name of test" );
            when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" );
            when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" );
            when( reportEntry.getSourceText() ).thenReturn( "test class display name" );
            when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );

            final Stream out = Stream.newStream();

            LegacyMasterProcessChannelEncoder encoder =
                new LegacyMasterProcessChannelEncoder( newBufferedChannel( out ) );

            LegacyMasterProcessChannelEncoder.class.getMethod( operation[0], ReportEntry.class, boolean.class )
                    .invoke( encoder, reportEntry, trim );

            ForkedProcessEventNotifier notifier = new ForkedProcessEventNotifier();

            ForkedProcessEventNotifier.class.getMethod( operation[1], ForkedProcessReportEventListener.class )
                    .invoke( notifier, new ReportEventAssertionListener( reportEntry, stackTraceWriter != null ) );

            ReadableByteChannel channel = newChannel( new ByteArrayInputStream( out.toByteArray() ) );

            EH eventHandler = new EH();
            CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
            ConsoleLogger logger = mock( ConsoleLogger.class );
            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
            when( arguments.getConsoleLogger() ).thenReturn( logger );
            try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
            {
                t.start();
                notifier.notifyEvent( eventHandler.pullEvent() );
            }
        }
    }

    private static class ProcessExitErrorListener implements ForkedProcessExitErrorListener
    {
        final AtomicBoolean called = new AtomicBoolean();

        @Override
        public void handle( StackTraceWriter stackTrace )
        {
            called.set( true );
            assertThat( stackTrace.getThrowable().getMessage() ).isEqualTo( "1" );
            assertThat( stackTrace.smartTrimmedStackTrace() ).isEqualTo( "2" );
            assertThat( stackTrace.writeTraceToString() ).isEqualTo( "3" );
        }
    }

    private static class PropertyEventAssertionListener implements ForkedProcessPropertyEventListener
    {
        final AtomicBoolean called = new AtomicBoolean();
        private final Map<?, ?> sysProps = System.getProperties();
        private final AtomicInteger counter = new AtomicInteger();

        public void handle( RunMode runMode, String key, String value )
        {
            called.set( true );
            counter.incrementAndGet();
            assertThat( runMode ).isEqualTo( NORMAL_RUN );
            assertTrue( sysProps.containsKey( key ) );
            assertThat( sysProps.get( key ) ).isEqualTo( value );
        }
    }

    private static class EventAssertionListener implements ForkedProcessEventListener
    {
        final AtomicBoolean called = new AtomicBoolean();

        public void handle()
        {
            called.set( true );
        }
    }

    private static class StringEventAssertionListener implements ForkedProcessStringEventListener
    {
        final AtomicBoolean called = new AtomicBoolean();
        private final String msg;

        StringEventAssertionListener( String msg )
        {
            this.msg = msg;
        }

        public void handle( String msg )
        {
            called.set( true );
            assertThat( msg )
                    .isEqualTo( this.msg );
        }
    }

    private static class StackTraceEventListener implements ForkedProcessStackTraceEventListener
    {
        final AtomicBoolean called = new AtomicBoolean();
        private final String msg;
        private final String smartStackTrace;
        private final String stackTrace;

        StackTraceEventListener( String msg, String smartStackTrace, String stackTrace )
        {
            this.msg = msg;
            this.smartStackTrace = smartStackTrace;
            this.stackTrace = stackTrace;
        }

        @Override
        public void handle( @Nonnull StackTraceWriter stackTrace )
        {
            called.set( true );

            assertThat( stackTrace.getThrowable().getMessage() )
                    .isEqualTo( msg );

            assertThat( stackTrace.smartTrimmedStackTrace() )
                    .isEqualTo( smartStackTrace );

            assertThat( stackTrace.writeTraceToString() )
                    .isEqualTo( this.stackTrace );
        }
    }

    private static class StandardOutErrEventAssertionListener implements ForkedProcessStandardOutErrEventListener
    {
        final AtomicBoolean called = new AtomicBoolean();
        private final RunMode runMode;
        private final String output;
        private final boolean newLine;

        StandardOutErrEventAssertionListener( RunMode runMode, String output, boolean newLine )
        {
            this.runMode = runMode;
            this.output = output;
            this.newLine = newLine;
        }

        public void handle( RunMode runMode, String output, boolean newLine )
        {
            called.set( true );

            assertThat( runMode )
                    .isEqualTo( this.runMode );

            assertThat( output )
                    .isEqualTo( this.output );

            assertThat( newLine )
                    .isEqualTo( this.newLine );
        }
    }

    private static class ReportEventAssertionListener implements ForkedProcessReportEventListener<ReportEntry>
    {
        final AtomicBoolean called = new AtomicBoolean();
        private final ReportEntry reportEntry;
        private final boolean hasStackTrace;

        ReportEventAssertionListener( ReportEntry reportEntry, boolean hasStackTrace )
        {
            this.reportEntry = reportEntry;
            this.hasStackTrace = hasStackTrace;
        }

        public void handle( RunMode runMode, ReportEntry reportEntry )
        {
            called.set( true );
            assertThat( reportEntry.getSourceName() ).isEqualTo( this.reportEntry.getSourceName() );
            assertThat( reportEntry.getSourceText() ).isEqualTo( this.reportEntry.getSourceText() );
            assertThat( reportEntry.getName() ).isEqualTo( this.reportEntry.getName() );
            assertThat( reportEntry.getNameText() ).isEqualTo( this.reportEntry.getNameText() );
            assertThat( reportEntry.getGroup() ).isEqualTo( this.reportEntry.getGroup() );
            assertThat( reportEntry.getMessage() ).isEqualTo( this.reportEntry.getMessage() );
            assertThat( reportEntry.getElapsed() ).isEqualTo( this.reportEntry.getElapsed() );
            if ( reportEntry.getStackTraceWriter() == null )
            {
                assertThat( hasStackTrace ).isFalse();
                assertThat( this.reportEntry.getStackTraceWriter() ).isNull();
            }
            else
            {
                assertThat( hasStackTrace ).isTrue();
                assertThat( this.reportEntry.getStackTraceWriter() ).isNotNull();

                assertThat( reportEntry.getStackTraceWriter().getThrowable().getMessage() )
                        .isEqualTo( this.reportEntry.getStackTraceWriter().getThrowable().getMessage() );

                assertThat( reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage() )
                        .isEqualTo( this.reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage() );

                assertThat( reportEntry.getStackTraceWriter().smartTrimmedStackTrace() )
                        .isEqualTo( this.reportEntry.getStackTraceWriter().smartTrimmedStackTrace() );
            }
        }
    }

    private static class Stream extends PrintStream
    {
        private final ByteArrayOutputStream out;

        Stream( ByteArrayOutputStream out )
        {
            super( out, true );
            this.out = out;
        }

        byte[] toByteArray()
        {
            return out.toByteArray();
        }

        LineNumberReader newReader( Charset streamCharset )
        {
            return new LineNumberReader( new StringReader( new String( toByteArray(), streamCharset ) ) );
        }

        static Stream newStream()
        {
            return new Stream( new ByteArrayOutputStream() );
        }
    }

    private static byte[] toArray( ByteBuffer buffer )
    {
        return copyOfRange( buffer.array(), buffer.arrayOffset(), buffer.arrayOffset() + buffer.remaining() );
    }

    private static class EH implements EventHandler<Event>
    {
        private final BlockingQueue<Event> cache = new LinkedTransferQueue<>();

        Event pullEvent() throws InterruptedException
        {
            return cache.poll( 1, TimeUnit.MINUTES );
        }

        @Override
        public void handleEvent( @Nonnull Event event )
        {
            cache.add( event );
        }
    }
}
