You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2018/08/23 19:27:48 UTC

[maven-surefire] 02/02: Version 3.0 for SUREFIRE-1535

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch V30_SUREFIRE-1535
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 15ab5472e21b0cf5667ce52c86443a263c86e52b
Author: Tibor17 <ti...@apache.org>
AuthorDate: Thu Aug 23 21:26:58 2018 +0200

    Version 3.0 for SUREFIRE-1535
---
 .../surefire/booterclient/BooterSerializer.java    | 62 +++++++++++++++++++++-
 .../maven/surefire/booter/PropertiesWrapper.java   |  4 +-
 .../maven/surefire/booter/TypeEncodedValue.java    | 19 ++++++-
 surefire-its/pom.xml                               |  2 +-
 .../surefire/testng/TestNGDirectoryTestSuite.java  |  4 +-
 .../maven/surefire/testng/TestNGExecutor.java      | 18 +++++--
 .../maven/surefire/testng/TestNGProvider.java      | 40 ++++++++++----
 .../maven/surefire/testng/TestNGXmlTestSuite.java  |  4 +-
 8 files changed, 127 insertions(+), 26 deletions(-)

diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
index 9c501db..c5d36c5 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/BooterSerializer.java
@@ -38,6 +38,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CHILD_DELEGATION;
 import static org.apache.maven.surefire.booter.AbstractPathConfiguration.CLASSPATH;
@@ -180,14 +181,71 @@ class BooterSerializer
         return writePropertiesFile( properties, surefireTmpDir, "surefire", debug );
     }
 
+    /**
+     * This method is complementary to
+     * {@link org.apache.maven.surefire.booter.TypeEncodedValue#getDecodedValue(ClassLoader)}.
+     *
+     * @param value a value to encode
+     * @return encoded value
+     */
     private static String getTypeEncoded( Object value )
     {
         if ( value == null )
         {
             return null;
         }
-        String valueToUse = value instanceof Class ? ( (Class<?>) value ).getName() : value.toString();
-        return value.getClass().getName() + "|" + valueToUse;
+        Class<?> type = value.getClass();
+        final String valueToUse;
+        if ( type == Class.class )
+        {
+            valueToUse = ( (Class<?>) value ).getName();
+        }
+        else if ( type == String.class )
+        {
+            valueToUse = (String) value;
+        }
+        else if ( type == File.class )
+        {
+            valueToUse = ( (File) value ).getAbsolutePath();
+        }
+        else if ( type == File[].class )
+        {
+            StringBuilder paths = new StringBuilder();
+            File[] files = (File[]) value;
+            for ( int i = 0; i < files.length; i++ )
+            {
+                paths.append( files[i].getAbsolutePath() );
+                if ( i != files.length - 1 )
+                {
+                    paths.append( '|' );
+                }
+            }
+            valueToUse = paths.toString();
+        }
+        else if ( type == Boolean.class || type == boolean.class
+                || type == Integer.class || type == int.class )
+        {
+            valueToUse = value.toString();
+        }
+        else if ( type == Properties.class )
+        {
+            StringBuilder stream = new StringBuilder();
+            Properties p = (Properties) value;
+            for ( String key : p.stringPropertyNames() )
+            {
+                String val = p.getProperty( key );
+                stream.append( key )
+                        .append( '=' )
+                        .append( val == null ? "" : val )
+                        .append( '\n' );
+            }
+            valueToUse = stream.toString();
+        }
+        else
+        {
+            valueToUse = value.toString();
+        }
+        return type.getCanonicalName() + "|" + valueToUse;
     }
 
     private static String toString( Object o )
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
index d94be71..e6f96b9 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/PropertiesWrapper.java
@@ -106,7 +106,7 @@ public class PropertiesWrapper
     /**
      * Retrieves as single object that is persisted with type encoding
      *
-     * @param key The key for the propery
+     * @param key The key for the property
      * @return The object, of a supported type
      */
     public TypeEncodedValue getTypeEncodedValue( String key )
