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 <tibordig...@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:tibordig...@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:tibordig...@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:tibordig...@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; }