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