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

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

/*
 * 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.
 */
package org.apache.maven.surefire.booter;

import java.io.File;
import java.lang.reflect.Constructor;
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.surefire.api.booter.BaseProviderFactory;
import org.apache.maven.surefire.api.cli.CommandLineOption;
import org.apache.maven.surefire.api.provider.ProviderParameters;
import org.apache.maven.surefire.api.report.ReporterConfiguration;
import org.apache.maven.surefire.api.report.ReporterFactory;
import org.apache.maven.surefire.api.suite.RunResult;
import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
import org.apache.maven.surefire.api.testset.RunOrderParameters;
import org.apache.maven.surefire.api.testset.TestArtifactInfo;
import org.apache.maven.surefire.api.testset.TestListResolver;
import org.apache.maven.surefire.api.testset.TestRequest;
import org.apache.maven.surefire.api.util.RunOrder;
import org.apache.maven.surefire.api.util.SurefireReflectionException;

import static java.util.Collections.checkedList;
import static org.apache.maven.surefire.api.util.ReflectionUtils.getConstructor;
import static org.apache.maven.surefire.api.util.ReflectionUtils.getMethod;
import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiateOneArg;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeGetter;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray;
import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeSetter;
import static org.apache.maven.surefire.api.util.ReflectionUtils.newInstance;

/**
 * Does reflection based invocation of the surefire methods.
 * 
* This is to avoid complications with linkage issues * * @author Kristian Rosenvold */ public final class SurefireReflector { private final ClassLoader surefireClassLoader; private final Class reporterConfiguration; private final Class testRequest; private final Class testArtifactInfo; private final Class directoryScannerParameters; private final Class runOrderParameters; private final Class baseProviderFactory; private final Class runResult; private final Class booterParameters; private final Class reporterFactory; private final Class testListResolver; private final Class> commandLineOptionsClass; @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()); directoryScannerParameters = surefireClassLoader.loadClass(DirectoryScannerParameters.class.getName()); runOrderParameters = surefireClassLoader.loadClass(RunOrderParameters.class.getName()); baseProviderFactory = surefireClassLoader.loadClass(BaseProviderFactory.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()); commandLineOptionsClass = (Class>) surefireClassLoader.loadClass(CommandLineOption.class.getName()); } catch (ClassNotFoundException e) { throw new SurefireReflectionException(e); } } public Object convertIfRunResult(Object result) { if (result == null || !isRunResult(result)) { return result; } int getCompletedCount1 = invokeGetter(result, "getCompletedCount"); int getErrors = invokeGetter(result, "getErrors"); int getSkipped = invokeGetter(result, "getSkipped"); int getFailures = invokeGetter(result, "getFailures"); return new RunResult(getCompletedCount1, getErrors, getFailures, getSkipped); } private 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()); } } private Object createTestListResolver(TestListResolver resolver) { if (resolver == null) { return null; } else { Constructor constructor = getConstructor(testListResolver, String.class); return newInstance(constructor, resolver.getPluginParameterTest()); } } private 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, String.class}; Constructor constructor = getConstructor(this.directoryScannerParameters, arguments); return newInstance( constructor, directoryScannerParameters.getTestClassesDirectory(), directoryScannerParameters.getIncludes(), directoryScannerParameters.getExcludes(), directoryScannerParameters.getSpecificTests(), RunOrder.asString(directoryScannerParameters.getRunOrder())); } private 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, Long.class}; Constructor constructor = getConstructor(this.runOrderParameters, arguments); File runStatisticsFile = runOrderParameters.getRunStatisticsFile(); return newInstance( constructor, RunOrder.asString(runOrderParameters.getRunOrder()), runStatisticsFile, runOrderParameters.getRunOrderRandomSeed()); } private 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()); } private Object createReporterConfiguration(ReporterConfiguration reporterConfig) { Constructor constructor = getConstructor(reporterConfiguration, File.class, boolean.class); return newInstance(constructor, reporterConfig.getReportsDirectory(), reporterConfig.isTrimStackTrace()); } public Object createBooterConfiguration(ClassLoader surefireClassLoader, boolean insideFork) { return instantiateOneArg(surefireClassLoader, BaseProviderFactory.class.getName(), 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 (baseProviderFactory.isAssignableFrom(o.getClass())) { setDirectoryScannerParameters(o, dirScannerParams); } } public void setMainCliOptions(Object o, List options) { if (baseProviderFactory.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 setSystemExitTimeout(Object o, Integer systemExitTimeout) { invokeSetter(o, "setSystemExitTimeout", Integer.class, systemExitTimeout); } 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 (baseProviderFactory.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 (baseProviderFactory.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 (baseProviderFactory.isAssignableFrom(o.getClass())) { setReporterConfiguration(o, reporterConfiguration1); } } private void setReporterConfiguration(Object o, ReporterConfiguration reporterConfiguration) { Object param = createReporterConfiguration(reporterConfiguration); invokeSetter(o, "setReporterConfiguration", this.reporterConfiguration, param); } public void setTestClassLoaderAware(Object o, ClassLoader testClassLoader) { if (baseProviderFactory.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 (baseProviderFactory.isAssignableFrom(o.getClass())) { setTestArtifactInfo(o, testArtifactInfo1); } } void setTestArtifactInfo(Object o, TestArtifactInfo testArtifactInfo) { Object param = createTestArtifactInfo(testArtifactInfo); invokeSetter(o, "setTestArtifactInfo", this.testArtifactInfo, param); } public void setReporterFactoryAware(Object o, Object reporterFactory) { if (baseProviderFactory.isAssignableFrom(o.getClass())) { setReporterFactory(o, reporterFactory); } } void setReporterFactory(Object o, Object reporterFactory) { invokeSetter(o, "setReporterFactory", this.reporterFactory, reporterFactory); } private boolean isRunResult(Object o) { return runResult.isAssignableFrom(o.getClass()); } private static Collection toOrdinals(Collection> enums) { Collection ordinals = new ArrayList<>(enums.size()); for (Enum e : enums) { ordinals.add(e.ordinal()); } return ordinals; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy