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.PrintStream;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.Iterator;
26
27 import org.apache.maven.surefire.providerapi.SurefireProvider;
28 import org.apache.maven.surefire.report.ReporterException;
29 import org.apache.maven.surefire.suite.RunResult;
30 import org.apache.maven.surefire.testset.TestSetFailedException;
31 import org.apache.maven.surefire.util.ReflectionUtils;
32
33
34
35
36
37
38
39
40 public class ProviderFactory
41 {
42 private final StartupConfiguration startupConfiguration;
43
44 private final ProviderConfiguration providerConfiguration;
45
46 private final ClassLoader classLoader;
47
48 private final SurefireReflector surefireReflector;
49
50 private final Object reporterManagerFactory;
51
52 private static final Class[] invokeParamaters = new Class[]{ Object.class };
53
54
55 public ProviderFactory( StartupConfiguration startupConfiguration, ProviderConfiguration providerConfiguration,
56 ClassLoader testsClassLoader, Object reporterManagerFactory )
57 {
58 this.providerConfiguration = providerConfiguration;
59 this.startupConfiguration = startupConfiguration;
60 this.surefireReflector = new SurefireReflector( testsClassLoader );
61 this.classLoader = testsClassLoader;
62 this.reporterManagerFactory = reporterManagerFactory;
63 }
64
65 public static RunResult invokeProvider( Object testSet, ClassLoader testsClassLoader, Object factory,
66 ProviderConfiguration providerConfiguration, boolean insideFork,
67 StartupConfiguration startupConfiguration1, boolean restoreStreams )
68 throws TestSetFailedException, InvocationTargetException
69 {
70 final PrintStream orgSystemOut = System.out;
71 final PrintStream orgSystemErr = System.err;
72
73
74
75 ProviderFactory providerFactory =
76 new ProviderFactory( startupConfiguration1, providerConfiguration, testsClassLoader,
77 factory );
78 final SurefireProvider provider = providerFactory.createProvider( insideFork );
79
80 try
81 {
82 return provider.invoke( testSet );
83 }
84 finally
85 {
86 if ( restoreStreams && System.getSecurityManager() == null )
87 {
88 System.setOut( orgSystemOut );
89 System.setErr( orgSystemErr );
90 }
91 }
92 }
93
94
95 public SurefireProvider createProvider( boolean isInsideFork )
96 {
97 ClassLoader systemClassLoader = java.lang.Thread.currentThread().getContextClassLoader();
98 Thread.currentThread().setContextClassLoader( classLoader );
99
100 StartupConfiguration starterConfiguration = startupConfiguration;
101
102
103 final Object o =
104 surefireReflector.createBooterConfiguration( classLoader, reporterManagerFactory, isInsideFork );
105 surefireReflector.setTestSuiteDefinitionAware( o, providerConfiguration.getTestSuiteDefinition() );
106 surefireReflector.setProviderPropertiesAware( o, providerConfiguration.getProviderProperties() );
107 surefireReflector.setReporterConfigurationAware( o, providerConfiguration.getReporterConfiguration() );
108 surefireReflector.setTestClassLoaderAware( o, classLoader );
109 surefireReflector.setTestArtifactInfoAware( o, providerConfiguration.getTestArtifact() );
110 surefireReflector.setRunOrderParameters( o, providerConfiguration.getRunOrderParameters() );
111 surefireReflector.setIfDirScannerAware( o, providerConfiguration.getDirScannerParams() );
112
113 Object provider = surefireReflector.instantiateProvider( starterConfiguration.getActualClassName(), o );
114 Thread.currentThread().setContextClassLoader( systemClassLoader );
115
116 return new ProviderProxy( provider, classLoader );
117 }
118
119
120 private class ProviderProxy
121 implements SurefireProvider
122 {
123 private final Object providerInOtherClassLoader;
124
125 private final ClassLoader testsClassLoader;
126
127
128 private ProviderProxy( Object providerInOtherClassLoader, ClassLoader testsClassLoader )
129 {
130 this.providerInOtherClassLoader = providerInOtherClassLoader;
131 this.testsClassLoader = testsClassLoader;
132 }
133
134 public Iterator getSuites()
135 {
136 ClassLoader current = swapClassLoader( testsClassLoader );
137 try
138 {
139 return (Iterator) ReflectionUtils.invokeGetter( providerInOtherClassLoader, "getSuites" );
140 }
141 finally
142 {
143 Thread.currentThread().setContextClassLoader( current );
144 }
145 }
146
147 public RunResult invoke( Object forkTestSet )
148 throws TestSetFailedException, ReporterException, InvocationTargetException
149 {
150 ClassLoader current = swapClassLoader( testsClassLoader );
151 try
152 {
153 final Method invoke =
154 ReflectionUtils.getMethod( providerInOtherClassLoader.getClass(), "invoke", invokeParamaters );
155
156 final Object result = ReflectionUtils.invokeMethodWithArray2( providerInOtherClassLoader, invoke,
157 new Object[]{ forkTestSet } );
158 return (RunResult) surefireReflector.convertIfRunResult( result );
159 }
160 finally
161 {
162 if ( System.getSecurityManager() == null )
163 {
164 Thread.currentThread().setContextClassLoader( current );
165 }
166 }
167
168 }
169
170 private ClassLoader swapClassLoader( ClassLoader newClassLoader )
171 {
172 ClassLoader current = Thread.currentThread().getContextClassLoader();
173 Thread.currentThread().setContextClassLoader( newClassLoader );
174 return current;
175 }
176
177 public void cancel()
178 {
179 final Method invoke =
180 ReflectionUtils.getMethod( providerInOtherClassLoader.getClass(), "cancel", new Class[]{ } );
181 ReflectionUtils.invokeMethodWithArray( providerInOtherClassLoader, invoke, null );
182 }
183 }
184 }