You are viewing a plain text version of this content. The canonical link for it is here.
Posted to surefire-commits@maven.apache.org by br...@apache.org on 2007/05/24 07:21:49 UTC

svn commit: r541168 - in /maven/surefire/trunk: maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/ surefire-api/src/main/java/org/apache/maven/surefire/suite/ surefire-booter/src/main/java/org/apache/maven/surefire/booter/ surefire-p...

Author: brett
Date: Wed May 23 22:21:47 2007
New Revision: 541168

URL: http://svn.apache.org/viewvc?view=rev&rev=541168
Log:
apply changes from the surefire-collab2 branch that improve TestNG support

Added:
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java   (with props)
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java   (with props)
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java   (with props)
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java   (with props)
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java   (with props)
Modified:
    maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
    maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/AbstractDirectoryTestSuite.java
    maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/SurefireTestSuite.java
    maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireBooter.java
    maven/surefire/trunk/surefire-providers/surefire-testng/pom.xml
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
    maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java

Modified: maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java (original)
+++ maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java Wed May 23 22:21:47 2007
@@ -98,15 +98,6 @@
      */
     private File basedir;
 
-    // FIXME this field is not used
-    /**
-     * The directory containing generated classes of the project being tested.
-     *
-     * @parameter expression="${project.build.outputDirectory}"
-     * @required
-     */
-    private File classesDirectory;
-
     /**
      * The directory containing generated test classes of the project being tested.
      *
@@ -183,6 +174,14 @@
     private Properties systemProperties;
 
     /**
+     * List of properties for configuring all TestNG related configurations. This is the new
+     * preferred method of configuring TestNG.
+     *
+     * @parameter
+     */
+    private Properties properties;
+
+    /**
      * Map of of plugin artifacts.
      *
      * @parameter expression="${plugin.artifactMap}"
@@ -324,7 +323,7 @@
      * default-value="false"
      * @todo test how this works with forking, and console/file output parallelism
      */
