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 )
113 + ",0," + stringBuilder.toString() );
114 }
115 catch ( Throwable t )
116 {
117 StackTraceWriter stackTraceWriter = new LegacyPojoStackTraceWriter( "test subystem", "no method", t );
118 StringBuilder stringBuilder = new StringBuilder();
119 ForkingRunListener.encode( stringBuilder, stackTraceWriter, false );
120 originalOut.println( ( (char) ForkingRunListener.BOOTERCODE_ERROR )
121 + ",0," + stringBuilder.toString() );
122 }
123
124 originalOut.println( ( (char) ForkingRunListener.BOOTERCODE_BYE ) + ",0,BYE!" );
125 originalOut.flush();
126
127 exit( 0 );
128 }
129 catch ( Throwable t )
130 {
131
132
133 t.printStackTrace( System.err );
134
135 exit( 1 );
136 }
137 }
138
139 private static final long SYSTEM_EXIT_TIMEOUT = 30 * 1000;
140
141 private static void exit( final int returnCode )
142 {
143 launchLastDitchDaemonShutdownThread( returnCode );
144 System.exit( returnCode );
145 }
146
147
148 private static RunResult runSuitesInProcess( Object testSet, StartupConfiguration startupConfiguration,
149 ProviderConfiguration providerConfiguration,
150 PrintStream originalSystemOut )
151 throws SurefireExecutionException, TestSetFailedException, InvocationTargetException
152 {
153 final ReporterFactory factory = createForkingReporterFactory( providerConfiguration, originalSystemOut );
154
155 return invokeProviderInSameClassLoader( testSet, factory, providerConfiguration, true, startupConfiguration,
156 false );
157 }
158
159 private static ReporterFactory createForkingReporterFactory( ProviderConfiguration providerConfiguration,
160 PrintStream originalSystemOut )
161 {
162 final Boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace();
163 return SurefireReflector.createForkingReporterFactoryInCurrentClassLoader( trimStackTrace, originalSystemOut );
164 }
165
166 @SuppressWarnings( "checkstyle:emptyblock" )
167 private static void launchLastDitchDaemonShutdownThread( final int returnCode )
168 {
169 Thread lastExit = new Thread( new Runnable()
170 {
171 public void run()
172 {
173 try
174 {
175 Thread.sleep( SYSTEM_EXIT_TIMEOUT );
176 Runtime.getRuntime().halt( returnCode );
177 }
178 catch ( InterruptedException ignore )
179 {
180 }
181 }
182 } );
183 lastExit.setDaemon( true );
184 lastExit.start();
185 }
186
187 public static RunResult invokeProviderInSameClassLoader( Object testSet, Object factory,
188 ProviderConfiguration providerConfiguration,
189 boolean insideFork,
190 StartupConfiguration startupConfiguration1,
191 boolean restoreStreams )
192 throws TestSetFailedException, InvocationTargetException
193 {
194 final PrintStream orgSystemOut = System.out;
195 final PrintStream orgSystemErr = System.err;
196
197
198
199 final SurefireProvider provider =
200 createProviderInCurrentClassloader( startupConfiguration1, insideFork, providerConfiguration, factory );
201 try
202 {
203 return provider.invoke( testSet );
204 }
205 finally
206 {
207 if ( restoreStreams && System.getSecurityManager() == null )
208 {
209 System.setOut( orgSystemOut );
210 System.setErr( orgSystemErr );
211 }
212 }
213 }
214
215 public static SurefireProvider createProviderInCurrentClassloader( StartupConfiguration startupConfiguration1,
216 boolean isInsideFork,
217 ProviderConfiguration providerConfiguration,
218 Object reporterManagerFactory1 )
219 {
220
221 BaseProviderFactory bpf = new BaseProviderFactory( (ReporterFactory) reporterManagerFactory1, isInsideFork );
222 bpf.setTestRequest( providerConfiguration.getTestSuiteDefinition() );
223 bpf.setReporterConfiguration( providerConfiguration.getReporterConfiguration() );
224 ClassLoader clasLoader = Thread.currentThread().getContextClassLoader();
225 bpf.setClassLoaders( clasLoader );
226 bpf.setTestArtifactInfo( providerConfiguration.getTestArtifact() );
227 bpf.setProviderProperties( providerConfiguration.getProviderProperties() );
228 bpf.setRunOrderParameters( providerConfiguration.getRunOrderParameters() );
229 bpf.setDirectoryScannerParameters( providerConfiguration.getDirScannerParams() );
230 return (SurefireProvider) ReflectionUtils.instantiateOneArg( clasLoader,
231 startupConfiguration1.getActualClassName(),
232 ProviderParameters.class, bpf );
233 }
234 }