1 package org.apache.maven.surefire.booter;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.PrintStream;
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.util.List;
29 import java.util.Properties;
30 import org.apache.maven.surefire.providerapi.ProviderParameters;
31 import org.apache.maven.surefire.report.ReporterConfiguration;
32 import org.apache.maven.surefire.report.ReporterFactory;
33 import org.apache.maven.surefire.suite.RunResult;
34 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
35 import org.apache.maven.surefire.testset.RunOrderParameters;
36 import org.apache.maven.surefire.testset.TestArtifactInfo;
37 import org.apache.maven.surefire.testset.TestRequest;
38 import org.apache.maven.surefire.util.NestedRuntimeException;
39 import org.apache.maven.surefire.util.ReflectionUtils;
40 import org.apache.maven.surefire.util.RunOrder;
41 import org.apache.maven.surefire.util.SurefireReflectionException;
42
43
44
45
46
47
48
49
50 public class SurefireReflector
51 {
52 private final ClassLoader surefireClassLoader;
53
54 private final Class reporterConfiguration;
55
56 private final Class testRequest;
57
58 private final Class testArtifactInfo;
59
60 private final Class testArtifactInfoAware;
61
62 private final Class directoryScannerParameters;
63
64 private final Class runOrderParameters;
65
66 private final Class directoryScannerParametersAware;
67
68 private final Class testSuiteDefinitionAware;
69
70 private final Class testClassLoaderAware;
71
72 private final Class reporterConfigurationAware;
73
74 private final Class providerPropertiesAware;
75
76 private final Class runResult;
77
78 private final Class booterParameters;
79
80 private final Class reporterFactory;
81
82 private final Method assertionStatusMethod;
83
84
85 public SurefireReflector( ClassLoader surefireClassLoader )
86 {
87 this.surefireClassLoader = surefireClassLoader;
88 try
89 {
90 reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() );
91 testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() );
92 testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() );
93 testArtifactInfoAware = surefireClassLoader.loadClass( TestArtifactInfoAware.class.getName() );
94 directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() );
95 runOrderParameters = surefireClassLoader.loadClass( RunOrderParameters.class.getName() );
96 directoryScannerParametersAware =
97 surefireClassLoader.loadClass( DirectoryScannerParametersAware.class.getName() );
98 testSuiteDefinitionAware = surefireClassLoader.loadClass( TestRequestAware.class.getName() );
99 testClassLoaderAware = surefireClassLoader.loadClass( SurefireClassLoadersAware.class.getName() );
100 reporterConfigurationAware = surefireClassLoader.loadClass( ReporterConfigurationAware.class.getName() );
101 providerPropertiesAware = surefireClassLoader.loadClass( ProviderPropertiesAware.class.getName() );
102 reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() );
103 runResult = surefireClassLoader.loadClass( RunResult.class.getName() );
104 booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() );
105 assertionStatusMethod = ReflectionUtils.tryGetMethod( ClassLoader.class, "setDefaultAssertionStatus",
106 new Class[]{ boolean.class } );
107 }
108 catch ( ClassNotFoundException e )
109 {
110 throw new SurefireReflectionException( e );
111 }
112 }
113
114 public Object convertIfRunResult( Object result )
115 {
116 if ( result == null || !isRunResult( result ) )
117 {
118 return result;
119 }
120 final Integer getCompletedCount1 = (Integer) ReflectionUtils.invokeGetter( result, "getCompletedCount" );
121 final Integer getErrors = (Integer) ReflectionUtils.invokeGetter( result, "getErrors" );
122 final Integer getSkipped = (Integer) ReflectionUtils.invokeGetter( result, "getSkipped" );
123 final Integer getFailures = (Integer) ReflectionUtils.invokeGetter( result, "getFailures" );
124 return new RunResult( getCompletedCount1.intValue(), getErrors.intValue(), getFailures.intValue(),
125 getSkipped.intValue() );
126
127 }
128
129
130
131
132
133 class ClassLoaderProxy
134 implements InvocationHandler
135 {
136 private final Object target;
137
138
139
140
141
142 public ClassLoaderProxy( Object delegate )
143 {
144 this.target = delegate;
145 }
146
147 public Object invoke( Object proxy, Method method, Object[] args )
148 throws Throwable
149 {
150 Method delegateMethod = target.getClass().getMethod( method.getName(), method.getParameterTypes() );
151 return delegateMethod.invoke( target, args );
152 }
153 }
154
155
156 Object createTestRequest( TestRequest suiteDefinition )
157 {
158 if ( suiteDefinition == null )
159 {
160 return null;
161 }
162 Class[] arguments = { List.class, File.class, String.class, String.class };
163 Constructor constructor = ReflectionUtils.getConstructor( this.testRequest, arguments );
164 return ReflectionUtils.newInstance( constructor, new Object[]{ suiteDefinition.getSuiteXmlFiles(),
165 suiteDefinition.getTestSourceDirectory(), suiteDefinition.getRequestedTest(),
166 suiteDefinition.getRequestedTestMethod() } );
167 }
168
169
170 Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
171 {
172 if ( directoryScannerParameters == null )
173 {
174 return null;
175 }
176
177 Class[] arguments = { File.class, List.class, List.class, Boolean.class, String.class };
178 Constructor constructor = ReflectionUtils.getConstructor( this.directoryScannerParameters, arguments );
179 return ReflectionUtils.newInstance( constructor,
180 new Object[]{ directoryScannerParameters.getTestClassesDirectory(),
181 directoryScannerParameters.getIncludes(),
182 directoryScannerParameters.getExcludes(),
183 directoryScannerParameters.isFailIfNoTests(),
184 RunOrder.asString( directoryScannerParameters.getRunOrder() ) } );
185 }
186
187
188 Object createRunOrderParameters( RunOrderParameters runOrderParameters )
189 {
190 if ( runOrderParameters == null )
191 {
192 return null;
193 }
194
195 Class[] arguments = { String.class, String.class };
196 Constructor constructor = ReflectionUtils.getConstructor( this.runOrderParameters, arguments );
197 final File runStatisticsFile = runOrderParameters.getRunStatisticsFile();
198 return ReflectionUtils.newInstance( constructor,
199 new Object[]{ RunOrder.asString( runOrderParameters.getRunOrder() ),
200 runStatisticsFile != null
201 ? runStatisticsFile.getAbsolutePath()
202 : null } );
203 }
204
205 Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo )
206 {
207 if ( testArtifactInfo == null )
208 {
209 return null;
210 }
211 Class[] arguments = { String.class, String.class };
212 Constructor constructor = ReflectionUtils.getConstructor( this.testArtifactInfo, arguments );
213 return ReflectionUtils.newInstance( constructor, new Object[]{ testArtifactInfo.getVersion(),
214 testArtifactInfo.getClassifier() } );
215 }
216
217
218 Object createReporterConfiguration( ReporterConfiguration reporterConfiguration )
219 {
220 Constructor constructor =
221 ReflectionUtils.getConstructor( this.reporterConfiguration, new Class[]{ File.class, Boolean.class } );
222 return ReflectionUtils.newInstance( constructor, new Object[]{ reporterConfiguration.getReportsDirectory(),
223 reporterConfiguration.isTrimStackTrace() } );
224 }
225
226 public Object createForkingReporterFactory( Boolean trimStackTrace, PrintStream originalSystemOut )
227 {
228 Class[] args = new Class[]{ Boolean.class, PrintStream.class };
229 Object[] values = new Object[]{ trimStackTrace, originalSystemOut };
230 return ReflectionUtils.instantiateObject( ForkingReporterFactory.class.getName(), args, values,
231 surefireClassLoader );
232 }
233
234 public Object createBooterConfiguration( ClassLoader surefireClassLoader, Object factoryInstance,
235 boolean insideFork )
236 {
237 return ReflectionUtils.instantiateTwoArgs( surefireClassLoader, BaseProviderFactory.class.getName(),
238 reporterFactory, factoryInstance, Boolean.class,
239 insideFork ? Boolean.TRUE : Boolean.FALSE );
240 }
241
242 public Object instantiateProvider( String providerClassName, Object booterParameters )
243 {
244 return ReflectionUtils.instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters,
245 booterParameters );
246 }
247
248 public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
249 {
250 if ( directoryScannerParametersAware.isAssignableFrom( o.getClass() ) )
251 {
252 setDirectoryScannerParameters( o, dirScannerParams );
253 }
254 }
255
256 public void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
257 {
258 final Object param = createDirectoryScannerParameters( dirScannerParams );
259 ReflectionUtils.invokeSetter( o, "setDirectoryScannerParameters", this.directoryScannerParameters, param );
260 }
261
262 public void setRunOrderParameters( Object o, RunOrderParameters runOrderParameters )
263 {
264 final Object param = createRunOrderParameters( runOrderParameters );
265 ReflectionUtils.invokeSetter( o, "setRunOrderParameters", this.runOrderParameters, param );
266 }
267
268
269 public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
270 {
271 if ( testSuiteDefinitionAware.isAssignableFrom( o.getClass() ) )
272 {
273 setTestSuiteDefinition( o, testSuiteDefinition2 );
274 }
275 }
276
277 void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 )
278 {
279 final Object param = createTestRequest( testSuiteDefinition1 );
280 ReflectionUtils.invokeSetter( o, "setTestRequest", this.testRequest, param );
281 }
282
283 public void setProviderPropertiesAware( Object o, Properties properties )
284 {
285 if ( providerPropertiesAware.isAssignableFrom( o.getClass() ) )
286 {
287 setProviderProperties( o, properties );
288 }
289 }
290
291 void setProviderProperties( Object o, Properties providerProperties )
292 {
293 ReflectionUtils.invokeSetter( o, "setProviderProperties", Properties.class, providerProperties );
294 }
295
296 public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
297 {
298 if ( reporterConfigurationAware.isAssignableFrom( o.getClass() ) )
299 {
300 setReporterConfiguration( o, reporterConfiguration1 );
301 }
302 }
303
304
305 void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration )
306 {
307 final Object param = createReporterConfiguration( reporterConfiguration );
308 ReflectionUtils.invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param );
309 }
310
311 public void setTestClassLoaderAware( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
312 {
313 if ( testClassLoaderAware.isAssignableFrom( o.getClass() ) )
314 {
315 setTestClassLoader( o, surefireClassLoader, testClassLoader );
316 }
317 }
318
319 void setTestClassLoader( Object o, ClassLoader surefireClassLoader, ClassLoader testClassLoader )
320 {
321 final Method setter =
322 ReflectionUtils.getMethod( o, "setClassLoaders", new Class[]{ ClassLoader.class, ClassLoader.class } );
323 ReflectionUtils.invokeMethodWithArray( o, setter, new Object[]{ surefireClassLoader, testClassLoader } );
324 }
325
326 public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
327 {
328 if ( testArtifactInfoAware.isAssignableFrom( o.getClass() ) )
329 {
330 setTestArtifactInfo( o, testArtifactInfo1 );
331 }
332 }
333
334 void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo )
335 {
336 final Object param = createTestArtifactInfo( testArtifactInfo );
337 ReflectionUtils.invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
338 }
339
340 private boolean isRunResult( Object o )
341 {
342 return runResult.isAssignableFrom( o.getClass() );
343 }
344
345 public void invokeAssertionStatusMethod( ClassLoader classLoader, boolean enableAssertions )
346 {
347 if ( assertionStatusMethod != null )
348 {
349 try
350 {
351 Object[] args = new Object[]{ enableAssertions ? Boolean.TRUE : Boolean.FALSE };
352 assertionStatusMethod.invoke( classLoader, args );
353 }
354 catch ( IllegalAccessException e )
355 {
356 throw new NestedRuntimeException( "Unable to access the assertion enablement method", e );
357 }
358 catch ( InvocationTargetException e )
359 {
360 throw new NestedRuntimeException( "Unable to invoke the assertion enablement method", e );
361 }
362 }
363 }
364
365 }