-    private boolean parallel;
+    private String parallel;
 
     /**
      * Whether to trim the stack trace in the reports to just the lines within the test, or show the full trace.
@@ -436,20 +435,13 @@
             getLog().info( "Tests are skipped." );
             return false;
         }
-        else if ( !testClassesDirectory.exists() )
+
+        if ( !testClassesDirectory.exists() )
         {
             getLog().info( "No tests to run." );
             return false;
         }
 
-        if ( parallel )
-        {
-            if ( threadCount < 1 )
-            {
-                throw new MojoFailureException( "Must have at least one thread in parallel mode" );
-            }
-        }
-
         if ( useSystemClassLoader && ForkConfiguration.FORK_NEVER.equals( forkMode ) )
         {
             getLog().warn( "useSystemClassloader=true setting has no effect when not forking" );
@@ -458,6 +450,36 @@
         return true;
     }
 
+    /**
+     * Converts old TestNG configuration parameters over to new properties based configuration
+     * method. (if any are defined the old way)
+     */
+    private void convertTestNGParameters()
+    {
+        if ( properties == null )
+        {
+            properties = new Properties();
+        }
+
+        if ( this.parallel != null )
+        {
+            properties.put( "parallel", this.parallel );
+        }
+        if ( this.excludedGroups != null )
+        {
+            properties.put( "excludegroups", this.excludedGroups );
+        }
+        if ( this.groups != null )
+        {
+            properties.put( "groups", this.groups );
+        }
+
+        if ( this.threadCount > 0 )
+        {
+            properties.put( "threadcount", new Integer( this.threadCount ) );
+        }
+    }
+
     private SurefireBooter constructSurefireBooter()
         throws MojoExecutionException, MojoFailureException
     {
@@ -484,8 +506,6 @@
 
             if ( testNgArtifact != null )
             {
-                addArtifact( surefireBooter, testNgArtifact );
-
                 VersionRange range = VersionRange.createFromVersionSpec( "[4.7,)" );
                 if ( !range.containsVersion( testNgArtifact.getSelectedVersion() ) )
                 {
@@ -494,6 +514,15 @@
                             testNgArtifact.getVersion() );
                 }
 
+                convertTestNGParameters();
+
+                if ( this.testClassesDirectory != null )
+                {
+                    properties.put( "testng.test.classpath", testClassesDirectory.getAbsolutePath() );
+                }
+
+                addArtifact( surefireBooter, testNgArtifact );
+
                 // The plugin uses a JDK based profile to select the right testng. We might be explicity using a
                 // different one since its based on the source level, not the JVM. Prune using the filter.
                 addProvider( surefireBooter, "surefire-testng", surefireArtifact.getBaseVersion(), testNgArtifact );
@@ -529,15 +558,10 @@
             {
                 throw new MojoExecutionException( "suiteXmlFiles is configured, but there is no TestNG dependency" );
             }
-            for ( int i = 0; i < suiteXmlFiles.length; i++ )
-            {
-                File file = suiteXmlFiles[i];
-                if ( file.exists() )
-                {
-                    surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite",
-                                                 new Object[]{file, testSourceDirectory.getAbsolutePath()} );
-                }
-            }
+
+            // TODO: properties should be passed in here too
+            surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGXmlTestSuite", new Object[]{
+                suiteXmlFiles, testSourceDirectory.getAbsolutePath(), testNgArtifact.getVersion()} );
         }
         else
         {
@@ -585,13 +609,14 @@
             if ( testNgArtifact != null )
             {
                 surefireBooter.addTestSuite( "org.apache.maven.surefire.testng.TestNGDirectoryTestSuite", new Object[]{
-                    testClassesDirectory, includes, excludes, groups, excludedGroups, Boolean.valueOf( parallel ),
-                    new Integer( threadCount ), testSourceDirectory.getAbsolutePath()} );
+                    testClassesDirectory, includes, excludes, testSourceDirectory.getAbsolutePath(),
+                    testNgArtifact.getVersion(), properties} );
             }
             else
             {
                 String junitDirectoryTestSuite;
-                if ( junitArtifact != null && junitArtifact.getBaseVersion() != null && junitArtifact.getBaseVersion().startsWith( "4" ) )
+                if ( junitArtifact != null && junitArtifact.getBaseVersion() != null &&
+                    junitArtifact.getBaseVersion().startsWith( "4" ) )
                 {
                     junitDirectoryTestSuite = "org.apache.maven.surefire.junit4.JUnit4DirectoryTestSuite";
                 }

Modified: maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/AbstractDirectoryTestSuite.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/AbstractDirectoryTestSuite.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/AbstractDirectoryTestSuite.java (original)
+++ maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/AbstractDirectoryTestSuite.java Wed May 23 22:21:47 2007
@@ -167,18 +167,9 @@
     {
         if ( testSets == null )
         {
-            throw new IllegalStateException( "You must call locateTestSets before calling getNumTestSets" );
+            throw new IllegalStateException( "You must call locateTestSets before calling getNumTests" );
         }
         return totalTests;
-    }
-
-    public int getNumTestSets()
-    {
-        if ( testSets == null )
-        {
-            throw new IllegalStateException( "You must call locateTestSets before calling getNumTestSets" );
-        }
-        return testSets.size();
     }
 
     private String[] collectTests( File basedir, List includes, List excludes )

Modified: maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/SurefireTestSuite.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/SurefireTestSuite.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/SurefireTestSuite.java (original)
+++ maven/surefire/trunk/surefire-api/src/main/java/org/apache/maven/surefire/suite/SurefireTestSuite.java Wed May 23 22:21:47 2007
@@ -40,8 +40,6 @@
 
     int getNumTests();
 
-    int getNumTestSets();
-
     Map locateTestSets( ClassLoader classLoader )
         throws TestSetFailedException;
 }

