Repository: maven-surefire Updated Branches: refs/heads/SUREFIRE-1367 34a5c1d4b -> 86396d896 (forced update)
[SUREFIRE-1367] System Output and Error should be reported in parallel JUnit tests if Assumption fails. Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/86396d89 Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/86396d89 Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/86396d89 Branch: refs/heads/SUREFIRE-1367 Commit: 86396d896bfeb614baa1547f16e035316e281049 Parents: 5593bf5 Author: Tibor17 <tibo...@lycos.com> Authored: Fri May 5 00:07:54 2017 +0200 Committer: Tibor17 <tibo...@lycos.com> Committed: Fri May 5 12:50:06 2017 +0200 ---------------------------------------------------------------------- .../surefire/util/internal/ByteBuffer.java | 147 ----------------- .../java/org/apache/maven/JUnit4SuiteTest.java | 2 - .../its/jiras/Surefire1367AssumptionLogsIT.java | 157 +++++++++++++++++++ .../src/test/resources/surefire-1367/pom.xml | 61 +++++++ .../surefire-1367/src/test/java/ATest.java | 38 +++++ .../surefire-1367/src/test/java/BTest.java | 34 ++++ .../junitcore/ConcurrentRunListener.java | 2 +- .../maven/surefire/junitcore/LogicalStream.java | 52 +++--- .../maven/surefire/junitcore/TestMethod.java | 20 ++- 9 files changed, 330 insertions(+), 183 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ByteBuffer.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ByteBuffer.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ByteBuffer.java deleted file mode 100644 index bdd983f..0000000 --- a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/ByteBuffer.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.apache.maven.surefire.util.internal; - -/* - * 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. - */ - -/** - * @author Kristian Rosenvold - */ -public class ByteBuffer -{ - private final byte[] data; - - private int position; - - public ByteBuffer( int length ) - { - this.data = new byte[length]; - } - - public ByteBuffer( byte[] buf, int off, int len ) - { - this.data = new byte[len]; - append( buf, off, len ); - } - - - public void append( char chararcter ) - { - data[position++] = (byte) chararcter; - } - - public void append( byte chararcter ) - { - data[position++] = chararcter; - } - - private static final byte COMMA = (byte) ','; - - public void comma() - { - data[position++] = COMMA; - } - - - public void advance( int i ) - { // Oooh nice break of encapsulation - position += i; - } - - public void append( Integer integer ) - { - toHex( integer ); - } - - /** - * Convert the integer to an unsigned number. - * - * @param i the value - */ - private void toHex( int i ) - { - byte[] buf = new byte[32]; - int charPos = 32; - int radix = 1 << 4; - int mask = radix - 1; - do - { - buf[--charPos] = (byte) DIGITS[i & mask]; - i >>>= 4; - } - while ( i != 0 ); - - append( buf, charPos, ( 32 - charPos ) ); - } - - private static final char[] DIGITS = - { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; - - - public byte[] getData() - { - return data; - } - - public int getlength() - { - return position; - } - - @Override - public String toString() - { - return new String( data, 0, position ); - } - - public static byte[] copy( byte[] src1, int off1, int len1 ) - { - byte[] combined = new byte[len1]; - int pos = 0; - for ( int i = off1; i < off1 + len1; i++ ) - { - combined[pos++] = src1[i]; - } - return combined; - } - - void append( byte[] src1, int off1, int len1 ) - { - for ( int i = off1; i < off1 + len1; i++ ) - { - data[position++] = src1[i]; - } - } - - public static byte[] join( byte[] src1, int off1, int len1, byte[] src2, int off2, int len2 ) - { - byte[] combined = new byte[len1 + len2]; - int pos = 0; - for ( int i = off1; i < off1 + len1; i++ ) - { - combined[pos++] = src1[i]; - } - for ( int i = off2; i < off2 + len2; i++ ) - { - combined[pos++] = src2[i]; - } - return combined; - } - -} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java index da6e6e4..dbf46ea 100644 --- a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java +++ b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java @@ -37,7 +37,6 @@ import org.apache.maven.surefire.util.RunOrderTest; import org.apache.maven.surefire.util.ScanResultTest; import org.apache.maven.surefire.util.TestsToRunTest; import org.apache.maven.surefire.util.UrlUtilsTest; -import org.apache.maven.surefire.util.internal.ByteBufferTest; import org.apache.maven.surefire.util.internal.ConcurrencyUtilsTest; import org.apache.maven.surefire.util.internal.ImmutableMapTest; import org.apache.maven.surefire.util.internal.StringUtilsTest; @@ -60,7 +59,6 @@ import org.junit.runners.Suite; RunResultTest.class, ResolvedTestTest.class, TestListResolverTest.class, - ByteBufferTest.class, ConcurrencyUtilsTest.class, StringUtilsTest.class, DefaultDirectoryScannerTest.class, http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1367AssumptionLogsIT.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1367AssumptionLogsIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1367AssumptionLogsIT.java new file mode 100644 index 0000000..48564fb --- /dev/null +++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1367AssumptionLogsIT.java @@ -0,0 +1,157 @@ +package org.apache.maven.surefire.its.jiras; + +/* + * 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.its.fixture.OutputValidator; +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.apache.maven.surefire.its.fixture.SurefireLauncher; +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +/** + * @author <a href="mailto:tibordig...@apache.org">Tibor Digana (tibor17)</a> + * @see <a href="https://issues.apache.org/jira/browse/SUREFIRE-1367">SUREFIRE-1367</a> + * @since 2.20.1 + */ +public class Surefire1367AssumptionLogsIT + extends SurefireJUnit4IntegrationTestCase +{ + private static final String NL = System.getProperty( "line.separator" ); + + @Test + public void shouldSeeLogsParallelForked() + { + OutputValidator outputValidator = unpack().setForkJvm() + .forkMode( "once" ) + .parallelClassesAndMethods() + .disablePerCoreThreadCount() + .threadCountClasses( 2 ) + .threadCountMethods( 2 ) + .executeTest() + .assertTestSuiteResults( 2, 0, 0, 2 ); + + verifyReportA( outputValidator ); + verifyReportB( outputValidator ); + } + + @Test + public void shouldSeeLogsParallelInPlugin() + { + OutputValidator outputValidator = unpack().setForkJvm() + .forkMode( "never" ) + .parallelClassesAndMethods() + .disablePerCoreThreadCount() + .threadCountClasses( 2 ) + .threadCountMethods( 2 ) + .executeTest() + .assertTestSuiteResults( 2, 0, 0, 2 ); + + verifyReportA( outputValidator ); + verifyReportB( outputValidator ); + } + + @Test + public void shouldSeeLogsForked() + { + OutputValidator outputValidator = unpack().setForkJvm() + .forkMode( "once" ) + .executeTest() + .assertTestSuiteResults( 2, 0, 0, 2 ); + + verifyReportA( outputValidator ); + verifyReportB( outputValidator ); + } + + @Test + public void shouldSeeLogsInPlugin() + { + OutputValidator outputValidator = unpack().setForkJvm() + .forkMode( "never" ) + .executeTest() + .assertTestSuiteResults( 2, 0, 0, 2 ); + + verifyReportA( outputValidator ); + verifyReportB( outputValidator ); + } + + + private SurefireLauncher unpack() + { + return unpack( "/surefire-1367" ); + } + + 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 + + " <system-err><![CDATA[Hello" + NL + + NL + + "What's up!" + NL + + "]]></system-err>"; + + assertThat( xmlReport ) + .contains( outputCData ); + + + String output = outputValidator.getSurefireReportsFile( "ATest-output.txt" ) + .readFileToString(); + + String outputExpected = "Hi" + NL + + NL + + "There!" + NL + + "Hello" + NL + + NL + + "What's up!" + NL; + + assertThat( output ) + .isEqualTo( outputExpected ); + } + + private void verifyReportB( OutputValidator outputValidator ) + { + String xmlReport = outputValidator.getSurefireReportsXmlFile( "TEST-BTest.xml" ) + .readFileToString(); + + String outputCData = "<system-out><![CDATA[Hey" + NL + + NL + + "you!" + NL + + "]]></system-out>"; + + assertThat( xmlReport ) + .contains( outputCData ); + + + String output = outputValidator.getSurefireReportsFile( "BTest-output.txt" ) + .readFileToString(); + + String outputExpected = "Hey" + NL + + NL + + "you!" + NL; + + assertThat( output ) + .isEqualTo( outputExpected ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-integration-tests/src/test/resources/surefire-1367/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/resources/surefire-1367/pom.xml b/surefire-integration-tests/src/test/resources/surefire-1367/pom.xml new file mode 100644 index 0000000..4bca308 --- /dev/null +++ b/surefire-integration-tests/src/test/resources/surefire-1367/pom.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<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> + + <parent> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>it-parent</artifactId> + <version>1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>org.apache.maven.plugins.surefire</groupId> + <artifactId>surefire-1367</artifactId> + <version>1.0</version> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.5</maven.compiler.source> + <maven.compiler.target>1.5</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <forkMode>${forkMode}</forkMode> + <redirectTestOutputToFile>true</redirectTestOutputToFile> + </configuration> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/ATest.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/ATest.java b/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/ATest.java new file mode 100644 index 0000000..df5231e --- /dev/null +++ b/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/ATest.java @@ -0,0 +1,38 @@ +/* + * 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.Test; + +import static org.junit.Assume.assumeTrue; + +public class ATest { + + @Test + public void test() { + System.out.println("Hi"); + System.out.println(); + System.out.println("There!"); + + System.err.println("Hello"); + System.err.println(); + System.err.println("What's up!"); + + assumeTrue( false ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/BTest.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/BTest.java b/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/BTest.java new file mode 100644 index 0000000..bec4da8 --- /dev/null +++ b/surefire-integration-tests/src/test/resources/surefire-1367/src/test/java/BTest.java @@ -0,0 +1,34 @@ +/* + * 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.Test; + +import static org.junit.Assume.assumeTrue; + +public class BTest { + + @Test + public void test() { + System.out.println("Hey"); + System.out.println(); + System.out.println("you!"); + + assumeTrue( false ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java index 27008ee..a4f88dc 100644 --- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java +++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java @@ -131,7 +131,7 @@ public abstract class ConcurrentRunListener final TestMethod testMethod = getOrCreateThreadAttachedTestMethod( failure ); if ( testMethod != null ) { - testMethod.testIgnored( failure ); + testMethod.testAssumption( failure ); testMethod.detachFromCurrentThread(); } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/LogicalStream.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/LogicalStream.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/LogicalStream.java index 41e09b8..1089585 100644 --- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/LogicalStream.java +++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/LogicalStream.java @@ -19,68 +19,62 @@ package org.apache.maven.surefire.junitcore; * under the License. */ -import java.util.Collection; -import java.util.concurrent.ConcurrentLinkedQueue; - import org.apache.maven.surefire.report.ConsoleOutputReceiver; -import org.apache.maven.surefire.util.internal.ByteBuffer; + +import java.util.Arrays; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * A stream-like object that preserves ordering between stdout/stderr */ public final class LogicalStream { - private final Collection<Entry> output = new ConcurrentLinkedQueue<Entry>(); + private final Queue<Entry> output = new ConcurrentLinkedQueue<Entry>(); - static final class Entry + private static final class Entry { - final boolean stdout; + private final boolean stdout; - final byte[] b; + private final byte[] b; - final int off; + private final int off; - final int len; + private final int len; - Entry( boolean stdout, byte[] b, int off, int len ) + private Entry( boolean stdout, byte[] b, int off, int len ) { this.stdout = stdout; - this.b = ByteBuffer.copy( b, off, len ); + this.b = Arrays.copyOfRange( b, off, off + len ); this.off = 0; this.len = len; } - public void writeDetails( ConsoleOutputReceiver outputReceiver ) + private void writeDetails( ConsoleOutputReceiver outputReceiver ) { outputReceiver.writeTestOutput( b, off, len, stdout ); } - - @Override - public String toString() - { - return new String( b, off, len ); - } - - public boolean isBlankLine() - { - return "\n".equals( toString() ); - } } - public synchronized void write( boolean stdout, byte b[], int off, int len ) + public void write( boolean stdout, byte b[], int off, int len ) { - Entry entry = new Entry( stdout, b, off, len ); - if ( !entry.isBlankLine() ) + if ( !isBlankLine( b, len ) ) { + Entry entry = new Entry( stdout, b, off, len ); output.add( entry ); } } - public synchronized void writeDetails( ConsoleOutputReceiver outputReceiver ) + public void writeDetails( ConsoleOutputReceiver outputReceiver ) { - for ( Entry entry : output ) + for ( Entry entry = output.poll(); entry != null; entry = output.poll() ) { entry.writeDetails( outputReceiver ); } } + + private static boolean isBlankLine( byte[] b, int len ) + { + return b == null || len == 0; + } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/86396d89/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestMethod.java ---------------------------------------------------------------------- diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestMethod.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestMethod.java index 7bba28c..1a7dd12 100644 --- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestMethod.java +++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/TestMethod.java @@ -52,7 +52,9 @@ class TestMethod private volatile ReportEntry testError; - private volatile ReportEntry ignored; + private volatile ReportEntry testIgnored; + + private volatile ReportEntry testAssumption; TestMethod( ReportEntry description, TestSet testSet ) { @@ -68,7 +70,7 @@ class TestMethod void testIgnored( ReportEntry description ) { - ignored = description; + testIgnored = description; setEndTime(); } @@ -84,6 +86,12 @@ class TestMethod setEndTime(); } + void testAssumption( ReportEntry failure ) + { + this.testAssumption = failure; + setEndTime(); + } + private void setEndTime() { this.endTime = System.currentTimeMillis(); @@ -106,9 +114,9 @@ class TestMethod void replay( RunListener reporter ) { - if ( ignored != null ) + if ( testIgnored != null ) { - reporter.testSkipped( createReportEntry( ignored ) ); + reporter.testSkipped( createReportEntry( testIgnored ) ); } else { @@ -128,6 +136,10 @@ class TestMethod { reporter.testError( createReportEntry( testError ) ); } + else if ( testAssumption != null ) + { + reporter.testAssumptionFailure( createReportEntry( testAssumption ) ); + } else { reporter.testSucceeded( descriptionReport );