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/02/07 00:51:54 UTC
[maven-surefire] branch maven2surefire-jvm-communication updated:
finished implementation of extension in ForkStarter (missing JavaDoc in
ForkChannel and unit test for NetworkingProcessExecutor - rework)
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch maven2surefire-jvm-communication
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
The following commit(s) were added to refs/heads/maven2surefire-jvm-communication by this push:
new 270160d finished implementation of extension in ForkStarter (missing JavaDoc in ForkChannel and unit test for NetworkingProcessExecutor - rework)
270160d is described below
commit 270160d0b48ade2f1db289047fe5e48fe8585a48
Author: tibordigana <ti...@apache.org>
AuthorDate: Fri Feb 7 01:51:40 2020 +0100
finished implementation of extension in ForkStarter (missing JavaDoc in ForkChannel and unit test for NetworkingProcessExecutor - rework)
---
.../plugin/surefire/AbstractSurefireMojo.java | 4 +-
.../plugin/surefire/booterclient/ForkStarter.java | 40 +++---
.../output/ThreadedStreamConsumer.java | 1 +
.../surefire/extensions/LegacyForkChannel.java | 79 ++++++++++--
.../surefire/extensions/LegacyForkNodeFactory.java | 6 +-
.../extensions/NetworkingProcessExecutor.java | 4 +-
.../surefire/extensions/PipeProcessExecutor.java | 143 ---------------------
.../surefire/extensions/SurefireForkChannel.java | 70 +++++++++-
.../extensions/SurefireForkNodeFactory.java | 5 +-
...NodeFactory.java => CloseableDaemonThread.java} | 21 ++-
.../surefire/extensions/ExecutableCommandline.java | 40 ------
.../maven/surefire/extensions/ForkChannel.java | 123 ++++++++++++++++--
.../maven/surefire/extensions/ForkNodeFactory.java | 3 +-
.../extensions/util/LineConsumerThread.java | 7 +-
.../surefire/extensions/util/StreamFeeder.java | 7 +-
15 files changed, 296 insertions(+), 257 deletions(-)
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 676b18f..2239921 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -25,8 +25,8 @@ import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.surefire.extensions.LegacyForkNodeFactory;
import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
-import org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
import org.apache.maven.plugins.annotations.Component;
@@ -2270,7 +2270,7 @@ public abstract class AbstractSurefireMojo
private ForkNodeFactory getForkNodeFactory()
{
ForkNodeFactory forkNode = getForkNode();
- return forkNode == null ? new SurefireForkNodeFactory() : forkNode;
+ return forkNode == null ? new LegacyForkNodeFactory() : forkNode;
}
@Nonnull
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
index 73340a8..8c50bf7 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
@@ -33,11 +33,10 @@ import org.apache.maven.plugin.surefire.booterclient.output.NativeStdErrStreamCo
import org.apache.maven.plugin.surefire.booterclient.output.ThreadedStreamConsumer;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
+import org.apache.maven.surefire.extensions.CloseableDaemonThread;
import org.apache.maven.surefire.extensions.util.CommandlineExecutor;
import org.apache.maven.surefire.extensions.util.CommandlineStreams;
import org.apache.maven.surefire.extensions.util.CountdownCloseable;
-import org.apache.maven.surefire.extensions.util.LineConsumerThread;
-import org.apache.maven.surefire.extensions.util.StreamFeeder;
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
@@ -50,6 +49,7 @@ import org.apache.maven.surefire.extensions.ForkChannel;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.providerapi.SurefireProvider;
import org.apache.maven.surefire.report.StackTraceWriter;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import org.apache.maven.surefire.suite.RunResult;
import org.apache.maven.surefire.testset.TestRequest;
import org.apache.maven.surefire.util.DefaultScanResult;
@@ -568,7 +568,7 @@ public class ForkStarter
final ForkChannel forkChannel;
try
{
- forkChannel = forkNodeFactory.createForkChannel();
+ forkChannel = forkNodeFactory.createForkChannel( forkNumber );
tempDir = forkConfiguration.getTempDirectory().getCanonicalPath();
BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
Long pluginPid = forkConfiguration.getPluginPlatform().getPluginPid();
@@ -619,33 +619,35 @@ public class ForkStarter
Integer result = null;
RunResult runResult = null;
SurefireBooterForkException booterForkException = null;
- StreamFeeder in = null;
- LineConsumerThread out = null;
- LineConsumerThread err = null;
+ CloseableDaemonThread in = null;
+ CloseableDaemonThread out = null;
+ CloseableDaemonThread err = null;
DefaultReporterFactory reporter = forkClient.getDefaultReporterFactory();
currentForkClients.add( forkClient );
CountdownCloseable countdownCloseable = new CountdownCloseable( eventConsumer, 2 );
- //todo implement extension: forkChannel.createExecutableCommandline()
- //todo implement extension: executableCommandline.executeCommandLineAsCallable(...)
try ( CommandlineExecutor exec = new CommandlineExecutor( cli, countdownCloseable ) )
{
- // default impl of the extension - solves everything including the encoder/decoder, Process starter,
- // adaptation of the streams to pipes and sockets
- // non-default impl may use another classes and not the LineConsumerThread, StreamFeeder - freedom
- // BEGIN: beginning of the call of the extension
CommandlineStreams streams = exec.execute();
closer.addCloseable( streams );
- in = new StreamFeeder( "std-in-fork-" + forkNumber, streams.getStdInChannel(), commandReader );
+
+ in = forkChannel.useStdIn()
+ ? forkChannel.bindCommandReader( commandReader, streams.getStdInChannel() )
+ : forkChannel.bindCommandReader( commandReader );
in.start();
- out = new LineConsumerThread( "std-out-fork-" + forkNumber, streams.getStdOutChannel(),
- eventConsumer, countdownCloseable );
+
+ StreamConsumer stdErrConsumer = new NativeStdErrStreamConsumer( reporter );
+
+ out = forkChannel.useStdOut()
+ ? forkChannel.bindEventHandler( eventConsumer, streams.getStdOutChannel(), countdownCloseable )
+ : forkChannel.bindStdOutConsumer( stdErrConsumer );
out.start();
- NativeStdErrStreamConsumer stdErrConsumer = new NativeStdErrStreamConsumer( reporter );
- err = new LineConsumerThread( "std-err-fork-" + forkNumber, streams.getStdErrChannel(),
- stdErrConsumer, countdownCloseable );
+
+ err = forkChannel.useStdErr()
+ ? forkChannel.bindStdErrConsumer( stdErrConsumer, streams.getStdErrChannel(), countdownCloseable )
+ : forkChannel.bindStdErrConsumer( stdErrConsumer );
err.start();
+
result = exec.awaitExit();
- // END: end of the call of the extension
if ( forkClient.hadTimeout() )
{
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ThreadedStreamConsumer.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ThreadedStreamConsumer.java
index b3c5c29..316167c 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ThreadedStreamConsumer.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ThreadedStreamConsumer.java
@@ -115,6 +115,7 @@ public final class ThreadedStreamConsumer
}
@Override
+ // todo remove this method and use object instead of string
public void handleEvent( @Nonnull String event )
{
consumeLine( event );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
index 28cad5a..c462142 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
@@ -19,32 +19,95 @@ package org.apache.maven.plugin.surefire.extensions;
* under the License.
*/
-import org.apache.maven.surefire.extensions.ExecutableCommandline;
+import org.apache.maven.surefire.extensions.CloseableDaemonThread;
+import org.apache.maven.surefire.extensions.CommandReader;
import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.util.CountdownCloseable;
+import org.apache.maven.surefire.extensions.util.LineConsumerThread;
+import org.apache.maven.surefire.extensions.util.StreamFeeder;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import javax.annotation.Nonnull;
-import java.io.IOException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
/**
*
*/
-final class LegacyForkChannel implements ForkChannel
+final class LegacyForkChannel extends ForkChannel
{
+ protected LegacyForkChannel( int forkChannelId )
+ {
+ super( forkChannelId );
+ }
+
@Override
public String getForkNodeConnectionString()
{
- return "pipe://";
+ return "pipe://" + getForkChannelId();
+ }
+
+ @Override
+ public boolean useStdIn()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean useStdOut()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean useStdErr()
+ {
+ return true;
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
+ @Nonnull WritableByteChannel stdIn )
+ {
+ return new StreamFeeder( "std-in-fork-" + getForkChannelId(), stdIn, commands );
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdOut,
+ @Nonnull CountdownCloseable countdownCloseable )
+ {
+ return new LineConsumerThread( "std-out-fork-" + getForkChannelId(), stdOut, consumer, countdownCloseable );
+ }
+
+ @Override
+ public CloseableDaemonThread bindStdOutConsumer( @Nonnull StreamConsumer consumer )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindStdErrConsumer(
+ @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdErr, @Nonnull CountdownCloseable countdownCloseable )
+ {
+ return new LineConsumerThread( "std-err-fork-" + getForkChannelId(), stdErr, consumer, countdownCloseable );
}
- @Nonnull
@Override
- public ExecutableCommandline createExecutableCommandline() throws IOException
+ public CloseableDaemonThread bindStdErrConsumer( @Nonnull StreamConsumer consumer )
{
- return new PipeProcessExecutor();
+ throw new UnsupportedOperationException();
}
@Override
- public void close() throws IOException
+ public void close()
{
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
index 7231d00..836464e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
@@ -22,8 +22,8 @@ package org.apache.maven.plugin.surefire.extensions;
import org.apache.maven.surefire.extensions.ForkChannel;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
-import java.io.IOException;
/**
*
@@ -32,8 +32,8 @@ public class LegacyForkNodeFactory implements ForkNodeFactory
{
@Nonnull
@Override
- public ForkChannel createForkChannel() throws IOException
+ public ForkChannel createForkChannel( @Nonnegative int forkChannelId )
{
- return new LegacyForkChannel();
+ return new LegacyForkChannel( forkChannelId );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/NetworkingProcessExecutor.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/NetworkingProcessExecutor.java
index eecb5ca..1164ba8 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/NetworkingProcessExecutor.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/NetworkingProcessExecutor.java
@@ -23,7 +23,6 @@ import org.apache.maven.surefire.booter.Command;
import org.apache.maven.surefire.booter.MasterProcessCommand;
import org.apache.maven.surefire.extensions.CommandReader;
import org.apache.maven.surefire.extensions.EventHandler;
-import org.apache.maven.surefire.extensions.ExecutableCommandline;
import org.apache.maven.surefire.extensions.StdErrStreamLine;
import org.apache.maven.surefire.extensions.StdOutStreamLine;
import org.apache.maven.surefire.shared.utils.cli.CommandLineUtils;
@@ -48,7 +47,7 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 3.0.0-M4
*/
-final class NetworkingProcessExecutor implements ExecutableCommandline
+final class NetworkingProcessExecutor
{
private final AsynchronousServerSocketChannel server;
private final ExecutorService executorService;
@@ -60,7 +59,6 @@ final class NetworkingProcessExecutor implements ExecutableCommandline
}
@Nonnull
- @Override
public Callable<Integer> executeCommandLineAsCallable( @Nonnull Commandline cli,
@Nonnull final CommandReader commands,
@Nonnull final EventHandler events,
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/PipeProcessExecutor.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/PipeProcessExecutor.java
deleted file mode 100644
index ad3bcfc..0000000
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/PipeProcessExecutor.java
+++ /dev/null
@@ -1,143 +0,0 @@
-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.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessCommand;
-import org.apache.maven.surefire.extensions.CommandReader;
-import org.apache.maven.surefire.extensions.EventHandler;
-import org.apache.maven.surefire.extensions.ExecutableCommandline;
-import org.apache.maven.surefire.extensions.StdErrStreamLine;
-import org.apache.maven.surefire.extensions.StdOutStreamLine;
-import org.apache.maven.surefire.shared.utils.cli.CommandLineUtils;
-import org.apache.maven.surefire.shared.utils.cli.Commandline;
-import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
-
-import javax.annotation.Nonnull;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.Callable;
-
-import static java.nio.charset.StandardCharsets.US_ASCII;
-
-/**
- * Commands which are sent from plugin to the forked jvm.
- * <br>
- * Events are received from the forked jvm.
- * <br>
- * <br>
- * magic number : opcode [: opcode specific data]*
- * <br>
- * or data encoded with Base64
- * <br>
- * magic number : opcode [: Base64(opcode specific data)]*
- *
- * The command and event must be finished by the character ':' and New Line.
- *
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 3.0.0-M4
- */
-final class PipeProcessExecutor
- implements ExecutableCommandline
-{
- @Override
- @Nonnull
- public Callable<Integer> executeCommandLineAsCallable( @Nonnull Commandline cli,
- @Nonnull CommandReader commands,
- @Nonnull EventHandler events,
- StdOutStreamLine stdOut,
- StdErrStreamLine stdErr,
- @Nonnull Runnable runAfterProcessTermination )
- throws Exception
- {
- return CommandLineUtils.executeCommandLineAsCallable( cli, new CommandReaderAdapter( commands ),
- new EventHandlerAdapter( events ), stdErr, 0, runAfterProcessTermination, US_ASCII );
- }
-
- private static class EventHandlerAdapter implements StreamConsumer
- {
- private final EventHandler events;
-
- private EventHandlerAdapter( EventHandler events )
- {
- this.events = events;
- }
-
- @Override
- public void consumeLine( String line )
- {
- events.handleEvent( line );
- }
- }
-
- private static class CommandReaderAdapter extends InputStream
- {
- private final CommandReader commands;
- private byte[] currentBuffer;
- private int currentPos;
- private volatile boolean closed;
-
- CommandReaderAdapter( CommandReader commands )
- {
- this.commands = commands;
- }
-
- @Override
- public int read() throws IOException
- {
- if ( commands.isClosed() )
- {
- close();
- }
-
- if ( closed )
- {
- return -1;
- }
-
- if ( currentBuffer == null )
- {
- Command cmd = commands.readNextCommand();
- if ( cmd == null )
- {
- currentPos = 0;
- return -1;
- }
- MasterProcessCommand cmdType = cmd.getCommandType();
- currentBuffer = cmdType.hasDataType() ? cmdType.encode( cmd.getData() ) : cmdType.encode();
- }
-
- @SuppressWarnings( "checkstyle:magicnumber" )
- int b = currentBuffer[currentPos++] & 0xff;
- if ( currentPos == currentBuffer.length )
- {
- currentBuffer = null;
- currentPos = 0;
- }
- return b;
- }
-
- @Override
- public void close()
- {
- closed = true;
- }
- }
-}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
index 2238898..e1932a9 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
@@ -19,14 +19,19 @@ package org.apache.maven.plugin.surefire.extensions;
* under the License.
*/
-import org.apache.maven.surefire.extensions.ExecutableCommandline;
+import org.apache.maven.surefire.extensions.CloseableDaemonThread;
+import org.apache.maven.surefire.extensions.CommandReader;
import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.util.CountdownCloseable;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketOption;
import java.nio.channels.AsynchronousServerSocketChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -40,14 +45,15 @@ import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDae
/**
*
*/
-final class SurefireForkChannel implements ForkChannel
+final class SurefireForkChannel extends ForkChannel
{
private final ExecutorService executorService;
private final AsynchronousServerSocketChannel server;
private final int serverPort;
- SurefireForkChannel() throws IOException
+ SurefireForkChannel( int forkChannelId ) throws IOException
{
+ super( forkChannelId );
executorService = Executors.newCachedThreadPool( newDaemonThreadFactory() );
server = open( withThreadPool( executorService ) );
setTrueOptions( SO_REUSEADDR, TCP_NODELAY, SO_KEEPALIVE );
@@ -73,11 +79,63 @@ final class SurefireForkChannel implements ForkChannel
return "tcp://127.0.0.1:" + serverPort;
}
- @Nonnull
@Override
- public ExecutableCommandline createExecutableCommandline()
+ public boolean useStdIn()
{
- return new NetworkingProcessExecutor( server, executorService );
+ return false;
+ }
+
+ @Override
+ public boolean useStdOut()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean useStdErr()
+ {
+ return false;
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
+ @Nonnull WritableByteChannel stdIn )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands ) throws IOException
+ {
+ return null;
+ }
+
+ @Override
+ public CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdOut,
+ @Nonnull CountdownCloseable countdownCloseable )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindStdOutConsumer( @Nonnull StreamConsumer consumer ) throws IOException
+ {
+ return null;
+ }
+
+ @Override
+ public CloseableDaemonThread bindStdErrConsumer( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdErr,
+ @Nonnull CountdownCloseable countdownCloseable )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindStdErrConsumer( @Nonnull StreamConsumer consumer ) throws IOException
+ {
+ return null;
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
index c483619..c076ba2 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
@@ -22,6 +22,7 @@ package org.apache.maven.plugin.surefire.extensions;
import org.apache.maven.surefire.extensions.ForkChannel;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.io.IOException;
@@ -32,8 +33,8 @@ public class SurefireForkNodeFactory implements ForkNodeFactory
{
@Nonnull
@Override
- public ForkChannel createForkChannel() throws IOException
+ public ForkChannel createForkChannel( @Nonnegative int forkChannelId ) throws IOException
{
- return new SurefireForkChannel();
+ return new SurefireForkChannel( forkChannelId );
}
}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
similarity index 69%
copy from surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
copy to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
index c054776..a15ed8a 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
@@ -20,19 +20,18 @@ package org.apache.maven.surefire.extensions;
*/
import javax.annotation.Nonnull;
-import java.io.IOException;
+import java.io.Closeable;
/**
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 3.0.0-M4
+ * The base thread class used to handle a stream and transform it to an object.
*/
-public interface ForkNodeFactory
+public abstract class CloseableDaemonThread extends Thread implements Closeable
{
- /**
- * Opens and closes the channel.
- *
- * @return specific implementation of the communication channel
- * @throws IOException if cannot open the channel
- */
- @Nonnull ForkChannel createForkChannel() throws IOException;
+ protected CloseableDaemonThread( @Nonnull String threadName )
+ {
+ setName( threadName );
+ setDaemon( true );
+ }
+
+ public abstract void disable();
}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ExecutableCommandline.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ExecutableCommandline.java
deleted file mode 100644
index ed7a8ec..0000000
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ExecutableCommandline.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.apache.maven.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.surefire.shared.utils.cli.Commandline;
-
-import javax.annotation.Nonnull;
-import java.util.concurrent.Callable;
-
-/**
- * todo add javadoc
- */
-public interface ExecutableCommandline
-{
- @Nonnull
- Callable<Integer> executeCommandLineAsCallable( @Nonnull Commandline cli,
- @Nonnull CommandReader commands,
- @Nonnull EventHandler events,
- StdOutStreamLine stdOut,
- StdErrStreamLine stdErr,
- @Nonnull Runnable runAfterProcessTermination )
- throws Exception;
-}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
index 62ef9bf..da19dfc 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
@@ -19,24 +19,125 @@ package org.apache.maven.surefire.extensions;
* under the License.
*/
+import org.apache.maven.surefire.extensions.util.CountdownCloseable;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
+
import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
/**
- * The constructor prepares I/O or throws {@link IOException}. Open channel can be closed and closes all streams.
- * <br>
- * The forked JVM uses the {@link #createExecutableCommandline() connection string}.
- * The executable CLI {@link #createExecutableCommandline()} is using the streams. This method and constructor should
- * not be blocked while establishing the connection.
+ * The constructor prepares I/O or throws {@link IOException}.
*/
-public interface ForkChannel extends Closeable
+public abstract class ForkChannel implements Closeable
{
- String getForkNodeConnectionString();
+ private final int forkChannelId;
+
+ /**
+ *
+ * @param forkChannelId
+ */
+ protected ForkChannel( int forkChannelId )
+ {
+ this.forkChannelId = forkChannelId;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public abstract String getForkNodeConnectionString();
+
+ /**
+ *
+ * @return
+ */
+ public abstract boolean useStdIn();
+
+ /**
+ *
+ * @return
+ */
+ public abstract boolean useStdOut();
+
+ /**
+ *
+ * @return
+ */
+ public abstract boolean useStdErr();
+
+ /**
+ *
+ * @param commands
+ * @param stdIn
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
+ @Nonnull WritableByteChannel stdIn )
+ throws IOException;
+
+ /**
+ *
+ * @param commands
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands )
+ throws IOException;
+
+ /**
+ *
+ * @param consumer
+ * @param stdOut
+ * @param countdownCloseable
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdOut,
+ @Nonnull CountdownCloseable countdownCloseable )
+ throws IOException;
+
+ /**
+ *
+ * @param consumer
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindStdOutConsumer( @Nonnull StreamConsumer consumer )
+ throws IOException;
+
+ /**
+ *
+ * @param consumer
+ * @param stdErr
+ * @param countdownCloseable
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindStdErrConsumer( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdErr,
+ @Nonnull CountdownCloseable countdownCloseable )
+ throws IOException;
- @Nonnull
- ExecutableCommandline createExecutableCommandline() throws IOException;
+ /**
+ *
+ * @param consumer
+ * @return
+ * @throws IOException
+ */
+ public abstract CloseableDaemonThread bindStdErrConsumer( @Nonnull StreamConsumer consumer )
+ throws IOException;
- @Override
- void close() throws IOException;
+ /**
+ *
+ * @return
+ */
+ protected final int getForkChannelId()
+ {
+ return forkChannelId;
+ }
}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
index c054776..3e0d6a6 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
@@ -19,6 +19,7 @@ package org.apache.maven.surefire.extensions;
* under the License.
*/
+import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.io.IOException;
@@ -34,5 +35,5 @@ public interface ForkNodeFactory
* @return specific implementation of the communication channel
* @throws IOException if cannot open the channel
*/
- @Nonnull ForkChannel createForkChannel() throws IOException;
+ @Nonnull ForkChannel createForkChannel( @Nonnegative int forkChannelId ) throws IOException;
}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/LineConsumerThread.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/LineConsumerThread.java
index 109e541..162af4b 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/LineConsumerThread.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/LineConsumerThread.java
@@ -19,10 +19,10 @@ package org.apache.maven.surefire.extensions.util;
* under the License.
*/
+import org.apache.maven.surefire.extensions.CloseableDaemonThread;
import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import javax.annotation.Nonnull;
-import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
@@ -31,7 +31,7 @@ import java.util.Scanner;
/**
*
*/
-public final class LineConsumerThread extends Thread implements Closeable
+public final class LineConsumerThread extends CloseableDaemonThread
{
private final Charset encoding;
private final ReadableByteChannel channel;
@@ -50,8 +50,7 @@ public final class LineConsumerThread extends Thread implements Closeable
@Nonnull ReadableByteChannel channel, @Nonnull StreamConsumer consumer,
@Nonnull CountdownCloseable countdownCloseable, @Nonnull Charset encoding )
{
- setName( threadName );
- setDaemon( true );
+ super( threadName );
this.channel = channel;
this.consumer = consumer;
this.countdownCloseable = countdownCloseable;
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/StreamFeeder.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/StreamFeeder.java
index 9305d07..78e5ce0 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/StreamFeeder.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/StreamFeeder.java
@@ -21,10 +21,10 @@ package org.apache.maven.surefire.extensions.util;
import org.apache.maven.surefire.booter.Command;
import org.apache.maven.surefire.booter.MasterProcessCommand;
+import org.apache.maven.surefire.extensions.CloseableDaemonThread;
import org.apache.maven.surefire.extensions.CommandReader;
import javax.annotation.Nonnull;
-import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
@@ -34,7 +34,7 @@ import java.nio.channels.WritableByteChannel;
/**
*
*/
-public class StreamFeeder extends Thread implements Closeable
+public class StreamFeeder extends CloseableDaemonThread
{
private final WritableByteChannel channel;
private final CommandReader commandReader;
@@ -45,8 +45,7 @@ public class StreamFeeder extends Thread implements Closeable
public StreamFeeder( @Nonnull String threadName, @Nonnull WritableByteChannel channel,
@Nonnull CommandReader commandReader )
{
- setName( threadName );
- setDaemon( true );
+ super( threadName );
this.channel = channel;
this.commandReader = commandReader;
}