Modified: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireBooter.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireBooter.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireBooter.java (original)
+++ maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireBooter.java Wed May 23 22:21:47 2007
@@ -192,7 +192,7 @@
     public boolean run()
         throws SurefireBooterForkException, SurefireExecutionException
     {
-        boolean result = false;
+        boolean result;
 
         if ( ForkConfiguration.FORK_NEVER.equals( forkConfiguration.getForkMode() ) )
         {
@@ -484,7 +484,7 @@
 
             if ( params != null )
             {
-                String paramProperty = params[0].toString();
+                String paramProperty = convert( params[0] );
                 String typeProperty = params[0].getClass().getName();
                 for ( int j = 1; j < params.length; j++ )
                 {
@@ -492,7 +492,7 @@
                     typeProperty += "|";
                     if ( params[j] != null )
                     {
-                        paramProperty += params[j].toString();
+                        paramProperty += convert( params[j] );
                         typeProperty += params[j].getClass().getName();
                     }
                 }
@@ -502,6 +502,28 @@
         }
     }
 
+    private String convert( Object param )
+    {
+        if ( param instanceof File[] )
+        {
+            String s = "[";
+            File[] f = (File[]) param;
+            for ( int i = 0; i < f.length; i++ )
+            {
+                s += f[i];
+                if ( i > 0 )
+                {
+                    s += ",";
+                }
+            }
+            return s + "]";
+        }
+        else
+        {
+            return param.toString();
+        }
+    }
+
     private boolean fork( Properties properties, boolean showHeading, boolean showFooter )
         throws SurefireBooterForkException
     {
@@ -716,6 +738,16 @@
                 else if ( types[i].equals( File.class.getName() ) )
                 {
                     paramObjects[i] = new File( params[i] );
+                }
+                else if ( types[i].equals( File[].class.getName() ) )
+                {
+                    List stringList = processStringList( params[i] );
+                    File[] fileList = new File[stringList.size()];
+                    for ( int j = 0; j < stringList.size(); j++ )
+                    {
+                        fileList[j] = new File( (String) stringList.get( j ) );
+                    }
+                    paramObjects[i] = fileList;
                 }
                 else if ( types[i].equals( ArrayList.class.getName() ) )
                 {

Modified: maven/surefire/trunk/surefire-providers/surefire-testng/pom.xml
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/pom.xml?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/pom.xml (original)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/pom.xml Wed May 23 22:21:47 2007
@@ -17,7 +17,8 @@
   ~ under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.maven.surefire</groupId>
@@ -26,6 +27,13 @@
   </parent>
   <artifactId>surefire-testng</artifactId>
   <name>SureFire TestNG Runner</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>2.0</version>
+    </dependency>
+  </dependencies>
   <profiles>
     <profile>
       <id>jdk14</id>
@@ -36,7 +44,7 @@
         <dependency>
           <groupId>org.testng</groupId>
           <artifactId>testng</artifactId>
-          <version>5.1</version>
+          <version>5.6</version>
           <classifier>jdk14</classifier>
         </dependency>
       </dependencies>
@@ -50,7 +58,7 @@
         <dependency>
           <groupId>org.testng</groupId>
           <artifactId>testng</artifactId>
-          <version>5.1</version>
+          <version>5.6</version>
           <classifier>jdk15</classifier>
         </dependency>
       </dependencies>

Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java (original)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGDirectoryTestSuite.java Wed May 23 22:21:47 2007
@@ -19,68 +19,41 @@
  * under the License.
  */
 
+import org.apache.maven.artifact.versioning.ArtifactVersion;
 import org.apache.maven.surefire.report.ReporterException;
 import org.apache.maven.surefire.report.ReporterManager;
 import org.apache.maven.surefire.suite.AbstractDirectoryTestSuite;
 import org.apache.maven.surefire.testset.SurefireTestSet;
 import org.apache.maven.surefire.testset.TestSetFailedException;
-import org.testng.ISuiteListener;
-import org.testng.ITestListener;
-import org.testng.TestNG;
-import org.testng.xml.XmlClass;
-import org.testng.xml.XmlSuite;
-import org.testng.xml.XmlTest;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 /**
  * Test suite for TestNG based on a directory of Java test classes. Can also execute JUnit tests.
  *
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
  */
 public class TestNGDirectoryTestSuite
     extends AbstractDirectoryTestSuite
 {
-    private String groups;
+    private ArtifactVersion version;
 
-    private String excludedGroups;
-
-    private boolean parallel;
-
-    private int threadCount;
+    private Map options;
 
     private String testSourceDirectory;
 
-    public TestNGDirectoryTestSuite( File basedir, ArrayList includes, ArrayList excludes, String groups,
-                                     String excludedGroups, Boolean parallel, Integer threadCount,
-                                     String testSourceDirectory )
+    public TestNGDirectoryTestSuite( File basedir, List includes, List excludes, String testSourceDirectory,
+                                     ArtifactVersion artifactVersion, Map confOptions )
     {
         super( basedir, includes, excludes );
 
-        this.groups = groups;
-
-        this.excludedGroups = excludedGroups;
-
-        this.parallel = parallel.booleanValue();
-
-        this.threadCount = threadCount.intValue();
-
+        this.options = confOptions;
         this.testSourceDirectory = testSourceDirectory;
-
-    }
-
-    public Map locateTestSets( ClassLoader classLoader )
-        throws TestSetFailedException
-    {
-        // TODO: fix
-        // override classloader. That keeps us all together for now, which makes it work, but could pose problems of
-        // classloader separation if the tests use plexus-utils.
-        return super.locateTestSets( classLoader );
+        this.version = artifactVersion;
     }
 
     protected SurefireTestSet createTestSet( Class testClass, ClassLoader classLoader )
@@ -88,6 +61,7 @@
         return new TestNGTestSet( testClass );
     }
 
+    // single class test
     public void execute( String testSetName, ReporterManager reporterManager, ClassLoader classLoader )
         throws ReporterException, TestSetFailedException
     {
@@ -102,13 +76,8 @@
             throw new TestSetFailedException( "Unable to find test set '" + testSetName + "' in suite" );
         }
 
-        XmlSuite suite = new XmlSuite();
-        suite.setParallel( parallel );
-        suite.setThreadCount( threadCount );
-
-        createXmlTest( suite, testSet );
-
-        executeTestNG( suite, reporterManager, classLoader );
+        TestNGExecutor.run( new Class[]{testSet.getTestClass()}, this.testSourceDirectory, this.options, this.version,
+                            reporterManager, this );
     }
 
     public void execute( ReporterManager reporterManager, ClassLoader classLoader )
@@ -119,79 +88,14 @@
             throw new IllegalStateException( "You must call locateTestSets before calling execute" );
         }
 
-        XmlSuite suite = new XmlSuite();
-        suite.setParallel( parallel );
-        suite.setThreadCount( threadCount );
-
-        for ( Iterator i = testSets.values().iterator(); i.hasNext(); )
-        {
-            SurefireTestSet testSet = (SurefireTestSet) i.next();
-
-            createXmlTest( suite, testSet );
-        }
-
-        executeTestNG( suite, reporterManager, classLoader );
-    }
-
-    private void createXmlTest( XmlSuite suite, SurefireTestSet testSet )
-    {
-        XmlTest xmlTest = new XmlTest( suite );
-        xmlTest.setName( testSet.getName() );
-        xmlTest.setXmlClasses( Collections.singletonList( new XmlClass( testSet.getTestClass() ) ) );
-
-        if ( groups != null )
+        Class[] testClasses = new Class[testSets.size()];
+        int i = 0;
+        for ( Iterator it = testSets.values().iterator(); it.hasNext(); )
         {
-            xmlTest.setIncludedGroups( Arrays.asList( groups.split( "," ) ) );
+            SurefireTestSet testSet = (SurefireTestSet) it.next();
+            testClasses[i++] = testSet.getTestClass();
         }
-        if ( excludedGroups != null )
-        {
-            xmlTest.setExcludedGroups( Arrays.asList( excludedGroups.split( "," ) ) );
-        }
-
-        // if ( !TestNGClassFinder.isTestNGClass( testSet.getTestClass(), annotationFinder ) )
-        // TODO: this is a bit dodgy, but isTestNGClass wasn't working
-        try
-        {
-            Class junitClass = Class.forName( "junit.framework.Test" );
-            Class junitBase = Class.forName( "junit.framework.TestCase" );
-
-            if ( junitClass.isAssignableFrom( testSet.getTestClass() ) ||
-                junitBase.isAssignableFrom( testSet.getTestClass() ) )
-            {
-                xmlTest.setJUnit( true );
-            }
-
-        }
-        catch ( ClassNotFoundException e )
-        {
-        }
-    }
-
-    private void executeTestNG( XmlSuite suite, ReporterManager reporterManager, ClassLoader classLoader )
-    {
-        TestNG testNG = new TestNG( false );
-
-        // turn off all TestNG output
-        testNG.setVerbose( 0 );
-
-        testNG.setXmlSuites( Collections.singletonList( suite ) );
-
-        testNG.setListenerClasses( new ArrayList() );
-
-        TestNGReporter reporter = new TestNGReporter( reporterManager, this );
-        testNG.addListener( (ITestListener) reporter );
-        testNG.addListener( (ISuiteListener) reporter );
-
-        // Set source path so testng can find javadoc annotations if not in 1.5 jvm
-        if ( testSourceDirectory != null )
-        {
-            testNG.setSourcePath( testSourceDirectory );
-        }
-
-        // workaround for SUREFIRE-49
-        // TestNG always creates an output directory, and if not set the name for the directory is "null"
-        testNG.setOutputDirectory( System.getProperty( "java.io.tmpdir" ) );
 
-        testNG.runSuitesLocally();
+        TestNGExecutor.run( testClasses, this.testSourceDirectory, this.options, this.version, reporterManager, this );
     }
 }

Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java (original)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGExecutor.java Wed May 23 22:21:47 2007
@@ -19,20 +19,26 @@
  * under the License.
  */
 
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
 import org.apache.maven.surefire.report.ReporterManager;
 import org.apache.maven.surefire.suite.SurefireTestSuite;
-import org.testng.ISuiteListener;
-import org.testng.ITestListener;
+import org.apache.maven.surefire.testng.conf.Configurator;
+import org.apache.maven.surefire.testng.conf.TestNG4751Configurator;
+import org.apache.maven.surefire.testng.conf.TestNG52Configurator;
+import org.apache.maven.surefire.testng.conf.TestNGMapConfigurator;
+import org.apache.maven.surefire.util.NestedRuntimeException;
 import org.testng.TestNG;
-import org.testng.xml.XmlSuite;
 
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Contains utility methods for executing TestNG.
  *
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
  */
 public class TestNGExecutor
 {
@@ -40,33 +46,74 @@
     {
     }
 
-    static void executeTestNG( SurefireTestSuite surefireSuite, String testSourceDirectory, XmlSuite suite,
-                               ReporterManager reporterManager )
+    public static void run( Class[] testClasses, String testSourceDirectory, Map options, ArtifactVersion version,
+                            ReporterManager reportManager, SurefireTestSuite suite )
     {
-        TestNG testNG = new TestNG( false );
+        TestNG testng = new TestNG( false );
+        Configurator configurator = getConfigurator( version );
+        configurator.configure( testng, options );
+        postConfigure( testng, testSourceDirectory, reportManager, suite );
 
-        // turn off all TestNG output
-        testNG.setVerbose( 0 );
+        testng.setTestClasses( testClasses );
+        testng.run();
+    }
 
-        testNG.setXmlSuites( Collections.singletonList( suite ) );
+    public static void run( List suiteFiles, String testSourceDirectory, Map options, ArtifactVersion version,
+                            ReporterManager reportManager, SurefireTestSuite suite )
+    {
+        TestNG testng = new TestNG( false );
+        Configurator configurator = getConfigurator( version );
+        configurator.configure( testng, options );
+        postConfigure( testng, testSourceDirectory, reportManager, suite );
 
-        testNG.setListenerClasses( new ArrayList() );
+        testng.setTestSuites( suiteFiles );
+        testng.run();
+    }
 
-        TestNGReporter reporter = new TestNGReporter( reporterManager, surefireSuite );
-        testNG.addListener( (ITestListener) reporter );
-        testNG.addListener( (ISuiteListener) reporter );
+    private static Configurator getConfigurator( ArtifactVersion version )
+    {
+        try
+        {
+            VersionRange range = VersionRange.createFromVersionSpec( "[4.7,5.1]" );
+            if ( range.containsVersion( version ) )
+            {
+                return new TestNG4751Configurator();
+            }
+            range = VersionRange.createFromVersion( "5.2" );
+            if ( range.containsVersion( version ) )
+            {
+                return new TestNG52Configurator();
+            }
+            range = VersionRange.createFromVersionSpec( "[5.3,)" );
+            if ( range.containsVersion( version ) )
+            {
+                return new TestNGMapConfigurator();
+            }
 
-        // Set source path so testng can find javadoc annotations if not in 1.5 jvm
-        if ( testSourceDirectory != null )
+            throw new NestedRuntimeException( "Unknown TestNG version " + version );
+        }
+        catch ( InvalidVersionSpecificationException invsex )
         {
-            testNG.setSourcePath( testSourceDirectory );
+            throw new NestedRuntimeException( "Bug in plugin. Please report it with the attached stacktrace", invsex );
         }
+    }
+
+
+    private static void postConfigure( TestNG testNG, String sourcePath, ReporterManager reportManager,
+                                       SurefireTestSuite suite )
+    {
+        // turn off all TestNG output
+        testNG.setVerbose( 0 );
 
-        // TODO: Doesn't find testng.xml based suites when these are un-commented
-        // TestNG ~also~ looks for the currentThread context classloader
-        // ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
-        // Thread.currentThread().setContextClassLoader( suite.getClass().getClassLoader() );
-        testNG.runSuitesLocally();
-        //Thread.currentThread().setContextClassLoader( oldClassLoader );
+        TestNGReporter reporter = new TestNGReporter( reportManager, suite );
+        testNG.addListener( (Object) reporter );
+        // TODO: we should have the Profile so that we can decide if this is needed or not
+        if ( sourcePath != null )
+        {
+            testNG.setSourcePath( sourcePath );
+        }
+        // workaround for SUREFIRE-49
+        // TestNG always creates an output directory, and if not set the name for the directory is "null"
+        testNG.setOutputDirectory( System.getProperty( "java.io.tmpdir" ) );
     }
 }

