Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SUREFIRE-1937] [SUREFIRE-1938] [SUREFIRE-1980] [SUREFIRE-1981] #444

Merged
merged 4 commits into from Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -28,6 +28,7 @@
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.api.util.internal.ImmutableMap;
import org.apache.maven.surefire.shared.utils.cli.CommandLineException;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -133,35 +134,42 @@ public OutputStreamFlushableCommandline createCommandLine( @Nonnull StartupConfi
@Nonnull File dumpLogDirectory )
throws SurefireBooterForkException
{
OutputStreamFlushableCommandline cli =
new OutputStreamFlushableCommandline( getExcludedEnvironmentVariables() );
try
{
OutputStreamFlushableCommandline cli =
new OutputStreamFlushableCommandline( getExcludedEnvironmentVariables() );

cli.setWorkingDirectory( getWorkingDirectory( forkNumber ).getAbsolutePath() );
cli.setWorkingDirectory( getWorkingDirectory( forkNumber ).getAbsolutePath() );

for ( Entry<String, String> entry : getEnvironmentVariables().entrySet() )
{
String value = entry.getValue();
cli.addEnvironment( entry.getKey(), value == null ? "" : value );
}
for ( Entry<String, String> entry : getEnvironmentVariables().entrySet() )
{
String value = entry.getValue();
cli.addEnvironment( entry.getKey(), value == null ? "" : value );
}

cli.setExecutable( getJdkForTests().getJvmExecutable().getAbsolutePath() );
cli.setExecutable( getJdkForTests().getJvmExecutable().getAbsolutePath() );

String jvmArgLine = newJvmArgLine( forkNumber );
if ( !jvmArgLine.isEmpty() )
{
cli.createArg()
.setLine( jvmArgLine );
}
String jvmArgLine = newJvmArgLine( forkNumber );
if ( !jvmArgLine.isEmpty() )
{
cli.createArg()
.setLine( jvmArgLine );
}

if ( getDebugLine() != null && !getDebugLine().isEmpty() )
{
cli.createArg()
.setLine( getDebugLine() );
}
if ( getDebugLine() != null && !getDebugLine().isEmpty() )
{
cli.createArg()
.setLine( getDebugLine() );
}

resolveClasspath( cli, findStartClass( config ), config, dumpLogDirectory );
resolveClasspath( cli, findStartClass( config ), config, dumpLogDirectory );

return cli;
return cli;
}
catch ( CommandLineException e )
{
throw new SurefireBooterForkException( e.getLocalizedMessage(), e );
}
}

protected ConsoleLogger getLogger()
Expand Down
Expand Up @@ -21,7 +21,6 @@

import org.apache.maven.surefire.api.event.Event;
import org.apache.maven.surefire.extensions.EventHandler;
import org.apache.maven.surefire.shared.utils.cli.StreamConsumer;

