You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2020/10/08 23:41:46 UTC

[maven-surefire] branch gh-build-fix updated (f0019bd -> 26e8c84)

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a change to branch gh-build-fix
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.


 discard f0019bd  [GH] build fix
 discard 9ebeb8f  [GH] build fix
 discard f28e313  [GH] investigating
 discard f919a47  [GH] build fix
 discard 85daaab  [GH] workspace clean up
 discard 3d90b96  [GH] build fix
     new 26e8c84  [GH] build fix

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (f0019bd)
            \
             N -- N -- N   refs/heads/gh-build-fix (26e8c84)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:


[maven-surefire] 01/01: [GH] build fix

Posted by ti...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch gh-build-fix
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 26e8c8485e1deac7ceedd679377cb9607db3be26
Author: tibordigana <ti...@apache.org>
AuthorDate: Thu Oct 8 01:19:58 2020 +0200

    [GH] build fix
---
 .github/workflows/maven.yml                        |   2 +-
 .github/workflows/smoketest.yml                    |   2 +-
 .../surefire/extensions/EventConsumerThread.java   |   8 +-
 .../booterclient/ForkingRunListenerTest.java       |  75 +++-
 .../booterclient/output/ForkClientTest.java        | 343 ++++++++++------
 .../extensions/ForkedProcessEventNotifierTest.java | 434 +++++++++++++++------
 6 files changed, 612 insertions(+), 252 deletions(-)

diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 41dde5e..2058b40 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -45,7 +45,7 @@ jobs:
           java-version: 14
 
       - name: Build with Maven
-        run: mvn install -e -B -V -nsu --no-transfer-progress -P run-its
+        run: mvn clean install -e -B -V -nsu --no-transfer-progress -P run-its
 
       - name: Upload artifact surefire-its
         uses: actions/upload-artifact@v2-preview
diff --git a/.github/workflows/smoketest.yml b/.github/workflows/smoketest.yml
index 67c17c7..f8bbae2 100644
--- a/.github/workflows/smoketest.yml
+++ b/.github/workflows/smoketest.yml
@@ -39,4 +39,4 @@ jobs:
           java-version: 14
 
       - name: Build with Maven
-        run: mvn install -e -B -V -nsu --no-transfer-progress -P run-its -DskipITs
+        run: mvn clean install -e -B -V -nsu --no-transfer-progress -P run-its -DskipITs
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
index 2647b60..8b855d8 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
@@ -822,8 +822,14 @@ public class EventConsumerThread extends CloseableDaemonThread
             {
                 return;
             }
-            ConsoleLogger logger = arguments.getConsoleLogger();
+
             String s = toString();