Modified: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java?view=diff&rev=541168&r1=541167&r2=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java (original)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGXmlTestSuite.java Wed May 23 22:21:47 2007
@@ -19,20 +19,17 @@
  * under the License.
  */
 
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.surefire.report.ReporterManager;
 import org.apache.maven.surefire.suite.SurefireTestSuite;
 import org.apache.maven.surefire.testset.TestSetFailedException;
-import org.testng.xml.Parser;
-import org.testng.xml.XmlSuite;
-import org.testng.xml.XmlTest;
-import org.xml.sax.SAXException;
 
-import javax.xml.parsers.ParserConfigurationException;
 import java.io.File;
-import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -40,32 +37,35 @@
  * Handles suite xml file definitions for TestNG.
  *
  * @author jkuhnert
+ * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
  */
 public class TestNGXmlTestSuite
     implements SurefireTestSuite
 {
-    private File suiteFile;
+    private File[] suiteFiles;
+
+    private List suiteFilePaths;
 
     private String testSourceDirectory;
 
-    private XmlSuite suite;
+    private ArtifactVersion version;
+
+    private Map options = new HashMap();
 
+    // Not really used
     private Map testSets;
 
     /**
      * Creates a testng testset to be configured by the specified
      * xml file.
      */
-    public TestNGXmlTestSuite( File suiteFile, String testSourceDirectory )
+    public TestNGXmlTestSuite( File[] suiteFiles, String testSourceDirectory, String artifactVersion )
     {
-        this.suiteFile = suiteFile;
+        this.suiteFiles = suiteFiles;
 
-        this.testSourceDirectory = testSourceDirectory;
-    }
+        this.version = new DefaultArtifactVersion( artifactVersion );
 
-    public TestNGXmlTestSuite( File suiteFile )
-    {
-        this( suiteFile, null );
+        this.testSourceDirectory = testSourceDirectory;
     }
 
     public void execute( ReporterManager reporterManager, ClassLoader classLoader )
@@ -75,47 +75,20 @@
             throw new IllegalStateException( "You must call locateTestSets before calling execute" );
         }
 
