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:46:44 UTC
[maven-surefire] 01/02: [SUREFIRE-1658] TCP/IP Channel for forked
Surefire JVM. Extensions API and SPI. Polymorphism for remote and local
process communication.
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 d98b703174ae03219321ad405d9dfe71ce79cfb7
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 5340988..ccd2646 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 0c049d6..ade1494 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
@@ -31,7 +31,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;
@@ -182,13 +182,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;
}
- String[] tokens = line.substring( MAGIC_NUMBER.length() ).split( ":" );
+ String[] tokens = line.substring( MAGIC_NUMBER_DELIMITED.length() ).split( ":" );
int index = -1;
String opcode = tokens.length > ++index ? tokens[index] : null;
ForkedProcessEvent event = opcode == null ? null : EVENTS.get( opcode );
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 9b0d9c9..ef28350 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() );
@@ -336,11 +336,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() );
@@ -356,8 +356,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();
@@ -374,8 +374,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();
@@ -394,8 +394,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();
@@ -413,9 +413,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();
@@ -432,8 +432,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();
@@ -450,8 +450,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();
@@ -467,8 +467,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();
@@ -484,8 +484,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();
@@ -501,8 +501,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();
@@ -518,8 +518,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();
@@ -535,8 +535,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();
@@ -552,8 +552,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();
@@ -569,8 +569,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();
@@ -597,22 +597,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();
@@ -714,10 +714,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 5340988..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, pull_request]
-
-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>