View Javadoc
1   package org.apache.maven.shared.invoker;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertFalse;
24  import static org.junit.Assert.assertTrue;
25  import static org.junit.Assert.fail;
26  
27  import java.io.File;
28  import java.io.FileWriter;
29  import java.io.IOException;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.HashSet;
34  import java.util.List;
35  import java.util.Properties;
36  import java.util.Set;
37  
38  import org.codehaus.plexus.util.FileUtils;
39  import org.codehaus.plexus.util.IOUtil;
40  import org.codehaus.plexus.util.Os;
41  import org.codehaus.plexus.util.cli.CommandLineException;
42  import org.codehaus.plexus.util.cli.Commandline;
43  import org.junit.After;
44  import org.junit.Assume;
45  import org.junit.Before;
46  import org.junit.Test;
47  
48  public class MavenCommandLineBuilderTest
49  {
50  
51      private List<File> toDelete = new ArrayList<File>();
52  
53      private Properties sysProps;
54  
55      @Test
56      public void testShouldFailToSetLocalRepoLocationGloballyWhenItIsAFile()
57          throws IOException
58      {
59          logTestStart();
60  
61          File lrd = File.createTempFile( "workdir-test", "file" ).getCanonicalFile();
62  
63          toDelete.add( lrd );
64  
65          TestCommandLineBuilder tcb = new TestCommandLineBuilder();
66          tcb.setLocalRepositoryDirectory( lrd );
67  
68          Commandline cli = new Commandline();
69  
70          try
71          {
72              tcb.setEnvironmentPaths( newRequest(), cli );
73              fail( "Should not set local repo location to point to a file." );
74          }
75          catch ( IllegalArgumentException e )
76          {
77              assertTrue( true );
78          }
79      }
80  
81      @Test
82      public void testShouldFailToSetLocalRepoLocationFromRequestWhenItIsAFile()
83          throws IOException
84      {
85          logTestStart();
86  
87          File lrd = File.createTempFile( "workdir-test", "file" ).getCanonicalFile();
88  
89          toDelete.add( lrd );
90  
91          TestCommandLineBuilder tcb = new TestCommandLineBuilder();
92  
93          Commandline cli = new Commandline();
94  
95          try
96          {
97              tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
98              fail( "Should not set local repo location to point to a file." );
99          }
100         catch ( IllegalArgumentException e )
101         {
102             assertTrue( true );
103         }
104     }
105 
106     @Test
107     public void testShouldSetLocalRepoLocationGlobally()
108         throws Exception
109     {
110         logTestStart();
111 
112         File tmpDir = getTempDir();
113 
114         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
115 
116         lrd.mkdirs();
117         toDelete.add( lrd );
118 
119         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
120         tcb.setLocalRepositoryDirectory( lrd );
121 
122         Commandline cli = new Commandline();
123 
124         tcb.setEnvironmentPaths( newRequest(), cli );
125 
126         assertArgumentsPresentInOrder( cli, "-D", "maven.repo.local=" + lrd.getPath() );
127     }
128 
129     @Test
130     public void testShouldSetLocalRepoLocationFromRequest()
131         throws Exception
132     {
133         logTestStart();
134 
135         File tmpDir = getTempDir();
136 
137         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
138 
139         lrd.mkdirs();
140         toDelete.add( lrd );
141 
142         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
143 
144         Commandline cli = new Commandline();
145 
146         tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
147 
148         assertArgumentsPresentInOrder( cli, "-D", "maven.repo.local=" + lrd.getPath() );
149     }
150 
151     @Test
152     public void testRequestProvidedLocalRepoLocationShouldOverrideGlobal()
153         throws Exception
154     {
155         logTestStart();
156 
157         File tmpDir = getTempDir();
158 
159         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
160         File glrd = new File( tmpDir, "global-workdir" ).getCanonicalFile();
161 
162         lrd.mkdirs();
163         glrd.mkdirs();
164 
165         toDelete.add( lrd );
166         toDelete.add( glrd );
167 
168         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
169         tcb.setLocalRepositoryDirectory( glrd );
170 
171         Commandline cli = new Commandline();
172 
173         tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
174 
175         assertArgumentsPresentInOrder( cli, "-D", "maven.repo.local=" + lrd.getPath() );
176     }
177 
178     @Test
179     public void testShouldSetWorkingDirectoryGlobally()
180         throws Exception
181     {
182         logTestStart();
183 
184         File tmpDir = getTempDir();
185 
186         File wd = new File( tmpDir, "workdir" );
187 
188         wd.mkdirs();
189 
190         toDelete.add( wd );
191 
192         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
193         tcb.setWorkingDirectory( wd );
194 
195         Commandline cli = new Commandline();
196 
197         tcb.setEnvironmentPaths( newRequest(), cli );
198 
199         assertEquals( cli.getWorkingDirectory(), wd );
200     }
201 
202     @Test
203     public void testShouldSetWorkingDirectoryFromRequest()
204         throws Exception
205     {
206         logTestStart();
207 
208         File tmpDir = getTempDir();
209 
210         File wd = new File( tmpDir, "workdir" );
211 
212         wd.mkdirs();
213 
214         toDelete.add( wd );
215 
216         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
217         InvocationRequest req = newRequest();
218         req.setBaseDirectory( wd );
219 
220         Commandline cli = new Commandline();
221 
222         tcb.setEnvironmentPaths( req, cli );
223 
224         assertEquals( cli.getWorkingDirectory(), wd );
225     }
226 
227     @Test
228     public void testRequestProvidedWorkingDirectoryShouldOverrideGlobal()
229         throws Exception
230     {
231         logTestStart();
232 
233         File tmpDir = getTempDir();
234 
235         File wd = new File( tmpDir, "workdir" );
236         File gwd = new File( tmpDir, "global-workdir" );
237 
238         wd.mkdirs();
239         gwd.mkdirs();
240 
241         toDelete.add( wd );
242         toDelete.add( gwd );
243 
244         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
245         tcb.setWorkingDirectory( gwd );
246 
247         InvocationRequest req = newRequest();
248         req.setBaseDirectory( wd );
249 
250         Commandline cli = new Commandline();
251 
252         tcb.setEnvironmentPaths( req, cli );
253 
254         assertEquals( cli.getWorkingDirectory(), wd );
255     }
256 
257     @Test
258     public void testShouldUseSystemOutLoggerWhenNoneSpecified()
259         throws Exception
260     {
261         logTestStart();
262         setupTempMavenHomeIfMissing( false );
263 
264         TestCommandLineBuilder tclb = new TestCommandLineBuilder();
265         tclb.checkRequiredState();
266     }
267 
268     private File setupTempMavenHomeIfMissing( boolean forceDummy )
269         throws Exception
270     {
271         String mavenHome = System.getProperty( "maven.home" );
272 
273         File appDir = null;
274 
275         if ( forceDummy || ( mavenHome == null ) || !new File( mavenHome ).exists() )
276         {
277             File tmpDir = getTempDir();
278             appDir = new File( tmpDir, "invoker-tests/maven-home" );
279 
280             File binDir = new File( appDir, "bin" );
281 
282             binDir.mkdirs();
283             toDelete.add( appDir );
284 
285             if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
286             {
287                 createDummyFile( binDir, "mvn.bat" );
288             }
289             else
290             {
291                 createDummyFile( binDir, "mvn" );
292             }
293 
294             Properties props = System.getProperties();
295             props.setProperty( "maven.home", appDir.getCanonicalPath() );
296 
297             System.setProperties( props );
298         }
299         else
300         {
301             appDir = new File( mavenHome );
302         }
303 
304         return appDir;
305     }
306 
307     @Test
308     public void testShouldFailIfLoggerSetToNull()
309     {
310         logTestStart();
311 
312         TestCommandLineBuilder tclb = new TestCommandLineBuilder();
313         tclb.setLogger( null );
314 
315         try
316         {
317             tclb.checkRequiredState();
318             fail( "Should not allow execution to proceed when logger is missing." );
319         }
320         catch ( IllegalStateException e )
321         {
322             assertTrue( true );
323         }
324         catch ( IOException e )
325         {
326             fail( e.getMessage() );
327         }
328     }
329 
330     @Test
331     public void testShouldFindDummyMavenExecutable()
332         throws Exception
333     {
334         logTestStart();
335 
336         File tmpDir = getTempDir();
337 
338         File base = new File( tmpDir, "invoker-tests" );
339 
340         File dummyMavenHomeBin = new File( base, "dummy-maven-home/bin" );
341 
342         dummyMavenHomeBin.mkdirs();
343 
344         toDelete.add( base );
345 
346         File check;
347         if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
348         {
349             check = createDummyFile( dummyMavenHomeBin, "mvn.bat" );
350         }
351         else
352         {
353             check = createDummyFile( dummyMavenHomeBin, "mvn" );
354         }
355 
356         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
357         tcb.setMavenHome( dummyMavenHomeBin.getParentFile() );
358 
359         File mavenExe = tcb.findMavenExecutable();
360 
361         assertEquals( check.getCanonicalPath(), mavenExe.getCanonicalPath() );
362     }
363 
364     @Test
365     public void testShouldSetBatchModeFlagFromRequest()
366     {
367         logTestStart();
368 
369         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
370         Commandline cli = new Commandline();
371 
372         tcb.setFlags( newRequest().setBatchMode( true ), cli );
373 
374         assertArgumentsPresent( cli, Collections.singleton( "-B" ) );
375     }
376 
377     @Test
378     public void testShouldSetOfflineFlagFromRequest()
379     {
380         logTestStart();
381 
382         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
383         Commandline cli = new Commandline();
384 
385         tcb.setFlags( newRequest().setOffline( true ), cli );
386 
387         assertArgumentsPresent( cli, Collections.singleton( "-o" ) );
388     }
389 
390     @Test
391     public void testShouldSetUpdateSnapshotsFlagFromRequest()
392     {
393         logTestStart();
394 
395         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
396         Commandline cli = new Commandline();
397 
398         tcb.setFlags( newRequest().setUpdateSnapshots( true ), cli );
399 
400         assertArgumentsPresent( cli, Collections.singleton( "-U" ) );
401     }
402 
403     @Test
404     public void testShouldSetDebugFlagFromRequest()
405     {
406         logTestStart();
407 
408         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
409         Commandline cli = new Commandline();
410 
411         tcb.setFlags( newRequest().setDebug( true ), cli );
412 
413         assertArgumentsPresent( cli, Collections.singleton( "-X" ) );
414     }
415 
416     @Test
417     public void testShouldSetErrorFlagFromRequest()
418     {
419         logTestStart();
420 
421         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
422         Commandline cli = new Commandline();
423 
424         tcb.setFlags( newRequest().setShowErrors( true ), cli );
425 
426         assertArgumentsPresent( cli, Collections.singleton( "-e" ) );
427     }
428 
429     @Test
430     public void testDebugOptionShouldMaskShowErrorsOption()
431     {
432         logTestStart();
433 
434         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
435         Commandline cli = new Commandline();
436 
437         tcb.setFlags( newRequest().setDebug( true ).setShowErrors( true ), cli );
438 
439         assertArgumentsPresent( cli, Collections.singleton( "-X" ) );
440         assertArgumentsNotPresent( cli, Collections.singleton( "-e" ) );
441     }
442 
443     @Test
444     public void testAlsoMake()
445     {
446         logTestStart();
447 
448         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
449         Commandline cli = new Commandline();
450 
451         tcb.setReactorBehavior( newRequest().setAlsoMake( true ), cli );
452 
453         // -am is only useful with -pl
454         assertArgumentsNotPresent( cli, Collections.singleton( "-am" ) );
455     }
456 
457     @Test
458     public void testProjectsAndAlsoMake()
459     {
460         logTestStart();
461 
462         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
463         Commandline cli = new Commandline();
464 
465         tcb.setReactorBehavior( newRequest().setProjects( Collections.singletonList( "proj1" ) ).setAlsoMake( true ),
466                                 cli );
467 
468         assertArgumentsPresentInOrder( cli, "-pl", "proj1", "-am" );
469     }
470 
471     @Test
472     public void testAlsoMakeDependents()
473     {
474         logTestStart();
475 
476         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
477         Commandline cli = new Commandline();
478 
479         tcb.setReactorBehavior( newRequest().setAlsoMakeDependents( true ), cli );
480 
481         // -amd is only useful with -pl
482         assertArgumentsNotPresent( cli, Collections.singleton( "-amd" ) );
483     }
484 
485     @Test
486     public void testProjectsAndAlsoMakeDependents()
487     {
488         logTestStart();
489 
490         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
491         Commandline cli = new Commandline();
492 
493         tcb.setReactorBehavior( newRequest().setProjects( Collections.singletonList( "proj1" ) ).setAlsoMakeDependents( true ),
494                                 cli );
495 
496         assertArgumentsPresentInOrder( cli, "-pl", "proj1", "-amd" );
497     }
498 
499     @Test
500     public void testProjectsAndAlsoMakeAndAlsoMakeDependents()
501     {
502         logTestStart();
503 
504         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
505         Commandline cli = new Commandline();
506 
507         tcb.setReactorBehavior( newRequest().setProjects( Collections.singletonList( "proj1" ) ).setAlsoMake( true ).setAlsoMakeDependents( true ),
508                                 cli );
509 
510         assertArgumentsPresentInOrder( cli, "-pl", "proj1", "-am", "-amd" );
511     }
512 
513     @Test
514     public void testShouldSetResumeFrom()
515     {
516         logTestStart();
517 
518         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
519         Commandline cli = new Commandline();
520 
521         tcb.setReactorBehavior( newRequest().setResumeFrom( ":module3" ), cli );
522 
523         assertArgumentsPresentInOrder( cli, "-rf", ":module3" );
524     }
525 
526     @Test
527     public void testShouldSetStrictChecksumPolityFlagFromRequest()
528     {
529         logTestStart();
530 
531         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
532         Commandline cli = new Commandline();
533 
534         tcb.setFlags( newRequest().setGlobalChecksumPolicy( InvocationRequest.CheckSumPolicy.Fail ), cli );
535 
536         assertArgumentsPresent( cli, Collections.singleton( "-C" ) );
537     }
538 
539     @Test
540     public void testShouldSetLaxChecksumPolicyFlagFromRequest()
541     {
542         logTestStart();
543 
544         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
545         Commandline cli = new Commandline();
546 
547         tcb.setFlags( newRequest().setGlobalChecksumPolicy( InvocationRequest.CheckSumPolicy.Warn ), cli );
548 
549         assertArgumentsPresent( cli, Collections.singleton( "-c" ) );
550     }
551 
552     @Test
553     public void testShouldSetFailAtEndFlagFromRequest()
554     {
555         logTestStart();
556 
557         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
558         Commandline cli = new Commandline();
559 
560         tcb.setReactorBehavior( newRequest().setReactorFailureBehavior( InvocationRequest.ReactorFailureBehavior.FailAtEnd ),
561                                 cli );
562 
563         assertArgumentsPresent( cli, Collections.singleton( "-fae" ) );
564     }
565 
566     @Test
567     public void testShouldSetFailNeverFlagFromRequest()
568     {
569         logTestStart();
570 
571         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
572         Commandline cli = new Commandline();
573 
574         tcb.setReactorBehavior( newRequest().setReactorFailureBehavior( InvocationRequest.ReactorFailureBehavior.FailNever ),
575                                 cli );
576 
577         assertArgumentsPresent( cli, Collections.singleton( "-fn" ) );
578     }
579 
580     @Test
581     public void testShouldUseDefaultOfFailFastWhenSpecifiedInRequest()
582     {
583         logTestStart();
584 
585         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
586         Commandline cli = new Commandline();
587 
588         tcb.setReactorBehavior( newRequest().setReactorFailureBehavior( InvocationRequest.ReactorFailureBehavior.FailFast ),
589                                 cli );
590 
591         Set<String> banned = new HashSet<String>();
592         banned.add( "-fae" );
593         banned.add( "-fn" );
594 
595         assertArgumentsNotPresent( cli, banned );
596     }
597 
598     @Test
599     public void testShouldSpecifyFileOptionUsingNonStandardPomFileLocation()
600         throws Exception
601     {
602         logTestStart();
603 
604         File tmpDir = getTempDir();
605         File base = new File( tmpDir, "invoker-tests" );
606 
607         toDelete.add( base );
608 
609         File projectDir = new File( base, "file-option-nonstd-pom-file-location" ).getCanonicalFile();
610 
611         projectDir.mkdirs();
612 
613         File pomFile = createDummyFile( projectDir, "non-standard-pom.xml" ).getCanonicalFile();
614 
615         Commandline cli = new Commandline();
616 
617         InvocationRequest req = newRequest().setPomFile( pomFile );
618 
619         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
620         tcb.setEnvironmentPaths( req, cli );
621         tcb.setPomLocation( req, cli );
622 
623         assertEquals( projectDir, cli.getWorkingDirectory() );
624 
625         Set<String> args = new HashSet<String>();
626         args.add( "-f" );
627         args.add( "non-standard-pom.xml" );
628 
629         assertArgumentsPresent( cli, args );
630     }
631 
632     @Test
633     public void testShouldSpecifyFileOptionUsingNonStandardPomInBasedir()
634         throws Exception
635     {
636         logTestStart();
637 
638         File tmpDir = getTempDir();
639         File base = new File( tmpDir, "invoker-tests" );
640 
641         toDelete.add( base );
642 
643         File projectDir = new File( base, "file-option-nonstd-basedir" ).getCanonicalFile();
644 
645         projectDir.mkdirs();
646 
647         File basedir = createDummyFile( projectDir, "non-standard-pom.xml" ).getCanonicalFile();
648 
649         Commandline cli = new Commandline();
650 
651         InvocationRequest req = newRequest().setBaseDirectory( basedir );
652 
653         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
654         tcb.setEnvironmentPaths( req, cli );
655         tcb.setPomLocation( req, cli );
656 
657         assertEquals( projectDir, cli.getWorkingDirectory() );
658 
659         Set<String> args = new HashSet<String>();
660         args.add( "-f" );
661         args.add( "non-standard-pom.xml" );
662 
663         assertArgumentsPresent( cli, args );
664     }
665 
666     @Test
667     public void testShouldNotSpecifyFileOptionUsingStandardPomFileLocation()
668         throws Exception
669     {
670         logTestStart();
671 
672         File tmpDir = getTempDir();
673         File base = new File( tmpDir, "invoker-tests" );
674 
675         toDelete.add( base );
676 
677         File projectDir = new File( base, "std-pom-file-location" ).getCanonicalFile();
678 
679         projectDir.mkdirs();
680 
681         File pomFile = createDummyFile( projectDir, "pom.xml" ).getCanonicalFile();
682 
683         Commandline cli = new Commandline();
684 
685         InvocationRequest req = newRequest().setPomFile( pomFile );
686 
687         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
688         tcb.setEnvironmentPaths( req, cli );
689         tcb.setPomLocation( req, cli );
690 
691         assertEquals( projectDir, cli.getWorkingDirectory() );
692 
693         Set<String> args = new HashSet<String>();
694         args.add( "-f" );
695         args.add( "pom.xml" );
696 
697         assertArgumentsNotPresent( cli, args );
698     }
699 
700     @Test
701     public void testShouldNotSpecifyFileOptionUsingStandardPomInBasedir()
702         throws Exception
703     {
704         logTestStart();
705 
706         File tmpDir = getTempDir();
707         File base = new File( tmpDir, "invoker-tests" );
708 
709         toDelete.add( base );
710 
711         File projectDir = new File( base, "std-basedir-is-pom-file" ).getCanonicalFile();
712 
713         projectDir.mkdirs();
714 
715         File basedir = createDummyFile( projectDir, "pom.xml" ).getCanonicalFile();
716 
717         Commandline cli = new Commandline();
718 
719         InvocationRequest req = newRequest().setBaseDirectory( basedir );
720 
721         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
722         tcb.setEnvironmentPaths( req, cli );
723         tcb.setPomLocation( req, cli );
724 
725         assertEquals( projectDir, cli.getWorkingDirectory() );
726 
727         Set<String> args = new HashSet<String>();
728         args.add( "-f" );
729         args.add( "pom.xml" );
730 
731         assertArgumentsNotPresent( cli, args );
732     }
733 
734     @Test
735     public void testShouldUseDefaultPomFileWhenBasedirSpecifiedWithoutPomFileName()
736         throws Exception
737     {
738         logTestStart();
739 
740         File tmpDir = getTempDir();
741         File base = new File( tmpDir, "invoker-tests" );
742 
743         toDelete.add( base );
744 
745         File projectDir = new File( base, "std-basedir-no-pom-filename" ).getCanonicalFile();
746 
747         projectDir.mkdirs();
748 
749         Commandline cli = new Commandline();
750 
751         InvocationRequest req = newRequest().setBaseDirectory( projectDir );
752 
753         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
754         tcb.setEnvironmentPaths( req, cli );
755         tcb.setPomLocation( req, cli );
756 
757         assertEquals( projectDir, cli.getWorkingDirectory() );
758 
759         Set<String> args = new HashSet<String>();
760         args.add( "-f" );
761         args.add( "pom.xml" );
762 
763         assertArgumentsNotPresent( cli, args );
764     }
765 
766     @Test
767     public void testShouldSpecifyPomFileWhenBasedirSpecifiedWithPomFileName()
768         throws Exception
769     {
770         logTestStart();
771 
772         File tmpDir = getTempDir();
773         File base = new File( tmpDir, "invoker-tests" );
774 
775         toDelete.add( base );
776 
777         File projectDir = new File( base, "std-basedir-with-pom-filename" ).getCanonicalFile();
778 
779         projectDir.mkdirs();
780 
781         Commandline cli = new Commandline();
782 
783         InvocationRequest req = newRequest().setBaseDirectory( projectDir ).setPomFileName( "non-standard-pom.xml" );
784 
785         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
786         tcb.setEnvironmentPaths( req, cli );
787         tcb.setPomLocation( req, cli );
788 
789         assertEquals( projectDir, cli.getWorkingDirectory() );
790 
791         Set<String> args = new HashSet<String>();
792         args.add( "-f" );
793         args.add( "non-standard-pom.xml" );
794 
795         assertArgumentsPresent( cli, args );
796     }
797 
798     @Test
799     public void testShouldSpecifyCustomUserSettingsLocationFromRequest()
800         throws Exception
801     {
802         logTestStart();
803 
804         File tmpDir = getTempDir();
805         File base = new File( tmpDir, "invoker-tests" );
806 
807         toDelete.add( base );
808 
809         File projectDir = new File( base, "custom-settings" ).getCanonicalFile();
810 
811         projectDir.mkdirs();
812 
813         File settingsFile = createDummyFile( projectDir, "settings.xml" );
814 
815         Commandline cli = new Commandline();
816 
817         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
818         tcb.setSettingsLocation( newRequest().setUserSettingsFile( settingsFile ), cli );
819 
820         Set<String> args = new HashSet<String>();
821         args.add( "-s" );
822         args.add( settingsFile.getCanonicalPath() );
823 
824         assertArgumentsPresent( cli, args );
825     }
826 
827     @Test
828     public void testShouldSpecifyCustomGlobalSettingsLocationFromRequest()
829         throws Exception
830     {
831         logTestStart();
832 
833         File tmpDir = getTempDir();
834         File base = new File( tmpDir, "invoker-tests" );
835 
836         toDelete.add( base );
837 
838         File projectDir = new File( base, "custom-settings" ).getCanonicalFile();
839 
840         projectDir.mkdirs();
841 
842         File settingsFile = createDummyFile( projectDir, "settings.xml" );
843 
844         Commandline cli = new Commandline();
845 
846         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
847         tcb.setSettingsLocation( newRequest().setGlobalSettingsFile( settingsFile ), cli );
848 
849         Set<String> args = new HashSet<String>();
850         args.add( "-gs" );
851         args.add( settingsFile.getCanonicalPath() );
852 
853         assertArgumentsPresent( cli, args );
854     }
855 
856     @Test
857     public void testShouldSpecifyCustomToolchainsLocationFromRequest()
858         throws Exception
859     {
860         logTestStart();
861 
862         File tmpDir = getTempDir();
863         File base = new File( tmpDir, "invoker-tests" );
864 
865         toDelete.add( base );
866 
867         File projectDir = new File( base, "custom-toolchains" ).getCanonicalFile();
868 
869         projectDir.mkdirs();
870 
871         File toolchainsFile = createDummyFile( projectDir, "toolchains.xml" );
872 
873         Commandline cli = new Commandline();
874 
875         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
876         tcb.setToolchainsLocation( newRequest().setToolchainsFile( toolchainsFile ), cli );
877 
878         Set<String> args = new HashSet<String>();
879         args.add( "-t" );
880         args.add( toolchainsFile.getCanonicalPath() );
881 
882         assertArgumentsPresent( cli, args );
883     }
884 
885     @Test
886     public void testShouldSpecifyCustomPropertyFromRequest()
887         throws IOException
888     {
889         logTestStart();
890 
891         Commandline cli = new Commandline();
892 
893         Properties properties = new Properties();
894         properties.setProperty( "key", "value" );
895 
896         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
897         tcb.setProperties( newRequest().setProperties( properties ), cli );
898 
899         assertArgumentsPresentInOrder( cli, "-D", "key=value" );
900     }
901 
902     @Test
903     public void testShouldSpecifyCustomPropertyWithSpacesInValueFromRequest()
904         throws IOException
905     {
906         logTestStart();
907 
908         Commandline cli = new Commandline();
909 
910         Properties properties = new Properties();
911         properties.setProperty( "key", "value with spaces" );
912 
913         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
914         tcb.setProperties( newRequest().setProperties( properties ), cli );
915 
916         assertArgumentsPresentInOrder( cli, "-D", "key=value with spaces" );
917     }
918 
919     @Test
920     public void testShouldSpecifyCustomPropertyWithSpacesInKeyFromRequest()
921         throws IOException
922     {
923         logTestStart();
924 
925         Commandline cli = new Commandline();
926 
927         Properties properties = new Properties();
928         properties.setProperty( "key with spaces", "value with spaces" );
929 
930         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
931         tcb.setProperties( newRequest().setProperties( properties ), cli );
932 
933         assertArgumentsPresentInOrder( cli, "-D", "key with spaces=value with spaces" );
934     }
935 
936     @Test
937     public void testShouldSpecifySingleGoalFromRequest()
938         throws IOException
939     {
940         logTestStart();
941 
942         Commandline cli = new Commandline();
943 
944         List<String> goals = new ArrayList<String>();
945         goals.add( "test" );
946 
947         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
948         tcb.setGoals( newRequest().setGoals( goals ), cli );
949 
950         assertArgumentsPresent( cli, Collections.singleton( "test" ) );
951     }
952 
953     @Test
954     public void testShouldSpecifyTwoGoalsFromRequest()
955         throws IOException
956     {
957         logTestStart();
958 
959         Commandline cli = new Commandline();
960 
961         List<String> goals = new ArrayList<String>();
962         goals.add( "test" );
963         goals.add( "clean" );
964 
965         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
966         tcb.setGoals( newRequest().setGoals( goals ), cli );
967 
968         assertArgumentsPresent( cli, new HashSet<String>( goals ) );
969         assertArgumentsPresentInOrder( cli, goals );
970     }
971 
972     @Test
973     public void testShouldSpecifyThreadsFromRequest()
974         throws IOException
975     {
976         logTestStart();
977 
978         Commandline cli = new Commandline();
979 
980         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
981         tcb.setThreads( newRequest().setThreads( "2.0C" ), cli );
982 
983         assertArgumentsPresentInOrder( cli, "-T", "2.0C" );
984     }
985 
986     @Test
987     public void testBuildTypicalMavenInvocationEndToEnd()
988         throws Exception
989     {
990         logTestStart();
991         File mavenDir = setupTempMavenHomeIfMissing( false );
992 
993         InvocationRequest request = newRequest();
994 
995         File tmpDir = getTempDir();
996         File projectDir = new File( tmpDir, "invoker-tests/typical-end-to-end-cli-build" );
997 
998         projectDir.mkdirs();
999         toDelete.add( projectDir.getParentFile() );
1000 
1001         request.setBaseDirectory( projectDir );
1002 
1003         Set<String> expectedArgs = new HashSet<String>();
1004         Set<String> bannedArgs = new HashSet<String>();
1005 
1006         createDummyFile( projectDir, "pom.xml" );
1007 
1008         bannedArgs.add( "-f" );
1009         bannedArgs.add( "pom.xml" );
1010 
1011         Properties properties = new Properties();
1012         // this is REALLY bad practice, but since it's just a test...
1013         properties.setProperty( "maven.tests.skip", "true" );
1014 
1015         expectedArgs.add( "maven.tests.skip=true" );
1016 
1017         request.setProperties( properties );
1018 
1019         request.setOffline( true );
1020 
1021         expectedArgs.add( "-o" );
1022 
1023         List<String> goals = new ArrayList<String>();
1024 
1025         goals.add( "post-clean" );
1026         goals.add( "deploy" );
1027         goals.add( "site-deploy" );
1028 
1029         request.setGoals( goals );
1030 
1031         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1032 
1033         Commandline commandline = commandLineBuilder.build( request );
1034 
1035         assertArgumentsPresent( commandline, expectedArgs );
1036         assertArgumentsNotPresent( commandline, bannedArgs );
1037         assertArgumentsPresentInOrder( commandline, goals );
1038 
1039         String executable = commandline.getExecutable();
1040 
1041         assertTrue( executable.indexOf( new File( mavenDir, "bin/mvn" ).getCanonicalPath() ) > -1 );
1042         assertEquals( projectDir.getCanonicalPath(), commandline.getWorkingDirectory().getCanonicalPath() );
1043     }
1044 
1045     @Test
1046     public void testShouldSetEnvVar_MAVEN_TERMINATE_CMD()
1047         throws Exception
1048     {
1049         logTestStart();
1050         setupTempMavenHomeIfMissing( false );
1051 
1052         InvocationRequest request = newRequest();
1053 
1054         File tmpDir = getTempDir();
1055         File projectDir = new File( tmpDir, "invoker-tests/maven-terminate-cmd-options-set" );
1056 
1057         projectDir.mkdirs();
1058         toDelete.add( projectDir.getParentFile() );
1059 
1060         request.setBaseDirectory( projectDir );
1061 
1062         createDummyFile( projectDir, "pom.xml" );
1063 
1064         List<String> goals = new ArrayList<String>();
1065 
1066         goals.add( "clean" );
1067         request.setGoals( goals );
1068 
1069         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1070 
1071         Commandline commandline = commandLineBuilder.build( request );
1072 
1073         String[] environmentVariables = commandline.getEnvironmentVariables();
1074         String envVarMavenTerminateCmd = null;
1075         for ( int i = 0; i < environmentVariables.length; i++ )
1076         {
1077             String envVar = environmentVariables[i];
1078             if ( envVar.startsWith( "MAVEN_TERMINATE_CMD=" ) )
1079             {
1080                 envVarMavenTerminateCmd = envVar;
1081                 break;
1082             }
1083         }
1084         assertEquals( "MAVEN_TERMINATE_CMD=on", envVarMavenTerminateCmd );
1085 
1086     }
1087 
1088     @Test
1089     public void testShouldInsertActivatedProfiles()
1090         throws Exception
1091     {
1092         setupTempMavenHomeIfMissing( false );
1093 
1094         String profile1 = "profile-1";
1095         String profile2 = "profile-2";
1096 
1097         InvocationRequest request = newRequest();
1098 
1099         List<String> profiles = new ArrayList<String>();
1100         profiles.add( profile1 );
1101         profiles.add( profile2 );
1102 
1103         request.setProfiles( profiles );
1104 
1105         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1106 
1107         Commandline commandline = commandLineBuilder.build( request );
1108 
1109         assertArgumentsPresentInOrder( commandline, "-P", profile1 + "," + profile2 );
1110     }
1111 
1112     @Test
1113     public void testShouldSetEnvVar_M2_HOME()
1114         throws Exception
1115     {
1116         Assume.assumeNotNull( System.getenv( "M2_HOME" ) );
1117 
1118         logTestStart();
1119         setupTempMavenHomeIfMissing( true );
1120 
1121         InvocationRequest request = newRequest();
1122 
1123         File tmpDir = getTempDir();
1124         File projectDir = new File( tmpDir, "invoker-tests/maven-terminate-cmd-options-set" );
1125 
1126         projectDir.mkdirs();
1127         toDelete.add( projectDir.getParentFile() );
1128 
1129         request.setBaseDirectory( projectDir );
1130 
1131         createDummyFile( projectDir, "pom.xml" );
1132 
1133         List<String> goals = new ArrayList<String>();
1134 
1135         goals.add( "clean" );
1136         request.setGoals( goals );
1137 
1138         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1139         File mavenHome2 = new File( System.getProperty( "maven.home" ) );
1140         commandLineBuilder.setMavenHome( mavenHome2 );
1141 
1142         Commandline commandline = commandLineBuilder.build( request );
1143 
1144         String[] environmentVariables = commandline.getEnvironmentVariables();
1145         String m2Home = null;
1146         for ( int i = 0; i < environmentVariables.length; i++ )
1147         {
1148             String envVar = environmentVariables[i];
1149             if ( envVar.startsWith( "M2_HOME=" ) )
1150             {
1151                 m2Home = envVar;
1152             }
1153         }
1154         assertEquals( "M2_HOME=" + mavenHome2.getAbsolutePath(), m2Home );
1155     }
1156 
1157     @Test
1158     public void testMvnCommand()
1159         throws Exception
1160     {
1161         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1162         File mavenExecutable = new File( "mvnDebug" );
1163         commandLineBuilder.setMavenExecutable( mavenExecutable );
1164         File executable = commandLineBuilder.findMavenExecutable();
1165         assertTrue( "Expected executable to exist", executable.exists() );
1166         assertTrue( "Expected executable to be absolute", executable.isAbsolute() );
1167     }
1168 
1169     @Test
1170     public void testAddShellEnvironment()
1171         throws Exception
1172     {
1173         setupTempMavenHomeIfMissing( false );
1174 
1175         InvocationRequest request = newRequest();
1176 
1177         String envVar1Name = "VAR-1";
1178         String envVar1Value = "VAR-1-VALUE";
1179 
1180         String envVar2Name = "VAR-2";
1181         String envVar2Value = "VAR-2-VALUE";
1182 
1183         request.addShellEnvironment( envVar1Name, envVar1Value );
1184         request.addShellEnvironment( envVar2Name, envVar2Value );
1185 
1186         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
1187 
1188         Commandline commandline = commandLineBuilder.build( request );
1189 
1190         assertEnvironmentVariablePresent( commandline, envVar1Name, envVar1Value );
1191         assertEnvironmentVariablePresent( commandline, envVar2Name, envVar2Value );
1192     }
1193 
1194     @Before
1195     public void setUp()
1196     {
1197         sysProps = System.getProperties();
1198 
1199         Properties p = new Properties( sysProps );
1200 
1201         System.setProperties( p );
1202     }
1203 
1204     @After
1205     public void tearDown()
1206         throws IOException
1207     {
1208         System.setProperties( sysProps );
1209 
1210         for ( File file : toDelete )
1211         {
1212             if ( file.exists() )
1213             {
1214                 if ( file.isDirectory() )
1215                 {
1216                     FileUtils.deleteDirectory( file );
1217                 }
1218                 else
1219                 {
1220                     file.delete();
1221                 }
1222             }
1223         }
1224     }
1225 
1226     // this is just a debugging helper for separating unit test output...
1227     private void logTestStart()
1228     {
1229         NullPointerException npe = new NullPointerException();
1230         StackTraceElement element = npe.getStackTrace()[1];
1231 
1232         System.out.println( "Starting: " + element.getMethodName() );
1233     }
1234 
1235     private void assertEnvironmentVariablePresent( Commandline cli, String varName, String varValue )
1236         throws CommandLineException
1237     {
1238         List<String> environmentVariables = Arrays.asList( cli.getEnvironmentVariables() );
1239 
1240         String expectedDeclaration = varName + "=" + varValue;
1241 
1242         assertTrue( "Environment variable setting: \'" + expectedDeclaration + "\' is mssing in "
1243             + environmentVariables, environmentVariables.contains( expectedDeclaration ) );
1244     }
1245 
1246     private void assertArgumentsPresentInOrder( Commandline cli, String... expected )
1247     {
1248         assertArgumentsPresentInOrder( cli, Arrays.asList( expected ) );
1249     }
1250 
1251     private void assertArgumentsPresentInOrder( Commandline cli, List<String> expected )
1252     {
1253         String[] arguments = cli.getArguments();
1254 
1255         int expectedCounter = 0;
1256 
1257         for ( int i = 0; i < arguments.length; i++ )
1258         {
1259             if ( arguments[i].equals( expected.get( expectedCounter ) ) )
1260             {
1261                 expectedCounter++;
1262             }
1263         }
1264 
1265         assertEquals( "Arguments: " + expected + " were not found or are in the wrong order: "
1266             + Arrays.asList( arguments ), expected.size(), expectedCounter );
1267     }
1268 
1269     private void assertArgumentsPresent( Commandline cli, Set<String> requiredArgs )
1270     {
1271         String[] argv = cli.getArguments();
1272         List<String> args = Arrays.asList( argv );
1273 
1274         for ( String arg : requiredArgs )
1275         {
1276             assertTrue( "Command-line argument: \'" + arg + "\' is missing in " + args, args.contains( arg ) );
1277         }
1278     }
1279 
1280     private void assertArgumentsNotPresent( Commandline cli, Set<String> bannedArgs )
1281     {
1282         String[] argv = cli.getArguments();
1283         List<String> args = Arrays.asList( argv );
1284 
1285         for ( String arg : bannedArgs )
1286         {
1287             assertFalse( "Command-line argument: \'" + arg + "\' should not be present.", args.contains( arg ) );
1288         }
1289     }
1290 
1291     private File createDummyFile( File directory, String filename )
1292         throws IOException
1293     {
1294         File dummyFile = new File( directory, filename );
1295 
1296         FileWriter writer = null;
1297         try
1298         {
1299             writer = new FileWriter( dummyFile );
1300             writer.write( "This is a dummy file." );
1301         }
1302         finally
1303         {
1304             IOUtil.close( writer );
1305         }
1306 
1307         toDelete.add( dummyFile );
1308 
1309         return dummyFile;
1310     }
1311 
1312     private static final class TestCommandLineBuilder
1313         extends MavenCommandLineBuilder
1314     {
1315         public void checkRequiredState()
1316             throws IOException
1317         {
1318             super.checkRequiredState();
1319         }
1320 
1321         public File findMavenExecutable()
1322             throws CommandLineConfigurationException, IOException
1323         {
1324             return super.findMavenExecutable();
1325         }
1326 
1327         public void setEnvironmentPaths( InvocationRequest request, Commandline cli )
1328         {
1329             super.setEnvironmentPaths( request, cli );
1330         }
1331 
1332         public void setFlags( InvocationRequest request, Commandline cli )
1333         {
1334             super.setFlags( request, cli );
1335         }
1336 
1337         public void setGoals( InvocationRequest request, Commandline cli )
1338         {
1339             super.setGoals( request, cli );
1340         }
1341 
1342         public void setPomLocation( InvocationRequest request, Commandline cli )
1343         {
1344             super.setPomLocation( request, cli );
1345         }
1346 
1347         public void setProperties( InvocationRequest request, Commandline cli )
1348         {
1349             super.setProperties( request, cli );
1350         }
1351 
1352         public void setReactorBehavior( InvocationRequest request, Commandline cli )
1353         {
1354             super.setReactorBehavior( request, cli );
1355         }
1356 
1357         public void setSettingsLocation( InvocationRequest request, Commandline cli )
1358         {
1359             super.setSettingsLocation( request, cli );
1360         }
1361 
1362         public void setShellEnvironment( InvocationRequest request, Commandline cli )
1363             throws CommandLineConfigurationException
1364         {
1365             super.setShellEnvironment( request, cli );
1366         }
1367 
1368     }
1369 
1370     private File getTempDir()
1371         throws Exception
1372     {
1373         return new File( System.getProperty( "java.io.tmpdir" ) ).getCanonicalFile();
1374     }
1375 
1376     private InvocationRequest newRequest()
1377     {
1378         return new DefaultInvocationRequest();
1379     }
1380 
1381 }