+            if ( s == null )
+            {
+                return;
+            }
+
+            ConsoleLogger logger = arguments.getConsoleLogger();
             if ( s.contains( PRINTABLE_JVM_NATIVE_STREAM ) )
             {
                 if ( logger.isDebugEnabled() )
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
index 8887e4d..a8eb91f 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
@@ -53,6 +53,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -60,12 +61,8 @@ import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedCh
 import static org.apache.maven.surefire.api.util.internal.Channels.newChannel;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.MapAssert.entry;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
 
 /**
  * @author Kristian Rosenvold
@@ -299,16 +296,15 @@ public class ForkingRunListenerTest
         EH handler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
         ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( stream ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, handler, countdown, arguments ) )
         {
             t.start();
             countdown.awaitClosed();
             verifyZeroInteractions( logger );
-            verify( arguments, never() ).dumpStreamText( anyString() );
+            assertThat( arguments.isCalled() )
+                .isFalse();
             for ( int i = 0, size = handler.countEventsInCache(); i < size; i++ )
             {
                 events.add( handler.pullEvent() );
@@ -318,6 +314,69 @@ public class ForkingRunListenerTest
         }
     }
 
+    /**
+     * Threadsafe impl. Mockito and Powermock are not thread-safe.
+     */
+    private static class ForkNodeArgumentsMock implements ForkNodeArguments
+    {
+        private final ConcurrentLinkedQueue<String> dumpStreamText = new ConcurrentLinkedQueue<>();
+        private final ConcurrentLinkedQueue<String> logWarningAtEnd = new ConcurrentLinkedQueue<>();
+        private final ConsoleLogger logger;
+        private final File dumpStreamTextFile;
+
+        ForkNodeArgumentsMock( ConsoleLogger logger, File dumpStreamTextFile )
+        {
+            this.logger = logger;
+            this.dumpStreamTextFile = dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public String getSessionId()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int getForkChannelId()
+        {
+            return 0;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamText( @Nonnull String text )
+        {
+            dumpStreamText.add( text );
+            return dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamException( @Nonnull Throwable t )
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void logWarningAtEnd( @Nonnull String text )
+        {
+            logWarningAtEnd.add( text );
+        }
+
+        @Nonnull
+        @Override
+        public ConsoleLogger getConsoleLogger()
+        {
+            return logger;
+        }
+
+        boolean isCalled()
+        {
+            return !dumpStreamText.isEmpty() || !logWarningAtEnd.isEmpty();
+        }
+    }
+
     private static class EH implements EventHandler<Event>
     {
         private final BlockingQueue<Event> cache = new LinkedBlockingQueue<>();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
index 60d48f3..5d871a3 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
@@ -46,16 +46,15 @@ import org.apache.maven.surefire.api.event.TestStartingEvent;
 import org.apache.maven.surefire.api.event.TestSucceededEvent;
 import org.apache.maven.surefire.api.event.TestsetCompletedEvent;
 import org.apache.maven.surefire.api.event.TestsetStartingEvent;
-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.SafeThrowable;
 import org.apache.maven.surefire.api.report.SimpleReportEntry;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
+import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
+import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.junit.Test;
-import org.mockito.ArgumentCaptor;
 
 import javax.annotation.Nonnull;
 import java.io.ByteArrayInputStream;
@@ -63,6 +62,7 @@ import java.io.Closeable;
 import java.io.File;
 import java.nio.channels.ReadableByteChannel;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -86,7 +86,6 @@ import static org.apache.maven.surefire.api.booter.ForkedProcessEventType.BOOTER
 import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.MapAssert.entry;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -125,30 +124,26 @@ public class ForkClientTest
         String nativeStream = "Listening for transport dt_socket at address: bla";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
-        when( logger.isDebugEnabled() ).thenReturn( false );
-        when( logger.isInfoEnabled() ).thenReturn( true );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, true, true, true );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .info( "Listening for transport dt_socket at address: bla" );
+            assertThat( logger.info )
+                .hasSize( 1 )
+                .contains( "Listening for transport dt_socket at address: bla" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
 
-        verify( logger ).isDebugEnabled();
-
-        verify( logger ).isInfoEnabled();
+        assertThat( logger.isDebugEnabledCalled )
+            .isTrue();
 
-        verifyNoMoreInteractions( logger );
+        assertThat( logger.isInfoEnabledCalled )
+            .isTrue();
     }
 
     @Test
@@ -157,25 +152,20 @@ public class ForkClientTest
         String nativeStream = "\nCould not create the Java Virtual Machine\n";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "Could not create the Java Virtual Machine" );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "Could not create the Java Virtual Machine" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -184,25 +174,20 @@ public class ForkClientTest
         String nativeStream = "\nError occurred during initialization of VM\n";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "Error occurred during initialization of VM" );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "Error occurred during initialization of VM" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -211,25 +196,20 @@ public class ForkClientTest
         String nativeStream = "\nError: A fatal exception has occurred. Program will exit.\n";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "Error: A fatal exception has occurred. Program will exit." );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "Error: A fatal exception has occurred. Program will exit." );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -238,25 +218,20 @@ public class ForkClientTest
         String nativeStream = "\nCould not reserve enough space for object heap\n";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "Could not reserve enough space for object heap" );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "Could not reserve enough space for object heap" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -265,25 +240,20 @@ public class ForkClientTest
         String nativeStream = "\njava.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "java.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api" );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "java.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -292,25 +262,20 @@ public class ForkClientTest
         String nativeStream = "\njava.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .error( "java.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api" );
