Repository: maven-surefire
Updated Branches:
  refs/heads/master d7592d670 -> a85d3276d


[SUREFIRE-1454] Speedup Standard Output if Tests


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/a85d3276
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/a85d3276
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/a85d3276

Branch: refs/heads/master
Commit: a85d3276dbf6728ec855992352d613142aac41d3
Parents: d7592d6
Author: Tibor17 <tibordig...@apache.org>
Authored: Sat Dec 16 21:01:48 2017 +0100
Committer: Tibor17 <tibordig...@apache.org>
Committed: Sat Dec 16 21:04:49 2017 +0100

----------------------------------------------------------------------
 .../surefire/booter/ForkingRunListener.java     | 29 ++-----
 .../surefire/util/internal/StringUtils.java     | 79 +++++++++++++-------
 .../surefire/util/internal/StringUtilsTest.java | 31 ++++++--
 3 files changed, 85 insertions(+), 54 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/a85d3276/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 a060469..ce806b9 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
@@ -29,6 +29,7 @@ import org.apache.maven.surefire.report.SafeThrowable;
 import org.apache.maven.surefire.report.SimpleReportEntry;
 import org.apache.maven.surefire.report.StackTraceWriter;
 import org.apache.maven.surefire.report.TestSetReportEntry;
+import org.apache.maven.surefire.util.internal.StringUtils.EncodedArray;
 
 import java.io.PrintStream;
 import java.util.Map.Entry;
@@ -188,7 +189,7 @@ public class ForkingRunListener
         encodeAndWriteToTarget( toString( BOOTERCODE_STOP_ON_NEXT_TEST, new 
SimpleReportEntry(), testSetChannelId ) );
     }
 
