Skip to content
Commits on Source (2)
# Auto detect text files and perform LF normalization
* text=auto
* text eol=lf
*.xml text diff=xml
*.java text diff=java
*.html text diff=html
*.vm text
*.fml text
*.md text
*.css text
*.js text
*.sql text
......@@ -21,23 +21,28 @@
properties(
[
buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '0', daysToKeepStr: env.BRANCH_NAME == 'master' ? '30' : '7', numToKeepStr: '5')),
buildDiscarder(logRotator(artifactDaysToKeepStr: env.BRANCH_NAME == 'master' ? '30' : '7',
artifactNumToKeepStr: '10',
daysToKeepStr: env.BRANCH_NAME == 'master' ? '30' : '7',
numToKeepStr: '10')
),
disableConcurrentBuilds()
]
)
final def oses = ['linux', 'windows']
final def mavens = ['3.2.x', '3.3.x', '3.5.x']//env.BRANCH_NAME == 'master' ? ['3.2.x', '3.3.x', '3.5.x'] : ['3.5.x']
final def jdks = [7, 8, 9, 10]//env.BRANCH_NAME == 'master' ? [7, 8, 9, 10] : [9, 10]
final def oses = ['linux':'ubuntu', 'windows':'Windows && !windows-2012-3']
final def mavens = env.BRANCH_NAME == 'master' ? ['3.2.x', '3.3.x', '3.5.x'] : ['3.5.x']
final def jdks = [7, 8, 9, 10]
final def options = ['-e', '-V', '-B', '-nsu', '-P', 'run-its']
final def goals = ['clean', 'install', 'jacoco:report']
final Map stages = [:]
oses.eachWithIndex { os, indexOfOs ->
oses.eachWithIndex { osMapping, indexOfOs ->
mavens.eachWithIndex { maven, indexOfMaven ->
jdks.eachWithIndex { jdk, indexOfJdk ->
final String label = jenkinsEnv.labelForOS(os);
def os = osMapping.key
def label = osMapping.value
final String jdkTestName = jenkinsEnv.jdkFromVersion(os, jdk.toString())
final String jdkName = jenkinsEnv.jdkFromVersion(os, '8')
final String mvnName = jenkinsEnv.mvnFromVersion(os, maven)
......@@ -72,31 +77,35 @@ oses.eachWithIndex { os, indexOfOs ->
}
}
timeout(time: 10, unit: 'HOURS') {
timeout(time: 12, unit: 'HOURS') {
try {
parallel(stages)
// JENKINS-34376 seems to make it hard to detect the aborted builds
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
println "org.jenkinsci.plugins.workflow.steps.FlowInterruptedException: ${e}"
// this ambiguous condition means a user probably aborted
if (e.causes.size() == 0) {
currentBuild.result = "ABORTED"
currentBuild.result = 'ABORTED'
} else {
currentBuild.result = "FAILURE"
currentBuild.result = 'FAILURE'
}
throw e
} catch (hudson.AbortException e) {
println "hudson.AbortException: ${e}"
// this ambiguous condition means during a shell step, user probably aborted
if (e.getMessage().contains('script returned exit code 143')) {
currentBuild.result = "ABORTED"
currentBuild.result = 'ABORTED'
} else {
currentBuild.result = "FAILURE"
currentBuild.result = 'FAILURE'
}
throw e
} catch (InterruptedException e) {
currentBuild.result = "ABORTED"
println "InterruptedException: ${e}"
currentBuild.result = 'ABORTED'
throw e
} catch (Throwable e) {
currentBuild.result = "FAILURE"
println "Throwable: ${e}"
currentBuild.result = 'FAILURE'
throw e
} finally {
stage("notifications") {
......@@ -108,16 +117,15 @@ timeout(time: 10, unit: 'HOURS') {
def buildProcess(String stageKey, String jdkName, String jdkTestName, String mvnName, goals, options, mavenOpts, boolean makeReports) {
cleanWs()
try {
def mvnLocalRepoDir = null
if (isUnix()) {
sh 'mkdir -p .m2'
mvnLocalRepoDir = "${pwd()}/.m2"
} else {
bat 'mkdir .m2'
mvnLocalRepoDir = "${pwd()}\\.m2"
}
def mvnLocalRepoDir = null
dir('.m2') {
mvnLocalRepoDir = "${pwd()}"
}
println "Maven Local Repository = ${mvnLocalRepoDir}."
assert mvnLocalRepoDir != null : 'Local Maven Repository is undefined.'
......@@ -174,14 +182,14 @@ def buildProcess(String stageKey, String jdkName, String jdkTestName, String mvn
}
if (fileExists('maven-failsafe-plugin/target/it')) {
zip(zipFile: "it--maven-failsafe-plugin--${stageKey}.zip", dir: 'maven-failsafe-plugin/target/it', archive: true)
zip(zipFile: "maven-failsafe-plugin--${stageKey}.zip", dir: 'maven-failsafe-plugin/target/it', archive: true)
}
if (fileExists('surefire-its/target')) {
zip(zipFile: "it--surefire-its--${stageKey}.zip", dir: 'surefire-its/target', archive: true)
zip(zipFile: "surefire-its--${stageKey}.zip", dir: 'surefire-its/target', archive: true)
}
archiveArtifacts(artifacts: '*.zip', allowEmptyArchive: true, onlyIfSuccessful: false)
archiveArtifacts(artifacts: "*--${stageKey}.zip", allowEmptyArchive: true, onlyIfSuccessful: false)
}
stage("cleanup ${stageKey}") {
......
......@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire</artifactId>
<version>2.21.0</version>
<version>2.22.0</version>
</parent>
<groupId>org.apache.maven.plugins</groupId>
......
......@@ -256,10 +256,11 @@ public class IntegrationTestMojo
private boolean useManifestOnlyJar;
/**
* The character encoding scheme to be applied.
* Deprecated since 2.20.1 and used encoding UTF-8 in <tt>failsafe-summary.xml</tt>.
* The character encoding scheme to be applied while generating test report
* files (see target/surefire-reports/yourTestName.txt).
* The report output files (*-out.txt) are still encoded with JVM's encoding used in standard out/err pipes.
*
* @deprecated since of 2.20.1
* @since 3.0.0-M1
*/
@Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
private String encoding;
......@@ -703,6 +704,18 @@ public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
this.useManifestOnlyJar = useManifestOnlyJar;
}
@Override
public String getEncoding()
{
return encoding;
}
@Override
public void setEncoding( String encoding )
{
this.encoding = encoding;
}
// the following will be refactored out once the common code is all in one place
public boolean isTestFailureIgnore()
......
......@@ -24,7 +24,7 @@
<parent>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire</artifactId>
<version>2.21.0</version>
<version>2.22.0</version>
</parent>
<artifactId>maven-surefire-common</artifactId>
......
......@@ -115,9 +115,11 @@
import static java.lang.Thread.currentThread;
import static java.util.Arrays.asList;
import static java.util.Collections.addAll;
import static java.util.Collections.singletonList;
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.shared.utils.StringUtils.capitalizeFirstLetter;
import static org.apache.maven.shared.utils.StringUtils.isEmpty;
import static org.apache.maven.shared.utils.StringUtils.isNotBlank;
......@@ -485,6 +487,15 @@ public abstract class AbstractSurefireMojo
@Parameter( property = "junitArtifactName", defaultValue = "junit:junit" )
private String junitArtifactName;
/**
* Allows you to specify the name of the JUnit Platform artifact.
* If not set, {@code org.junit.platform:junit-platform-engine} will be used.
*
* @since 2.22.0
*/
@Parameter( property = "junitPlatformArtifactName", defaultValue = "org.junit.platform:junit-platform-engine" )
private String junitPlatformArtifactName;
/**
* Allows you to specify the name of the TestNG artifact. If not set, {@code org.testng:testng} will be used.
*
......@@ -731,8 +742,11 @@ public abstract class AbstractSurefireMojo
* List of dependencies to scan for test classes to include in the test run.
* The child elements of this element must be &lt;dependency&gt; elements, and the
* contents of each of these elements must be a string which follows the format:
*
* <br>
* <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>.
* <br>
* Since version 2.22.0 you can scan for test classes from a project
* dependency of your multi-module project.
*
* @since 2.15
*/
......@@ -894,7 +908,13 @@ private DefaultScanResult scanDirectories()
return scanner.scan();
}
private DefaultScanResult scanDependencies()
@SuppressWarnings( "unchecked" )
List<Artifact> getProjectTestArtifacts()
{
return project.getTestArtifacts();
}
DefaultScanResult scanDependencies() throws MojoFailureException
{
if ( getDependenciesToScan() == null )
{
......@@ -904,16 +924,40 @@ private DefaultScanResult scanDependencies()
{
try
{
// @TODO noinspection unchecked, check MavenProject 3.x for Generics in surefire:3.0
@SuppressWarnings( "unchecked" )
List<File> dependenciesToScan =
DependencyScanner.filter( project.getTestArtifacts(), asList( getDependenciesToScan() ) );
DependencyScanner scanner = new DependencyScanner( dependenciesToScan, getIncludedAndExcludedTests() );
return scanner.scan();
DefaultScanResult result = null;
List<Artifact> dependenciesToScan =
filter( getProjectTestArtifacts(), asList( getDependenciesToScan() ) );
for ( Artifact artifact : dependenciesToScan )
{
String type = artifact.getType();
File out = artifact.getFile();
if ( out == null || !out.exists()
|| !( "jar".equals( type ) || out.isDirectory() || out.getName().endsWith( ".jar" ) ) )
{
continue;
}
if ( out.isFile() )
{
DependencyScanner scanner =
new DependencyScanner( singletonList( out ), getIncludedAndExcludedTests() );
result = result == null ? scanner.scan() : result.append( scanner.scan() );
}
else if ( out.isDirectory() )
{
DirectoryScanner scanner =
new DirectoryScanner( out, getIncludedAndExcludedTests() );
result = result == null ? scanner.scan() : result.append( scanner.scan() );
}
}
return result;
}
catch ( Exception e )
{
throw new RuntimeException( e );
throw new MojoFailureException( e.getLocalizedMessage(), e );
}
}
}
......@@ -1022,6 +1066,7 @@ protected List<ProviderInfo> createProviders()
Artifact junitDepArtifact = getJunitDepArtifact();
return new ProviderList( new DynamicProviderInfo( null ),
new TestNgProviderInfo( getTestNgArtifact() ),
new JUnitPlatformProviderInfo( getJunitPlatformArtifact() ),
new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit3ProviderInfo() )
......@@ -1540,7 +1585,7 @@ private boolean isAnyJunit4( Artifact artifact )
return dependencyResolver.isWithinVersionSpec( artifact, "[4.0,)" );
}
static boolean isForkModeNever( String forkMode )
private static boolean isForkModeNever( String forkMode )
{
return FORK_NEVER.equals( forkMode );
}
......@@ -1807,7 +1852,7 @@ private StartupReportConfiguration getStartupReportConfiguration( String configC
isRedirectTestOutputToFile(), isDisableXmlReport(),
getReportsDirectory(), isTrimStackTrace(), getReportNameSuffix(),
getStatisticsFile( configChecksum ), requiresRunHistory(),
getRerunFailingTestsCount(), getReportSchemaLocation() );
getRerunFailingTestsCount(), getReportSchemaLocation(), getEncoding() );
}
private boolean isSpecificTestSpecified()
......@@ -2033,6 +2078,21 @@ private Artifact getJunitDepArtifact()
return getProjectArtifactMap().get( "junit:junit-dep" );
}
private Artifact getJunitPlatformArtifact()
{
Artifact artifact = getProjectArtifactMap().get( getJunitPlatformArtifactName() );
Artifact projectArtifact = project.getArtifact();
String projectArtifactName = projectArtifact.getGroupId() + ":" + projectArtifact.getArtifactId();
if ( artifact == null && projectArtifactName.equals( getJunitPlatformArtifactName() ) )
{
artifact = projectArtifact;
}
return artifact;
}
private ForkStarter createForkStarter( @Nonnull ProviderInfo provider, @Nonnull ForkConfiguration forkConfiguration,
@Nonnull ClassLoaderConfiguration classLoaderConfiguration,
@Nonnull RunOrderParameters runOrderParameters, @Nonnull ConsoleLogger log,
......@@ -2337,6 +2397,7 @@ private String getConfigChecksum()
checksum.add( isDisableXmlReport() );
checksum.add( isUseSystemClassLoader() );
checksum.add( isUseManifestOnlyJar() );
checksum.add( getEncoding() );
checksum.add( isEnableAssertions() );
checksum.add( getObjectFactory() );
checksum.add( getFailIfNoTests() );
......@@ -2659,7 +2720,8 @@ private void warnIfDefunctGroupsCombinations()
{
Artifact junitArtifact = getJunitArtifact();
boolean junit47Compatible = isJunit47Compatible( junitArtifact );
if ( !junit47Compatible )
boolean junit5PlatformCompatible = getJunitPlatformArtifact() != null;
if ( !junit47Compatible && !junit5PlatformCompatible )
{
if ( junitArtifact != null )
{
......@@ -2668,8 +2730,8 @@ private void warnIfDefunctGroupsCombinations()
+ "Check your dependency:tree to see if your project "
+ "is picking up an old junit version" );
}
throw new MojoFailureException( "groups/excludedGroups require TestNG or JUnit48+ on project test "
+ "classpath" );
throw new MojoFailureException( "groups/excludedGroups require TestNG, JUnit48+ or JUnit 5 "
+ "on project test classpath" );
}
}
......@@ -2872,6 +2934,40 @@ public Classpath getProviderClasspath()
}
final class JUnitPlatformProviderInfo
implements ProviderInfo
{
private final Artifact junitArtifact;
JUnitPlatformProviderInfo( Artifact junitArtifact )
{
this.junitArtifact = junitArtifact;
}
@Nonnull public String getProviderName()
{
return "org.apache.maven.surefire.junitplatform.JUnitPlatformProvider";
}
public boolean isApplicable()
{
return junitArtifact != null;
}
public void addProviderProperties() throws MojoExecutionException
{
convertGroupParameters();
}
public Classpath getProviderClasspath()
throws ArtifactResolutionException, ArtifactNotFoundException
{
return dependencyResolver.getProviderClasspath( "surefire-junit-platform",
surefireBooterArtifact.getBaseVersion(),
null );
}
}
final class JUnitCoreProviderInfo
implements ProviderInfo
{
......@@ -3328,6 +3424,17 @@ public void setJunitArtifactName( String junitArtifactName )
this.junitArtifactName = junitArtifactName;
}
public String getJunitPlatformArtifactName()
{
return junitPlatformArtifactName;
}
@SuppressWarnings( "UnusedDeclaration" )
public void setJunitPlatformArtifactName( String junitPlatformArtifactName )
{
this.junitPlatformArtifactName = junitPlatformArtifactName;
}
public String getTestNGArtifactName()
{
return testNGArtifactName;
......
......@@ -72,14 +72,15 @@ private Object createStartupReportConfiguration( @Nonnull StartupReportConfigura
Constructor<?> constructor = getConstructor( startupReportConfiguration, boolean.class, boolean.class,
String.class, boolean.class, boolean.class, File.class,
boolean.class, String.class, File.class, boolean.class,
int.class, String.class );
int.class, String.class, String.class );
//noinspection BooleanConstructorCall
Object[] params = { reporterConfiguration.isUseFile(), reporterConfiguration.isPrintSummary(),
reporterConfiguration.getReportFormat(), reporterConfiguration.isRedirectTestOutputToFile(),
reporterConfiguration.isDisableXmlReport(), reporterConfiguration.getReportsDirectory(),
reporterConfiguration.isTrimStackTrace(), reporterConfiguration.getReportNameSuffix(),
reporterConfiguration.getStatisticsFile(), reporterConfiguration.isRequiresRunHistory(),
reporterConfiguration.getRerunFailingTestsCount(), reporterConfiguration.getXsdSchemaLocation() };
reporterConfiguration.getRerunFailingTestsCount(), reporterConfiguration.getXsdSchemaLocation(),
reporterConfiguration.getEncoding().name() };
return newInstance( constructor, params );
}
......
......@@ -30,12 +30,14 @@
import javax.annotation.Nonnull;
import java.io.File;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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;
/**
* All the parameters used to construct reporters
......@@ -80,6 +82,8 @@ public final class StartupReportConfiguration
private final Map<String, Map<String, List<WrappedReportEntry>>> testClassMethodRunHistory
= new ConcurrentHashMap<String, Map<String, List<WrappedReportEntry>>>();
private final Charset encoding;
private StatisticsReporter statisticsReporter;
@SuppressWarnings( "checkstyle:parameternumber" )
......@@ -87,7 +91,7 @@ public StartupReportConfiguration( boolean useFile, boolean printSummary, String
boolean redirectTestOutputToFile, boolean disableXmlReport,
@Nonnull File reportsDirectory, boolean trimStackTrace, String reportNameSuffix,
File statisticsFile, boolean requiresRunHistory,
int rerunFailingTestsCount, String xsdSchemaLocation )
int rerunFailingTestsCount, String xsdSchemaLocation, String encoding )
{
this.useFile = useFile;
this.printSummary = printSummary;
......@@ -103,32 +107,8 @@ public StartupReportConfiguration( boolean useFile, boolean printSummary, String
this.originalSystemErr = System.err;
this.rerunFailingTestsCount = rerunFailingTestsCount;
this.xsdSchemaLocation = xsdSchemaLocation;
}
/**
* For testing purposes only.
*
* @return StartupReportConfiguration fo testing purposes
*/
public static StartupReportConfiguration defaultValue()
{
File target = new File( "./target" );
File statisticsFile = new File( target, "TESTHASH" );
return new StartupReportConfiguration( true, true, "PLAIN", false, false, target, false, null, statisticsFile,
false, 0, null );
}
/**
* For testing purposes only.
*
* @return StartupReportConfiguration fo testing purposes
*/
public static StartupReportConfiguration defaultNoXml()
{
File target = new File( "./target" );
File statisticsFile = new File( target, "TESTHASHxXML" );
return new StartupReportConfiguration( true, true, "PLAIN", false, true, target, false, null, statisticsFile,
false, 0, null );
String charset = trimToNull( encoding );
this.encoding = charset == null ? Charset.defaultCharset() : Charset.forName( charset );
}
public boolean isUseFile()
......@@ -182,7 +162,7 @@ public StatelessXmlReporter instantiateStatelessXmlReporter()
public FileReporter instantiateFileReporter()
{
return isUseFile() && isBriefOrPlainFormat()
? new FileReporter( reportsDirectory, getReportNameSuffix() )
? new FileReporter( reportsDirectory, getReportNameSuffix(), encoding )
: null;
}
......@@ -232,4 +212,9 @@ public String getXsdSchemaLocation()
{
return xsdSchemaLocation;
}
public Charset getEncoding()
{
return encoding;
}
}
......@@ -118,6 +118,10 @@ public interface SurefireExecutionParameters
void setUseManifestOnlyJar( boolean useManifestOnlyJar );
String getEncoding();
void setEncoding( String encoding );
Boolean getFailIfNoSpecifiedTests();
void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests );
......
......@@ -37,7 +37,7 @@ abstract class AbstractClasspathForkConfiguration
{
@SuppressWarnings( "checkstyle:parameternumber" )
public AbstractClasspathForkConfiguration( @Nonnull Classpath bootClasspath,
AbstractClasspathForkConfiguration( @Nonnull Classpath bootClasspath,
@Nonnull File tempDirectory,
@Nullable String debugLine,
@Nonnull File workingDirectory,
......
......@@ -162,7 +162,7 @@ private final class CloseableCloser
private final Thread inputStreamCloserHook;
public CloseableCloser( int jvmRun, Closeable... testProvidingInputStream )
CloseableCloser( int jvmRun, Closeable... testProvidingInputStream )
{
this.jvmRun = jvmRun;
this.testProvidingInputStream = new ConcurrentLinkedQueue<Closeable>();
......
......@@ -22,17 +22,18 @@
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
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;
/**
* Surefire output consumer proxy that writes test output to a {@link java.io.File} for each test suite.
* <br>
* This class is not threadsafe, but can be serially handed off from thread to thread.
*
* @author Kristian Rosenvold
* @author Carlos Sanchez
......@@ -40,13 +41,20 @@
public class ConsoleOutputFileReporter
implements TestcycleConsoleOutputReceiver
{
private final File reportsDirectory;
private static final int STREAM_BUFFER_SIZE = 16 * 1024;
private static final int OPEN = 0;
private static final int CLOSED_TO_REOPEN = 1;
private static final int CLOSED = 2;
private final File reportsDirectory;
private final String reportNameSuffix;
private String reportEntryName;
private final AtomicStampedReference<FilterOutputStream> fileOutputStream =
new AtomicStampedReference<FilterOutputStream>( null, OPEN );
private OutputStream fileOutputStream;
private final ReentrantLock lock = new ReentrantLock();
private volatile String reportEntryName;
public ConsoleOutputFileReporter( File reportsDirectory, String reportNameSuffix )
{
......@@ -57,8 +65,15 @@ public ConsoleOutputFileReporter( File reportsDirectory, String reportNameSuffix
@Override
public void testSetStarting( ReportEntry reportEntry )
{
close();
reportEntryName = reportEntry.getName();
lock.lock();
try
{
closeNullReportFile( reportEntry );
}
finally
{
lock.unlock();
}
}
@Override
......@@ -67,39 +82,33 @@ public void testSetCompleted( ReportEntry report )
}
@Override
@SuppressWarnings( "checkstyle:emptyblock" )
public void close()
{
if ( fileOutputStream != null )
{
//noinspection EmptyCatchBlock
// The close() method is called in main Thread T2.
lock.lock();
try
{
fileOutputStream.flush();
}
catch ( IOException e )
{
closeReportFile();
}
finally
{
try
{
fileOutputStream.close();
}
catch ( IOException ignored )
{
}
}
fileOutputStream = null;
lock.unlock();
}
}
@Override
public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
{
lock.lock();
try
{
if ( fileOutputStream == null )
// This method is called in single thread T1 per fork JVM (see ThreadedStreamConsumer).
// The close() method is called in main Thread T2.
int[] status = new int[1];
FilterOutputStream os = fileOutputStream.get( status );
if ( status[0] != CLOSED )
{
if ( os == null )
{
if ( !reportsDirectory.exists() )
{
......@@ -107,13 +116,71 @@ public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
reportsDirectory.mkdirs();
}
File file = getReportFile( reportsDirectory, reportEntryName, reportNameSuffix, "-output.txt" );
fileOutputStream = new BufferedOutputStream( new FileOutputStream( file ), 16 * 1024 );
os = new BufferedOutputStream( new FileOutputStream( file ), STREAM_BUFFER_SIZE );
fileOutputStream.set( os, OPEN );
}
os.write( buf, off, len );
}
fileOutputStream.write( buf, off, len );
}
catch ( IOException e )
{
DumpErrorSingleton.getSingleton()
.dumpException( e );
throw new RuntimeException( e );
}
finally
{
lock.unlock();
}
}
@SuppressWarnings( "checkstyle:emptyblock" )
private void closeNullReportFile( ReportEntry reportEntry )
{
try
{
// close null-output.txt report file
close( true );
}
catch ( IOException ignored )
{
DumpErrorSingleton.getSingleton()
.dumpException( ignored );
}
finally
{
// prepare <class>-output.txt report file
reportEntryName = reportEntry.getName();
}
}
@SuppressWarnings( "checkstyle:emptyblock" )
private void closeReportFile()
{
try
{
close( false );
}
catch ( IOException ignored )
{
DumpErrorSingleton.getSingleton()
.dumpException( ignored );
}
}
private void close( boolean closeReattempt )
throws IOException
{
int[] status = new int[1];
FilterOutputStream os = fileOutputStream.get( status );
if ( status[0] != CLOSED )
{
fileOutputStream.set( null, closeReattempt ? CLOSED_TO_REOPEN : CLOSED );
if ( os != null && status[0] == OPEN )
{
os.close();
}
}
}
}
......@@ -22,7 +22,6 @@
import org.apache.maven.plugin.surefire.StartupReportConfiguration;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.log.api.Level;
import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.surefire.report.ReporterFactory;
......@@ -207,16 +206,6 @@ public RunStatistics getGlobalRunStatistics()
return globalStats;
}
/**
* For testing purposes only.
*
* @return DefaultReporterFactory for testing purposes
*/
public static DefaultReporterFactory defaultNoXml()
{
return new DefaultReporterFactory( StartupReportConfiguration.defaultNoXml(), new NullConsoleLogger() );
}
/**
* Get the result of a test based on all its runs. If it has success and failures/errors, then it is a flake;
* if it only has errors or failures, then count its result based on its first run
......@@ -258,14 +247,7 @@ else if ( resultType == ERROR )
}
else
{
if ( seenError )
{
return error;
}
else
{
return failure;
}
return seenError ? error : failure;
}
}
else if ( seenSuccess )
......
......@@ -24,9 +24,12 @@
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.List;
import static org.apache.maven.plugin.surefire.report.FileReporterUtils.stripIllegalFilenameChars;
......@@ -41,13 +44,14 @@
public class FileReporter
{
private final File reportsDirectory;
private final String reportNameSuffix;
private final Charset encoding;
public FileReporter( File reportsDirectory, String reportNameSuffix )
public FileReporter( File reportsDirectory, String reportNameSuffix, Charset encoding )
{
this.reportsDirectory = reportsDirectory;
this.reportNameSuffix = reportNameSuffix;
this.encoding = encoding;
}
private PrintWriter testSetStarting( ReportEntry report )
......@@ -61,7 +65,9 @@ private PrintWriter testSetStarting( ReportEntry report )
try
{
PrintWriter writer = new PrintWriter( new BufferedWriter( new FileWriter( reportFile ), 16 * 1024 ) );
Writer encodedStream = new OutputStreamWriter( new FileOutputStream( reportFile ), encoding );
PrintWriter writer = new PrintWriter( new BufferedWriter( encodedStream, 16 * 1024 ) );
writer.println( "-------------------------------------------------------------------------------" );
......@@ -77,7 +83,7 @@ private PrintWriter testSetStarting( ReportEntry report )
}
}
public static File getReportFile( File reportsDirectory, String reportEntryName, String reportNameSuffix,
static File getReportFile( File reportsDirectory, String reportEntryName, String reportNameSuffix,
String fileExtension )
{
String fileName =
......
......@@ -35,7 +35,7 @@ class NullFileReporter
private NullFileReporter()
{
super( null, null );
super( null, null, null );
}
@Override
......
......@@ -44,12 +44,13 @@
import static org.apache.commons.io.IOUtils.closeQuietly;
import static org.apache.maven.plugin.surefire.report.DefaultReporterFactory.TestResultType;
import static org.apache.maven.plugin.surefire.report.FileReporterUtils.stripIllegalFilenameChars;
import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS;
import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8;
import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
@SuppressWarnings( { "javadoc", "checkstyle:javadoctype" } )
// CHECKSTYLE_OFF: LineLength
/**
/*
* XML format reporter writing to <code>TEST-<i>reportName</i>[-<i>suffix</i>].xml</code> file like written and read
* by Ant's <a href="http://ant.apache.org/manual/Tasks/junit.html"><code>&lt;junit&gt;</code></a> and
* <a href="http://ant.apache.org/manual/Tasks/junitreport.html"><code>&lt;junitreport&gt;</code></a> tasks,
......@@ -146,13 +147,12 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat
{
if ( rerunFailingTestsCount > 0 )
{
TestResultType resultType = getTestResultType( methodEntryList );
switch ( resultType )
switch ( getTestResultType( methodEntryList ) )
{
case success:
for ( WrappedReportEntry methodEntry : methodEntryList )
{
if ( methodEntry.getReportEntryType() == ReportEntryType.SUCCESS )
if ( methodEntry.getReportEntryType() == SUCCESS )
{
startTestElement( ppw, methodEntry, reportNameSuffix,
methodEntryList.get( 0 ).elapsedTimeAsString() );
......@@ -188,7 +188,7 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat
// Get the run time of the first successful run
for ( WrappedReportEntry singleRunEntry : methodEntryList )
{
if ( singleRunEntry.getReportEntryType() == ReportEntryType.SUCCESS )
if ( singleRunEntry.getReportEntryType() == SUCCESS )
{
runtime = singleRunEntry.elapsedTimeAsString();
break;
......@@ -197,7 +197,7 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat
startTestElement( ppw, methodEntryList.get( 0 ), reportNameSuffix, runtime );
for ( WrappedReportEntry singleRunEntry : methodEntryList )
{
if ( singleRunEntry.getReportEntryType() != ReportEntryType.SUCCESS )
if ( singleRunEntry.getReportEntryType() != SUCCESS )
{
getTestProblems( fw, ppw, singleRunEntry, trimStackTrace, outputStream,
singleRunEntry.getReportEntryType().getFlakyXmlTag(), true );
......@@ -224,7 +224,7 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat
for ( WrappedReportEntry methodEntry : methodEntryList )
{
startTestElement( ppw, methodEntry, reportNameSuffix, methodEntry.elapsedTimeAsString() );
if ( methodEntry.getReportEntryType() != ReportEntryType.SUCCESS )
if ( methodEntry.getReportEntryType() != SUCCESS )
{
getTestProblems( fw, ppw, methodEntry, trimStackTrace, outputStream,
methodEntry.getReportEntryType().getXmlTag(), false );
......@@ -502,12 +502,12 @@ private static final class EncodingOutputStream
private int c2;
public EncodingOutputStream( OutputStream out )
EncodingOutputStream( OutputStream out )
{
super( out );
}
public OutputStream getUnderlying()
OutputStream getUnderlying()
{
return out;
}
......
......@@ -160,12 +160,12 @@ public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
{
testStdErr.write( buf, off, len );
}
consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
}
catch ( IOException e )
{
throw new RuntimeException( e );
}
consoleOutputReceiver.writeTestOutput( buf, off, len, stdout );
}
@Override
......@@ -176,7 +176,7 @@ public void testSetStarting( TestSetReportEntry report )
consoleOutputReceiver.testSetStarting( report );
}
public void clearCapture()
private void clearCapture()
{
testStdOut = initDeferred( "stdout" );
testStdErr = initDeferred( "stderr" );
......@@ -248,7 +248,6 @@ public void testFailed( ReportEntry reportEntry )
public void testSkipped( ReportEntry reportEntry )
{
WrappedReportEntry wrapped = wrap( reportEntry, SKIPPED );
detailsForThis.testSkipped( wrapped );
statisticsReporter.testSkipped( reportEntry );
clearCapture();
......@@ -267,21 +266,11 @@ public void testAssumptionFailure( ReportEntry report )
private WrappedReportEntry wrap( ReportEntry other, ReportEntryType reportEntryType )
{
final int estimatedElapsed;
int estimatedElapsed = 0;
if ( reportEntryType != SKIPPED )
{
if ( other.getElapsed() != null )
{
estimatedElapsed = other.getElapsed();
}
else
{
estimatedElapsed = detailsForThis.getElapsedSinceLastStart();
}
}
else
{
estimatedElapsed = 0;
Integer etime = other.getElapsed();
estimatedElapsed = etime == null ? detailsForThis.getElapsedSinceLastStart() : etime;
}
return new WrappedReportEntry( other, reportEntryType, estimatedElapsed, testStdOut, testStdErr );
......@@ -299,7 +288,7 @@ public void close()
consoleOutputReceiver.close();
}
public void addTestMethodStats()
private void addTestMethodStats()
{
for ( WrappedReportEntry reportEntry : detailsForThis.getReportEntries() )
{
......@@ -315,7 +304,7 @@ public List<TestMethodStats> getTestMethodStats()
return testMethodStats;
}
public static String trimTrailingNewLine( final String message )
private static String trimTrailingNewLine( final String message )
{
final int e = message == null ? 0 : lineBoundSymbolWidth( message );
return message != null && e != 0 ? message.substring( 0, message.length() - e ) : message;
......
......@@ -93,19 +93,16 @@ public void testStart()
lastStartAt = testStartAt;
}
private long finishTest( WrappedReportEntry reportEntry )
private void finishTest( WrappedReportEntry reportEntry )
{
reportEntries.add( reportEntry );
incrementCompletedCount();
long testEndAt = System.currentTimeMillis();
// SUREFIRE-398 skipped tests call endTest without calling testStarting
// if startTime = 0, set it to endTime, so the diff will be 0
if ( testStartAt == 0 )
{
testStartAt = testEndAt;
testStartAt = System.currentTimeMillis();
}
Integer elapsedTime = reportEntry.getElapsed();
return elapsedTime != null ? elapsedTime : testEndAt - testStartAt;
}
public void testSucceeded( WrappedReportEntry reportEntry )
......@@ -167,11 +164,6 @@ public int getSkipped()
return skipped;
}
public String elapsedTimeAsString( long runTime )
{
return ReporterUtils.formatElapsedTime( runTime );
}
private void incrementCompletedCount()
{
completedCount += 1;
......@@ -284,6 +276,7 @@ else if ( plainFormat && testResult.isSucceeded() )
result.add( testResult.getElapsedTimeSummary() );
}
}
// This should be Map with an enum and the enums will be displayed with colors on console.
return result;
}
......@@ -300,7 +293,7 @@ public Collection<WrappedReportEntry> getReportEntries()
* @param report report whose test set is starting
* @return the message
*/
public static String concatenateWithTestGroup( MessageBuilder builder, ReportEntry report )
static String concatenateWithTestGroup( MessageBuilder builder, ReportEntry report )
{
final String testClass = report.getNameWithGroup();
int delimiter = testClass.lastIndexOf( '.' );
......
......@@ -28,11 +28,9 @@
public interface TestcycleConsoleOutputReceiver
extends ConsoleOutputReceiver
{
void testSetStarting( ReportEntry reportEntry );
void testSetCompleted( ReportEntry report );
void close();
}
......@@ -42,7 +42,7 @@ class Utf8RecodingDeferredFileOutputStream
private boolean closed = false;
@SuppressWarnings( "checkstyle:magicnumber" )
public Utf8RecodingDeferredFileOutputStream( String channel )
Utf8RecodingDeferredFileOutputStream( String channel )
{
this.deferredFileOutputStream = new DeferredFileOutputStream( 1000000, channel, "deferred", null );
}
......