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