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