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/12 00:32:41 UTC
[maven-surefire] branch maven2surefire-jvm-communication updated
(9f4fb37 -> 7545eab)
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a change to branch maven2surefire-jvm-communication
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.
discard 9f4fb37 Finished JavaDoc, TCP client, renamed magic number.
discard f67a727 JavaDoc in ForkChannel
discard 97f8408 fixed ForkStarter
discard d3d4153 fixed checkstyle
discard be1981e finished implementation of extension in ForkStarter, unit test and removed unused code (missing JavaDoc)
discard 270160d finished implementation of extension in ForkStarter (missing JavaDoc in ForkChannel and unit test for NetworkingProcessExecutor - rework)
omit 9b0b15d fixed Surefire946KillMainProcessInReusableForkIT
omit 43bbb2a fixed unit tests and completed surefire-shadefire
omit 1f013b9 added surefire-extensions-api to classpath
omit ecc2b8c Revert "investigate dumps on Ubuntu"
omit f0fd66c investigate only Ubuntu
omit a8fba24 upload artifact
omit a2850b0 cat dumps
omit 1d09662 skipped tests
omit 83b7f52 -fn
omit 4be01d7 investigate dumps on Ubuntu
omit b413542 removed '-DskipTests', '-DskipITs'
omit f0c9ae5 surefire JAR not created. Let's use the old version.
omit c070d9e fixed few tests after bad merge
omit e2254d8 used reader of Command-s instead of InputStream
omit aaeccca [SUREFIRE-1658] TCP/IP Channel for forked Surefire JVM. Extensions API and SPI. Polymorphism for remote and local process communication.
add 3a4efc0 fixed warnings in AbstractSurefireMojo upon the reports in IntelliJ IDEA
add 7fad650 excluded H23, H29 and H30
add 733d92f prune local repo in Travis CI
add fb76d32 [jenkinsfile] excluded H40 and H41
add 5e8ee4f exluded H24 and explicit GC setting
new 7545eab [SUREFIRE-1658] TCP/IP Channel for forked Surefire JVM. Extensions API and SPI. Polymorphism for remote and local process communication.
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 (9f4fb37)
\
N -- N -- N refs/heads/maven2surefire-jvm-communication (7545eab)
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:
.travis.yml | 9 +-
Jenkinsfile | 12 +-
.../plugin/surefire/AbstractSurefireMojo.java | 7 +-
pom.xml | 2 +-
.../org/apache/maven/surefire/suite/RunResult.java | 2 +-
.../maven/surefire/util/ReflectionUtils.java | 12 +-
.../maven/surefire/booter/SurefireReflector.java | 40 ++--
.../java/org/apache/maven/surefire/booter/Foo.java | 17 +-
.../surefire/booter/SurefireReflectorTest.java | 226 ++++++++++++++++++++-
9 files changed, 265 insertions(+), 62 deletions(-)
[maven-surefire] 01/01: [SUREFIRE-1658] TCP/IP Channel for forked
Surefire JVM. Extensions API and SPI. Polymorphism for remote and local
process communication.
Posted by ti...@apache.org.
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
commit 7545eabee83824159bb8286d701c7fced21e2fe7
Author: tibordigana <ti...@apache.org>
AuthorDate: Sat Jul 6 17:51:13 2019 +0200
[SUREFIRE-1658] TCP/IP Channel for forked Surefire JVM. Extensions API and SPI. Polymorphism for remote and local process communication.
---
.github/workflows/maven.yml | 2 +-
Jenkinsfile | 6 +-
.../maven/plugin/failsafe/IntegrationTestMojo.java | 10 +
maven-surefire-common/pom.xml | 16 -
.../plugin/surefire/AbstractSurefireMojo.java | 72 ++--
.../maven/plugin/surefire/CommonReflector.java | 18 +-
.../surefire/SurefireDependencyResolver.java | 1 +
.../AbstractClasspathForkConfiguration.java | 7 +-
.../surefire/booterclient/BooterSerializer.java | 5 +-
.../booterclient/ClasspathForkConfiguration.java | 7 +-
.../booterclient/DefaultForkConfiguration.java | 13 +-
.../surefire/booterclient/ForkConfiguration.java | 2 +
.../plugin/surefire/booterclient/ForkStarter.java | 96 +++--
.../booterclient/JarManifestForkConfiguration.java | 7 +-
.../ModularClasspathForkConfiguration.java | 7 +-
...InputStream.java => AbstractCommandReader.java} | 16 +-
...ommandStream.java => DefaultCommandReader.java} | 60 +--
.../DefferedChannelCommandSender.java | 14 +-
.../lazytestprovider/TestLessInputStream.java | 7 +-
.../lazytestprovider/TestProvidingInputStream.java | 14 +-
.../surefire/booterclient/output/ForkClient.java | 3 +-
.../booterclient/output/ForkedChannelDecoder.java | 6 +-
.../output/NativeStdErrStreamConsumer.java | 4 +-
.../output/NativeStdOutStreamConsumer.java | 28 +-
.../output/ThreadedStreamConsumer.java | 13 +-
.../surefire/extensions/LegacyForkChannel.java | 98 +++++
.../surefire/extensions/LegacyForkNodeFactory.java | 19 +-
.../surefire/extensions/SurefireForkChannel.java | 140 +++++++
.../extensions/SurefireForkNodeFactory.java | 21 +-
.../AbstractSurefireMojoJava7PlusTest.java | 27 +-
.../plugin/surefire/AbstractSurefireMojoTest.java | 44 ++-
.../maven/plugin/surefire/CommonReflectorTest.java | 50 +++
.../maven/plugin/surefire/MojoMocklessTest.java | 7 +
.../plugin/surefire/SurefireReflectorTest.java | 71 ----
...ooterDeserializerProviderConfigurationTest.java | 8 +-
...BooterDeserializerStartupConfigurationTest.java | 23 +-
.../booterclient/DefaultForkConfigurationTest.java | 48 ++-
.../booterclient/ForkConfigurationTest.java | 17 +-
.../surefire/booterclient/ForkStarterTest.java | 12 +-
.../booterclient/ForkingRunListenerTest.java | 12 +-
.../plugin/surefire/booterclient/MainClass.java | 14 +-
.../ModularClasspathForkConfigurationTest.java | 10 +-
.../TestLessInputStreamBuilderTest.java | 59 ++-
.../TestProvidingInputStreamTest.java | 150 ++++++--
.../booterclient/output/ForkClientTest.java | 54 +--
.../output/ForkedChannelDecoderTest.java | 90 ++---
.../org/apache/maven/surefire/JUnit4SuiteTest.java | 4 +-
.../maven/surefire/extensions/ForkChannelTest.java | 146 ++++++++
.../maven/plugin/surefire/SurefirePlugin.java | 10 +
pom.xml | 5 +-
.../maven/surefire/booter/BaseProviderFactory.java | 79 ++--
.../org/apache/maven/surefire/booter/Command.java | 21 +-
.../maven/surefire/booter/ForkedProcessEvent.java | 4 +-
.../surefire/booter/ForkingReporterFactory.java | 5 +-
.../maven/surefire/booter/ForkingRunListener.java | 5 +-
.../surefire/booter/MasterProcessCommand.java | 159 +++-----
.../surefire/booter/RunOrderParametersAware.java | 30 --
.../surefire/booter/TestArtifactInfoAware.java | 30 --
.../CommandChainReader.java} | 19 +-
.../{booter => providerapi}/CommandListener.java | 4 +-
.../providerapi/MasterProcessChannelDecoder.java | 47 +++
.../providerapi/MasterProcessChannelEncoder.java | 84 +++++
.../surefire/providerapi/ProviderParameters.java | 8 +-
.../org/apache/maven/surefire/suite/RunResult.java | 2 +-
.../maven/surefire/testset/TestListResolver.java | 2 +-
.../maven/surefire/util/ReflectionUtils.java | 31 +-
.../util/internal/DaemonThreadFactory.java | 35 +-
.../java/org/apache/maven/JUnit4SuiteTest.java | 10 +-
.../surefire/booter/ForkingRunListenerTest.java | 25 +-
.../surefire/booter/MasterProcessCommandTest.java | 164 ---------
.../surefire/booter/SurefireReflectorTest.java | 198 ----------
surefire-booter/pom.xml | 37 +-
.../maven/surefire/booter/BooterConstants.java | 1 +
.../maven/surefire/booter/BooterDeserializer.java | 14 +
.../maven/surefire/booter/CommandReader.java | 127 +++----
.../apache/maven/surefire/booter/ForkedBooter.java | 78 +++-
.../maven/surefire/booter/LazyTestsToRun.java | 13 +-
.../surefire/booter/ProviderConfiguration.java | 2 -
.../maven/surefire/booter/ProviderFactory.java | 4 +-
.../surefire/booter/StartupConfiguration.java | 22 +-
.../maven/surefire/booter/SurefireReflector.java | 120 ++----
.../spi/LegacyMasterProcessChannelDecoder.java | 166 +++++++++
.../spi/LegacyMasterProcessChannelEncoder.java | 50 ++-
...LegacyMasterProcessChannelProcessorFactory.java | 70 ++++
...MasterProcessCommandNoMagicNumberException.java | 17 +-
.../spi/MasterProcessUnknownCommandException.java | 18 +-
...refireMasterProcessChannelProcessorFactory.java | 91 +++++
...refire.spi.MasterProcessChannelProcessorFactory | 32 +-
.../surefire/booter/BooterDeserializerTest.java | 2 +-
.../maven/surefire/booter/CommandReaderTest.java | 49 +--
.../java/org/apache/maven/surefire/booter/Foo.java | 48 +--
.../surefire/booter/ForkedBooterMockTest.java | 55 ++-
.../surefire/booter/IsolatedClassLoaderTest.java | 66 ++++
.../maven/surefire/booter/JUnit4SuiteTest.java | 7 +
.../surefire/booter/NewClassLoaderRunner.java | 0
.../surefire/booter/SurefireReflectorTest.java | 408 +++++++++++++++++++++
.../spi/LegacyMasterProcessChannelDecoderTest.java | 150 ++++++++
.../spi/LegacyMasterProcessChannelEncoderTest.java | 195 +++++-----
surefire-extensions-api/pom.xml | 38 +-
.../surefire/extensions/CloseableDaemonThread.java | 17 +-
.../maven/surefire/extensions/CommandReader.java | 25 +-
.../maven/surefire/extensions/EventHandler.java | 15 +-
.../maven/surefire/extensions/ForkChannel.java | 138 +++++++
.../maven/surefire/extensions/ForkNodeFactory.java | 22 +-
.../surefire/extensions/StdErrStreamLine.java | 9 +-
.../surefire/extensions/StdOutStreamLine.java | 8 +-
.../extensions/util/CountdownCloseable.java | 7 +-
.../extensions/util/LineConsumerThread.java | 7 +-
.../surefire/extensions/util/StreamFeeder.java | 27 +-
.../extensions/util/CommandlineExecutorTest.java | 29 +-
surefire-extensions-spi/pom.xml | 42 +++
.../spi/MasterProcessChannelProcessorFactory.java | 62 ++++
surefire-logger-api/pom.xml | 2 +-
.../maven/surefire/junit4/JUnit4Provider.java | 9 +-
.../maven/surefire/junit4/JUnit4ProviderTest.java | 2 +-
.../surefire/junitcore/JUnitCoreProvider.java | 9 +-
.../maven/surefire/junitcore/Surefire746Test.java | 3 +-
.../maven/surefire/testng/TestNGProvider.java | 9 +-
surefire-shadefire/pom.xml | 2 +
119 files changed, 3224 insertions(+), 1635 deletions(-)
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 0d56bb9..9bfd417 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -39,4 +39,4 @@ jobs:
java-version: 1.8
- name: Build with Maven
- run: mvn install -e -B -V -nsu --no-transfer-progress -P run-its
+ run: mvn install -e -B -V -nsu --no-transfer-progress -P run-its
\ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
index a27c0f9..3cf852e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -21,10 +21,10 @@
properties(
[
- buildDiscarder(logRotator(artifactDaysToKeepStr: env.BRANCH_NAME == 'master' ? '1' : '2',
+ buildDiscarder(logRotator(artifactDaysToKeepStr: env.BRANCH_NAME == 'master' ? '14' : '7',
artifactNumToKeepStr: '50',
- daysToKeepStr: env.BRANCH_NAME == 'master' ? '10' : '5',
- numToKeepStr: env.BRANCH_NAME == 'master' ? '5' : '3')
+ daysToKeepStr: env.BRANCH_NAME == 'master' ? '30' : '14',
+ numToKeepStr: env.BRANCH_NAME == 'master' ? '20' : '10')
),
disableConcurrentBuilds()
]
diff --git a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
index e465bb2..a6771bc 100644
--- a/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
+++ b/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
@@ -27,6 +27,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.suite.RunResult;
import java.io.File;
@@ -384,6 +385,9 @@ public class IntegrationTestMojo
@Parameter( property = "failsafe.useModulePath", defaultValue = "true" )
private boolean useModulePath;
+ @Parameter( property = "failsafe.forkNode" )
+ private ForkNodeFactory forkNode;
+
/**
* You can selectively exclude individual environment variables by enumerating their keys.
* <br>
@@ -912,6 +916,12 @@ public class IntegrationTestMojo
}
@Override
+ protected final ForkNodeFactory getForkNode()
+ {
+ return forkNode;
+ }
+
+ @Override
protected final String[] getExcludedEnvironmentVariables()
{
return excludedEnvironmentVariables == null ? new String[0] : excludedEnvironmentVariables;
diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml
index fefe831..8ab9e98 100644
--- a/maven-surefire-common/pom.xml
+++ b/maven-surefire-common/pom.xml
@@ -120,22 +120,6 @@
<build>
<plugins>
<plugin>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>build-test-classpath</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>build-classpath</goal>
- </goals>
- <configuration>
- <includeScope>test</includeScope>
- <outputFile>target/test-classpath/cp.txt</outputFile>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
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 ea1e3f4..6bab194 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,6 +25,7 @@ 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.SurefireStatelessReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
@@ -73,6 +74,7 @@ import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.booter.SurefireExecutionException;
import org.apache.maven.surefire.cli.CommandLineOption;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.providerapi.SurefireProvider;
import org.apache.maven.surefire.report.ReporterConfiguration;
import org.apache.maven.surefire.suite.RunResult;
@@ -773,8 +775,6 @@ public abstract class AbstractSurefireMojo
@Component
private DependencyResolver dependencyResolver;
- private Artifact surefireBooterArtifact;
-
private Toolchain toolchain;
private int effectiveForkCount = -1;
@@ -831,6 +831,8 @@ public abstract class AbstractSurefireMojo
protected abstract String getEnableProcessChecker();
+ protected abstract ForkNodeFactory getForkNode();
+
/**
* This plugin MOJO artifact.
*
@@ -912,8 +914,7 @@ public abstract class AbstractSurefireMojo
getPluginName(), getDependencyResolver(),
getSession().isOffline() );
- surefireBooterArtifact = getBooterArtifact();
- if ( surefireBooterArtifact == null )
+ if ( getBooterArtifact() == null )
{
throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" );
}
@@ -1746,7 +1747,7 @@ public abstract class AbstractSurefireMojo
return new File( getBasedir(), ".surefire-" + configurationHash );
}
- private StartupConfiguration createStartupConfiguration( @Nonnull ProviderInfo provider, boolean isInprocess,
+ private StartupConfiguration createStartupConfiguration( @Nonnull ProviderInfo provider, boolean isForking,
@Nonnull ClassLoaderConfiguration classLoaderConfiguration,
@Nonnull DefaultScanResult scanResult,
@Nonnull Platform platform,
@@ -1757,7 +1758,7 @@ public abstract class AbstractSurefireMojo
{
Set<Artifact> providerArtifacts = provider.getProviderClasspath();
String providerName = provider.getProviderName();
- if ( canExecuteProviderWithModularPath( platform ) && !isInprocess )
+ if ( isForking && canExecuteProviderWithModularPath( platform ) )
{
String jvmExecutable = platform.getJdkExecAttributesForTests().getJvmExecutable();
String javaHome = Paths.get( jvmExecutable )
@@ -1799,8 +1800,8 @@ public abstract class AbstractSurefireMojo
getConsoleLogger().debug( testClasspath.getCompactLogMessage( "test(compact) classpath:" ) );
getConsoleLogger().debug( providerClasspath.getCompactLogMessage( "provider(compact) classpath:" ) );
- Artifact[] additionalInProcArtifacts =
- { getCommonArtifact(), getExtensionsArtifact(), getApiArtifact(), getLoggerApiArtifact() };
+ Artifact[] additionalInProcArtifacts = { getCommonArtifact(), getBooterArtifact(), getExtensionsArtifact(),
+ getApiArtifact(), getSpiArtifact(), getLoggerApiArtifact(), getSurefireSharedUtilsArtifact() };
Set<Artifact> inProcArtifacts = retainInProcArtifactsUnique( providerArtifacts, additionalInProcArtifacts );
Classpath inProcClasspath = createInProcClasspath( providerClasspath, inProcArtifacts );
getConsoleLogger().debug( inProcClasspath.getLogMessage( "in-process classpath:" ) );
@@ -1809,8 +1810,8 @@ public abstract class AbstractSurefireMojo
ClasspathConfiguration classpathConfiguration = new ClasspathConfiguration( testClasspath, providerClasspath,
inProcClasspath, effectiveIsEnableAssertions(), isChildDelegation() );
- return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration, isForking(),
- false, ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
+ return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration,
+ ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
}
private static Set<Artifact> retainInProcArtifactsUnique( Set<Artifact> providerArtifacts,
@@ -1902,8 +1903,8 @@ public abstract class AbstractSurefireMojo
ModularClasspath modularClasspath = new ModularClasspath( result.getMainModuleDescriptor().name(),
testModulepath.getClassPath(), packages, getTestClassesDirectory() );
- Artifact[] additionalInProcArtifacts =
- { getCommonArtifact(), getExtensionsArtifact(), getApiArtifact(), getLoggerApiArtifact() };
+ Artifact[] additionalInProcArtifacts = { getCommonArtifact(), getBooterArtifact(), getExtensionsArtifact(),
+ getApiArtifact(), getSpiArtifact(), getLoggerApiArtifact(), getSurefireSharedUtilsArtifact() };
Set<Artifact> inProcArtifacts = retainInProcArtifactsUnique( providerArtifacts, additionalInProcArtifacts );
Classpath inProcClasspath = createInProcClasspath( providerClasspath, inProcArtifacts );
@@ -1919,8 +1920,8 @@ public abstract class AbstractSurefireMojo
getConsoleLogger().debug( inProcClasspath.getLogMessage( "in-process classpath:" ) );
getConsoleLogger().debug( inProcClasspath.getCompactLogMessage( "in-process(compact) classpath:" ) );
- return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration, isForking(),
- false, ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
+ return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration,
+ ProcessCheckerType.toEnum( getEnableProcessChecker() ) );
}
private Artifact getCommonArtifact()
@@ -1933,11 +1934,21 @@ public abstract class AbstractSurefireMojo
return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-extensions-api" );
}
+ private Artifact getSpiArtifact()
+ {
+ return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-extensions-spi" );
+ }
+
private Artifact getApiArtifact()
{
return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-api" );
}
+ private Artifact getSurefireSharedUtilsArtifact()
+ {
+ return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-shared-utils" );
+ }
+
private Artifact getLoggerApiArtifact()
{
return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-logger-api" );
@@ -2227,7 +2238,7 @@ public abstract class AbstractSurefireMojo
@Nonnull TestClassPath testClasspathWrapper )
throws MojoExecutionException, MojoFailureException
{
- StartupConfiguration startupConfiguration = createStartupConfiguration( provider, false,
+ StartupConfiguration startupConfiguration = createStartupConfiguration( provider, true,
classLoaderConfiguration, scanResult, platform, testClasspathWrapper );
String configChecksum = getConfigChecksum();
StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum, true );
@@ -2244,7 +2255,7 @@ public abstract class AbstractSurefireMojo
@Nonnull TestClassPath testClasspathWrapper )
throws MojoExecutionException, MojoFailureException
{
- StartupConfiguration startupConfiguration = createStartupConfiguration( provider, true, classLoaderConfig,
+ StartupConfiguration startupConfiguration = createStartupConfiguration( provider, false, classLoaderConfig,
scanResult, platform, testClasspathWrapper );
String configChecksum = getConfigChecksum();
StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum, false );
@@ -2253,6 +2264,14 @@ public abstract class AbstractSurefireMojo
getConsoleLogger() );
}
+ // todo this is in separate method and can be better tested than whole method createForkConfiguration()
+ @Nonnull
+ private ForkNodeFactory getForkNodeFactory()
+ {
+ ForkNodeFactory forkNode = getForkNode();
+ return forkNode == null ? new LegacyForkNodeFactory() : forkNode;
+ }
+
@Nonnull
private ForkConfiguration createForkConfiguration( Platform platform )
{
@@ -2260,7 +2279,9 @@ public abstract class AbstractSurefireMojo
Artifact shadeFire = getShadefireArtifact();
- Classpath bootClasspath = getArtifactClasspath( shadeFire != null ? shadeFire : surefireBooterArtifact );
+ Classpath bootClasspath = getArtifactClasspath( shadeFire != null ? shadeFire : getBooterArtifact() );
+
+ ForkNodeFactory forkNode = getForkNodeFactory();
if ( canExecuteProviderWithModularPath( platform ) )
{
@@ -2276,7 +2297,8 @@ public abstract class AbstractSurefireMojo
getEffectiveForkCount(),
reuseForks,
platform,
- getConsoleLogger() );
+ getConsoleLogger(),
+ forkNode );
}
else if ( getClassLoaderConfiguration().isManifestOnlyJarRequestedAndUsable() )
{
@@ -2292,7 +2314,8 @@ public abstract class AbstractSurefireMojo
getEffectiveForkCount(),
reuseForks,
platform,
- getConsoleLogger() );
+ getConsoleLogger(),
+ forkNode );
}
else
{
@@ -2308,7 +2331,8 @@ public abstract class AbstractSurefireMojo
getEffectiveForkCount(),
reuseForks,
platform,
- getConsoleLogger() );
+ getConsoleLogger(),
+ forkNode );
}
}
@@ -2919,7 +2943,7 @@ public abstract class AbstractSurefireMojo
{
// add the JUnit provider as default - it doesn't require JUnit to be present,
// since it supports POJO tests.
- String version = surefireBooterArtifact.getBaseVersion();
+ String version = getBooterArtifact().getBaseVersion();
return surefireDependencyResolver.getProviderClasspath( "surefire-junit3", version );
}
}
@@ -2958,7 +2982,7 @@ public abstract class AbstractSurefireMojo
@Nonnull
public Set<Artifact> getProviderClasspath()
{
- String version = surefireBooterArtifact.getBaseVersion();
+ String version = getBooterArtifact().getBaseVersion();
return surefireDependencyResolver.getProviderClasspath( "surefire-junit4", version );
}
}
@@ -3001,7 +3025,7 @@ public abstract class AbstractSurefireMojo
@Nonnull
public Set<Artifact> getProviderClasspath() throws MojoExecutionException
{
- String surefireVersion = surefireBooterArtifact.getBaseVersion();
+ String surefireVersion = getBooterArtifact().getBaseVersion();
Map<String, Artifact> providerArtifacts =
surefireDependencyResolver.getProviderClasspathAsMap( "surefire-junit-platform", surefireVersion );
Map<String, Artifact> testDependencies = testClasspath.getTestDependencies();
@@ -3172,7 +3196,7 @@ public abstract class AbstractSurefireMojo
@Nonnull
public Set<Artifact> getProviderClasspath()
{
- String version = surefireBooterArtifact.getBaseVersion();
+ String version = getBooterArtifact().getBaseVersion();
return surefireDependencyResolver.getProviderClasspath( "surefire-junit47", version );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
index 835fb89..466148f 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
@@ -23,8 +23,8 @@ import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
-import org.apache.maven.surefire.booter.SurefireReflector;
import org.apache.maven.surefire.util.SurefireReflectionException;
import javax.annotation.Nonnull;
@@ -71,7 +71,7 @@ public class CommonReflector
{
Class<?>[] args = { this.startupReportConfiguration, this.consoleLogger };
Object src = createStartupReportConfiguration( startupReportConfiguration );
- Object logger = SurefireReflector.createConsoleLogger( consoleLogger, surefireClassLoader );
+ Object logger = createConsoleLogger( consoleLogger, surefireClassLoader );
Object[] params = { src, logger };
return instantiateObject( DefaultReporterFactory.class.getName(), args, params, surefireClassLoader );
}
@@ -84,7 +84,6 @@ public class CommonReflector
int.class, String.class, String.class, boolean.class,
statelessTestsetReporter, consoleOutputReporter,
statelessTestsetInfoReporter );
- //noinspection BooleanConstructorCall
Object[] params = { reporterConfiguration.isUseFile(), reporterConfiguration.isPrintSummary(),
reporterConfiguration.getReportFormat(), reporterConfiguration.isRedirectTestOutputToFile(),
reporterConfiguration.getReportsDirectory(),
@@ -98,4 +97,17 @@ public class CommonReflector
};
return newInstance( constructor, params );
}
+
+ static Object createConsoleLogger( ConsoleLogger consoleLogger, ClassLoader cl )
+ {
+ try
+ {
+ Class<?> decoratorClass = cl.loadClass( ConsoleLoggerDecorator.class.getName() );
+ return getConstructor( decoratorClass, Object.class ).newInstance( consoleLogger );
+ }
+ catch ( Exception e )
+ {
+ throw new SurefireReflectionException( e );
+ }
+ }
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
index 4684563..6da4a1a 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
@@ -74,6 +74,7 @@ final class SurefireDependencyResolver
"surefire-junit-platform",
"surefire-api",
"surefire-logger-api",
+ "surefire-shared-utils",
"common-java5",
"common-junit3",
"common-junit4",
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
index 692f486..f8e08ea 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
@@ -21,6 +21,7 @@ package org.apache.maven.plugin.surefire.booterclient;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.Classpath;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -49,10 +50,12 @@ abstract class AbstractClasspathForkConfiguration
int forkCount,
boolean reuseForks,
@Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull ForkNodeFactory forkNodeFactory )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
+ forkNodeFactory );
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
index 7eacb74..9a04326 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
@@ -71,6 +71,7 @@ import static org.apache.maven.surefire.booter.BooterConstants.TESTARTIFACT_CLAS
import static org.apache.maven.surefire.booter.BooterConstants.TESTARTIFACT_VERSION;
import static org.apache.maven.surefire.booter.BooterConstants.USEMANIFESTONLYJAR;
import static org.apache.maven.surefire.booter.BooterConstants.USESYSTEMCLASSLOADER;
+import static org.apache.maven.surefire.booter.BooterConstants.FORK_NODE_CONNECTION_STRING;
import static org.apache.maven.surefire.booter.SystemPropertyManager.writePropertiesFile;
/**
@@ -102,11 +103,11 @@ class BooterSerializer
*/
File serialize( KeyValueSource sourceProperties, ProviderConfiguration providerConfiguration,
StartupConfiguration startupConfiguration, Object testSet, boolean readTestsFromInStream,
- Long pid, int forkNumber )
+ Long pid, int forkNumber, String forkNodeConnectionString )
throws IOException
{
SurefireProperties properties = new SurefireProperties( sourceProperties );
-
+ properties.setNullableProperty( FORK_NODE_CONNECTION_STRING, forkNodeConnectionString );
properties.setProperty( PLUGIN_PID, pid );
AbstractPathConfiguration cp = startupConfiguration.getClasspathConfiguration();
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
index 1ca3932..9c906c4 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
@@ -24,6 +24,7 @@ import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -48,10 +49,12 @@ public final class ClasspathForkConfiguration
@Nonnull String[] excludedEnvironmentVariables,
boolean debug, int forkCount,
boolean reuseForks, @Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull ForkNodeFactory forkNodeFactory )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
+ forkNodeFactory );
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
index 4ab4435..443bf45 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfiguration.java
@@ -26,6 +26,7 @@ import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.util.internal.ImmutableMap;
import javax.annotation.Nonnull;
@@ -65,6 +66,7 @@ public abstract class DefaultForkConfiguration
private final boolean reuseForks;
@Nonnull private final Platform pluginPlatform;
@Nonnull private final ConsoleLogger log;
+ @Nonnull private final ForkNodeFactory forkNodeFactory;
@SuppressWarnings( "checkstyle:parameternumber" )
protected DefaultForkConfiguration( @Nonnull Classpath booterClasspath,
@@ -79,7 +81,8 @@ public abstract class DefaultForkConfiguration
int forkCount,
boolean reuseForks,
@Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull ForkNodeFactory forkNodeFactory )
{
this.booterClasspath = booterClasspath;
this.tempDirectory = tempDirectory;
@@ -94,6 +97,7 @@ public abstract class DefaultForkConfiguration
this.reuseForks = reuseForks;
this.pluginPlatform = pluginPlatform;
this.log = log;
+ this.forkNodeFactory = forkNodeFactory;
}
protected abstract void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@@ -108,6 +112,13 @@ public abstract class DefaultForkConfiguration
return jvmArgLine;
}
+ @Nonnull
+ @Override
+ public final ForkNodeFactory getForkNodeFactory()
+ {
+ return forkNodeFactory;
+ }
+
/**
* @param config The startup configuration
* @param forkNumber index of forked JVM, to be the replacement in the argLine
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
index 92bebd0..9fddf96 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
@@ -25,6 +25,7 @@ import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.ForkedBooter;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -39,6 +40,7 @@ public abstract class ForkConfiguration
{
static final String DEFAULT_PROVIDER_CLASS = ForkedBooter.class.getName();
+ @Nonnull public abstract ForkNodeFactory getForkNodeFactory();
@Nonnull public abstract File getTempDirectory();
@Nullable protected abstract String getDebugLine();
@Nonnull protected abstract File getWorkingDirectory();
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 0ba2f46..a23d656 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
@@ -22,7 +22,7 @@ package org.apache.maven.plugin.surefire.booterclient;
import org.apache.maven.plugin.surefire.CommonReflector;
import org.apache.maven.plugin.surefire.StartupReportConfiguration;
import org.apache.maven.plugin.surefire.SurefireProperties;
-import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractForkInputStream;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.NotifiableTestStream;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
@@ -33,12 +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.shared.utils.cli.CommandLineException;
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
@@ -47,8 +45,12 @@ import org.apache.maven.surefire.booter.Shutdown;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.booter.SurefireExecutionException;
+import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
+import org.apache.maven.surefire.extensions.util.LineConsumerThread;
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;
@@ -79,7 +81,6 @@ import static java.lang.StrictMath.min;
import static java.lang.System.currentTimeMillis;
import static java.lang.Thread.currentThread;
import static java.util.Collections.addAll;
-import static java.util.Objects.requireNonNull;
import static java.util.concurrent.Executors.newScheduledThreadPool;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -192,7 +193,7 @@ public class ForkStarter
{
closeable.close();
}
- catch ( IOException e )
+ catch ( IOException | RuntimeException e )
{
// This error does not fail a test and does not necessarily mean that the forked JVM std/out stream
// was not closed, see ThreadedStreamConsumer. This error means that JVM wrote messages to a native
@@ -212,11 +213,17 @@ public class ForkStarter
@Override
public void close()
{
- run();
- testProvidingInputStream.clear();
- if ( inputStreamCloserHook != null )
+ try
{
- removeShutdownHook( inputStreamCloserHook );
+ run();
+ }
+ finally
+ {
+ testProvidingInputStream.clear();
+ if ( inputStreamCloserHook != null )
+ {
+ removeShutdownHook( inputStreamCloserHook );
+ }
}
}
@@ -289,7 +296,8 @@ public class ForkStarter
defaultReporterFactories.add( forkedReporterFactory );
ForkClient forkClient =
new ForkClient( forkedReporterFactory, stream, log, new AtomicBoolean(), forkNumber );
- return fork( null, props, forkClient, effectiveSystemProperties, forkNumber, stream, false );
+ return fork( null, props, forkClient, effectiveSystemProperties, forkNumber, stream,
+ forkConfiguration.getForkNodeFactory(), false );
}
finally
{
@@ -379,7 +387,8 @@ public class ForkStarter
try
{
return fork( null, new PropertiesWrapper( providerProperties ), forkClient,
- effectiveSystemProperties, forkNumber, testProvidingInputStream, true );
+ effectiveSystemProperties, forkNumber, testProvidingInputStream,
+ forkConfiguration.getForkNodeFactory(), true );
}
finally
{
@@ -453,7 +462,8 @@ public class ForkStarter
{
return fork( testSet,
new PropertiesWrapper( providerConfiguration.getProviderProperties() ),
- forkClient, effectiveSystemProperties, forkNumber, stream, false );
+ forkClient, effectiveSystemProperties, forkNumber, stream,
+ forkConfiguration.getForkNodeFactory(), false );
}
finally
{
@@ -549,21 +559,25 @@ public class ForkStarter
private RunResult fork( Object testSet, PropertiesWrapper providerProperties, ForkClient forkClient,
SurefireProperties effectiveSystemProperties, int forkNumber,
- AbstractForkInputStream commandInputStream, boolean readTestsFromInStream )
+ AbstractCommandReader commandReader, ForkNodeFactory forkNodeFactory,
+ boolean readTestsFromInStream )
throws SurefireBooterForkException
{
final String tempDir;
final File surefireProperties;
final File systPropsFile;
+ final ForkChannel forkChannel;
try
{
+ forkChannel = forkNodeFactory.createForkChannel( forkNumber );
tempDir = forkConfiguration.getTempDirectory().getCanonicalPath();
BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
Long pluginPid = forkConfiguration.getPluginPlatform().getPluginPid();
- surefireProperties = booterSerializer.serialize( providerProperties, providerConfiguration,
- startupConfiguration, testSet, readTestsFromInStream, pluginPid, forkNumber );
-
log.debug( "Determined Maven Process ID " + pluginPid );
+ String connectionString = forkChannel.getForkNodeConnectionString();
+ log.debug( "Fork Channel [" + forkNumber + "] connection string " + connectionString );
+ surefireProperties = booterSerializer.serialize( providerProperties, providerConfiguration,
+ startupConfiguration, testSet, readTestsFromInStream, pluginPid, forkNumber, connectionString );
if ( effectiveSystemProperties != null )
{
@@ -588,10 +602,7 @@ public class ForkStarter
OutputStreamFlushableCommandline cli =
forkConfiguration.createCommandLine( startupConfiguration, forkNumber, dumpLogDir );
- if ( commandInputStream != null )
- {
- commandInputStream.setFlushReceiverProvider( cli );
- }
+ commandReader.setFlushReceiverProvider( cli );
cli.createArg().setValue( tempDir );
cli.createArg().setValue( DUMP_FILE_PREFIX + forkNumber );
@@ -602,38 +613,44 @@ public class ForkStarter
}
ThreadedStreamConsumer eventConsumer = new ThreadedStreamConsumer( forkClient );
- CloseableCloser closer = new CloseableCloser( forkNumber, eventConsumer, requireNonNull( commandInputStream ) );
+ CloseableCloser closer = new CloseableCloser( forkNumber, eventConsumer, commandReader );
log.debug( "Forking command line: " + cli );
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 );
+ CountdownCloseable countdownCloseable =
+ new CountdownCloseable( eventConsumer, 1 + ( forkChannel.useStdOut() ? 1 : 0 ) );
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(), commandInputStream );
+
+ forkChannel.openChannel();
+
+ 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.bindEventHandler( stdErrConsumer );
out.start();
- NativeStdErrStreamConsumer stdErrConsumer = new NativeStdErrStreamConsumer( reporter );
+
err = new LineConsumerThread( "std-err-fork-" + forkNumber, streams.getStdErrChannel(),
- stdErrConsumer, countdownCloseable );
+ stdErrConsumer, countdownCloseable );
err.start();
+
result = exec.awaitExit();
- // END: end of the call of the extension
if ( forkClient.hadTimeout() )
{
@@ -652,8 +669,9 @@ public class ForkStarter
out.disable();
err.disable();
}
- catch ( CommandLineException e )
+ catch ( Exception e )
{
+ // CommandLineException from pipes and IOException from sockets
runResult = failure( reporter.getGlobalRunStatistics().getRunResult(), e );
String cliErr = e.getLocalizedMessage();
Throwable cause = e.getCause();
@@ -665,7 +683,7 @@ public class ForkStarter
currentForkClients.remove( forkClient );
try
{
- Closeable c = forkClient.isSaidGoodBye() ? closer : commandInputStream;
+ Closeable c = forkClient.isSaidGoodBye() ? closer : commandReader;
c.close();
}
catch ( IOException e )
@@ -710,7 +728,7 @@ public class ForkStarter
//noinspection ThrowFromFinallyBlock
throw new SurefireBooterForkException( "There was an error in the forked process"
+ detail
- + ( stackTrace == null ? "" : stackTrace ), cause );
+ + ( stackTrace == null ? "" : "\n" + stackTrace ), cause );
}
if ( !forkClient.isSaidGoodBye() )
{
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
index 02c275c..382bec6 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
@@ -28,6 +28,7 @@ import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -70,10 +71,12 @@ public final class JarManifestForkConfiguration
@Nonnull String[] excludedEnvironmentVariables,
boolean debug,
int forkCount, boolean reuseForks, @Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull ForkNodeFactory forkNodeFactory )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
+ forkNodeFactory );
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
index 8f5030b..d659a6c 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfiguration.java
@@ -28,6 +28,7 @@ import org.apache.maven.surefire.booter.ModularClasspath;
import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
@@ -67,10 +68,12 @@ public class ModularClasspathForkConfiguration
@Nonnegative int forkCount,
boolean reuseForks,
@Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull ForkNodeFactory forkNodeFactory )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, excludedEnvironmentVariables, debug, forkCount, reuseForks, pluginPlatform, log,
+ forkNodeFactory );
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
similarity index 84%
rename from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
index a884c15..a31e9f7 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractForkInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandReader.java
@@ -19,32 +19,34 @@ package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
* under the License.
*/
+import org.apache.maven.surefire.extensions.CommandReader;
+
import java.io.IOException;
-import java.io.InputStream;
import static java.util.Objects.requireNonNull;
/**
- * Reader stream sends bytes to forked jvm std-{@link InputStream input-stream}.
+ * Stream reader returns bytes which ar finally sent to the forked jvm std-input-stream.
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 2.19
*/
-public abstract class AbstractForkInputStream
- extends InputStream
- implements NotifiableTestStream
+public abstract class AbstractCommandReader
+ implements CommandReader, DefferedChannelCommandSender
{
private volatile FlushReceiverProvider flushReceiverProvider;
/**
* @param flushReceiverProvider the provider for a flush receiver.
*/
+ @Override
public void setFlushReceiverProvider( FlushReceiverProvider flushReceiverProvider )
{
this.flushReceiverProvider = requireNonNull( flushReceiverProvider );
}
- protected boolean tryFlush()
+ @Override
+ public void tryFlush()
throws IOException
{
if ( flushReceiverProvider != null )
@@ -53,9 +55,7 @@ public abstract class AbstractForkInputStream
if ( flushReceiver != null )
{
flushReceiver.flush();
- return true;
}
}
- return false;
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
similarity index 63%
rename from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
index 31b56c4..9aa19c3 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/AbstractCommandStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefaultCommandReader.java
@@ -20,7 +20,6 @@ package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
*/
import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessCommand;
import java.io.IOException;
@@ -31,14 +30,9 @@ import java.io.IOException;
* @since 2.19
* @see org.apache.maven.surefire.booter.Command
*/
-public abstract class AbstractCommandStream
- extends AbstractForkInputStream
+public abstract class DefaultCommandReader
+ extends AbstractCommandReader
{
- private byte[] currentBuffer;
- private int currentPos;
-
- protected abstract boolean isClosed();
-
/**
* Opposite to {@link #isClosed()}.
* @return {@code true} if not closed
@@ -62,59 +56,35 @@ public abstract class AbstractCommandStream
protected abstract Command nextCommand();
/**
- * Returns quietly and immediately.
- */
- protected final void invalidateInternalBuffer()
- {
- currentBuffer = null;
- currentPos = 0;
- }
-
- /**
* Used by single thread in StreamFeeder class.
*
* @return {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
- @SuppressWarnings( "checkstyle:magicnumber" )
@Override
- public int read()
+ public Command readNextCommand()
throws IOException
{
+ tryFlush();
+
if ( isClosed() )
{
- tryFlush();
- return -1;
+ return null;
}
- if ( currentBuffer == null )
+ if ( !canContinue() )
{
- tryFlush();
-
- if ( !canContinue() )
- {
- close();
- return -1;
- }
-
- beforeNextCommand();
-
- if ( isClosed() )
- {
- return -1;
- }
-
- Command cmd = nextCommand();
- MasterProcessCommand cmdType = cmd.getCommandType();
- currentBuffer = cmdType.hasDataType() ? cmdType.encode( cmd.getData() ) : cmdType.encode();
+ close();
+ return null;
}
- int b = currentBuffer[currentPos++] & 0xff;
- if ( currentPos == currentBuffer.length )
+ beforeNextCommand();
+
+ if ( isClosed() )
{
- currentBuffer = null;
- currentPos = 0;
+ return null;
}
- return b;
+
+ return nextCommand();
}
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ShutdownAware.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefferedChannelCommandSender.java
similarity index 66%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/ShutdownAware.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefferedChannelCommandSender.java
index 0bfcdb8..e489caa 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ShutdownAware.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/DefferedChannelCommandSender.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,13 +19,17 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import java.io.Closeable;
+
/**
- * See the plugin configuration parameter {@code shutdown}.
+ * Physical implementation of command sender.<br>
+ * Instance of {@link AbstractCommandReader} (namely {@link TestLessInputStream} or {@link TestProvidingInputStream}).
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
+ * @since 3.0.0-M4
*/
-public interface ShutdownAware
+public interface DefferedChannelCommandSender
+ extends NotifiableTestStream, Closeable
{
- void setShutdown( Shutdown shutdown );
+ void setFlushReceiverProvider( FlushReceiverProvider flushReceiverProvider );
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
index 372ce00..a1060a7 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStream.java
@@ -45,7 +45,7 @@ import static org.apache.maven.surefire.booter.Command.toShutdown;
* @since 2.19
*/
public final class TestLessInputStream
- extends AbstractCommandStream
+ extends DefaultCommandReader
{
private final Semaphore barrier = new Semaphore( 0 );
@@ -108,7 +108,7 @@ public final class TestLessInputStream
}
@Override
- protected boolean isClosed()
+ public boolean isClosed()
{
return closed.get();
}
@@ -141,7 +141,6 @@ public final class TestLessInputStream
{
if ( closed.compareAndSet( false, true ) )
{
- invalidateInternalBuffer();
barrier.drainPermits();
barrier.release();
}
@@ -166,8 +165,6 @@ public final class TestLessInputStream
}
catch ( InterruptedException e )
{
- // help GC to free this object because StreamFeeder Thread cannot read it anyway after IOE
- invalidateInternalBuffer();
throw new IOException( e.getLocalizedMessage() );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
index a4255cc..6f3a4de 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStream.java
@@ -31,6 +31,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static org.apache.maven.surefire.booter.Command.BYE_ACK;
import static org.apache.maven.surefire.booter.Command.NOOP;
import static org.apache.maven.surefire.booter.Command.SKIP_SINCE_NEXT_TEST;
+import static org.apache.maven.surefire.booter.Command.TEST_SET_FINISHED;
import static org.apache.maven.surefire.booter.Command.toRunClass;
import static org.apache.maven.surefire.booter.Command.toShutdown;
@@ -50,7 +51,7 @@ import static org.apache.maven.surefire.booter.Command.toShutdown;
* @author Tibor Digana (tibor17)
*/
public final class TestProvidingInputStream
- extends AbstractCommandStream
+ extends DefaultCommandReader
{
private final Semaphore barrier = new Semaphore( 0 );
@@ -77,7 +78,7 @@ public final class TestProvidingInputStream
{
if ( canContinue() )
{
- commands.add( Command.TEST_SET_FINISHED );
+ commands.add( TEST_SET_FINISHED );
barrier.release();
}
}
@@ -129,7 +130,7 @@ public final class TestProvidingInputStream
if ( cmd == null )
{
String cmdData = testClassNames.poll();
- return cmdData == null ? Command.TEST_SET_FINISHED : toRunClass( cmdData );
+ return cmdData == null ? TEST_SET_FINISHED : toRunClass( cmdData );
}
else
{
@@ -145,7 +146,7 @@ public final class TestProvidingInputStream
}
@Override
- protected boolean isClosed()
+ public boolean isClosed()
{
return closed.get();
}
@@ -167,7 +168,6 @@ public final class TestProvidingInputStream
{
if ( closed.compareAndSet( false, true ) )
{
- invalidateInternalBuffer();
barrier.drainPermits();
barrier.release();
}
@@ -182,9 +182,7 @@ public final class TestProvidingInputStream
}
catch ( InterruptedException e )
{
- // help GC to free this object because StreamFeeder Thread cannot read it anyway after IOE
- invalidateInternalBuffer();
- throw new IOException( e.getLocalizedMessage() );
+ throw new IOException( e.getLocalizedMessage(), e );
}
}
}
\ No newline at end of file
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
index 18cfe28..a02db78 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
@@ -22,6 +22,7 @@ package org.apache.maven.plugin.surefire.booterclient.output;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.NotifiableTestStream;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import org.apache.maven.surefire.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.report.ReportEntry;
@@ -74,7 +75,7 @@ public class ForkClient
/**
* <em>testSetStartedAt</em> is set to non-zero after received
- * {@link org.apache.maven.surefire.booter.ForkedChannelEncoder#testSetStarting(ReportEntry, boolean)}.
+ * {@link MasterProcessChannelEncoder#testSetStarting(ReportEntry, boolean)}.
*/
private final AtomicLong testSetStartedAt = new AtomicLong( START_TIME_ZERO );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoder.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoder.java
index f0c96e3..5d49b0e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoder.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoder.java
@@ -32,7 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.nio.charset.StandardCharsets.US_ASCII;
-import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER;
+import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER_DELIMITED;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDERR;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDERR_NEW_LINE;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDOUT;
@@ -183,13 +183,13 @@ public final class ForkedChannelDecoder
public void handleEvent( String line, ForkedChannelDecoderErrorHandler errorHandler )
{
- if ( line == null || !line.startsWith( MAGIC_NUMBER ) )
+ if ( line == null || !line.startsWith( MAGIC_NUMBER_DELIMITED ) )
{
errorHandler.handledError( line, null );
return;
}
- StringTokenizer tokenizer = new StringTokenizer( line.substring( MAGIC_NUMBER.length() ), ":" );
+ StringTokenizer tokenizer = new StringTokenizer( line.substring( MAGIC_NUMBER_DELIMITED.length() ), ":" );
String opcode = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
ForkedProcessEvent event = opcode == null ? null : EVENTS.get( opcode );
if ( event == null )
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdErrStreamConsumer.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdErrStreamConsumer.java
index b17bfe4..8e4f6f0 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdErrStreamConsumer.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdErrStreamConsumer.java
@@ -20,7 +20,7 @@ package org.apache.maven.plugin.surefire.booterclient.output;
*/
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
-import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
+import org.apache.maven.surefire.extensions.StdErrStreamLine;
/**
* Used by forked JMV, see {@link org.apache.maven.plugin.surefire.booterclient.ForkStarter}.
@@ -30,7 +30,7 @@ import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
* @see org.apache.maven.plugin.surefire.booterclient.ForkStarter
*/
public final class NativeStdErrStreamConsumer
- implements StreamConsumer
+ implements StdErrStreamLine
{
private final DefaultReporterFactory defaultReporterFactory;
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdOutStreamConsumer.java
similarity index 58%
copy from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
copy to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdOutStreamConsumer.java
index eddebed..1f915ae 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/NativeStdOutStreamConsumer.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.plugin.surefire.booterclient.output;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -9,7 +9,7 @@ package org.apache.maven.surefire.booter;
* "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
+ * 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
@@ -19,17 +19,25 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
-
-import java.util.List;
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.extensions.StdOutStreamLine;
/**
- * CLI options in plugin (main) JVM process.
*
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
*/
-interface MainCliOptionsAware
+public class NativeStdOutStreamConsumer
+ implements StdOutStreamLine
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+ private final ConsoleLogger logger;
+
+ public NativeStdOutStreamConsumer( ConsoleLogger logger )
+ {
+ this.logger = logger;
+ }
+
+ @Override
+ public void handleLine( String line )
+ {
+ logger.info( line );
+ }
}
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 853d35c..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
@@ -20,8 +20,10 @@ package org.apache.maven.plugin.surefire.booterclient.output;
*/
import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
+import org.apache.maven.surefire.extensions.EventHandler;
import org.apache.maven.surefire.util.internal.DaemonThreadFactory;
+import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.ArrayBlockingQueue;
@@ -36,7 +38,7 @@ import static java.lang.Thread.currentThread;
* @author Kristian Rosenvold
*/
public final class ThreadedStreamConsumer
- implements StreamConsumer, Closeable
+ implements EventHandler, StreamConsumer, Closeable
{
private static final String END_ITEM = "";
@@ -113,7 +115,14 @@ public final class ThreadedStreamConsumer
}
@Override
- public void consumeLine( String s )
+ // todo remove this method and use object instead of string
+ public void handleEvent( @Nonnull String event )
+ {
+ consumeLine( event );
+ }
+
+ @Override
+ public void consumeLine( @Nonnull String s )
{
if ( stop.get() )
{
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
new file mode 100644
index 0000000..31ad325
--- /dev/null
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkChannel.java
@@ -0,0 +1,98 @@
+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.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.nio.channels.ReadableByteChannel;
+import java.nio.channels.WritableByteChannel;
+
+/**
+ *
+ */
+final class LegacyForkChannel extends ForkChannel
+{
+ protected LegacyForkChannel( int forkChannelId )
+ {
+ super( forkChannelId );
+ }
+
+ @Override
+ public void openChannel()
+ {
+ }
+
+ @Override
+ public String getForkNodeConnectionString()
+ {
+ return "pipe://" + getForkChannelId();
+ }
+
+ @Override
+ public boolean useStdIn()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean useStdOut()
+ {
+ 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 bindEventHandler( @Nonnull StreamConsumer consumer )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void close()
+ {
+ }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/DirectoryScannerParametersAware.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
similarity index 63%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/DirectoryScannerParametersAware.java
rename to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
index cefeb33..836464e 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/DirectoryScannerParametersAware.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/LegacyForkNodeFactory.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.plugin.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,12 +19,21 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.testset.DirectoryScannerParameters;
+import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
+
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
/**
- * @author Kristian Rosenvold
+ *
*/
-interface DirectoryScannerParametersAware
+public class LegacyForkNodeFactory implements ForkNodeFactory
{
- void setDirectoryScannerParameters( DirectoryScannerParameters directoryScanner );
+ @Nonnull
+ @Override
+ public ForkChannel createForkChannel( @Nonnegative int forkChannelId )
+ {
+ return new LegacyForkChannel( forkChannelId );
+ }
}
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
new file mode 100644
index 0000000..214c9dc
--- /dev/null
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkChannel.java
@@ -0,0 +1,140 @@
+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.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.net.InetSocketAddress;
+import java.net.SocketOption;
+import java.nio.channels.Channel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
+
+import static java.net.StandardSocketOptions.SO_KEEPALIVE;
+import static java.net.StandardSocketOptions.SO_REUSEADDR;
+import static java.net.StandardSocketOptions.TCP_NODELAY;
+import static java.nio.channels.ServerSocketChannel.open;
+
+/**
+ *
+ */
+final class SurefireForkChannel extends ForkChannel
+{
+ private final ServerSocketChannel server;
+ private final int serverPort;
+ private SocketChannel channel;
+
+ SurefireForkChannel( int forkChannelId ) throws IOException
+ {
+ super( forkChannelId );
+ server = open();
+ setTrueOptions( SO_REUSEADDR, TCP_NODELAY, SO_KEEPALIVE );
+ server.bind( new InetSocketAddress( 0 ) );
+ serverPort = ( (InetSocketAddress) server.getLocalAddress() ).getPort();
+ }
+
+ @Override
+ public void openChannel() throws IOException
+ {
+ if ( channel != null )
+ {
+ throw new IllegalStateException( "already accepted TCP client connection" );
+ }
+ channel = server.accept();
+ }
+
+ @SafeVarargs
+ private final void setTrueOptions( SocketOption<Boolean>... options ) throws IOException
+ {
+ for ( SocketOption<Boolean> option : options )
+ {
+ if ( server.supportedOptions().contains( option ) )
+ {
+ server.setOption( option, true );
+ }
+ }
+ }
+
+ @Override
+ public String getForkNodeConnectionString()
+ {
+ return "tcp://127.0.0.1:" + serverPort;
+ }
+
+ @Override
+ public boolean useStdIn()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean useStdOut()
+ {
+ return false;
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
+ @Nonnull WritableByteChannel stdIn )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands )
+ {
+ return new StreamFeeder( "commands-fork-" + getForkChannelId(), channel, commands );
+ }
+
+ @Override
+ public CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdOut,
+ @Nonnull CountdownCloseable countdownCloseable )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer )
+ {
+ CountdownCloseable countdownCloseable = new CountdownCloseable( null, 0 );
+ return new LineConsumerThread( "events-fork-" + getForkChannelId(), channel, consumer, countdownCloseable );
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ //noinspection EmptyTryBlock
+ try ( Channel c1 = channel; Channel c2 = server )
+ {
+ // only close all channels
+ }
+ }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
similarity index 61%
copy from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
copy to maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
index eddebed..c076ba2 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/SurefireForkNodeFactory.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.plugin.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +19,22 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
+import org.apache.maven.surefire.extensions.ForkChannel;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
-import java.util.List;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import java.io.IOException;
/**
- * CLI options in plugin (main) JVM process.
*
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
*/
-interface MainCliOptionsAware
+public class SurefireForkNodeFactory implements ForkNodeFactory
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+ @Nonnull
+ @Override
+ public ForkChannel createForkChannel( @Nonnegative int forkChannelId ) throws IOException
+ {
+ return new SurefireForkChannel( forkChannelId );
+ }
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
index 9faa4eb..abd896e 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
@@ -28,6 +28,7 @@ import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
import org.apache.maven.surefire.booter.StartupConfiguration;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.suite.RunResult;
import org.apache.maven.surefire.util.DefaultScanResult;
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor;
@@ -180,11 +181,26 @@ public class AbstractSurefireMojoJava7PlusTest
"jar", "", handler );
loggerApi.setFile( mockFile( "surefire-logger-api.jar" ) );
+ Artifact spi = new DefaultArtifact( "org.apache.maven.surefire", "surefire-extensions-spi",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ spi.setFile( mockFile( "surefire-extensions-spi.jar" ) );
+
+ Artifact booter = new DefaultArtifact( "org.apache.maven.surefire", "surefire-booter",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ booter.setFile( mockFile( "surefire-booter.jar" ) );
+
+ Artifact utils = new DefaultArtifact( "org.apache.maven.surefire", "surefire-shared-utils",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ utils.setFile( mockFile( "surefire-shared-utils.jar" ) );
+
Map<String, Artifact> artifacts = new HashMap<>();
artifacts.put( "org.apache.maven.surefire:maven-surefire-common", common );
artifacts.put( "org.apache.maven.surefire:surefire-extensions-api", ext );
artifacts.put( "org.apache.maven.surefire:surefire-api", api );
artifacts.put( "org.apache.maven.surefire:surefire-logger-api", loggerApi );
+ artifacts.put( "org.apache.maven.surefire:surefire-extensions-spi", spi );
+ artifacts.put( "org.apache.maven.surefire:surefire-booter", booter );
+ artifacts.put( "org.apache.maven.surefire:surefire-shared-utils", utils );
when( mojo.getPluginArtifactMap() ).thenReturn( artifacts );
StartupConfiguration conf = invokeMethod( mojo, "newStartupConfigWithModularPath",
@@ -193,7 +209,6 @@ public class AbstractSurefireMojoJava7PlusTest
verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
verify( mojo, times( 1 ) ).isChildDelegation();
- verify( mojo, times( 1 ) ).getEffectiveForkCount();
verify( mojo, times( 1 ) ).getTestClassesDirectory();
verify( scanResult, times( 1 ) ).getClasses();
verifyStatic( ResolvePathsRequest.class, times( 1 ) );
@@ -219,8 +234,8 @@ public class AbstractSurefireMojoJava7PlusTest
"test(compact) classpath: non-modular.jar junit.jar hamcrest.jar",
"test(compact) modulepath: modular.jar classes",
"provider(compact) classpath: surefire-provider.jar",
- "in-process classpath: surefire-provider.jar maven-surefire-common.jar surefire-extensions-api.jar surefire-api.jar surefire-logger-api.jar",
- "in-process(compact) classpath: surefire-provider.jar maven-surefire-common.jar surefire-extensions-api.jar surefire-api.jar surefire-logger-api.jar"
+ "in-process classpath: surefire-provider.jar maven-surefire-common.jar surefire-booter.jar surefire-extensions-api.jar surefire-api.jar surefire-extensions-spi.jar surefire-logger-api.jar surefire-shared-utils.jar",
+ "in-process(compact) classpath: surefire-provider.jar maven-surefire-common.jar surefire-booter.jar surefire-extensions-api.jar surefire-api.jar surefire-extensions-spi.jar surefire-logger-api.jar surefire-shared-utils.jar"
);
assertThat( conf ).isNotNull();
@@ -632,6 +647,12 @@ public class AbstractSurefireMojoJava7PlusTest
}
@Override
+ protected ForkNodeFactory getForkNode()
+ {
+ return null;
+ }
+
+ @Override
protected Artifact getMojoArtifact()
{
return null;
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
index b1e7c1e..0553de7 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
@@ -42,6 +42,7 @@ import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.StartupConfiguration;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.suite.RunResult;
import org.codehaus.plexus.logging.Logger;
import org.junit.Before;
@@ -312,11 +313,26 @@ public class AbstractSurefireMojoTest
createFromVersion( "1" ), "runtime", "jar", "", handler );
loggerApi.setFile( mockFile( "surefire-logger-api.jar" ) );
+ Artifact spi = new DefaultArtifact( "org.apache.maven.surefire", "surefire-extensions-spi",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ spi.setFile( mockFile( "surefire-extensions-spi.jar" ) );
+
+ Artifact booter = new DefaultArtifact( "org.apache.maven.surefire", "surefire-booter",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ booter.setFile( mockFile( "surefire-booter.jar" ) );
+
+ Artifact utils = new DefaultArtifact( "org.apache.maven.surefire", "surefire-shared-utils",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ utils.setFile( mockFile( "surefire-shared-utils.jar" ) );
+
Map<String, Artifact> providerArtifactsMap = new HashMap<>();
providerArtifactsMap.put( "org.apache.maven.surefire:maven-surefire-common", common );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-extensions-api", ext );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-api", api );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-logger-api", loggerApi );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-extensions-spi", spi );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-booter", booter );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-shared-utils", utils );
when( mojo.getPluginArtifactMap() )
.thenReturn( providerArtifactsMap );
@@ -358,7 +374,6 @@ public class AbstractSurefireMojoTest
verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
verify( mojo, times( 1 ) ).isChildDelegation();
- verify( mojo, times( 1 ) ).getEffectiveForkCount();
ArgumentCaptor<String> argument = ArgumentCaptor.forClass( String.class );
verify( logger, times( 6 ) ).debug( argument.capture() );
assertThat( argument.getAllValues() )
@@ -366,8 +381,8 @@ public class AbstractSurefireMojoTest
"provider classpath: surefire-provider.jar",
"test(compact) classpath: test-classes classes junit.jar hamcrest.jar",
"provider(compact) classpath: surefire-provider.jar",
- "in-process classpath: surefire-provider.jar maven-surefire-common.jar surefire-extensions-api.jar surefire-api.jar surefire-logger-api.jar",
- "in-process(compact) classpath: surefire-provider.jar maven-surefire-common.jar surefire-extensions-api.jar surefire-api.jar surefire-logger-api.jar"
+ "in-process classpath: surefire-provider.jar maven-surefire-common.jar surefire-booter.jar surefire-extensions-api.jar surefire-api.jar surefire-extensions-spi.jar surefire-logger-api.jar surefire-shared-utils.jar",
+ "in-process(compact) classpath: surefire-provider.jar maven-surefire-common.jar surefire-booter.jar surefire-extensions-api.jar surefire-api.jar surefire-extensions-spi.jar surefire-logger-api.jar surefire-shared-utils.jar"
);
assertThat( conf.getClassLoaderConfiguration() )
@@ -405,7 +420,7 @@ public class AbstractSurefireMojoTest
Artifact provider = new DefaultArtifact( "com.example", "provider", createFromVersion( "1" ), "runtime",
"jar", "", handler );
provider.setFile( mockFile( "original-test-provider.jar" ) );
- HashSet<Artifact> providerClasspath = new HashSet<>( asList( provider ) );
+ Set<Artifact> providerClasspath = singleton( provider );
when( providerInfo.getProviderClasspath() ).thenReturn( providerClasspath );
StartupConfiguration startupConfiguration = startupConfigurationForProvider( providerInfo );
@@ -448,11 +463,26 @@ public class AbstractSurefireMojoTest
createFromVersion( "1" ), "runtime", "jar", "", handler );
loggerApi.setFile( mockFile( "surefire-logger-api.jar" ) );
+ Artifact spi = new DefaultArtifact( "org.apache.maven.surefire", "surefire-extensions-spi",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ spi.setFile( mockFile( "surefire-extensions-spi.jar" ) );
+
+ Artifact booter = new DefaultArtifact( "org.apache.maven.surefire", "surefire-booter",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ booter.setFile( mockFile( "surefire-booter.jar" ) );
+
+ Artifact utils = new DefaultArtifact( "org.apache.maven.surefire", "surefire-shared-utils",
+ createFromVersion( "1" ), "runtime", "jar", "", handler );
+ utils.setFile( mockFile( "surefire-shared-utils.jar" ) );
+
Map<String, Artifact> providerArtifactsMap = new HashMap<>();
providerArtifactsMap.put( "org.apache.maven.surefire:maven-surefire-common", common );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-extensions-api", ext );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-api", api );
providerArtifactsMap.put( "org.apache.maven.surefire:surefire-logger-api", loggerApi );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-extensions-spi", spi );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-booter", booter );
+ providerArtifactsMap.put( "org.apache.maven.surefire:surefire-shared-utils", utils );
when( mojo.getPluginArtifactMap() ).thenReturn( providerArtifactsMap );
@@ -2121,6 +2151,12 @@ public class AbstractSurefireMojoTest
}
@Override
+ protected ForkNodeFactory getForkNode()
+ {
+ return null;
+ }
+
+ @Override
protected Artifact getMojoArtifact()
{
return new DefaultArtifact( "org.apache.maven.surefire", "maven-surefire-plugin", createFromVersion( "1" ),
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
index 1f94a75..4f954d4 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
@@ -23,15 +23,30 @@ import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
+import org.apache.maven.plugin.surefire.log.api.PrintStreamLogger;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
+import org.hamcrest.MatcherAssert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.ArgumentCaptor;
import java.io.File;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.maven.surefire.util.ReflectionUtils.getMethod;
+import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray;
import static org.fest.assertions.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static org.powermock.reflect.Whitebox.getInternalState;
/**
@@ -96,4 +111,39 @@ public class CommonReflectorTest
assertThat( reportConfiguration.getConsoleOutputReporter().toString() )
.isEqualTo( consoleOutputReporter.toString() );
}
+
+ @Test
+ public void shouldProxyConsoleLogger()
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ ConsoleLogger logger = spy( new PrintStreamLogger( System.out ) );
+ Object mirror = CommonReflector.createConsoleLogger( logger, cl );
+ MatcherAssert.assertThat( mirror, is( notNullValue() ) );
+ MatcherAssert.assertThat( mirror.getClass().getInterfaces()[0].getName(), is( ConsoleLogger.class.getName() ) );
+ MatcherAssert.assertThat( mirror, is( not( sameInstance( (Object) logger ) ) ) );
+ MatcherAssert.assertThat( mirror, is( instanceOf( ConsoleLoggerDecorator.class ) ) );
+ invokeMethodWithArray( mirror, getMethod( mirror, "info", String.class ), "Hi There!" );
+ verify( logger, times( 1 ) ).info( "Hi There!" );
+ }
+
+ @Test
+ public void testCreateConsoleLogger()
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ ConsoleLogger consoleLogger = mock( ConsoleLogger.class );
+ ConsoleLogger decorator = (ConsoleLogger) CommonReflector.createConsoleLogger( consoleLogger, cl );
+ assertThat( decorator )
+ .isNotSameAs( consoleLogger );
+
+ assertThat( decorator.isDebugEnabled() ).isFalse();
+ when( consoleLogger.isDebugEnabled() ).thenReturn( true );
+ assertThat( decorator.isDebugEnabled() ).isTrue();
+ verify( consoleLogger, times( 2 ) ).isDebugEnabled();
+
+ decorator.info( "msg" );
+ ArgumentCaptor<String> argumentMsg = ArgumentCaptor.forClass( String.class );
+ verify( consoleLogger, times( 1 ) ).info( argumentMsg.capture() );
+ assertThat( argumentMsg.getAllValues() ).hasSize( 1 );
+ assertThat( argumentMsg.getAllValues().get( 0 ) ).isEqualTo( "msg" );
+ }
}
\ No newline at end of file
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
index ccf63f7..835ce8e 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/MojoMocklessTest.java
@@ -28,6 +28,7 @@ import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.suite.RunResult;
import org.apache.maven.surefire.util.DefaultScanResult;
import org.apache.maven.toolchain.Toolchain;
@@ -751,6 +752,12 @@ public class MojoMocklessTest
}
@Override
+ protected ForkNodeFactory getForkNode()
+ {
+ return null;
+ }
+
+ @Override
protected String getEnableProcessChecker()
{
return null;
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireReflectorTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireReflectorTest.java
deleted file mode 100644
index 2553617..0000000
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireReflectorTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.apache.maven.plugin.surefire;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
-import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
-import org.apache.maven.plugin.surefire.log.api.PrintStreamLogger;
-import org.apache.maven.surefire.booter.IsolatedClassLoader;
-import org.apache.maven.surefire.booter.SurefireReflector;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.apache.maven.surefire.util.ReflectionUtils.getMethod;
-import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray;
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.CoreMatchers.sameInstance;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-/**
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @see ConsoleLogger
- * @see SurefireReflector
- * @since 2.20
- */
-public class SurefireReflectorTest
-{
- private ConsoleLogger logger;
- private ClassLoader cl;
-
- @Before
- public void prepareData()
- {
- logger = spy( new PrintStreamLogger( System.out ) );
- cl = new IsolatedClassLoader( Thread.currentThread().getContextClassLoader(), false, "role" );
- }
-
- @Test
- public void shouldProxyConsoleLogger()
- {
- Object mirror = SurefireReflector.createConsoleLogger( logger, cl );
- assertThat( mirror, is( notNullValue() ) );
- assertThat( mirror.getClass().getInterfaces()[0].getName(), is( ConsoleLogger.class.getName() ) );
- assertThat( mirror, is( not( sameInstance( (Object) logger ) ) ) );
- assertThat( mirror, is( instanceOf( ConsoleLoggerDecorator.class ) ) );
- invokeMethodWithArray( mirror, getMethod( mirror, "info", String.class ), "Hi There!" );
- verify( logger, times( 1 ) ).info( "Hi There!" );
- }
-}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
index ca42c44..10563a8 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java
@@ -25,7 +25,6 @@ import org.apache.maven.surefire.shared.io.FileUtils;
import org.apache.maven.surefire.booter.BooterDeserializer;
import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.ClasspathConfiguration;
-import org.apache.maven.surefire.booter.ProcessCheckerType;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.booter.Shutdown;
@@ -52,6 +51,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
+import static org.apache.maven.surefire.booter.ProcessCheckerType.ALL;
import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
import static org.apache.maven.surefire.cli.CommandLineOption.REACTOR_FAIL_FAST;
import static org.apache.maven.surefire.cli.CommandLineOption.SHOW_ERRORS;
@@ -260,9 +260,10 @@ public class BooterDeserializerProviderConfigurationTest
test = "aTest";
}
final File propsTest = booterSerializer.serialize( props, booterConfiguration, testProviderConfiguration, test,
- readTestsFromInStream, 51L, 1 );
+ readTestsFromInStream, 51L, 1, "pipe://1" );
BooterDeserializer booterDeserializer = new BooterDeserializer( new FileInputStream( propsTest ) );
assertEquals( "51", (Object) booterDeserializer.getPluginPid() );
+ assertEquals( "pipe://1", booterDeserializer.getConnectionString() );
return booterDeserializer.deserialize();
}
@@ -285,8 +286,7 @@ public class BooterDeserializerProviderConfigurationTest
{
ClasspathConfiguration classpathConfiguration = new ClasspathConfiguration( true, true );
- return new StartupConfiguration( "com.provider", classpathConfiguration, classLoaderConfiguration, false,
- false, ProcessCheckerType.ALL );
+ return new StartupConfiguration( "com.provider", classpathConfiguration, classLoaderConfiguration, ALL );
}
private File getTestSourceDirectory()
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
index 4e9bbc9..63f6162 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java
@@ -20,24 +20,23 @@ package org.apache.maven.plugin.surefire.booterclient;
*/
import junit.framework.TestCase;
-import org.apache.maven.surefire.shared.io.FileUtils;
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
import org.apache.maven.surefire.booter.BooterDeserializer;
+import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.ClasspathConfiguration;
-import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
-import org.apache.maven.surefire.booter.ProcessCheckerType;
import org.apache.maven.surefire.booter.PropertiesWrapper;
import org.apache.maven.surefire.booter.ProviderConfiguration;
-import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.Shutdown;
+import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.cli.CommandLineOption;
import org.apache.maven.surefire.report.ReporterConfiguration;
+import org.apache.maven.surefire.shared.io.FileUtils;
import org.apache.maven.surefire.testset.DirectoryScannerParameters;
import org.apache.maven.surefire.testset.RunOrderParameters;
import org.apache.maven.surefire.testset.TestArtifactInfo;
-import org.apache.maven.surefire.testset.TestRequest;
import org.apache.maven.surefire.testset.TestListResolver;
+import org.apache.maven.surefire.testset.TestRequest;
import org.apache.maven.surefire.util.RunOrder;
import org.junit.After;
import org.junit.Before;
@@ -50,6 +49,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
+import static org.apache.maven.surefire.booter.ProcessCheckerType.ALL;
import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
import static org.apache.maven.surefire.cli.CommandLineOption.REACTOR_FAIL_FAST;
import static org.apache.maven.surefire.cli.CommandLineOption.SHOW_ERRORS;
@@ -105,7 +105,7 @@ public class BooterDeserializerStartupConfigurationTest
public void testProcessChecker() throws IOException
{
- assertEquals( ProcessCheckerType.ALL, getReloadedStartupConfiguration().getProcessChecker() );
+ assertEquals( ALL, getReloadedStartupConfiguration().getProcessChecker() );
}
private void assertCpConfigEquals( ClasspathConfiguration expectedConfiguration,
@@ -136,13 +136,13 @@ public class BooterDeserializerStartupConfigurationTest
public void testProcessCheckerAll() throws IOException
{
- assertEquals( ProcessCheckerType.ALL, getReloadedStartupConfiguration().getProcessChecker() );
+ assertEquals( ALL, getReloadedStartupConfiguration().getProcessChecker() );
}
public void testProcessCheckerNull() throws IOException
{
StartupConfiguration startupConfiguration = new StartupConfiguration( "com.provider", classpathConfiguration,
- getManifestOnlyJarForkConfiguration(), false, false, null );
+ getManifestOnlyJarForkConfiguration(), null );
assertNull( saveAndReload( startupConfiguration ).getProcessChecker() );
}
@@ -178,15 +178,15 @@ public class BooterDeserializerStartupConfigurationTest
BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
String aTest = "aTest";
File propsTest = booterSerializer.serialize( props, getProviderConfiguration(), startupConfiguration, aTest,
- false, null, 1 );
+ false, null, 1, "tcp://127.0.0.1:63003" );
BooterDeserializer booterDeserializer = new BooterDeserializer( new FileInputStream( propsTest ) );
assertNull( booterDeserializer.getPluginPid() );
+ assertEquals( "tcp://127.0.0.1:63003", booterDeserializer.getConnectionString() );
return booterDeserializer.getStartupConfiguration();
}
private ProviderConfiguration getProviderConfiguration()
{
-
File cwd = new File( "." );
DirectoryScannerParameters directoryScannerParameters =
new DirectoryScannerParameters( cwd, new ArrayList<String>(), new ArrayList<String>(),
@@ -204,8 +204,7 @@ public class BooterDeserializerStartupConfigurationTest
private StartupConfiguration getTestStartupConfiguration( ClassLoaderConfiguration classLoaderConfiguration )
{
- return new StartupConfiguration( "com.provider", classpathConfiguration, classLoaderConfiguration, false,
- false, ProcessCheckerType.ALL );
+ return new StartupConfiguration( "com.provider", classpathConfiguration, classLoaderConfiguration, ALL );
}
private File getTestSourceDirectory()
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
index 06fe754..45a6b4a 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/DefaultForkConfigurationTest.java
@@ -27,7 +27,7 @@ import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.ClasspathConfiguration;
import org.apache.maven.surefire.booter.ForkedBooter;
import org.apache.maven.surefire.booter.StartupConfiguration;
-import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -80,6 +80,7 @@ public class DefaultForkConfigurationTest
private boolean reuseForks;
private Platform pluginPlatform;
private ConsoleLogger log;
+ private ForkNodeFactory forkNodeFactory;
@Before
public void setup()
@@ -97,6 +98,7 @@ public class DefaultForkConfigurationTest
reuseForks = true;
pluginPlatform = new Platform();
log = mock( ConsoleLogger.class );
+ forkNodeFactory = mock( ForkNodeFactory.class );
}
@Test
@@ -104,16 +106,15 @@ public class DefaultForkConfigurationTest
{
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -130,16 +131,15 @@ public class DefaultForkConfigurationTest
argLine = "";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -156,16 +156,15 @@ public class DefaultForkConfigurationTest
argLine = "\n\r";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -182,16 +181,15 @@ public class DefaultForkConfigurationTest
argLine = "-Dfile.encoding=UTF-8";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -209,16 +207,15 @@ public class DefaultForkConfigurationTest
argLine = "-Dfile.encoding=@{encoding}";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -235,16 +232,15 @@ public class DefaultForkConfigurationTest
argLine = "a\n\rb";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -261,16 +257,15 @@ public class DefaultForkConfigurationTest
argLine = "-Dthread=${surefire.threadNumber}";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -287,16 +282,15 @@ public class DefaultForkConfigurationTest
argLine = "-Dthread=${surefire.forkNumber}";
DefaultForkConfiguration config = new DefaultForkConfiguration( booterClasspath, tempDirectory, debugLine,
workingDirectory, modelProperties, argLine, environmentVariables, excludedEnvironmentVariables,
- debug, forkCount, reuseForks, pluginPlatform, log )
+ debug, forkCount, reuseForks, pluginPlatform, log, forkNodeFactory )
{
@Override
protected void resolveClasspath( @Nonnull OutputStreamFlushableCommandline cli,
@Nonnull String booterThatHasMainMethod,
@Nonnull StartupConfiguration config,
- @Nonnull File dumpLogDirectory ) throws SurefireBooterForkException
+ @Nonnull File dumpLogDirectory )
{
-
}
};
@@ -313,7 +307,7 @@ public class DefaultForkConfigurationTest
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
ClasspathConfiguration cc = new ClasspathConfiguration( true, true );
StartupConfiguration conf = new StartupConfiguration( "org.apache.maven.shadefire.surefire.MyProvider",
- cc, clc, false, false, null );
+ cc, clc, null );
StartupConfiguration confMock = spy( conf );
mockStatic( Relocator.class );
when( Relocator.relocate( anyString() ) ).thenCallRealMethod();
@@ -334,7 +328,7 @@ public class DefaultForkConfigurationTest
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
ClasspathConfiguration cc = new ClasspathConfiguration( true, true );
StartupConfiguration conf =
- new StartupConfiguration( "org.apache.maven.surefire.MyProvider", cc, clc, false, false, null );
+ new StartupConfiguration( "org.apache.maven.surefire.MyProvider", cc, clc, null );
StartupConfiguration confMock = spy( conf );
mockStatic( Relocator.class );
when( Relocator.relocate( anyString() ) ).thenCallRealMethod();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
index 72e5372..bc01ee8 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
@@ -30,6 +30,7 @@ import org.apache.maven.surefire.booter.Classpath;
import org.apache.maven.surefire.booter.ClasspathConfiguration;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -47,6 +48,7 @@ import static org.fest.util.Files.temporaryFolder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
/**
*
@@ -55,10 +57,7 @@ public class ForkConfigurationTest
{
private static final StartupConfiguration STARTUP_CONFIG = new StartupConfiguration( "",
new ClasspathConfiguration( true, true ),
- new ClassLoaderConfiguration( true, true ),
- false,
- false,
- ALL );
+ new ClassLoaderConfiguration( true, true ), ALL );
private static int idx = 0;
@@ -91,7 +90,7 @@ public class ForkConfigurationTest
ClasspathConfiguration cpConfig = new ClasspathConfiguration( new Classpath( cp ), emptyClasspath(),
emptyClasspath(), true, true );
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
- StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, false, false, ALL );
+ StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, ALL );
Commandline cli = config.createCommandLine( startup, 1, temporaryFolder() );
@@ -111,7 +110,7 @@ public class ForkConfigurationTest
ClasspathConfiguration cpConfig = new ClasspathConfiguration( new Classpath( cp ), emptyClasspath(),
emptyClasspath(), true, true );
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
- StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, false, false, ALL );
+ StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, ALL );
Commandline commandLine = config.createCommandLine( startup, 1, temporaryFolder() );
assertTrue( commandLine.toString().contains( "abc def" ) );
@@ -126,7 +125,7 @@ public class ForkConfigurationTest
ClasspathConfiguration cpConfig = new ClasspathConfiguration( emptyClasspath(), emptyClasspath(),
emptyClasspath(), true, true );
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
- StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, false, false, ALL );
+ StartupConfiguration startup = new StartupConfiguration( "", cpConfig, clc, ALL );
ForkConfiguration config = getForkConfiguration( cwd.getCanonicalFile() );
Commandline commandLine = config.createCommandLine( startup, 1, temporaryFolder() );
@@ -225,7 +224,7 @@ public class ForkConfigurationTest
return new JarManifestForkConfiguration( emptyClasspath(), tmpDir, null,
cwd, new Properties(), argLine,
Collections.<String, String>emptyMap(), new String[0], false, 1, false,
- platform, new NullConsoleLogger() );
+ platform, new NullConsoleLogger(), mock( ForkNodeFactory.class ) );
}
// based on http://stackoverflow.com/questions/2591083/getting-version-of-java-in-runtime
@@ -233,6 +232,6 @@ public class ForkConfigurationTest
private static boolean isJavaVersionAtLeast7u60()
{
String[] javaVersionElements = System.getProperty( "java.runtime.version" ).split( "\\.|_|-b" );
- return Integer.valueOf( javaVersionElements[1] ) >= 7 && Integer.valueOf( javaVersionElements[3] ) >= 60;
+ return Integer.parseInt( javaVersionElements[1] ) >= 7 && Integer.parseInt( javaVersionElements[3] ) >= 60;
}
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkStarterTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkStarterTest.java
index e0874f0..a7ab4d7 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkStarterTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkStarterTest.java
@@ -21,12 +21,13 @@ package org.apache.maven.plugin.surefire.booterclient;
import org.apache.maven.plugin.surefire.StartupReportConfiguration;
import org.apache.maven.plugin.surefire.SurefireProperties;
-import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractForkInputStream;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.AbstractCommandReader;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestProvidingInputStream;
import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
+import org.apache.maven.plugin.surefire.extensions.LegacyForkNodeFactory;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
import org.apache.maven.surefire.booter.AbstractPathConfiguration;
@@ -37,6 +38,7 @@ import org.apache.maven.surefire.booter.ProviderConfiguration;
import org.apache.maven.surefire.booter.Shutdown;
import org.apache.maven.surefire.booter.StartupConfiguration;
import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.report.ReporterConfiguration;
import org.apache.maven.surefire.shared.compress.archivers.zip.Zip64Mode;
import org.apache.maven.surefire.shared.compress.archivers.zip.ZipArchiveEntry;
@@ -170,12 +172,12 @@ public class ForkStarterTest
e.expectMessage( containsString( "VM crash or System.exit called?" ) );
Class<?>[] types = {Object.class, PropertiesWrapper.class, ForkClient.class, SurefireProperties.class,
- int.class, AbstractForkInputStream.class, boolean.class};
+ int.class, AbstractCommandReader.class, ForkNodeFactory.class, boolean.class};
TestProvidingInputStream testProvidingInputStream = new TestProvidingInputStream( new ArrayDeque<String>() );
invokeMethod( forkStarter, "fork", types, null,
new PropertiesWrapper( Collections.<String, String>emptyMap() ),
new ForkClient( reporterFactory, null, logger, new AtomicBoolean(), 1 ),
- new SurefireProperties(), 1, testProvidingInputStream, true );
+ new SurefireProperties(), 1, testProvidingInputStream, new LegacyForkNodeFactory(), true );
testProvidingInputStream.close();
}
@@ -224,12 +226,12 @@ public class ForkStarterTest
DefaultReporterFactory reporterFactory = new DefaultReporterFactory( startupReportConfiguration, logger, 1 );
Class<?>[] types = {Object.class, PropertiesWrapper.class, ForkClient.class, SurefireProperties.class,
- int.class, AbstractForkInputStream.class, boolean.class};
+ int.class, AbstractCommandReader.class, ForkNodeFactory.class, boolean.class};
TestLessInputStream testLessInputStream = new TestLessInputStreamBuilder().build();
invokeMethod( forkStarter, "fork", types, null,
new PropertiesWrapper( Collections.<String, String>emptyMap() ),
new ForkClient( reporterFactory, testLessInputStream, logger, new AtomicBoolean(), 1 ),
- new SurefireProperties(), 1, testLessInputStream, true );
+ new SurefireProperties(), 1, testLessInputStream, new LegacyForkNodeFactory(), true );
testLessInputStream.close();
}
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 79c6f0e..2e44e75 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
@@ -25,7 +25,7 @@ import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.Notifiable
import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
-import org.apache.maven.surefire.booter.ForkedChannelEncoder;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
import org.apache.maven.surefire.booter.ForkingRunListener;
import org.apache.maven.surefire.report.CategorizedReportEntry;
import org.apache.maven.surefire.report.ConsoleOutputReceiver;
@@ -196,8 +196,8 @@ public class ForkingRunListenerTest
ForkClient forkStreamClient =
new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, new AtomicBoolean(), 1 );
- forkStreamClient.consumeMultiLineContent( ":maven:surefire:std:out:sys-prop:normal-run:UTF-8:azE=:djE="
- + "\n:maven:surefire:std:out:sys-prop:normal-run:UTF-8:azI=:djI=" );
+ forkStreamClient.consumeMultiLineContent( ":maven-surefire-event:sys-prop:normal-run:UTF-8:azE=:djE="
+ + "\n:maven-surefire-event:sys-prop:normal-run:UTF-8:azI=:djI=" );
MatcherAssert.assertThat( forkStreamClient.getTestVmSystemProperties().size(), is( 2 ) );
}
@@ -239,10 +239,10 @@ public class ForkingRunListenerTest
ReportEntry expected = createDefaultReportEntry();
final SimpleReportEntry secondExpected = createAnotherDefaultReportEntry();
- new ForkingRunListener( new ForkedChannelEncoder( printStream ), false )
+ new ForkingRunListener( new LegacyMasterProcessChannelEncoder( printStream ), false )
.testStarting( expected );
- new ForkingRunListener( new ForkedChannelEncoder( anotherPrintStream ), false )
+ new ForkingRunListener( new LegacyMasterProcessChannelEncoder( anotherPrintStream ), false )
.testSkipped( secondExpected );
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
@@ -312,7 +312,7 @@ public class ForkingRunListenerTest
private RunListener createForkingRunListener()
{
- return new ForkingRunListener( new ForkedChannelEncoder( printStream ), false );
+ return new ForkingRunListener( new LegacyMasterProcessChannelEncoder( printStream ), false );
}
private class StandardTestRun
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MainClass.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MainClass.java
index d90a128..63fdd4e 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MainClass.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MainClass.java
@@ -34,15 +34,11 @@ public class MainClass
}
else
{
- System.out.println( ":maven:surefire:std:out:bye" );
- if ( System.in.read() == 0
- && System.in.read() == 0
- && System.in.read() == 0
- && System.in.read() == 5
- && System.in.read() == 0
- && System.in.read() == 0
- && System.in.read() == 0
- && System.in.read() == 0 )
+ System.out.println( ":maven-surefire-event:bye\n" );
+ String byeAck = ":maven-surefire-command:bye-ack:";
+ byte[] cmd = new byte[byeAck.length()];
+ int len = System.in.read( cmd );
+ if ( len != -1 && new String( cmd, 0, len ).equals( byeAck ) )
{
System.exit( 0 );
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
index 492c5c0..cfa7dce 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ModularClasspathForkConfigurationTest.java
@@ -27,6 +27,7 @@ import org.apache.maven.surefire.booter.ForkedBooter;
import org.apache.maven.surefire.booter.ModularClasspath;
import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
import org.apache.maven.surefire.booter.StartupConfiguration;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.junit.Test;
import java.io.File;
@@ -43,9 +44,10 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.readAllLines;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
-import static org.apache.maven.surefire.shared.utils.StringUtils.replace;
import static org.apache.maven.surefire.booter.Classpath.emptyClasspath;
+import static org.apache.maven.surefire.shared.utils.StringUtils.replace;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
/**
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
@@ -66,7 +68,7 @@ public class ModularClasspathForkConfigurationTest
ModularClasspathForkConfiguration config = new ModularClasspathForkConfiguration( booter, tmp, "", pwd,
new Properties(), "",
Collections.<String, String>emptyMap(), new String[0], true, 1, true,
- new Platform(), new NullConsoleLogger() );
+ new Platform(), new NullConsoleLogger(), mock( ForkNodeFactory.class ) );
File patchFile = new File( "target" + separatorChar + "test-classes" );
File descriptor = new File( tmp, "module-info.class" );
@@ -141,8 +143,8 @@ public class ModularClasspathForkConfigurationTest
new ModularClasspathConfiguration( modularClasspath, testClasspathUrls, surefireClasspathUrls,
emptyClasspath(), true, true );
ClassLoaderConfiguration clc = new ClassLoaderConfiguration( true, true );
- StartupConfiguration startupConfiguration =
- new StartupConfiguration( "JUnitCoreProvider", modularClasspathConfiguration, clc, true, true, null );
+ StartupConfiguration startupConfiguration = new StartupConfiguration( "JUnitCoreProvider",
+ modularClasspathConfiguration, clc, null );
OutputStreamFlushableCommandline cli = new OutputStreamFlushableCommandline();
config.resolveClasspath( cli, ForkedBooter.class.getName(), startupConfiguration,
createTempFile( "surefire", "surefire-reports" ) );
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStreamBuilderTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStreamBuilderTest.java
index bbc85d4..6496bb8 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStreamBuilderTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestLessInputStreamBuilderTest.java
@@ -21,20 +21,21 @@ package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
import org.apache.maven.surefire.booter.Command;
import org.apache.maven.surefire.booter.MasterProcessCommand;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelDecoder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import java.io.DataInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import static org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
-import static org.apache.maven.surefire.booter.Command.NOOP;
+import static org.apache.maven.plugin.surefire.booterclient.lazytestprovider
+ .TestLessInputStream.TestLessInputStreamBuilder;
import static org.apache.maven.surefire.booter.Command.SKIP_SINCE_NEXT_TEST;
import static org.apache.maven.surefire.booter.MasterProcessCommand.SHUTDOWN;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
import static org.apache.maven.surefire.booter.Shutdown.EXIT;
import static org.apache.maven.surefire.booter.Shutdown.KILL;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -87,7 +88,7 @@ public class TestLessInputStreamBuilderTest
assertThat( is.availablePermits(), is( 1 ) );
is.beforeNextCommand();
assertThat( is.availablePermits(), is( 0 ) );
- assertThat( is.nextCommand(), is( NOOP ) );
+ assertThat( is.nextCommand(), is( Command.NOOP ) );
assertThat( is.availablePermits(), is( 0 ) );
e.expect( NoSuchElementException.class );
is.nextCommand();
@@ -105,7 +106,7 @@ public class TestLessInputStreamBuilderTest
assertThat( is.availablePermits(), is( 2 ) );
is.beforeNextCommand();
assertThat( is.availablePermits(), is( 1 ) );
- assertThat( is.nextCommand(), is( NOOP ) );
+ assertThat( is.nextCommand(), is( Command.NOOP ) );
assertThat( is.availablePermits(), is( 1 ) );
builder.getCachableCommands().skipSinceNextTest();
assertThat( is.availablePermits(), is( 1 ) );
@@ -123,7 +124,7 @@ public class TestLessInputStreamBuilderTest
builder.getCachableCommands().shutdown( EXIT );
assertThat( is.availablePermits(), is( 2 ) );
is.beforeNextCommand();
- assertThat( is.nextCommand(), is( NOOP ) );
+ assertThat( is.nextCommand(), is( Command.NOOP ) );
assertThat( is.availablePermits(), is( 1 ) );
is.beforeNextCommand();
assertThat( is.nextCommand().getCommandType(), is( SHUTDOWN ) );
@@ -137,15 +138,51 @@ public class TestLessInputStreamBuilderTest
throws IOException
{
TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
- TestLessInputStream pluginIs = builder.build();
+ final TestLessInputStream pluginIs = builder.build();
+ InputStream is = new InputStream()
+ {
+ private byte[] buffer;
+ private int idx;
+
+ @Override
+ public int read() throws IOException
+ {
+ if ( buffer == null )
+ {
+ idx = 0;
+ Command cmd = pluginIs.readNextCommand();
+ if ( cmd == null )
+ {
+ buffer = null;
+ }
+ else
+ {
+ MasterProcessCommand cmdType = cmd.getCommandType();
+ buffer = cmdType.hasDataType() ? cmdType.encode( cmd.getData() ) : cmdType.encode();
+ }
+ }
+
+ if ( buffer != null )
+ {
+ byte b = buffer[idx++];
+ if ( idx == buffer.length )
+ {
+ buffer = null;
+ idx = 0;
+ }
+ return b;
+ }
+ throw new IOException();
+ }
+ };
+ MasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( is );
builder.getImmediateCommands().shutdown( KILL );
builder.getImmediateCommands().noop();
- DataInputStream is = new DataInputStream( pluginIs );
- Command bye = decode( is );
+ Command bye = decoder.decode();
assertThat( bye, is( notNullValue() ) );
assertThat( bye.getCommandType(), is( SHUTDOWN ) );
assertThat( bye.getData(), is( KILL.name() ) );
- Command noop = decode( is );
+ Command noop = decoder.decode();
assertThat( noop, is( notNullValue() ) );
assertThat( noop.getCommandType(), is( MasterProcessCommand.NOOP ) );
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStreamTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStreamTest.java
index 21bc663..731a1ff 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStreamTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/lazytestprovider/TestProvidingInputStreamTest.java
@@ -20,11 +20,13 @@ package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
*/
import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessCommand;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelDecoder;
import org.junit.Test;
-import java.io.DataInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.lang.Thread.State;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Callable;
@@ -32,11 +34,14 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
+import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.apache.maven.surefire.booter.MasterProcessCommand.BYE_ACK;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.NOOP;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertTrue;
/**
* Asserts that this stream properly reads bytes from queue.
@@ -46,14 +51,15 @@ import static org.hamcrest.Matchers.notNullValue;
*/
public class TestProvidingInputStreamTest
{
+ private static final int WAIT_LOOPS = 100;
@Test
- public void closedStreamShouldReturnEndOfStream()
+ public void closedStreamShouldReturnNullAsEndOfStream()
throws IOException
{
Queue<String> commands = new ArrayDeque<>();
TestProvidingInputStream is = new TestProvidingInputStream( commands );
is.close();
- assertThat( is.read(), is( -1 ) );
+ assertThat( is.readNextCommand(), is( nullValue() ) );
}
@Test
@@ -63,22 +69,22 @@ public class TestProvidingInputStreamTest
Queue<String> commands = new ArrayDeque<>();
final TestProvidingInputStream is = new TestProvidingInputStream( commands );
final Thread streamThread = Thread.currentThread();
- FutureTask<Thread.State> futureTask = new FutureTask<>( new Callable<Thread.State>()
+ FutureTask<State> futureTask = new FutureTask<>( new Callable<State>()
{
@Override
- public Thread.State call()
+ public State call()
{
- sleep( 1000 );
- Thread.State state = streamThread.getState();
+ sleep( 1000L );
+ State state = streamThread.getState();
is.close();
return state;
}
} );
Thread assertionThread = new Thread( futureTask );
assertionThread.start();
- assertThat( is.read(), is( -1 ) );
- Thread.State state = futureTask.get();
- assertThat( state, is( Thread.State.WAITING ) );
+ assertThat( is.readNextCommand(), is( nullValue() ) );
+ State state = futureTask.get();
+ assertThat( state, is( State.WAITING ) );
}
@Test
@@ -96,16 +102,23 @@ public class TestProvidingInputStreamTest
is.provideNewTest();
}
} ).start();
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 1 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
+
+ Command cmd = is.readNextCommand();
+ assertThat( cmd.getData(), is( nullValue() ) );
+ String stream = new String( cmd.getCommandType().encode(), US_ASCII );
+
+ cmd = is.readNextCommand();
+ assertThat( cmd.getData(), is( nullValue() ) );
+ stream += new String( cmd.getCommandType().encode(), US_ASCII );
+
+ assertThat( stream,
+ is( ":maven-surefire-command:testset-finished::maven-surefire-command:testset-finished:" ) );
+
+ boolean emptyStream = isInputStreamEmpty( is );
+
is.close();
- assertThat( is.read(), is( -1 ) );
+ assertTrue( emptyStream );
+ assertThat( is.readNextCommand(), is( nullValue() ) );
}
@Test
@@ -123,34 +136,55 @@ public class TestProvidingInputStreamTest
is.provideNewTest();
}
} ).start();
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 0 ) );
- assertThat( is.read(), is( 4 ) );
- assertThat( is.read(), is( (int) 'T' ) );
- assertThat( is.read(), is( (int) 'e' ) );
- assertThat( is.read(), is( (int) 's' ) );
- assertThat( is.read(), is( (int) 't' ) );
+
+ Command cmd = is.readNextCommand();
+ assertThat( cmd.getData(), is( "Test" ) );
+
+ is.close();
}
@Test
public void shouldDecodeTwoCommands()
throws IOException
{
- TestProvidingInputStream pluginIs = new TestProvidingInputStream( new ConcurrentLinkedQueue<String>() );
+ final TestProvidingInputStream pluginIs = new TestProvidingInputStream( new ConcurrentLinkedQueue<String>() );
+ InputStream is = new InputStream()
+ {
+ private byte[] buffer;
+ private int idx;
+
+ @Override
+ public int read() throws IOException
+ {
+ if ( buffer == null )
+ {
+ idx = 0;
+ Command cmd = pluginIs.readNextCommand();
+ buffer = cmd == null ? null : cmd.getCommandType().encode();
+ }
+
+ if ( buffer != null )
+ {
+ byte b = buffer[idx++];
+ if ( idx == buffer.length )
+ {
+ buffer = null;
+ idx = 0;
+ }
+ return b;
+ }
+ throw new IOException();
+ }
+ };
+ MasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( is );
pluginIs.acknowledgeByeEventReceived();
pluginIs.noop();
- DataInputStream is = new DataInputStream( pluginIs );
- Command bye = decode( is );
+ Command bye = decoder.decode();
assertThat( bye, is( notNullValue() ) );
assertThat( bye.getCommandType(), is( BYE_ACK ) );
- Command noop = decode( is );
+ Command noop = decoder.decode();
assertThat( noop, is( notNullValue() ) );
- assertThat( noop.getCommandType(), is( MasterProcessCommand.NOOP ) );
+ assertThat( noop.getCommandType(), is( NOOP ) );
}
private static void sleep( long millis )
@@ -164,4 +198,44 @@ public class TestProvidingInputStreamTest
// do nothing
}
}
+
+ /**
+ * Waiting (max of 20 seconds)
+ * @param is examined stream
+ * @return {@code true} if the {@link InputStream#read()} is waiting for a new byte.
+ */
+ private static boolean isInputStreamEmpty( final TestProvidingInputStream is )
+ {
+ Thread t = new Thread( new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ is.readNextCommand();
+ }
+ catch ( IOException e )
+ {
+ Throwable cause = e.getCause();
+ Throwable err = cause == null ? e : cause;
+ if ( !( err instanceof InterruptedException ) )
+ {
+ System.err.println( err.toString() );
+ }
+ }
+ }
+ } );
+ t.start();
+ State state;
+ int loops = 0;
+ do
+ {
+ sleep( 100L );
+ state = t.getState();
+ }
+ while ( state == State.NEW && loops++ < WAIT_LOOPS );
+ t.interrupt();
+ return state == State.WAITING || state == State.TIMED_WAITING;
+ }
}
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 09230bb..8a5db41 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
@@ -299,7 +299,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:next-test\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:next-test\n" );
verify( notifiableTestStream, times( 1 ) )
.provideNewTest();
verifyNoMoreInteractions( notifiableTestStream );
@@ -334,7 +334,7 @@ public class ForkClientTest
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:bye\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:bye\n" );
client.kill();
verify( notifiableTestStream, times( 1 ) )
@@ -381,7 +381,7 @@ public class ForkClientTest
verified[0] = true;
}
};
- client.consumeMultiLineContent( ":maven:surefire:std:out:stop-on-next-test\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:stop-on-next-test\n" );
verifyZeroInteractions( notifiableTestStream );
verifyZeroInteractions( factory );
assertThat( verified[0] )
@@ -418,7 +418,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:std-out-stream:normal-run:UTF-8:bXNn\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:std-out-stream:normal-run:UTF-8:bXNn\n" );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
.createReporter();
@@ -463,7 +463,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:std-out-stream-new-line:normal-run:UTF-8:bXNn\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:std-out-stream-new-line:normal-run:UTF-8:bXNn\n" );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
.createReporter();
@@ -508,7 +508,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:std-err-stream:normal-run:UTF-8:bXNn\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:std-err-stream:normal-run:UTF-8:bXNn\n" );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
.createReporter();
@@ -553,7 +553,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:std-err-stream-new-line:normal-run:UTF-8:bXNn\n" );
+ client.consumeMultiLineContent( ":maven-surefire-event:std-err-stream-new-line:normal-run:UTF-8:bXNn\n" );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
.createReporter();
@@ -598,7 +598,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:console-error-log:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:console-error-log:UTF-8:"
+ encodeBase64String( "Listening for transport dt_socket at address:".getBytes( UTF_8 ) )
+ ":-:-:-" );
verifyZeroInteractions( notifiableTestStream );
@@ -649,7 +649,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:console-error-log:UTF-8"
+ client.consumeMultiLineContent( ":maven-surefire-event:console-error-log:UTF-8"
+ ":" + encodeBase64String( "Listening for transport dt_socket at address:".getBytes( UTF_8 ) )
+ ":" + encodeBase64String( "s1".getBytes( UTF_8 ) )
+ ":" + encodeBase64String( "s2".getBytes( UTF_8 ) ) );
@@ -709,7 +709,7 @@ public class ForkClientTest
when( logger.isWarnEnabled() )
.thenReturn( true );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:console-warning-log:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:console-warning-log:UTF-8:"
+ encodeBase64String( "s1".getBytes( UTF_8 ) ) );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
@@ -757,7 +757,7 @@ public class ForkClientTest
when( logger.isDebugEnabled() )
.thenReturn( true );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:console-debug-log:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:console-debug-log:UTF-8:"
+ encodeBase64String( "s1".getBytes( UTF_8 ) ) );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
@@ -803,7 +803,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:console-info-log:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:console-info-log:UTF-8:"
+ encodeBase64String( "s1".getBytes( UTF_8 ) ) );
verifyZeroInteractions( notifiableTestStream );
verify( factory, times( 1 ) )
@@ -849,7 +849,7 @@ public class ForkClientTest
AtomicBoolean printedErrorStream = new AtomicBoolean();
ConsoleLogger logger = mock( ConsoleLogger.class );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:sys-prop:normal-run:UTF-8:azE=:djE="
+ client.consumeMultiLineContent( ":maven-surefire-event:sys-prop:normal-run:UTF-8:azE=:djE="
+ encodeBase64String( "s1".getBytes( UTF_8 ) ) );
verifyZeroInteractions( notifiableTestStream );
verifyZeroInteractions( factory );
@@ -928,7 +928,7 @@ public class ForkClientTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:testset-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1063,7 +1063,7 @@ public class ForkClientTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:testset-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ encodedSourceText
@@ -1194,7 +1194,7 @@ public class ForkClientTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:testset-completed:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:testset-completed:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1323,7 +1323,7 @@ public class ForkClientTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1454,7 +1454,7 @@ public class ForkClientTest
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":-:-:-:-:-:-:-:-:-" );
@@ -1462,7 +1462,7 @@ public class ForkClientTest
.hasSize( 1 )
.contains( "pkg.MyTest" );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-succeeded:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-succeeded:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1596,7 +1596,7 @@ public class ForkClientTest
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":-:-:-:-:-:-:-:-:-" );
@@ -1604,7 +1604,7 @@ public class ForkClientTest
.hasSize( 1 )
.contains( "pkg.MyTest" );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-failed:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-failed:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1742,7 +1742,7 @@ public class ForkClientTest
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":-:-:-:-:-:-:-:-:-" );
@@ -1750,7 +1750,7 @@ public class ForkClientTest
.hasSize( 1 )
.contains( "pkg.MyTest" );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-skipped:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-skipped:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -1890,7 +1890,7 @@ public class ForkClientTest
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ encodedSourceText
@@ -1900,7 +1900,7 @@ public class ForkClientTest
.hasSize( 1 )
.contains( "pkg.MyTest" );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-error:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-error:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ encodedSourceText
@@ -2036,7 +2036,7 @@ public class ForkClientTest
ForkClient client = new ForkClient( factory, notifiableTestStream, logger, printedErrorStream, 0 );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":-:-:-:-:-:-:-:-:-" );
@@ -2044,7 +2044,7 @@ public class ForkClientTest
.hasSize( 1 )
.contains( "pkg.MyTest" );
- client.consumeMultiLineContent( ":maven:surefire:std:out:test-assumption-failure:normal-run:UTF-8:"
+ client.consumeMultiLineContent( ":maven-surefire-event:test-assumption-failure:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java
index 42dd636..5265f09 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java
@@ -20,7 +20,7 @@ package org.apache.maven.plugin.surefire.booterclient.output;
*/
import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerUtils;
-import org.apache.maven.surefire.booter.ForkedChannelEncoder;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
import org.apache.maven.surefire.report.ReportEntry;
import org.apache.maven.surefire.report.RunMode;
import org.apache.maven.surefire.report.SafeThrowable;
@@ -93,8 +93,8 @@ public class ForkedChannelDecoderTest
public void shouldHaveSystemProperty() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.sendSystemProperties( ObjectUtils.systemProps() );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.sendSystemProperties( ObjectUtils.systemProps() );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
decoder.setSystemPropertiesListener( new PropertyEventAssertionListener() );
@@ -259,11 +259,11 @@ public class ForkedChannelDecoderTest
public void shouldSendByeEvent() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.bye();
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.bye();
String read = new String( out.toByteArray(), UTF_8 );
assertThat( read )
- .isEqualTo( ":maven:surefire:std:out:bye\n" );
+ .isEqualTo( ":maven-surefire-event:bye\n" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
decoder.setByeListener( new EventAssertionListener() );
@@ -279,11 +279,11 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stopOnNextTest();
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stopOnNextTest();
String read = new String( out.toByteArray(), UTF_8 );
assertThat( read )
- .isEqualTo( ":maven:surefire:std:out:stop-on-next-test\n" );
+ .isEqualTo( ":maven-surefire-event:stop-on-next-test\n" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
decoder.setStopOnNextTestListener( new EventAssertionListener() );
@@ -299,11 +299,11 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.acquireNextTest();
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.acquireNextTest();
String read = new String( out.toByteArray(), UTF_8 );
assertThat( read )
- .isEqualTo( ":maven:surefire:std:out:next-test\n" );
+ .isEqualTo( ":maven-surefire-event:next-test\n" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
decoder.setAcquireNextTestListener( new EventAssertionListener() );
@@ -319,8 +319,8 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.consoleInfoLog( "msg" );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.consoleInfoLog( "msg" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -337,8 +337,8 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.consoleErrorLog( "msg" );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.consoleErrorLog( "msg" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -357,8 +357,8 @@ public class ForkedChannelDecoderTest
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.consoleErrorLog( t );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.consoleErrorLog( t );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -376,9 +376,9 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
StackTraceWriter stackTraceWriter = new DeserializedStacktraceWriter( "1", "2", "3" );
- forkedChannelEncoder.consoleErrorLog( stackTraceWriter, false );
+ encoder.consoleErrorLog( stackTraceWriter, false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -395,8 +395,8 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.consoleDebugLog( "msg" );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.consoleDebugLog( "msg" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -413,8 +413,8 @@ public class ForkedChannelDecoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.consoleWarningLog( "msg" );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.consoleWarningLog( "msg" );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -430,8 +430,8 @@ public class ForkedChannelDecoderTest
public void testStdOutStream() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdOut( "msg", false );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdOut( "msg", false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -447,8 +447,8 @@ public class ForkedChannelDecoderTest
public void testStdOutStreamPrint() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdOut( "", false );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdOut( "", false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -464,8 +464,8 @@ public class ForkedChannelDecoderTest
public void testStdOutStreamPrintWithNull() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdOut( null, false );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdOut( null, false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -481,8 +481,8 @@ public class ForkedChannelDecoderTest
public void testStdOutStreamPrintln() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdOut( "", true );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdOut( "", true );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -498,8 +498,8 @@ public class ForkedChannelDecoderTest
public void testStdOutStreamPrintlnWithNull() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdOut( null, true );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdOut( null, true );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -515,8 +515,8 @@ public class ForkedChannelDecoderTest
public void testStdErrStream() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.stdErr( "msg", false );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.stdErr( "msg", false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -532,8 +532,8 @@ public class ForkedChannelDecoderTest
public void shouldCountSameNumberOfSystemProperties() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
- forkedChannelEncoder.sendSystemProperties( ObjectUtils.systemProps() );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
+ encoder.sendSystemProperties( ObjectUtils.systemProps() );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -560,22 +560,22 @@ public class ForkedChannelDecoderTest
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
decoder.setSystemPropertiesListener( new PropertyEventAssertionListener() );
AssertionErrorHandler errorHandler = mock( AssertionErrorHandler.class );
- decoder.handleEvent( ":maven:surefire:std:out:abnormal-run:-", errorHandler );
+ decoder.handleEvent( ":maven-surefire-event:abnormal-run:-", errorHandler );
verify( errorHandler, times( 1 ) )
- .handledError( eq( ":maven:surefire:std:out:abnormal-run:-" ), nullable( Throwable.class ) );
+ .handledError( eq( ":maven-surefire-event:abnormal-run:-" ), nullable( Throwable.class ) );
}
@Test
public void shouldHandleExit() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
- forkedChannelEncoder.sendExitEvent( stackTraceWriter, false );
+ encoder.sendExitEvent( stackTraceWriter, false );
LineNumberReader lines = out.newReader( UTF_8 );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
@@ -677,10 +677,10 @@ public class ForkedChannelDecoderTest
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- ForkedChannelEncoder.class.getMethod( operation[0], ReportEntry.class, boolean.class )
- .invoke( forkedChannelEncoder, reportEntry, trim );
+ LegacyMasterProcessChannelEncoder.class.getMethod( operation[0], ReportEntry.class, boolean.class )
+ .invoke( encoder, reportEntry, trim );
ForkedChannelDecoder decoder = new ForkedChannelDecoder();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
index b1e3b22..14a28fe 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java
@@ -28,7 +28,6 @@ import org.apache.maven.plugin.surefire.AbstractSurefireMojoTest;
import org.apache.maven.plugin.surefire.CommonReflectorTest;
import org.apache.maven.plugin.surefire.MojoMocklessTest;
import org.apache.maven.plugin.surefire.SurefireHelperTest;
-import org.apache.maven.plugin.surefire.SurefireReflectorTest;
import org.apache.maven.plugin.surefire.SurefirePropertiesTest;
import org.apache.maven.plugin.surefire.booterclient.BooterDeserializerProviderConfigurationTest;
import org.apache.maven.plugin.surefire.booterclient.BooterDeserializerStartupConfigurationTest;
@@ -52,6 +51,7 @@ import org.apache.maven.plugin.surefire.util.DirectoryScannerTest;
import org.apache.maven.plugin.surefire.util.ScannerUtilTest;
import org.apache.maven.plugin.surefire.util.SpecificFileFilterTest;
import org.apache.maven.surefire.extensions.ConsoleOutputReporterTest;
+import org.apache.maven.surefire.extensions.ForkChannelTest;
import org.apache.maven.surefire.extensions.StatelessReporterTest;
import org.apache.maven.surefire.extensions.StatelessTestsetInfoReporterTest;
import org.apache.maven.surefire.report.FileReporterTest;
@@ -89,7 +89,6 @@ public class JUnit4SuiteTest extends TestCase
suite.addTest( new JUnit4TestAdapter( TestProvidingInputStreamTest.class ) );
suite.addTest( new JUnit4TestAdapter( TestLessInputStreamBuilderTest.class ) );
suite.addTest( new JUnit4TestAdapter( SPITest.class ) );
- suite.addTest( new JUnit4TestAdapter( SurefireReflectorTest.class ) );
suite.addTest( new JUnit4TestAdapter( SurefireHelperTest.class ) );
suite.addTest( new JUnit4TestAdapter( AbstractSurefireMojoTest.class ) );
suite.addTest( new JUnit4TestAdapter( DefaultForkConfigurationTest.class ) );
@@ -106,6 +105,7 @@ public class JUnit4SuiteTest extends TestCase
suite.addTest( new JUnit4TestAdapter( StatelessTestsetInfoReporterTest.class ) );
suite.addTest( new JUnit4TestAdapter( CommonReflectorTest.class ) );
suite.addTest( new JUnit4TestAdapter( ForkStarterTest.class ) );
+ suite.addTest( new JUnit4TestAdapter( ForkChannelTest.class ) );
return suite;
}
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java
new file mode 100644
index 0000000..63db316
--- /dev/null
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/extensions/ForkChannelTest.java
@@ -0,0 +1,146 @@
+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.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream;
+import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
+import org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.io.IOException;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.net.Socket;
+import java.net.URI;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ *
+ */
+@RunWith( PowerMockRunner.class )
+@PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
+public class ForkChannelTest
+{
+ private static final long TESTCASE_TIMEOUT = 30_000L;
+
+ @Mock
+ private StreamConsumer consumer;
+
+ @Test( timeout = TESTCASE_TIMEOUT )
+ public void shouldRequestReplyMessagesViaTCP() throws Exception
+ {
+ ForkNodeFactory factory = new SurefireForkNodeFactory();
+ ForkChannel channel = factory.createForkChannel( 1 );
+
+ assertThat( channel.getForkChannelId() )
+ .isEqualTo( 1 );
+
+ assertThat( channel.useStdIn() )
+ .isFalse();
+
+ assertThat( channel.useStdOut() )
+ .isFalse();
+
+ assertThat( channel.getForkNodeConnectionString() )
+ .startsWith( "tcp://127.0.0.1:" )
+ .isNotEqualTo( "tcp://127.0.0.1:" );
+
+ URI uri = new URI( channel.getForkNodeConnectionString() );
+
+ assertThat( uri.getPort() )
+ .isPositive();
+
+ ArgumentCaptor<String> line = ArgumentCaptor.forClass( String.class );
+ doNothing().when( consumer ).consumeLine( anyString() );
+
+ Client client = new Client( uri.getPort() );
+ final AtomicBoolean hasError = new AtomicBoolean();
+ client.setUncaughtExceptionHandler( new UncaughtExceptionHandler()
+ {
+ @Override
+ public void uncaughtException( Thread t, Throwable e )
+ {
+ hasError.set( true );
+ e.printStackTrace( System.err );
+ }
+ } );
+ client.start();
+
+ channel.openChannel();
+ SECONDS.sleep( 3L );
+
+ TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
+ TestLessInputStream commandReader = builder.build();
+ commandReader.noop();
+ channel.bindCommandReader( commandReader ).start();
+ channel.bindEventHandler( consumer ).start();
+
+ client.join( TESTCASE_TIMEOUT );
+
+ assertThat( hasError.get() )
+ .isFalse();
+
+ verify( consumer, times( 1 ) )
+ .consumeLine( line.capture() );
+
+ assertThat( line.getValue() )
+ .isEqualTo( "Hi There!" );
+ }
+
+ private static class Client extends Thread
+ {
+ private final int port;
+
+ private Client( int port )
+ {
+ this.port = port;
+ }
+
+ @Override
+ public void run()
+ {
+ try ( Socket socket = new Socket( "127.0.0.1", port ) )
+ {
+ byte[] data = new byte[128];
+ int readLength = socket.getInputStream().read( data );
+ String token = new String( data, 0, readLength, US_ASCII );
+ assertThat( token ).isEqualTo( ":maven-surefire-command:noop:" );
+ socket.getOutputStream().write( "Hi There!".getBytes( US_ASCII ) );
+ }
+ catch ( IOException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+ }
+}
diff --git a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
index b39181a..5f6edea 100644
--- a/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
+++ b/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
@@ -29,6 +29,7 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.suite.RunResult;
import static org.apache.maven.plugin.surefire.SurefireHelper.reportExecution;
@@ -365,6 +366,9 @@ public class SurefirePlugin
@Parameter( property = "surefire.useModulePath", defaultValue = "true" )
private boolean useModulePath;
+ @Parameter( property = "surefire.forkNode" )
+ private ForkNodeFactory forkNode;
+
/**
* You can selectively exclude individual environment variables by enumerating their keys.
* <br>
@@ -831,4 +835,10 @@ public class SurefirePlugin
{
return enableProcessChecker;
}
+
+ @Override
+ protected final ForkNodeFactory getForkNode()
+ {
+ return forkNode;
+ }
}
diff --git a/pom.xml b/pom.xml
index d005dd4..3b0e4bb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
<module>surefire-logger-api</module>
<module>surefire-api</module>
<module>surefire-extensions-api</module>
+ <module>surefire-extensions-spi</module>
<module>surefire-booter</module>
<module>surefire-grouper</module>
<module>surefire-providers</module>
@@ -474,10 +475,8 @@
</goals>
<configuration>
<includes>
- <include>org/apache/maven/shared/utils/logging/*.java</include>
<include>HelpMojo.java</include>
<include>**/HelpMojo.java</include>
- <include>org/apache/maven/plugin/failsafe/xmlsummary/*.java</include>
</includes>
<compilerArgs>
<!-- FIXME: maven-plugin-plugin therefore used -syntax or none due to HelpMojo -->
@@ -493,10 +492,8 @@
</goals>
<configuration>
<excludes>
- <exclude>org/apache/maven/shared/utils/logging/*.java</exclude>
<exclude>HelpMojo.java</exclude>
<exclude>**/HelpMojo.java</exclude>
- <exclude>org/apache/maven/plugin/failsafe/xmlsummary/*.java</exclude>
</excludes>
<compilerArgs>
<arg>-Xdoclint:all</arg>
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
index ec05580..6ac0ce2 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java
@@ -20,6 +20,8 @@ package org.apache.maven.surefire.booter;
*/
import org.apache.maven.surefire.cli.CommandLineOption;
+import org.apache.maven.surefire.providerapi.CommandChainReader;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.providerapi.ProviderParameters;
import org.apache.maven.surefire.report.ConsoleStream;
import org.apache.maven.surefire.report.DefaultDirectConsoleReporter;
@@ -46,15 +48,13 @@ import static java.util.Collections.emptyList;
* @author Kristian Rosenvold
*/
public class BaseProviderFactory
- implements DirectoryScannerParametersAware, ReporterConfigurationAware, SurefireClassLoadersAware, TestRequestAware,
- ProviderPropertiesAware, ProviderParameters, TestArtifactInfoAware, RunOrderParametersAware, MainCliOptionsAware,
- FailFastAware, ShutdownAware
+ implements ProviderParameters
{
- private final ReporterFactory reporterFactory;
-
private final boolean insideFork;
- private ForkedChannelEncoder forkedChannelEncoder;
+ private ReporterFactory reporterFactory;
+
+ private MasterProcessChannelEncoder masterProcessChannelEncoder;
private List<CommandLineOption> mainCliOptions = emptyList();
@@ -74,17 +74,27 @@ public class BaseProviderFactory
private int skipAfterFailureCount;
- private Shutdown shutdown;
-
private Integer systemExitTimeout;
- public BaseProviderFactory( ReporterFactory reporterFactory, boolean insideFork )
+ private CommandChainReader commandReader;
+
+ public BaseProviderFactory( boolean insideFork )
{
- this.reporterFactory = reporterFactory;
this.insideFork = insideFork;
}
@Override
+ public CommandChainReader getCommandReader()
+ {
+ return commandReader;
+ }
+
+ public void setCommandReader( CommandChainReader commandReader )
+ {
+ this.commandReader = commandReader;
+ }
+
+ @Override
@Deprecated
public DirectoryScanner getDirectoryScanner()
{
@@ -114,25 +124,27 @@ public class BaseProviderFactory
? null : new DefaultRunOrderCalculator( runOrderParameters, getThreadCount() );
}
+ public void setReporterFactory( ReporterFactory reporterFactory )
+ {
+ this.reporterFactory = reporterFactory;
+ }
+
@Override
public ReporterFactory getReporterFactory()
{
return reporterFactory;
}
- @Override
public void setDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
{
this.directoryScannerParameters = directoryScannerParameters;
}
- @Override
public void setReporterConfiguration( ReporterConfiguration reporterConfiguration )
{
this.reporterConfiguration = reporterConfiguration;
}
- @Override
public void setClassLoaders( ClassLoader testClassLoader )
{
this.testClassLoader = testClassLoader;
@@ -141,11 +153,11 @@ public class BaseProviderFactory
@Override
public ConsoleStream getConsoleLogger()
{
- return insideFork ? new ForkingRunListener( forkedChannelEncoder, reporterConfiguration.isTrimStackTrace() )
- : new DefaultDirectConsoleReporter( reporterConfiguration.getOriginalSystemOut() );
+ return insideFork
+ ? new ForkingRunListener( masterProcessChannelEncoder, reporterConfiguration.isTrimStackTrace() )
+ : new DefaultDirectConsoleReporter( reporterConfiguration.getOriginalSystemOut() );
}
- @Override
public void setTestRequest( TestRequest testRequest )
{
this.testRequest = testRequest;
@@ -175,7 +187,6 @@ public class BaseProviderFactory
return testClassLoader;
}
- @Override
public void setProviderProperties( Map<String, String> providerProperties )
{
this.providerProperties = providerProperties;
@@ -193,13 +204,11 @@ public class BaseProviderFactory
return testArtifactInfo;
}
- @Override
public void setTestArtifactInfo( TestArtifactInfo testArtifactInfo )
{
this.testArtifactInfo = testArtifactInfo;
}
- @Override
public void setRunOrderParameters( RunOrderParameters runOrderParameters )
{
this.runOrderParameters = runOrderParameters;
@@ -211,7 +220,11 @@ public class BaseProviderFactory
return mainCliOptions;
}
- @Override
+ /**
+ * CLI options in plugin (main) JVM process.
+ *
+ * @param mainCliOptions options
+ */
public void setMainCliOptions( List<CommandLineOption> mainCliOptions )
{
this.mainCliOptions = mainCliOptions == null ? Collections.<CommandLineOption>emptyList() : mainCliOptions;
@@ -223,7 +236,11 @@ public class BaseProviderFactory
return skipAfterFailureCount;
}
- @Override
+ /**
+ * See the plugin configuration parameter "skipAfterFailureCount".
+ *
+ * @param skipAfterFailureCount the value in config parameter "skipAfterFailureCount"
+ */
public void setSkipAfterFailureCount( int skipAfterFailureCount )
{
this.skipAfterFailureCount = skipAfterFailureCount;
@@ -236,18 +253,6 @@ public class BaseProviderFactory
}
@Override
- public Shutdown getShutdown()
- {
- return shutdown;
- }
-
- @Override
- public void setShutdown( Shutdown shutdown )
- {
- this.shutdown = shutdown;
- }
-
- @Override
public Integer getSystemExitTimeout()
{
return systemExitTimeout;
@@ -259,13 +264,13 @@ public class BaseProviderFactory
}
@Override
- public ForkedChannelEncoder getForkedChannelEncoder()
+ public MasterProcessChannelEncoder getForkedChannelEncoder()
{
- return forkedChannelEncoder;
+ return masterProcessChannelEncoder;
}
- public void setForkedChannelEncoder( ForkedChannelEncoder forkedChannelEncoder )
+ public void setForkedChannelEncoder( MasterProcessChannelEncoder masterProcessChannelEncoder )
{
- this.forkedChannelEncoder = forkedChannelEncoder;
+ this.masterProcessChannelEncoder = masterProcessChannelEncoder;
}
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/Command.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/Command.java
index f05c0f6..834317b 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/Command.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/Command.java
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import java.util.Objects;
+
import static java.util.Objects.requireNonNull;
import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank;
import static org.apache.maven.surefire.booter.MasterProcessCommand.RUN_CLASS;
@@ -47,6 +49,11 @@ public final class Command
this.data = data;
}
+ public Command( MasterProcessCommand command )
+ {
+ this( command, null );
+ }
+
public static Command toShutdown( Shutdown shutdownType )
{
return new Command( SHUTDOWN, shutdownType.name() );
@@ -57,11 +64,6 @@ public final class Command
return new Command( RUN_CLASS, runClass );
}
- public Command( MasterProcessCommand command )
- {
- this( command, null );
- }
-
public MasterProcessCommand getCommandType()
{
return command;
@@ -78,18 +80,13 @@ public final class Command
*/
public Shutdown toShutdownData()
{
- if ( !isType( SHUTDOWN ) )
+ if ( command != SHUTDOWN )
{
throw new IllegalStateException( "expected MasterProcessCommand.SHUTDOWN" );
}
return isBlank( data ) ? DEFAULT : Shutdown.valueOf( data );
}
- public boolean isType( MasterProcessCommand command )
- {
- return command == this.command;
- }
-
@Override
public boolean equals( Object o )
{
@@ -105,7 +102,7 @@ public final class Command
Command arg = (Command) o;
- return command == arg.command && ( data == null ? arg.data == null : data.equals( arg.data ) );
+ return command == arg.command && Objects.equals( data, arg.data );
}
@Override
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java
index 74b9eb9..617eadc 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java
@@ -59,7 +59,9 @@ public enum ForkedProcessEvent
BOOTERCODE_JVM_EXIT_ERROR( "jvm-exit-error" );
- public static final String MAGIC_NUMBER = ":maven:surefire:std:out:";
+ public static final String MAGIC_NUMBER = "maven-surefire-event";
+
+ public static final String MAGIC_NUMBER_DELIMITED = ':' + MAGIC_NUMBER + ':';
public static final Map<String, ForkedProcessEvent> EVENTS = events();
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java
index 5bb16ee..1c6db50 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java
@@ -19,6 +19,7 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.report.ReporterFactory;
import org.apache.maven.surefire.report.RunListener;
import org.apache.maven.surefire.suite.RunResult;
@@ -34,9 +35,9 @@ public class ForkingReporterFactory
{
private final boolean trimstackTrace;
- private final ForkedChannelEncoder eventChannel;
+ private final MasterProcessChannelEncoder eventChannel;
- public ForkingReporterFactory( boolean trimstackTrace, ForkedChannelEncoder eventChannel )
+ public ForkingReporterFactory( boolean trimstackTrace, MasterProcessChannelEncoder eventChannel )
{
this.trimstackTrace = trimstackTrace;
this.eventChannel = eventChannel;
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
index 528b607..6148149 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
@@ -20,6 +20,7 @@ package org.apache.maven.surefire.booter;
*/
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.report.ConsoleStream;
import org.apache.maven.surefire.report.ReportEntry;
@@ -50,13 +51,13 @@ import static java.util.Objects.requireNonNull;
public class ForkingRunListener
implements RunListener, ConsoleLogger, ConsoleOutputReceiver, ConsoleStream
{
- private final ForkedChannelEncoder target;
+ private final MasterProcessChannelEncoder target;
private final boolean trim;
private volatile RunMode runMode = NORMAL_RUN;
- public ForkingRunListener( ForkedChannelEncoder target, boolean trim )
+ public ForkingRunListener( MasterProcessChannelEncoder target, boolean trim )
{
this.target = target;
this.trim = trim;
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessCommand.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessCommand.java
index 7c4520f..6fa85a1 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessCommand.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessCommand.java
@@ -19,44 +19,49 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import java.io.DataInputStream;
-import java.io.IOException;
-
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.util.Objects.requireNonNull;
-import static java.lang.String.format;
/**
* Commands which are sent from plugin to the forked jvm.
* Support and methods related to the commands.
+ * <br>
+ * <br>
+ * magic number : opcode [: opcode specific data]*
+ * <br>
+ * or data encoded with Base64
+ * <br>
+ * magic number : opcode [: Base64(opcode specific data)]*
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 2.19
*/
public enum MasterProcessCommand
{
- RUN_CLASS( 0, String.class ),
- TEST_SET_FINISHED( 1, Void.class ),
- SKIP_SINCE_NEXT_TEST( 2, Void.class ),
- SHUTDOWN( 3, String.class ),
+ RUN_CLASS( "run-testclass", String.class ),
+ TEST_SET_FINISHED( "testset-finished", Void.class ),
+ SKIP_SINCE_NEXT_TEST( "skip-since-next-test", Void.class ),
+ SHUTDOWN( "shutdown", String.class ),
/** To tell a forked process that the master process is still alive. Repeated after 10 seconds. */
- NOOP( 4, Void.class ),
- BYE_ACK( 5, Void.class );
+ NOOP( "noop", Void.class ),
+ BYE_ACK( "bye-ack", Void.class );
+
+ public static final String MAGIC_NUMBER = "maven-surefire-command";
- private final int id;
+ private final String opcodeName;
private final Class<?> dataType;
- MasterProcessCommand( int id, Class<?> dataType )
+ MasterProcessCommand( String opcodeName, Class<?> dataType )
{
- this.id = id;
+ this.opcodeName = opcodeName;
this.dataType = requireNonNull( dataType, "dataType cannot be null" );
}
- public int getId()
+ public String getOpcode()
{
- return id;
+ return opcodeName;
}
public Class<?> getDataType()
@@ -69,7 +74,18 @@ public enum MasterProcessCommand
return dataType != Void.class;
}
- @SuppressWarnings( "checkstyle:magicnumber" )
+ public static MasterProcessCommand byOpcode( String opcode )
+ {
+ for ( MasterProcessCommand cmd : values() )
+ {
+ if ( cmd.opcodeName.equals( opcode ) )
+ {
+ return cmd;
+ }
+ }
+ return null;
+ }
+
public byte[] encode( String data )
{
if ( !hasDataType() )
@@ -82,109 +98,44 @@ public enum MasterProcessCommand
throw new IllegalArgumentException( "Data type can be only " + String.class );
}
- final byte[] dataBytes = fromDataType( data );
- final int len = dataBytes.length;
-
- final byte[] encoded = new byte[8 + len];
-
- final int command = getId();
- setCommandAndDataLength( command, len, encoded );
- System.arraycopy( dataBytes, 0, encoded, 8, len );
-
- return encoded;
+ return encode( opcodeName, data )
+ .toString()
+ .getBytes( US_ASCII );
}
- @SuppressWarnings( "checkstyle:magicnumber" )
public byte[] encode()
{
if ( getDataType() != Void.class )
{
throw new IllegalArgumentException( "Data type can be only " + getDataType() );
}
- byte[] encoded = new byte[8];
- int command = getId();
- setCommandAndDataLength( command, 0, encoded );
- return encoded;
- }
-
- public static Command decode( DataInputStream is )
- throws IOException
- {
- MasterProcessCommand command = resolve( is.readInt() );
- if ( command == null )
- {
- return null;
- }
- else
- {
- int dataLength = is.readInt();
- if ( dataLength > 0 )
- {
- byte[] buffer = new byte[ dataLength ];
- is.readFully( buffer );
- if ( command.getDataType() == Void.class )
- {
- throw new IOException( format( "Command %s unexpectedly read Void data with length %d.",
- command, dataLength ) );
- }
-
- String data = command.toDataTypeAsString( buffer );
- return new Command( command, data );
- }
- else
- {
- return new Command( command );
- }
- }
+ return encode( opcodeName, null )
+ .toString()
+ .getBytes( US_ASCII );
}
- String toDataTypeAsString( byte... data )
+ /**
+ * Encodes opcode and data.
+ *
+ * @param operation opcode
+ * @param data data
+ * @return encoded command
+ */
+ private static StringBuilder encode( String operation, String data )
{
- switch ( this )
- {
- case RUN_CLASS:
- case SHUTDOWN:
- return new String( data, US_ASCII );
- default:
- return null;
- }
- }
+ StringBuilder s = new StringBuilder( 128 )
+ .append( ':' )
+ .append( MAGIC_NUMBER )
+ .append( ':' )
+ .append( operation );
- byte[] fromDataType( String data )
- {
- switch ( this )
+ if ( data != null )
{
- case RUN_CLASS:
- case SHUTDOWN:
- return data.getBytes( US_ASCII );
- default:
- return new byte[0];
+ s.append( ':' )
+ .append( data );
}
- }
- static MasterProcessCommand resolve( int id )
- {
- for ( MasterProcessCommand command : values() )
- {
- if ( id == command.id )
- {
- return command;
- }
- }
- return null;
- }
-
- @SuppressWarnings( "checkstyle:magicnumber" )
- static void setCommandAndDataLength( int command, int dataLength, byte... encoded )
- {
- encoded[0] = (byte) ( command >>> 24 );
- encoded[1] = (byte) ( command >>> 16 );
- encoded[2] = (byte) ( command >>> 8 );
- encoded[3] = (byte) command;
- encoded[4] = (byte) ( dataLength >>> 24 );
- encoded[5] = (byte) ( dataLength >>> 16 );
- encoded[6] = (byte) ( dataLength >>> 8 );
- encoded[7] = (byte) dataLength;
+ return s.append( ':' );
}
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/RunOrderParametersAware.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/RunOrderParametersAware.java
deleted file mode 100644
index 3bee07d..0000000
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/RunOrderParametersAware.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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.testset.RunOrderParameters;
-
-/**
- * @author Kristian Rosenvold
- */
-interface RunOrderParametersAware
-{
- void setRunOrderParameters( RunOrderParameters runOrderParameters );
-}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TestArtifactInfoAware.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/TestArtifactInfoAware.java
deleted file mode 100644
index 9898061..0000000
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TestArtifactInfoAware.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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.testset.TestArtifactInfo;
-
-/**
- * @author Kristian Rosenvold
- */
-interface TestArtifactInfoAware
-{
- void setTestArtifactInfo( TestArtifactInfo testArtifactInfo );
-}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ReporterConfigurationAware.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandChainReader.java
similarity index 62%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/ReporterConfigurationAware.java
rename to surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandChainReader.java
index 8c65be3..2c94e9d 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ReporterConfigurationAware.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandChainReader.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.providerapi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,12 +19,21 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.report.ReporterConfiguration;
+import org.apache.maven.surefire.testset.TestSetFailedException;
/**
- * @author Kristian Rosenvold
+ * Hiding CommandReader instance in provider.
*/
-interface ReporterConfigurationAware
+public interface CommandChainReader
{
- void setReporterConfiguration( ReporterConfiguration reporterConfiguration );
+ boolean awaitStarted()
+ throws TestSetFailedException;
+
+ void addTestsFinishedListener( CommandListener listener );
+
+ void addSkipNextTestsListener( CommandListener listener );
+
+ void addShutdownListener( CommandListener listener );
+
+ void removeListener( CommandListener listener );
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandListener.java
similarity index 90%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java
rename to surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandListener.java
index 523ca76..b0d8870 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/CommandListener.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.providerapi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.booter.Command;
+
/**
* Command listener interface.
*/
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelDecoder.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelDecoder.java
new file mode 100644
index 0000000..6c64b25
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelDecoder.java
@@ -0,0 +1,47 @@
+package org.apache.maven.surefire.providerapi;
+
+/*
+ * 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 java.io.IOException;
+
+/**
+ * An abstraction for physical decoder of commands. The commands are sent from master Maven process and
+ * received by the child forked Surefire process. The session must be open after the MasterProcessChannelDecoderFactory
+ * has created the decoder instance. The session can be closed on the decoder instance.
+ */
+public interface MasterProcessChannelDecoder
+ extends AutoCloseable
+{
+ /**
+ * Reads the bytes from a channel, waiting until the command is read completely or
+ * the channel throws {@link java.io.EOFException}.
+ * <br>
+ * This method is called in a single Thread. The constructor can be called within another thread.
+ *
+ * @return decoded command
+ * @throws IOException exception in channel
+ */
+ Command decode() throws IOException;
+
+ @Override
+ void close() throws IOException;
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelEncoder.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelEncoder.java
new file mode 100644
index 0000000..b734b61
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/MasterProcessChannelEncoder.java
@@ -0,0 +1,84 @@
+package org.apache.maven.surefire.providerapi;
+
+/*
+ * 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.report.ReportEntry;
+import org.apache.maven.surefire.report.StackTraceWriter;
+
+import java.util.Map;
+
+/**
+ * An abstraction for physical encoder of events.
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 3.0.0-M5
+ */
+public interface MasterProcessChannelEncoder
+{
+ MasterProcessChannelEncoder asRerunMode();
+
+ MasterProcessChannelEncoder asNormalMode();
+
+ boolean checkError();
+
+ void sendSystemProperties( Map<String, String> sysProps );
+
+ void testSetStarting( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testSetCompleted( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testStarting( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testSucceeded( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testFailed( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testSkipped( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testError( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void testAssumptionFailure( ReportEntry reportEntry, boolean trimStackTraces );
+
+ void stdOut( String msg, boolean newLine );
+
+ void stdErr( String msg, boolean newLine );
+
+ void consoleInfoLog( String msg );
+
+ void consoleErrorLog( String msg );
+
+ void consoleErrorLog( Throwable t );
+
+ void consoleErrorLog( String msg, Throwable t );
+
+ void consoleErrorLog( StackTraceWriter stackTraceWriter, boolean trimStackTraces );
+
+ void consoleDebugLog( String msg );
+
+ void consoleWarningLog( String msg );
+
+ void bye();
+
+ void stopOnNextTest();
+
+ void acquireNextTest();
+
+ void sendExitEvent( StackTraceWriter stackTraceWriter, boolean trimStackTraces );
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
index 0fea537..47a6a7e 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
@@ -19,8 +19,6 @@ package org.apache.maven.surefire.providerapi;
* under the License.
*/
-import org.apache.maven.surefire.booter.ForkedChannelEncoder;
-import org.apache.maven.surefire.booter.Shutdown;
import org.apache.maven.surefire.cli.CommandLineOption;
import org.apache.maven.surefire.report.ConsoleStream;
import org.apache.maven.surefire.report.ReporterConfiguration;
@@ -147,9 +145,9 @@ public interface ProviderParameters
*/
boolean isInsideFork();
- Shutdown getShutdown();
-
Integer getSystemExitTimeout();
- ForkedChannelEncoder getForkedChannelEncoder();
+ MasterProcessChannelEncoder getForkedChannelEncoder();
+
+ CommandChainReader getCommandReader();
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java b/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
index 8145e51..cb89c31 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/suite/RunResult.java
@@ -48,7 +48,7 @@ public class RunResult
public static final int SUCCESS = 0;
- private static final int FAILURE = 255;
+ public static final int FAILURE = 255;
private static final int NO_TESTS = 254;
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java b/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java
index c7c123a..e7ed763 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java
@@ -41,7 +41,7 @@ import static org.apache.maven.surefire.testset.ResolvedTest.Type.METHOD;
* composed of included and excluded tests.<br>
* The methods {@link #shouldRun(String, String)} are filters easily used in JUnit filter or TestNG.
* This class is independent of JUnit and TestNG API.<br>
- * It is accessed by Java Reflection API in {@link org.apache.maven.surefire.booter.SurefireReflector}
+ * It is accessed by Java Reflection API in {@code org.apache.maven.surefire.booter.SurefireReflector}
* using specific ClassLoader.
*/
public class TestListResolver
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/ReflectionUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/ReflectionUtils.java
index 57e9ea7..2e4eba6 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/util/ReflectionUtils.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/ReflectionUtils.java
@@ -76,7 +76,7 @@ public final class ReflectionUtils
return invokeMethodWithArray( instance, method );
}
- public static Constructor getConstructor( Class<?> clazz, Class<?>... arguments )
+ public static Constructor<?> getConstructor( Class<?> clazz, Class<?>... arguments )
{
try
{
@@ -88,7 +88,7 @@ public final class ReflectionUtils
}
}
- public static Object newInstance( Constructor constructor, Object... params )
+ public static Object newInstance( Constructor<?> constructor, Object... params )
{
try
{
@@ -119,7 +119,7 @@ public final class ReflectionUtils
try
{
Class<?> aClass = loadClass( classLoader, className );
- Constructor constructor = getConstructor( aClass, param1Class );
+ Constructor<?> constructor = getConstructor( aClass, param1Class );
return constructor.newInstance( param1 );
}
catch ( InvocationTargetException e )
@@ -132,25 +132,6 @@ public final class ReflectionUtils
}
}
- public static Object instantiateTwoArgs( ClassLoader classLoader, String className, Class<?> param1Class,
- Object param1, Class param2Class, Object param2 )
- {
- try
- {
- Class<?> aClass = loadClass( classLoader, className );
- Constructor constructor = getConstructor( aClass, param1Class, param2Class );
- return constructor.newInstance( param1, param2 );
- }
- catch ( InvocationTargetException e )
- {
- throw new SurefireReflectionException( e.getTargetException() );
- }
- catch ( ReflectiveOperationException e )
- {
- throw new SurefireReflectionException( e );
- }
- }
-
public static void invokeSetter( Object o, String name, Class<?> value1clazz, Object value )
{
Method setter = getMethod( o, name, value1clazz );
@@ -191,10 +172,10 @@ public final class ReflectionUtils
}
}
- public static Object instantiateObject( String className, Class[] types, Object[] params, ClassLoader classLoader )
+ public static Object instantiateObject( String className, Class<?>[] types, Object[] params, ClassLoader cl )
{
- Class<?> clazz = loadClass( classLoader, className );
- final Constructor constructor = getConstructor( clazz, types );
+ Class<?> clazz = loadClass( cl, className );
+ final Constructor<?> constructor = getConstructor( clazz, types );
return newInstance( constructor, params );
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DaemonThreadFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DaemonThreadFactory.java
index 3610a4b..32b597a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DaemonThreadFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DaemonThreadFactory.java
@@ -19,6 +19,7 @@ package org.apache.maven.surefire.util.internal;
* under the License.
*/
+import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
@@ -28,29 +29,24 @@ import java.util.concurrent.atomic.AtomicInteger;
public final class DaemonThreadFactory
implements ThreadFactory
{
+ private static final ThreadFactory DEFAULT_THREAD_FACTORY = Executors.defaultThreadFactory();
+
private static final AtomicInteger POOL_NUMBER = new AtomicInteger( 1 );
private final AtomicInteger threadNumber = new AtomicInteger( 1 );
- private final ThreadGroup group;
-
private final String namePrefix;
private DaemonThreadFactory()
{
- SecurityManager s = System.getSecurityManager();
- group = s != null ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool-" + POOL_NUMBER.getAndIncrement() + "-thread-";
}
@Override
public Thread newThread( Runnable r )
{
- Thread t = new Thread( group, r, namePrefix + threadNumber.getAndIncrement() );
- if ( t.getPriority() != Thread.NORM_PRIORITY )
- {
- t.setPriority( Thread.NORM_PRIORITY );
- }
+ Thread t = DEFAULT_THREAD_FACTORY.newThread( r );
+ t.setName( namePrefix + threadNumber.getAndIncrement() );
t.setDaemon( true );
return t;
}
@@ -71,34 +67,19 @@ public final class DaemonThreadFactory
public static Thread newDaemonThread( Runnable r )
{
- SecurityManager s = System.getSecurityManager();
- ThreadGroup group = s == null ? Thread.currentThread().getThreadGroup() : s.getThreadGroup();
- Thread t = new Thread( group, r );
- if ( t.getPriority() != Thread.NORM_PRIORITY )
- {
- t.setPriority( Thread.NORM_PRIORITY );
- }
- t.setDaemon( true );
- return t;
+ return new DaemonThreadFactory().newThread( r );
}
public static Thread newDaemonThread( Runnable r, String name )
{
- SecurityManager s = System.getSecurityManager();
- ThreadGroup group = s == null ? Thread.currentThread().getThreadGroup() : s.getThreadGroup();
- Thread t = new Thread( group, r, name );
- if ( t.getPriority() != Thread.NORM_PRIORITY )
- {
- t.setPriority( Thread.NORM_PRIORITY );
- }
- t.setDaemon( true );
+ Thread t = new DaemonThreadFactory().newThread( r );
+ t.setName( name );
return t;
}
private static class NamedThreadFactory
implements ThreadFactory
{
-
private final String name;
private NamedThreadFactory( String name )
diff --git a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
index 38f0c48..66a95a6 100644
--- a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java
@@ -23,11 +23,7 @@ import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import org.apache.maven.plugin.surefire.runorder.ThreadedExecutionSchedulerTest;
import org.apache.maven.surefire.SpecificTestClassFilterTest;
-import org.apache.maven.surefire.booter.CommandReaderTest;
-import org.apache.maven.surefire.booter.ForkedChannelEncoderTest;
import org.apache.maven.surefire.booter.ForkingRunListenerTest;
-import org.apache.maven.surefire.booter.MasterProcessCommandTest;
-import org.apache.maven.surefire.booter.SurefireReflectorTest;
import org.apache.maven.surefire.report.LegacyPojoStackTraceWriterTest;
import org.apache.maven.surefire.suite.RunResultTest;
import org.apache.maven.surefire.testset.FundamentalFilterTest;
@@ -51,11 +47,8 @@ import org.junit.runners.Suite;
* @since 2.19
*/
@Suite.SuiteClasses( {
- CommandReaderTest.class,
ThreadedExecutionSchedulerTest.class,
ForkingRunListenerTest.class,
- MasterProcessCommandTest.class,
- SurefireReflectorTest.class,
LegacyPojoStackTraceWriterTest.class,
RunResultTest.class,
ResolvedTestTest.class,
@@ -69,8 +62,7 @@ import org.junit.runners.Suite;
SpecificTestClassFilterTest.class,
FundamentalFilterTest.class,
ImmutableMapTest.class,
- ReflectionUtilsTest.class,
- ForkedChannelEncoderTest.class
+ ReflectionUtilsTest.class
} )
@RunWith( Suite.class )
public class JUnit4SuiteTest
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkingRunListenerTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkingRunListenerTest.java
index 549f3aa..b125b0c 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkingRunListenerTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkingRunListenerTest.java
@@ -19,10 +19,17 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-
import junit.framework.TestCase;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
+import org.mockito.ArgumentCaptor;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* @author <a href="mailto:kristian.rosenvold@gmail.com">Kristian Rosenvold</a>
@@ -32,10 +39,16 @@ public class ForkingRunListenerTest
{
public void testInfo()
{
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- PrintStream target = new PrintStream( byteArrayOutputStream );
- ForkingRunListener forkingRunListener = new ForkingRunListener( new ForkedChannelEncoder( target ), true );
+ MasterProcessChannelEncoder encoder = mock( MasterProcessChannelEncoder.class );
+ ArgumentCaptor<String> argument1 = ArgumentCaptor.forClass( String.class );
+ doNothing().when( encoder ).consoleInfoLog( anyString() );
+ ForkingRunListener forkingRunListener = new ForkingRunListener( encoder, true );
forkingRunListener.info( new String( new byte[]{ (byte) 'A' } ) );
forkingRunListener.info( new String( new byte[]{ } ) );
+ verify( encoder, times( 2 ) ).consoleInfoLog( argument1.capture() );
+ assertThat( argument1.getAllValues() )
+ .hasSize( 2 )
+ .containsSequence( "A", "" );
+ verifyNoMoreInteractions( encoder );
}
}
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/MasterProcessCommandTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/booter/MasterProcessCommandTest.java
deleted file mode 100644
index cfd4d5f..0000000
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/MasterProcessCommandTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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 junit.framework.TestCase;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-
-import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.resolve;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.setCommandAndDataLength;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.BYE_ACK;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.NOOP;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.RUN_CLASS;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-
-/**
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
- */
-public class MasterProcessCommandTest
- extends TestCase
-{
- @Rule
- public final ExpectedException exception = ExpectedException.none();
-
- public void testEncodedStreamSequence()
- {
- byte[] streamSequence = new byte[10];
- streamSequence[8] = (byte) 'T';
- streamSequence[9] = (byte) 'e';
- setCommandAndDataLength( 256, 2, streamSequence );
- assertEquals( streamSequence[0], (byte) 0 );
- assertEquals( streamSequence[1], (byte) 0 );
- assertEquals( streamSequence[2], (byte) 1 );
- assertEquals( streamSequence[3], (byte) 0 );
- assertEquals( streamSequence[4], (byte) 0 );
- assertEquals( streamSequence[5], (byte) 0 );
- assertEquals( streamSequence[6], (byte) 0 );
- assertEquals( streamSequence[7], (byte) 2 );
- // remain unchanged
- assertEquals( streamSequence[8], (byte) 'T' );
- assertEquals( streamSequence[9], (byte) 'e' );
- }
-
- public void testResolved()
- {
- for ( MasterProcessCommand command : MasterProcessCommand.values() )
- {
- assertThat( command, is( resolve( command.getId() ) ) );
- }
- }
-
- public void testDataToByteArrayAndBack()
- {
- String dummyData = "pkg.Test";
- for ( MasterProcessCommand command : MasterProcessCommand.values() )
- {
- switch ( command )
- {
- case RUN_CLASS:
- assertEquals( String.class, command.getDataType() );
- byte[] encoded = command.fromDataType( dummyData );
- assertThat( encoded.length, is( 8 ) );
- assertThat( encoded[0], is( (byte) 'p' ) );
- assertThat( encoded[1], is( (byte) 'k' ) );
- assertThat( encoded[2], is( (byte) 'g' ) );
- assertThat( encoded[3], is( (byte) '.' ) );
- assertThat( encoded[4], is( (byte) 'T' ) );
- assertThat( encoded[5], is( (byte) 'e' ) );
- assertThat( encoded[6], is( (byte) 's' ) );
- assertThat( encoded[7], is( (byte) 't' ) );
- String decoded = command.toDataTypeAsString( encoded );
- assertThat( decoded, is( dummyData ) );
- break;
- case TEST_SET_FINISHED:
- case SKIP_SINCE_NEXT_TEST:
- case NOOP:
- case BYE_ACK:
- assertEquals( Void.class, command.getDataType() );
- encoded = command.fromDataType( dummyData );
- assertThat( encoded.length, is( 0 ) );
- decoded = command.toDataTypeAsString( encoded );
- assertNull( decoded );
- break;
- case SHUTDOWN:
- assertEquals( String.class, command.getDataType() );
- encoded = command.fromDataType( Shutdown.EXIT.name() );
- assertThat( encoded.length, is( 4 ) );
- decoded = command.toDataTypeAsString( encoded );
- assertThat( decoded, is( Shutdown.EXIT.name() ) );
- break;
- default:
- fail();
- }
- assertThat( command, is( resolve( command.getId() ) ) );
- }
- }
-
- public void testEncodedDecodedIsSameForRunClass()
- throws IOException
- {
- byte[] encoded = RUN_CLASS.encode( "pkg.Test" );
- assertThat( encoded.length, is( 16 ) );
- assertThat( encoded[0], is( (byte) 0 ) );
- assertThat( encoded[1], is( (byte) 0 ) );
- assertThat( encoded[2], is( (byte) 0 ) );
- assertThat( encoded[3], is( (byte) 0 ) );
- assertThat( encoded[4], is( (byte) 0 ) );
- assertThat( encoded[5], is( (byte) 0 ) );
- assertThat( encoded[6], is( (byte) 0 ) );
- assertThat( encoded[7], is( (byte) 8 ) );
- assertThat( encoded[8], is( (byte) 'p' ) );
- assertThat( encoded[9], is( (byte) 'k' ) );
- assertThat( encoded[10], is( (byte) 'g' ) );
- assertThat( encoded[11], is( (byte) '.' ) );
- assertThat( encoded[12], is( (byte) 'T' ) );
- assertThat( encoded[13], is( (byte) 'e' ) );
- assertThat( encoded[14], is( (byte) 's' ) );
- assertThat( encoded[15], is( (byte) 't' ) );
- Command command = decode( new DataInputStream( new ByteArrayInputStream( encoded ) ) );
- assertNotNull( command );
- assertThat( command.getCommandType(), is( RUN_CLASS ) );
- assertThat( command.getData(), is( "pkg.Test" ) );
- }
-
- public void testShouldDecodeTwoCommands() throws IOException
- {
- byte[] cmd1 = BYE_ACK.encode();
- byte[] cmd2 = NOOP.encode();
- byte[] stream = new byte[cmd1.length + cmd2.length];
- System.arraycopy( cmd1, 0, stream, 0, cmd1.length );
- System.arraycopy( cmd2, 0, stream, cmd1.length, cmd2.length );
- DataInputStream is = new DataInputStream( new ByteArrayInputStream( stream ) );
- Command bye = decode( is );
- assertNotNull( bye );
- assertThat( bye.getCommandType(), is( BYE_ACK ) );
- Command noop = decode( is );
- assertNotNull( noop );
- assertThat( noop.getCommandType(), is( NOOP ) );
- }
-}
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
deleted file mode 100644
index 0a006bf..0000000
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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 junit.framework.TestCase;
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
-import org.apache.maven.surefire.report.ReporterConfiguration;
-import org.apache.maven.surefire.report.ReporterFactory;
-import org.apache.maven.surefire.report.RunListener;
-import org.apache.maven.surefire.suite.RunResult;
-import org.apache.maven.surefire.testset.DirectoryScannerParameters;
-import org.apache.maven.surefire.testset.RunOrderParameters;
-import org.apache.maven.surefire.testset.TestArtifactInfo;
-import org.apache.maven.surefire.testset.TestListResolver;
-import org.apache.maven.surefire.testset.TestRequest;
-import org.apache.maven.surefire.util.RunOrder;
-import org.mockito.ArgumentCaptor;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- *
- */
-public class SurefireReflectorTest
- extends TestCase
-{
- public void testCreateConsoleLogger()
- {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- ConsoleLogger consoleLogger = mock( ConsoleLogger.class );
- ConsoleLogger decorator = (ConsoleLogger) SurefireReflector.createConsoleLogger( consoleLogger, cl );
- assertThat( decorator )
- .isNotSameAs( consoleLogger );
-
- assertThat( decorator.isDebugEnabled() ).isFalse();
- when( consoleLogger.isDebugEnabled() ).thenReturn( true );
- assertThat( decorator.isDebugEnabled() ).isTrue();
- verify( consoleLogger, times( 2 ) ).isDebugEnabled();
-
- decorator.info( "msg" );
- ArgumentCaptor<String> argumentMsg = ArgumentCaptor.forClass( String.class );
- verify( consoleLogger, times( 1 ) ).info( argumentMsg.capture() );
- assertThat( argumentMsg.getAllValues() ).hasSize( 1 );
- assertThat( argumentMsg.getAllValues().get( 0 ) ).isEqualTo( "msg" );
- }
-
- public void testShouldCreateFactoryWithoutException()
- {
- ReporterFactory factory = new ReporterFactory()
- {
- @Override
- public RunListener createReporter()
- {
- return null;
- }
-
- @Override
- public RunResult close()
- {
- return null;
- }
- };
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- SurefireReflector reflector = new SurefireReflector( cl );
- BaseProviderFactory baseProviderFactory =
- (BaseProviderFactory) reflector.createBooterConfiguration( cl, factory, true );
- assertNotNull( baseProviderFactory.getReporterFactory() );
- assertSame( factory, baseProviderFactory.getReporterFactory() );
- }
-
- public void testSetDirectoryScannerParameters()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- DirectoryScannerParameters directoryScannerParameters =
- new DirectoryScannerParameters( new File( "ABC" ), new ArrayList<String>(), new ArrayList<String>(),
- new ArrayList<String>(), false, "hourly" );
- surefireReflector.setDirectoryScannerParameters( foo, directoryScannerParameters );
- assertTrue( isCalled( foo ) );
- }
-
- public void testRunOrderParameters()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- RunOrderParameters runOrderParameters = new RunOrderParameters( RunOrder.DEFAULT, new File( "." ) );
- surefireReflector.setRunOrderParameters( foo, runOrderParameters );
- assertTrue( isCalled( foo ) );
- }
-
- public void testTestSuiteDefinition()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- TestRequest testSuiteDefinition =
- new TestRequest( Arrays.asList( new File( "file1" ), new File( "file2" ) ),
- new File( "TestSOurce" ), new TestListResolver( "aUserRequestedTest#aMethodRequested" ) );
- surefireReflector.setTestSuiteDefinition( foo, testSuiteDefinition );
- assertTrue( isCalled( foo ) );
- }
-
- public void testProviderProperties()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- surefireReflector.setProviderProperties( foo, new HashMap<String, String>() );
- assertTrue( isCalled( foo ) );
- }
-
- public void testReporterConfiguration()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- ReporterConfiguration reporterConfiguration = getReporterConfiguration();
- surefireReflector.setReporterConfigurationAware( foo, reporterConfiguration );
- assertTrue( isCalled( foo ) );
- }
-
- private ReporterConfiguration getReporterConfiguration()
- {
- return new ReporterConfiguration( new File( "CDE" ), true );
- }
-
- public void testTestClassLoaderAware()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- surefireReflector.setTestClassLoader( foo, getClass().getClassLoader() );
- assertTrue( isCalled( foo ) );
- }
-
- public void testArtifactInfoAware()
- {
- SurefireReflector surefireReflector = getReflector();
- Object foo = getFoo();
-
- TestArtifactInfo testArtifactInfo = new TestArtifactInfo( "12.3", "test" );
- surefireReflector.setTestArtifactInfo( foo, testArtifactInfo );
- assertTrue( isCalled( foo ) );
- }
-
- private SurefireReflector getReflector()
- {
- return new SurefireReflector( this.getClass().getClassLoader() );
- }
-
- private Object getFoo()
- { // Todo: Setup a different classloader so we can really test crossing
- return new Foo();
- }
-
- private Boolean isCalled( Object foo )
- {
- final Method isCalled;
- try
- {
- isCalled = foo.getClass().getMethod( "isCalled" );
- return (Boolean) isCalled.invoke( foo );
- }
- catch ( ReflectiveOperationException e )
- {
- throw new RuntimeException( e );
- }
- }
-}
diff --git a/surefire-booter/pom.xml b/surefire-booter/pom.xml
index 1fa5045..a0dbd9a 100644
--- a/surefire-booter/pom.xml
+++ b/surefire-booter/pom.xml
@@ -38,6 +38,16 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-extensions-spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-shared-utils</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
@@ -73,22 +83,35 @@
<build>
<plugins>
<plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
+ <artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
- <id>jacoco-instrumentation</id>
+ <id>build-test-classpath</id>
+ <phase>generate-sources</phase>
<goals>
- <goal>instrument</goal>
+ <goal>build-classpath</goal>
</goals>
+ <configuration>
+ <includeScope>test</includeScope>
+ <outputFile>target/test-classpath/cp.txt</outputFile>
+ </configuration>
</execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <executions>
<execution>
- <id>restore-classes</id>
+ <id>jacoco-agent</id>
<goals>
- <goal>restore-instrumented-classes</goal>
+ <goal>prepare-agent</goal>
</goals>
</execution>
</executions>
+ <configuration>
+ <propertyName>jacoco.agent</propertyName>
+ </configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
@@ -100,7 +123,7 @@
</dependency>
</dependencies>
<configuration>
- <argLine>${jvm.args.tests}</argLine>
+ <argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
<includes>
<include>**/JUnit4SuiteTest.java</include>
</includes>
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
index fc570f0..fa664be 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterConstants.java
@@ -58,4 +58,5 @@ public final class BooterConstants
public static final String SYSTEM_EXIT_TIMEOUT = "systemExitTimeout";
public static final String PLUGIN_PID = "pluginPid";
public static final String PROCESS_CHECKER = "processChecker";
+ public static final String FORK_NODE_CONNECTION_STRING = "forkNodeConnectionString";
}
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
index b091679..9c8a9ed 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/BooterDeserializer.java
@@ -32,6 +32,8 @@ import org.apache.maven.surefire.testset.TestListResolver;
import org.apache.maven.surefire.testset.TestRequest;
// CHECKSTYLE_OFF: imports
+import javax.annotation.Nonnull;
+
import static org.apache.maven.surefire.booter.BooterConstants.*;
import static org.apache.maven.surefire.cli.CommandLineOption.*;
@@ -59,6 +61,18 @@ public class BooterDeserializer
}
/**
+ * Describes the current connection channel used by the client in the forked JVM
+ * in order to connect to the plugin process.
+ *
+ * @return connection string (must not be null)
+ */
+ @Nonnull
+ public String getConnectionString()
+ {
+ return properties.getProperty( FORK_NODE_CONNECTION_STRING );
+ }
+
+ /**
* @return PID of Maven process where plugin is executed; or null if PID could not be determined.
*/
public String getPluginPid()
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
similarity index 81%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
rename to surefire-booter/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
index b51f713..4b43fb2 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
@@ -20,10 +20,14 @@ package org.apache.maven.surefire.booter;
*/
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
-import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
+import org.apache.maven.surefire.booter.spi.MasterProcessCommandNoMagicNumberException;
+import org.apache.maven.surefire.booter.spi.MasterProcessUnknownCommandException;
+import org.apache.maven.surefire.providerapi.CommandChainReader;
+import org.apache.maven.surefire.providerapi.CommandListener;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.testset.TestSetFailedException;
-import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Iterator;
@@ -47,7 +51,6 @@ import static org.apache.maven.surefire.booter.MasterProcessCommand.RUN_CLASS;
import static org.apache.maven.surefire.booter.MasterProcessCommand.SHUTDOWN;
import static org.apache.maven.surefire.booter.MasterProcessCommand.SKIP_SINCE_NEXT_TEST;
import static org.apache.maven.surefire.booter.MasterProcessCommand.TEST_SET_FINISHED;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDaemonThread;
import static org.apache.maven.surefire.shared.utils.StringUtils.isBlank;
import static org.apache.maven.surefire.shared.utils.StringUtils.isNotBlank;
@@ -58,12 +61,10 @@ import static org.apache.maven.surefire.shared.utils.StringUtils.isNotBlank;
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 2.19
*/
-public final class CommandReader
+public final class CommandReader implements CommandChainReader
{
private static final String LAST_TEST_SYMBOL = "";
- private static final CommandReader READER = new CommandReader();
-
private final Queue<BiProperty<MasterProcessCommand, CommandListener>> listeners = new ConcurrentLinkedQueue<>();
private final Thread commandThread = newDaemonThread( new CommandRunnable(), "surefire-forkedjvm-command-thread" );
@@ -76,38 +77,24 @@ public final class CommandReader
private final CopyOnWriteArrayList<String> testClasses = new CopyOnWriteArrayList<>();
- private volatile Shutdown shutdown;
-
- private int iteratedCount;
-
- private volatile ConsoleLogger logger = new NullConsoleLogger();
+ private final MasterProcessChannelDecoder decoder;
- private CommandReader()
- {
- }
+ private final Shutdown shutdown;
- public static CommandReader getReader()
- {
- final CommandReader reader = READER;
- if ( reader.state.compareAndSet( NEW, RUNNABLE ) )
- {
- reader.commandThread.start();
- }
- return reader;
- }
+ private final ConsoleLogger logger;
- public CommandReader setShutdown( Shutdown shutdown )
- {
- this.shutdown = shutdown;
- return this;
- }
+ private int iteratedCount;
- public CommandReader setLogger( ConsoleLogger logger )
+ public CommandReader( MasterProcessChannelDecoder decoder, Shutdown shutdown, ConsoleLogger logger )
{
+ this.decoder = requireNonNull( decoder, "null decoder" );
+ this.shutdown = requireNonNull( shutdown, "null Shutdown config" );
this.logger = requireNonNull( logger, "null logger" );
- return this;
+ state.set( RUNNABLE );
+ commandThread.start();
}
+ @Override
public boolean awaitStarted()
throws TestSetFailedException
{
@@ -143,11 +130,13 @@ public final class CommandReader
addListener( RUN_CLASS, listener );
}
+ @Override
public void addTestsFinishedListener( CommandListener listener )
{
addListener( TEST_SET_FINISHED, listener );
}
+ @Override
public void addSkipNextTestsListener( CommandListener listener )
{
addListener( SKIP_SINCE_NEXT_TEST, listener );
@@ -173,6 +162,7 @@ public final class CommandReader
listeners.add( new BiProperty<>( cmd, listener ) );
}
+ @Override
public void removeListener( CommandListener listener )
{
for ( Iterator<BiProperty<MasterProcessCommand, CommandListener>> it = listeners.iterator(); it.hasNext(); )
@@ -186,7 +176,8 @@ public final class CommandReader
}
/**
- * @return test classes which have been retrieved by {@link CommandReader#getIterableClasses(ForkedChannelEncoder)}.
+ * @return test classes which have been retrieved by
+ * {@link CommandReader#getIterableClasses(MasterProcessChannelEncoder)}.
*/
Iterator<String> iterated()
{
@@ -200,7 +191,7 @@ public final class CommandReader
* @param eventChannel original stream in current JVM process
* @return Iterator with test classes lazily loaded as commands from the main process
*/
- Iterable<String> getIterableClasses( ForkedChannelEncoder eventChannel )
+ Iterable<String> getIterableClasses( MasterProcessChannelEncoder eventChannel )
{
return new ClassesIterable( eventChannel );
}
@@ -251,9 +242,9 @@ public final class CommandReader
private final class ClassesIterable
implements Iterable<String>
{
- private final ForkedChannelEncoder eventChannel;
+ private final MasterProcessChannelEncoder eventChannel;
- ClassesIterable( ForkedChannelEncoder eventChannel )
+ ClassesIterable( MasterProcessChannelEncoder eventChannel )
{
this.eventChannel = eventChannel;
}
@@ -268,13 +259,13 @@ public final class CommandReader
private final class ClassesIterator
implements Iterator<String>
{
- private final ForkedChannelEncoder eventChannel;
+ private final MasterProcessChannelEncoder eventChannel;
private String clazz;
private int nextQueueIndex;
- private ClassesIterator( ForkedChannelEncoder eventChannel )
+ private ClassesIterator( MasterProcessChannelEncoder eventChannel )
{
this.eventChannel = eventChannel;
}
@@ -374,54 +365,43 @@ public final class CommandReader
public void run()
{
CommandReader.this.startMonitor.countDown();
- DataInputStream stdIn = new DataInputStream( System.in );
boolean isTestSetFinished = false;
try
{
while ( CommandReader.this.state.get() == RUNNABLE )
{
- Command command = decode( stdIn );
- if ( command == null )
- {
- String errorMessage = "[SUREFIRE] std/in stream corrupted: first sequence not recognized";
- DumpErrorSingleton.getSingleton().dumpStreamText( errorMessage );
- logger.error( errorMessage );
- break;
- }
- else
+ Command command = CommandReader.this.decoder.decode();
+ switch ( command.getCommandType() )
{
- switch ( command.getCommandType() )
- {
- case RUN_CLASS:
- String test = command.getData();
- boolean inserted = CommandReader.this.insertToQueue( test );
- if ( inserted )
- {
- CommandReader.this.wakeupIterator();
- callListeners( command );
- }
- break;
- case TEST_SET_FINISHED:
- CommandReader.this.makeQueueFull();
- isTestSetFinished = true;
- CommandReader.this.wakeupIterator();
- callListeners( command );
- break;
- case SHUTDOWN:
- CommandReader.this.makeQueueFull();
+ case RUN_CLASS:
+ String test = command.getData();
+ boolean inserted = CommandReader.this.insertToQueue( test );
+ if ( inserted )
+ {
CommandReader.this.wakeupIterator();
callListeners( command );
+ }
+ break;
+ case TEST_SET_FINISHED:
+ CommandReader.this.makeQueueFull();
+ isTestSetFinished = true;
+ CommandReader.this.wakeupIterator();
+ callListeners( command );
+ break;
+ case SHUTDOWN:
+ CommandReader.this.makeQueueFull();
+ CommandReader.this.wakeupIterator();
+ callListeners( command );
break;
case BYE_ACK:
callListeners( command );
- // After SHUTDOWN no more commands can come.
+ // After SHUTDOWN no more commands can come.
// Hence, do NOT go back to blocking in I/O.
CommandReader.this.state.set( TERMINATED );
break;
- default:
- callListeners( command );
- break;
- }
+ default:
+ callListeners( command );
+ break;
}
}
}
@@ -439,6 +419,11 @@ public final class CommandReader
// does not go to finally for non-default config: Shutdown.EXIT or Shutdown.KILL
}
}
+ catch ( MasterProcessCommandNoMagicNumberException | MasterProcessUnknownCommandException e )
+ {
+ DumpErrorSingleton.getSingleton().dumpStreamException( e );
+ CommandReader.this.logger.error( e );
+ }
catch ( IOException e )
{
CommandReader.this.state.set( TERMINATED );
@@ -447,7 +432,7 @@ public final class CommandReader
{
String msg = "[SUREFIRE] std/in stream corrupted";
DumpErrorSingleton.getSingleton().dumpStreamException( e, msg );
- logger.error( msg, e );
+ CommandReader.this.logger.error( msg, e );
}
}
finally
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
index 2701221..34b752e 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
@@ -20,9 +20,16 @@ package org.apache.maven.surefire.booter;
*/
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelProcessorFactory;
+import org.apache.maven.surefire.booter.spi.SurefireMasterProcessChannelProcessorFactory;
+import org.apache.maven.surefire.providerapi.CommandListener;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.providerapi.ProviderParameters;
import org.apache.maven.surefire.providerapi.SurefireProvider;
import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
+import org.apache.maven.surefire.report.StackTraceWriter;
+import org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory;
import org.apache.maven.surefire.testset.TestSetFailedException;
import java.io.File;
@@ -45,6 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import static java.lang.Math.max;
import static java.lang.Thread.currentThread;
+import static java.util.ServiceLoader.load;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.maven.surefire.booter.ProcessCheckerType.ALL;
@@ -73,10 +81,11 @@ public final class ForkedBooter
private static final String LAST_DITCH_SHUTDOWN_THREAD = "surefire-forkedjvm-last-ditch-daemon-shutdown-thread-";
private static final String PING_THREAD = "surefire-forkedjvm-ping-";
- private final CommandReader commandReader = CommandReader.getReader();
- private final ForkedChannelEncoder eventChannel = new ForkedChannelEncoder( System.out );
private final Semaphore exitBarrier = new Semaphore( 0 );
+ private volatile MasterProcessChannelEncoder eventChannel;
+ private volatile MasterProcessChannelProcessorFactory channelProcessorFactory;
+ private volatile CommandReader commandReader;
private volatile long systemExitTimeoutInSeconds = DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS;
private volatile PingScheduler pingScheduler;
@@ -106,9 +115,16 @@ public final class ForkedBooter
startupConfiguration = booterDeserializer.getStartupConfiguration();
- forkingReporterFactory = createForkingReporterFactory();
+ String channelConfig = booterDeserializer.getConnectionString();
+ channelProcessorFactory = lookupDecoderFactory( channelConfig );
+ channelProcessorFactory.connect( channelConfig );
+ eventChannel = channelProcessorFactory.createEncoder();
+ MasterProcessChannelDecoder decoder = channelProcessorFactory.createDecoder();
+ forkingReporterFactory = createForkingReporterFactory();
ConsoleLogger logger = (ConsoleLogger) forkingReporterFactory.createReporter();
+ commandReader = new CommandReader( decoder, providerConfiguration.getShutdown(), logger );
+
pingScheduler = isDebugging() ? null : listenToShutdownCommands( booterDeserializer.getPluginPid(), logger );
systemExitTimeoutInSeconds = providerConfiguration.systemExitTimeout( DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS );
@@ -162,7 +178,7 @@ public final class ForkedBooter
}
else if ( readTestsFromCommandReader )
{
- return new LazyTestsToRun( eventChannel );
+ return new LazyTestsToRun( eventChannel, commandReader );
}
return null;
}
@@ -191,6 +207,21 @@ public final class ForkedBooter
}
}
+ private void closeForkChannel()
+ {
+ if ( channelProcessorFactory != null )
+ {
+ try
+ {
+ channelProcessorFactory.close();
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
private PingScheduler listenToShutdownCommands( String ppid, ConsoleLogger logger )
{
PpidChecker ppidChecker = ppid == null ? null : new PpidChecker( ppid );
@@ -339,6 +370,7 @@ public final class ForkedBooter
private void kill( int returnCode )
{
commandReader.stop();
+ closeForkChannel();
Runtime.getRuntime().halt( returnCode );
}
@@ -365,6 +397,7 @@ public final class ForkedBooter
acquireOnePermit( exitBarrier, timeoutMillis );
cancelPingScheduler();
commandReader.stop();
+ closeForkChannel();
System.exit( 0 );
}
@@ -418,7 +451,9 @@ public final class ForkedBooter
private SurefireProvider createProviderInCurrentClassloader( ForkingReporterFactory reporterManagerFactory )
{
- BaseProviderFactory bpf = new BaseProviderFactory( reporterManagerFactory, true );
+ BaseProviderFactory bpf = new BaseProviderFactory( true );
+ bpf.setReporterFactory( reporterManagerFactory );
+ bpf.setCommandReader( commandReader );
bpf.setTestRequest( providerConfiguration.getTestSuiteDefinition() );
bpf.setReporterConfiguration( providerConfiguration.getReporterConfiguration() );
bpf.setForkedChannelEncoder( eventChannel );
@@ -430,12 +465,38 @@ public final class ForkedBooter
bpf.setDirectoryScannerParameters( providerConfiguration.getDirScannerParams() );
bpf.setMainCliOptions( providerConfiguration.getMainCliOptions() );
bpf.setSkipAfterFailureCount( providerConfiguration.getSkipAfterFailureCount() );
- bpf.setShutdown( providerConfiguration.getShutdown() );
bpf.setSystemExitTimeout( providerConfiguration.getSystemExitTimeout() );
String providerClass = startupConfiguration.getActualClassName();
return (SurefireProvider) instantiateOneArg( classLoader, providerClass, ProviderParameters.class, bpf );
}
+ private static MasterProcessChannelProcessorFactory lookupDecoderFactory( String channelConfig )
+ {
+ MasterProcessChannelProcessorFactory defaultFactory = null;
+ MasterProcessChannelProcessorFactory customFactory = null;
+ for ( MasterProcessChannelProcessorFactory factory : load( MasterProcessChannelProcessorFactory.class ) )
+ {
+ Class<?> cls = factory.getClass();
+
+ boolean isSurefireFactory =
+ cls == LegacyMasterProcessChannelProcessorFactory.class
+ || cls == SurefireMasterProcessChannelProcessorFactory.class;
+
+ if ( isSurefireFactory )
+ {
+ if ( factory.canUse( channelConfig ) )
+ {
+ defaultFactory = factory;
+ }
+ }
+ else
+ {
+ customFactory = factory;
+ }
+ }
+ return customFactory != null ? customFactory : defaultFactory;
+ }
+
/**
* This method is invoked when Surefire is forked - this method parses and organizes the arguments passed to it and
* then calls the Surefire class' run method. <br> The system exit code will be 1 if an exception is thrown.
@@ -465,6 +526,11 @@ public final class ForkedBooter
{
DumpErrorSingleton.getSingleton().dumpException( t );
t.printStackTrace();
+ if ( booter.eventChannel != null )
+ {
+ StackTraceWriter stack = new LegacyPojoStackTraceWriter( "test subsystem", "no method", t );
+ booter.eventChannel.consoleErrorLog( stack, false );
+ }
booter.cancelPingScheduler();
booter.exit1();
}
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
index 9d0b2e0..568a2c5 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
@@ -22,10 +22,10 @@ package org.apache.maven.surefire.booter;
import java.util.Collections;
import java.util.Iterator;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.util.CloseableIterator;
import org.apache.maven.surefire.util.TestsToRun;
-import static org.apache.maven.surefire.booter.CommandReader.getReader;
import static org.apache.maven.surefire.util.ReflectionUtils.loadClass;
/**
@@ -43,24 +43,25 @@ import static org.apache.maven.surefire.util.ReflectionUtils.loadClass;
final class LazyTestsToRun
extends TestsToRun
{
- private final ForkedChannelEncoder eventChannel;
+ private final MasterProcessChannelEncoder eventChannel;
+ private final CommandReader commandReader;
/**
* C'tor
*
* @param eventChannel the output stream to use when requesting new new tests
*/
- LazyTestsToRun( ForkedChannelEncoder eventChannel )
+ LazyTestsToRun( MasterProcessChannelEncoder eventChannel, CommandReader commandReader )
{
super( Collections.<Class<?>>emptySet() );
-
this.eventChannel = eventChannel;
+ this.commandReader = commandReader;
}
private final class BlockingIterator
implements Iterator<Class<?>>
{
- private final Iterator<String> it = getReader().getIterableClasses( eventChannel ).iterator();
+ private final Iterator<String> it = commandReader.getIterableClasses( eventChannel ).iterator();
@Override
public boolean hasNext()
@@ -132,7 +133,7 @@ final class LazyTestsToRun
*/
private Iterator<Class<?>> newWeakIterator()
{
- final Iterator<String> it = getReader().iterated();
+ final Iterator<String> it = commandReader.iterated();
return new CloseableIterator<Class<?>>()
{
@Override
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
index c7379e4..caa26d2 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderConfiguration.java
@@ -96,7 +96,6 @@ public class ProviderConfiguration
return reporterConfiguration;
}
-
public boolean isFailIfNoTests()
{
return failIfNoTests;
@@ -107,7 +106,6 @@ public class ProviderConfiguration
return dirScannerParams.getTestClassesDirectory();
}
-
public DirectoryScannerParameters getDirScannerParams()
{
return dirScannerParams;
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
index 41badfd..614ff92 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
@@ -99,7 +99,8 @@ public class ProviderFactory
final ClassLoader systemClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader( classLoader );
// Note: Duplicated in ForkedBooter#createProviderInCurrentClassloader
- Object o = surefireReflector.createBooterConfiguration( classLoader, reporterManagerFactory, isInsideFork );
+ Object o = surefireReflector.createBooterConfiguration( classLoader, isInsideFork );
+ surefireReflector.setReporterFactoryAware( o, reporterManagerFactory );
surefireReflector.setTestSuiteDefinitionAware( o, providerConfiguration.getTestSuiteDefinition() );
surefireReflector.setProviderPropertiesAware( o, providerConfiguration.getProviderProperties() );
surefireReflector.setReporterConfigurationAware( o, providerConfiguration.getReporterConfiguration() );
@@ -109,7 +110,6 @@ public class ProviderFactory
surefireReflector.setIfDirScannerAware( o, providerConfiguration.getDirScannerParams() );
surefireReflector.setMainCliOptions( o, providerConfiguration.getMainCliOptions() );
surefireReflector.setSkipAfterFailureCount( o, providerConfiguration.getSkipAfterFailureCount() );
- surefireReflector.setShutdown( o, providerConfiguration.getShutdown() );
if ( isInsideFork )
{
surefireReflector.setSystemExitTimeout( o, providerConfiguration.getSystemExitTimeout() );
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java
index 0bbe988..d6a3dd0 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java
@@ -33,20 +33,16 @@ public class StartupConfiguration
private final String providerClassName;
private final AbstractPathConfiguration classpathConfiguration;
private final ClassLoaderConfiguration classLoaderConfiguration;
- private final boolean isForkRequested;
- private final boolean isInForkedVm;
private final ProcessCheckerType processChecker;
public StartupConfiguration( @Nonnull String providerClassName,
@Nonnull AbstractPathConfiguration classpathConfiguration,
- @Nonnull ClassLoaderConfiguration classLoaderConfiguration, boolean isForkRequested,
- boolean inForkedVm, ProcessCheckerType processChecker )
+ @Nonnull ClassLoaderConfiguration classLoaderConfiguration,
+ ProcessCheckerType processChecker )
{
this.classpathConfiguration = classpathConfiguration;
this.classLoaderConfiguration = classLoaderConfiguration;
- this.isForkRequested = isForkRequested;
this.providerClassName = providerClassName;
- isInForkedVm = inForkedVm;
this.processChecker = processChecker;
}
@@ -56,12 +52,11 @@ public class StartupConfiguration
}
public static StartupConfiguration inForkedVm( String providerClassName,
- ClasspathConfiguration classpathConfiguration,
- ClassLoaderConfiguration classLoaderConfiguration,
+ ClasspathConfiguration classpathConfig,
+ ClassLoaderConfiguration classLoaderConfig,
ProcessCheckerType processChecker )
{
- return new StartupConfiguration( providerClassName, classpathConfiguration, classLoaderConfiguration, true,
- true, processChecker );
+ return new StartupConfiguration( providerClassName, classpathConfig, classLoaderConfig, processChecker );
}
public AbstractPathConfiguration getClasspathConfiguration()
@@ -69,13 +64,6 @@ public class StartupConfiguration
return classpathConfiguration;
}
- @Deprecated
- public boolean useSystemClassLoader()
- {
- // todo; I am not totally convinced this logic is as simple as it could be
- return classLoaderConfiguration.isUseSystemClassLoader() && ( isInForkedVm || isForkRequested );
- }
-
public boolean isManifestOnlyJarRequestedAndUsable()
{
return classLoaderConfiguration.isManifestOnlyJarRequestedAndUsable();
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
similarity index 74%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
rename to surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
index 5cc1415..140cf0e 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireReflector.java
@@ -19,8 +19,6 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
-import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
import org.apache.maven.surefire.cli.CommandLineOption;
import org.apache.maven.surefire.providerapi.ProviderParameters;
import org.apache.maven.surefire.report.ReporterConfiguration;
@@ -46,7 +44,6 @@ import static java.util.Collections.checkedList;
import static org.apache.maven.surefire.util.ReflectionUtils.getConstructor;
import static org.apache.maven.surefire.util.ReflectionUtils.getMethod;
import static org.apache.maven.surefire.util.ReflectionUtils.instantiateOneArg;
-import static org.apache.maven.surefire.util.ReflectionUtils.instantiateTwoArgs;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeGetter;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeSetter;
@@ -59,7 +56,7 @@ import static org.apache.maven.surefire.util.ReflectionUtils.newInstance;
*
* @author Kristian Rosenvold
*/
-public class SurefireReflector
+public final class SurefireReflector
{
private final ClassLoader surefireClassLoader;
@@ -69,21 +66,11 @@ public class SurefireReflector
private final Class<?> testArtifactInfo;
- private final Class<?> testArtifactInfoAware;
-
private final Class<?> directoryScannerParameters;
private final Class<?> runOrderParameters;
- private final Class<?> directoryScannerParametersAware;
-
- private final Class<?> testSuiteDefinitionAware;
-
- private final Class<?> testClassLoaderAware;
-
- private final Class<?> reporterConfigurationAware;
-
- private final Class<?> providerPropertiesAware;
+ private final Class<?> baseProviderFactory;
private final Class<?> runResult;
@@ -93,13 +80,7 @@ public class SurefireReflector
private final Class<?> testListResolver;
- private final Class<?> mainCliOptions;
-
- private final Class<Enum> commandLineOptionsClass;
-
- private final Class<?> shutdownAwareClass;
-
- private final Class<Enum> shutdownClass;
+ private final Class<Enum<?>> commandLineOptionsClass;
@SuppressWarnings( "unchecked" )
public SurefireReflector( ClassLoader surefireClassLoader )
@@ -110,23 +91,15 @@ public class SurefireReflector
reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() );
testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() );
testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() );
- testArtifactInfoAware = surefireClassLoader.loadClass( TestArtifactInfoAware.class.getName() );
directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() );
runOrderParameters = surefireClassLoader.loadClass( RunOrderParameters.class.getName() );
- directoryScannerParametersAware =
- surefireClassLoader.loadClass( DirectoryScannerParametersAware.class.getName() );
- testSuiteDefinitionAware = surefireClassLoader.loadClass( TestRequestAware.class.getName() );
- testClassLoaderAware = surefireClassLoader.loadClass( SurefireClassLoadersAware.class.getName() );
- reporterConfigurationAware = surefireClassLoader.loadClass( ReporterConfigurationAware.class.getName() );
- providerPropertiesAware = surefireClassLoader.loadClass( ProviderPropertiesAware.class.getName() );
+ baseProviderFactory = surefireClassLoader.loadClass( BaseProviderFactory.class.getName() );
reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() );
runResult = surefireClassLoader.loadClass( RunResult.class.getName() );
booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() );
testListResolver = surefireClassLoader.loadClass( TestListResolver.class.getName() );
- mainCliOptions = surefireClassLoader.loadClass( MainCliOptionsAware.class.getName() );
- commandLineOptionsClass = (Class<Enum>) surefireClassLoader.loadClass( CommandLineOption.class.getName() );
- shutdownAwareClass = surefireClassLoader.loadClass( ShutdownAware.class.getName() );
- shutdownClass = (Class<Enum>) surefireClassLoader.loadClass( Shutdown.class.getName() );
+ commandLineOptionsClass =
+ (Class<Enum<?>>) surefireClassLoader.loadClass( CommandLineOption.class.getName() );
}
catch ( ClassNotFoundException e )
{
@@ -157,7 +130,7 @@ public class SurefireReflector
{
Object resolver = createTestListResolver( suiteDefinition.getTestListResolver() );
Class<?>[] arguments = { List.class, File.class, testListResolver, int.class };
- Constructor constructor = getConstructor( testRequest, arguments );
+ Constructor<?> constructor = getConstructor( testRequest, arguments );
return newInstance( constructor,
suiteDefinition.getSuiteXmlFiles(),
suiteDefinition.getTestSourceDirectory(),
@@ -174,7 +147,7 @@ public class SurefireReflector
}
else
{
- Constructor constructor = getConstructor( testListResolver, String.class );
+ Constructor<?> constructor = getConstructor( testListResolver, String.class );
return newInstance( constructor, resolver.getPluginParameterTest() );
}
}
@@ -187,7 +160,7 @@ public class SurefireReflector
}
//Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
Class<?>[] arguments = { File.class, List.class, List.class, List.class, boolean.class, String.class };
- Constructor constructor = getConstructor( this.directoryScannerParameters, arguments );
+ Constructor<?> constructor = getConstructor( this.directoryScannerParameters, arguments );
return newInstance( constructor,
directoryScannerParameters.getTestClassesDirectory(),
directoryScannerParameters.getIncludes(),
@@ -205,7 +178,7 @@ public class SurefireReflector
}
//Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
Class<?>[] arguments = { String.class, File.class };
- Constructor constructor = getConstructor( this.runOrderParameters, arguments );
+ Constructor<?> constructor = getConstructor( this.runOrderParameters, arguments );
File runStatisticsFile = runOrderParameters.getRunStatisticsFile();
return newInstance( constructor, RunOrder.asString( runOrderParameters.getRunOrder() ), runStatisticsFile );
}
@@ -217,21 +190,19 @@ public class SurefireReflector
return null;
}
Class<?>[] arguments = { String.class, String.class };
- Constructor constructor = getConstructor( this.testArtifactInfo, arguments );
+ Constructor<?> constructor = getConstructor( this.testArtifactInfo, arguments );
return newInstance( constructor, testArtifactInfo.getVersion(), testArtifactInfo.getClassifier() );
}
private Object createReporterConfiguration( ReporterConfiguration reporterConfig )
{
- Constructor constructor = getConstructor( reporterConfiguration, File.class, boolean.class );
+ Constructor<?> constructor = getConstructor( reporterConfiguration, File.class, boolean.class );
return newInstance( constructor, reporterConfig.getReportsDirectory(), reporterConfig.isTrimStackTrace() );
}
- public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance,
- boolean insideFork )
+ public Object createBooterConfiguration( ClassLoader surefireClassLoader, boolean insideFork )
{
- return instantiateTwoArgs( surefireClassLoader, BaseProviderFactory.class.getName(),
- reporterFactory, factoryInstance, boolean.class, insideFork );
+ return instantiateOneArg( surefireClassLoader, BaseProviderFactory.class.getName(), boolean.class, insideFork );
}
public Object instantiateProvider( String providerClassName, Object booterParameters )
@@ -241,7 +212,7 @@ public class SurefireReflector
public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
{
- if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setDirectoryScannerParameters( o, dirScannerParams );
}
@@ -249,11 +220,11 @@ public class SurefireReflector
public void setMainCliOptions( Object o, List<CommandLineOption> options )
{
- if ( mainCliOptions.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
- List<Enum> newOptions = checkedList( new ArrayList<Enum>( options.size() ), commandLineOptionsClass );
+ List<Enum<?>> newOptions = checkedList( new ArrayList<Enum<?>>( options.size() ), commandLineOptionsClass );
Collection<Integer> ordinals = toOrdinals( options );
- for ( Enum e : commandLineOptionsClass.getEnumConstants() )
+ for ( Enum<?> e : commandLineOptionsClass.getEnumConstants() )
{
if ( ordinals.contains( e.ordinal() ) )
{
@@ -269,21 +240,6 @@ public class SurefireReflector
invokeSetter( o, "setSkipAfterFailureCount", int.class, skipAfterFailureCount );
}
- public void setShutdown( Object o, Shutdown shutdown )
- {
- if ( shutdownAwareClass.isAssignableFrom( o.getClass() ) )
- {
- for ( Enum e : shutdownClass.getEnumConstants() )
- {
- if ( shutdown.ordinal() == e.ordinal() )
- {
- invokeSetter( o, "setShutdown", shutdownClass, e );
- break;
- }
- }
- }
- }
-
public void setSystemExitTimeout( Object o, Integer systemExitTimeout )
{
invokeSetter( o, "setSystemExitTimeout", Integer.class, systemExitTimeout );
@@ -303,7 +259,7 @@ public class SurefireReflector
public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
{
- if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setTestSuiteDefinition( o, testSuiteDefinition2 );
}
@@ -317,7 +273,7 @@ public class SurefireReflector
public void setProviderPropertiesAware( Object o, Map<String, String> properties )
{
- if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setProviderProperties( o, properties );
}
@@ -330,7 +286,7 @@ public class SurefireReflector
public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
{
- if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setReporterConfiguration( o, reporterConfiguration1 );
}
@@ -344,7 +300,7 @@ public class SurefireReflector
public void setTestClassLoaderAware( Object o, ClassLoader testClassLoader )
{
- if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setTestClassLoader( o, testClassLoader );
}
@@ -358,7 +314,7 @@ public class SurefireReflector
public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
{
- if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) )
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
{
setTestArtifactInfo( o, testArtifactInfo1 );
}
@@ -370,31 +326,31 @@ public class SurefireReflector
invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
}
+ public void setReporterFactoryAware( Object o, Object reporterFactory )
+ {
+ if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
+ {
+ setReporterFactory( o, reporterFactory );
+ }
+ }
+
+ void setReporterFactory( Object o, Object reporterFactory )
+ {
+ invokeSetter( o, "setReporterFactory", this.reporterFactory, reporterFactory );
+ }
+
private boolean isRunResult( Object o )
{
return runResult.isAssignableFrom( o.getClass() );
}
- private static Collection<Integer> toOrdinals( Collection<? extends Enum> enums )
+ private static Collection<Integer> toOrdinals( Collection<? extends Enum<?>> enums )
{
Collection<Integer> ordinals = new ArrayList<>( enums.size() );
- for ( Enum e : enums )
+ for ( Enum<?> e : enums )
{
ordinals.add( e.ordinal() );
}
return ordinals;
}
-
- public static Object createConsoleLogger( ConsoleLogger consoleLogger, ClassLoader cl )
- {
- try
- {
- Class<?> decoratorClass = cl.loadClass( ConsoleLoggerDecorator.class.getName() );
- return getConstructor( decoratorClass, Object.class ).newInstance( consoleLogger );
- }
- catch ( Exception e )
- {
- throw new SurefireReflectionException( e );
- }
- }
}
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoder.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoder.java
new file mode 100644
index 0000000..c22ee11
--- /dev/null
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoder.java
@@ -0,0 +1,166 @@
+package org.apache.maven.surefire.booter.spi;
+
+/*
+ * 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.providerapi.MasterProcessChannelDecoder;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * magic number : opcode [: opcode specific data]*
+ * <br>
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 3.0.0-M5
+ */
+public class LegacyMasterProcessChannelDecoder implements MasterProcessChannelDecoder
+{
+ private final InputStream is;
+
+ public LegacyMasterProcessChannelDecoder( InputStream is )
+ {
+ this.is = is;
+ }
+
+ protected boolean hasData( String opcode )
+ {
+ MasterProcessCommand cmd = MasterProcessCommand.byOpcode( opcode );
+ return cmd == null || cmd.hasDataType();
+ }
+
+ @SuppressWarnings( "checkstyle:innerassignment" )
+ @Override
+ public Command decode() throws IOException
+ {
+ List<String> tokens = new ArrayList<>();
+ StringBuilder frame = new StringBuilder();
+ boolean frameStarted = false;
+ boolean frameFinished = false;
+ boolean notEndOfStream;
+ for ( int r; notEndOfStream = ( r = is.read() ) != -1 ; )
+ {
+ char c = (char) r;
+ if ( frameFinished && c == '\n' )
+ {
+ continue;
+ }
+
+ if ( !frameStarted )
+ {
+ if ( c == ':' )
+ {
+ frameStarted = true;
+ frameFinished = false;
+ frame.setLength( 0 );
+ tokens.clear();
+ continue;
+ }
+ }
+ else if ( !frameFinished )
+ {
+ boolean isColon = c == ':';
+ if ( isColon || c == '\n' || c == '\r' )
+ {
+ tokens.add( frame.toString() );
+ frame.setLength( 0 );
+ }
+ else
+ {
+ frame.append( c );
+ }
+ boolean isFinishedFrame = isTokenComplete( tokens );
+ if ( isFinishedFrame )
+ {
+ frameFinished = true;
+ frameStarted = false;
+ break;
+ }
+ }
+
+ boolean removed = removeUnsynchronizedTokens( tokens );
+ if ( removed && tokens.isEmpty() )
+ {
+ frameStarted = false;
+ frameFinished = true;
+ }
+ }
+
+ if ( !notEndOfStream )
+ {
+ throw new EOFException();
+ }
+
+ if ( tokens.size() <= 1 ) // todo
+ {
+ throw new MasterProcessCommandNoMagicNumberException( frame.toString() );
+ }
+ if ( tokens.size() == 2 )
+ {
+ return new Command( MasterProcessCommand.byOpcode( tokens.get( 1 ) ) );
+ }
+ else if ( tokens.size() == 3 )
+ {
+ return new Command( MasterProcessCommand.byOpcode( tokens.get( 1 ) ), tokens.get( 2 ) );
+ }
+ else
+ {
+ throw new MasterProcessUnknownCommandException( frame.toString() );
+ }
+ }
+
+ private boolean isTokenComplete( List<String> tokens )
+ {
+ if ( tokens.size() >= 2 )
+ {
+ return hasData( tokens.get( 1 ) ) == ( tokens.size() == 3 );
+ }
+ return false;
+ }
+
+ private boolean removeUnsynchronizedTokens( Collection<String> tokens )
+ {
+ boolean removed = false;
+ for ( Iterator<String> it = tokens.iterator(); it.hasNext(); )
+ {
+ String token = it.next();
+ if ( token.equals( MasterProcessCommand.MAGIC_NUMBER ) )
+ {
+ break;
+ }
+ removed = true;
+ it.remove();
+ System.err.println( "Forked JVM could not synchronize the '" + token + "' token with preamble sequence." );
+ }
+ return removed;
+ }
+
+ @Override
+ public void close()
+ {
+ }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoder.java
similarity index 92%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java
rename to surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoder.java
index 94f620a..d4b32bd 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoder.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.booter.spi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,9 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.booter.DumpErrorSingleton;
+import org.apache.maven.surefire.booter.ForkedProcessEvent;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
import org.apache.maven.surefire.shared.codec.binary.Base64;
import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerUtils;
import org.apache.maven.surefire.report.ReportEntry;
@@ -34,7 +37,7 @@ import java.util.Map.Entry;
import static java.nio.charset.StandardCharsets.US_ASCII;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER;
+import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER_DELIMITED;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_SYSPROPS;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDERR;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDERR_NEW_LINE;
@@ -67,42 +70,46 @@ import static java.util.Objects.requireNonNull;
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 3.0.0-M4
*/
-public final class ForkedChannelEncoder
+public class LegacyMasterProcessChannelEncoder implements MasterProcessChannelEncoder
{
private static final Base64 BASE64 = new Base64();
private static final Charset STREAM_ENCODING = US_ASCII;
private static final Charset STRING_ENCODING = UTF_8;
- private final OutputStream out;
+ protected final OutputStream out;
private final RunMode runMode;
private volatile boolean trouble;
- public ForkedChannelEncoder( OutputStream out )
+ public LegacyMasterProcessChannelEncoder( OutputStream out )
{
this( out, NORMAL_RUN );
}
- private ForkedChannelEncoder( OutputStream out, RunMode runMode )
+ protected LegacyMasterProcessChannelEncoder( OutputStream out, RunMode runMode )
{
this.out = requireNonNull( out );
this.runMode = requireNonNull( runMode );
}
- public ForkedChannelEncoder asRerunMode() // todo apply this and rework providers
+ @Override
+ public MasterProcessChannelEncoder asRerunMode() // todo apply this and rework providers
{
- return new ForkedChannelEncoder( out, RERUN_TEST_AFTER_FAILURE );
+ return new LegacyMasterProcessChannelEncoder( out, RERUN_TEST_AFTER_FAILURE );
}
- public ForkedChannelEncoder asNormalMode()
+ @Override
+ public MasterProcessChannelEncoder asNormalMode()
{
- return new ForkedChannelEncoder( out, NORMAL_RUN );
+ return new LegacyMasterProcessChannelEncoder( out, NORMAL_RUN );
}
+ @Override
public boolean checkError()
{
return trouble;
}
+ @Override
public void sendSystemProperties( Map<String, String> sysProps )
{
for ( Entry<String, String> entry : sysProps.entrySet() )
@@ -114,52 +121,62 @@ public final class ForkedChannelEncoder
}
}
+ @Override
public void testSetStarting( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TESTSET_STARTING, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testSetCompleted( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TESTSET_COMPLETED, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testStarting( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_STARTING, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testSucceeded( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_SUCCEEDED, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testFailed( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_FAILED, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testSkipped( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_SKIPPED, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testError( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_ERROR, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void testAssumptionFailure( ReportEntry reportEntry, boolean trimStackTraces )
{
encode( BOOTERCODE_TEST_ASSUMPTIONFAILURE, runMode, reportEntry, trimStackTraces );
}
+ @Override
public void stdOut( String msg, boolean newLine )
{
ForkedProcessEvent event = newLine ? BOOTERCODE_STDOUT_NEW_LINE : BOOTERCODE_STDOUT;
setOutErr( event.getOpcode(), msg );
}
+ @Override
public void stdErr( String msg, boolean newLine )
{
ForkedProcessEvent event = newLine ? BOOTERCODE_STDERR_NEW_LINE : BOOTERCODE_STDERR;
@@ -173,23 +190,27 @@ public final class ForkedChannelEncoder
encodeAndPrintEvent( event );
}
+ @Override
public void consoleInfoLog( String msg )
{
StringBuilder event = print( BOOTERCODE_CONSOLE_INFO.getOpcode(), msg );
encodeAndPrintEvent( event );
}
+ @Override
public void consoleErrorLog( String msg )
{
StringBuilder event = print( BOOTERCODE_CONSOLE_ERROR.getOpcode(), msg );
encodeAndPrintEvent( event );
}
+ @Override
public void consoleErrorLog( Throwable t )
{
consoleErrorLog( t.getLocalizedMessage(), t );
}
+ @Override
public void consoleErrorLog( String msg, Throwable t )
{
StringBuilder encoded = encodeHeader( BOOTERCODE_CONSOLE_ERROR.getOpcode(), null );
@@ -197,38 +218,45 @@ public final class ForkedChannelEncoder
encodeAndPrintEvent( encoded );
}
+ @Override
public void consoleErrorLog( StackTraceWriter stackTraceWriter, boolean trimStackTraces )
{
error( stackTraceWriter, trimStackTraces, BOOTERCODE_CONSOLE_ERROR );
}
+ @Override
public void consoleDebugLog( String msg )
{
StringBuilder event = print( BOOTERCODE_CONSOLE_DEBUG.getOpcode(), msg );
encodeAndPrintEvent( event );
}
+ @Override
public void consoleWarningLog( String msg )
{
StringBuilder event = print( BOOTERCODE_CONSOLE_WARNING.getOpcode(), msg );
encodeAndPrintEvent( event );
}
+ @Override
public void bye()
{
encodeOpcode( BOOTERCODE_BYE );
}
+ @Override
public void stopOnNextTest()
{
encodeOpcode( BOOTERCODE_STOP_ON_NEXT_TEST );
}
+ @Override
public void acquireNextTest()
{
encodeOpcode( BOOTERCODE_NEXT_TEST );
}
+ @Override
public void sendExitEvent( StackTraceWriter stackTraceWriter, boolean trimStackTraces )
{
error( stackTraceWriter, trimStackTraces, BOOTERCODE_JVM_EXIT_ERROR );
@@ -390,7 +418,7 @@ public final class ForkedChannelEncoder
static StringBuilder encodeOpcode( String operation, String runMode )
{
StringBuilder s = new StringBuilder( 128 )
- .append( MAGIC_NUMBER )
+ .append( MAGIC_NUMBER_DELIMITED )
.append( operation );
return runMode == null ? s : s.append( ':' ).append( runMode );
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelProcessorFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelProcessorFactory.java
new file mode 100644
index 0000000..b5d4dd5
--- /dev/null
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelProcessorFactory.java
@@ -0,0 +1,70 @@
+package org.apache.maven.surefire.booter.spi;
+
+/*
+ * 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.providerapi.MasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
+import org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+/**
+ * Producer of encoder and decoder for process pipes.
+ * <br>
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 3.0.0-M5
+ */
+public class LegacyMasterProcessChannelProcessorFactory
+ implements MasterProcessChannelProcessorFactory
+{
+ @Override
+ public boolean canUse( String channelConfig )
+ {
+ return channelConfig.startsWith( "pipe://" );
+ }
+
+ @Override
+ public void connect( String channelConfig ) throws IOException
+ {
+ if ( !canUse( channelConfig ) )
+ {
+ throw new MalformedURLException( "Unknown chanel string " + channelConfig );
+ }
+ }
+
+ @Override
+ public MasterProcessChannelDecoder createDecoder()
+ {
+ return new LegacyMasterProcessChannelDecoder( System.in );
+ }
+
+ @Override
+ public MasterProcessChannelEncoder createEncoder()
+ {
+ return new LegacyMasterProcessChannelEncoder( System.out );
+ }
+
+ @Override
+ public void close()
+ {
+ }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/FailFastAware.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessCommandNoMagicNumberException.java
similarity index 65%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/FailFastAware.java
rename to surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessCommandNoMagicNumberException.java
index 994b60d..261969e 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/FailFastAware.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessCommandNoMagicNumberException.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.booter.spi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,13 +19,20 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.booter.MasterProcessCommand;
+
+import java.io.IOException;
+
/**
- * See the plugin configuration parameter {@code skipAfterFailureCount}.
+ * No magic number recognized in the command line, see the JavaDoc in {@link MasterProcessCommand}.
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
+ * @since 3.0.0-M4
*/
-interface FailFastAware
+public class MasterProcessCommandNoMagicNumberException extends IOException
{
- void setSkipAfterFailureCount( int skipAfterFailureCount );
+ MasterProcessCommandNoMagicNumberException( String line )
+ {
+ super( "No magic # recognized in the line '" + line + "'" );
+ }
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessUnknownCommandException.java
similarity index 63%
copy from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
copy to surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessUnknownCommandException.java
index eddebed..11cab97 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/MasterProcessUnknownCommandException.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.booter.spi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +19,21 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
+import org.apache.maven.surefire.booter.MasterProcessCommand;
-import java.util.List;
+import java.io.IOException;
/**
- * CLI options in plugin (main) JVM process.
+ * No {@link MasterProcessCommand command} recognized according to the opcode
+ * encapsulated in the command line, see the JavaDoc in {@link MasterProcessCommand}.
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
+ * @since 3.0.0-M4
*/
-interface MainCliOptionsAware
+public class MasterProcessUnknownCommandException extends IOException
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+ MasterProcessUnknownCommandException( String line )
+ {
+ super( "Unrecognized command found '" + line + "'" );
+ }
}
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/SurefireMasterProcessChannelProcessorFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/SurefireMasterProcessChannelProcessorFactory.java
new file mode 100644
index 0000000..497e748
--- /dev/null
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/SurefireMasterProcessChannelProcessorFactory.java
@@ -0,0 +1,91 @@
+package org.apache.maven.surefire.booter.spi;
+
+/*
+ * 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.providerapi.MasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
+import org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.channels.Channels;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Producer of TCP/IP encoder and decoder.
+ * <br>
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 3.0.0-M5
+ */
+public class SurefireMasterProcessChannelProcessorFactory
+ implements MasterProcessChannelProcessorFactory
+{
+ private volatile SocketChannel channel;
+
+ @Override
+ public boolean canUse( String channelConfig )
+ {
+ return channelConfig.startsWith( "tcp://" );
+ }
+
+ @Override
+ public void connect( String channelConfig ) throws IOException
+ {
+ if ( !canUse( channelConfig ) )
+ {
+ throw new MalformedURLException( "Unknown chanel string " + channelConfig );
+ }
+
+ try
+ {
+ URI uri = new URI( channelConfig );
+ channel = SocketChannel.open( new InetSocketAddress( uri.getHost(), uri.getPort() ) );
+ }
+ catch ( URISyntaxException e )
+ {
+ throw new IOException( e.getLocalizedMessage(), e );
+ }
+ }
+
+ @Override
+ public MasterProcessChannelDecoder createDecoder()
+ {
+ return new LegacyMasterProcessChannelDecoder( Channels.newInputStream( channel ) );
+ }
+
+ @Override
+ public MasterProcessChannelEncoder createEncoder()
+ {
+ return new LegacyMasterProcessChannelEncoder( Channels.newOutputStream( channel ) );
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ if ( channel != null )
+ {
+ channel.close();
+ }
+ }
+}
diff --git a/.github/workflows/maven.yml b/surefire-booter/src/main/resources/META-INF/services/org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory
similarity index 58%
copy from .github/workflows/maven.yml
copy to surefire-booter/src/main/resources/META-INF/services/org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory
index 0d56bb9..22a3f43 100644
--- a/.github/workflows/maven.yml
+++ b/surefire-booter/src/main/resources/META-INF/services/org.apache.maven.surefire.spi.MasterProcessChannelProcessorFactory
@@ -1,3 +1,4 @@
+#
# 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
@@ -6,7 +7,7 @@
# "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
+# 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
@@ -14,29 +15,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-
-name: GitHub CI
-
-on: [push]
-
-jobs:
- build:
-
- strategy:
- matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
- fail-fast: false
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - name: Checkout
- uses: actions/checkout@v1
-
- - name: Set up JDK 1.8
- uses: actions/setup-java@v1
- with:
- java-version: 1.8
-
- - name: Build with Maven
- run: mvn install -e -B -V -nsu --no-transfer-progress -P run-its
+#
+org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelProcessorFactory
+org.apache.maven.surefire.booter.spi.SurefireMasterProcessChannelProcessorFactory
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/BooterDeserializerTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/BooterDeserializerTest.java
index 302f7ad..b1c0284 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/BooterDeserializerTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/BooterDeserializerTest.java
@@ -48,7 +48,7 @@ public class BooterDeserializerTest
assertThat( deserializer.getStartupConfiguration().getProcessChecker() )
.isEqualTo( ALL );
- assertThat( deserializer.getStartupConfiguration().useSystemClassLoader() )
+ assertThat( deserializer.getStartupConfiguration().getClassLoaderConfiguration().isUseSystemClassLoader() )
.isTrue();
assertThat( deserializer.getStartupConfiguration().getProviderClassName() )
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
similarity index 78%
rename from surefire-api/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
rename to surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
index 40c0243..74d7b16 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
@@ -19,6 +19,11 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelDecoder;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelDecoder;
import org.apache.maven.surefire.testset.TestSetFailedException;
import org.junit.After;
import org.junit.Before;
@@ -29,7 +34,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
-import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
@@ -39,8 +43,7 @@ import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import static java.nio.charset.StandardCharsets.ISO_8859_1;
-
+import static java.nio.charset.StandardCharsets.US_ASCII;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -61,7 +64,6 @@ public class CommandReaderTest
private static final long TEST_TIMEOUT = 15_000L;
private final BlockingQueue<Byte> blockingStream = new LinkedBlockingQueue<>();
- private InputStream realInputStream;
private CommandReader reader;
static class A
@@ -83,24 +85,25 @@ public class CommandReaderTest
@Before
public void init()
{
+ //noinspection ResultOfMethodCallIgnored
Thread.interrupted();
- realInputStream = System.in;
+ InputStream realInputStream = new SystemInputStream();
addTestToPipeline( getClass().getName() );
- System.setIn( new SystemInputStream() );
- reader = CommandReader.getReader();
+ ConsoleLogger logger = new NullConsoleLogger();
+ MasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( realInputStream );
+ reader = new CommandReader( decoder, Shutdown.DEFAULT, logger );
}
@After
public void deinit()
{
reader.stop();
- System.setIn( realInputStream );
}
@Test
public void readJustOneClass()
{
- Iterator<String> it = reader.getIterableClasses( new ForkedChannelEncoder( nul() ) ).iterator();
+ Iterator<String> it = reader.getIterableClasses( new LegacyMasterProcessChannelEncoder( nul() ) ).iterator();
assertTrue( it.hasNext() );
assertThat( it.next(), is( getClass().getName() ) );
reader.stop();
@@ -119,7 +122,7 @@ public class CommandReaderTest
@Test
public void manyClasses()
{
- Iterator<String> it1 = reader.getIterableClasses( new ForkedChannelEncoder( nul() ) ).iterator();
+ Iterator<String> it1 = reader.getIterableClasses( new LegacyMasterProcessChannelEncoder( nul() ) ).iterator();
assertThat( it1.next(), is( getClass().getName() ) );
addTestToPipeline( A.class.getName() );
assertThat( it1.next(), is( A.class.getName() ) );
@@ -135,7 +138,7 @@ public class CommandReaderTest
@Test
public void twoIterators() throws Exception
{
- Iterator<String> it1 = reader.getIterableClasses( new ForkedChannelEncoder( nul() ) ).iterator();
+ Iterator<String> it1 = reader.getIterableClasses( new LegacyMasterProcessChannelEncoder( nul() ) ).iterator();
assertThat( it1.next(), is( getClass().getName() ) );
addTestToPipeline( A.class.getName() );
@@ -168,7 +171,8 @@ public class CommandReaderTest
@Override
public void run()
{
- Iterator<String> it = reader.getIterableClasses( new ForkedChannelEncoder( nul() ) ).iterator();
+ Iterator<String> it =
+ reader.getIterableClasses( new LegacyMasterProcessChannelEncoder( nul() ) ).iterator();
assertThat( it.next(), is( CommandReaderTest.class.getName() ) );
}
};
@@ -195,7 +199,8 @@ public class CommandReaderTest
@Override
public void run()
{
- Iterator<String> it = reader.getIterableClasses( new ForkedChannelEncoder( nul() ) ).iterator();
+ Iterator<String> it =
+ reader.getIterableClasses( new LegacyMasterProcessChannelEncoder( nul() ) ).iterator();
assertThat( it.next(), is( CommandReaderTest.class.getName() ) );
counter.countDown();
assertThat( it.next(), is( Foo.class.getName() ) );
@@ -242,24 +247,20 @@ public class CommandReaderTest
private void addTestToPipeline( String cls )
{
- byte[] clazz = cls.getBytes( ISO_8859_1 );
- ByteBuffer buffer = ByteBuffer.allocate( 8 + clazz.length ).putInt(
- MasterProcessCommand.RUN_CLASS.getId() ).putInt( clazz.length ).put( clazz );
- buffer.rewind();
- for ( ; buffer.hasRemaining(); )
+ String cmd = ":maven-surefire-command:"
+ + MasterProcessCommand.RUN_CLASS.getOpcode() + ':' + cls + '\n';
+ for ( byte cmdByte : cmd.getBytes( US_ASCII ) )
{
- blockingStream.add( buffer.get() );
+ blockingStream.add( cmdByte );
}
}
private void addEndOfPipeline()
{
- ByteBuffer buffer = ByteBuffer.allocate( 8 ).putInt( MasterProcessCommand.TEST_SET_FINISHED.getId() ).putInt(
- 0 );
- buffer.rewind();
- for ( ; buffer.hasRemaining(); )
+ String cmd = ":maven-surefire-command:" + MasterProcessCommand.TEST_SET_FINISHED.getOpcode() + '\n';
+ for ( byte cmdByte : cmd.getBytes( US_ASCII ) )
{
- blockingStream.add( buffer.get() );
+ blockingStream.add( cmdByte );
}
}
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/Foo.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/Foo.java
similarity index 71%
rename from surefire-api/src/test/java/org/apache/maven/surefire/booter/Foo.java
rename to surefire-booter/src/test/java/org/apache/maven/surefire/booter/Foo.java
index ccb01e3..1f96fbf 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/Foo.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/Foo.java
@@ -19,9 +19,9 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-
import java.util.Map;
import org.apache.maven.surefire.report.ReporterConfiguration;
+import org.apache.maven.surefire.report.ReporterFactory;
import org.apache.maven.surefire.testset.DirectoryScannerParameters;
import org.apache.maven.surefire.testset.RunOrderParameters;
import org.apache.maven.surefire.testset.TestArtifactInfo;
@@ -30,36 +30,32 @@ import org.apache.maven.surefire.testset.TestRequest;
/**
* @author Kristian Rosenvold
*/
-public class Foo
- implements DirectoryScannerParametersAware, TestRequestAware, ProviderPropertiesAware, ReporterConfigurationAware,
- SurefireClassLoadersAware, TestArtifactInfoAware, RunOrderParametersAware
+public class Foo extends BaseProviderFactory
{
- DirectoryScannerParameters directoryScannerParameters;
-
- Map<String, String> providerProperties;
-
- ReporterConfiguration reporterConfiguration;
+ private Map<String, String> providerProperties;
- ClassLoader surefireClassLoader;
+ private ReporterConfiguration reporterConfiguration;
- ClassLoader testClassLoader;
+ private ClassLoader testClassLoader;
- TestRequest testRequest;
+ private TestArtifactInfo testArtifactInfo;
- TestArtifactInfo testArtifactInfo;
+ private RunOrderParameters runOrderParameters;
- RunOrderParameters runOrderParameters;
+ private boolean called;
- boolean called = false;
+ Foo()
+ {
+ super( false );
+ }
@Override
public void setDirectoryScannerParameters( DirectoryScannerParameters directoryScanner )
{
- this.directoryScannerParameters = directoryScanner;
+ super.setDirectoryScannerParameters( directoryScanner );
this.called = true;
}
-
/**
* @return true if it has been called
*/
@@ -71,8 +67,8 @@ public class Foo
@Override
public void setProviderProperties( Map<String, String> providerProperties )
{
- this.providerProperties = providerProperties;
- this.called = true;
+ super.setProviderProperties( providerProperties );
+ called = true;
}
@Override
@@ -86,14 +82,13 @@ public class Foo
public void setClassLoaders( ClassLoader testClassLoader )
{
this.testClassLoader = testClassLoader;
- this.surefireClassLoader = surefireClassLoader;
this.called = true;
}
@Override
- public void setTestRequest( TestRequest testRequest1 )
+ public void setTestRequest( TestRequest testRequest )
{
- this.testRequest = testRequest1;
+ super.setTestRequest( testRequest );
this.called = true;
}
@@ -107,7 +102,14 @@ public class Foo
@Override
public void setRunOrderParameters( RunOrderParameters runOrderParameters )
{
- this.runOrderParameters = runOrderParameters;
+ super.setRunOrderParameters( runOrderParameters );
this.called = true;
}
+
+ @Override
+ public void setReporterFactory( ReporterFactory reporterFactory )
+ {
+ super.setReporterFactory( reporterFactory );
+ called = true;
+ }
}
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ForkedBooterMockTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ForkedBooterMockTest.java
index e65beb1..2cbb3f2 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ForkedBooterMockTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/ForkedBooterMockTest.java
@@ -19,11 +19,15 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder;
+import org.apache.maven.surefire.report.StackTraceWriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@@ -31,18 +35,24 @@ import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.doCallRealMethod;
+import static org.powermock.api.mockito.PowerMockito.doNothing;
import static org.powermock.api.mockito.PowerMockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.verifyNoMoreInteractions;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.reflect.Whitebox.invokeMethod;
+import static org.powermock.reflect.Whitebox.setInternalState;
+import static org.powermock.utils.JavaVersion.JAVA_RECENT;
+import static org.powermock.utils.JavaVersion.JAVA_12;
/**
* PowerMock tests for {@link ForkedBooter}.
*/
@RunWith( PowerMockRunner.class )
-@PrepareForTest( { PpidChecker.class, ForkedBooter.class } )
+@PrepareForTest( { PpidChecker.class, ForkedBooter.class, LegacyMasterProcessChannelEncoder.class } )
+@PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
public class ForkedBooterMockTest
{
@Mock
@@ -51,6 +61,21 @@ public class ForkedBooterMockTest
@Mock
private ForkedBooter booter;
+ @Mock
+ private LegacyMasterProcessChannelEncoder eventChannel;
+
+ @Captor
+ private ArgumentCaptor<StackTraceWriter> capturedStackTraceWriter;
+
+ @Captor
+ private ArgumentCaptor<Boolean> capturedBoolean;
+
+ @Captor
+ private ArgumentCaptor<String[]> capturedArgs;
+
+ @Captor
+ private ArgumentCaptor<ForkedBooter> capturedBooter;
+
@Test
public void shouldCheckNewPingMechanism() throws Exception
{
@@ -71,8 +96,6 @@ public class ForkedBooterMockTest
{
PowerMockito.mockStatic( ForkedBooter.class );
- ArgumentCaptor<String[]> capturedArgs = ArgumentCaptor.forClass( String[].class );
- ArgumentCaptor<ForkedBooter> capturedBooter = ArgumentCaptor.forClass( ForkedBooter.class );
doCallRealMethod()
.when( ForkedBooter.class, "run", capturedBooter.capture(), capturedArgs.capture() );
@@ -106,6 +129,13 @@ public class ForkedBooterMockTest
@Test
public void testMainWithError() throws Exception
{
+ //does not work in PowerMock
+ //assumeFalse( JAVA_RECENT.atLeast( JAVA_12 ) );
+ if ( JAVA_RECENT.atLeast( JAVA_12 ) )
+ {
+ return;
+ }
+
PowerMockito.mockStatic( ForkedBooter.class );
doCallRealMethod()
@@ -114,6 +144,13 @@ public class ForkedBooterMockTest
doThrow( new RuntimeException( "dummy exception" ) )
.when( booter, "execute" );
+ doNothing()
+ .when( booter, "setupBooter",
+ any( String.class ), any( String.class ), any( String.class ), any( String.class ) );
+
+ // broken in PowerMock JDK 12
+ setInternalState( booter, "eventChannel", eventChannel );
+
String[] args = new String[]{ "/", "dump", "surefire.properties", "surefire-effective.properties" };
invokeMethod( ForkedBooter.class, "run", booter, args );
@@ -123,6 +160,18 @@ public class ForkedBooterMockTest
verifyPrivate( booter, times( 1 ) )
.invoke( "execute" );
+ verify( eventChannel, times( 1 ) )
+ .consoleErrorLog( capturedStackTraceWriter.capture(), capturedBoolean.capture() );
+ assertThat( capturedStackTraceWriter.getValue() )
+ .isNotNull();
+ assertThat( capturedStackTraceWriter.getValue().smartTrimmedStackTrace() )
+ .isEqualTo( "test subsystem#no method RuntimeException dummy exception" );
+ assertThat( capturedStackTraceWriter.getValue().getThrowable().getTarget() )
+ .isNotNull()
+ .isInstanceOf( RuntimeException.class );
+ assertThat( capturedStackTraceWriter.getValue().getThrowable().getTarget().getMessage() )
+ .isEqualTo( "dummy exception" );
+
verifyPrivate( booter, times( 1 ) )
.invoke( "cancelPingScheduler" );
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/IsolatedClassLoaderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/IsolatedClassLoaderTest.java
new file mode 100644
index 0000000..b424526
--- /dev/null
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/IsolatedClassLoaderTest.java
@@ -0,0 +1,66 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * 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.shared.utils.io.FileUtils;
+import org.apache.maven.surefire.providerapi.AbstractProvider;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.net.URL;
+
+import static java.io.File.pathSeparator;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Tests isolated CL.
+ */
+public class IsolatedClassLoaderTest
+{
+ private IsolatedClassLoader classLoader;
+
+ @Before
+ public void prepareClassLoader() throws Exception
+ {
+ classLoader = new IsolatedClassLoader( null, false, "role" );
+
+ String[] files = FileUtils.fileRead( new File( "target/test-classpath/cp.txt" ), "UTF-8" )
+ .split( pathSeparator );
+
+ for ( String file : files )
+ {
+ URL fileUrl = new File( file ).toURL();
+ classLoader.addURL( fileUrl );
+ }
+ }
+
+ @Test
+ public void shouldLoadIsolatedClass() throws Exception
+ {
+ Class<?> isolatedClass = classLoader.loadClass( AbstractProvider.class.getName() );
+ assertThat( isolatedClass, is( notNullValue() ) );
+ assertThat( isolatedClass.getName(), is( AbstractProvider.class.getName() ) );
+ assertThat( isolatedClass, is( not( (Class) AbstractProvider.class ) ) );
+ }
+}
\ No newline at end of file
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
index 75b2ef0..a7c6298 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
@@ -23,6 +23,8 @@ import junit.framework.JUnit4TestAdapter;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelDecoderTest;
+import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoderTest;
/**
* Adapt the JUnit4 tests which use only annotations to the JUnit3 test suite.
@@ -35,13 +37,18 @@ public class JUnit4SuiteTest extends TestCase
public static Test suite()
{
TestSuite suite = new TestSuite();
+ suite.addTest( new JUnit4TestAdapter( CommandReaderTest.class ) );
suite.addTest( new JUnit4TestAdapter( PpidCheckerTest.class ) );
suite.addTest( new JUnit4TestAdapter( SystemUtilsTest.class ) );
+ suite.addTest( new JUnit4TestAdapter( IsolatedClassLoaderTest.class ) );
suite.addTest( new JUnit4TestAdapter( ForkedBooterTest.class ) );
suite.addTest( new JUnit4TestAdapter( ForkedBooterMockTest.class ) );
suite.addTest( new JUnit4TestAdapter( BooterDeserializerTest.class ) );
suite.addTestSuite( ClasspathTest.class );
suite.addTestSuite( PropertiesWrapperTest.class );
+ suite.addTestSuite( LegacyMasterProcessChannelDecoderTest.class );
+ suite.addTest( new JUnit4TestAdapter( LegacyMasterProcessChannelEncoderTest.class ) );
+ suite.addTestSuite( SurefireReflectorTest.class );
return suite;
}
}
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/NewClassLoaderRunner.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/NewClassLoaderRunner.java
similarity index 100%
rename from surefire-api/src/test/java/org/apache/maven/surefire/booter/NewClassLoaderRunner.java
rename to surefire-booter/src/test/java/org/apache/maven/surefire/booter/NewClassLoaderRunner.java
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
new file mode 100644
index 0000000..9f7372d
--- /dev/null
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
@@ -0,0 +1,408 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.maven.surefire.providerapi.ProviderParameters;
+import org.apache.maven.surefire.providerapi.SurefireProvider;
+import org.apache.maven.surefire.report.ReporterConfiguration;
+import org.apache.maven.surefire.report.ReporterFactory;
+import org.apache.maven.surefire.report.RunListener;
+import org.apache.maven.surefire.suite.RunResult;
+import org.apache.maven.surefire.testset.DirectoryScannerParameters;
+import org.apache.maven.surefire.testset.RunOrderParameters;
+import org.apache.maven.surefire.testset.TestArtifactInfo;
+import org.apache.maven.surefire.testset.TestListResolver;
+import org.apache.maven.surefire.testset.TestRequest;
+import org.apache.maven.surefire.util.RunOrder;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+
+import static java.util.Arrays.asList;
+import static org.apache.maven.surefire.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
+import static org.apache.maven.surefire.cli.CommandLineOption.SHOW_ERRORS;
+
+/**
+ *
+ */
+public class SurefireReflectorTest
+ extends TestCase
+{
+ public void testShouldCreateFactoryWithoutException()
+ {
+ ReporterFactory factory = new ReporterFactory()
+ {
+ @Override
+ public RunListener createReporter()
+ {
+ return null;
+ }
+
+ @Override
+ public RunResult close()
+ {
+ return null;
+ }
+ };
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ SurefireReflector reflector = new SurefireReflector( cl );
+ BaseProviderFactory bpf = (BaseProviderFactory) reflector.createBooterConfiguration( cl, true );
+ bpf.setReporterFactory( factory );
+ assertNotNull( bpf.getReporterFactory() );
+ assertSame( factory, bpf.getReporterFactory() );
+ }
+
+ public void testSetDirectoryScannerParameters()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ DirectoryScannerParameters directoryScannerParameters =
+ new DirectoryScannerParameters( new File( "ABC" ), new ArrayList<String>(), new ArrayList<String>(),
+ new ArrayList<String>(), false, "hourly" );
+ surefireReflector.setDirectoryScannerParameters( foo, directoryScannerParameters );
+ assertTrue( isCalled( foo ) );
+ assertNotNull( ( (Foo) foo ).getDirectoryScannerParameters() );
+ }
+
+ public void testNullSetDirectoryScannerParameters()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setDirectoryScannerParameters( foo, null );
+ assertTrue( isCalled( foo ) );
+ assertNull( ( (Foo) foo ).getDirectoryScannerParameters() );
+ }
+
+ public void testSetIfDirScannerAware()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ DirectoryScannerParameters directoryScannerParameters =
+ new DirectoryScannerParameters( new File( "ABC" ), new ArrayList<String>(), new ArrayList<String>(),
+ new ArrayList<String>(), false, "hourly" );
+ surefireReflector.setIfDirScannerAware( foo, directoryScannerParameters );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testRunOrderParameters()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ RunOrderParameters runOrderParameters = new RunOrderParameters( RunOrder.DEFAULT, new File( "." ) );
+ surefireReflector.setRunOrderParameters( foo, runOrderParameters );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testNullRunOrderParameters()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setRunOrderParameters( foo, null );
+ assertTrue( isCalled( foo ) );
+ assertNull( ( (Foo) foo ).getRunOrderCalculator() );
+ }
+
+ public void testTestSuiteDefinition()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ TestRequest testSuiteDefinition =
+ new TestRequest( asList( new File( "file1" ), new File( "file2" ) ),
+ new File( "TestSOurce" ), new TestListResolver( "aUserRequestedTest#aMethodRequested" ) );
+ surefireReflector.setTestSuiteDefinition( foo, testSuiteDefinition );
+ assertTrue( isCalled( foo ) );
+ assertNotNull( ( (Foo) foo ).getTestRequest() );
+ }
+
+ public void testNullTestSuiteDefinition()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+ surefireReflector.setTestSuiteDefinition( foo, null );
+ assertTrue( isCalled( foo ) );
+ assertNull( ( (Foo) foo ).getTestRequest() );
+ }
+
+ public void testProviderProperties()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setProviderProperties( foo, new HashMap<String, String>() );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testReporterConfiguration()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ ReporterConfiguration reporterConfiguration = getReporterConfiguration();
+ surefireReflector.setReporterConfigurationAware( foo, reporterConfiguration );
+ assertTrue( isCalled( foo ) );
+ }
+
+ private ReporterConfiguration getReporterConfiguration()
+ {
+ return new ReporterConfiguration( new File( "CDE" ), true );
+ }
+
+ public void testTestClassLoader()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setTestClassLoader( foo, getClass().getClassLoader() );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testTestClassLoaderAware()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setTestClassLoaderAware( foo, getClass().getClassLoader() );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testArtifactInfo()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ TestArtifactInfo testArtifactInfo = new TestArtifactInfo( "12.3", "test" );
+ surefireReflector.setTestArtifactInfo( foo, testArtifactInfo );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testNullArtifactInfo()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ surefireReflector.setTestArtifactInfo( foo, null );
+ assertTrue( isCalled( foo ) );
+ assertNull( ( (Foo) foo ).getTestArtifactInfo() );
+ }
+
+ public void testArtifactInfoAware()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ TestArtifactInfo testArtifactInfo = new TestArtifactInfo( "12.3", "test" );
+ surefireReflector.setTestArtifactInfoAware( foo, testArtifactInfo );
+ assertTrue( isCalled( foo ) );
+ assertEquals( testArtifactInfo.getClassifier(), "test" );
+ assertEquals( testArtifactInfo.getVersion(), "12.3" );
+ }
+
+ public void testReporterFactory()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ ReporterFactory reporterFactory = new ReporterFactory()
+ {
+ @Override
+ public RunListener createReporter()
+ {
+ return null;
+ }
+
+ @Override
+ public RunResult close()
+ {
+ return null;
+ }
+ };
+
+ surefireReflector.setReporterFactory( foo, reporterFactory );
+ assertTrue( isCalled( foo ) );
+ }
+
+ public void testReporterFactoryAware()
+ {
+ SurefireReflector surefireReflector = getReflector();
+ Object foo = getFoo();
+
+ ReporterFactory reporterFactory = new ReporterFactory()
+ {
+ @Override
+ public RunListener createReporter()
+ {
+ return null;
+ }
+
+ @Override
+ public RunResult close()
+ {
+ return null;
+ }
+ };
+
+ surefireReflector.setReporterFactoryAware( foo, reporterFactory );
+ assertTrue( isCalled( foo ) );
+ assertSame( ( (Foo) foo ).getReporterFactory(), reporterFactory );
+ }
+
+ @SuppressWarnings( "checkstyle:magicnumber" )
+ public void testConvertIfRunResult()
+ {
+ RunResult runResult = new RunResult( 20, 1, 2, 3, 4, "IOException", true );
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ RunResult obj = (RunResult) reflector.convertIfRunResult( runResult );
+ assertEquals( obj.getCompletedCount(), 20 );
+ assertEquals( obj.getErrors(), 1 );
+ assertEquals( obj.getFailures(), 2 );
+ assertEquals( obj.getSkipped(), 3 );
+ assertFalse( obj.isErrorFree() );
+ assertFalse( obj.isInternalError() );
+ assertEquals( obj.getFailsafeCode(), (Integer) RunResult.FAILURE );
+
+ assertNull( reflector.convertIfRunResult( null ) );
+ assertEquals( reflector.convertIfRunResult( "" ), "" );
+ }
+
+ public void testInstantiateProvider()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Object booterParams = getFoo();
+ Object provider = reflector.instantiateProvider( DummyProvider.class.getName(), booterParams );
+ assertNotNull( provider );
+ assertEquals( provider.getClass(), DummyProvider.class );
+ }
+
+ public void testSetMainCliOptions()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Object booterParams = getFoo();
+ reflector.setMainCliOptions( booterParams, asList( SHOW_ERRORS, LOGGING_LEVEL_DEBUG ) );
+ assertEquals( ( (BaseProviderFactory) booterParams ).getMainCliOptions().size(), 2 );
+ assertEquals( ( (BaseProviderFactory) booterParams ).getMainCliOptions().get( 0 ), SHOW_ERRORS );
+ assertEquals( ( (BaseProviderFactory) booterParams ).getMainCliOptions().get( 1 ), LOGGING_LEVEL_DEBUG );
+ }
+
+ public void testSetSkipAfterFailureCount()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Foo booterParams = (Foo) getFoo();
+ assertEquals( booterParams.getSkipAfterFailureCount(), 0 );
+ reflector.setSkipAfterFailureCount( booterParams, 5 );
+ assertEquals( booterParams.getSkipAfterFailureCount(), 5 );
+ }
+
+ @SuppressWarnings( "checkstyle:magicnumber" )
+ public void testSetSystemExitTimeout()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Foo booterParams = (Foo) getFoo();
+ assertNull( booterParams.getSystemExitTimeout() );
+ reflector.setSystemExitTimeout( booterParams, 60 );
+ assertEquals( booterParams.getSystemExitTimeout(), (Integer) 60 );
+ }
+
+ public void testSetTestSuiteDefinitionAware()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Foo booterParams = (Foo) getFoo();
+ TestRequest request = new TestRequest( Collections.emptyList(), null, null );
+ reflector.setTestSuiteDefinitionAware( booterParams, request );
+ assertTrue( booterParams.isCalled() );
+ assertNotNull( booterParams.getTestRequest() );
+ assertTrue( booterParams.getTestRequest().getSuiteXmlFiles().isEmpty() );
+ assertNull( booterParams.getTestRequest().getTestSourceDirectory() );
+ assertNull( booterParams.getTestRequest().getTestListResolver() );
+ assertEquals( booterParams.getTestRequest().getRerunFailingTestsCount(), 0 );
+ }
+
+ public void testSetProviderPropertiesAware()
+ {
+ SurefireReflector reflector = new SurefireReflector( Thread.currentThread().getContextClassLoader() );
+ Foo booterParams = (Foo) getFoo();
+ reflector.setProviderPropertiesAware( booterParams, Collections.singletonMap( "k", "v" ) );
+ assertTrue( booterParams.isCalled() );
+ assertNotNull( booterParams.getProviderProperties() );
+ assertEquals( booterParams.getProviderProperties().size(), 1 );
+ assertEquals( booterParams.getProviderProperties().get( "k" ), "v" );
+ }
+
+ private SurefireReflector getReflector()
+ {
+ return new SurefireReflector( getClass().getClassLoader() );
+ }
+
+ private Object getFoo()
+ { // Todo: Setup a different classloader so we can really test crossing
+ return new Foo();
+ }
+
+ private Boolean isCalled( Object foo )
+ {
+ final Method isCalled;
+ try
+ {
+ isCalled = foo.getClass().getMethod( "isCalled" );
+ return (Boolean) isCalled.invoke( foo );
+ }
+ catch ( ReflectiveOperationException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+
+ /**
+ *
+ */
+ public static final class DummyProvider implements SurefireProvider
+ {
+ public DummyProvider( ProviderParameters providerParameters )
+ {
+ }
+
+ @Override
+ public Iterable<Class<?>> getSuites()
+ {
+ return null;
+ }
+
+ @Override
+ public RunResult invoke( Object forkTestSet )
+ {
+ return null;
+ }
+
+ @Override
+ public void cancel()
+ {
+
+ }
+ }
+}
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoderTest.java
new file mode 100644
index 0000000..13efee2
--- /dev/null
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelDecoderTest.java
@@ -0,0 +1,150 @@
+package org.apache.maven.surefire.booter.spi;
+
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.maven.surefire.booter.Command;
+import org.apache.maven.surefire.booter.MasterProcessCommand;
+import org.apache.maven.surefire.booter.Shutdown;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.apache.maven.surefire.booter.MasterProcessCommand.BYE_ACK;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Tests for {@link LegacyMasterProcessChannelDecoder}.
+ */
+public class LegacyMasterProcessChannelDecoderTest
+ extends TestCase
+{
+ public void testDataToByteArrayAndBack() throws IOException
+ {
+ for ( MasterProcessCommand commandType : MasterProcessCommand.values() )
+ {
+ switch ( commandType )
+ {
+ case RUN_CLASS:
+ assertEquals( String.class, commandType.getDataType() );
+ byte[] encoded = commandType.encode( "pkg.Test" );
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:run-testclass:pkg.Test:" );
+ byte[] line = addNL( encoded, '\n' );
+ InputStream is = new ByteArrayInputStream( line );
+ LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( is );
+ Command command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertThat( command.getData(), is( "pkg.Test" ) );
+ break;
+ case TEST_SET_FINISHED:
+ assertThat( commandType ).isSameAs( Command.TEST_SET_FINISHED.getCommandType() );
+ assertEquals( Void.class, commandType.getDataType() );
+ encoded = commandType.encode();
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:testset-finished:" );
+ is = new ByteArrayInputStream( encoded );
+ decoder = new LegacyMasterProcessChannelDecoder( is );
+ command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertNull( command.getData() );
+ break;
+ case SKIP_SINCE_NEXT_TEST:
+ assertThat( commandType ).isSameAs( Command.SKIP_SINCE_NEXT_TEST.getCommandType() );
+ assertEquals( Void.class, commandType.getDataType() );
+ encoded = commandType.encode();
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:skip-since-next-test:" );
+ is = new ByteArrayInputStream( encoded );
+ decoder = new LegacyMasterProcessChannelDecoder( is );
+ command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertNull( command.getData() );
+ break;
+ case SHUTDOWN:
+ assertEquals( String.class, commandType.getDataType() );
+ encoded = commandType.encode( Shutdown.EXIT.name() );
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:shutdown:EXIT:" );
+ is = new ByteArrayInputStream( encoded );
+ decoder = new LegacyMasterProcessChannelDecoder( is );
+ command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertThat( command.getData(), is( "EXIT" ) );
+ break;
+ case NOOP:
+ assertThat( commandType ).isSameAs( Command.NOOP.getCommandType() );
+ assertEquals( Void.class, commandType.getDataType() );
+ encoded = commandType.encode();
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:noop:" );
+ is = new ByteArrayInputStream( encoded );
+ decoder = new LegacyMasterProcessChannelDecoder( is );
+ command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertNull( command.getData() );
+ break;
+ case BYE_ACK:
+ assertThat( commandType ).isSameAs( Command.BYE_ACK.getCommandType() );
+ assertEquals( Void.class, commandType.getDataType() );
+ encoded = commandType.encode();
+ assertThat( new String( encoded ) )
+ .isEqualTo( ":maven-surefire-command:bye-ack:" );
+ is = new ByteArrayInputStream( encoded );
+ decoder = new LegacyMasterProcessChannelDecoder( is );
+ command = decoder.decode();
+ assertThat( command.getCommandType(), is( commandType ) );
+ assertNull( command.getData() );
+ break;
+ default:
+ fail();
+ }
+ }
+ }
+
+ public void testShouldDecodeTwoCommands() throws IOException
+ {
+ String cmd = ":maven-surefire-command:bye-ack\n:maven-surefire-command:bye-ack:";
+ InputStream is = new ByteArrayInputStream( cmd.getBytes() );
+ LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( is );
+
+ Command command = decoder.decode();
+ assertThat( command.getCommandType() ).isEqualTo( BYE_ACK );
+ assertThat( command.getData() ).isNull();
+
+ command = decoder.decode();
+ assertThat( command.getCommandType() ).isEqualTo( BYE_ACK );
+ assertThat( command.getData() ).isNull();
+ }
+
+ private static byte[] addNL( byte[] encoded, char... newLines )
+ {
+ byte[] line = new byte[encoded.length + newLines.length];
+ System.arraycopy( encoded, 0, line, 0, encoded.length );
+ for ( int i = encoded.length, j = 0; i < line.length; i++, j++ )
+ {
+ line[i] = (byte) newLines[j];
+ }
+ return line;
+ }
+}
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkedChannelEncoderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoderTest.java
similarity index 84%
rename from surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkedChannelEncoderTest.java
rename to surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoderTest.java
index 1dcf4d9..eaafd6e 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/booter/ForkedChannelEncoderTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/spi/LegacyMasterProcessChannelEncoderTest.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.booter.spi;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -36,40 +36,41 @@ import java.util.Map;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Arrays.copyOfRange;
+import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encode;
import static org.apache.maven.surefire.shared.codec.binary.Base64.encodeBase64String;
-import static org.apache.maven.surefire.booter.ForkedChannelEncoder.encode;
-import static org.apache.maven.surefire.booter.ForkedChannelEncoder.encodeHeader;
-import static org.apache.maven.surefire.booter.ForkedChannelEncoder.encodeMessage;
-import static org.apache.maven.surefire.booter.ForkedChannelEncoder.encodeOpcode;
+import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeHeader;
+import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeMessage;
+import static org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelEncoder.encodeOpcode;
import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_SYSPROPS;
-import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER;
+import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER_DELIMITED;
import static org.apache.maven.surefire.report.RunMode.NORMAL_RUN;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
- * Test for {@link ForkedChannelEncoder}.
+ * Test for {@link LegacyMasterProcessChannelEncoder}.
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
* @since 3.0.0-M4
*/
-public class ForkedChannelEncoderTest
+public class LegacyMasterProcessChannelEncoderTest
{
private static final int ELAPSED_TIME = 102;
@Test
public void shouldBeFailSafe()
{
- assertThat( ForkedChannelEncoder.toBase64( null ) ).isEqualTo( "-" );
- assertThat( ForkedChannelEncoder.toBase64( "" ) ).isEqualTo( "" );
+ assertThat( LegacyMasterProcessChannelEncoder.toBase64( null ) ).isEqualTo( "-" );
+ assertThat( LegacyMasterProcessChannelEncoder.toBase64( "" ) ).isEqualTo( "" );
}
@Test
public void shouldHaveSystemProperty()
{
StringBuilder actualEncoded = encode( BOOTERCODE_SYSPROPS, NORMAL_RUN, "arg1", "arg2" );
- String expected = MAGIC_NUMBER + BOOTERCODE_SYSPROPS.getOpcode() + ":normal-run" + ":UTF-8:YXJnMQ==:YXJnMg==";
+ String expected = MAGIC_NUMBER_DELIMITED + BOOTERCODE_SYSPROPS.getOpcode()
+ + ":normal-run:UTF-8:YXJnMQ==:YXJnMg==";
assertThat( actualEncoded.toString() )
.isEqualTo( expected );
@@ -179,7 +180,7 @@ public class ForkedChannelEncoderTest
StringBuilder encode = encode( "X", "normal-run", reportEntry, false );
assertThat( encode.toString() )
- .isEqualTo( ":maven:surefire:std:out:X:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:X:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -204,7 +205,7 @@ public class ForkedChannelEncoderTest
encode = encode( "X", "normal-run", reportEntry, true );
assertThat( encode.toString() )
- .isEqualTo( ":maven:surefire:std:out:X:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:X:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -228,12 +229,12 @@ public class ForkedChannelEncoderTest
);
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testSetStarting( reportEntry, true );
+ encoder.testSetStarting( reportEntry, true );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:testset-starting:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -258,12 +259,12 @@ public class ForkedChannelEncoderTest
assertThat( printedLines.readLine() ).isNull();
out = Stream.newStream();
- forkedChannelEncoder = new ForkedChannelEncoder( out );
+ encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testSetStarting( reportEntry, false );
+ encoder.testSetStarting( reportEntry, false );
printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:testset-starting:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:testset-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -325,12 +326,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testSetCompleted( reportEntry, false );
+ encoder.testSetCompleted( reportEntry, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:testset-completed:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:testset-completed:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -392,12 +393,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testStarting( reportEntry, true );
+ encoder.testStarting( reportEntry, true );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-starting:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-starting:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -459,12 +460,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testSucceeded( reportEntry, true );
+ encoder.testSucceeded( reportEntry, true );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-succeeded:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-succeeded:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -526,12 +527,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testFailed( reportEntry, false );
+ encoder.testFailed( reportEntry, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-failed:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-failed:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -592,12 +593,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testSkipped( reportEntry, false );
+ encoder.testSkipped( reportEntry, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-skipped:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-skipped:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -657,12 +658,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testError( reportEntry, false );
+ encoder.testError( reportEntry, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-error:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-error:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -720,12 +721,12 @@ public class ForkedChannelEncoderTest
String encodedMessage = encodeBase64String( toArray( UTF_8.encode( reportEntry.getMessage() ) ) );
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.testAssumptionFailure( reportEntry, false );
+ encoder.testAssumptionFailure( reportEntry, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:test-assumption-failure:normal-run:UTF-8:"
+ .isEqualTo( ":maven-surefire-event:test-assumption-failure:normal-run:UTF-8:"
+ encodedSourceName
+ ":"
+ "-"
@@ -754,12 +755,12 @@ public class ForkedChannelEncoderTest
public void testBye() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.bye();
+ encoder.bye();
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:bye" );
+ .isEqualTo( ":maven-surefire-event:bye" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -767,12 +768,12 @@ public class ForkedChannelEncoderTest
public void testStopOnNextTest() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.stopOnNextTest();
+ encoder.stopOnNextTest();
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:stop-on-next-test" );
+ .isEqualTo( ":maven-surefire-event:stop-on-next-test" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -780,12 +781,12 @@ public class ForkedChannelEncoderTest
public void testAcquireNextTest() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.acquireNextTest();
+ encoder.acquireNextTest();
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .isEqualTo( ":maven:surefire:std:out:next-test" );
+ .isEqualTo( ":maven-surefire-event:next-test" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -794,38 +795,38 @@ public class ForkedChannelEncoderTest
{
StringBuilder encoded = encodeOpcode( "some-opcode", "normal-run" );
assertThat( encoded.toString() )
- .isEqualTo( ":maven:surefire:std:out:some-opcode:normal-run" );
+ .isEqualTo( ":maven-surefire-event:some-opcode:normal-run" );
encoded = encodeHeader( "some-opcode", "normal-run" );
assertThat( encoded.toString() )
- .isEqualTo( ":maven:surefire:std:out:some-opcode:normal-run:UTF-8" );
+ .isEqualTo( ":maven-surefire-event:some-opcode:normal-run:UTF-8" );
encoded = encodeMessage( "some-opcode", "normal-run", "msg" );
assertThat( encoded.toString() )
- .isEqualTo( ":maven:surefire:std:out:some-opcode:normal-run:UTF-8:msg" );
+ .isEqualTo( ":maven-surefire-event:some-opcode:normal-run:UTF-8:msg" );
Stream out = Stream.newStream();
- ForkedChannelEncoder encoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
encoded = encoder.print( "some-opcode", "msg" );
assertThat( encoded.toString() )
- .isEqualTo( ":maven:surefire:std:out:some-opcode:UTF-8:bXNn" );
+ .isEqualTo( ":maven-surefire-event:some-opcode:UTF-8:bXNn" );
encoded = encoder.print( "some-opcode", new String[] { null } );
assertThat( encoded.toString() )
- .isEqualTo( ":maven:surefire:std:out:some-opcode:UTF-8:-" );
+ .isEqualTo( ":maven-surefire-event:some-opcode:UTF-8:-" );
}
@Test
public void testConsoleInfo()
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleInfoLog( "msg" );
+ encoder.consoleInfoLog( "msg" );
String encoded = new String( out.toByteArray(), UTF_8 );
- String expected = ":maven:surefire:std:out:console-info-log:UTF-8:"
+ String expected = ":maven-surefire-event:console-info-log:UTF-8:"
+ encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
+ "\n";
@@ -837,13 +838,13 @@ public class ForkedChannelEncoderTest
public void testConsoleError()
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleErrorLog( "msg" );
+ encoder.consoleErrorLog( "msg" );
String encoded = new String( out.toByteArray(), UTF_8 );
- String expected = ":maven:surefire:std:out:console-error-log:UTF-8:"
+ String expected = ":maven-surefire-event:console-error-log:UTF-8:"
+ encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
+ "\n";
@@ -855,12 +856,12 @@ public class ForkedChannelEncoderTest
public void testConsoleErrorLog1() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleErrorLog( new Exception( "msg" ) );
+ encoder.consoleErrorLog( new Exception( "msg" ) );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .startsWith( ":maven:surefire:std:out:console-error-log:UTF-8:bXNn:-:" );
+ .startsWith( ":maven-surefire-event:console-error-log:UTF-8:bXNn:-:" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -868,12 +869,12 @@ public class ForkedChannelEncoderTest
public void testConsoleErrorLog2() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleErrorLog( "msg2", new Exception( "msg" ) );
+ encoder.consoleErrorLog( "msg2", new Exception( "msg" ) );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .startsWith( ":maven:surefire:std:out:console-error-log:UTF-8:bXNnMg==:-:" );
+ .startsWith( ":maven-surefire-event:console-error-log:UTF-8:bXNnMg==:-:" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -881,7 +882,7 @@ public class ForkedChannelEncoderTest
public void testConsoleErrorLog3() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
@@ -889,10 +890,10 @@ public class ForkedChannelEncoderTest
when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
- forkedChannelEncoder.consoleErrorLog( stackTraceWriter, true );
+ encoder.consoleErrorLog( stackTraceWriter, true );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .startsWith( ":maven:surefire:std:out:console-error-log:UTF-8:MQ==:Mg==:NA==" );
+ .startsWith( ":maven-surefire-event:console-error-log:UTF-8:MQ==:Mg==:NA==" );
assertThat( printedLines.readLine() ).isNull();
}
@@ -900,13 +901,13 @@ public class ForkedChannelEncoderTest
public void testConsoleDebug()
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleDebugLog( "msg" );
+ encoder.consoleDebugLog( "msg" );
String encoded = new String( out.toByteArray(), UTF_8 );
- String expected = ":maven:surefire:std:out:console-debug-log:UTF-8:"
+ String expected = ":maven-surefire-event:console-debug-log:UTF-8:"
+ encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
+ "\n";
@@ -918,13 +919,13 @@ public class ForkedChannelEncoderTest
public void testConsoleWarning()
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.consoleWarningLog( "msg" );
+ encoder.consoleWarningLog( "msg" );
String encoded = new String( out.toByteArray(), UTF_8 );
- String expected = ":maven:surefire:std:out:console-warning-log:UTF-8:"
+ String expected = ":maven-surefire-event:console-warning-log:UTF-8:"
+ encodeBase64String( toArray( UTF_8.encode( "msg" ) ) )
+ "\n";
@@ -936,11 +937,11 @@ public class ForkedChannelEncoderTest
public void testStdOutStream() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.stdOut( "msg", false );
+ encoder.stdOut( "msg", false );
- String expected = ":maven:surefire:std:out:std-out-stream:normal-run:UTF-8:bXNn";
+ String expected = ":maven-surefire-event:std-out-stream:normal-run:UTF-8:bXNn";
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
@@ -953,11 +954,11 @@ public class ForkedChannelEncoderTest
public void testStdOutStreamLn() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.stdOut( "msg", true );
+ encoder.stdOut( "msg", true );
- String expected = ":maven:surefire:std:out:std-out-stream-new-line:normal-run:UTF-8:bXNn";
+ String expected = ":maven-surefire-event:std-out-stream-new-line:normal-run:UTF-8:bXNn";
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
@@ -970,11 +971,11 @@ public class ForkedChannelEncoderTest
public void testStdErrStream() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.stdErr( "msg", false );
+ encoder.stdErr( "msg", false );
- String expected = ":maven:surefire:std:out:std-err-stream:normal-run:UTF-8:bXNn";
+ String expected = ":maven-surefire-event:std-err-stream:normal-run:UTF-8:bXNn";
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
@@ -987,11 +988,11 @@ public class ForkedChannelEncoderTest
public void testStdErrStreamLn() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
- forkedChannelEncoder.stdErr( "msg", true );
+ encoder.stdErr( "msg", true );
- String expected = ":maven:surefire:std:out:std-err-stream-new-line:normal-run:UTF-8:bXNn";
+ String expected = ":maven-surefire-event:std-err-stream-new-line:normal-run:UTF-8:bXNn";
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
@@ -1005,11 +1006,11 @@ public class ForkedChannelEncoderTest
public void shouldCountSameNumberOfSystemProperties() throws IOException
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
Map<String, String> sysProps = ObjectUtils.systemProps();
int expectedSize = sysProps.size();
- forkedChannelEncoder.sendSystemProperties( sysProps );
+ encoder.sendSystemProperties( sysProps );
LineNumberReader printedLines = out.newReader( UTF_8 );
@@ -1017,7 +1018,7 @@ public class ForkedChannelEncoderTest
for ( String line; ( line = printedLines.readLine() ) != null; size++ )
{
assertThat( line )
- .startsWith( ":maven:surefire:std:out:sys-prop:normal-run:UTF-8:" );
+ .startsWith( ":maven-surefire-event:sys-prop:normal-run:UTF-8:" );
}
assertThat( size )
@@ -1029,17 +1030,17 @@ public class ForkedChannelEncoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
- forkedChannelEncoder.sendExitEvent( stackTraceWriter, false );
+ encoder.sendExitEvent( stackTraceWriter, false );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .startsWith( ":maven:surefire:std:out:jvm-exit-error:UTF-8:MQ==:Mg==:Mw==" );
+ .startsWith( ":maven-surefire-event:jvm-exit-error:UTF-8:MQ==:Mg==:Mw==" );
}
@Test
@@ -1047,17 +1048,17 @@ public class ForkedChannelEncoderTest
{
Stream out = Stream.newStream();
- ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( out );
+ LegacyMasterProcessChannelEncoder encoder = new LegacyMasterProcessChannelEncoder( out );
StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class );
when( stackTraceWriter.getThrowable() ).thenReturn( new SafeThrowable( "1" ) );
when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( "2" );
when( stackTraceWriter.writeTraceToString() ).thenReturn( "3" );
when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( "4" );
- forkedChannelEncoder.sendExitEvent( stackTraceWriter, true );
+ encoder.sendExitEvent( stackTraceWriter, true );
LineNumberReader printedLines = out.newReader( UTF_8 );
assertThat( printedLines.readLine() )
- .startsWith( ":maven:surefire:std:out:jvm-exit-error:UTF-8:MQ==:Mg==:NA==" );
+ .startsWith( ":maven-surefire-event:jvm-exit-error:UTF-8:MQ==:Mg==:NA==" );
}
private static class Stream extends PrintStream
diff --git a/surefire-extensions-api/pom.xml b/surefire-extensions-api/pom.xml
index 1e88403..87fcff4 100644
--- a/surefire-extensions-api/pom.xml
+++ b/surefire-extensions-api/pom.xml
@@ -38,11 +38,6 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-component-annotations</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<scope>provided</scope>
@@ -72,33 +67,20 @@
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
- <id>jacoco-instrumentation</id>
- <!--
- phase: the order of the plugins matters and maven-plugin-plugin must be before jacoco plugin
- -->
- <goals>
- <goal>instrument</goal>
- </goals>
- </execution>
- <execution>
- <id>restore-classes</id>
+ <id>jacoco-agent</id>
<goals>
- <goal>restore-instrumented-classes</goal>
+ <goal>prepare-agent</goal>
</goals>
</execution>
</executions>
+ <configuration>
+ <propertyName>jacoco.agent</propertyName>
+ </configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
- <dependencies>
- <dependency>
- <groupId>org.apache.maven.surefire</groupId>
- <artifactId>surefire-shadefire</artifactId>
- <version>3.0.0-M4</version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
- </dependency>
- </dependencies>
<configuration>
- <argLine>${jvm.args.tests}</argLine>
+ <argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
<includes>
<include>**/JUnit4SuiteTest.java</include>
</includes>
@@ -106,8 +88,14 @@
<jacoco-agent.destfile>${project.build.directory}/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-shadefire</artifactId>
+ <version>3.0.0-M4</version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
+ </dependency>
+ </dependencies>
</plugin>
</plugins>
</build>
-
</project>
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderPropertiesAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
similarity index 65%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderPropertiesAware.java
rename to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
index caedb98..a15ed8a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderPropertiesAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CloseableDaemonThread.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,12 +19,19 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import java.util.Map;
+import javax.annotation.Nonnull;
+import java.io.Closeable;
/**
- * @author Kristian Rosenvold
+ * The base thread class used to handle a stream and transform it to an object.
*/
-interface ProviderPropertiesAware
+public abstract class CloseableDaemonThread extends Thread implements Closeable
{
- void setProviderProperties( Map<String, String> providerProperties );
+ protected CloseableDaemonThread( @Nonnull String threadName )
+ {
+ setName( threadName );
+ setDaemon( true );
+ }
+
+ public abstract void disable();
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CommandReader.java
similarity index 62%
copy from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
copy to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CommandReader.java
index eddebed..08fe5ed 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/CommandReader.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +19,28 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
+import org.apache.maven.surefire.booter.Command;
-import java.util.List;
+import java.io.Closeable;
+import java.io.IOException;
/**
- * CLI options in plugin (main) JVM process.
+ * Stream reader returns bytes which ar finally sent to the forked jvm.
*
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
+ * @since 3.0.0-M4
*/
-interface MainCliOptionsAware
+public interface CommandReader extends Closeable
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+
+ /**
+ * Waits for the next command and returns it.
+ *
+ * @return the command, or null if closed
+ */
+ Command readNextCommand() throws IOException;
+ @Override
+ void close();
+ boolean isClosed();
+ void tryFlush() throws IOException;
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/EventHandler.java
similarity index 69%
copy from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
copy to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/EventHandler.java
index eddebed..bcb6c81 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/EventHandler.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +19,14 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
-
-import java.util.List;
+import javax.annotation.Nonnull;
/**
- * CLI options in plugin (main) JVM process.
*
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
*/
-interface MainCliOptionsAware
+public interface EventHandler
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+ // todo here should be Event object as POJO which separates physical stream representation from the independent
+ // todo Event parser in ForkClient. So the parser should be part of ForkChannel implementation.
+ void handleEvent( @Nonnull String event );
}
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
new file mode 100644
index 0000000..baeae00
--- /dev/null
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkChannel.java
@@ -0,0 +1,138 @@
+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.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;
+
+/**
+ * It's a session object used only by a particular Thread in ForkStarter
+ * and dedicated forked JVM {@link #getForkChannelId()}. It represents a server.
+ * <br>
+ * <br>
+ * It opens the channel via {@link #openChannel()}, provides a connection string {@link #getForkNodeConnectionString()}
+ * used by the client in the JVM, binds event and command handlers.
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 3.0.0-M5
+ */
+public abstract class ForkChannel implements Closeable
+{
+ private final int forkChannelId;
+
+ /**
+ * @param forkChannelId the index of the forked JVM, from 1 to N.
+ */
+ protected ForkChannel( int forkChannelId )
+ {
+ this.forkChannelId = forkChannelId;
+ }
+
+ public abstract void openChannel() throws IOException;
+
+ /**
+ * This is server related class, which if binds to a TCP port, determines the connection string for the client.
+ *
+ * @return a connection string utilized by the client in the fork JVM
+ */
+ public abstract String getForkNodeConnectionString();
+
+ /**
+ * Determines which one of the two <em>bindCommandReader-s</em> to call in <em>ForkStarter</em>.
+ * Can be called anytime.
+ *
+ * @return If {@code true}, calling {@link #bindCommandReader(CommandReader, WritableByteChannel)} by
+ * <em>ForkStarter</em> and {@link #bindCommandReader(CommandReader)} throws {@link UnsupportedOperationException}.
+ * If {@code false}, then opposite.
+ */
+ public abstract boolean useStdIn();
+
+ /**
+ * Determines which one of the two <em>bindEventHandler-s</em> to call in <em>ForkStarter</em>.
+ * Can be called anytime.
+ *
+ * @return If {@code true}, the {@link #bindEventHandler(StreamConsumer, ReadableByteChannel, CountdownCloseable)}
+ * is called in <em>ForkStarter</em> and {@link #bindEventHandler(StreamConsumer)} throws
+ * {@link UnsupportedOperationException}.
+ * If {@code false}, then opposite.
+ */
+ public abstract boolean useStdOut();
+
+ /**
+ * Binds command handler to the channel.
+ *
+ * @param commands command reader, see {@link CommandReader#readNextCommand()}
+ * @param stdIn the standard input stream of the JVM to write the encoded commands into it
+ * @return the thread instance to start up in order to stream out the data
+ * @throws IOException if an error in the fork channel
+ */
+ public abstract CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands,
+ @Nonnull WritableByteChannel stdIn )
+ throws IOException;
+
+ /**
+ * Binds command handler to the channel.
+ *
+ * @param commands command reader, see {@link CommandReader#readNextCommand()}
+ * @return the thread instance to start up in order to stream out the data
+ * @throws IOException if an error in the fork channel
+ */
+ public abstract CloseableDaemonThread bindCommandReader( @Nonnull CommandReader commands )
+ throws IOException;
+
+ /**
+ *
+ * @param consumer event consumer
+ * @param stdOut the standard output stream of the JVM
+ * @param countdownCloseable count down of the final call of {@link Closeable#close()}
+ * @return the thread instance to start up in order to stream out the data
+ * @throws IOException if an error in the fork channel
+ */
+ public abstract CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer,
+ @Nonnull ReadableByteChannel stdOut,
+ @Nonnull CountdownCloseable countdownCloseable )
+ throws IOException;
+
+ /**
+ * Binds event handler to the channel.
+ *
+ * @param consumer event consumer
+ * @return the thread instance to start up in order to stream out the data
+ * @throws IOException if an error in the fork channel
+ */
+ public abstract CloseableDaemonThread bindEventHandler( @Nonnull StreamConsumer consumer )
+ throws IOException;
+
+ /**
+ * The index of the fork.
+ *
+ * @return the index of the forked JVM, from 1 to N.
+ */
+ protected final int getForkChannelId()
+ {
+ return forkChannelId;
+ }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
similarity index 65%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
rename to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
index eddebed..db0e7b8 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MainCliOptionsAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/ForkNodeFactory.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,17 +19,21 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.cli.CommandLineOption;
-
-import java.util.List;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import java.io.IOException;
/**
- * CLI options in plugin (main) JVM process.
- *
* @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
+ * @since 3.0.0-M5
*/
-interface MainCliOptionsAware
+public interface ForkNodeFactory
{
- void setMainCliOptions( List<CommandLineOption> mainCliOptions );
+ /**
+ * Opens and closes the channel.
+ *
+ * @return specific implementation of the communication channel
+ * @throws IOException if cannot open the channel
+ */
+ @Nonnull ForkChannel createForkChannel( @Nonnegative int forkChannelId ) throws IOException;
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TestRequestAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdErrStreamLine.java
similarity index 78%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/TestRequestAware.java
rename to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdErrStreamLine.java
index 3e98b92..f0ae082 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TestRequestAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdErrStreamLine.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,12 +19,11 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.testset.TestRequest;
+import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
/**
- * @author Kristian Rosenvold
+ * The line handler of forked process standard-error.
*/
-interface TestRequestAware
+public interface StdErrStreamLine extends StreamConsumer
{
- void setTestRequest( TestRequest testSuiteDefinition );
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireClassLoadersAware.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdOutStreamLine.java
similarity index 82%
rename from surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireClassLoadersAware.java
rename to surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdOutStreamLine.java
index c2f5d99..f615764 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/SurefireClassLoadersAware.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/StdOutStreamLine.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.booter;
+package org.apache.maven.surefire.extensions;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,9 +20,9 @@ package org.apache.maven.surefire.booter;
*/
/**
- * @author Kristian Rosenvold
+ * The line handler of forked process standard-output.
*/
-interface SurefireClassLoadersAware
+public interface StdOutStreamLine
{
- void setClassLoaders( ClassLoader testClassLoader );
+ void handleLine( String line );
}
diff --git a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/CountdownCloseable.java b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/CountdownCloseable.java
index 9818ec9..4bb5272 100644
--- a/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/CountdownCloseable.java
+++ b/surefire-extensions-api/src/main/java/org/apache/maven/surefire/extensions/util/CountdownCloseable.java
@@ -20,7 +20,6 @@ package org.apache.maven.surefire.extensions.util;
*/
import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
import java.io.Closeable;
import java.io.IOException;
@@ -33,8 +32,12 @@ public final class CountdownCloseable
private final Closeable closeable;
private volatile int countdown;
- public CountdownCloseable( @Nonnull Closeable closeable, @Nonnegative int countdown )
+ public CountdownCloseable( Closeable closeable, @Nonnegative int countdown )
{
+ if ( closeable == null && countdown > 0 )
+ {
+ throw new IllegalStateException( "closeable is null and countdown is " + countdown );
+ }
this.closeable = closeable;
this.countdown = countdown;
}
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 ca8eb8e..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
@@ -19,10 +19,13 @@ package org.apache.maven.surefire.extensions.util;
* under the License.
*/
+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.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NonWritableChannelException;
@@ -31,33 +34,35 @@ import java.nio.channels.WritableByteChannel;
/**
*
*/
-public class StreamFeeder extends Thread implements Closeable
+public class StreamFeeder extends CloseableDaemonThread
{
private final WritableByteChannel channel;
- private final InputStream is;
+ private final CommandReader commandReader;
private volatile boolean disabled;
private volatile Throwable exception;
- public StreamFeeder( @Nonnull String threadName, @Nonnull WritableByteChannel channel, @Nonnull InputStream is )
+ public StreamFeeder( @Nonnull String threadName, @Nonnull WritableByteChannel channel,
+ @Nonnull CommandReader commandReader )
{
- setName( threadName );
- setDaemon( true );
+ super( threadName );
this.channel = channel;
- this.is = is;
+ this.commandReader = commandReader;
}
@Override
+ @SuppressWarnings( "checkstyle:innerassignment" )
public void run()
{
try ( WritableByteChannel c = channel )
{
- for ( int data = is.read(); data != -1; data = is.read() )
+ for ( Command cmd; ( cmd = commandReader.readNextCommand() ) != null; )
{
if ( !disabled )
{
- // todo use CommandReader interface instead of InputStream. Then we would write ByteBuffer.
- c.write( ByteBuffer.wrap( new byte[] {(byte) data} ) );
+ MasterProcessCommand cmdType = cmd.getCommandType();
+ byte[] data = cmdType.hasDataType() ? cmdType.encode( cmd.getData() ) : cmdType.encode();
+ c.write( ByteBuffer.wrap( data ) );
}
}
}
diff --git a/surefire-extensions-api/src/test/java/org/apache/maven/surefire/extensions/util/CommandlineExecutorTest.java b/surefire-extensions-api/src/test/java/org/apache/maven/surefire/extensions/util/CommandlineExecutorTest.java
index fd99059..fc919d2 100644
--- a/surefire-extensions-api/src/test/java/org/apache/maven/surefire/extensions/util/CommandlineExecutorTest.java
+++ b/surefire-extensions-api/src/test/java/org/apache/maven/surefire/extensions/util/CommandlineExecutorTest.java
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.extensions.util;
* under the License.
*/
+import org.apache.maven.surefire.booter.Command;
+import org.apache.maven.surefire.extensions.CommandReader;
import org.apache.maven.surefire.shared.utils.cli.Commandline;
import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;
import org.junit.After;
@@ -26,7 +28,6 @@ import org.junit.Before;
import org.junit.Test;
import java.io.Closeable;
-import java.io.InputStream;
import java.nio.file.Paths;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
@@ -90,15 +91,33 @@ public class CommandlineExecutorTest
exec = new CommandlineExecutor( cli, countdownCloseable );
streams = exec.execute();
StreamConsumer consumer = mock( StreamConsumer.class );
- InputStream is = new InputStream()
+ CommandReader commandReader = new CommandReader()
{
@Override
- public int read()
+ public Command readNextCommand()
{
- return -1;
+ return null;
+ }
+
+ @Override
+ public void close()
+ {
+
+ }
+
+ @Override
+ public boolean isClosed()
+ {
+ return false;
+ }
+
+ @Override
+ public void tryFlush()
+ {
+
}
};
- StreamFeeder in = new StreamFeeder( "std-in-fork-1", streams.getStdInChannel(), is );
+ StreamFeeder in = new StreamFeeder( "std-in-fork-1", streams.getStdInChannel(), commandReader );
in.start();
out = new LineConsumerThread( "std-out-fork-1", streams.getStdOutChannel(), consumer, countdownCloseable );
out.start();
diff --git a/surefire-extensions-spi/pom.xml b/surefire-extensions-spi/pom.xml
new file mode 100644
index 0000000..95cf3d9
--- /dev/null
+++ b/surefire-extensions-spi/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>surefire-extensions-spi</artifactId>
+ <name>Surefire Extensions SPI</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.surefire</groupId>
+ <artifactId>surefire-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/surefire-extensions-spi/src/main/java/org/apache/maven/surefire/spi/MasterProcessChannelProcessorFactory.java b/surefire-extensions-spi/src/main/java/org/apache/maven/surefire/spi/MasterProcessChannelProcessorFactory.java
new file mode 100644
index 0000000..989a52d
--- /dev/null
+++ b/surefire-extensions-spi/src/main/java/org/apache/maven/surefire/spi/MasterProcessChannelProcessorFactory.java
@@ -0,0 +1,62 @@
+package org.apache.maven.surefire.spi;
+
+/*
+ * 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.providerapi.MasterProcessChannelDecoder;
+import org.apache.maven.surefire.providerapi.MasterProcessChannelEncoder;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * The SPI interface, a factory of an encoder and a decoder.
+ */
+public interface MasterProcessChannelProcessorFactory extends Closeable
+{
+ /**
+ * Evaluates the {@code channelConfig}.
+ *
+ * @param channelConfig a connection string used by the fork JVM
+ * @return {@code true} if {@code channelConfig} is applicable and thus this SPI is eligible in the fork
+ */
+ boolean canUse( String channelConfig );
+
+ /**
+ * Open a new connection.
+ *
+ * @param channelConfig e.g. "pipe://3" or "tcp://127.0.0.1:65035"
+ * @throws IOException if cannot connect
+ */
+ void connect( String channelConfig ) throws IOException;
+
+ /**
+ * Decoder factory method.
+ *
+ * @return a new instance of decoder
+ */
+ MasterProcessChannelDecoder createDecoder() throws IOException;
+
+ /**
+ * Encoder factory method.
+ *
+ * @return a new instance of encoder
+ */
+ MasterProcessChannelEncoder createEncoder() throws IOException;
+}
diff --git a/surefire-logger-api/pom.xml b/surefire-logger-api/pom.xml
index bcac4ad..559e829 100644
--- a/surefire-logger-api/pom.xml
+++ b/surefire-logger-api/pom.xml
@@ -87,7 +87,7 @@
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-shadefire</artifactId>
-<!-- <version>3.0.0-M4</version>-->
+<!-- <version>3.0.0-M3</version>-->
<version>3.0.0-M3</version> <!-- ${shadedVersion}, but resolved due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
</dependency>
</dependencies>
diff --git a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
index b964933..9e5efad 100644
--- a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
+++ b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.junit4;
*/
import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.CommandListener;
-import org.apache.maven.surefire.booter.CommandReader;
+import org.apache.maven.surefire.providerapi.CommandChainReader;
+import org.apache.maven.surefire.providerapi.CommandListener;
import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
import org.apache.maven.surefire.common.junit4.JUnit4TestChecker;
import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
@@ -52,7 +52,6 @@ import java.util.Set;
import static java.lang.reflect.Modifier.isAbstract;
import static java.lang.reflect.Modifier.isInterface;
-import static org.apache.maven.surefire.booter.CommandReader.getReader;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.createMatchAnyDescriptionFilter;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.generateFailingTestDescriptions;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
@@ -92,14 +91,14 @@ public class JUnit4Provider
private final int rerunFailingTestsCount;
- private final CommandReader commandsReader;
+ private final CommandChainReader commandsReader;
private TestsToRun testsToRun;
public JUnit4Provider( ProviderParameters bootParams )
{
// don't start a thread in CommandReader while we are in in-plugin process
- commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
+ commandsReader = bootParams.isInsideFork() ? bootParams.getCommandReader() : null;
providerParameters = bootParams;
testClassLoader = bootParams.getTestClassLoader();
scanResult = bootParams.getScanResult();
diff --git a/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java b/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
index b949baa..c03ea7e 100644
--- a/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
+++ b/surefire-providers/surefire-junit4/src/test/java/org/apache/maven/surefire/junit4/JUnit4ProviderTest.java
@@ -50,7 +50,7 @@ public class JUnit4ProviderTest
private JUnit4Provider getJUnit4Provider()
{
- BaseProviderFactory providerParameters = new BaseProviderFactory( null, true );
+ BaseProviderFactory providerParameters = new BaseProviderFactory( true );
providerParameters.setProviderProperties( new HashMap<String, String>() );
providerParameters.setClassLoaders( getClass().getClassLoader() );
providerParameters.setTestRequest( new TestRequest( null, null, null ) );
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
index 7c74e8b..daabb60 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.junitcore;
*/
import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.CommandListener;
-import org.apache.maven.surefire.booter.CommandReader;
+import org.apache.maven.surefire.providerapi.CommandChainReader;
+import org.apache.maven.surefire.providerapi.CommandListener;
import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
import org.apache.maven.surefire.common.junit4.Notifier;
@@ -46,7 +46,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import static org.apache.maven.surefire.booter.CommandReader.getReader;
import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.generateFailingTestDescriptions;
import static org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory.createCustomListeners;
import static org.apache.maven.surefire.common.junit4.Notifier.pureNotifier;
@@ -82,14 +81,14 @@ public class JUnitCoreProvider
private final TestListResolver testResolver;
- private final CommandReader commandsReader;
+ private final CommandChainReader commandsReader;
private TestsToRun testsToRun;
public JUnitCoreProvider( ProviderParameters bootParams )
{
// don't start a thread in CommandReader while we are in in-plugin process
- commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
+ commandsReader = bootParams.isInsideFork() ? bootParams.getCommandReader() : null;
providerParameters = bootParams;
testClassLoader = bootParams.getTestClassLoader();
scanResult = bootParams.getScanResult();
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
index 8859c19..66f0b85 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
@@ -110,7 +110,8 @@ public class Surefire746Test
public void surefireIsConfused_ByMultipleIgnore_OnClassLevel() throws Exception
{
ReporterFactory reporterFactory = JUnitCoreTester.defaultNoXml();
- BaseProviderFactory providerParameters = new BaseProviderFactory( reporterFactory, true );
+ BaseProviderFactory providerParameters = new BaseProviderFactory( true );
+ providerParameters.setReporterFactory( reporterFactory );
providerParameters.setReporterConfiguration( new ReporterConfiguration( new File( "" ), false ) );
Map<String, String> junitProps = new HashMap<>();
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
index 14e103a..a8a5fb7 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.testng;
*/
import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.CommandListener;
-import org.apache.maven.surefire.booter.CommandReader;
+import org.apache.maven.surefire.providerapi.CommandChainReader;
+import org.apache.maven.surefire.providerapi.CommandListener;
import org.apache.maven.surefire.cli.CommandLineOption;
import org.apache.maven.surefire.providerapi.AbstractProvider;
import org.apache.maven.surefire.providerapi.ProviderParameters;
@@ -43,7 +43,6 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
-import static org.apache.maven.surefire.booter.CommandReader.getReader;
import static org.apache.maven.surefire.report.ConsoleOutputCapture.startCapture;
import static org.apache.maven.surefire.testset.TestListResolver.getEmptyTestListResolver;
import static org.apache.maven.surefire.testset.TestListResolver.optionallyWildcardFilter;
@@ -71,14 +70,14 @@ public class TestNGProvider
private final List<CommandLineOption> mainCliOptions;
- private final CommandReader commandsReader;
+ private final CommandChainReader commandsReader;
private TestsToRun testsToRun;
public TestNGProvider( ProviderParameters bootParams )
{
// don't start a thread in CommandReader while we are in in-plugin process
- commandsReader = bootParams.isInsideFork() ? getReader().setShutdown( bootParams.getShutdown() ) : null;
+ commandsReader = bootParams.isInsideFork() ? bootParams.getCommandReader() : null;
providerParameters = bootParams;
testClassLoader = bootParams.getTestClassLoader();
runOrderCalculator = bootParams.getRunOrderCalculator();
diff --git a/surefire-shadefire/pom.xml b/surefire-shadefire/pom.xml
index 6ade032..1d2c468 100644
--- a/surefire-shadefire/pom.xml
+++ b/surefire-shadefire/pom.xml
@@ -73,8 +73,10 @@
<configuration>
<artifactSet>
<includes>
+ <include>org.apache.maven.surefire:surefire-shared-utils</include>
<include>org.apache.maven.surefire:surefire-logger-api</include>
<include>org.apache.maven.surefire:surefire-api</include>
+ <include>org.apache.maven.surefire:surefire-extensions-spi</include>
<include>org.apache.maven.surefire:surefire-booter</include>
<include>org.apache.maven.surefire:common-junit3</include>
<include>org.apache.maven.surefire:surefire-junit3</include>