All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.surefire.booter.SurefireReflector Maven / Gradle / Ivy

Go to download

API used in Surefire and Failsafe MOJO, Booter, Common and test framework providers.

There is a newer version: 3.5.2
Show newest version
package org.apache.maven.surefire.booter;

/*
 * 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.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.plugin.surefire.log.api.ConsoleLoggerDecorator;
import org.apache.maven.surefire.cli.CommandLineOption;
import org.apache.maven.surefire.providerapi.ProviderParameters;
import org.apache.maven.surefire.report.ReporterConfiguration;
import org.apache.maven.surefire.report.ReporterFactory;
import org.apache.maven.surefire.suite.RunResult;
import org.apache.maven.surefire.testset.DirectoryScannerParameters;
import org.apache.maven.surefire.testset.RunOrderParameters;
import org.apache.maven.surefire.testset.TestArtifactInfo;
import org.apache.maven.surefire.testset.TestListResolver;
import org.apache.maven.surefire.testset.TestRequest;
import org.apache.maven.surefire.util.RunOrder;
import org.apache.maven.surefire.util.SurefireReflectionException;

import javax.annotation.Nonnull;

import static java.util.Collections.checkedList;

import static org.apache.maven.surefire.util.ReflectionUtils.getConstructor;
import static org.apache.maven.surefire.util.ReflectionUtils.getMethod;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeGetter;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray;
import static org.apache.maven.surefire.util.ReflectionUtils.instantiateOneArg;
import static org.apache.maven.surefire.util.ReflectionUtils.invokeSetter;
import static org.apache.maven.surefire.util.ReflectionUtils.instantiateTwoArgs;
import static org.apache.maven.surefire.util.ReflectionUtils.newInstance;

/**
 * Does reflection based invocation of the surefire methods.
 * 

* This is to avoid complications with linkage issues * * @author Kristian Rosenvold */ public class SurefireReflector { private final ClassLoader surefireClassLoader; private final Class reporterConfiguration; private final Class testRequest; private final Class testArtifactInfo; private final Class testArtifactInfoAware; private final Class directoryScannerParameters; private final Class runOrderParameters; private final Class directoryScannerParametersAware; private final Class testSuiteDefinitionAware; private final Class testClassLoaderAware; private final Class reporterConfigurationAware; private final Class providerPropertiesAware; private final Class runResult; private final Class booterParameters; private final Class reporterFactory; private final Class testListResolver; private final Class mainCliOptions; private final Class commandLineOptionsClass; private final Class shutdownAwareClass; private final Class shutdownClass; @SuppressWarnings( "unchecked" ) public SurefireReflector( ClassLoader surefireClassLoader ) { this.surefireClassLoader = surefireClassLoader; try { reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() ); testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() ); testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() ); testArtifactInfoAware = surefireClassLoader.loadClass( TestArtifactInfoAware.class.getName() ); directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() ); runOrderParameters = surefireClassLoader.loadClass( RunOrderParameters.class.getName() ); directoryScannerParametersAware = surefireClassLoader.loadClass( DirectoryScannerParametersAware.class.getName() ); testSuiteDefinitionAware = surefireClassLoader.loadClass( TestRequestAware.class.getName() ); testClassLoaderAware = surefireClassLoader.loadClass( SurefireClassLoadersAware.class.getName() ); reporterConfigurationAware = surefireClassLoader.loadClass( ReporterConfigurationAware.class.getName() ); providerPropertiesAware = surefireClassLoader.loadClass( ProviderPropertiesAware.class.getName() ); reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() ); runResult = surefireClassLoader.loadClass( RunResult.class.getName() ); booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() ); testListResolver = surefireClassLoader.loadClass( TestListResolver.class.getName() ); mainCliOptions = surefireClassLoader.loadClass( MainCliOptionsAware.class.getName() ); commandLineOptionsClass = (Class) surefireClassLoader.loadClass( CommandLineOption.class.getName() ); shutdownAwareClass = surefireClassLoader.loadClass( ShutdownAware.class.getName() ); shutdownClass = (Class) surefireClassLoader.loadClass( Shutdown.class.getName() ); } catch ( ClassNotFoundException e ) { throw new SurefireReflectionException( e ); } } public Object convertIfRunResult( Object result ) { if ( result == null || !isRunResult( result ) ) { return result; } int getCompletedCount1 = (Integer) invokeGetter( result, "getCompletedCount" ); int getErrors = (Integer) invokeGetter( result, "getErrors" ); int getSkipped = (Integer) invokeGetter( result, "getSkipped" ); int getFailures = (Integer) invokeGetter( result, "getFailures" ); return new RunResult( getCompletedCount1, getErrors, getFailures, getSkipped ); } /** * @noinspection UnusedDeclaration */ class ClassLoaderProxy implements InvocationHandler { private final Object target; /** * @param delegate a target * @noinspection UnusedDeclaration */ public ClassLoaderProxy( Object delegate ) { this.target = delegate; } public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { Method delegateMethod = target.getClass().getMethod( method.getName(), method.getParameterTypes() ); return delegateMethod.invoke( target, args ); } } Object createTestRequest( TestRequest suiteDefinition ) { if ( suiteDefinition == null ) { return null; } else { Object resolver = createTestListResolver( suiteDefinition.getTestListResolver() ); Class[] arguments = { List.class, File.class, testListResolver, int.class }; Constructor constructor = getConstructor( testRequest, arguments ); return newInstance( constructor, suiteDefinition.getSuiteXmlFiles(), suiteDefinition.getTestSourceDirectory(), resolver, suiteDefinition.getRerunFailingTestsCount() ); } } Object createTestListResolver( TestListResolver resolver ) { if ( resolver == null ) { return null; } else { Constructor constructor = getConstructor( testListResolver, String.class ); return newInstance( constructor, resolver.getPluginParameterTest() ); } } Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters ) { if ( directoryScannerParameters == null ) { return null; } //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail. Class[] arguments = { File.class, List.class, List.class, List.class, boolean.class, String.class }; Constructor constructor = getConstructor( this.directoryScannerParameters, arguments ); return newInstance( constructor, directoryScannerParameters.getTestClassesDirectory(), directoryScannerParameters.getIncludes(), directoryScannerParameters.getExcludes(), directoryScannerParameters.getSpecificTests(), directoryScannerParameters.isFailIfNoTests(), RunOrder.asString( directoryScannerParameters.getRunOrder() ) ); } Object createRunOrderParameters( RunOrderParameters runOrderParameters ) { if ( runOrderParameters == null ) { return null; } //Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail. Class[] arguments = { String.class, File.class }; Constructor constructor = getConstructor( this.runOrderParameters, arguments ); File runStatisticsFile = runOrderParameters.getRunStatisticsFile(); return newInstance( constructor, RunOrder.asString( runOrderParameters.getRunOrder() ), runStatisticsFile ); } Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo ) { if ( testArtifactInfo == null ) { return null; } Class[] arguments = { String.class, String.class }; Constructor constructor = getConstructor( this.testArtifactInfo, arguments ); return newInstance( constructor, testArtifactInfo.getVersion(), testArtifactInfo.getClassifier() ); } Object createReporterConfiguration( ReporterConfiguration reporterConfig ) { Constructor constructor = getConstructor( reporterConfiguration, File.class, boolean.class ); return newInstance( constructor, reporterConfig.getReportsDirectory(), reporterConfig.isTrimStackTrace() ); } public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance, boolean insideFork ) { return instantiateTwoArgs( surefireClassLoader, BaseProviderFactory.class.getName(), reporterFactory, factoryInstance, boolean.class, insideFork ); } public Object instantiateProvider( String providerClassName, Object booterParameters ) { return instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters, booterParameters ); } public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams ) { if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) ) { setDirectoryScannerParameters( o, dirScannerParams ); } } public void setMainCliOptions( Object o, List options ) { if ( mainCliOptions.isAssignableFrom( o.getClass() ) ) { List newOptions = checkedList( new ArrayList( options.size() ), commandLineOptionsClass ); Collection ordinals = toOrdinals( options ); for ( Enum e : commandLineOptionsClass.getEnumConstants() ) { if ( ordinals.contains( e.ordinal() ) ) { newOptions.add( e ); } } invokeSetter( o, "setMainCliOptions", List.class, newOptions ); } } public void setSkipAfterFailureCount( Object o, int skipAfterFailureCount ) { invokeSetter( o, "setSkipAfterFailureCount", int.class, skipAfterFailureCount ); } public void setShutdown( Object o, Shutdown shutdown ) { if ( shutdownAwareClass.isAssignableFrom( o.getClass() ) ) { for ( Enum e : shutdownClass.getEnumConstants() ) { if ( shutdown.ordinal() == e.ordinal() ) { invokeSetter( o, "setShutdown", shutdownClass, e ); break; } } } } public void setSystemExitTimeout( Object o, Integer systemExitTimeout ) { invokeSetter( o, "setSystemExitTimeout", Integer.class, systemExitTimeout ); } public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams ) { Object param = createDirectoryScannerParameters( dirScannerParams ); invokeSetter( o, "setDirectoryScannerParameters", directoryScannerParameters, param ); } public void setRunOrderParameters( Object o, RunOrderParameters runOrderParameters ) { Object param = createRunOrderParameters( runOrderParameters ); invokeSetter( o, "setRunOrderParameters", this.runOrderParameters, param ); } public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 ) { if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) ) { setTestSuiteDefinition( o, testSuiteDefinition2 ); } } void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 ) { Object param = createTestRequest( testSuiteDefinition1 ); invokeSetter( o, "setTestRequest", testRequest, param ); } public void setProviderPropertiesAware( Object o, Map properties ) { if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) ) { setProviderProperties( o, properties ); } } void setProviderProperties( Object o, Map providerProperties ) { invokeSetter( o, "setProviderProperties", Map.class, providerProperties ); } public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 ) { if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) ) { setReporterConfiguration( o, reporterConfiguration1 ); } } void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration ) { Object param = createReporterConfiguration( reporterConfiguration ); invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param ); } public void setTestClassLoaderAware( Object o, ClassLoader testClassLoader ) { if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) ) { setTestClassLoader( o, testClassLoader ); } } void setTestClassLoader( Object o, ClassLoader testClassLoader ) { Method setter = getMethod( o, "setClassLoaders", ClassLoader.class ); invokeMethodWithArray( o, setter, testClassLoader ); } public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 ) { if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) ) { setTestArtifactInfo( o, testArtifactInfo1 ); } } void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo ) { Object param = createTestArtifactInfo( testArtifactInfo ); invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param ); } private boolean isRunResult( Object o ) { return runResult.isAssignableFrom( o.getClass() ); } public Object createConsoleLogger( @Nonnull ConsoleLogger consoleLogger ) { return createConsoleLogger( consoleLogger, surefireClassLoader ); } private static Collection toOrdinals( Collection enums ) { Collection ordinals = new ArrayList( enums.size() ); for ( Enum e : enums ) { ordinals.add( e.ordinal() ); } return ordinals; } public static Object createConsoleLogger( ConsoleLogger consoleLogger, ClassLoader cl ) { try { Class decoratorClass = cl.loadClass( ConsoleLoggerDecorator.class.getName() ); return getConstructor( decoratorClass, Object.class ).newInstance( consoleLogger ); } catch ( Exception e ) { throw new SurefireReflectionException( e ); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy