Skip to content

Commit

Permalink
[SUREFIRE-1614] JUnit Runner that writes to System.out corrupts Suref…
Browse files Browse the repository at this point in the history
…ire's STDOUT when using JUnit's Vintage Engine
  • Loading branch information
sormuras authored and snicoll committed Mar 13, 2019
1 parent af417b8 commit 18b4078
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.apache.maven.surefire.its;

/*
* 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.it.VerificationException;
import org.apache.maven.surefire.its.fixture.OutputValidator;
import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaVersion;
import static org.fest.assertions.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.startsWith;

public class JUnitPlatformStreamCorruptionIT
extends SurefireJUnit4IntegrationTestCase
{
@Before
public void setUp()
{
assumeJavaVersion( 1.8d );
}

@Test
public void warningIsNotEmitted() throws VerificationException
{
OutputValidator validator = unpack( "/surefire-1614-stream-corruption" )
.executeTest()
.verifyErrorFree( 1 );

List<String> lines = validator.loadLogLines(
startsWith( "[WARNING] Corrupted STDOUT by directly writing to native stream in forked JVM" ) );

assertThat( lines )
.isEmpty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.plugins.surefire</groupId>
<artifactId>junit-platform-1.0.0</artifactId>
<version>1.0</version>
<name>[SUREFIRE-1614] JUnit 5: Vintage Output Stream Corruption</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.3.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.demo;

import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.TestClass;

public class CustomRunner
extends BlockJUnit4ClassRunner
{

public CustomRunner( Class<?> klass ) throws InitializationError
{
super( klass );
}

@Override
protected TestClass createTestClass( Class<?> testClass )
{
System.out.println( "Creating test class" );
return super.createTestClass( testClass );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith( CustomRunner.class )
public class SurefireStreamCorruptionTest
{
@Test
public void contextLoads()
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import static java.util.stream.Collectors.toList;
import static org.apache.maven.surefire.booter.ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP;
import static org.apache.maven.surefire.booter.ProviderParameterNames.TESTNG_GROUPS_PROP;
import static org.apache.maven.surefire.report.ConsoleOutputCapture.startCapture;
import static org.apache.maven.surefire.util.TestsToRun.fromClass;
import static org.junit.platform.commons.util.StringUtils.isBlank;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request;
Expand All @@ -44,7 +46,6 @@

import org.apache.maven.surefire.providerapi.AbstractProvider;
import org.apache.maven.surefire.providerapi.ProviderParameters;
import org.apache.maven.surefire.report.ConsoleOutputCapture;
import org.apache.maven.surefire.report.ConsoleOutputReceiver;
import org.apache.maven.surefire.report.ReporterException;
import org.apache.maven.surefire.report.ReporterFactory;
Expand Down Expand Up @@ -104,22 +105,35 @@ public Iterable<Class<?>> getSuites()
public RunResult invoke( Object forkTestSet )
throws TestSetFailedException, ReporterException
{
if ( forkTestSet instanceof TestsToRun )
{
return invokeAllTests( (TestsToRun) forkTestSet );
}
else if ( forkTestSet instanceof Class )
{
return invokeAllTests( TestsToRun.fromClass( (Class<?>) forkTestSet ) );
}
else if ( forkTestSet == null )
ReporterFactory reporterFactory = parameters.getReporterFactory();
final RunResult runResult;
try
{
return invokeAllTests( scanClasspath() );
RunListener runListener = reporterFactory.createReporter();
startCapture( ( ConsoleOutputReceiver ) runListener );
if ( forkTestSet instanceof TestsToRun )
{
invokeAllTests( (TestsToRun) forkTestSet, runListener );
}
else if ( forkTestSet instanceof Class )
{
invokeAllTests( fromClass( ( Class<?> ) forkTestSet ), runListener );
}
else if ( forkTestSet == null )
{
invokeAllTests( scanClasspath(), runListener );
}
else
{
throw new IllegalArgumentException(
"Unexpected value of forkTestSet: " + forkTestSet );
}
}
else
finally
{
throw new IllegalArgumentException( "Unexpected value of forkTestSet: " + forkTestSet );
runResult = reporterFactory.close();
}
return runResult;
}

private TestsToRun scanClasspath()
Expand All @@ -130,22 +144,10 @@ private TestsToRun scanClasspath()
return parameters.getRunOrderCalculator().orderTestClasses( scannedClasses );
}

private RunResult invokeAllTests( TestsToRun testsToRun )
private void invokeAllTests( TestsToRun testsToRun, RunListener runListener )
{
RunResult runResult;
ReporterFactory reporterFactory = parameters.getReporterFactory();
try
{
RunListener runListener = reporterFactory.createReporter();
ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) runListener );
LauncherDiscoveryRequest discoveryRequest = buildLauncherDiscoveryRequest( testsToRun );
launcher.execute( discoveryRequest, new RunListenerAdapter( runListener ) );
}
finally
{
runResult = reporterFactory.close();
}
return runResult;
LauncherDiscoveryRequest discoveryRequest = buildLauncherDiscoveryRequest( testsToRun );
launcher.execute( discoveryRequest, new RunListenerAdapter( runListener ) );
}

private LauncherDiscoveryRequest buildLauncherDiscoveryRequest( TestsToRun testsToRun )
Expand Down

0 comments on commit 18b4078

Please sign in to comment.