Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id C035F200CD9 for ; Thu, 3 Aug 2017 14:48:15 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id BEA0D16B7B2; Thu, 3 Aug 2017 12:48:15 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 5004716B7B5 for ; Thu, 3 Aug 2017 14:48:11 +0200 (CEST) Received: (qmail 76088 invoked by uid 500); 3 Aug 2017 12:48:08 -0000 Mailing-List: contact commits-help@maven.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@maven.apache.org Delivered-To: mailing list commits@maven.apache.org Received: (qmail 76078 invoked by uid 99); 3 Aug 2017 12:48:08 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 03 Aug 2017 12:48:08 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id A5603F1820; Thu, 3 Aug 2017 12:48:05 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tibordigana@apache.org To: commits@maven.apache.org Date: Thu, 03 Aug 2017 12:48:06 -0000 Message-Id: <6c21c205035d44bfa756587ef76e82d3@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [2/3] maven-surefire git commit: [SUREFIRE-1222] ForkClient attempts to consume unrelated lines archived-at: Thu, 03 Aug 2017 12:48:15 -0000 http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java new file mode 100644 index 0000000..06849f0 --- /dev/null +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkedChannelDecoderTest.java @@ -0,0 +1,666 @@ +package org.apache.maven.plugin.surefire.booterclient.output; + +/* + * 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.booter.ForkedChannelEncoder; +import org.apache.maven.surefire.report.ReportEntry; +import org.apache.maven.surefire.report.RunMode; +import org.apache.maven.surefire.report.SafeThrowable; +import org.apache.maven.surefire.report.StackTraceWriter; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.runners.Enclosed; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.FromDataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.PrintStream; +import java.io.StringReader; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Map; + +import static java.nio.charset.Charset.defaultCharset; +import static javax.xml.bind.DatatypeConverter.printBase64Binary; +import static org.apache.maven.plugin.surefire.booterclient.output.ForkedChannelDecoder.toReportEntry; +import static org.apache.maven.surefire.report.RunMode.NORMAL_RUN; +import static org.fest.assertions.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.rules.ExpectedException.none; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author Tibor Digana (tibor17) + * @since 2.20.1 + */ +@RunWith( Enclosed.class ) +public class ForkedChannelDecoderTest +{ + public static class DecoderOperationsTest + { + @Rule + public final ExpectedException rule = none(); + + @Test + public void shouldBeFailSafe() + { + Charset encoding = Charset.defaultCharset(); + assertThat( ForkedChannelDecoder.decode( null, encoding ) ).isNull(); + assertThat( ForkedChannelDecoder.decode( "-", encoding ) ).isNull(); + assertThat( ForkedChannelDecoder.decodeToInteger( null ) ).isNull(); + assertThat( ForkedChannelDecoder.decodeToInteger( "-" ) ).isNull(); + assertThat( ForkedChannelDecoder.decodeToBytes( null ) ).isNull(); + assertThat( ForkedChannelDecoder.decodeToBytes( "-" ) ).isNull(); + } + + @Test + public void shouldHaveSystemProperty() throws IOException + { + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.sendSystemProperties(); + + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setSystemPropertiesListener( new PropertyEventAssertionListener( NORMAL_RUN ) ); + LineNumberReader reader = out.newReader( defaultCharset() ); + for ( String line; ( line = reader.readLine() ) != null; ) + { + decoder.handleEvent( line, new AssertionErrorHandler() ); + } + assertThat( reader.getLineNumber() ).isPositive(); + } + + @Test + public void shouldRecognizeEmptyStream4ReportEntry() + { + ReportEntry reportEntry = toReportEntry( null, null, "", null, null, "", "", "", null ); + assertThat( reportEntry ).isNull(); + + reportEntry = toReportEntry( defaultCharset(), "", "", "", "", "-", "", "", "" ); + assertThat( reportEntry ).isNotNull(); + assertThat( reportEntry.getStackTraceWriter() ).isNull(); + assertThat( reportEntry.getSourceName() ).isEmpty(); + assertThat( reportEntry.getName() ).isEmpty(); + assertThat( reportEntry.getGroup() ).isEmpty(); + assertThat( reportEntry.getNameWithGroup() ).isEmpty(); + assertThat( reportEntry.getMessage() ).isEmpty(); + assertThat( reportEntry.getElapsed() ).isNull(); + + rule.expect( NumberFormatException.class ); + toReportEntry( defaultCharset(), "", "", "", "", "", "", "", "" ); + fail(); + } + + @Test + public void testCreatingReportEntry() + { + final Charset utf8 = Charset.forName( "UTF-8" ); + + final String exceptionMessage = "msg"; + final String encodedExceptionMsg = printBase64Binary( toArray( utf8.encode( exceptionMessage ) ) ); + + final String smartStackTrace = "MyTest:86 >> Error"; + final String encodedSmartStackTrace = printBase64Binary( toArray( utf8.encode( smartStackTrace ) ) ); + + final String stackTrace = "Exception: msg\ntrace line 1\ntrace line 2"; + final String encodedStackTrace = printBase64Binary( toArray( utf8.encode( stackTrace ) ) ); + + final String trimmedStackTrace = "trace line 1\ntrace line 2"; + final String encodedTrimmedStackTrace = printBase64Binary( toArray( utf8.encode( trimmedStackTrace ) ) ); + + SafeThrowable safeThrowable = new SafeThrowable( exceptionMessage ); + StackTraceWriter stackTraceWriter = mock( StackTraceWriter.class ); + when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable ); + when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace ); + when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( trimmedStackTrace ); + when( stackTraceWriter.writeTraceToString() ).thenReturn( stackTrace ); + + ReportEntry reportEntry = mock( ReportEntry.class ); + when( reportEntry.getElapsed() ).thenReturn( 102 ); + when( reportEntry.getGroup() ).thenReturn( "this group" ); + when( reportEntry.getMessage() ).thenReturn( "skipped test" ); + when( reportEntry.getName() ).thenReturn( "my test" ); + when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" ); + when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" ); + when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter ); + + String encodedSourceName = printBase64Binary( toArray( utf8.encode( reportEntry.getSourceName() ) ) ); + String encodedName = printBase64Binary( toArray( utf8.encode( reportEntry.getName() ) ) ); + String encodedGroup = printBase64Binary( toArray( utf8.encode( reportEntry.getGroup() ) ) ); + String encodedMessage = printBase64Binary( toArray( utf8.encode( reportEntry.getMessage() ) ) ); + + ReportEntry decodedReportEntry = toReportEntry( utf8, encodedSourceName, encodedName, encodedGroup, + encodedMessage, "-", null, null, null + ); + + assertThat( decodedReportEntry ).isNotNull(); + assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() ); + assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() ); + assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() ); + assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() ); + assertThat( decodedReportEntry.getStackTraceWriter() ).isNull(); + + decodedReportEntry = toReportEntry( utf8, encodedSourceName, encodedName, encodedGroup, encodedMessage, "-", + encodedExceptionMsg, encodedSmartStackTrace, null + ); + + assertThat( decodedReportEntry ).isNotNull(); + assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() ); + assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() ); + assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() ); + assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() ); + assertThat( decodedReportEntry.getElapsed() ).isNull(); + assertThat( decodedReportEntry.getStackTraceWriter() ).isNull(); + + decodedReportEntry = toReportEntry( utf8, encodedSourceName, encodedName, encodedGroup, encodedMessage, + "1003", encodedExceptionMsg, encodedSmartStackTrace, null + ); + + assertThat( decodedReportEntry ).isNotNull(); + assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() ); + assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() ); + assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() ); + assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() ); + assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 ); + assertThat( decodedReportEntry.getStackTraceWriter() ).isNull(); + + decodedReportEntry = toReportEntry( utf8, encodedSourceName, encodedName, encodedGroup, encodedMessage, + "1003", encodedExceptionMsg, encodedSmartStackTrace, + encodedStackTrace + ); + + assertThat( decodedReportEntry ).isNotNull(); + assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() ); + assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() ); + assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() ); + assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() ); + assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 ); + assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull(); + assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ).isNotNull(); + assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ) + .isEqualTo( exceptionMessage ); + assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() ) + .isEqualTo( smartStackTrace ); + assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() ).isEqualTo( stackTrace ); + assertThat( decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString() ).isEqualTo( stackTrace ); + + decodedReportEntry = toReportEntry( utf8, encodedSourceName, encodedName, encodedGroup, encodedMessage, + "1003", encodedExceptionMsg, encodedSmartStackTrace, + encodedTrimmedStackTrace + ); + + assertThat( decodedReportEntry ).isNotNull(); + assertThat( decodedReportEntry.getSourceName() ).isEqualTo( reportEntry.getSourceName() ); + assertThat( decodedReportEntry.getName() ).isEqualTo( reportEntry.getName() ); + assertThat( decodedReportEntry.getGroup() ).isEqualTo( reportEntry.getGroup() ); + assertThat( decodedReportEntry.getMessage() ).isEqualTo( reportEntry.getMessage() ); + assertThat( decodedReportEntry.getElapsed() ).isEqualTo( 1003 ); + assertThat( decodedReportEntry.getStackTraceWriter() ).isNotNull(); + assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ).isNotNull(); + assertThat( decodedReportEntry.getStackTraceWriter().getThrowable().getMessage() ) + .isEqualTo( exceptionMessage ); + assertThat( decodedReportEntry.getStackTraceWriter().smartTrimmedStackTrace() ) + .isEqualTo( smartStackTrace ); + assertThat( decodedReportEntry.getStackTraceWriter().writeTraceToString() ).isEqualTo( trimmedStackTrace ); + assertThat( decodedReportEntry.getStackTraceWriter().writeTrimmedTraceToString() ) + .isEqualTo( trimmedStackTrace ); + } + + @Test + public void shouldSendByeEvent() throws IOException + { + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.bye(); + String read = new String( out.toByteArray(), defaultCharset() ); + assertThat( read ) + .isEqualTo( ":maven:surefire:std:out:bye:normal-run\n" ); + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setByeListener( new EventAssertionListener( NORMAL_RUN ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void shouldSendStopOnNextTestEvent() throws IOException + { + + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.stopOnNextTest(); + String read = new String( out.toByteArray(), defaultCharset() ); + assertThat( read ) + .isEqualTo( ":maven:surefire:std:out:stopOnNextTest:normal-run\n" ); + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setStopOnNextTestListener( new EventAssertionListener( NORMAL_RUN ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void shouldSendNextTestEvent() throws IOException + { + + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.acquireNextTest(); + String read = new String( out.toByteArray(), defaultCharset() ); + assertThat( read ) + .isEqualTo( ":maven:surefire:std:out:nextTest:normal-run\n" ); + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setAcquireNextTestListener( new EventAssertionListener( NORMAL_RUN ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void testConsole() throws IOException + { + Stream out = Stream.newStream(); + + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.console( "msg" ); + + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setConsoleInfoListener( new StringEventAssertionListener( "msg" ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void testError() throws IOException + { + Stream out = Stream.newStream(); + + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.error( "msg" ); + + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setConsoleErrorListener( new StackTraceEventListener( "msg", "stack trace" ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void testDebug() throws IOException + { + Stream out = Stream.newStream(); + + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.debug( "msg" ); + + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setConsoleDebugListener( new StringEventAssertionListener( "msg" ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void testWarning() throws IOException + { + Stream out = Stream.newStream(); + + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + forkedChannelEncoder.warning( "msg" ); + + LineNumberReader lines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setConsoleWarningListener( new StringEventAssertionListener( "msg" ) ); + decoder.handleEvent( lines.readLine(), new AssertionErrorHandler() ); + assertThat( lines.readLine() ) + .isNull(); + } + + @Test + public void testStdOutStream() throws IOException + { + Charset streamEncoding = Charset.forName( "UTF-8" ); + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( streamEncoding, out ); + + final Charset encoding = defaultCharset(); + byte[] msgArray = toArray( encoding.encode( "msg" ) ); + assertThat( encoding.decode( ByteBuffer.wrap( msgArray ) ).toString() ).isEqualTo( "msg" ); + forkedChannelEncoder.stdOut( msgArray, 0, msgArray.length ); + + LineNumberReader printedLines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setStdOutListener( new BinaryEventAssertionListener( NORMAL_RUN, encoding, + "msg".getBytes( encoding ) + ) + ); + decoder.handleEvent( printedLines.readLine(), new AssertionErrorHandler() ); + assertThat( printedLines.readLine() ) + .isNull(); + } + + @Test + public void testStdErrStream() throws IOException + { + Charset streamEncoding = Charset.forName( "ISO-8859-1" ); + Stream out = Stream.newStream(); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( streamEncoding, out ); + + final Charset encoding = defaultCharset(); + byte[] msgArray = toArray( encoding.encode( "msg" ) ); + assertThat( encoding.decode( ByteBuffer.wrap( msgArray ) ).toString() ).isEqualTo( "msg" ); + forkedChannelEncoder.stdErr( msgArray, 0, msgArray.length ); + + LineNumberReader printedLines = out.newReader( defaultCharset() ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setStdErrListener( new BinaryEventAssertionListener( NORMAL_RUN, encoding, + "msg".getBytes( encoding ) + ) + ); + decoder.handleEvent( printedLines.readLine(), new AssertionErrorHandler() ); + assertThat( printedLines.readLine() ) + .isNull(); + } + + @Test + public void shouldCountSameNumberOfSystemProperties() throws IOException + { + Stream out = Stream.newStream(); + + Charset streamEncoding = Charset.forName( "ISO-8859-1" ); + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( streamEncoding, out ); + forkedChannelEncoder.sendSystemProperties(); + + LineNumberReader printedLines = out.newReader( streamEncoding ); + ForkedChannelDecoder decoder = new ForkedChannelDecoder(); + decoder.setSystemPropertiesListener( new PropertyEventAssertionListener( NORMAL_RUN ) ); + decoder.handleEvent( printedLines.readLine(), new AssertionErrorHandler() ); + } + } + + @RunWith( Theories.class ) + public static class ReportEntryTest + { + @DataPoints( value = "operation" ) + public static String[][] operations = { { "testSetStarting", "setTestSetStartingListener" }, + { "testSetCompleted", "setTestSetCompletedListener" }, + { "testStarting", "setTestStartingListener" }, + { "testSucceeded", "setTestSucceededListener" }, + { "testFailed", "setTestFailedListener" }, + { "testSkipped", "setTestSkippedListener" }, + { "testError", "setTestErrorListener" }, + { "testAssumptionFailure", "setTestAssumptionFailureListener" } + }; + + @DataPoints( value = "reportedMessage" ) + public static String[] reportedMessage = { null, "skipped test" }; + + @DataPoints( value = "elapsed" ) + public static Integer[] elapsed = { null, 102 }; + + @DataPoints( value = "trim" ) + public static boolean[] trim = { false, true }; + + @DataPoints( value = "msg" ) + public static boolean[] msg = { false, true }; + + @DataPoints( value = "smart" ) + public static boolean[] smart = { false, true }; + + @DataPoints( value = "trace" ) + public static boolean[] trace = { false, true }; + + @Theory + public void testReportEntryOperations( @FromDataPoints( "operation" ) String[] operation, + @FromDataPoints( "reportedMessage" ) String reportedMessage, + @FromDataPoints( "elapsed" ) Integer elapsed, + @FromDataPoints( "trim" ) boolean trim, + @FromDataPoints( "msg" ) boolean msg, + @FromDataPoints( "smart" ) boolean smart, + @FromDataPoints( "trace" ) boolean trace ) + throws Exception + { + String exceptionMessage = msg ? "msg" : null; + String smartStackTrace = smart ? "MyTest:86 >> Error" : null; + String exceptionStackTrace = + trace ? ( trim ? "trace line 1\ntrace line 2" : "Exception: msg\ntrace line 1\ntrace line 2" ) + : null; + + StackTraceWriter stackTraceWriter = null; + if ( exceptionStackTrace != null ) + { + SafeThrowable safeThrowable = new SafeThrowable( exceptionMessage ); + stackTraceWriter = mock( StackTraceWriter.class ); + when( stackTraceWriter.getThrowable() ).thenReturn( safeThrowable ); + when( stackTraceWriter.smartTrimmedStackTrace() ).thenReturn( smartStackTrace ); + when( stackTraceWriter.writeTrimmedTraceToString() ).thenReturn( exceptionStackTrace ); + when( stackTraceWriter.writeTraceToString() ).thenReturn( exceptionStackTrace ); + } + + ReportEntry reportEntry = mock( ReportEntry.class ); + when( reportEntry.getElapsed() ).thenReturn( elapsed ); + when( reportEntry.getGroup() ).thenReturn( "this group" ); + when( reportEntry.getMessage() ).thenReturn( reportedMessage ); + when( reportEntry.getName() ).thenReturn( "my test" ); + when( reportEntry.getNameWithGroup() ).thenReturn( "name with group" ); + when( reportEntry.getSourceName() ).thenReturn( "pkg.MyTest" ); + when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter ); + + Stream out = Stream.newStream(); + + ForkedChannelEncoder forkedChannelEncoder = new ForkedChannelEncoder( defaultCharset(), out ); + + ForkedChannelEncoder.class.getMethod( operation[0], ReportEntry.class, boolean.class ) + .invoke( forkedChannelEncoder, reportEntry, trim ); + + ForkedChannelDecoder forkedChannelDecoder = new ForkedChannelDecoder(); + + ForkedChannelDecoder.class.getMethod( operation[1], ForkedProcessReportEventListener.class ) + .invoke( forkedChannelDecoder, new ReportEventAssertionListener( reportEntry ) ); + + forkedChannelDecoder.handleEvent( out.newReader( defaultCharset() ).readLine(), + new AssertionErrorHandler() + ); + } + } + + private static class AssertionErrorHandler implements ForkedChannelDecoderErrorHandler + { + public void handledError( String line, Throwable e ) + { + if ( e != null ) + { + e.printStackTrace(); + } + fail( line + ( e == null ? "" : "\n" + e.getLocalizedMessage() ) ); + } + } + + private static class PropertyEventAssertionListener implements ForkedProcessPropertyEventListener + { + private final Map sysProps = System.getProperties(); + private final RunMode runMode; + + PropertyEventAssertionListener( RunMode runMode ) + { + this.runMode = runMode; + } + + public void handle( String key, String value ) + { + assertTrue( sysProps.containsKey( key ) ); + assertThat( sysProps.get( key ) ).isEqualTo( value ); + } + } + + private static class EventAssertionListener implements ForkedProcessEventListener + { + public void handle() + { + } + } + + private static class StringEventAssertionListener implements ForkedProcessStringEventListener + { + private final String msg; + + StringEventAssertionListener( String msg ) + { + this.msg = msg; + } + + public void handle( String msg ) + { + assertThat( msg ) + .isEqualTo( this.msg ); + } + } + + private static class StackTraceEventListener implements ForkedProcessStackTraceEventListener + { + private final String msg; + private final String stackTrace; + + StackTraceEventListener( String msg, String stackTrace ) + { + this.msg = msg; + this.stackTrace = stackTrace; + } + + @Override + public void handle( String msg, String stackTrace ) + { + assertThat( msg ) + .isEqualTo( this.msg ); + + assertThat( stackTrace ) + .isEqualTo( this.stackTrace ); + } + } + + private static class BinaryEventAssertionListener implements ForkedProcessBinaryEventListener + { + private final RunMode runMode; + private final Charset encoding; + private final byte[] binary; + + BinaryEventAssertionListener( RunMode runMode, Charset encoding, byte[] binary ) + { + this.runMode = runMode; + this.encoding = encoding; + this.binary = binary; + } + + public void handle( RunMode runMode, Charset encoding, byte[] binary ) + { + assertThat( runMode ) + .isEqualTo( this.runMode ); + + assertThat( encoding ) + .isEqualTo( this.encoding ); + + assertThat( binary ) + .isEqualTo( this.binary ); + } + } + + private static class ReportEventAssertionListener implements ForkedProcessReportEventListener + { + private final ReportEntry reportEntry; + + ReportEventAssertionListener( ReportEntry reportEntry ) + { + this.reportEntry = reportEntry; + } + + public void handle( RunMode runMode, ReportEntry reportEntry ) + { + assertThat( reportEntry.getSourceName() ).isEqualTo( this.reportEntry.getSourceName() ); + assertThat( reportEntry.getName() ).isEqualTo( this.reportEntry.getName() ); + assertThat( reportEntry.getGroup() ).isEqualTo( this.reportEntry.getGroup() ); + assertThat( reportEntry.getMessage() ).isEqualTo( this.reportEntry.getMessage() ); + assertThat( reportEntry.getElapsed() ).isEqualTo( this.reportEntry.getElapsed() ); + if ( reportEntry.getStackTraceWriter() == null ) + { + assertThat( this.reportEntry.getStackTraceWriter() ).isNull(); + } + else + { + assertThat( this.reportEntry.getStackTraceWriter() ).isNotNull(); + + assertThat( reportEntry.getStackTraceWriter().getThrowable().getMessage() ) + .isEqualTo( this.reportEntry.getStackTraceWriter().getThrowable().getMessage() ); + + assertThat( reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage() ) + .isEqualTo( this.reportEntry.getStackTraceWriter().getThrowable().getLocalizedMessage() ); + + assertThat( reportEntry.getStackTraceWriter().smartTrimmedStackTrace() ) + .isEqualTo( this.reportEntry.getStackTraceWriter().smartTrimmedStackTrace() ); + } + } + } + + private static class Stream extends PrintStream + { + private final ByteArrayOutputStream out; + + public Stream( ByteArrayOutputStream out ) + { + super( out, true ); + this.out = out; + } + + byte[] toByteArray() + { + return out.toByteArray(); + } + + LineNumberReader newReader( Charset streamCharset ) + { + return new LineNumberReader( new StringReader( new String( toByteArray(), streamCharset ) ) ); + } + + static Stream newStream() + { + return new Stream( new ByteArrayOutputStream() ); + } + } + + private static byte[] toArray( ByteBuffer buffer ) + { + return Arrays.copyOfRange( buffer.array(), buffer.arrayOffset(), buffer.arrayOffset() + buffer.remaining() ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java index 9fb45bf..0c92635 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/surefire/JUnit4SuiteTest.java @@ -30,6 +30,7 @@ import org.apache.maven.plugin.surefire.booterclient.ForkConfigurationTest; import org.apache.maven.plugin.surefire.booterclient.ForkingRunListenerTest; import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStreamBuilderTest; import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestProvidingInputStreamTest; +import org.apache.maven.plugin.surefire.booterclient.output.ForkClientTest; import org.apache.maven.plugin.surefire.report.DefaultReporterFactoryTest; import org.apache.maven.plugin.surefire.report.StatelessXmlReporterTest; import org.apache.maven.plugin.surefire.report.WrappedReportEntryTest; @@ -75,6 +76,7 @@ import org.junit.runners.Suite; SurefireReflectorTest.class, ImmutableMapTest.class, SurefireHelperTest.class, + ForkClientTest.class } ) @RunWith( Suite.class ) public class JUnit4SuiteTest http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-api/pom.xml b/surefire-api/pom.xml index 5f0f2fd..b705e0a 100644 --- a/surefire-api/pom.xml +++ b/surefire-api/pom.xml @@ -40,6 +40,11 @@ org.apache.maven.shared maven-shared-utils + + org.mockito + mockito-core + test + http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java index 2a713ef..a794255 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BaseProviderFactory.java @@ -136,7 +136,8 @@ public class BaseProviderFactory { boolean trim = reporterConfiguration.isTrimStackTrace(); PrintStream out = reporterConfiguration.getOriginalSystemOut(); - return insideFork ? new ForkingRunListener( out, ROOT_CHANNEL, trim ) : new DefaultDirectConsoleReporter( out ); + return insideFork ? new ForkingRunListener( new ForkedChannelEncoder( out ), ROOT_CHANNEL, trim ) + : new DefaultDirectConsoleReporter( out ); } public void setTestRequest( TestRequest testRequest ) http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java new file mode 100644 index 0000000..f63fd7e --- /dev/null +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedChannelEncoder.java @@ -0,0 +1,432 @@ +package org.apache.maven.surefire.booter; + +/* + * 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.plugin.surefire.log.api.ConsoleLoggerUtils; +import org.apache.maven.surefire.report.ReportEntry; +import org.apache.maven.surefire.report.RunMode; +import org.apache.maven.surefire.report.SafeThrowable; +import org.apache.maven.surefire.report.StackTraceWriter; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; + +import static java.lang.System.arraycopy; +import static javax.xml.bind.DatatypeConverter.printBase64Binary; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_BYE; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_CONSOLE_INFO; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_CONSOLE_DEBUG; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_CONSOLE_ERROR; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_NEXT_TEST; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDERR; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STDOUT; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_STOP_ON_NEXT_TEST; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_SYSPROPS; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TESTSET_COMPLETED; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TESTSET_STARTING; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_ASSUMPTIONFAILURE; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_ERROR; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_FAILED; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_SKIPPED; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_STARTING; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_TEST_SUCCEEDED; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.BOOTERCODE_CONSOLE_WARNING; +import static org.apache.maven.surefire.booter.ForkedProcessEvent.MAGIC_NUMBER; +import static org.apache.maven.surefire.report.RunMode.NORMAL_RUN; +import static org.apache.maven.surefire.report.RunMode.RERUN; +import static org.apache.maven.surefire.util.internal.ObjectUtils.requireNonNull; + +/** + * magic number : opcode : run mode [: opcode specific data]* + *

+ * + * @author Tibor Digana (tibor17) + * @since 2.20.1 + */ +public final class ForkedChannelEncoder +{ + private static final Charset ASCII = Charset.forName( "US-ASCII" ); + private static final Charset UTF_8 = Charset.forName( "UTF-8" ); + + private final Charset defaultCharset = Charset.defaultCharset(); + private final Charset streamCharset; + private final OutputStream out; + private final RunMode runMode; + private boolean trouble; + + public ForkedChannelEncoder( OutputStream out ) + { + this( ASCII, out, NORMAL_RUN ); + } + + public ForkedChannelEncoder( Charset streamCharset, OutputStream out ) + { + this( streamCharset, out, NORMAL_RUN ); + } + + private ForkedChannelEncoder( Charset streamCharset, OutputStream out, RunMode runMode ) + { + this.streamCharset = requireNonNull( streamCharset ); + this.out = requireNonNull( out ); + this.runMode = requireNonNull( runMode ); + } + + public ForkedChannelEncoder asRerunMode() + { + return new ForkedChannelEncoder( streamCharset, out, RERUN ); + } + + public ForkedChannelEncoder asNormalMode() + { + return new ForkedChannelEncoder( streamCharset, out, NORMAL_RUN ); + } + + public boolean checkError() + { + return trouble; + } + + public void sendSystemProperties() + { + SortedMap sortedProperties = new TreeMap(); + for ( Entry entry : System.getProperties().entrySet() ) + { + Object key = entry.getKey(); + Object value = entry.getValue(); + if ( key instanceof String && ( value == null || value instanceof String ) ) + { + sortedProperties.put( (String) key, (String) value ); + } + } + + for ( Entry entry : sortedProperties.entrySet() ) + { + String key = entry.getKey(); + Object value = entry.getValue(); + String valueAsString = value == null ? null : value.toString(); + StringBuilder event = encode( BOOTERCODE_SYSPROPS, runMode, key, valueAsString ); + encodeAndPrintEvent( event ); + } + } + + public void testSetStarting( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TESTSET_STARTING, runMode, reportEntry, trimStackTraces ); + } + + public void testSetCompleted( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TESTSET_COMPLETED, runMode, reportEntry, trimStackTraces ); + } + + public void testStarting( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_STARTING, runMode, reportEntry, trimStackTraces ); + } + + public void testSucceeded( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_SUCCEEDED, runMode, reportEntry, trimStackTraces ); + } + + public void testFailed( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_FAILED, runMode, reportEntry, trimStackTraces ); + } + + public void testSkipped( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_SKIPPED, runMode, reportEntry, trimStackTraces ); + } + + public void testError( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_ERROR, runMode, reportEntry, trimStackTraces ); + } + + public void testAssumptionFailure( ReportEntry reportEntry, boolean trimStackTraces ) + { + encode( BOOTERCODE_TEST_ASSUMPTIONFAILURE, runMode, reportEntry, trimStackTraces ); + } + + public void stdOut( byte[] buf, int off, int len ) + { + StringBuilder event = + stdOutErr( BOOTERCODE_STDOUT.getOpcode(), runMode.geRunName(), buf, off, len, defaultCharset ); + encodeAndPrintEvent( event ); + } + + public void stdErr( byte[] buf, int off, int len ) + { + StringBuilder event = + stdOutErr( BOOTERCODE_STDERR.getOpcode(), runMode.geRunName(), buf, off, len, defaultCharset ); + encodeAndPrintEvent( event ); + } + + public void console( String msg ) + { + StringBuilder event = print( BOOTERCODE_CONSOLE_INFO.getOpcode(), runMode.geRunName(), UTF_8, msg ); + encodeAndPrintEvent( event ); + } + + public void error( String msg ) + { + StringBuilder event = print( BOOTERCODE_CONSOLE_ERROR.getOpcode(), runMode.geRunName(), UTF_8, msg ); + encodeAndPrintEvent( event ); + } + + public void error( Throwable t ) + { + error( t.getLocalizedMessage(), ConsoleLoggerUtils.toString( t ) ); + } + + public void error( String msg, String stackTrace ) + { + StringBuilder event = print( BOOTERCODE_CONSOLE_ERROR.getOpcode(), runMode.geRunName(), UTF_8, msg, stackTrace ); + encodeAndPrintEvent( event ); + } + + public void debug( String msg ) + { + StringBuilder event = print( BOOTERCODE_CONSOLE_DEBUG.getOpcode(), runMode.geRunName(), UTF_8, msg ); + encodeAndPrintEvent( event ); + } + + public void warning( String msg ) + { + StringBuilder event = print( BOOTERCODE_CONSOLE_WARNING.getOpcode(), runMode.geRunName(), UTF_8, msg ); + encodeAndPrintEvent( event ); + } + + public void bye() + { + encodeOpcode( BOOTERCODE_BYE ); + } + + public void stopOnNextTest() + { + encodeOpcode( BOOTERCODE_STOP_ON_NEXT_TEST ); + } + + public void acquireNextTest() + { + encodeOpcode( BOOTERCODE_NEXT_TEST ); + } + + private void encode( ForkedProcessEvent operation, RunMode runMode, ReportEntry reportEntry, + boolean trimStackTraces ) + { + StringBuilder event = encode( operation.getOpcode(), runMode.geRunName(), reportEntry, trimStackTraces ); + encodeAndPrintEvent( event ); + } + + private void encodeOpcode( ForkedProcessEvent operation ) + { + StringBuilder event = encodeOpcode( operation.getOpcode(), runMode.geRunName() ); + encodeAndPrintEvent( event ); + } + + private void encodeAndPrintEvent( StringBuilder command ) + { + byte[] array = command.append( '\n' ).toString().getBytes( streamCharset ); + synchronized ( out ) + { + try + { + out.write( array ); + out.flush(); + } + catch ( IOException e ) + { + // todo loguj do dum filu pozri ForkingRunListener + trouble = true; + } + } + } + + static StringBuilder encode( ForkedProcessEvent operation, RunMode runMode, String... args ) + { + StringBuilder encodedTo = encodeHeader( operation.getOpcode(), runMode.geRunName(), UTF_8 ) + .append( ':' ); + + for ( int i = 0; i < args.length; ) + { + String arg = args[i++]; + base64WithUtf8( encodedTo, arg == null ? "-" : arg ); + if ( i != args.length ) + { + encodedTo.append( ':' ); + } + } + return encodedTo; + } + + static void encode( StringBuilder encoded, StackTraceWriter stw, boolean trimStackTraces ) + { + encoded.append( ':' ); + + SafeThrowable throwable = stw == null ? null : stw.getThrowable(); + String message = throwable == null ? null : throwable.getLocalizedMessage(); + base64WithUtf8( encoded, message ); + + encoded.append( ':' ); + + String smartStackTrace = stw == null ? null : stw.smartTrimmedStackTrace(); + base64WithUtf8( encoded, smartStackTrace ); + + encoded.append( ':' ); + + String stackTrace = stw == null ? null : toStackTrace( stw, trimStackTraces ); + base64WithUtf8( encoded, stackTrace ); + } + + /** + * Used operations:
+ *

+ *

    + *
  • {@link ForkedProcessEvent#BOOTERCODE_TESTSET_STARTING},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TESTSET_COMPLETED},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_STARTING},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_SUCCEEDED},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_FAILED},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_ERROR},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_SKIPPED},
  • + *
  • {@link ForkedProcessEvent#BOOTERCODE_TEST_ASSUMPTIONFAILURE}.
  • + *
+ *

+ */ + static StringBuilder encode( String operation, String runMode, ReportEntry reportEntry, boolean trimStackTraces ) + { + StringBuilder encodedTo = encodeHeader( operation, runMode, UTF_8 ) + .append( ':' ); + + base64WithUtf8( encodedTo, reportEntry.getSourceName() ); + encodedTo.append( ':' ); + base64WithUtf8( encodedTo, reportEntry.getName() ); + encodedTo.append( ':' ); + base64WithUtf8( encodedTo, reportEntry.getGroup() ); + encodedTo.append( ':' ); + base64WithUtf8( encodedTo, reportEntry.getMessage() ); + encodedTo.append( ':' ) + .append( reportEntry.getElapsed() == null ? "-" : reportEntry.getElapsed().toString() ); + encode( encodedTo, reportEntry.getStackTraceWriter(), trimStackTraces ); + + return encodedTo; + } + + static StringBuilder stdOutErr( String operation, String runMode, byte[] buf, int off, int len, + Charset bufEncoding ) + { + final byte[] encodeBytes; + if ( off == 0 && buf.length == len ) + { + encodeBytes = buf; + } + else + { + encodeBytes = new byte[len]; + arraycopy( buf, off, encodeBytes, 0, len ); + } + return encodeMessage( operation, runMode, bufEncoding, printBase64Binary( encodeBytes ) ); + } + + /** + * Used in {@link #console(String)}, {@link #error(String)}, {@link #debug(String)} and {@link #warning(String)} + * and private methods extending the buffer. + */ + static StringBuilder print( String operation, String runMode, Charset msgEncoding, String... msgs ) + { + String[] encodedMsgs = new String[msgs.length]; + for ( int i = 0; i < encodedMsgs.length; i++ ) + { + String msg = encodedMsgs[i]; + encodedMsgs[i] = toBase64( msg, msgEncoding ); + } + return encodeMessage( operation, runMode, msgEncoding, encodedMsgs ); + } + + static StringBuilder encodeMessage( String operation, String runMode, Charset encoding, String... msgs ) + { + StringBuilder builder = encodeHeader( operation, runMode, encoding ); + for ( String msg : msgs ) + { + builder.append( ':' ) + .append( msg ); + + } + return builder; + } + + static StringBuilder encodeHeader( String operation, String runMode, Charset encoding ) + { + return encodeOpcode( operation, runMode ) + .append( ':' ) + .append( encoding.name() ); + } + + /** + * Used in {@link #bye()}, {@link #stopOnNextTest()} and {@link #encodeOpcode(ForkedProcessEvent)} + * and private methods extending the buffer. + * + * @param operation opcode + * @param runMode run mode + * @return encoded command + */ + static StringBuilder encodeOpcode( String operation, String runMode ) + { + return new StringBuilder( 128 ) + .append( MAGIC_NUMBER ) + .append( operation ) + .append( ':' ) + .append( runMode ); + } + + static String base64WithUtf8( String msg ) + { + if ( msg == null ) + { + return "-"; + } + else + { + byte[] binary = msg.getBytes( UTF_8 ); + return printBase64Binary( binary ); + } + } + + static void base64WithUtf8( StringBuilder encoded, String msg ) + { + encoded.append( base64WithUtf8( msg ) ); + } + + private static String toStackTrace( StackTraceWriter stw, boolean trimStackTraces ) + { + return trimStackTraces ? stw.writeTrimmedTraceToString() : stw.writeTraceToString(); + } + + static String toBase64( String msg, Charset encoding ) + { + return msg == null ? "-" : printBase64Binary( msg.getBytes( encoding ) ); + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java new file mode 100644 index 0000000..229367e --- /dev/null +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkedProcessEvent.java @@ -0,0 +1,123 @@ +package org.apache.maven.surefire.booter; + +/* + * 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 java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static java.util.Collections.unmodifiableMap; + +/** + * Events sent back to the plugin process. + * + * @author Tibor Digana (tibor17) + * @since 2.20.1 + */ +public enum ForkedProcessEvent +{ + BOOTERCODE_SYSPROPS( "sysProp", 0 ), + + BOOTERCODE_TESTSET_STARTING( "testSetStarting", 1 ), + BOOTERCODE_TESTSET_COMPLETED( "testSetCompleted", 1 ), + BOOTERCODE_TEST_STARTING( "testStarting", 1 ), + BOOTERCODE_TEST_SUCCEEDED( "testSucceeded", 1 ), + BOOTERCODE_TEST_FAILED( "testFailed", 1 ), + BOOTERCODE_TEST_SKIPPED( "testSkipped", 1 ), + BOOTERCODE_TEST_ERROR( "testError", 1 ), + BOOTERCODE_TEST_ASSUMPTIONFAILURE( "testAssumptionFailure", 1 ), + + BOOTERCODE_STDOUT( "stdOutStream", 2 ), + BOOTERCODE_STDERR( "stdErrStream", 2 ), + + BOOTERCODE_CONSOLE_INFO( "console", 3 ), + BOOTERCODE_CONSOLE_DEBUG( "debug", 3 ), + BOOTERCODE_CONSOLE_WARNING( "warning", 3 ), + BOOTERCODE_CONSOLE_ERROR( "error", 4 ), + + BOOTERCODE_BYE( "bye", 5 ), + BOOTERCODE_STOP_ON_NEXT_TEST( "stopOnNextTest", 5 ), + BOOTERCODE_NEXT_TEST( "nextTest", 5 ), + + BOOTERCODE_JVM_EXIT_ERROR( "jvmExitError", 6 ); + + public static final String MAGIC_NUMBER = ":maven:surefire:std:out:"; + + public static final Map EVENTS = events(); + + private static Map events() + { + Map events = new ConcurrentHashMap(); + for ( ForkedProcessEvent event : values() ) + { + events.put( event.getOpcode(), event ); + } + return unmodifiableMap( events ); + } + + + private final String opcode; + private final int category; + + ForkedProcessEvent( String opcode, int category ) + { + this.opcode = opcode; + this.category = category; + } + + public String getOpcode() + { + return opcode; + } + + public boolean isSysPropCategory() + { + return category == 0; + } + + public boolean isTestCategory() + { + return category == 1; + } + + public boolean isStandardStreamCategory() + { + return category == 2; + } + + public boolean isConsoleCategory() + { + return category == 3; + } + + public boolean isConsoleErrorCategory() + { + return category == 4; + } + + public boolean isControlCategory() + { + return category == 5; + } + + public boolean isJvmExitError() + { + return category == 6; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java index def345d..59c6bcb 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingReporterFactory.java @@ -19,13 +19,12 @@ package org.apache.maven.surefire.booter; * under the License. */ -import java.io.PrintStream; -import java.util.concurrent.atomic.AtomicInteger; - import org.apache.maven.surefire.report.ReporterFactory; import org.apache.maven.surefire.report.RunListener; import org.apache.maven.surefire.suite.RunResult; +import java.util.concurrent.atomic.AtomicInteger; + /** * Creates ForkingReporters, which are typically one instance per TestSet or thread. * This factory is only used inside forks. @@ -39,19 +38,19 @@ public class ForkingReporterFactory { private final boolean isTrimstackTrace; - private final PrintStream originalSystemOut; + private final ForkedChannelEncoder eventChannel; private final AtomicInteger testSetChannelId = new AtomicInteger( 1 ); - public ForkingReporterFactory( boolean trimstackTrace, PrintStream originalSystemOut ) + public ForkingReporterFactory( boolean trimstackTrace, ForkedChannelEncoder eventChannel ) { isTrimstackTrace = trimstackTrace; - this.originalSystemOut = originalSystemOut; + this.eventChannel = eventChannel; } public RunListener createReporter() { - return new ForkingRunListener( originalSystemOut, testSetChannelId.getAndIncrement(), isTrimstackTrace ); + return new ForkingRunListener( eventChannel, testSetChannelId.getAndIncrement(), isTrimstackTrace ); } public RunResult close() http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java index 6c0842a..ffe029f 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java @@ -28,15 +28,19 @@ import org.apache.maven.surefire.report.ConsoleOutputReceiver; import org.apache.maven.surefire.report.ConsoleStream; import org.apache.maven.surefire.report.ReportEntry; import org.apache.maven.surefire.report.RunListener; +import org.apache.maven.surefire.report.RunMode; import org.apache.maven.surefire.report.SafeThrowable; import org.apache.maven.surefire.report.SimpleReportEntry; import org.apache.maven.surefire.report.StackTraceWriter; import static java.lang.Integer.toHexString; import static java.nio.charset.Charset.defaultCharset; +import static org.apache.maven.surefire.report.RunMode.NORMAL_RUN; +import static org.apache.maven.surefire.util.internal.ObjectUtils.requireNonNull; import static org.apache.maven.surefire.util.internal.StringUtils.encodeStringForForkCommunication; import static org.apache.maven.surefire.util.internal.StringUtils.escapeBytesToPrintable; import static org.apache.maven.surefire.util.internal.StringUtils.escapeToPrintable; +import static org.apache.maven.surefire.util.internal.StringUtils.isBlank; /** * Encodes the full output of the test run to the stdout stream. @@ -84,11 +88,11 @@ public class ForkingRunListener */ public static final byte BOOTERCODE_CONSOLE = (byte) 'H'; - public static final byte BOOTERCODE_SYSPROPS = (byte) 'I'; + public static final byte BOOTERCODE_SYSPROPS = (byte) 'I';// - public static final byte BOOTERCODE_NEXT_TEST = (byte) 'N'; + public static final byte BOOTERCODE_NEXT_TEST = (byte) 'N';// - public static final byte BOOTERCODE_STOP_ON_NEXT_TEST = (byte) 'S'; + public static final byte BOOTERCODE_STOP_ON_NEXT_TEST = (byte) 'S';// /** * ERROR logger @@ -111,7 +115,7 @@ public class ForkingRunListener public static final byte BOOTERCODE_WARNING = (byte) 'W'; - private final PrintStream target; + private final ForkedChannelEncoder target; private final int testSetChannelId; @@ -121,7 +125,9 @@ public class ForkingRunListener private final byte[] stdErrHeader; - public ForkingRunListener( PrintStream target, int testSetChannelId, boolean trimStackTraces ) + private volatile RunMode runMode = NORMAL_RUN; + + public ForkingRunListener( ForkedChannelEncoder target, int testSetChannelId, boolean trimStackTraces ) { this.target = target; this.testSetChannelId = testSetChannelId; @@ -176,6 +182,13 @@ public class ForkingRunListener encodeAndWriteToTarget( toString( BOOTERCODE_STOP_ON_NEXT_TEST, new SimpleReportEntry(), testSetChannelId ) ); } + public RunMode markAs( RunMode currentRunMode ) + { + RunMode runMode = this.runMode; + this.runMode = requireNonNull( currentRunMode ); + return runMode; + } + void sendProps() { Properties systemProperties = System.getProperties(); @@ -260,7 +273,7 @@ public class ForkingRunListener public void error( String message, Throwable t ) { - error( ConsoleLoggerUtils.toString( message, t ) ); + error( ConsoleLoggerUtils.toString( message, t ) );//tu daj localized msg a potom string:stacktrace } public void error( Throwable t ) @@ -355,7 +368,7 @@ public class ForkingRunListener private static void nullableEncoding( StringBuilder stringBuilder, String source ) { - if ( source == null || source.length() == 0 ) + if ( isBlank( source ) ) { stringBuilder.append( "null" ); } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/report/RunListener.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/RunListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/RunListener.java index b964430..74e8e9b 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/report/RunListener.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/RunListener.java @@ -93,4 +93,13 @@ public interface RunListener * (The event is fired after the Nth test failed to signal skipping the rest of test-set.) */ void testExecutionSkippedByUser(); + + /** + * Marks the listener with run mode, e.g. normal run or re-run. + * + * @param currentRunMode set current run + * @return previous run mode; never returns null + * @throws NullPointerException if currentRunMode is null + */ + RunMode markAs( RunMode currentRunMode ); } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/report/RunMode.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/RunMode.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/RunMode.java new file mode 100644 index 0000000..0323d9a --- /dev/null +++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/RunMode.java @@ -0,0 +1,60 @@ +package org.apache.maven.surefire.report; + +/* + * 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 java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import static java.util.Collections.unmodifiableMap; + +/** + * Determines the purpose the provider started the tests. It can be either normal run or re-run. + * + * @author Tibor Digana (tibor17) + * @since 2.20.1 + */ +public enum RunMode +{ + NORMAL_RUN( "normal-run" ), RERUN( "re-run" ); + + public static final Map MODES = modes(); + + private static Map modes() + { + Map modes = new ConcurrentHashMap(); + for ( RunMode mode : values() ) + { + modes.put( mode.geRunName(), mode ); + } + return unmodifiableMap( modes ); + } + + private final String runName; + + RunMode( String runName ) + { + this.runName = runName; + } + + public String geRunName() + { + return runName; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java b/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java index e2ae963..66cef8d 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/testset/TestListResolver.java @@ -74,7 +74,7 @@ public class TestListResolver for ( String request : split( csvTests, "," ) ) { request = request.trim(); - if ( request.length() != 0 && !request.equals( "!" ) ) + if ( !request.isEmpty() && !request.equals( "!" ) ) { resolveTestRequest( request, patterns, includedFilters, excludedFilters ); } @@ -249,7 +249,7 @@ public class TestListResolver } aggregatedTest += aggregatedTest( "!", getExcludedPatterns() ); - return aggregatedTest.length() == 0 ? "" : aggregatedTest; + return aggregatedTest.isEmpty() ? "" : aggregatedTest; } public Set getIncludedPatterns() @@ -309,7 +309,7 @@ public class TestListResolver static String removeExclamationMark( String s ) { - return s.length() != 0 && s.charAt( 0 ) == '!' ? s.substring( 1 ) : s; + return !s.isEmpty() && s.charAt( 0 ) == '!' ? s.substring( 1 ) : s; } private static void updatedFilters( boolean isExcluded, ResolvedTest test, IncludedExcludedPatterns patterns, @@ -334,7 +334,7 @@ public class TestListResolver for ( ResolvedTest test : tests ) { String readableTest = test.toString(); - if ( readableTest.length() != 0 ) + if ( !readableTest.isEmpty() ) { if ( aggregatedTest.length() != 0 ) { @@ -357,7 +357,7 @@ public class TestListResolver if ( exc != null ) { exc = exc.trim(); - if ( exc.length() != 0 ) + if ( !exc.isEmpty() ) { if ( exc.contains( "!" ) ) { @@ -457,8 +457,8 @@ public class TestListResolver if ( isRegexPrefixedPattern( request ) ) { final String[] unwrapped = unwrapRegex( request ); - final boolean hasClass = unwrapped[0].length() != 0; - final boolean hasMethod = unwrapped[1].length() != 0; + final boolean hasClass = !unwrapped[0].isEmpty(); + final boolean hasMethod = !unwrapped[1].isEmpty(); if ( hasClass && hasMethod ) { test = new ResolvedTest( unwrapped[0], unwrapped[1], true ); http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java ---------------------------------------------------------------------- diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java index d1838b2..44410de 100644 --- a/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java +++ b/surefire-api/src/main/java/org/apache/maven/surefire/util/internal/StringUtils.java @@ -19,11 +19,6 @@ package org.apache.maven.surefire.util.internal; * under the License. */ -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.CharacterCodingException; -import java.nio.charset.Charset; import java.util.StringTokenizer; /** @@ -62,8 +57,6 @@ public final class StringUtils private static final byte[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - private static final Charset DEFAULT_CHARSET = Charset.defaultCharset(); - // 8-bit charset Latin-1 public static final String FORK_STREAM_CHARSET_NAME = "ISO-8859-1"; @@ -148,216 +141,6 @@ public final class StringUtils } /** - * Escape the specified string to a representation that only consists of nicely printable characters, without any - * newlines and without a comma. - *

- * The reverse-method is {@link #unescapeString(StringBuilder, CharSequence)}. - * - * @param target target string buffer. The required space will be up to {@code str.getBytes().length * 5} chars. - * @param str String to escape values in, may be {@code null}. - */ - @SuppressWarnings( "checkstyle:magicnumber" ) - public static void escapeToPrintable( StringBuilder target, CharSequence str ) - { - if ( target == null ) - { - throw new IllegalArgumentException( "The target buffer must not be null" ); - } - if ( str == null ) - { - return; - } - - for ( int i = 0; i < str.length(); i++ ) - { - char c = str.charAt( i ); - - // handle non-nicely printable chars and the comma - if ( c < 32 || c > 126 || c == '\\' || c == ',' ) - { - target.append( '\\' ); - target.append( (char) HEX_CHARS[( 0xF000 & c ) >> 12] ); - target.append( (char) HEX_CHARS[( 0x0F00 & c ) >> 8] ); - target.append( (char) HEX_CHARS[( 0x00F0 & c ) >> 4] ); - target.append( (char) HEX_CHARS[( 0x000F & c )] ); - } - else - { - target.append( c ); - } - } - } - - /** - * Reverses the effect of {@link #escapeToPrintable(StringBuilder, CharSequence)}. - * - * @param target target string buffer - * @param str the String to un-escape, as created by {@link #escapeToPrintable(StringBuilder, CharSequence)} - */ - public static void unescapeString( StringBuilder target, CharSequence str ) - { - if ( target == null ) - { - throw new IllegalArgumentException( "The target buffer must not be null" ); - } - if ( str == null ) - { - return; - } - - for ( int i = 0; i < str.length(); i++ ) - { - char ch = str.charAt( i ); - - if ( ch == '\\' ) - { - target.append( (char) ( - digit( str.charAt( ++i ) ) << 12 - | digit( str.charAt( ++i ) ) << 8 - | digit( str.charAt( ++i ) ) << 4 - | digit( str.charAt( ++i ) ) - ) ); - } - else - { - target.append( ch ); - } - } - } - - private static int digit( char ch ) - { - if ( ch >= 'a' ) - { - return 10 + ch - 'a'; - } - else if ( ch >= 'A' ) - { - return 10 + ch - 'A'; - } - else - { - return ch - '0'; - } - } - - /** - * Escapes the bytes in the array {@code str} to contain only 'printable' bytes. - *

- * Escaping is done by encoding the non-nicely printable bytes to {@code '\' + upperCaseHexBytes(byte)}. - *

- * A save length of {@code out} is {@code len * 3 + outoff}. - *

- * The reverse-method is {@link #unescapeBytes(byte[], String)}. - * - * @param out output buffer - * @param outoff offset in the output buffer - * @param input input buffer - * @param off offset in the input buffer - * @param len number of bytes to copy from the input buffer - * @return number of bytes written to {@code out} - */ - @SuppressWarnings( "checkstyle:magicnumber" ) - public static int escapeBytesToPrintable( byte[] out, int outoff, byte[] input, int off, int len ) - { - if ( out == null ) - { - throw new IllegalArgumentException( "The output array must not be null" ); - } - if ( input == null || input.length == 0 ) - { - return 0; - } - int outputPos = outoff; - int end = off + len; - for ( int i = off; i < end; i++ ) - { - byte b = input[i]; - - // handle non-nicely printable bytes - if ( b < 32 || b > 126 || b == '\\' || b == ',' ) - { - int upper = ( 0xF0 & b ) >> 4; - int lower = ( 0x0F & b ); - out[outputPos++] = '\\'; - out[outputPos++] = HEX_CHARS[upper]; - out[outputPos++] = HEX_CHARS[lower]; - } - else - { - out[outputPos++] = b; - } - } - - return outputPos - outoff; - } - - /** - * Reverses the effect of {@link #escapeBytesToPrintable(byte[], int, byte[], int, int)}. - * - * @param str the input String - * @param charsetName the charset name - * @return the number of bytes written to {@code out} - */ - public static ByteBuffer unescapeBytes( String str, String charsetName ) - { - int outPos = 0; - - if ( str == null ) - { - return ByteBuffer.wrap( new byte[0] ); - } - - byte[] out = new byte[str.length()]; - for ( int i = 0; i < str.length(); i++ ) - { - char ch = str.charAt( i ); - - if ( ch == '\\' ) - { - int upper = digit( str.charAt( ++i ) ); - int lower = digit( str.charAt( ++i ) ); - out[outPos++] = (byte) ( upper << 4 | lower ); - } - else - { - out[outPos++] = (byte) ch; - } - } - - Charset sourceCharset = Charset.forName( charsetName ); - if ( !DEFAULT_CHARSET.equals( sourceCharset ) ) - { - CharBuffer decodedFromSourceCharset; - try - { - decodedFromSourceCharset = sourceCharset.newDecoder().decode( ByteBuffer.wrap( out, 0, outPos ) ); - ByteBuffer defaultEncoded = DEFAULT_CHARSET.encode( decodedFromSourceCharset ); - - return defaultEncoded; - } - catch ( CharacterCodingException e ) - { - // ignore and fall through to the non-recoded version - } - } - - return ByteBuffer.wrap( out, 0, outPos ); - } - - public static byte[] encodeStringForForkCommunication( String string ) - { - try - { - return string.getBytes( FORK_STREAM_CHARSET_NAME ); - } - catch ( UnsupportedEncodingException e ) - { - throw new RuntimeException( "The JVM must support Charset " + FORK_STREAM_CHARSET_NAME, e ); - } - } - - /** * * @param buffer Examined StringBuffer * @param pattern a pattern which should start in buffer http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/64ae8e88/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 c43a3a6..d64b5a5 100644 --- a/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java +++ b/surefire-api/src/test/java/org/apache/maven/JUnit4SuiteTest.java @@ -39,7 +39,6 @@ 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.StringUtilsTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -60,7 +59,6 @@ import org.junit.runners.Suite; TestListResolverTest.class, ByteBufferTest.class, ConcurrencyUtilsTest.class, - StringUtilsTest.class, DefaultDirectoryScannerTest.class, RunOrderCalculatorTest.class, RunOrderTest.class,