View Javadoc

1   package org.apache.maven.surefire.testng.conf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import org.apache.maven.surefire.booter.ProviderParameterNames;
29  import org.apache.maven.surefire.testset.TestSetFailedException;
30  import org.testng.TestNG;
31  import org.testng.xml.XmlSuite;
32  
33  /**
34   * TestNG configurator for 5.3+ versions. TestNG exposes a {@link org.testng.TestNG#configure(java.util.Map)} method.
35   * All suppported TestNG options are passed in String format, except
36   * <code>TestNGCommandLineArgs.LISTENER_COMMAND_OPT</code> which is <code>List&gt;Class&lt;</code>,
37   * <code>TestNGCommandLineArgs.JUNIT_DEF_OPT</code> which is a <code>Boolean</code>,
38   * <code>TestNGCommandLineArgs.SKIP_FAILED_INVOCATION_COUNT_OPT</code> which is a <code>Boolean</code>,
39   * <code>TestNGCommandLineArgs.OBJECT_FACTORY_COMMAND_OPT</code> which is a <code>Class</code>,
40   * <code>TestNGCommandLineArgs.REPORTERS_LIST</code> which is a <code>List&gt;ReporterConfig&lt;</code>.
41   * <p/>
42   * Test classes and/or suite files are not passed along as options parameters, but configured separately.
43   *
44   * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
45   */
46  public class TestNGMapConfigurator
47      implements Configurator
48  {
49      public void configure( TestNG testng, Map options )
50          throws TestSetFailedException
51      {
52          Map convertedOptions = getConvertedOptions( options );
53          testng.configure( convertedOptions );
54      }
55  
56      public void configure( XmlSuite suite, Map options )
57          throws TestSetFailedException
58      {
59          String threadCountString = (String) options.get( ProviderParameterNames.THREADCOUNT_PROP );
60          int threadCount = ( null != threadCountString ) ? Integer.parseInt( threadCountString ) : 1;
61          suite.setThreadCount( threadCount );
62  
63          String parallel = (String) options.get( ProviderParameterNames.PARALLEL_PROP );
64          if ( parallel != null ) {
65              suite.setParallel( parallel );
66          }
67      }
68  
69      Map getConvertedOptions( Map options )
70          throws TestSetFailedException
71      {
72          Map convertedOptions = new HashMap();
73          convertedOptions.put( "-mixed", Boolean.FALSE );
74          for ( Iterator it = options.entrySet().iterator(); it.hasNext(); )
75          {
76              Map.Entry entry = (Map.Entry) it.next();
77              String key = (String) entry.getKey();
78              Object val = entry.getValue();
79              if ( "listener".equals( key ) )
80              {
81                  val = AbstractDirectConfigurator.loadListenerClasses( (String) val );
82              }
83              if ( "objectfactory".equals( key ) )
84              {
85                  val = AbstractDirectConfigurator.loadClass( (String) val );
86              }
87              if ( "reporter".equals( key ) )
88              {
89                  // TODO support multiple reporters?
90                  val = convertReporterConfig( val );
91                  key = "reporterslist";
92  
93              }
94              if ( "junit".equals( key ) )
95              {
96                  val = convert( val, Boolean.class );
97              }
98              else if ( "skipfailedinvocationcounts".equals( key ) )
99              {
100                 val = convert( val, Boolean.class );
101             }
102             else if ( "mixed".equals( key ) )
103             {
104                 val = convert( val, Boolean.class );
105             }
106             else if ( "configfailurepolicy".equals( key ) )
107             {
108                 val = convert( val, String.class );
109             }
110             else if ( "group-by-instances".equals( key ) )
111             {
112                 val = convert( val, Boolean.class );
113             }
114             else if ( ProviderParameterNames.THREADCOUNT_PROP.equals( key ) )
115             {
116                 val = convert( val, String.class );
117             }
118             // TODO objectfactory... not even documented, does it work?
119             if ( key.startsWith( "-" ) )
120             {
121                 convertedOptions.put( key, val );
122             }
123             else
124             {
125                 convertedOptions.put( "-" + key, val );
126             }
127         }
128         return convertedOptions;
129     }
130 
131     // ReporterConfig only became available in later versions of TestNG
132     private Object convertReporterConfig( Object val )
133     {
134         final String reporterConfigClassName = "org.testng.ReporterConfig";
135         try
136         {
137             Class reporterConfig = Class.forName( reporterConfigClassName );
138             Method deserialize = reporterConfig.getMethod( "deserialize", new Class[]{ String.class } );
139             Object rc = deserialize.invoke( null, new Object[]{ val } );
140             ArrayList reportersList = new ArrayList();
141             reportersList.add( rc );
142             return reportersList;
143         }
144         catch ( Exception e )
145         {
146             return val;
147         }
148     }
149 
150     protected Object convert( Object val, Class type )
151     {
152         if ( val == null )
153         {
154             return null;
155         }
156         if ( type.isAssignableFrom( val.getClass() ) )
157         {
158             return val;
159         }
160 
161         if ( ( Boolean.class.equals( type ) || boolean.class.equals( type ) ) && String.class.equals( val.getClass() ) )
162         {
163             return Boolean.valueOf( (String) val );
164         }
165 
166         if ( String.class.equals( type ) )
167         {
168             return val.toString();
169         }
170 
171         return val;
172     }
173 }