import javax.annotation.Nonnull;
import java.io.Closeable;
Expand Down Expand Up @@ -69,7 +68,7 @@ final class Pumper
/**
* Calls {@link ForkClient#handleEvent(Event)} which may throw any {@link RuntimeException}.<br>
* Even if {@link ForkClient} is not fault-tolerant, this method MUST be fault-tolerant and thus the
* try-catch block must be inside of the loop which prevents from loosing events from {@link StreamConsumer}.
* try-catch block must be inside of the loop which prevents from loosing events from {@link EventHandler}.
* <br>
* If {@link org.apache.maven.plugin.surefire.report.ConsoleOutputFileReporter#writeTestOutput} throws
* {@link java.io.IOException} and then {@code target.consumeLine()} throws any RuntimeException, this method
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.apache.maven.surefire.shared.utils.xml.PrettyPrintXMLWriter;
import org.apache.maven.surefire.shared.utils.xml.XMLWriter;
import org.apache.maven.surefire.extensions.StatelessReportEventListener;
import org.apache.maven.surefire.api.report.ReporterException;
import org.apache.maven.surefire.api.report.SafeThrowable;

import java.io.BufferedOutputStream;
Expand Down Expand Up @@ -135,8 +134,10 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat
Map<String, Map<String, List<WrappedReportEntry>>> classMethodStatistics =
arrangeMethodStatistics( testSetReportEntry, testSetStats );

OutputStream outputStream = getOutputStream( testSetReportEntry );
try ( OutputStreamWriter fw = getWriter( outputStream ) )
// The Java Language Spec:
// "Note that the close methods of resources are called in the opposite order of their creation."
try ( OutputStream outputStream = getOutputStream( testSetReportEntry );
OutputStreamWriter fw = getWriter( outputStream ) )
{
XMLWriter ppw = new PrettyPrintXMLWriter( fw );
ppw.setEncoding( UTF_8.name() );
Expand All @@ -155,7 +156,7 @@ public void testSetCompleted( WrappedReportEntry testSetReportEntry, TestSetStat

ppw.endElement(); // TestSuite
}
catch ( Exception e )
catch ( IOException e )
{
// It's not a test error.
// This method must be sail-safe and errors are in a dump log.
Expand Down Expand Up @@ -201,6 +202,7 @@ private Deque<WrappedReportEntry> aggregateCacheFromMultipleReruns( WrappedRepor

private void serializeTestClass( OutputStream outputStream, OutputStreamWriter fw, XMLWriter ppw,
List<WrappedReportEntry> methodEntries )
throws IOException
{
if ( rerunFailingTestsCount > 0 )
{
Expand All @@ -216,6 +218,7 @@ private void serializeTestClass( OutputStream outputStream, OutputStreamWriter f

private void serializeTestClassWithoutRerun( OutputStream outputStream, OutputStreamWriter fw, XMLWriter ppw,
List<WrappedReportEntry> methodEntries )
throws IOException
{
for ( WrappedReportEntry methodEntry : methodEntries )
{
Expand All @@ -232,6 +235,7 @@ private void serializeTestClassWithoutRerun( OutputStream outputStream, OutputSt

private void serializeTestClassWithRerun( OutputStream outputStream, OutputStreamWriter fw, XMLWriter ppw,
List<WrappedReportEntry> methodEntries )
throws IOException
{
WrappedReportEntry firstMethodEntry = methodEntries.get( 0 );
switch ( getTestResultType( methodEntries ) )
Expand Down Expand Up @@ -339,22 +343,15 @@ private Deque<WrappedReportEntry> getAddMethodRunHistoryMap( String testClassNam
}

private OutputStream getOutputStream( WrappedReportEntry testSetReportEntry )
throws IOException
{
File reportFile = getReportFile( testSetReportEntry );

File reportDir = reportFile.getParentFile();

//noinspection ResultOfMethodCallIgnored
reportDir.mkdirs();

try
{
return new BufferedOutputStream( new FileOutputStream( reportFile ), 64 * 1024 );
}
catch ( Exception e )
{
throw new ReporterException( "When writing report", e );
}
return new BufferedOutputStream( new FileOutputStream( reportFile ), 64 * 1024 );
}

private static OutputStreamWriter getWriter( OutputStream fos )
Expand All @@ -370,6 +367,7 @@ private File getReportFile( WrappedReportEntry report )
}

private void startTestElement( XMLWriter ppw, WrappedReportEntry report )
throws IOException
{
ppw.startElement( "testcase" );
String name = phrasedMethodName ? report.getReportName() : report.getName();
Expand All @@ -391,6 +389,7 @@ private void startTestElement( XMLWriter ppw, WrappedReportEntry report )
}

private void createTestSuiteElement( XMLWriter ppw, WrappedReportEntry report, TestSetStats testSetStats )
throws IOException
{
ppw.startElement( "testsuite" );

Expand Down Expand Up @@ -421,6 +420,7 @@ private void createTestSuiteElement( XMLWriter ppw, WrappedReportEntry report, T
private static void getTestProblems( OutputStreamWriter outputStreamWriter, XMLWriter ppw,
WrappedReportEntry report, boolean trimStackTrace, OutputStream fw,
String testErrorType, boolean createOutErrElementsInside )
throws IOException
{
ppw.startElement( testErrorType );

Expand Down Expand Up @@ -478,6 +478,7 @@ private static void getTestProblems( OutputStreamWriter outputStreamWriter, XMLW
// Create system-out and system-err elements
private static void createOutErrElements( OutputStreamWriter outputStreamWriter, XMLWriter ppw,
WrappedReportEntry report, OutputStream fw )
throws IOException
{
EncodingOutputStream eos = new EncodingOutputStream( fw );
addOutputStreamElement( outputStreamWriter, eos, ppw, report.getStdout(), "system-out" );
Expand All @@ -488,24 +489,17 @@ private static void addOutputStreamElement( OutputStreamWriter outputStreamWrite
EncodingOutputStream eos, XMLWriter xmlWriter,
Utf8RecodingDeferredFileOutputStream utf8RecodingDeferredFileOutputStream,
String name )
throws IOException
{
if ( utf8RecodingDeferredFileOutputStream != null && utf8RecodingDeferredFileOutputStream.getByteCount() > 0 )
{
xmlWriter.startElement( name );

try
{
xmlWriter.writeText( "" ); // Cheat sax to emit element
outputStreamWriter.flush();
eos.getUnderlying().write( ByteConstantsHolder.CDATA_START_BYTES ); // emit cdata
utf8RecodingDeferredFileOutputStream.writeTo( eos );
eos.getUnderlying().write( ByteConstantsHolder.CDATA_END_BYTES );
eos.flush();
}
catch ( IOException e )
{
throw new ReporterException( "When writing xml report stdout/stderr", e );
}
xmlWriter.writeText( "" ); // Cheat sax to emit element
outputStreamWriter.flush();
eos.getUnderlying().write( ByteConstantsHolder.CDATA_START_BYTES ); // emit cdata
utf8RecodingDeferredFileOutputStream.writeTo( eos );
eos.getUnderlying().write( ByteConstantsHolder.CDATA_END_BYTES );
eos.flush();
xmlWriter.endElement();
}
}
Expand All @@ -517,6 +511,7 @@ private static void addOutputStreamElement( OutputStreamWriter outputStreamWrite
* @param xmlWriter The test suite to report to
*/
private static void showProperties( XMLWriter xmlWriter, Map<String, String> systemProperties )
throws IOException
{
xmlWriter.startElement( "properties" );
for ( final Entry<String, String> entry : systemProperties.entrySet() )
Expand Down Expand Up @@ -559,6 +554,7 @@ private static String extraEscapeAttribute( String message )
*/
private static void extraEscapeElementValue( String message, OutputStreamWriter outputStreamWriter,
XMLWriter xmlWriter, OutputStream fw )
throws IOException
{
// Someday convert to xml 1.1 which handles everything but 0 inside string
if ( containsEscapesIllegalXml10( message ) )
Expand All @@ -567,20 +563,13 @@ private static void extraEscapeElementValue( String message, OutputStreamWriter
}
else
{
try
{
EncodingOutputStream eos = new EncodingOutputStream( fw );
xmlWriter.writeText( "" ); // Cheat sax to emit element
outputStreamWriter.flush();
eos.getUnderlying().write( ByteConstantsHolder.CDATA_START_BYTES );
eos.write( message.getBytes( UTF_8 ) );
eos.getUnderlying().write( ByteConstantsHolder.CDATA_END_BYTES );
eos.flush();
}
catch ( IOException e )
{
throw new ReporterException( "When writing xml element", e );
}
EncodingOutputStream eos = new EncodingOutputStream( fw );
xmlWriter.writeText( "" ); // Cheat sax to emit element
outputStreamWriter.flush();
eos.getUnderlying().write( ByteConstantsHolder.CDATA_START_BYTES );
eos.write( message.getBytes( UTF_8 ) );
eos.getUnderlying().write( ByteConstantsHolder.CDATA_END_BYTES );
eos.flush();
}
}

Expand Down
Expand Up @@ -32,7 +32,6 @@
import org.apache.maven.surefire.booter.SurefireBooterForkException;
import org.apache.maven.surefire.extensions.ForkNodeFactory;
import org.apache.maven.surefire.shared.io.FileUtils;
import org.apache.maven.surefire.shared.lang3.SystemUtils;
import org.apache.maven.surefire.shared.utils.StringUtils;
import org.apache.maven.surefire.shared.utils.cli.Commandline;
import org.junit.After;
Expand All @@ -56,6 +55,7 @@
import static org.apache.maven.surefire.api.util.internal.StringUtils.NL;
import static org.apache.maven.surefire.booter.Classpath.emptyClasspath;
import static org.apache.maven.surefire.booter.ProcessCheckerType.ALL;
import static org.apache.maven.surefire.shared.lang3.SystemUtils.IS_OS_WINDOWS;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.util.Files.temporaryFolder;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -168,11 +168,7 @@ public void testCliArgs() throws Exception
// "/path/to/java arg1 @/path/to/argfile"
int beginOfFileArg = cliAsString.indexOf( '@', cliAsString.lastIndexOf( "arg1" ) );
assertThat( beginOfFileArg ).isPositive();
int endOfFileArg = cliAsString.indexOf( '"', beginOfFileArg );
if ( endOfFileArg == -1 )
{
endOfFileArg = cliAsString.length();
}
int endOfFileArg = cliAsString.indexOf( IS_OS_WINDOWS ? '"' : '\'', beginOfFileArg );
assertThat( endOfFileArg ).isPositive();
Path argFile = Paths.get( cliAsString.substring( beginOfFileArg + 1, endOfFileArg ) );
String argFileText = new String( readAllBytes( argFile ) );
Expand Down Expand Up @@ -283,7 +279,7 @@ public void testArglineWithNewline()
new StartupConfiguration( "", cpConfig, clc, ALL, Collections.<String[]>emptyList() );

Commandline commandLine = config.createCommandLine( startup, 1, temporaryFolder() );
assertTrue( commandLine.toString().contains( "abc def" ) );
assertThat( commandLine.toString() ).contains( IS_OS_WINDOWS ? "abc def" : "'abc' 'def'" );
}