-    void sendProps()
+    private void sendProps()
     {
         for ( Entry<String, String> entry : systemProps().entrySet() )
         {
@@ -200,18 +201,11 @@ public class ForkingRunListener
     @Override
     public void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
     {
-        byte[] header = stdout ? stdOutHeader : stdErrHeader;
-        byte[] content =
-            new byte[buf.length * 3 + 1]; // Hex-escaping can be up to 3 times 
length of a regular byte.
-        int i = escapeBytesToPrintable( content, 0, buf, off, len );
-        content[i++] = (byte) '\n';
-        byte[] encodeBytes = new byte[header.length + i];
-        System.arraycopy( header, 0, encodeBytes, 0, header.length );
-        System.arraycopy( content, 0, encodeBytes, header.length, i );
+        EncodedArray encodedArray = escapeBytesToPrintable( stdout ? 
stdOutHeader : stdErrHeader, buf, off, len );
 
         synchronized ( target ) // See notes about synchronization/thread 
safety in class javadoc
         {
-            target.write( encodeBytes, 0, encodeBytes.length );
+            target.write( encodedArray.getArray(), 0, encodedArray.getSize() );
             target.flush();
             if ( target.checkError() )
             {
@@ -361,28 +355,19 @@ public class ForkingRunListener
         stringBuilder.append( "," );
     }
 
-    private ForkingRunListener append( StringBuilder stringBuilder, String 
message )
+    private void append( StringBuilder stringBuilder, String message )
     {
         stringBuilder.append( encode( message ) );
-        return this;
     }
 
-    private ForkingRunListener append( StringBuilder stringBuilder, byte b )
+    private void append( StringBuilder stringBuilder, byte b )
     {
         stringBuilder.append( (char) b );
-        return this;
     }
 
     private void nullableEncoding( StringBuilder stringBuilder, Integer source 
)
     {
-        if ( source == null )
-        {
-            stringBuilder.append( "null" );
-        }
-        else
-        {
-            stringBuilder.append( source.toString() );
-        }
+        stringBuilder.append( source == null ? "null" : source.toString() );
     }
 
     private String encode( String source )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/a85d3276/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 b32d5d0..23d372c 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
@@ -218,58 +218,62 @@ public final class StringUtils
     }
 
     /**
-     * Escapes the bytes in the array {@code str} to contain only 'printable' 
bytes.
-     * <p>
+     * Escapes the bytes in the array {@code input} to contain only 
'printable' bytes.
+     * <br>
      * Escaping is done by encoding the non-nicely printable bytes to {@code 
'\' + upperCaseHexBytes(byte)}.
-     * <p>
-     * A save length of {@code out} is {@code len * 3 + outoff}.
-     * <p>
+     * <br>
      * The reverse-method is {@link #unescapeBytes(String, String)}.
+     * <br>
+     * The returned byte array is started with aligned sequence {@code header} 
and finished by {@code \n}.
      *
-     * @param out output buffer
-     * @param outoff offset in the output buffer
+     * @param header prefix header
      * @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}
+     * @throws NullPointerException if the specified parameter {@code header} 
or {@code input} is null
+     * @throws IndexOutOfBoundsException if {@code off} or {@code len} is out 
of range
+     *         ({@code off < 0 || len < 0 || off >= input.length || len > 
input.length || off > len})
      */
     @SuppressWarnings( "checkstyle:magicnumber" )
-    public static int escapeBytesToPrintable( byte[] out, int outoff, byte[] 
input, int off, int len )
+    public static EncodedArray escapeBytesToPrintable( final byte[] header, 
final byte[] input, final int off,
+                                                       final int len )
     {
-        if ( out == null )
-        {
-            throw new IllegalArgumentException( "The output array must not be 
null" );
-        }
-        if ( input == null || input.length == 0 )
+        if ( off < 0 || len < 0 || off >= input.length || len > input.length 
|| off > len )
         {
-            return 0;
+            throw new IndexOutOfBoundsException(
+                    "off < 0 || len < 0 || off >= input.length || len > 
input.length || off > len" );
         }
-        int outputPos = outoff;
-        int end = off + len;
+        // Hex-escaping can be up to 3 times length of a regular byte. Last 
character is '\n', see (+1).
+        final byte[] encodeBytes = new byte[header.length + 3 * len + 1];
+        System.arraycopy( header, 0, encodeBytes, 0, header.length );
+        int outputPos = header.length;
+        final int end = off + len;
         for ( int i = off; i < end; i++ )
         {
-            byte b = input[i];
+            final 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];
+                final int upper = ( 0xF0 & b ) >> 4;
+                final int lower = ( 0x0F & b );
+                encodeBytes[outputPos++] = '\\';
+                encodeBytes[outputPos++] = HEX_CHARS[upper];
+                encodeBytes[outputPos++] = HEX_CHARS[lower];
             }
             else
             {
-                out[outputPos++] = b;
+                encodeBytes[outputPos++] = b;
             }
         }
+        encodeBytes[outputPos++] = (byte) '\n';
 
-        return outputPos - outoff;
+        return new EncodedArray( encodeBytes, outputPos );
     }
 
     /**
-     * Reverses the effect of {@link #escapeBytesToPrintable(byte[], int, 
byte[], int, int)}.
+     * Reverses the effect of {@link #escapeBytesToPrintable(byte[], byte[], 
int, int)}.
      *
      * @param str the input String
      * @param charsetName the charset name
@@ -349,4 +353,29 @@ public final class StringUtils
             return true;
         }
     }
+
+    /**
+     * Escaped string to byte array with offset 0 and certain length.
+     */
+    public static final class EncodedArray
+    {
+        private final byte[] array;
+        private final int size;
+
+        private EncodedArray( byte[] array, int size )
+        {
+            this.array = array;
+            this.size = size;
+        }
+
+        public byte[] getArray()
+        {
+            return array;
+        }
+
+        public int getSize()
+        {
+            return size;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/a85d3276/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
index c1c8d73..dea6c9b 100644
--- 
a/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
+++ 
b/surefire-api/src/test/java/org/apache/maven/surefire/util/internal/StringUtilsTest.java
@@ -19,9 +19,13 @@ package org.apache.maven.surefire.util.internal;
  * under the License.
  */
 
+import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 
 import junit.framework.TestCase;
+import org.apache.maven.surefire.util.internal.StringUtils.EncodedArray;
+
+import static org.junit.Assert.assertArrayEquals;
 
 /**
  * @author Andreas Gudian
@@ -76,21 +80,34 @@ public class StringUtilsTest
             input[i] = b;
         }
 
-        byte[] escaped = new byte[input.length * 3];
-
-        int escapedBytes = StringUtils.escapeBytesToPrintable( escaped, 0, 
input, 0, input.length );
+        EncodedArray encodedArray = StringUtils.escapeBytesToPrintable( new 
byte[0], input, 0, input.length );
 
-        String escapedString = new String( escaped, 0, escapedBytes );
+        String escapedString = new String( encodedArray.getArray(), 0, 
encodedArray.getSize() );
 
-        assertEquals( escapedBytes, escapedString.length() );
+        assertEquals( encodedArray.getSize(), escapedString.length() );
 
-        java.nio.ByteBuffer unescaped = StringUtils.unescapeBytes( 
escapedString, Charset.defaultCharset().name() );
+        ByteBuffer unescaped = StringUtils.unescapeBytes( escapedString, 
Charset.defaultCharset().name() );
 
-        assertEquals( input.length, unescaped.remaining() - 
unescaped.position() );
+        assertEquals( input.length + 1, unescaped.remaining() - 
unescaped.position() );
 
         for ( int i = 0; i < input.length; i++ )
         {
             assertEquals( "At position " + i, input[i], unescaped.get() );
         }
     }
+
+    public void testEscapeWithHeader()
+    {
+        byte[] header = { (byte) 'a' };
+        byte[] input = { (byte) '1' };
+
+        EncodedArray encodedArray = StringUtils.escapeBytesToPrintable( 
header, input, 0, input.length );
+        assertEquals( 3, encodedArray.getSize() );
+
+        byte[] expectedResult = new byte[] { (byte) 'a', (byte) '1', (byte) 
'\n' };
+        byte[] actualResult = new byte[encodedArray.getSize()];
+        System.arraycopy( encodedArray.getArray(), 0, actualResult, 0, 
encodedArray.getSize() );
+
+        assertArrayEquals( expectedResult, actualResult );
+    }
 }

Reply via email to