1
package org.apache.maven.surefire.booter;
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
12
* http://www.apache.org/licenses/LICENSE-2.0
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
23
import java.io.PrintStream;
24
import java.lang.reflect.Constructor;
25
import java.lang.reflect.InvocationHandler;
26
import java.lang.reflect.Method;
27
import java.util.List;
28
import java.util.Properties;
30
import org.apache.maven.plugin.surefire.report.FileReporterFactory;
31
import org.apache.maven.surefire.providerapi.ProviderParameters;
32
import org.apache.maven.surefire.report.ReporterConfiguration;
33
import org.apache.maven.surefire.report.ReporterFactory;
34
import org.apache.maven.surefire.suite.RunResult;
35
import org.apache.maven.surefire.testset.DirectoryScannerParameters;
36
import org.apache.maven.surefire.testset.TestArtifactInfo;
37
import org.apache.maven.surefire.testset.TestRequest;
38
import org.apache.maven.surefire.util.ReflectionUtils;
39
import org.apache.maven.surefire.util.RunOrder;
40
import org.apache.maven.surefire.util.SurefireReflectionException;
43
* Does reflection based invocation of the surefire methods.
45
* This is to avoid compilications with linkage issues
47
* @author Kristian Rosenvold
49
public class SurefireReflector
51
private final ClassLoader surefireClassLoader;
53
private final Class reporterConfiguration;
55
private final Class testRequest;
57
private final Class testArtifactInfo;
59
private final Class testArtifactInfoAware;
61
private final Class directoryScannerParameters;
63
private final Class directoryScannerParametersAware;
65
private final Class testSuiteDefinitionAware;
67
private final Class testClassLoaderAware;
69
private final Class reporterConfigurationAware;
71
private final Class providerPropertiesAware;
73
private final Class runResult;
75
private final Class booterParameters;
77
private final Class reporterFactory;
79
private final Class startupReportConfiguration;
81
public SurefireReflector( ClassLoader surefireClassLoader )
83
this.surefireClassLoader = surefireClassLoader;
86
reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() );
87
startupReportConfiguration = surefireClassLoader.loadClass( StartupReportConfiguration.class.getName() );
88
testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() );
89
testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() );
90
testArtifactInfoAware = surefireClassLoader.loadClass( TestArtifactInfoAware.class.getName() );
91
directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() );
92
directoryScannerParametersAware =
93
surefireClassLoader.loadClass( DirectoryScannerParametersAware.class.getName() );
94
testSuiteDefinitionAware = surefireClassLoader.loadClass( TestRequestAware.class.getName() );
95
testClassLoaderAware = surefireClassLoader.loadClass( SurefireClassLoadersAware.class.getName() );
96
reporterConfigurationAware = surefireClassLoader.loadClass( ReporterConfigurationAware.class.getName() );
97
providerPropertiesAware = surefireClassLoader.loadClass( ProviderPropertiesAware.class.getName() );
98
reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() );
99
runResult = surefireClassLoader.loadClass( RunResult.class.getName() );
100
booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() );
102
catch ( ClassNotFoundException e )
104
throw new SurefireReflectionException( e );
108
public Object convertIfRunResult( Object result )
110
if ( result == null || !isRunResult( result ) )
114
final Integer getCompletedCount1 = (Integer) ReflectionUtils.invokeGetter( result, "getCompletedCount" );
115
final Integer getErrors = (Integer) ReflectionUtils.invokeGetter( result, "getErrors" );
116
final Integer getSkipped = (Integer) ReflectionUtils.invokeGetter( result, "getSkipped" );
117
final Integer getFailures = (Integer) ReflectionUtils.invokeGetter( result, "getFailures" );
118
return new RunResult( getCompletedCount1.intValue(), getErrors.intValue(), getFailures.intValue(),
119
getSkipped.intValue() );
125
* @noinspection UnusedDeclaration
127
class ClassLoaderProxy
128
implements InvocationHandler
130
private final Object target;
133
* @param delegate a target
134
* @noinspection UnusedDeclaration
136
public ClassLoaderProxy( Object delegate )
138
this.target = delegate;
141
public Object invoke( Object proxy, Method method, Object[] args )
144
Method delegateMethod = target.getClass().getMethod( method.getName(), method.getParameterTypes() );
145
return delegateMethod.invoke( target, args );
150
Object createTestRequest( TestRequest suiteDefinition )
152
if ( suiteDefinition == null )
156
Class[] arguments = { List.class, File.class, String.class, String.class };
157
Constructor constructor = ReflectionUtils.getConstructor( this.testRequest, arguments );
158
return ReflectionUtils.newInstance( constructor, new Object[]{ suiteDefinition.getSuiteXmlFiles(),
159
suiteDefinition.getTestSourceDirectory(), suiteDefinition.getRequestedTest(),
160
suiteDefinition.getRequestedTestMethod() } );
164
Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
166
if ( directoryScannerParameters == null )
170
//Can't use the constructor with the RunOrder parameter. Using it causes some integration tests to fail.
171
Class[] arguments = { File.class, List.class, List.class, Boolean.class, String.class };
172
Constructor constructor = ReflectionUtils.getConstructor( this.directoryScannerParameters, arguments );
173
return ReflectionUtils.newInstance( constructor,
174
new Object[]{ directoryScannerParameters.getTestClassesDirectory(),
175
directoryScannerParameters.getIncludes(),
176
directoryScannerParameters.getExcludes(),
177
directoryScannerParameters.isFailIfNoTests(),
178
directoryScannerParameters.getRunOrder().name() } );
181
Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo )
183
if ( testArtifactInfo == null )
187
Class[] arguments = { String.class, String.class };
188
Constructor constructor = ReflectionUtils.getConstructor( this.testArtifactInfo, arguments );
189
return ReflectionUtils.newInstance( constructor, new Object[]{ testArtifactInfo.getVersion(),
190
testArtifactInfo.getClassifier() } );
194
Object createReporterConfiguration( ReporterConfiguration reporterConfiguration )
196
Constructor constructor = ReflectionUtils.getConstructor( this.reporterConfiguration,
197
new Class[]{ File.class, Boolean.class } );
198
return ReflectionUtils.newInstance( constructor, new Object[]{ reporterConfiguration.getReportsDirectory(),
199
reporterConfiguration.isTrimStackTrace()} );
202
Object createStartupReportConfiguration( StartupReportConfiguration reporterConfiguration )
204
Constructor constructor = ReflectionUtils.getConstructor( this.startupReportConfiguration,
205
new Class[]{ boolean.class, boolean.class,
206
String.class, boolean.class, boolean.class,
207
File.class, boolean.class, String.class } );
208
//noinspection BooleanConstructorCall
209
final Object[] params =
210
{ new Boolean( reporterConfiguration.isUseFile() ), new Boolean( reporterConfiguration.isPrintSummary() ),
211
reporterConfiguration.getReportFormat(),
212
new Boolean( reporterConfiguration.isRedirectTestOutputToFile() ),
213
new Boolean( reporterConfiguration.isDisableXmlReport() ),
214
reporterConfiguration.getReportsDirectory(),
215
new Boolean( reporterConfiguration.isTrimStackTrace()),
216
reporterConfiguration.getReportNameSuffix()};
217
return ReflectionUtils.newInstance( constructor, params );
220
public Object createForkingReporterFactory( Boolean trimStackTrace, PrintStream originalSystemOut )
222
Class[] args = new Class[]{ Boolean.class, PrintStream.class };
223
Object[] values = new Object[]{ trimStackTrace, originalSystemOut };
224
return ReflectionUtils.instantiateObject( ForkingReporterFactory.class.getName(), args, values,
225
surefireClassLoader );
228
public Object createReportingReporterFactory( StartupReportConfiguration startupReportConfiguration )
231
new Class[]{ this.startupReportConfiguration };
232
Object src = createStartupReportConfiguration( startupReportConfiguration );
233
Object[] params = new Object[]{ src };
234
return ReflectionUtils.instantiateObject( FileReporterFactory.class.getName(), args, params,
235
surefireClassLoader );
239
public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance )
241
return ReflectionUtils.instantiateOneArg( surefireClassLoader, BaseProviderFactory.class.getName(),
242
reporterFactory, factoryInstance );
245
public Object instantiateProvider( String providerClassName, Object booterParameters )
247
return ReflectionUtils.instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters,
251
public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
253
if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) )
255
setDirectoryScannerParameters( o, dirScannerParams );
259
public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
261
final Object param = createDirectoryScannerParameters( dirScannerParams );
262
ReflectionUtils.invokeSetter( o, "setDirectoryScannerParameters", this.directoryScannerParameters, param );
266
public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
268
if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) )
270
setTestSuiteDefinition( o, testSuiteDefinition2 );
274
void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 )
276
final Object param = createTestRequest( testSuiteDefinition1 );
277
ReflectionUtils.invokeSetter( o, "setTestRequest", this.testRequest, param );
280
public void setProviderPropertiesAware( Object o, Properties properties )
282
if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) )
284
setProviderProperties( o, properties );
288
void setProviderProperties( Object o, Properties providerProperties )
290
ReflectionUtils.invokeSetter( o, "setProviderProperties", Properties.class, providerProperties );
293
public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
295
if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) )
297
setReporterConfiguration( o, reporterConfiguration1 );
302
void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration )
304
final Object param = createReporterConfiguration( reporterConfiguration );
305
ReflectionUtils.invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param );
308
public void setTestClassLoaderAware( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
310
if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) )
312
setTestClassLoader( o, surefireClassLoader, testClassLoader );
316
void setTestClassLoader( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
318
final Method setter =
319
ReflectionUtils.getMethod( o, "setClassLoaders", new Class[]{ ClassLoader.class, ClassLoader.class } );
320
ReflectionUtils.invokeMethodWithArray( o, setter, new Object[]{ surefireClassLoader, testClassLoader } );
323
public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
325
if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) )
327
setTestArtifactInfo( o, testArtifactInfo1 );
331
void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo )
333
final Object param = createTestArtifactInfo( testArtifactInfo );
334
ReflectionUtils.invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
337
private boolean isRunResult( Object o )
339
return runResult.isAssignableFrom( o.getClass() );