@Test
Expand Down Expand Up @@ -357,7 +353,7 @@ public void testExceptionWhenCurrentDirectoryCannotBeCreated()
FileUtils.deleteDirectory( cwd );
}

if ( SystemUtils.IS_OS_WINDOWS || isJavaVersionAtLeast7u60() )
if ( IS_OS_WINDOWS || isJavaVersionAtLeast7u60() )
{
fail();
}
Expand Down
14 changes: 7 additions & 7 deletions pom.xml
Expand Up @@ -89,15 +89,14 @@
<properties>
<javaVersion>8</javaVersion>
<mavenVersion>3.2.5</mavenVersion>
<!-- <shadedVersion>3.0.0-M2</shadedVersion> commented out due to https://issues.apache.org/jira/browse/MRELEASE-799 -->
<commonsLang3Version>3.8.1</commonsLang3Version>
<commonsCompress>1.20</commonsCompress>
<commonsIoVersion>2.6</commonsIoVersion>
<commonsLang3Version>3.12.0</commonsLang3Version>
<commonsCompress>1.21</commonsCompress>
<commonsIoVersion>2.11.0</commonsIoVersion>
<doxiaVersion>1.11.1</doxiaVersion>
<doxiaSitetoolsVersion>1.11.1</doxiaSitetoolsVersion>
<plexus-java-version>1.1.0</plexus-java-version>
<!-- maven-shared-utils:3.2.0+ another behavior - broke Surefire performance - end of subprocess notification not arrived in ForkStarter -->
<mavenSharedUtilsVersion>3.1.0</mavenSharedUtilsVersion>
<!-- maven-shared-utils:3.3.4 uses org.fusesource.jansi:jansi:2.2.0 -->
<mavenSharedUtilsVersion>3.3.4</mavenSharedUtilsVersion>
<powermockVersion>2.0.9</powermockVersion>
<mavenPluginToolsVersion>3.6.2</mavenPluginToolsVersion>
<jacocoVersion>0.8.7</jacocoVersion>
Expand Down Expand Up @@ -258,9 +257,10 @@
<version>2.33</version>
</dependency>
<dependency>
<!-- used in the unit tests and maven-shared-utils:3.3.4 -->
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<version>1.13</version>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
Expand Down
Expand Up @@ -87,7 +87,7 @@ private void verifyReportA( OutputValidator outputValidator )
{
String xmlReport = outputValidator.getSurefireReportsXmlFile( "TEST-ATest.xml" ).readFileToString();

String outputCData = "<system-out><![CDATA[Hi" + NL + NL + "There!" + NL + "]]></system-out>" + NL + " "
String outputCData = "<system-out><![CDATA[Hi" + NL + NL + "There!" + NL + "]]></system-out>\n "
+ "<system-err><![CDATA[Hello" + NL + NL + "What's up!" + NL + "]]></system-err>";

assertThat( xmlReport ).contains( outputCData );
Expand Down