-        TestNGExecutor.executeTestNG( this, testSourceDirectory, suite, reporterManager );
+        TestNGExecutor.run( this.suiteFilePaths, this.testSourceDirectory, this.options, this.version, reporterManager,
+                            this );
     }
 
     public void execute( String testSetName, ReporterManager reporterManager, ClassLoader classLoader )
         throws TestSetFailedException
     {
-        if ( testSets == null )
-        {
-            throw new IllegalStateException( "You must call locateTestSets before calling execute" );
-        }
-        XmlTest testSet = (XmlTest) testSets.get( testSetName );
-
-        if ( testSet == null )
-        {
-            throw new TestSetFailedException( "Unable to find test set '" + testSetName + "' in suite" );
-        }
-
-        List originalTests = new ArrayList( suite.getTests() );
-        for ( Iterator i = suite.getTests().iterator(); i.hasNext(); )
-        {
-            XmlTest test = (XmlTest) i.next();
-            if ( !test.getName().equals( testSetName ) )
-            {
-                i.remove();
-            }
-        }
-        TestNGExecutor.executeTestNG( this, testSourceDirectory, suite, reporterManager );
-
-        suite.getTests().clear();
-        suite.getTests().addAll( originalTests );
+        throw new TestSetFailedException( "Cannot run individual test when suite files are specified" );
     }
 
     public int getNumTests()
     {
-        // TODO: need to get this from TestNG somehow
-        return 1;
-    }
-
-    public int getNumTestSets()
-    {
-        return suite.getTests().size();
+        // TODO: this is not correct
+        return suiteFiles.length;
     }
 
     public Map locateTestSets( ClassLoader classLoader )