+            assertThat( logger.error )
+                .hasSize( 1 )
+                .contains( "java.lang.module.FindException: Module java.ws.rs not found, required by com.foo.api" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -319,41 +284,34 @@ public class ForkClientTest
         String nativeStream = "unordered error";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
-        when( logger.isDebugEnabled() )
-            .thenReturn( true );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( true, true, true, true );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
             t.start();
-
             countdown.awaitClosed();
-
-            verify( logger )
-                .debug( "unordered error" );
+            assertThat( logger.debug )
+                .hasSize( 1 )
+                .contains( "unordered error" );
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
 
-        verify( logger ).isDebugEnabled();
+        assertThat( logger.isDebugEnabledCalled )
+            .isTrue();
 
-        ArgumentCaptor<String> dumpText = ArgumentCaptor.forClass( String.class );
-        verify( arguments ).dumpStreamText( dumpText.capture() );
         String msg = "Corrupted STDOUT by directly writing to native stream in forked JVM 0. Stream 'unordered error'.";
-        assertThat( dumpText.getValue() )
-            .isEqualTo( msg );
+        assertThat( arguments.dumpStreamText )
+            .hasSize( 1 )
+            .contains( msg );
 
-        ArgumentCaptor<String> warningText = ArgumentCaptor.forClass( String.class );
-        verify( arguments ).logWarningAtEnd( warningText.capture() );
-        assertThat( warningText.getValue() )
+        assertThat( arguments.logWarningAtEnd )
+            .hasSize( 1 );
+        assertThat( arguments.logWarningAtEnd.peek() )
             .startsWith( "Corrupted STDOUT by directly writing to native stream in forked JVM 0. "
                 + "See FAQ web page and the dump file" );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -362,11 +320,8 @@ public class ForkClientTest
         String nativeStream = "Listening for transport dt_socket at address: bla\n:maven-surefire-event:\u0003:bye:\n";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
-        when( logger.isDebugEnabled() ).thenReturn( true );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( true, true, true, true );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
@@ -380,8 +335,9 @@ public class ForkClientTest
             assertThat( event.getEventType() )
                 .isEqualTo( BOOTERCODE_BYE );
 
-            verify( logger )
-                .debug( "Listening for transport dt_socket at address: bla" );
+            assertThat( logger.debug )
+                .hasSize( 1 )
+                .contains( "Listening for transport dt_socket at address: bla" );
 
             countdown.awaitClosed();
         }
@@ -389,9 +345,8 @@ public class ForkClientTest
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
 
-        verify( logger ).isDebugEnabled();
-
-        verifyNoMoreInteractions( logger );
+        assertThat( logger.isDebugEnabledCalled )
+            .isTrue();
     }
 
     @Test
@@ -734,9 +689,8 @@ public class ForkClientTest
             + ":\u0000\u0000\u0000\u0002:s1:\u0000\u0000\u0000\u0002:s2:";
         EH eventHandler = new EH();
         CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 1 );
-        ConsoleLogger logger = mock( ConsoleLogger.class );
-        ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-        when( arguments.getConsoleLogger() ).thenReturn( logger );
+        ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+        ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
         ReadableByteChannel channel = newChannel( new ByteArrayInputStream( nativeStream.getBytes() ) );
         try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
         {
@@ -762,13 +716,12 @@ public class ForkClientTest
 
             countdown.awaitClosed();
 
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
         }
 
         assertThat( eventHandler.sizeOfEventCache() )
             .isEqualTo( 0 );
-
-        verifyNoMoreInteractions( logger );
     }
 
     @Test
@@ -1868,4 +1821,166 @@ public class ForkClientTest
             cache.add( event );
         }
     }
