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 org.apache.maven.surefire.providerapi.SurefireProvider;
24 import org.apache.maven.surefire.report.ReporterException;
25 import org.apache.maven.surefire.suite.RunResult;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.apache.maven.surefire.util.NestedRuntimeException;
28 import org.apache.maven.surefire.util.ReflectionUtils;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public class SurefireStarter
44 {
45 private final ProviderConfiguration providerConfiguration;
46
47 private final StartupConfiguration startupConfiguration;
48
49 private final static String SUREFIRE_TEST_CLASSPATH = "surefire.test.class.path";
50
51 private final StartupReportConfiguration startupReportConfiguration;
52
53 public SurefireStarter( StartupConfiguration startupConfiguration, ProviderConfiguration providerConfiguration,
54 StartupReportConfiguration startupReportConfiguration )
55 {
56 this.providerConfiguration = providerConfiguration;
57 this.startupConfiguration = startupConfiguration;
58 this.startupReportConfiguration = startupReportConfiguration;
59 }
60
61 public RunResult runSuitesInProcessWhenForked( TypeEncodedValue testSet )
62 throws SurefireExecutionException
63 {
64 writeSurefireTestClasspathProperty();
65 final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
66
67
68
69
70 ClassLoader testsClassLoader = classpathConfiguration.createTestClassLoaderConditionallySystem(
71 startupConfiguration.useSystemClassLoader() );
72
73 ClassLoader surefireClassLoader = classpathConfiguration.createSurefireClassLoader( testsClassLoader );
74
75 SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
76
77 final Object forkingReporterFactory = createForkingReporterFactory( surefireReflector );
78
79 Object test = testSet.getDecodedValue();
80
81 return invokeProvider( test, testsClassLoader, surefireClassLoader, forkingReporterFactory );
82 }
83
84 private Object createForkingReporterFactory( SurefireReflector surefireReflector )
85 {
86 final Boolean trimStackTrace = this.providerConfiguration.getReporterConfiguration().isTrimStackTrace();
87 final PrintStream originalSystemOut =
88 this.providerConfiguration.getReporterConfiguration().getOriginalSystemOut();
89 return surefireReflector.createForkingReporterFactory( trimStackTrace, originalSystemOut );
90 }
91
92
93
94
95
96 public RunResult runSuitesInProcessWhenForked()
97 throws SurefireExecutionException
98 {
99 ClassLoader testsClassLoader = createInProcessTestClassLoader();
100
101 ClassLoader surefireClassLoader = createSurefireClassloader( testsClassLoader );
102
103 SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
104
105 final Object factory = createForkingReporterFactory( surefireReflector );
106
107 return invokeProvider( null, testsClassLoader, surefireClassLoader, factory );
108 }
109
110 public RunResult runSuitesInProcess()
111 throws SurefireExecutionException
112 {
113
114
115 ClassLoader testsClassLoader = createInProcessTestClassLoader();
116
117 ClassLoader surefireClassLoader = createSurefireClassloader( testsClassLoader );
118
119 SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader );
120
121 final Object factory = surefireReflector.createReportingReporterFactory( startupReportConfiguration );
122
123 return invokeProvider( null, testsClassLoader, surefireClassLoader, factory );
124 }
125
126 private ClassLoader createSurefireClassloader( ClassLoader testsClassLoader )
127 throws SurefireExecutionException
128 {
129 final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
130
131 return classpathConfiguration.createSurefireClassLoader( testsClassLoader );
132 }
133
134 private ClassLoader createInProcessTestClassLoader()
135 throws SurefireExecutionException
136 {
137 writeSurefireTestClasspathProperty();
138 ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
139 if ( startupConfiguration.isManifestOnlyJarRequestedAndUsable() )
140 {
141 ClassLoader testsClassLoader = getClass().getClassLoader();
142
143
144 System.setProperty( "surefire.real.class.path", System.getProperty( "java.class.path" ) );
145 classpathConfiguration.getTestClasspath().writeToSystemProperty( "java.class.path" );
146 return testsClassLoader;
147 }
148 else
149 {
150 return classpathConfiguration.createTestClassLoader();
151 }
152 }
153
154 private void writeSurefireTestClasspathProperty()
155 {
156 ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
157 classpathConfiguration.getTestClasspath().writeToSystemProperty( SUREFIRE_TEST_CLASSPATH );
158 }
159
160 private RunResult invokeProvider( Object testSet, ClassLoader testsClassLoader, ClassLoader surefireClassLoader,
161 Object factory )
162 {
163 final PrintStream orgSystemOut = System.out;
164 final PrintStream orgSystemErr = System.err;
165
166
167
168 ProviderFactory providerFactory =
169 new ProviderFactory( startupConfiguration, providerConfiguration, surefireClassLoader, testsClassLoader,
170 factory );
171 final SurefireProvider provider = providerFactory.createProvider();
172
173 try
174 {
175 return provider.invoke( testSet );
176 }
177 catch ( TestSetFailedException e )
178 {
179 throw new NestedRuntimeException( e );
180 }
181 catch ( ReporterException e )
182 {
183 throw new NestedRuntimeException( e );
184 }
185 finally
186 {
187 if ( System.getSecurityManager() == null )
188 {
189 System.setOut( orgSystemOut );
190 System.setErr( orgSystemErr );
191 }
192 }
193 }
194 }