@@ -125,37 +98,26 @@
         {
             throw new IllegalStateException( "You can't call locateTestSets twice" );
         }
-        testSets = new LinkedHashMap();
 
-        try
-        {
-            suite = new Parser( suiteFile.getAbsolutePath() ).parse();
-        }
-        catch ( IOException e )
+        if ( this.suiteFiles == null )
         {
-            throw new TestSetFailedException( "Error reading test suite", e );
-        }
-        catch ( ParserConfigurationException e )
-        {
-            throw new TestSetFailedException( "Error reading test suite", e );
-        }
-        catch ( SAXException e )
-        {
-            throw new TestSetFailedException( "Error reading test suite", e );
+            throw new IllegalStateException( "No suite files were specified" );
         }
 
-        for ( Iterator i = suite.getTests().iterator(); i.hasNext(); )
-        {
-            XmlTest xmlTest = (XmlTest) i.next();
+        this.testSets = new HashMap();
+        this.suiteFilePaths = new ArrayList();
 
-            if ( testSets.containsKey( xmlTest.getName() ) )
+        for ( Iterator i = Arrays.asList( suiteFiles ).iterator(); i.hasNext(); )
+        {
+            File file = (File) i.next();
+            if ( !file.exists() || !file.isFile() )
             {
-                throw new TestSetFailedException( "Duplicate test set '" + xmlTest.getName() + "'" );
+                throw new TestSetFailedException( "Suite file " + file + " is not a valid file" );
             }
-
-            // We don't need to put real test sets in here, the key is the important part
-            testSets.put( xmlTest.getName(), xmlTest );
+            this.testSets.put( file, file.getAbsolutePath() );
+            this.suiteFilePaths.add( file.getAbsolutePath() );
         }
-        return testSets;
+
+        return this.testSets;
     }
 }

Added: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java?view=auto&rev=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java (added)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java Wed May 23 22:21:47 2007
@@ -0,0 +1,114 @@
+package org.apache.maven.surefire.testng.conf;
+
+/*
+ * 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.util.NestedRuntimeException;
+import org.testng.TestNG;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public abstract class AbstractDirectConfigurator
+    implements Configurator
+{
+    protected final Map setters;
+
+    protected AbstractDirectConfigurator()
+    {
+        Map options = new HashMap();
+        options.put( "groups", new Setter( "setGroups", String.class ) );
+        options.put( "excludedgroups", new Setter( "setExcludedGroups", String.class ) );
+        options.put( "junit", new Setter( "setJUnit", Boolean.class ) );
+        options.put( "threadcount", new Setter( "setThreadCount", int.class ) );
+        this.setters = options;
+    }
+
+    public void configure( TestNG testng, Map options )
+    {
+        for ( Iterator it = options.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            String key = (String) entry.getKey();
+            Object val = entry.getValue();
+
+            Setter setter = (Setter) setters.get( key );
+            if ( setter != null )
+            {
+                try
+                {
+                    setter.invoke( testng, val );
+                }
+                catch ( Exception ex )
+                {
+                    throw new NestedRuntimeException( "Cannot set option " + key + " with value " + val, ex );
+                }
+
+            }
+        }
+    }
+
+    public static final class Setter
+    {
+        private final String setterName;
+
+        private final Class paramClass;
+
+        public Setter( String name, Class clazz )
+        {
+            this.setterName = name;
+            this.paramClass = clazz;
+        }
+
+        public void invoke( Object target, Object value )
+            throws Exception
+        {
+            Method setter = target.getClass().getMethod( this.setterName, new Class[]{this.paramClass} );
+            if ( setter != null )
+            {
+                setter.invoke( target, new Object[]{convertValue( value )} );
+            }
+        }
+
+        protected Object convertValue( Object value )
+        {
+            if ( value == null )
+            {
+                return value;
+            }
+            if ( this.paramClass.isAssignableFrom( value.getClass() ) )
+            {
+                return value;
+            }
+
+            if ( Boolean.class.equals( this.paramClass ) || boolean.class.equals( this.paramClass ) )
+            {
+                return Boolean.valueOf( value.toString() );
+            }
+            if ( Integer.class.equals( this.paramClass ) || int.class.equals( this.paramClass ) )
+            {
+                return new Integer( value.toString() );
+            }
+
+            return value;
+        }
+    }
+}

Propchange: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java?view=auto&rev=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java (added)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java Wed May 23 22:21:47 2007
@@ -0,0 +1,29 @@
+package org.apache.maven.surefire.testng.conf;
+
+/*
+ * 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.testng.TestNG;
+
+import java.util.Map;
+
+public interface Configurator
+{
+    void configure( TestNG testng, Map options );
+}
\ No newline at end of file

Propchange: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/Configurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java?view=auto&rev=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java (added)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java Wed May 23 22:21:47 2007
@@ -0,0 +1,42 @@
+package org.apache.maven.surefire.testng.conf;
+
+/*
+ * 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.
+ */
+
+/**
+ * TestNG 4.7 and 5.1 configurator.
+ * <p/>
+ * Allowed options:
+ * -groups
+ * -excludedgroups
+ * -junit (boolean)
+ * -threadcount (int)
+ * -parallel (boolean)
+ * <p/>
+ * Not supported yet:
+ * -setListenerClasses(List<Class>) or setListeners(List<Object>)
+ */
+public class TestNG4751Configurator
+    extends AbstractDirectConfigurator
+{
+    public TestNG4751Configurator()
+    {
+        setters.put( "parallel", new Setter( "setParallel", boolean.class ) );
+    }
+}
\ No newline at end of file

