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