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 2018/09/06 23:35:31 UTC
[maven-surefire] 02/02: [SUREFIRE-1565] Surefire should support
parameterized reportsDirectory
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch INV1561
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
commit 232d260cad3091f3315f880a061efdf7c03d9c65
Author: Tibor17 <ti...@apache.org>
AuthorDate: Fri Sep 7 01:35:21 2018 +0200
[SUREFIRE-1565] Surefire should support parameterized reportsDirectory
---
.../plugin/surefire/AbstractSurefireMojo.java | 20 +---
.../surefire/StartupReportConfiguration.java | 28 ++---
.../maven/plugin/surefire/SurefireHelper.java | 49 +++++++++
.../surefire/booterclient/BooterSerializer.java | 6 +-
.../booterclient/DefaultForkConfiguration.java | 16 +--
.../plugin/surefire/booterclient/ForkStarter.java | 64 ++++++-----
.../surefire/booterclient/output/ForkClient.java | 18 ++--
.../output/InPluginProcessDumpSingleton.java | 57 ++++++----
.../output/NativeStdErrStreamConsumer.java | 3 +-
.../surefire/report/ConsoleOutputFileReporter.java | 38 ++++---
.../surefire/report/DefaultReporterFactory.java | 26 ++---
.../surefire/report/NullConsoleOutputReceiver.java | 59 ----------
.../maven/plugin/surefire/SurefireHelperTest.java | 26 ++++-
...ooterDeserializerProviderConfigurationTest.java | 2 +-
...BooterDeserializerStartupConfigurationTest.java | 4 +-
.../booterclient/ForkingRunListenerTest.java | 10 +-
.../report/ConsoleOutputFileReporterTest.java | 8 +-
maven-surefire-plugin/src/site/fml/faq.fml | 1 +
.../maven/surefire/booter/DumpErrorSingleton.java | 15 ++-
.../surefire/util/internal/DumpFileUtils.java | 8 +-
.../apache/maven/surefire/booter/ForkedBooter.java | 3 +-
.../maven/surefire/its/fixture/TestFile.java | 11 +-
.../jiras/Surefire1535TestNGParallelSuitesIT.java | 119 +++++++++++++++++++--
.../surefire-1535-parallel-testng/pom.xml | 48 ++++-----
.../src/test/java/it/ParallelTest1.java | 1 +
.../src/test/java/it/ParallelTest2.java | 1 +
26 files changed, 382 insertions(+), 259 deletions(-)
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index fa19214..cc3dff9 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
@@ -120,6 +120,7 @@ import static java.util.Collections.singletonMap;
import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
import static org.apache.maven.plugin.surefire.util.DependencyScanner.filter;
+import static org.apache.maven.plugin.surefire.SurefireHelper.replaceThreadNumberPlaceholders;
import static org.apache.maven.shared.utils.StringUtils.capitalizeFirstLetter;
import static org.apache.maven.shared.utils.StringUtils.isEmpty;
import static org.apache.maven.shared.utils.StringUtils.isNotBlank;
@@ -769,19 +770,6 @@ public abstract class AbstractSurefireMojo
private int effectiveForkCount = -1;
- /**
- * The placeholder that is replaced by the executing thread's running number. The thread number
- * range starts with 1
- * Deprecated.
- */
- public static final String THREAD_NUMBER_PLACEHOLDER = "${surefire.threadNumber}";
-
- /**
- * The placeholder that is replaced by the executing fork's running number. The fork number
- * range starts with 1
- */
- public static final String FORK_NUMBER_PLACEHOLDER = "${surefire.forkNumber}";
-
protected abstract String getPluginName();
protected abstract int getRerunFailingTestsCount();
@@ -1215,16 +1203,12 @@ public abstract class AbstractSurefireMojo
SurefireProperties effectiveSystemProperties, int threadNumber )
{
SurefireProperties filteredProperties = new SurefireProperties( ( KeyValueSource) effectiveSystemProperties );
- String threadNumberString = String.valueOf( threadNumber );
for ( Entry<Object, Object> entry : effectiveSystemProperties.entrySet() )
{
if ( entry.getValue() instanceof String )
{
String value = (String) entry.getValue();
- value = value.replace( THREAD_NUMBER_PLACEHOLDER, threadNumberString );
- value = value.replace( FORK_NUMBER_PLACEHOLDER, threadNumberString );
-
- filteredProperties.put( entry.getKey(), value );
+ filteredProperties.put( entry.getKey(), replaceThreadNumberPlaceholders( value, threadNumber ) );
}
}
return filteredProperties;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/StartupReportConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/StartupReportConfiguration.java
index caf0db3..26d4d18 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/StartupReportConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/StartupReportConfiguration.java
@@ -35,6 +35,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import static org.apache.maven.plugin.surefire.SurefireHelper.replaceForkThreadsInPath;
import static org.apache.maven.plugin.surefire.report.ConsoleReporter.BRIEF;
import static org.apache.maven.plugin.surefire.report.ConsoleReporter.PLAIN;
import static org.apache.commons.lang3.StringUtils.trimToNull;
@@ -47,10 +48,6 @@ import static org.apache.commons.lang3.StringUtils.trimToNull;
*/
public final class StartupReportConfiguration
{
- public static final String BRIEF_REPORT_FORMAT = BRIEF;
-
- public static final String PLAIN_REPORT_FORMAT = PLAIN;
-
private final PrintStream originalSystemOut;
private final PrintStream originalSystemErr;
@@ -151,31 +148,31 @@ public final class StartupReportConfiguration
return rerunFailingTestsCount;
}
- public StatelessXmlReporter instantiateStatelessXmlReporter()
+ public StatelessXmlReporter instantiateStatelessXmlReporter( Integer forkNumber )
{
return isDisableXmlReport()
? null
- : new StatelessXmlReporter( reportsDirectory, reportNameSuffix, trimStackTrace, rerunFailingTestsCount,
- testClassMethodRunHistory, xsdSchemaLocation );
+ : new StatelessXmlReporter( resolveReportsDirectory( forkNumber ), reportNameSuffix, trimStackTrace,
+ rerunFailingTestsCount, testClassMethodRunHistory, xsdSchemaLocation );
}
- public FileReporter instantiateFileReporter()
+ public FileReporter instantiateFileReporter( Integer forkNumber )
{
return isUseFile() && isBriefOrPlainFormat()
- ? new FileReporter( reportsDirectory, getReportNameSuffix(), encoding )
+ ? new FileReporter( resolveReportsDirectory( forkNumber ), reportNameSuffix, encoding )
: null;
}
public boolean isBriefOrPlainFormat()
{
String fmt = getReportFormat();
- return BRIEF_REPORT_FORMAT.equals( fmt ) || PLAIN_REPORT_FORMAT.equals( fmt );
+ return BRIEF.equals( fmt ) || PLAIN.equals( fmt );
}
- public TestcycleConsoleOutputReceiver instantiateConsoleOutputFileReporter()
+ public TestcycleConsoleOutputReceiver instantiateConsoleOutputFileReporter( Integer forkNumber )
{
return isRedirectTestOutputToFile()
- ? new ConsoleOutputFileReporter( reportsDirectory, getReportNameSuffix() )
+ ? new ConsoleOutputFileReporter( resolveReportsDirectory( forkNumber ), reportNameSuffix, forkNumber )
: new DirectConsoleOutput( originalSystemOut, originalSystemErr );
}
@@ -183,7 +180,7 @@ public final class StartupReportConfiguration
{
if ( statisticsReporter == null )
{
- statisticsReporter = requiresRunHistory ? new StatisticsReporter( getStatisticsFile() ) : null;
+ statisticsReporter = requiresRunHistory ? new StatisticsReporter( statisticsFile ) : null;
}
return statisticsReporter;
}
@@ -217,4 +214,9 @@ public final class StartupReportConfiguration
{
return encoding;
}
+
+ private File resolveReportsDirectory( Integer forkNumber )
+ {
+ return forkNumber == null ? reportsDirectory : replaceForkThreadsInPath( reportsDirectory, forkNumber );
+ }
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
index dd29cb4..44dbdd4 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireHelper.java
@@ -29,10 +29,14 @@ import org.apache.maven.surefire.suite.RunResult;
import org.apache.maven.surefire.testset.TestSetFailedException;
import org.apache.maven.surefire.util.internal.DumpFileUtils;
+import javax.annotation.Nonnull;
+import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Deque;
+import java.util.LinkedList;
import java.util.List;
import static java.util.Collections.unmodifiableList;
@@ -54,8 +58,14 @@ public final class SurefireHelper
public static final String DUMP_FILE_PREFIX = DUMP_FILE_DATE + "-jvmRun";
+ public static final String DUMP_FILENAME_FORMATTER = DUMP_FILE_PREFIX + "%d" + DUMP_FILE_EXT;
+
public static final String DUMPSTREAM_FILENAME_FORMATTER = DUMP_FILE_PREFIX + "%d" + DUMPSTREAM_FILE_EXT;
+ public static final String DUMPSTREAM_FILENAME = DUMP_FILE_DATE + DUMPSTREAM_FILE_EXT;
+
+ public static final String DUMP_FILENAME = DUMP_FILE_DATE + DUMP_FILE_EXT;
+
/**
* The maximum path that does not require long path prefix on Windows.<br>
* See {@code sun/nio/fs/WindowsPath} in
@@ -71,12 +81,26 @@ public final class SurefireHelper
private static final String[] DUMP_FILES_PRINT =
{
+ "[date]" + DUMP_FILE_EXT,
"[date]-jvmRun[N]" + DUMP_FILE_EXT,
"[date]" + DUMPSTREAM_FILE_EXT,
"[date]-jvmRun[N]" + DUMPSTREAM_FILE_EXT
};
/**
+ * The placeholder that is replaced by the executing thread's running number. The thread number
+ * range starts with 1
+ * Deprecated.
+ */
+ private static final String THREAD_NUMBER_PLACEHOLDER = "${surefire.threadNumber}";
+
+ /**
+ * The placeholder that is replaced by the executing fork's running number. The fork number
+ * range starts with 1
+ */
+ private static final String FORK_NUMBER_PLACEHOLDER = "${surefire.forkNumber}";
+
+ /**
* Do not instantiate.
*/
private SurefireHelper()
@@ -84,6 +108,31 @@ public final class SurefireHelper
throw new IllegalAccessError( "Utility class" );
}
+ @Nonnull
+ public static String replaceThreadNumberPlaceholders( @Nonnull String argLine, int threadNumber )
+ {
+ String threadNumberAsString = String.valueOf( threadNumber );
+ return argLine.replace( THREAD_NUMBER_PLACEHOLDER, threadNumberAsString )
+ .replace( FORK_NUMBER_PLACEHOLDER, threadNumberAsString );
+ }
+
+ public static File replaceForkThreadsInPath( File path, int replacement )
+ {
+ Deque<String> dirs = new LinkedList<String>();
+ File root = path;
+ while ( !root.exists() )
+ {
+ dirs.addFirst( replaceThreadNumberPlaceholders( root.getName(), replacement ) );
+ root = root.getParentFile();
+ }
+ File replacedPath = root;
+ for ( String dir : dirs )
+ {
+ replacedPath = new File( replacedPath, dir );
+ }
+ return replacedPath;
+ }
+
public static String[] getDumpFilesToPrint()
{
return DUMP_FILES_PRINT.clone();
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 9c501db..fe72fce 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
@@ -39,6 +39,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.List;
+import static org.apache.maven.plugin.surefire.SurefireHelper.replaceForkThreadsInPath;
import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CHILD_DELEGATION;
import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CLASSPATH;
import static org.apache.maven.surefire.booter.AbstractPathConfiguration.ENABLE_ASSERTIONS;
@@ -99,7 +100,7 @@ class BooterSerializer
*/
File serialize( KeyValueSource sourceProperties, ProviderConfiguration booterConfiguration,
StartupConfiguration providerConfiguration, Object testSet, boolean readTestsFromInStream,
- Long pid )
+ Long pid, int forkNumber )
throws IOException
{
SurefireProperties properties = new SurefireProperties( sourceProperties );
@@ -159,8 +160,9 @@ class BooterSerializer
ReporterConfiguration reporterConfiguration = booterConfiguration.getReporterConfiguration();
boolean rep = reporterConfiguration.isTrimStackTrace();
+ File reportsDirectory = replaceForkThreadsInPath( reporterConfiguration.getReportsDirectory(), forkNumber );
properties.setProperty( ISTRIMSTACKTRACE, rep );
- properties.setProperty( REPORTSDIRECTORY, reporterConfiguration.getReportsDirectory() );
+ properties.setProperty( REPORTSDIRECTORY, reportsDirectory );
ClassLoaderConfiguration classLoaderConfig = providerConfiguration.getClassLoaderConfiguration();
properties.setProperty( USESYSTEMCLASSLOADER, toString( classLoaderConfig.isUseSystemClassLoader() ) );
properties.setProperty( USEMANIFESTONLYJAR, toString( classLoaderConfig.isUseManifestOnlyJar() ) );
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 c35d01c..591491d 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
@@ -37,9 +37,9 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
-import static org.apache.maven.plugin.surefire.AbstractSurefireMojo.FORK_NUMBER_PLACEHOLDER;
-import static org.apache.maven.plugin.surefire.AbstractSurefireMojo.THREAD_NUMBER_PLACEHOLDER;
+import static org.apache.maven.plugin.surefire.SurefireHelper.replaceForkThreadsInPath;
import static org.apache.maven.plugin.surefire.util.Relocator.relocate;
+import static org.apache.maven.plugin.surefire.SurefireHelper.replaceThreadNumberPlaceholders;
import static org.apache.maven.surefire.booter.Classpath.join;
/**
@@ -169,7 +169,7 @@ public abstract class DefaultForkConfiguration
private File getWorkingDirectory( int forkNumber )
throws SurefireBooterForkException
{
- File cwd = new File( replaceThreadNumberPlaceholder( getWorkingDirectory().getAbsolutePath(), forkNumber ) );
+ File cwd = replaceForkThreadsInPath( getWorkingDirectory(), forkNumber );
if ( !cwd.exists() && !cwd.mkdirs() )
{
@@ -184,14 +184,6 @@ public abstract class DefaultForkConfiguration
return cwd;
}
- @Nonnull
- private static String replaceThreadNumberPlaceholder( @Nonnull String argLine, int threadNumber )
- {
- String threadNumberAsString = String.valueOf( threadNumber );
- return argLine.replace( THREAD_NUMBER_PLACEHOLDER, threadNumberAsString )
- .replace( FORK_NUMBER_PLACEHOLDER, threadNumberAsString );
- }
-
/**
* Replaces expressions <pre>@{property-name}</pre> with the corresponding properties
* from the model. This allows late evaluation of property values when the plugin is executed (as compared
@@ -331,7 +323,7 @@ public abstract class DefaultForkConfiguration
private String newJvmArgLine( int forks )
{
String interpolatedArgs = stripNewLines( interpolateArgLineWithPropertyExpressions() );
- String argsWithReplacedForkNumbers = replaceThreadNumberPlaceholder( interpolatedArgs, forks );
+ String argsWithReplacedForkNumbers = replaceThreadNumberPlaceholders( interpolatedArgs, forks );
return extendJvmArgLine( argsWithReplacedForkNumbers );
}
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 44b5bff..74645a4 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
@@ -197,8 +197,9 @@ public class ForkStarter
// if tests failed, but if this does not happen then printing warning to console is the only way to
// inform the users.
String msg = "ForkStarter IOException: " + e.getLocalizedMessage() + ".";
+ File reportsDir = defaultReporterFactory.getReportsDirectory();
File dump = InPluginProcessDumpSingleton.getSingleton()
- .dumpException( e, msg, defaultReporterFactory, jvmRun );
+ .dumpStreamException( e, msg, reportsDir, jvmRun );
log.warning( msg + " See the dump file " + dump.getAbsolutePath() );
}
}
@@ -264,21 +265,25 @@ public class ForkStarter
private RunResult run( SurefireProperties effectiveSystemProperties, Map<String, String> providerProperties )
throws SurefireBooterForkException
{
- DefaultReporterFactory forkedReporterFactory = new DefaultReporterFactory( startupReportConfiguration, log );
- defaultReporterFactories.add( forkedReporterFactory );
TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
PropertiesWrapper props = new PropertiesWrapper( providerProperties );
TestLessInputStream stream = builder.build();
- ForkClient forkClient = new ForkClient( forkedReporterFactory, stream, log, new AtomicBoolean() );
Thread shutdown = createImmediateShutdownHookThread( builder, providerConfiguration.getShutdown() );
ScheduledFuture<?> ping = triggerPingTimerForShutdown( builder );
+ int forkNumber = drawNumber();
try
{
addShutDownHook( shutdown );
- return fork( null, props, forkClient, effectiveSystemProperties, stream, false );
+ DefaultReporterFactory forkedReporterFactory =
+ new DefaultReporterFactory( startupReportConfiguration, log, forkNumber );
+ defaultReporterFactories.add( forkedReporterFactory );
+ ForkClient forkClient =
+ new ForkClient( forkedReporterFactory, stream, log, new AtomicBoolean(), forkNumber );
+ return fork( null, props, forkClient, effectiveSystemProperties, forkNumber, stream, false );
}
finally
{
+ returnNumber( forkNumber );
removeShutdownHook( shutdown );
ping.cancel( true );
builder.removeStream( stream );
@@ -344,10 +349,12 @@ public class ForkStarter
public RunResult call()
throws Exception
{
- DefaultReporterFactory reporter = new DefaultReporterFactory( startupReportConfiguration, log );
+ int forkNumber = drawNumber();
+ DefaultReporterFactory reporter =
+ new DefaultReporterFactory( startupReportConfiguration, log, forkNumber );
defaultReporterFactories.add( reporter );
- ForkClient forkClient =
- new ForkClient( reporter, testProvidingInputStream, log, printedErrorStream )
+ ForkClient forkClient = new ForkClient( reporter, testProvidingInputStream, log,
+ printedErrorStream, forkNumber )
{
@Override
protected void stopOnNextTest()
@@ -358,9 +365,16 @@ public class ForkStarter
}
}
};
-
- return fork( null, new PropertiesWrapper( providerConfiguration.getProviderProperties() ),
- forkClient, effectiveSystemProperties, testProvidingInputStream, true );
+ Map<String, String> providerProperties = providerConfiguration.getProviderProperties();
+ try
+ {
+ return fork( null, new PropertiesWrapper( providerProperties ), forkClient,
+ effectiveSystemProperties, forkNumber, testProvidingInputStream, true );
+ }
+ finally
+ {
+ returnNumber( forkNumber );
+ }
}
};
results.add( executorService.submit( pf ) );
@@ -408,11 +422,12 @@ public class ForkStarter
public RunResult call()
throws Exception
{
+ int forkNumber = drawNumber();
DefaultReporterFactory forkedReporterFactory =
- new DefaultReporterFactory( startupReportConfiguration, log );
+ new DefaultReporterFactory( startupReportConfiguration, log, forkNumber );
defaultReporterFactories.add( forkedReporterFactory );
ForkClient forkClient = new ForkClient( forkedReporterFactory, builder.getImmediateCommands(),
- log, printedErrorStream )
+ log, printedErrorStream, forkNumber )
{
@Override
protected void stopOnNextTest()
@@ -428,10 +443,11 @@ public class ForkStarter
{
return fork( testSet,
new PropertiesWrapper( providerConfiguration.getProviderProperties() ),
- forkClient, effectiveSystemProperties, stream, false );
+ forkClient, effectiveSystemProperties, forkNumber, stream, false );
}
finally
{
+ returnNumber( forkNumber );
builder.removeStream( stream );
}
}
@@ -522,24 +538,6 @@ public class ForkStarter
}
private RunResult fork( Object testSet, KeyValueSource providerProperties, ForkClient forkClient,
- SurefireProperties effectiveSystemProperties,
- AbstractForkInputStream testProvidingInputStream, boolean readTestsFromInStream )
- throws SurefireBooterForkException
- {
- int forkNumber = drawNumber();
- forkClient.setForkNumber( forkNumber );
- try
- {
- return fork( testSet, providerProperties, forkClient, effectiveSystemProperties, forkNumber,
- testProvidingInputStream, readTestsFromInStream );
- }
- finally
- {
- returnNumber( forkNumber );
- }
- }
-
- private RunResult fork( Object testSet, KeyValueSource providerProperties, ForkClient forkClient,
SurefireProperties effectiveSystemProperties, int forkNumber,
AbstractForkInputStream testProvidingInputStream, boolean readTestsFromInStream )
throws SurefireBooterForkException
@@ -553,7 +551,7 @@ public class ForkStarter
BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
Long pluginPid = forkConfiguration.getPluginPlatform().getPluginPid();
surefireProperties = booterSerializer.serialize( providerProperties, providerConfiguration,
- startupConfiguration, testSet, readTestsFromInStream, pluginPid );
+ startupConfiguration, testSet, readTestsFromInStream, pluginPid, forkNumber );
log.debug( "Determined Maven Process ID " + pluginPid );
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 4871e2a..254111b 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
@@ -107,6 +107,8 @@ public class ForkClient
*/
private final AtomicBoolean printedErrorStream;
+ private final int forkNumber;
+
/**
* Used by single Thread started by {@link ThreadedStreamConsumer} and therefore does not need to be volatile.
*/
@@ -119,15 +121,14 @@ public class ForkClient
private volatile StackTraceWriter errorInFork;
- private volatile int forkNumber;
-
public ForkClient( DefaultReporterFactory defaultReporterFactory, NotifiableTestStream notifiableTestStream,
- ConsoleLogger log, AtomicBoolean printedErrorStream )
+ ConsoleLogger log, AtomicBoolean printedErrorStream, int forkNumber )
{
this.defaultReporterFactory = defaultReporterFactory;
this.notifiableTestStream = notifiableTestStream;
this.log = log;
this.printedErrorStream = printedErrorStream;
+ this.forkNumber = forkNumber;
}
protected void stopOnNextTest()
@@ -317,10 +318,11 @@ public class ForkClient
String msg = "Corrupted STDOUT by directly writing to native stream in forked JVM " + forkNumber + ".";
InPluginProcessDumpSingleton util = InPluginProcessDumpSingleton.getSingleton();
+ File reportsDir = defaultReporterFactory.getReportsDirectory();
File dump =
e == null
- ? util.dumpText( msg + " Stream '" + event + "'.", defaultReporterFactory, forkNumber )
- : util.dumpException( e, msg + " Stream '" + event + "'.", defaultReporterFactory, forkNumber );
+ ? util.dumpStreamText( msg + " Stream '" + event + "'.", reportsDir, forkNumber )
+ : util.dumpStreamException( e, msg + " Stream '" + event + "'.", reportsDir, forkNumber );
if ( printedErrorStream.compareAndSet( false, true ) )
{
@@ -491,12 +493,6 @@ public class ForkClient
return !testsInProgress.isEmpty();
}
- public void setForkNumber( int forkNumber )
- {
- assert this.forkNumber == 0;
- this.forkNumber = forkNumber;
- }
-
private static final class OperationalData
{
private final byte operationId;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/InPluginProcessDumpSingleton.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/InPluginProcessDumpSingleton.java
index 0676b52..d7bbe9f 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/InPluginProcessDumpSingleton.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/InPluginProcessDumpSingleton.java
@@ -19,14 +19,15 @@ package org.apache.maven.plugin.surefire.booterclient.output;
* under the License.
*/
-import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
import org.apache.maven.surefire.util.internal.DumpFileUtils;
import java.io.File;
import static java.lang.String.format;
+import static org.apache.maven.plugin.surefire.SurefireHelper.DUMP_FILENAME;
+import static org.apache.maven.plugin.surefire.SurefireHelper.DUMP_FILENAME_FORMATTER;
+import static org.apache.maven.plugin.surefire.SurefireHelper.DUMPSTREAM_FILENAME;
import static org.apache.maven.plugin.surefire.SurefireHelper.DUMPSTREAM_FILENAME_FORMATTER;
-import static org.apache.maven.surefire.booter.DumpErrorSingleton.DUMPSTREAM_FILE_EXT;
/**
* Reports errors to dump file.
@@ -36,8 +37,6 @@ public final class InPluginProcessDumpSingleton
{
private static final InPluginProcessDumpSingleton SINGLETON = new InPluginProcessDumpSingleton();
- private final String creationDate = DumpFileUtils.newFormattedDateFileName();
-
private InPluginProcessDumpSingleton()
{
}
@@ -47,45 +46,59 @@ public final class InPluginProcessDumpSingleton
return SINGLETON;
}
- public synchronized File dumpException( Throwable t, String msg, DefaultReporterFactory defaultReporterFactory,
- int jvmRun )
+ public synchronized File dumpStreamException( Throwable t, String msg, File reportsDirectory, int jvmRun )
{
- File dump = newDumpFile( defaultReporterFactory, jvmRun );
+ File dump = newDumpStreamFile( reportsDirectory, jvmRun );
DumpFileUtils.dumpException( t, msg == null ? "null" : msg, dump );
return dump;
}
- public synchronized void dumpException( Throwable t, String msg, DefaultReporterFactory defaultReporterFactory )
+ public synchronized void dumpStreamException( Throwable t, String msg, File reportsDirectory )
{
- DumpFileUtils.dumpException( t, msg == null ? "null" : msg, newDumpFile( defaultReporterFactory ) );
+ DumpFileUtils.dumpException( t, msg == null ? "null" : msg, newDumpStreamFile( reportsDirectory ) );
}
- public synchronized void dumpException( Throwable t, DefaultReporterFactory defaultReporterFactory )
+ public synchronized File dumpStreamText( String msg, File reportsDirectory, int jvmRun )
{
- DumpFileUtils.dumpException( t, newDumpFile( defaultReporterFactory ) );
+ File dump = newDumpStreamFile( reportsDirectory, jvmRun );
+ DumpFileUtils.dumpText( msg == null ? "null" : msg, dump );
+ return dump;
}
- public synchronized File dumpText( String msg, DefaultReporterFactory defaultReporterFactory, int jvmRun )
+ public synchronized void dumpStreamText( String msg, File reportsDirectory )
{
- File dump = newDumpFile( defaultReporterFactory, jvmRun );
- DumpFileUtils.dumpText( msg == null ? "null" : msg, dump );
- return dump;
+ DumpFileUtils.dumpText( msg == null ? "null" : msg, newDumpStreamFile( reportsDirectory ) );
+ }
+
+ public synchronized void dumpException( Throwable t, String msg, File reportsDirectory, int jvmRun )
+ {
+ File dump = newDumpFile( reportsDirectory, jvmRun );
+ DumpFileUtils.dumpException( t, msg == null ? "null" : msg, dump );
}
- public synchronized void dumpText( String msg, DefaultReporterFactory defaultReporterFactory )
+ public synchronized void dumpException( Throwable t, String msg, File reportsDirectory )
{
- DumpFileUtils.dumpText( msg == null ? "null" : msg, newDumpFile( defaultReporterFactory ) );
+ File dump = newDumpFile( reportsDirectory );
+ DumpFileUtils.dumpException( t, msg == null ? "null" : msg, dump );
}
- private File newDumpFile( DefaultReporterFactory defaultReporterFactory )
+ private File newDumpStreamFile( File reportsDirectory )
{
- File reportsDirectory = defaultReporterFactory.getReportsDirectory();
- return new File( reportsDirectory, creationDate + DUMPSTREAM_FILE_EXT );
+ return new File( reportsDirectory, DUMPSTREAM_FILENAME );
}
- private static File newDumpFile( DefaultReporterFactory defaultReporterFactory, int jvmRun )
+ private static File newDumpStreamFile( File reportsDirectory, int jvmRun )
{
- File reportsDirectory = defaultReporterFactory.getReportsDirectory();
return new File( reportsDirectory, format( DUMPSTREAM_FILENAME_FORMATTER, jvmRun ) );
}
+
+ private static File newDumpFile( File reportsDirectory, int jvmRun )
+ {
+ return new File( reportsDirectory, format( DUMP_FILENAME_FORMATTER, jvmRun ) );
+ }
+
+ private static File newDumpFile( File reportsDirectory )
+ {
+ return new File( reportsDirectory, DUMP_FILENAME );
+ }
}
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 d460583..ace4f8a 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
@@ -42,6 +42,7 @@ public final class NativeStdErrStreamConsumer
@Override
public void consumeLine( String line )
{
- InPluginProcessDumpSingleton.getSingleton().dumpText( line, defaultReporterFactory );
+ InPluginProcessDumpSingleton.getSingleton()
+ .dumpStreamText( line, defaultReporterFactory.getReportsDirectory() );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/ConsoleOutputFileReporter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/ConsoleOutputFileReporter.java
index bbbd9c4..5bce92a 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/ConsoleOutputFileReporter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/ConsoleOutputFileReporter.java
@@ -19,6 +19,9 @@ package org.apache.maven.plugin.surefire.report;
* under the License.
*/
+import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
+import org.apache.maven.surefire.report.ReportEntry;
+
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@@ -27,9 +30,6 @@ import java.io.IOException;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.ReentrantLock;
-import org.apache.maven.surefire.booter.DumpErrorSingleton;
-import org.apache.maven.surefire.report.ReportEntry;
-
import static org.apache.maven.plugin.surefire.report.FileReporter.getReportFile;
/**
@@ -48,6 +48,7 @@ public class ConsoleOutputFileReporter
private final File reportsDirectory;
private final String reportNameSuffix;
+ private final Integer forkNumber;
private final AtomicStampedReference<FilterOutputStream> fileOutputStream =
new AtomicStampedReference<FilterOutputStream>( null, OPEN );
@@ -56,10 +57,11 @@ public class ConsoleOutputFileReporter
private volatile String reportEntryName;
- public ConsoleOutputFileReporter( File reportsDirectory, String reportNameSuffix )
+ public ConsoleOutputFileReporter( File reportsDirectory, String reportNameSuffix, Integer forkNumber )
{
this.reportsDirectory = reportsDirectory;
this.reportNameSuffix = reportNameSuffix;
+ this.forkNumber = forkNumber;
}
@Override
@@ -124,9 +126,7 @@ public class ConsoleOutputFileReporter
}
catch ( IOException e )
{
- DumpErrorSingleton.getSingleton()
- .dumpException( e );
-
+ dumpException( e );
throw new RuntimeException( e );
}
finally
@@ -143,10 +143,9 @@ public class ConsoleOutputFileReporter
// close null-output.txt report file
close( true );
}
- catch ( IOException ignored )
+ catch ( IOException e )
{
- DumpErrorSingleton.getSingleton()
- .dumpException( ignored );
+ dumpException( e );
}
finally
{
@@ -162,10 +161,9 @@ public class ConsoleOutputFileReporter
{
close( false );
}
- catch ( IOException ignored )
+ catch ( IOException e )
{
- DumpErrorSingleton.getSingleton()
- .dumpException( ignored );
+ dumpException( e );
}
}
@@ -183,4 +181,18 @@ public class ConsoleOutputFileReporter
}
}
}
+
+ private void dumpException( IOException e )
+ {
+ if ( forkNumber == null )
+ {
+ InPluginProcessDumpSingleton.getSingleton()
+ .dumpException( e, e.getLocalizedMessage(), reportsDirectory );
+ }
+ else
+ {
+ InPluginProcessDumpSingleton.getSingleton()
+ .dumpException( e, e.getLocalizedMessage(), reportsDirectory, forkNumber );
+ }
+ }
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
index 15b4306..1fd2bfe 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
@@ -63,9 +63,10 @@ import static org.apache.maven.surefire.util.internal.ObjectUtils.useNonNull;
public class DefaultReporterFactory
implements ReporterFactory
{
+ private final Collection<TestSetRunListener> listeners = new ConcurrentLinkedQueue<TestSetRunListener>();
private final StartupReportConfiguration reportConfiguration;
private final ConsoleLogger consoleLogger;
- private final Collection<TestSetRunListener> listeners;
+ private final Integer forkNumber;
private RunStatistics globalStats = new RunStatistics();
@@ -80,9 +81,15 @@ public class DefaultReporterFactory
public DefaultReporterFactory( StartupReportConfiguration reportConfiguration, ConsoleLogger consoleLogger )
{
+ this( reportConfiguration, consoleLogger, null );
+ }
+
+ public DefaultReporterFactory( StartupReportConfiguration reportConfiguration, ConsoleLogger consoleLogger,
+ Integer forkNumber )
+ {
this.reportConfiguration = reportConfiguration;
this.consoleLogger = consoleLogger;
- listeners = new ConcurrentLinkedQueue<TestSetRunListener>();
+ this.forkNumber = forkNumber;
}
@Override
@@ -113,26 +120,24 @@ public class DefaultReporterFactory
private FileReporter createFileReporter()
{
- final FileReporter fileReporter = reportConfiguration.instantiateFileReporter();
+ FileReporter fileReporter = reportConfiguration.instantiateFileReporter( forkNumber );
return useNonNull( fileReporter, NullFileReporter.INSTANCE );
}
private StatelessXmlReporter createSimpleXMLReporter()
{
- final StatelessXmlReporter xmlReporter = reportConfiguration.instantiateStatelessXmlReporter();
+ StatelessXmlReporter xmlReporter = reportConfiguration.instantiateStatelessXmlReporter( forkNumber );
return useNonNull( xmlReporter, NullStatelessXmlReporter.INSTANCE );
}
private TestcycleConsoleOutputReceiver createConsoleOutputReceiver()
{
- final TestcycleConsoleOutputReceiver consoleOutputReceiver =
- reportConfiguration.instantiateConsoleOutputFileReporter();
- return useNonNull( consoleOutputReceiver, NullConsoleOutputReceiver.INSTANCE );
+ return reportConfiguration.instantiateConsoleOutputFileReporter( forkNumber );
}
private StatisticsReporter createStatisticsReporter()
{
- final StatisticsReporter statisticsReporter = reportConfiguration.getStatisticsReporter();
+ StatisticsReporter statisticsReporter = reportConfiguration.getStatisticsReporter();
return useNonNull( statisticsReporter, NullStatisticsReporter.INSTANCE );
}
@@ -147,10 +152,7 @@ public class DefaultReporterFactory
{
for ( DefaultReporterFactory factory : factories )
{
- for ( TestSetRunListener listener : factory.listeners )
- {
- listeners.add( listener );
- }
+ listeners.addAll( factory.listeners );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/NullConsoleOutputReceiver.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/NullConsoleOutputReceiver.java
deleted file mode 100644
index 327c77d..0000000
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/NullConsoleOutputReceiver.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.apache.maven.plugin.surefire.report;
-
-/*
- * 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;
-
-/**
- * ConsoleReporter doing nothing rather than using null.
- *
- * @author <a href="mailto:britter@apache.org">Benedikt Ritter</a>
- * @since 2.20
- */
-class NullConsoleOutputReceiver
- implements TestcycleConsoleOutputReceiver
-{
-
- static final NullConsoleOutputReceiver INSTANCE = new NullConsoleOutputReceiver();
-
- private NullConsoleOutputReceiver()
- {
- }
-
- @Override
- public void testSetStarting( ReportEntry reportEntry )
- {
- }
-
- @Override
- public void testSetCompleted( ReportEntry report )
- {
- }
-
- @Override
- public void close()
- {
- }
-
- @Override
- public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
- {
- }
-}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
index c00f7f9..40ab309 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireHelperTest.java
@@ -21,6 +21,7 @@ package org.apache.maven.plugin.surefire;
import org.junit.Test;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -37,15 +38,36 @@ import static org.junit.Assume.assumeTrue;
public class SurefireHelperTest
{
@Test
+ public void shouldReplaceForkNumberPath()
+ {
+ File root = new File( System.getProperty( "user.dir", "" ) );
+ File pathWithPlaceholder = new File( root, "${surefire.forkNumber}" );
+ File changed = SurefireHelper.replaceForkThreadsInPath( pathWithPlaceholder, 5 );
+ assertThat( changed.getPath() )
+ .isEqualTo( new File( root, "5" ).getPath() );
+ }
+
+ @Test
+ public void shouldReplaceLongForkNumberPath()
+ {
+ File root = new File( System.getProperty( "user.dir", "" ) );
+ File subDir = new File( root, "reports-${surefire.forkNumber}" );
+ File pathWithPlaceholder = new File( subDir, "subfolder" );
+ File changed = SurefireHelper.replaceForkThreadsInPath( pathWithPlaceholder, 5 );
+ assertThat( changed.getPath() )
+ .isEqualTo( new File( new File( root, "reports-5" ), "subfolder" ).getPath() );
+ }
+
+ @Test
public void shouldBeThreeDumpFiles()
{
String[] dumps = SurefireHelper.getDumpFilesToPrint();
- assertThat( dumps ).hasSize( 3 );
+ assertThat( dumps ).hasSize( 4 );
assertThat( dumps ).doesNotHaveDuplicates();
List<String> onlyStrings = new ArrayList<String>();
addAll( onlyStrings, dumps );
onlyStrings.removeAll( singleton( (String) null ) );
- assertThat( onlyStrings ).hasSize( 3 );
+ assertThat( onlyStrings ).hasSize( 4 );
}
@Test
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 26b8be7..4777ce8 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
@@ -220,7 +220,7 @@ public class BooterDeserializerProviderConfigurationTest
test = "aTest";
}
final File propsTest = booterSerializer.serialize( props, booterConfiguration, testProviderConfiguration, test,
- readTestsFromInStream, 51L );
+ readTestsFromInStream, 51L, 1 );
BooterDeserializer booterDeserializer = new BooterDeserializer( new FileInputStream( propsTest ) );
assertEquals( 51L, (Object) booterDeserializer.getPluginPid() );
return booterDeserializer.deserialize();
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 fc00bcd..7a1a7e2 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
@@ -125,8 +125,8 @@ public class BooterDeserializerStartupConfigurationTest
PropertiesWrapper props = new PropertiesWrapper( new HashMap<String, String>() );
BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration );
String aTest = "aTest";
- final File propsTest =
- booterSerializer.serialize( props, getProviderConfiguration(), startupConfiguration, aTest, false, null );
+ File propsTest = booterSerializer.serialize( props, getProviderConfiguration(), startupConfiguration, aTest,
+ false, null, 1 );
BooterDeserializer booterDeserializer = new BooterDeserializer( new FileInputStream( propsTest ) );
assertNull( booterDeserializer.getPluginPid() );
return booterDeserializer.getProviderConfiguration();
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 7d2e6be..0fd275f 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
@@ -223,7 +223,7 @@ public class ForkingRunListenerTest
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
ForkClient forkStreamClient =
- new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null );
+ new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null, 1 );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
@@ -248,7 +248,7 @@ public class ForkingRunListenerTest
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
ForkClient forkStreamClient =
- new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null );
+ new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null, 1 );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
@@ -277,7 +277,7 @@ public class ForkingRunListenerTest
NotifiableTestStream notifiableTestStream = new MockNotifiableTestStream();
NullConsoleLogger log = new NullConsoleLogger();
- ForkClient forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null );
+ ForkClient forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null, 1 );
forkStreamClient.consumeMultiLineContent( content.toString( "UTF-8" ) );
MockReporter reporter = (MockReporter) forkStreamClient.getReporter();
@@ -285,7 +285,7 @@ public class ForkingRunListenerTest
Assert.assertEquals( expected, reporter.getFirstData() );
Assert.assertEquals( 1, reporter.getEvents().size() );
- forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null );
+ forkStreamClient = new ForkClient( providerReporterFactory, notifiableTestStream, log, null, 2 );
forkStreamClient.consumeMultiLineContent( anotherContent.toString( "UTF-8" ) );
MockReporter reporter2 = (MockReporter) forkStreamClient.getReporter();
Assert.assertEquals( MockReporter.TEST_SKIPPED, reporter2.getFirstEvent() );
@@ -355,7 +355,7 @@ public class ForkingRunListenerTest
TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
NullConsoleLogger log = new NullConsoleLogger();
final ForkClient forkStreamClient =
- new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null );
+ new ForkClient( providerReporterFactory, new MockNotifiableTestStream(), log, null, 1 );
forkStreamClient.consumeMultiLineContent( content.toString( ) );
reporter = (MockReporter) forkStreamClient.getReporter();
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/report/ConsoleOutputFileReporterTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/report/ConsoleOutputFileReporterTest.java
index df011d9..2ee6186 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/report/ConsoleOutputFileReporterTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/report/ConsoleOutputFileReporterTest.java
@@ -46,7 +46,7 @@ public class ConsoleOutputFileReporterTest
//noinspection ResultOfMethodCallIgnored
reportDir.mkdirs();
ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), getClass().getName() );
- ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null );
+ ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null, null );
reporter.testSetStarting( reportEntry );
reporter.writeTestOutput( "some text".getBytes( US_ASCII ), 0, 5, true );
reporter.testSetCompleted( reportEntry );
@@ -74,7 +74,7 @@ public class ConsoleOutputFileReporterTest
reportDir.mkdirs();
String suffixText = "sampleSuffixText";
ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), getClass().getName() );
- ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, suffixText );
+ ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, suffixText, null );
reporter.testSetStarting( reportEntry );
reporter.writeTestOutput( "some text".getBytes( US_ASCII ), 0, 5, true );
reporter.testSetCompleted( reportEntry );
@@ -97,7 +97,7 @@ public class ConsoleOutputFileReporterTest
File reportDir = new File( new File( System.getProperty( "user.dir" ), "target" ), "tmp3" );
//noinspection ResultOfMethodCallIgnored
reportDir.mkdirs();
- ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null );
+ ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null, null );
reporter.writeTestOutput( "some text".getBytes( US_ASCII ), 0, 5, true );
reporter.testSetCompleted( new SimpleReportEntry( getClass().getName(), getClass().getName() ) );
reporter.close();
@@ -119,7 +119,7 @@ public class ConsoleOutputFileReporterTest
File reportDir = new File( new File( System.getProperty( "user.dir" ), "target" ), "tmp4" );
//noinspection ResultOfMethodCallIgnored
reportDir.mkdirs();
- final ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null );
+ final ConsoleOutputFileReporter reporter = new ConsoleOutputFileReporter( reportDir, null, null );
reporter.testSetStarting( new SimpleReportEntry( getClass().getName(), getClass().getName() ) );
ExecutorService scheduler = Executors.newFixedThreadPool( 10 );
final ArrayList<Callable<Void>> jobs = new ArrayList<Callable<Void>>();
diff --git a/maven-surefire-plugin/src/site/fml/faq.fml b/maven-surefire-plugin/src/site/fml/faq.fml
index b73dde6..96053cf 100644
--- a/maven-surefire-plugin/src/site/fml/faq.fml
+++ b/maven-surefire-plugin/src/site/fml/faq.fml
@@ -130,6 +130,7 @@ under the License.
<![CDATA[ [date]-jvmRun[N].dump]]><br/>
<![CDATA[ [date]-jvmRun[N].dumpstream]]><br/>
<![CDATA[ [date].dumpstream]]><br/>
+ <![CDATA[ [date].dump]]><br/>
</code>
Forked JVM process and plugin process communicate via std/out. If this channel is corrupted, for a whatever
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/DumpErrorSingleton.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/DumpErrorSingleton.java
index e287f05..97e37d0 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/DumpErrorSingleton.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/DumpErrorSingleton.java
@@ -19,7 +19,6 @@ package org.apache.maven.surefire.booter;
* under the License.
*/
-import org.apache.maven.surefire.report.ReporterConfiguration;
import org.apache.maven.surefire.util.internal.DumpFileUtils;
import java.io.File;
@@ -51,10 +50,10 @@ public final class DumpErrorSingleton
return SINGLETON;
}
- public synchronized void init( String dumpFileName, ReporterConfiguration configuration )
+ public synchronized void init( File reportsDir, String dumpFileName )
{
- dumpFile = createDumpFile( dumpFileName, configuration );
- dumpStreamFile = createDumpStreamFile( dumpFileName, configuration );
+ dumpFile = createDumpFile( reportsDir, dumpFileName );
+ dumpStreamFile = createDumpStreamFile( reportsDir, dumpFileName );
}
public synchronized void dumpException( Throwable t, String msg )
@@ -87,13 +86,13 @@ public final class DumpErrorSingleton
DumpFileUtils.dumpText( msg == null ? "null" : msg, dumpStreamFile );
}
- private File createDumpFile( String dumpFileName, ReporterConfiguration configuration )
+ private File createDumpFile( File reportsDir, String dumpFileName )
{
- return newDumpFile( dumpFileName + DUMP_FILE_EXT, configuration );
+ return newDumpFile( reportsDir, dumpFileName + DUMP_FILE_EXT );
}
- private File createDumpStreamFile( String dumpFileName, ReporterConfiguration configuration )
+ private File createDumpStreamFile( File reportsDir, String dumpFileName )
{
- return newDumpFile( dumpFileName + DUMPSTREAM_FILE_EXT, configuration );
+ return newDumpFile( reportsDir, dumpFileName + DUMPSTREAM_FILE_EXT );
}
}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
index c83ae1f..cc2d04a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/DumpFileUtils.java
@@ -19,8 +19,6 @@ package org.apache.maven.surefire.util.internal;
* under the License.
*/
-import org.apache.maven.surefire.report.ReporterConfiguration;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -49,12 +47,12 @@ public final class DumpFileUtils
/**
* New dump file. Synchronized object appears in main memory and perfectly visible in other threads.
*
+ * @param reportsDir only report directory
* @param dumpFileName dump file name
- * @param configuration only report directory
*/
- public static synchronized File newDumpFile( String dumpFileName, ReporterConfiguration configuration )
+ public static synchronized File newDumpFile( File reportsDir, String dumpFileName )
{
- return new File( configuration.getReportsDirectory(), dumpFileName );
+ return new File( reportsDir, dumpFileName );
}
public static void dumpException( Throwable t, File dumpFile )
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 bbb3294..03ef036 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
@@ -95,7 +95,8 @@ public final class ForkedBooter
setSystemProperties( new File( tmpDir, effectiveSystemPropertiesFileName ) );
providerConfiguration = booterDeserializer.deserialize();
- DumpErrorSingleton.getSingleton().init( dumpFileName, providerConfiguration.getReporterConfiguration() );
+ DumpErrorSingleton.getSingleton()
+ .init( providerConfiguration.getReporterConfiguration().getReportsDirectory(), dumpFileName );
startupConfiguration = booterDeserializer.getProviderConfiguration();
systemExitTimeoutInSeconds = providerConfiguration.systemExitTimeout( DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS );
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/TestFile.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/TestFile.java
index f68eb35..abf17cb 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/TestFile.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/fixture/TestFile.java
@@ -31,8 +31,10 @@ import java.util.List;
import org.apache.commons.io.FileUtils;
import junit.framework.Assert;
+import org.hamcrest.Matcher;
import static junit.framework.Assert.assertTrue;
+import static org.hamcrest.Matchers.containsString;
/**
* @author Kristian Rosenvold
@@ -129,12 +131,12 @@ public class TestFile
return file.isFile();
}
- public TestFile assertContainsText( String text )
+ public TestFile assertContainsText( Matcher<String> matcher )
{
final List<String> list = surefireVerifier.loadFile( file, encoding );
for ( String line : list )
{
- if ( line.contains( text ) )
+ if ( matcher.matches( line ) )
{
return this;
}
@@ -143,6 +145,11 @@ public class TestFile
return null;
}
+ public TestFile assertContainsText( String text )
+ {
+ return assertContainsText( containsString( text ) );
+ }
+
public URI toURI()
{
return file.toURI();
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1535TestNGParallelSuitesIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1535TestNGParallelSuitesIT.java
index a3ffd5b..0c8061d 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1535TestNGParallelSuitesIT.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1535TestNGParallelSuitesIT.java
@@ -19,20 +19,125 @@ package org.apache.maven.surefire.its.jiras;
* under the License.
*/
+import org.apache.maven.it.VerificationException;
+import org.apache.maven.surefire.its.fixture.OutputValidator;
import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.apache.maven.surefire.its.fixture.SurefireLauncher;
+import org.apache.maven.surefire.its.fixture.TestFile;
import org.junit.Test;
+import java.nio.charset.Charset;
+
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+
public class Surefire1535TestNGParallelSuitesIT
extends SurefireJUnit4IntegrationTestCase
{
+ private static final Charset UTF8 = Charset.forName( "UTF-8" );
+
+ @Test
+ public void forks2() throws VerificationException
+ {
+ OutputValidator validator = unpack()
+ .activateProfile( "forked-reports-directory" )
+ .forkCount( 2 )
+ .executeTest();
+
+ TestFile testFile = validator.getSurefireReportsFile( "../surefire-reports-1/TEST-TestSuite.xml", UTF8 );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest" );
+
+ testFile = validator.getSurefireReportsFile( "../surefire-reports-2/TEST-TestSuite.xml", UTF8 );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest" );
+
+ validator.assertThatLogLine( containsString( "Tests run: 2, Failures: 0, Errors: 0, Skipped: 0" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, " ), is( 2 ) )
+ .assertThatLogLine( containsString( "Suite1.xml" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Suite2.xml" ), is( 1 ) )
+ .assertThatLogLine( containsString( "test 1" ), is( 1 ) )
+ .assertThatLogLine( containsString( "test 2" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Running TestSuite" ), is( 2 ) );
+ }
+
@Test
- public void testParallelSuites()
+ public void forks2Redirected() throws VerificationException
+ {
+ OutputValidator validator = unpack()
+ .activateProfile( "forked-reports-directory" )
+ .forkCount( 2 )
+ .redirectToFile( true )
+ .executeTest();
+
+ TestFile testFile = validator.getSurefireReportsFile( "../surefire-reports-1/TEST-TestSuite.xml", UTF8 );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest" );
+
+ testFile = validator.getSurefireReportsFile( "../surefire-reports-2/TEST-TestSuite.xml", UTF8 );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest" );
+
+ validator.assertThatLogLine( containsString( "Tests run: 2, Failures: 0, Errors: 0, Skipped: 0" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, " ), is( 2 ) )
+ .assertThatLogLine( containsString( "Running TestSuite" ), is( 2 ) );
+
+ TestFile outFile = validator.getSurefireReportsFile( "../surefire-reports-1/TestSuite-output.txt" );
+ outFile.assertFileExists();
+ outFile.assertContainsText( anyOf( containsString( "Suite1.xml" ), containsString( "Suite2.xml" ) ) );
+ outFile.assertContainsText( anyOf( containsString( "test 1" ), containsString( "test 2" ) ) );
+
+ outFile = validator.getSurefireReportsFile( "../surefire-reports-2/TestSuite-output.txt" );
+ outFile.assertFileExists();
+ outFile.assertContainsText( anyOf( containsString( "Suite1.xml" ), containsString( "Suite2.xml" ) ) );
+ outFile.assertContainsText( anyOf( containsString( "test 1" ), containsString( "test 2" ) ) );
+ }
+
+ @Test
+ public void forks0() throws VerificationException
+ {
+ OutputValidator validator = unpack()
+ .forkCount( 0 )
+ .executeTest();
+
+ TestFile testFile = validator.getSurefireReportsFile( "TEST-TestSuite.xml" );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest1\"" );
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest2\"" );
+
+ validator.assertThatLogLine( containsString( "Suite1.xml" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Suite2.xml" ), is( 1 ) )
+ .assertThatLogLine( containsString( "test 1" ), is( 1 ) )
+ .assertThatLogLine( containsString( "test 2" ), is( 1 ) )
+ .assertThatLogLine( containsString( "Running TestSuite" ), is( 1 ) );
+ }
+
+ @Test
+ public void forks0Redirected() throws VerificationException
+ {
+ OutputValidator validator = unpack()
+ .forkCount( 0 )
+ .redirectToFile( true )
+ .executeTest();
+
+ TestFile testFile = validator.getSurefireReportsXmlFile( "TEST-TestSuite.xml" );
+ testFile.assertFileExists();
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest1\"" );
+ testFile.assertContainsText( "<testcase name=\"test\" classname=\"it.ParallelTest2\"" );
+
+ validator.assertThatLogLine( containsString( "Running TestSuite" ), is( 1 ) );
+
+ TestFile outFile = validator.getSurefireReportsFile( "TestSuite-output.txt" );
+ outFile.assertFileExists();
+ outFile.assertContainsText( "Suite1.xml" );
+ outFile.assertContainsText( "Suite1.xml" );
+ outFile.assertContainsText( "test 1" );
+ outFile.assertContainsText( "test 2" );
+ }
+
+ private SurefireLauncher unpack()
{
- unpack("/surefire-1535-parallel-testng")
- .maven()
- .sysProp( "testNgVersion", "5.7" )
- .sysProp( "testNgClassifier", "jdk15" )
- .executeTest()
- .assertTestSuiteResults( 2, 0, 0, 0 );
+ return unpack("/surefire-1535-parallel-testng");
}
}
diff --git a/surefire-its/src/test/resources/surefire-1535-parallel-testng/pom.xml b/surefire-its/src/test/resources/surefire-1535-parallel-testng/pom.xml
index 942ddb6..c7aba88 100644
--- a/surefire-its/src/test/resources/surefire-1535-parallel-testng/pom.xml
+++ b/surefire-its/src/test/resources/surefire-1535-parallel-testng/pom.xml
@@ -33,33 +33,30 @@
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.7</version>
+ <classifier>jdk15</classifier>
+ </dependency>
+ </dependencies>
+
<profiles>
<profile>
- <id>testng-old</id>
- <activation>
- <property><name>testNgClassifier</name></property>
- </activation>
- <dependencies>
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>${testNgVersion}</version>
- <classifier>${testNgClassifier}</classifier>
- </dependency>
- </dependencies>
- </profile>
- <profile>
- <id>testng-new</id>
- <activation>
- <property><name>!testNgClassifier</name></property>
- </activation>
- <dependencies>
- <dependency>
- <groupId>org.testng</groupId>
- <artifactId>testng</artifactId>
- <version>${testNgVersion}</version>
- </dependency>
- </dependencies>
+ <id>forked-reports-directory</id>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <reportsDirectory>target/surefire-reports-${surefire.forkNumber}</reportsDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
</profile>
</profiles>
@@ -69,7 +66,6 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<configuration>
- <forkCount>2</forkCount>
<reuseForks>false</reuseForks>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/Suite1.xml</suiteXmlFile>
diff --git a/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest1.java b/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest1.java
index 177c420..0590851 100644
--- a/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest1.java
+++ b/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest1.java
@@ -29,6 +29,7 @@ public class ParallelTest1
{
public void test() throws Exception
{
+ System.out.println( "test 1" );
TimeUnit.SECONDS.sleep( 1L );
}
}
diff --git a/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest2.java b/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest2.java
index d56fa62..8467ea7 100644
--- a/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest2.java
+++ b/surefire-its/src/test/resources/surefire-1535-parallel-testng/src/test/java/it/ParallelTest2.java
@@ -29,6 +29,7 @@ public class ParallelTest2
{
public void test() throws Exception
{
+ System.out.println( "test 2" );
TimeUnit.SECONDS.sleep( 1L );
}
}