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 org.apache.maven.surefire.api.booter.BaseProviderFactory;
23 import org.apache.maven.surefire.api.cli.CommandLineOption;
24 import org.apache.maven.surefire.api.provider.ProviderParameters;
25 import org.apache.maven.surefire.api.report.ReporterConfiguration;
26 import org.apache.maven.surefire.api.report.ReporterFactory;
27 import org.apache.maven.surefire.api.suite.RunResult;
28 import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
29 import org.apache.maven.surefire.api.testset.RunOrderParameters;
30 import org.apache.maven.surefire.api.testset.TestArtifactInfo;
31 import org.apache.maven.surefire.api.testset.TestListResolver;
32 import org.apache.maven.surefire.api.testset.TestRequest;
33 import org.apache.maven.surefire.api.util.RunOrder;
34 import org.apache.maven.surefire.api.util.SurefireReflectionException;
35
36 import java.io.File;
37 import java.lang.reflect.Constructor;
38 import java.lang.reflect.Method;
39 import java.util.ArrayList;
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.Map;
43
44 import static java.util.Collections.checkedList;
45 import static org.apache.maven.surefire.api.util.ReflectionUtils.getConstructor;
46 import static org.apache.maven.surefire.api.util.ReflectionUtils.getMethod;
47 import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiateOneArg;
48 import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeGetter;
49 import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray;
50 import static org.apache.maven.surefire.api.util.ReflectionUtils.invokeSetter;
51 import static org.apache.maven.surefire.api.util.ReflectionUtils.newInstance;
52
53
54
55
56
57
58
59
60 public final class SurefireReflector
61 {
62 private final ClassLoader surefireClassLoader;
63
64 private final Class<?> reporterConfiguration;
65
66 private final Class<?> testRequest;
67
68 private final Class<?> testArtifactInfo;
69
70 private final Class<?> directoryScannerParameters;
71
72 private final Class<?> runOrderParameters;
73
74 private final Class<?> baseProviderFactory;
75
76 private final Class<?> runResult;
77
78 private final Class<?> booterParameters;
79
80 private final Class<?> reporterFactory;
81
82 private final Class<?> testListResolver;
83
84 private final Class<Enum<?>> commandLineOptionsClass;
85
86 @SuppressWarnings( "unchecked" )
87 public SurefireReflector( ClassLoader surefireClassLoader )
88 {
89 this.surefireClassLoader = surefireClassLoader;
90 try
91 {
92 reporterConfiguration = surefireClassLoader.loadClass( ReporterConfiguration.class.getName() );
93 testRequest = surefireClassLoader.loadClass( TestRequest.class.getName() );
94 testArtifactInfo = surefireClassLoader.loadClass( TestArtifactInfo.class.getName() );
95 directoryScannerParameters = surefireClassLoader.loadClass( DirectoryScannerParameters.class.getName() );
96 runOrderParameters = surefireClassLoader.loadClass( RunOrderParameters.class.getName() );
97 baseProviderFactory = surefireClassLoader.loadClass( BaseProviderFactory.class.getName() );
98 reporterFactory = surefireClassLoader.loadClass( ReporterFactory.class.getName() );
99 runResult = surefireClassLoader.loadClass( RunResult.class.getName() );
100 booterParameters = surefireClassLoader.loadClass( ProviderParameters.class.getName() );
101 testListResolver = surefireClassLoader.loadClass( TestListResolver.class.getName() );
102 commandLineOptionsClass =
103 (Class<Enum<?>>) surefireClassLoader.loadClass( CommandLineOption.class.getName() );
104 }
105 catch ( ClassNotFoundException e )
106 {
107 throw new SurefireReflectionException( e );
108 }
109 }
110
111 public Object convertIfRunResult( Object result )
112 {
113 if ( result == null || !isRunResult( result ) )
114 {
115 return result;
116 }
117 int getCompletedCount1 = (Integer) invokeGetter( result, "getCompletedCount" );
118 int getErrors = (Integer) invokeGetter( result, "getErrors" );
119 int getSkipped = (Integer) invokeGetter( result, "getSkipped" );
120 int getFailures = (Integer) invokeGetter( result, "getFailures" );
121 return new RunResult( getCompletedCount1, getErrors, getFailures, getSkipped );
122 }
123
124 private Object createTestRequest( TestRequest suiteDefinition )
125 {
126 if ( suiteDefinition == null )
127 {
128 return null;
129 }
130 else
131 {
132 Object resolver = createTestListResolver( suiteDefinition.getTestListResolver() );
133 Class<?>[] arguments = { List.class, File.class, testListResolver, int.class };
134 Constructor<?> constructor = getConstructor( testRequest, arguments );
135 return newInstance( constructor,
136 suiteDefinition.getSuiteXmlFiles(),
137 suiteDefinition.getTestSourceDirectory(),
138 resolver,
139 suiteDefinition.getRerunFailingTestsCount() );
140 }
141 }
142
143 private Object createTestListResolver( TestListResolver resolver )
144 {
145 if ( resolver == null )
146 {
147 return null;
148 }
149 else
150 {
151 Constructor<?> constructor = getConstructor( testListResolver, String.class );
152 return newInstance( constructor, resolver.getPluginParameterTest() );
153 }
154 }
155
156 private Object createDirectoryScannerParameters( DirectoryScannerParameters directoryScannerParameters )
157 {
158 if ( directoryScannerParameters == null )
159 {
160 return null;
161 }
162
163 Class<?>[] arguments = { File.class, List.class, List.class, List.class, boolean.class, String.class };
164 Constructor<?> constructor = getConstructor( this.directoryScannerParameters, arguments );
165 return newInstance( constructor,
166 directoryScannerParameters.getTestClassesDirectory(),
167 directoryScannerParameters.getIncludes(),
168 directoryScannerParameters.getExcludes(),
169 directoryScannerParameters.getSpecificTests(),
170 directoryScannerParameters.isFailIfNoTests(),
171 RunOrder.asString( directoryScannerParameters.getRunOrder() ) );
172 }
173
174 private Object createRunOrderParameters( RunOrderParameters runOrderParameters )
175 {
176 if ( runOrderParameters == null )
177 {
178 return null;
179 }
180
181 Class<?>[] arguments = { String.class, File.class };
182 Constructor<?> constructor = getConstructor( this.runOrderParameters, arguments );
183 File runStatisticsFile = runOrderParameters.getRunStatisticsFile();
184 return newInstance( constructor, RunOrder.asString( runOrderParameters.getRunOrder() ), runStatisticsFile );
185 }
186
187 private Object createTestArtifactInfo( TestArtifactInfo testArtifactInfo )
188 {
189 if ( testArtifactInfo == null )
190 {
191 return null;
192 }
193 Class<?>[] arguments = { String.class, String.class };
194 Constructor<?> constructor = getConstructor( this.testArtifactInfo, arguments );
195 return newInstance( constructor, testArtifactInfo.getVersion(), testArtifactInfo.getClassifier() );
196 }
197
198 private Object createReporterConfiguration( ReporterConfiguration reporterConfig )
199 {
200 Constructor<?> constructor = getConstructor( reporterConfiguration, File.class, boolean.class );
201 return newInstance( constructor, reporterConfig.getReportsDirectory(), reporterConfig.isTrimStackTrace() );
202 }
203
204 public Object createBooterConfiguration( ClassLoader surefireClassLoader, boolean insideFork )
205 {
206 return instantiateOneArg( surefireClassLoader, BaseProviderFactory.class.getName(), boolean.class, insideFork );
207 }
208
209 public Object instantiateProvider( String providerClassName, Object booterParameters )
210 {
211 return instantiateOneArg( surefireClassLoader, providerClassName, this.booterParameters, booterParameters );
212 }
213
214 public void setIfDirScannerAware( Object o, DirectoryScannerParameters dirScannerParams )
215 {
216 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
217 {
218 setDirectoryScannerParameters( o, dirScannerParams );
219 }
220 }
221
222 public void setMainCliOptions( Object o, List<CommandLineOption> options )
223 {
224 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
225 {
226 List<Enum<?>> newOptions = checkedList( new ArrayList<Enum<?>>( options.size() ), commandLineOptionsClass );
227 Collection<Integer> ordinals = toOrdinals( options );
228 for ( Enum<?> e : commandLineOptionsClass.getEnumConstants() )
229 {
230 if ( ordinals.contains( e.ordinal() ) )
231 {
232 newOptions.add( e );
233 }
234 }
235 invokeSetter( o, "setMainCliOptions", List.class, newOptions );
236 }
237 }
238
239 public void setSkipAfterFailureCount( Object o, int skipAfterFailureCount )
240 {
241 invokeSetter( o, "setSkipAfterFailureCount", int.class, skipAfterFailureCount );
242 }
243
244 public void setSystemExitTimeout( Object o, Integer systemExitTimeout )
245 {
246 invokeSetter( o, "setSystemExitTimeout", Integer.class, systemExitTimeout );
247 }
248
249 void setDirectoryScannerParameters( Object o, DirectoryScannerParameters dirScannerParams )
250 {
251 Object param = createDirectoryScannerParameters( dirScannerParams );
252 invokeSetter( o, "setDirectoryScannerParameters", directoryScannerParameters, param );
253 }
254
255 public void setRunOrderParameters( Object o, RunOrderParameters runOrderParameters )
256 {
257 Object param = createRunOrderParameters( runOrderParameters );
258 invokeSetter( o, "setRunOrderParameters", this.runOrderParameters, param );
259 }
260
261 public void setTestSuiteDefinitionAware( Object o, TestRequest testSuiteDefinition2 )
262 {
263 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
264 {
265 setTestSuiteDefinition( o, testSuiteDefinition2 );
266 }
267 }
268
269 void setTestSuiteDefinition( Object o, TestRequest testSuiteDefinition1 )
270 {
271 Object param = createTestRequest( testSuiteDefinition1 );
272 invokeSetter( o, "setTestRequest", testRequest, param );
273 }
274
275 public void setProviderPropertiesAware( Object o, Map<String, String> properties )
276 {
277 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
278 {
279 setProviderProperties( o, properties );
280 }
281 }
282
283 void setProviderProperties( Object o, Map<String, String> providerProperties )
284 {
285 invokeSetter( o, "setProviderProperties", Map.class, providerProperties );
286 }
287
288 public void setReporterConfigurationAware( Object o, ReporterConfiguration reporterConfiguration1 )
289 {
290 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
291 {
292 setReporterConfiguration( o, reporterConfiguration1 );
293 }
294 }
295
296 private void setReporterConfiguration( Object o, ReporterConfiguration reporterConfiguration )
297 {
298 Object param = createReporterConfiguration( reporterConfiguration );
299 invokeSetter( o, "setReporterConfiguration", this.reporterConfiguration, param );
300 }
301
302 public void setTestClassLoaderAware( Object o, ClassLoader testClassLoader )
303 {
304 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
305 {
306 setTestClassLoader( o, testClassLoader );
307 }
308 }
309
310 void setTestClassLoader( Object o, ClassLoader testClassLoader )
311 {
312 Method setter = getMethod( o, "setClassLoaders", ClassLoader.class );
313 invokeMethodWithArray( o, setter, testClassLoader );
314 }
315
316 public void setTestArtifactInfoAware( Object o, TestArtifactInfo testArtifactInfo1 )
317 {
318 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
319 {
320 setTestArtifactInfo( o, testArtifactInfo1 );
321 }
322 }
323
324 void setTestArtifactInfo( Object o, TestArtifactInfo testArtifactInfo )
325 {
326 Object param = createTestArtifactInfo( testArtifactInfo );
327 invokeSetter( o, "setTestArtifactInfo", this.testArtifactInfo, param );
328 }
329
330 public void setReporterFactoryAware( Object o, Object reporterFactory )
331 {
332 if ( baseProviderFactory.isAssignableFrom( o.getClass() ) )
333 {
334 setReporterFactory( o, reporterFactory );
335 }
336 }
337
338 void setReporterFactory( Object o, Object reporterFactory )
339 {
340 invokeSetter( o, "setReporterFactory", this.reporterFactory, reporterFactory );
341 }
342
343 private boolean isRunResult( Object o )
344 {
345 return runResult.isAssignableFrom( o.getClass() );
346 }
347
348 private static Collection<Integer> toOrdinals( Collection<? extends Enum<?>> enums )
349 {
350 Collection<Integer> ordinals = new ArrayList<>( enums.size() );
351 for ( Enum<?> e : enums )
352 {
353 ordinals.add( e.ordinal() );
354 }
355 return ordinals;
356 }
357 }