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