blob: ed918f538cfefbcd55c739bbefaaaaa57a27b1e4 [file] [log] [blame]
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 java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.surefire.api.booter.ProviderParameterNames;
import org.apache.maven.surefire.api.testset.TestSetFailedException;
import org.testng.TestNG;
import org.testng.xml.XmlSuite;
/**
* Configurator that relies on reflection to set parameters in TestNG
*
*/
public abstract class AbstractDirectConfigurator
implements Configurator
{
final Map<String, Setter> setters;
AbstractDirectConfigurator()
{
Map<String, Setter> options = new HashMap<>();
// options.put( ProviderParameterNames.TESTNG_GROUPS_PROP, new Setter( "setGroups", String.class ) );
// options.put( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP, new Setter( "setExcludedGroups", String.class
// ) );
options.put( "junit", new Setter( "setJUnit", Boolean.class ) );
options.put( ProviderParameterNames.THREADCOUNT_PROP, new Setter( "setThreadCount", int.class ) );
options.put( "usedefaultlisteners", new Setter( "setUseDefaultListeners", boolean.class ) );
this.setters = options;
}
@Override
public void configure( TestNG testng, Map<String, String> options )
throws TestSetFailedException
{
System.out.println( "\n\n\n\nCONFIGURING TESTNG\n\n\n\n" );
// kind of ugly, but listeners are configured differently
final String listeners = options.remove( "listener" );
// DGF In 4.7, default listeners dump XML files in the surefire-reports directory,
// confusing the report plugin. This was fixed in later versions.
testng.setUseDefaultListeners( false );
configureInstance( testng, options );
// TODO: we should have the Profile so that we can decide if this is needed or not
testng.setListenerClasses( loadListenerClasses( listeners ) );
}
@Override
public void configure( XmlSuite suite, Map<String, String> options )
throws TestSetFailedException
{
Map<String, String> filtered = filterForSuite( options );
configureInstance( suite, filtered );
}
protected Map<String, String> filterForSuite( Map<String, String> options )
{
Map<String, String> result = new HashMap<>();
addPropIfNotNull( options, result, ProviderParameterNames.PARALLEL_PROP );
addPropIfNotNull( options, result, ProviderParameterNames.THREADCOUNT_PROP );
return result;
}
private void addPropIfNotNull( Map<String, String> options, Map<String, String> result, String prop )
{
if ( options.containsKey( prop ) )
{
result.put( prop, options.get( prop ) );
}
}
private void configureInstance( Object testngInstance, Map<String, String> options )
{
for ( Map.Entry<String, String> entry : options.entrySet() )
{
String key = entry.getKey();
String val = entry.getValue();
Setter setter = setters.get( key );
if ( setter != null )
{
try
{
setter.invoke( testngInstance, val );
}
catch ( Exception e )
{
throw new RuntimeException( "Cannot set option " + key + " with value " + val, e );
}
}
}
}
static List<Class> loadListenerClasses( String listenerClasses )
throws TestSetFailedException
{
if ( listenerClasses == null || listenerClasses.trim().isEmpty() )
{
return new ArrayList<>();
}
List<Class> classes = new ArrayList<>();
String[] classNames = listenerClasses.split( "\\s*,\\s*(\\r?\\n)?\\s*" );
for ( String className : classNames )
{
Class<?> clazz = loadClass( className );
classes.add( clazz );
}
return classes;
}
static Class<?> loadClass( String className )
throws TestSetFailedException
{
try
{
return Class.forName( className );
}
catch ( Exception ex )
{
throw new TestSetFailedException( "Cannot find listener class " + className, ex );
}
}
/**
* Describes a property setter by method name and parameter class
*
*/
public static final class Setter
{
private final String setterName;
private final Class<?> paramClass;
public Setter( String name, Class<?> clazz )
{
setterName = name;
paramClass = clazz;
}
public void invoke( Object target, String value )
throws Exception
{
Method setter = target.getClass().getMethod( setterName, paramClass );
if ( setter != null )
{
setter.invoke( target, convertValue( value ) );
}
}
private Object convertValue( String value )
{
if ( value == null )
{
return null;
}
if ( paramClass.isAssignableFrom( value.getClass() ) )
{
return value;
}
if ( Boolean.class.equals( paramClass ) || boolean.class.equals( paramClass ) )
{
return Boolean.valueOf( value );
}
if ( Integer.class.equals( paramClass ) || int.class.equals( paramClass ) )
{
return Integer.valueOf( value );
}
return value;
}
}
}