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 2021/03/31 09:42:42 UTC
[maven-surefire] branch master updated: [SUREFIRE-1659] Log4j
logger in TestExecutionListener corrupts Surefire's STDOUT
This is an automated email from the ASF dual-hosted git repository.
tibordigana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git
The following commit(s) were added to refs/heads/master by this push:
new 0ec1283 [SUREFIRE-1659] Log4j logger in TestExecutionListener corrupts Surefire's STDOUT
0ec1283 is described below
commit 0ec1283c1652408cae53650eebdd0c33f876a807
Author: Xavier Dury <ka...@hotmail.com>
AuthorDate: Fri Mar 26 15:43:56 2021 +0100
[SUREFIRE-1659] Log4j logger in TestExecutionListener corrupts
Surefire's STDOUT
---
.../its/JUnitPlatformStreamCorruptionIT.java | 30 ++++++++
.../surefire-1659-stream-corruption/pom.xml | 88 ++++++++++++++++++++++
.../com/example/demo/JUnitPlatformSampleTest.java | 17 +++++
.../src/test/resources/jul-to-slf4j.properties | 1 +
.../src/test/resources/junit-platform.properties | 1 +
.../src/test/resources/log4j2.xml | 13 ++++
.../src/test/resources/logback-test.xml | 11 +++
.../junitplatform/JUnitPlatformProvider.java | 3 +-
.../maven/surefire/junitplatform/LazyLauncher.java | 64 ++++++++++++++++
9 files changed, 226 insertions(+), 2 deletions(-)
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformStreamCorruptionIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformStreamCorruptionIT.java
index 67ba567..160170e 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformStreamCorruptionIT.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformStreamCorruptionIT.java
@@ -57,4 +57,34 @@ public class JUnitPlatformStreamCorruptionIT
assertThat( lines )
.isEmpty();
}
+
+ @Test
+ public void warningIsNotEmittedWithJulToSlf4j() throws VerificationException
+ {
+ OutputValidator validator = unpack( "/surefire-1659-stream-corruption" )
+ .activateProfile( "junit-platform-with-jul-to-slf4j" )
+ .executeTest()
+ .verifyErrorFree( 1 );
+
+ List<String> lines = validator.loadLogLines(
+ startsWith( "[WARNING] Corrupted STDOUT by directly writing to native stream in forked JVM" ) );
+
+ assertThat( lines )
+ .isEmpty();
+ }
+
+ @Test
+ public void warningIsNotEmittedWithJulToLog4j() throws VerificationException
+ {
+ OutputValidator validator = unpack( "/surefire-1659-stream-corruption" )
+ .activateProfile( "junit-platform-with-jul-to-log4j" )
+ .executeTest()
+ .verifyErrorFree( 1 );
+
+ List<String> lines = validator.loadLogLines(
+ startsWith( "[WARNING] Corrupted STDOUT by directly writing to native stream in forked JVM" ) );
+
+ assertThat( lines )
+ .isEmpty();
+ }
}
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/pom.xml b/surefire-its/src/test/resources/surefire-1659-stream-corruption/pom.xml
new file mode 100644
index 0000000..1184931
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/pom.xml
@@ -0,0 +1,88 @@
+<?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-1659] Log4j logger in TestExecutionListener corrupts Surefire's STDOUT.</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>${java.specification.version}</maven.compiler.source>
+ <maven.compiler.target>${java.specification.version}</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>5.7.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>junit-platform-with-jul-to-slf4j</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <systemPropertyVariables>
+ <java.util.logging.config.file>${project.basedir}/src/test/resources/jul-to-slf4j.properties</java.util.logging.config.file>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>1.7.25</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.2.3</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>junit-platform-with-jul-to-log4j</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <systemPropertyVariables>
+ <java.util.logging.manager>org.apache.logging.log4j.jul.LogManager</java.util.logging.manager>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ <version>2.13.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-jul</artifactId>
+ <version>2.13.1</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/java/com/example/demo/JUnitPlatformSampleTest.java b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/java/com/example/demo/JUnitPlatformSampleTest.java
new file mode 100644
index 0000000..f0359bb
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/java/com/example/demo/JUnitPlatformSampleTest.java
@@ -0,0 +1,17 @@
+package com.example.demo;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.logging.Logger;
+
+public class JUnitPlatformSampleTest
+{
+
+ @Test
+ public void sampleTest()
+ {
+ Logger.getLogger( getClass().getName() ).info( "running test" );
+ Assertions.assertTrue( true );
+ }
+}
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/jul-to-slf4j.properties b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/jul-to-slf4j.properties
new file mode 100644
index 0000000..637a886
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/jul-to-slf4j.properties
@@ -0,0 +1 @@
+handlers = org.slf4j.bridge.SLF4JBridgeHandler
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/junit-platform.properties b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/junit-platform.properties
new file mode 100644
index 0000000..648ee97
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/junit-platform.properties
@@ -0,0 +1 @@
+# This file is needed in order for JUnit to log something early on org.junit.platform.launcher.core.LauncherConfigurationParameters
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/log4j2.xml b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/log4j2.xml
new file mode 100644
index 0000000..a5185ce
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/log4j2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="INFO">
+ <Appenders>
+ <Console name="console" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
+ </Console>
+ </Appenders>
+ <Loggers>
+ <Root level="info" additivity="false">
+ <AppenderRef ref="console"/>
+ </Root>
+ </Loggers>
+</Configuration>
diff --git a/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/logback-test.xml b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..35d1b19
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1659-stream-corruption/src/test/resources/logback-test.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <root level="INFO">
+ <appender-ref ref="STDOUT"/>
+ </root>
+</configuration>
diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
index 5bd3ee4..6853a3e 100644
--- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
+++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
@@ -65,7 +65,6 @@ import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TagFilter;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
-import org.junit.platform.launcher.core.LauncherFactory;
/**
* JUnit 5 Platform Provider.
@@ -87,7 +86,7 @@ public class JUnitPlatformProvider
public JUnitPlatformProvider( ProviderParameters parameters )
{
- this( parameters, LauncherFactory.create() );
+ this( parameters, new LazyLauncher() );
}
JUnitPlatformProvider( ProviderParameters parameters, Launcher launcher )
diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java
new file mode 100644
index 0000000..45c9c49
--- /dev/null
+++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/LazyLauncher.java
@@ -0,0 +1,64 @@
+package org.apache.maven.surefire.junitplatform;
+
+/*
+ * 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.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.LauncherDiscoveryRequest;
+import org.junit.platform.launcher.TestExecutionListener;
+import org.junit.platform.launcher.TestPlan;
+import org.junit.platform.launcher.core.LauncherFactory;
+
+/**
+ * Launcher proxy which delays the most possible the initialization of the real JUnit
+ * Launcher in order to avoid stream/stdout corruption due to early logging.
+ */
+class LazyLauncher implements Launcher
+{
+
+ private Launcher launcher;
+
+ @Override
+ public void registerTestExecutionListeners( TestExecutionListener... testExecutionListeners )
+ {
+ launcher().registerTestExecutionListeners( testExecutionListeners );
+ }
+
+ @Override
+ public TestPlan discover( LauncherDiscoveryRequest launcherDiscoveryRequest )
+ {
+ return launcher().discover( launcherDiscoveryRequest );
+ }
+
+ @Override
+ public void execute( LauncherDiscoveryRequest launcherDiscoveryRequest,
+ TestExecutionListener... testExecutionListeners )
+ {
+ launcher().execute( launcherDiscoveryRequest, testExecutionListeners );
+ }
+
+ private Launcher launcher()
+ {
+ if ( launcher == null )
+ {
+ launcher = LauncherFactory.create();
+ }
+ return launcher;
+ }
+}