1 package org.apache.maven.surefire.its.fixture;
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.IOException;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import org.apache.commons.lang.text.StrSubstitutor;
30 import org.apache.maven.it.VerificationException;
31 import org.apache.maven.it.Verifier;
32 import org.apache.maven.it.util.ResourceExtractor;
33 import org.apache.maven.shared.utils.io.FileUtils;
34
35
36
37
38
39
40
41 public class MavenLauncher
42 {
43 private final List<String> cliOptions = new ArrayList<String>();
44
45 private final List<String> goals = new ArrayList<String>();
46
47 private final Map<String, String> envvars = new HashMap<String, String>();
48
49 private File unpackedAt;
50
51 private Verifier verifier;
52
53 private OutputValidator validator;
54
55 private final Class testCaseBeingRun;
56
57 private final String resourceName;
58
59 private final String suffix;
60
61 private boolean expectFailure;
62
63 public MavenLauncher( Class testClass, String resourceName, String suffix )
64 {
65 this.testCaseBeingRun = testClass;
66 this.resourceName = resourceName;
67 this.suffix = suffix != null ? suffix : "";
68 resetGoals();
69 resetCliOptions();
70 }
71
72 public File getUnpackedAt()
73 {
74 return ensureUnpacked();
75 }
76
77 private File ensureUnpacked()
78 {
79 if ( unpackedAt == null )
80 {
81 unpackedAt = simpleExtractResources( testCaseBeingRun, resourceName );
82 }
83 return unpackedAt;
84 }
85
86 public void moveUnpackTo( File dest )
87 throws IOException
88 {
89 FileUtils.deleteDirectory( dest );
90
91 getUnpackedAt().renameTo( dest );
92 unpackedAt = dest;
93 }
94
95 public void resetGoals()
96 {
97 goals.clear();
98 }
99
100 void addCliOption( String cliOption )
101 {
102 cliOptions.add( cliOption );
103 }
104
105
106
107 private StackTraceElement findTopElemenent( StackTraceElement[] stackTrace, Class testClassToLookFor )
108 {
109 StackTraceElement bestmatch = null;
110 for ( StackTraceElement stackTraceElement : stackTrace )
111 {
112 if ( stackTraceElement.getClassName().equals( testClassToLookFor.getName() ) )
113 {
114 bestmatch = stackTraceElement;
115 }
116 }
117 return bestmatch;
118 }
119
120 StackTraceElement[] getStackTraceElements()
121 {
122 try
123 {
124 throw new RuntimeException();
125 }
126 catch ( RuntimeException e )
127 {
128 return e.getStackTrace();
129 }
130 }
131
132 public void reset()
133 {
134 resetGoals();
135 resetCliOptions();
136 }
137
138 private void resetCliOptions()
139 {
140 cliOptions.clear();
141 }
142
143 public MavenLauncher getSubProjectLauncher( String subProject )
144 throws VerificationException
145 {
146 MavenLauncher mavenLauncher =
147 new MavenLauncher( testCaseBeingRun, resourceName + File.separator + subProject, suffix );
148 mavenLauncher.unpackedAt = new File( ensureUnpacked(), subProject );
149 return mavenLauncher;
150 }
151
152 public OutputValidator getSubProjectValidator( String subProject )
153 throws VerificationException
154 {
155 final File subFile = getValidator().getSubFile( subProject );
156 return new OutputValidator( new Verifier( subFile.getAbsolutePath() ) );
157 }
158
159
160 public MavenLauncher addEnvVar( String key, String value )
161 {
162 envvars.put( key, value );
163 return this;
164 }
165
166 public MavenLauncher assertNotPresent( String subFile )
167 {
168 getVerifier().assertFileNotPresent( getValidator().getSubFile( subFile ).getAbsolutePath() );
169 return this;
170 }
171
172 public MavenLauncher showErrorStackTraces()
173 {
174 addCliOption( "-e" );
175 return this;
176 }
177
178 public MavenLauncher debugLogging()
179 {
180 addCliOption( "-X" );
181 return this;
182 }
183
184 public MavenLauncher failNever()
185 {
186 addCliOption( "-fn" );
187 return this;
188 }
189
190 public MavenLauncher offline()
191 {
192 addCliOption( "-o" );
193 return this;
194 }
195
196 public MavenLauncher skipClean()
197 {
198 goals.add( "-Dclean.skip=true" );
199 return this;
200 }
201
202 public MavenLauncher addGoal( String goal )
203 {
204 goals.add( goal );
205 return this;
206 }
207
208 public FailsafeOutputValidator executeVerify()
209 {
210 return new FailsafeOutputValidator( conditionalExec( "verify" ) );
211 }
212
213 public OutputValidator executeTest()
214 {
215 return conditionalExec( "test" );
216 }
217
218 private OutputValidator conditionalExec(String goal)
219 {
220 OutputValidator verify;
221 try
222 {
223 verify = execute( goal );
224 }
225 catch ( SurefireVerifierException exc )
226 {
227 if ( expectFailure )
228 {
229 return getValidator();
230 }
231 else
232 {
233 throw exc;
234 }
235 }
236 if ( expectFailure )
237 {
238 throw new RuntimeException( "Expecting build failure, got none!" );
239 }
240 return verify;
241
242 }
243
244 public MavenLauncher withFailure()
245 {
246 this.expectFailure = true;
247 return this;
248 }
249
250
251 public OutputValidator execute( String goal )
252 {
253 addGoal( goal );
254 return executeCurrentGoals();
255 }
256
257 public OutputValidator executeCurrentGoals()
258 {
259
260 String userLocalRepo = System.getProperty( "user.localRepository" );
261 String testBuildDirectory = System.getProperty( "testBuildDirectory" );
262 boolean useInterpolatedSettings = Boolean.getBoolean( "useInterpolatedSettings" );
263
264 try
265 {
266 if ( useInterpolatedSettings )
267 {
268 File interpolatedSettings = new File( testBuildDirectory, "interpolated-settings" );
269
270 if ( !interpolatedSettings.exists() )
271 {
272
273
274
275 Map<String, String> values = new HashMap<String, String>( 1 );
276 values.put( "localRepositoryUrl", toUrl( userLocalRepo ) );
277 StrSubstitutor strSubstitutor = new StrSubstitutor( values );
278
279 String fileContent = FileUtils.fileRead( new File( testBuildDirectory, "settings.xml" ) );
280
281 String filtered = strSubstitutor.replace( fileContent );
282
283 FileUtils.fileWrite( interpolatedSettings.getAbsolutePath(), filtered );
284
285 }
286
287 addCliOption( "-s " + interpolatedSettings.getCanonicalPath() );
288 }
289 getVerifier().setCliOptions( cliOptions );
290
291 getVerifier().executeGoals( goals, envvars );
292 return getValidator();
293 }
294 catch ( IOException e )
295 {
296 throw new SurefireVerifierException( e.getMessage(), e );
297 }
298 catch ( VerificationException e )
299 {
300 throw new SurefireVerifierException( e.getMessage(), e );
301 }
302 finally
303 {
304 getVerifier().resetStreams();
305 }
306 }
307
308 private static String toUrl( String filename )
309 {
310
311
312
313
314 String url = "file://" + new File( filename ).toURI().getPath();
315 if ( url.endsWith( "/" ) )
316 {
317 url = url.substring( 0, url.length() - 1 );
318 }
319 return url;
320 }
321
322 public MavenLauncher activateProfile( String profile )
323 {
324 return addGoal( "-P" + profile );
325 }
326
327 public MavenLauncher sysProp( String variable, String value )
328 {
329 return addGoal( "-D" + variable + "=" + value );
330 }
331
332 public MavenLauncher sysProp( String variable, boolean value )
333 {
334 return addGoal( "-D" + variable + "=" + value );
335 }
336
337 public MavenLauncher sysProp( String variable, int value )
338 {
339 return addGoal( "-D" + variable + "=" + value );
340 }
341
342 public MavenLauncher showExceptionMessages()
343 {
344 addCliOption( "-e" );
345 return this;
346 }
347
348 public MavenLauncher deleteSiteDir()
349 {
350 try
351 {
352 FileUtils.deleteDirectory( getValidator().getSubFile( "site" ) );
353 }
354 catch ( IOException e )
355 {
356 throw new SurefireVerifierException( e );
357 }
358 return this;
359 }
360
361 public OutputValidator getValidator()
362 {
363 if ( validator == null )
364 {
365 this.validator = new OutputValidator( getVerifier() );
366 }
367 return validator;
368 }
369
370 public void setForkJvm( boolean forkJvm ) {
371 getVerifier().setForkJvm( forkJvm );
372 }
373
374 private Verifier getVerifier()
375 {
376 if ( verifier == null )
377 {
378 try
379 {
380 this.verifier = new Verifier( ensureUnpacked().getAbsolutePath() );
381 }
382 catch ( VerificationException e )
383 {
384 throw new RuntimeException( e );
385 }
386 }
387 return verifier;
388 }
389
390 private File simpleExtractResources( Class<?> cl, String resourcePath )
391 {
392 if ( !resourcePath.startsWith( "/" ) )
393 {
394 resourcePath = "/" + resourcePath;
395 }
396 File tempDir = getUnpackDir();
397 File testDir = new File( tempDir, resourcePath );
398 try
399 {
400 File parentPom = new File( tempDir.getParentFile(), "pom.xml" );
401 if (!parentPom.exists()){
402 URL resource = cl.getResource( "/pom.xml" );
403 FileUtils.copyURLToFile( resource, parentPom );
404 }
405
406 FileUtils.deleteDirectory( testDir );
407 File file = ResourceExtractor.extractResourceToDestination( cl, resourcePath, tempDir, true );
408 return file.getCanonicalFile();
409 }
410 catch ( IOException e )
411 {
412 throw new RuntimeException( e );
413 }
414
415 }
416
417 File getUnpackDir()
418 {
419 String tempDirPath = System.getProperty( "maven.test.tmpdir", System.getProperty( "java.io.tmpdir" ) );
420 return new File( tempDirPath,
421 testCaseBeingRun.getSimpleName() + "_" + getTestMethodName() + suffix );
422 }
423
424 public File getArtifactPath( String gid, String aid, String version, String ext )
425 {
426 return new File( verifier.getArtifactPath( gid, aid, version, ext ) );
427 }
428
429 String getTestMethodName()
430 {
431
432 StackTraceElement[] stackTrace = getStackTraceElements();
433 StackTraceElement topInTestClass;
434 topInTestClass = findTopElemenent( stackTrace, testCaseBeingRun );
435 if ( topInTestClass == null )
436 {
437
438 topInTestClass = findTopElemenent( stackTrace, testCaseBeingRun.getSuperclass() );
439 }
440 if ( topInTestClass != null )
441 {
442 return topInTestClass.getMethodName();
443 }
444 throw new IllegalStateException( "Cannot find " + testCaseBeingRun.getName() + "in stacktrace" );
445 }
446 }