+
+    /**
+     * Threadsafe impl. Mockito and Powermock are not thread-safe.
+     */
+    private static class ForkNodeArgumentsMock implements ForkNodeArguments
+    {
+        private final ConcurrentLinkedQueue<String> dumpStreamText = new ConcurrentLinkedQueue<>();
+        private final ConcurrentLinkedQueue<String> logWarningAtEnd = new ConcurrentLinkedQueue<>();
+        private final ConsoleLogger logger;
+        private final File dumpStreamTextFile;
+
+        ForkNodeArgumentsMock( ConsoleLogger logger, File dumpStreamTextFile )
+        {
+            this.logger = logger;
+            this.dumpStreamTextFile = dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public String getSessionId()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int getForkChannelId()
+        {
+            return 0;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamText( @Nonnull String text )
+        {
+            dumpStreamText.add( text );
+            return dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamException( @Nonnull Throwable t )
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void logWarningAtEnd( @Nonnull String text )
+        {
+            logWarningAtEnd.add( text );
+        }
+
+        @Nonnull
+        @Override
+        public ConsoleLogger getConsoleLogger()
+        {
+            return logger;
+        }
+
+        boolean isCalled()
+        {
+            return !dumpStreamText.isEmpty() || !logWarningAtEnd.isEmpty();
+        }
+    }
+
+    /**
+     * Threadsafe impl. Mockito and Powermock are not thread-safe.
+     */
+    private static class ConsoleLoggerMock implements ConsoleLogger
+    {
+        final ConcurrentLinkedQueue<String> debug = new ConcurrentLinkedQueue<>();
+        final ConcurrentLinkedQueue<String> info = new ConcurrentLinkedQueue<>();
+        final ConcurrentLinkedQueue<String> error = new ConcurrentLinkedQueue<>();
+        final boolean isDebug;
+        final boolean isInfo;
+        final boolean isWarning;
+        final boolean isError;
+        boolean called;
+        boolean isDebugEnabledCalled;
+        boolean isInfoEnabledCalled;
+
+        ConsoleLoggerMock( boolean isDebug, boolean isInfo, boolean isWarning, boolean isError )
+        {
+            this.isDebug = isDebug;
+            this.isInfo = isInfo;
+            this.isWarning = isWarning;
+            this.isError = isError;
+        }
+
+        @Override
+        public boolean isDebugEnabled()
+        {
+            isDebugEnabledCalled = true;
+            called = true;
+            return isDebug;
+        }
+
+        @Override
+        public void debug( String message )
+        {
+            debug.add( message );
+            called = true;
+        }
+
+        @Override
+        public boolean isInfoEnabled()
+        {
+            isInfoEnabledCalled = true;
+            called = true;
+            return isInfo;
+        }
+
+        @Override
+        public void info( String message )
+        {
+            info.add( message );
+            called = true;
+        }
+
+        @Override
+        public boolean isWarnEnabled()
+        {
+            called = true;
+            return isWarning;
+        }
+
+        @Override
+        public void warning( String message )
+        {
+            called = true;
+        }
+
+        @Override
+        public boolean isErrorEnabled()
+        {
+            called = true;
+            return isError;
+        }
+
+        @Override
+        public void error( String message )
+        {
+            error.add( message );
+            called = true;
+        }
+
+        @Override
+        public void error( String message, Throwable t )
+        {
+            called = true;
+        }
+
+        @Override
+        public void error( Throwable t )
+        {
+            called = true;
+        }
+
+        boolean isCalled()
+        {
+            return called;
+        }
+    }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
index b83884a..3dbde1f 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/extensions/ForkedProcessEventNotifierTest.java
@@ -30,17 +30,17 @@ import org.apache.maven.plugin.surefire.booterclient.output.ForkedProcessStandar
 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.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
+import org.apache.maven.surefire.extensions.EventHandler;
+import org.apache.maven.surefire.extensions.ForkNodeArguments;
+import org.apache.maven.surefire.extensions.util.CountdownCloseable;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.runners.Enclosed;
@@ -50,7 +50,6 @@ 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;
 
@@ -66,6 +65,7 @@ import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.Charset;
 import java.util.Map;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.LinkedTransferQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -79,13 +79,8 @@ import static org.apache.maven.surefire.api.util.internal.Channels.newChannel;
 import static org.fest.assertions.Assertions.assertThat;
 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.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
 
 /**
  * Test for {@link ForkedProcessEventNotifier}.
@@ -124,10 +119,8 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
@@ -136,7 +129,10 @@ public class ForkedProcessEventNotifierTest
                     notifier.notifyEvent( eventHandler.pullEvent() );
                 }
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.counter.get() )
                 .isEqualTo( props.size() );
         }
@@ -310,16 +306,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -350,17 +347,19 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
-            verify( arguments, never() ).dumpStreamText( anyString() );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.dumpStreamText )
+                .isEmpty();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -403,15 +402,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -436,16 +437,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -466,16 +468,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -496,16 +499,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -528,16 +532,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -560,16 +565,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -591,17 +597,19 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
 
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+
+            assertThat( arguments.isCalled() )
+                .isFalse();
 
             assertThat( listener.called.get() )
                 .isTrue();
@@ -627,16 +635,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -659,16 +668,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -691,16 +701,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -723,15 +734,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -754,15 +767,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -785,15 +800,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -816,16 +833,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -847,16 +865,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -879,36 +898,35 @@ public class ForkedProcessEventNotifierTest
 
             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 );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( true, true, true, true );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 countdown.awaitClosed();
             }
 
-            ArgumentCaptor<String> dumpLine = ArgumentCaptor.forClass( String.class );
-            verify( logger, times( 1 ) ).debug( dumpLine.capture() );
-            assertThat( dumpLine.getAllValues() )
-                .hasSize( 1 )
+            assertThat( arguments.isCalled() )
+                .isTrue();
+
+            assertThat( logger.isCalled() )
+                .isTrue();
+
+            assertThat( logger.debug )
+                .hasSize( 1 );
+
+            assertThat( logger.debug.peek() )
                 .contains( ":maven-surefire-event:\u000c:abnormal-run:-:" );
 
-            ArgumentCaptor<String> dumpText = ArgumentCaptor.forClass( String.class );
-            verify( arguments, times( 1 ) ).dumpStreamText( dumpText.capture() );
             String dump = "Corrupted STDOUT by directly writing to native stream in forked JVM 0.";
-            assertThat( dumpText.getAllValues() )
+            assertThat( arguments.dumpStreamText )
                 .hasSize( 1 )
                 .contains( format( dump + " Stream '%s'.", ":maven-surefire-event:\u000c:abnormal-run:-:" ) );
 
-            ArgumentCaptor<String> warning = ArgumentCaptor.forClass( String.class );
-            verify( arguments, times( 1 ) ).logWarningAtEnd( warning.capture() );
             dump += " See FAQ web page and the dump file ";
-            assertThat( warning.getAllValues() )
+            assertThat( arguments.logWarningAtEnd )
                 .hasSize( 1 );
-            assertThat( warning.getAllValues().get( 0 ) )
+            assertThat( arguments.logWarningAtEnd.peek() )
                 .startsWith( dump );
         }
 
@@ -934,18 +952,17 @@ public class ForkedProcessEventNotifierTest
 
             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 );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-
-            verifyZeroInteractions( logger );
-
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
             assertThat( listener.called.get() )
                 .isTrue();
         }
@@ -1048,16 +1065,17 @@ public class ForkedProcessEventNotifierTest
 
             EH eventHandler = new EH();
             CountdownCloseable countdown = new CountdownCloseable( mock( Closeable.class ), 0 );
-            ConsoleLogger logger = mock( ConsoleLogger.class );
-            ForkNodeArguments arguments = mock( ForkNodeArguments.class );
-            when( arguments.dumpStreamText( anyString() ) ).thenReturn( new File( "" ) );
-            when( arguments.getConsoleLogger() ).thenReturn( logger );
+            ConsoleLoggerMock logger = new ConsoleLoggerMock( false, false, false, false );
+            ForkNodeArgumentsMock arguments = new ForkNodeArgumentsMock( logger, new File( "" ) );
             try ( EventConsumerThread t = new EventConsumerThread( "t", channel, eventHandler, countdown, arguments ) )
             {
                 t.start();
                 notifier.notifyEvent( eventHandler.pullEvent() );
             }
-            verifyZeroInteractions( logger );
+            assertThat( logger.isCalled() )
+                .isFalse();
+            assertThat( arguments.isCalled() )
+                .isFalse();
         }
     }
 
@@ -1263,4 +1281,166 @@ public class ForkedProcessEventNotifierTest
             cache.add( event );
         }
     }
+
+    /**
+     * Threadsafe impl. Mockito and Powermock are not thread-safe.
+     */
+    private static class ForkNodeArgumentsMock implements ForkNodeArguments
+    {
+        private final ConcurrentLinkedQueue<String> dumpStreamText = new ConcurrentLinkedQueue<>();
+        private final ConcurrentLinkedQueue<String> logWarningAtEnd = new ConcurrentLinkedQueue<>();
+        private final ConsoleLogger logger;
+        private final File dumpStreamTextFile;
+
+        ForkNodeArgumentsMock( ConsoleLogger logger, File dumpStreamTextFile )
+        {
+            this.logger = logger;
+            this.dumpStreamTextFile = dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public String getSessionId()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int getForkChannelId()
+        {
+            return 0;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamText( @Nonnull String text )
+        {
+            dumpStreamText.add( text );
+            return dumpStreamTextFile;
+        }
+
+        @Nonnull
+        @Override
+        public File dumpStreamException( @Nonnull Throwable t )
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void logWarningAtEnd( @Nonnull String text )
+        {
+            logWarningAtEnd.add( text );
+        }
+
+        @Nonnull
+        @Override
+        public ConsoleLogger getConsoleLogger()
+        {
+            return logger;
+        }
+
+        boolean isCalled()
+        {
+            return !dumpStreamText.isEmpty() || !logWarningAtEnd.isEmpty();
+        }
+    }
+
+    /**
+     * Threadsafe impl. Mockito and Powermock are not thread-safe.
+     */
+    private static class ConsoleLoggerMock implements ConsoleLogger
+    {
+        final ConcurrentLinkedQueue<String> debug = new ConcurrentLinkedQueue<>();
+        final ConcurrentLinkedQueue<String> info = new ConcurrentLinkedQueue<>();
+        final ConcurrentLinkedQueue<String> error = new ConcurrentLinkedQueue<>();
+        final boolean isDebug;
+        final boolean isInfo;
+        final boolean isWarning;
+        final boolean isError;
+        boolean called;
+        boolean isDebugEnabledCalled;
+        boolean isInfoEnabledCalled;
+
+        ConsoleLoggerMock( boolean isDebug, boolean isInfo, boolean isWarning, boolean isError )
+        {
+            this.isDebug = isDebug;
+            this.isInfo = isInfo;
+            this.isWarning = isWarning;
+            this.isError = isError;
+        }
+
+        @Override
+        public boolean isDebugEnabled()
+        {
+            isDebugEnabledCalled = true;
+            called = true;
+            return isDebug;
+        }
+
+        @Override
+        public void debug( String message )
+        {
+            debug.add( message );
+            called = true;
+        }
+
+        @Override
+        public boolean isInfoEnabled()
+        {
+            isInfoEnabledCalled = true;
+            called = true;
+            return isInfo;
+        }
+
+        @Override
+        public void info( String message )
+        {
+            info.add( message );
+            called = true;
+        }
+
+        @Override
+        public boolean isWarnEnabled()
+        {
+            called = true;
+            return isWarning;
+        }
+
+        @Override
+        public void warning( String message )
+        {
+            called = true;
+        }
+
+        @Override
+        public boolean isErrorEnabled()
+        {
+            called = true;
+            return isError;
+        }
+
+        @Override
+        public void error( String message )
+        {
+            error.add( message );
+            called = true;
+        }
+
+        @Override
+        public void error( String message, Throwable t )
+        {
+            called = true;
+        }
+
+        @Override
+        public void error( Throwable t )
+        {
+            called = true;
+        }
+
+        boolean isCalled()
+        {
+            return called;
+        }
+    }
 }