@@ -114,7 +114,7 @@ public class PropertiesWrapper
         String typeEncoded = getProperty( key );
         if ( typeEncoded != null )
         {
-            int typeSep = typeEncoded.indexOf( "|" );
+            int typeSep = typeEncoded.indexOf( '|' );
             String type = typeEncoded.substring( 0, typeSep );
             String value = typeEncoded.substring( typeSep + 1 );
             return new TypeEncodedValue( type, value );
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/TypeEncodedValue.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/TypeEncodedValue.java
index 00ad2e9..70b6c97 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/TypeEncodedValue.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/TypeEncodedValue.java
@@ -22,10 +22,14 @@ package org.apache.maven.surefire.booter;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Properties;
+import java.util.StringTokenizer;
 
 import static org.apache.maven.surefire.util.ReflectionUtils.loadClass;
 import static org.apache.maven.surefire.util.internal.StringUtils.ISO_8859_1;
+import static org.apache.maven.surefire.util.internal.StringUtils.isNotBlank;
 
 /**
  * @author Kristian Rosenvold
@@ -41,7 +45,7 @@ public class TypeEncodedValue
         this.value = value;
     }
 
-    public boolean isTypeClass()
+    private boolean isTypeClass()
     {
         return Class.class.getName().equals( type );
     }
@@ -69,6 +73,19 @@ public class TypeEncodedValue
         {
             return new File( value );
         }
+        else if ( type.equals( File[].class.getCanonicalName() ) )
+        {
+            List<File> suites = new ArrayList<File>();
+            for ( StringTokenizer tokenizer = new StringTokenizer( value, "|" ); tokenizer.hasMoreTokens(); )
+            {
+                String file = tokenizer.nextToken();
+                if ( isNotBlank( file ) )
+                {
+                    suites.add( new File( file ) );
+                }
+            }
+            return suites;
+        }
         else if ( type.equals( Boolean.class.getName() ) )
         {
             return Boolean.valueOf( value );
diff --git a/surefire-its/pom.xml b/surefire-its/pom.xml
index 5ee30c9..b89289e 100644
--- a/surefire-its/pom.xml
+++ b/surefire-its/pom.xml
@@ -104,7 +104,7 @@
           <forkMode>once</forkMode>
           <argLine>-server -Xmx64m -XX:+UseG1GC -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Djava.awt.headless=true</argLine>
           <includes>
-            <include>org/apache/**/*IT*.java</include>
+            <include>org/apache/**/*1535*.java</include>
           </includes>
           <!-- Pass current surefire version to the main suite so that it -->
           <!-- can forward to all integration test projects. SUREFIRE-513 -->
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
index a695ef6..39f1852 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
@@ -50,7 +50,7 @@ final class TestNGDirectoryTestSuite
 
     private final Map<String, String> junitOptions;
 
-    private final String testSourceDirectory;
+    private final File testSourceDirectory;
 
     private final File reportsDirectory;
 
@@ -66,7 +66,7 @@ final class TestNGDirectoryTestSuite
 
     private final int skipAfterFailureCount;
 
-    TestNGDirectoryTestSuite( String testSourceDirectory, Map<String, String> confOptions, File reportsDirectory,
+    TestNGDirectoryTestSuite( File testSourceDirectory, Map<String, String> confOptions, File reportsDirectory,
                               TestListResolver methodFilter, List<CommandLineOption> mainCliOptions,
                               int skipAfterFailureCount )
     {
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
index 0b52c4d..7f2fad3 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
@@ -37,6 +37,7 @@ import org.testng.xml.XmlSuite;
 import org.testng.xml.XmlTest;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -76,7 +77,7 @@ final class TestNGExecutor
     }
 
     @SuppressWarnings( "checkstyle:parameternumbercheck" )
-    static void run( Iterable<Class<?>> testClasses, String testSourceDirectory,
+    static void run( Iterable<Class<?>> testClasses, File testSourceDirectory,
                             Map<String, String> options, // string,string because TestNGMapConfigurator#configure()
                             RunListener reportManager, File reportsDirectory,
                             TestListResolver methodFilter, List<CommandLineOption> mainCliOptions,
@@ -269,7 +270,7 @@ final class TestNGExecutor
         return xms;
     }
 
-    static void run( List<String> suiteFiles, String testSourceDirectory,
+    static void run( List<String> suiteFiles, File testSourceDirectory,
                             Map<String, String> options, // string,string because TestNGMapConfigurator#configure()
                             RunListener reportManager, File reportsDirectory, int skipAfterFailureCount )
         throws TestSetFailedException
@@ -303,8 +304,9 @@ final class TestNGExecutor
         }
     }
 
-    private static void postConfigure( TestNG testNG, String sourcePath, final RunListener reportManager,
+    private static void postConfigure( TestNG testNG, File sourcePath, final RunListener reportManager,
                                        File reportsDirectory, int skipAfterFailureCount, int verboseLevel )
+            throws TestSetFailedException
     {
         // 0 (default): turn off all TestNG output
         testNG.setVerbose( verboseLevel );
@@ -320,10 +322,16 @@ final class TestNGExecutor
             testNG.addListener( new FailFastListener( createStoppable( reportManager, skipAfterFailureCount ) ) );
         }
 
-        // FIXME: use classifier to decide if we need to pass along the source dir (only for JDK14)
         if ( sourcePath != null )
         {
-            testNG.setSourcePath( sourcePath );
+            try
+            {
+                testNG.setSourcePath( sourcePath.getCanonicalPath() );
+            }
+            catch ( IOException e )
+            {
+                throw new TestSetFailedException( e.getLocalizedMessage(), e );
+            }
         }
 
         testNG.setOutputDirectory( reportsDirectory.getAbsolutePath() );
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
index 14e103a..8b85819 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
@@ -43,6 +43,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.apache.maven.surefire.booter.CommandReader.getReader;
 import static org.apache.maven.surefire.report.ConsoleOutputCapture.startCapture;
 import static org.apache.maven.surefire.testset.TestListResolver.getEmptyTestListResolver;
@@ -100,22 +102,29 @@ public class TestNGProvider
 
         final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
         final RunListener reporter = reporterFactory.createReporter();
-        /**
+        /*
          * {@link org.apache.maven.surefire.report.ConsoleOutputCapture#startCapture(ConsoleOutputReceiver)}
          * called in prior to initializing variable {@link #testsToRun}
          */
         startCapture( (ConsoleOutputReceiver) reporter );
 
-        RunResult runResult;
+        final RunResult runResult;
         try
         {
-            if ( isTestNGXmlTestSuite( testRequest ) )
+            final Class<?> forkTestSetType = forkTestSet.getClass();
+
+            final boolean isXmlSuite =
+                    forkTestSetType == File.class || forkTestSetType.getComponentType() == File.class;
+
+            final List<File> suiteXmlFiles = isXmlSuite ? toXmlSuiteFiles( forkTestSetType, forkTestSet ) : null;
+
+            if ( suiteXmlFiles != null )
             {
                 if ( commandsReader != null )
                 {
                     commandsReader.awaitStarted();
                 }
-                TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite();
+                TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite( suiteXmlFiles );
                 testNGXmlTestSuite.locateTestSets();
                 testNGXmlTestSuite.execute( reporter );
             }
@@ -153,9 +162,13 @@ public class TestNGProvider
         return runResult;
     }
 
-    boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
+    private boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
+    {
+        return isTestNGXmlTestSuite( testSuiteDefinition.getSuiteXmlFiles() );
+    }
+
+    private boolean isTestNGXmlTestSuite( Collection<File> suiteXmlFiles )
     {
-        Collection<File> suiteXmlFiles = testSuiteDefinition.getSuiteXmlFiles();
         return !suiteXmlFiles.isEmpty() && !hasSpecificTests();
     }
 
@@ -195,15 +208,15 @@ public class TestNGProvider
 
     private TestNGDirectoryTestSuite newDirectorySuite()
     {
-        return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
+        return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory(), providerProperties,
                                              reporterConfiguration.getReportsDirectory(), getTestFilter(),
                                              mainCliOptions, getSkipAfterFailureCount() );
     }
 
-    private TestNGXmlTestSuite newXmlSuite()
+    private TestNGXmlTestSuite newXmlSuite( List<File> suiteXmlFiles )
     {
-        return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(),
-                                       testRequest.getTestSourceDirectory().toString(),
+        return new TestNGXmlTestSuite( suiteXmlFiles,
+                                       testRequest.getTestSourceDirectory(),
                                        providerProperties,
                                        reporterConfiguration.getReportsDirectory(), getSkipAfterFailureCount() );
     }
@@ -216,7 +229,7 @@ public class TestNGProvider
         {
             try
             {
-                return newXmlSuite().locateTestSets();
+                return newXmlSuite( testRequest.getSuiteXmlFiles() ).locateTestSets();
             }
             catch ( TestSetFailedException e )
             {
@@ -247,4 +260,9 @@ public class TestNGProvider
         TestListResolver filter = optionallyWildcardFilter( testRequest.getTestListResolver() );
         return filter.isWildcard() ? getEmptyTestListResolver() : filter;
     }
+
+    private static List<File> toXmlSuiteFiles( Class<?> forkTestSetType, Object forkTestSet )
+    {
+        return forkTestSetType.isArray() ? asList( (File[]) forkTestSet ) : singletonList( (File) forkTestSet );
+    }
 }
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
index c8abd60..1570a14 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
@@ -42,7 +42,7 @@ final class TestNGXmlTestSuite
 
     private List<String> suiteFilePaths;
 
-    private final String testSourceDirectory;
+    private final File testSourceDirectory;
 
     private final Map<String, String> options;
 
@@ -54,7 +54,7 @@ final class TestNGXmlTestSuite
      * Creates a testng testset to be configured by the specified
      * xml file(s). The XML files are suite definitions files according to TestNG DTD.
      */
-    TestNGXmlTestSuite( List<File> suiteFiles, String testSourceDirectory, Map<String, String> confOptions,
+    TestNGXmlTestSuite( List<File> suiteFiles, File testSourceDirectory, Map<String, String> confOptions,
                         File reportsDirectory, int skipAfterFailureCount )
     {
         this.suiteFiles = suiteFiles;