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.File;
23 import java.io.FileInputStream;
24 import java.io.InputStream;
25 import java.io.PrintStream;
26 import java.lang.reflect.InvocationTargetException;
27
28 import org.apache.maven.surefire.providerapi.ProviderParameters;
29 import org.apache.maven.surefire.providerapi.SurefireProvider;
30 import org.apache.maven.surefire.report.LegacyPojoStackTraceWriter;
31 import org.apache.maven.surefire.report.ReporterFactory;
32 import org.apache.maven.surefire.report.StackTraceWriter;
33 import org.apache.maven.surefire.suite.RunResult;
34 import org.apache.maven.surefire.testset.TestSetFailedException;
35 import org.apache.maven.surefire.util.ReflectionUtils;
36
37
38
39
40
41
42
43
44
45
46
47 public class ForkedBooter
48 {
49
50
51
52
53
54
55
56
57 public static void main( String[] args )
58 throws Throwable
59 {
60 final PrintStream originalOut = System.out;
61 try
62 {
63 if ( args.length > 1 )
64 {
65 SystemPropertyManager.setSystemProperties( new File( args[1] ) );
66 }
67
68 File surefirePropertiesFile = new File( args[0] );
69 InputStream stream = surefirePropertiesFile.exists() ? new FileInputStream( surefirePropertiesFile ) : null;
70 BooterDeserializer booterDeserializer = new BooterDeserializer( stream );
71 ProviderConfiguration providerConfiguration = booterDeserializer.deserialize();
72 final StartupConfiguration startupConfiguration = booterDeserializer.getProviderConfiguration();
73
74 TypeEncodedValue forkedTestSet = providerConfiguration.getTestForFork();
75 boolean readTestsFromInputStream = providerConfiguration.isReadTestsFromInStream();
76
77 final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration();
78 if ( startupConfiguration.isManifestOnlyJarRequestedAndUsable() )
79 {
80 classpathConfiguration.trickClassPathWhenManifestOnlyClasspath();
81 }
82
83 Thread.currentThread().getContextClassLoader().setDefaultAssertionStatus(
84 classpathConfiguration.isEnableAssertions() );
85 startupConfiguration.writeSurefireTestClasspathProperty();
86
87 Object testSet;
88 if ( forkedTestSet != null )
89 {
90 testSet = forkedTestSet.getDecodedValue( Thread.currentThread().getContextClassLoader() );
91 }
92 else if ( readTestsFromInputStream )
93 {
94 testSet = new LazyTestsToRun( System.in, originalOut );
95 }
96 else
97 {
98 testSet = null;
99 }
100
101 try
102 {
103 runSuitesInProcess( testSet, startupConfiguration, providerConfiguration, originalOut );
104 }
105 catch ( InvocationTargetException t )
106 {
107
108 LegacyPojoStackTraceWriter stackTraceWriter =
109 new LegacyPojoStackTraceWriter( "test subystem", "no method", t.getTargetException() );
110 StringBuilder stringBuilder = new StringBuilder();
111 ForkingRunListener.encode( stringBuilder, stackTraceWriter, false );
112 originalOut.println( ( (char) ForkingRunListener.BOOTERCODE_ERROR ) + ",0," + stringBuilder.toString() );
113 }
114 catch ( Throwable t )
115 {
116 StackTraceWriter stackTraceWriter = new LegacyPojoStackTraceWriter( "test subystem", "no method", t );
117 StringBuilder stringBuilder = new StringBuilder();
118 ForkingRunListener.encode( stringBuilder, stackTraceWriter, false );
119 originalOut.println( ( (char) ForkingRunListener.BOOTERCODE_ERROR ) + ",0," + stringBuilder.toString() );
120 }
121
122 originalOut.println( ( (char) ForkingRunListener.BOOTERCODE_BYE ) + ",0,BYE!" );
123 originalOut.flush();
124
125 exit( 0 );
126 }
127 catch ( Throwable t )
128 {
129
130
131 t.printStackTrace( System.err );
132
133 exit( 1 );
134 }
135 }
136
137 private final static long SYSTEM_EXIT_TIMEOUT = 30 * 1000;
138
139 private static void exit( final int returnCode )
140 {
141 launchLastDitchDaemonShutdownThread( returnCode );
142 System.exit( returnCode );
143 }
144
145
146 private static RunResult runSuitesInProcess( Object testSet, StartupConfiguration startupConfiguration,
147 ProviderConfiguration providerConfiguration,
148 PrintStream originalSystemOut )
149 throws SurefireExecutionException, TestSetFailedException, InvocationTargetException
150 {
151 final ReporterFactory factory = createForkingReporterFactory( providerConfiguration, originalSystemOut );
152
153 return invokeProviderInSameClassLoader( testSet, factory, providerConfiguration, true, startupConfiguration,
154 false );
155 }
156
157 private static ReporterFactory createForkingReporterFactory( ProviderConfiguration providerConfiguration,
158 PrintStream originalSystemOut )
159 {
160 final Boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace();
161 return SurefireReflector.createForkingReporterFactoryInCurrentClassLoader( trimStackTrace, originalSystemOut );
162 }
163
164 private static void launchLastDitchDaemonShutdownThread( final int returnCode )
165 {
166 Thread lastExit = new Thread( new Runnable()
167 {
168 public void run()
169 {
170 try
171 {
172 Thread.sleep( SYSTEM_EXIT_TIMEOUT );
173 Runtime.getRuntime().halt( returnCode );
174 }
175 catch ( InterruptedException ignore )
176 {
177 }
178 }
179 } );
180 lastExit.setDaemon( true );
181 lastExit.start();
182 }
183
184 public static RunResult invokeProviderInSameClassLoader( Object testSet, Object factory,
185 ProviderConfiguration providerConfiguration,
186 boolean insideFork,
187 StartupConfiguration startupConfiguration1,
188 boolean restoreStreams )
189 throws TestSetFailedException, InvocationTargetException
190 {
191 final PrintStream orgSystemOut = System.out;
192 final PrintStream orgSystemErr = System.err;
193
194
195
196 final SurefireProvider provider =
197 createProviderInCurrentClassloader( startupConfiguration1, insideFork, providerConfiguration, factory );
198 try
199 {
200 return provider.invoke( testSet );
201 }
202 finally
203 {
204 if ( restoreStreams && System.getSecurityManager() == null )
205 {
206 System.setOut( orgSystemOut );
207 System.setErr( orgSystemErr );
208 }
209 }
210 }
211
212 public static SurefireProvider createProviderInCurrentClassloader( StartupConfiguration startupConfiguration1,
213 boolean isInsideFork,
214 ProviderConfiguration providerConfiguration,
215 Object reporterManagerFactory1 )
216 {
217
218 BaseProviderFactory bpf = new BaseProviderFactory( (ReporterFactory) reporterManagerFactory1, isInsideFork );
219 bpf.setTestRequest( providerConfiguration.getTestSuiteDefinition() );
220 bpf.setReporterConfiguration( providerConfiguration.getReporterConfiguration() );
221 ClassLoader clasLoader = Thread.currentThread().getContextClassLoader();
222 bpf.setClassLoaders( clasLoader );
223 bpf.setTestArtifactInfo( providerConfiguration.getTestArtifact() );
224 bpf.setProviderProperties( providerConfiguration.getProviderProperties() );
225 bpf.setRunOrderParameters( providerConfiguration.getRunOrderParameters() );
226 bpf.setDirectoryScannerParameters( providerConfiguration.getDirScannerParams() );
227 return (SurefireProvider) ReflectionUtils.instantiateOneArg( clasLoader,
228 startupConfiguration1.getActualClassName(),
229 ProviderParameters.class, bpf );
230 }
231 }