Propchange: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG4751Configurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java?view=auto&rev=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java (added)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java Wed May 23 22:21:47 2007
@@ -0,0 +1,42 @@
+package org.apache.maven.surefire.testng.conf;
+
+/*
+ * 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.
+ */
+
+/**
+ * TestNG 5.2 configurator.
+ * <p/>
+ * Allowed options:
+ * -groups
+ * -excludedgroups
+ * -junit (boolean)
+ * -threadcount (int)
+ * -parallel (String)
+ * <p/>
+ * Not supported yet:
+ * -setListenerClasses(List<Class>) or setListeners(List<Object>)
+ */
+public class TestNG52Configurator
+    extends AbstractDirectConfigurator
+{
+    public TestNG52Configurator()
+    {
+        setters.put( "parallel", new Setter( "setParallel", String.class ) );
+    }
+}
\ No newline at end of file

Propchange: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNG52Configurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java?view=auto&rev=541168
==============================================================================
--- maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java (added)
+++ maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java Wed May 23 22:21:47 2007
@@ -0,0 +1,86 @@
+package org.apache.maven.surefire.testng.conf;
+
+/*
+ * 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.testng.TestNG;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * TestNG configurator for 5.3+ versions. TestNG exposes
+ * a {@link org.testng.TestNG#configure(java.util.Map)} method.
+ * All suppported TestNG options are passed in String format, except
+ * <code>TestNGCommandLineArgs.LISTENER_COMMAND_OPT</code> which is <code>List<Class></code>
+ * and <code>TestNGCommandLineArgs.JUNIT_DEF_OPT</code> which is a <code>Boolean</code>.
+ * <p/>
+ * Test classes and/or suite files are not passed along as options parameters, but
+ * configured separately.
+ */
+public class TestNGMapConfigurator
+    implements Configurator
+{
+    public void configure( TestNG testng, Map options )
+    {
+        Map convertedOptions = new HashMap();
+        for ( Iterator it = options.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) it.next();
+            String key = (String) entry.getKey();
+            Object val = entry.getValue();
+            if ( "junit".equals( key ) )
+            {
+                val = convert( val, Boolean.class );
+            }
+            else if ( "threadcount".equals( key ) )
+            {
+                val = convert( val, String.class );
+            }
+            convertedOptions.put( "-" + key, val );
+        }
+
+        testng.configure( convertedOptions );
+    }
+
+    protected Object convert( Object val, Class type )
+    {
+        if ( val == null )
+        {
+            return null;
+        }
+        if ( type.isAssignableFrom( val.getClass() ) )
+        {
+            return val;
+        }
+
+        if ( ( Boolean.class.equals( type ) || boolean.class.equals( type ) ) && String.class.equals( val.getClass() ) )
+        {
+            return Boolean.valueOf( (String) val );
+        }
+
+        if ( String.class.equals( type ) )
+        {
+            return val.toString();
+        }
+
+        return val;
+    }
+}
\ No newline at end of file

Propchange: maven/surefire/trunk/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/TestNGMapConfigurator.java
------------------------------------------------------------------------------
    svn:eol-style = native