1 package org.apache.maven.it;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.ByteArrayOutputStream;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileNotFoundException;
27 import java.io.FileReader;
28 import java.io.FileWriter;
29 import java.io.FilenameFilter;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.InputStreamReader;
33 import java.io.PrintStream;
34 import java.io.Writer;
35 import java.net.MalformedURLException;
36 import java.net.URL;
37 import java.text.DecimalFormat;
38 import java.text.NumberFormat;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Collections;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Properties;
46 import java.util.StringTokenizer;
47 import java.util.regex.Pattern;
48
49 import javax.xml.parsers.ParserConfigurationException;
50 import javax.xml.parsers.SAXParser;
51 import javax.xml.parsers.SAXParserFactory;
52
53 import junit.framework.Assert;
54
55 import org.apache.maven.shared.utils.StringUtils;
56 import org.apache.maven.shared.utils.cli.CommandLineException;
57 import org.apache.maven.shared.utils.cli.CommandLineUtils;
58 import org.apache.maven.shared.utils.cli.Commandline;
59 import org.apache.maven.shared.utils.cli.StreamConsumer;
60 import org.apache.maven.shared.utils.cli.WriterStreamConsumer;
61 import org.apache.maven.shared.utils.io.FileUtils;
62 import org.apache.maven.shared.utils.io.IOUtil;
63 import org.xml.sax.InputSource;
64 import org.xml.sax.SAXException;
65 import org.xml.sax.SAXParseException;
66 import org.xml.sax.helpers.DefaultHandler;
67
68
69
70
71
72
73
74 public class Verifier
75 {
76 private static final String LOG_FILENAME = "log.txt";
77
78 private static final String[] DEFAULT_CLI_OPTIONS = {"-e", "--batch-mode"};
79
80 private String localRepo;
81
82 private final String basedir;
83
84 private final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
85
86 private final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
87
88 private final String[] defaultCliOptions;
89
90 private PrintStream originalOut;
91
92 private PrintStream originalErr;
93
94 private List<String> cliOptions = new ArrayList<String>();
95
96 private Properties systemProperties = new Properties();
97
98 private Map<String, String> environmentVariables = new HashMap<String, String>();
99
100 private Properties verifierProperties = new Properties();
101
102 private boolean autoclean = true;
103
104 private String localRepoLayout = "default";
105
106 private boolean debug;
107
108 private Boolean forkJvm;
109
110 private String logFileName = LOG_FILENAME;
111
112 private String defaultMavenHome;
113
114 private String defaultClassworldConf;
115
116 private String defaultClasspath;
117
118
119 private boolean mavenDebug = false;
120
121 private String forkMode;
122
123 private boolean debugJvm = false;
124
125 private static MavenLauncher embeddedLauncher;
126
127 public Verifier( String basedir )
128 throws VerificationException
129 {
130 this( basedir, null );
131 }
132
133 public Verifier( String basedir, boolean debug )
134 throws VerificationException
135 {
136 this( basedir, null, debug );
137 }
138
139 public Verifier( String basedir, String settingsFile )
140 throws VerificationException
141 {
142 this( basedir, settingsFile, false );
143 }
144
145 public Verifier( String basedir, String settingsFile, boolean debug )
146 throws VerificationException
147 {
148 this( basedir, settingsFile, debug, DEFAULT_CLI_OPTIONS );
149 }
150
151 public Verifier( String basedir, String settingsFile, boolean debug, String[] defaultCliOptions )
152 throws VerificationException
153 {
154 this( basedir, settingsFile, debug, null, defaultCliOptions );
155 }
156
157 public Verifier( String basedir, String settingsFile, boolean debug, boolean forkJvm )
158 throws VerificationException
159 {
160 this( basedir, settingsFile, debug, forkJvm, DEFAULT_CLI_OPTIONS );
161 }
162
163 public Verifier( String basedir, String settingsFile, boolean debug, boolean forkJvm, String[] defaultCliOptions )
164 throws VerificationException
165 {
166 this( basedir, settingsFile, debug, (Boolean) forkJvm, defaultCliOptions );
167 }
168
169 private Verifier( String basedir, String settingsFile, boolean debug, Boolean forkJvm, String[] defaultCliOptions )
170 throws VerificationException
171 {
172 this.basedir = basedir;
173
174 this.forkJvm = forkJvm;
175 this.forkMode = System.getProperty( "verifier.forkMode" );
176
177 if ( !debug )
178 {
179 originalOut = System.out;
180
181 originalErr = System.err;
182 }
183
184 setDebug( debug );
185
186 findLocalRepo( settingsFile );
187 findDefaultMavenHome();
188
189 if ( StringUtils.isEmpty( defaultMavenHome ) && StringUtils.isEmpty( forkMode ) )
190 {
191 forkMode = "auto";
192 }
193
194 this.defaultCliOptions = defaultCliOptions == null ? new String[0] : defaultCliOptions.clone();
195 }
196
197 private void findDefaultMavenHome()
198 throws VerificationException
199 {
200 defaultClasspath = System.getProperty( "maven.bootclasspath" );
201 defaultClassworldConf = System.getProperty( "classworlds.conf" );
202 defaultMavenHome = System.getProperty( "maven.home" );
203
204 if ( defaultMavenHome == null )
205 {
206 Properties envVars = CommandLineUtils.getSystemEnvVars();
207 defaultMavenHome = envVars.getProperty( "M2_HOME" );
208 }
209
210 if ( defaultMavenHome == null )
211 {
212 File f = new File( System.getProperty( "user.home" ), "m2" );
213 if ( new File( f, "bin/mvn" ).isFile() )
214 {
215 defaultMavenHome = f.getAbsolutePath();
216 }
217 }
218 }
219
220 public void setLocalRepo( String localRepo )
221 {
222 this.localRepo = localRepo;
223 }
224
225 public void resetStreams()
226 {
227 if ( !debug )
228 {
229 System.setOut( originalOut );
230
231 System.setErr( originalErr );
232 }
233 }
234
235 public void displayStreamBuffers()
236 {
237 String out = outStream.toString();
238
239 if ( out != null && out.trim().length() > 0 )
240 {
241 System.out.println( "----- Standard Out -----" );
242
243 System.out.println( out );
244 }
245
246 String err = errStream.toString();
247
248 if ( err != null && err.trim().length() > 0 )
249 {
250 System.err.println( "----- Standard Error -----" );
251
252 System.err.println( err );
253 }
254 }
255
256
257
258
259
260 public void verify( boolean chokeOnErrorOutput )
261 throws VerificationException
262 {
263 List<String> lines = loadFile( getBasedir(), "expected-results.txt", false );
264
265 for ( String line : lines )
266 {
267 verifyExpectedResult( line );
268 }
269
270 if ( chokeOnErrorOutput )
271 {
272 verifyErrorFreeLog();
273 }
274 }
275
276 public void verifyErrorFreeLog()
277 throws VerificationException
278 {
279 List<String> lines = loadFile( getBasedir(), getLogFileName(), false );
280
281 for ( String line : lines )
282 {
283
284 if ( line.contains( "[ERROR]" ) && !isVelocityError( line ) )
285 {
286 throw new VerificationException( "Error in execution: " + line );
287 }
288 }
289 }
290
291
292
293
294
295
296
297
298 private static boolean isVelocityError( String line )
299 {
300 return line.contains( "VM_global_library.vm" ) || line.contains( "VM #" ) && line.contains( "macro" );
301 }
302
303
304
305
306
307
308
309 public void verifyTextInLog( String text )
310 throws VerificationException
311 {
312 List<String> lines = loadFile( getBasedir(), getLogFileName(), false );
313
314 boolean result = false;
315 for ( String line : lines )
316 {
317 if ( line.contains( text ) )
318 {
319 result = true;
320 break;
321 }
322 }
323 if ( !result )
324 {
325 throw new VerificationException( "Text not found in log: " + text );
326 }
327 }
328
329 public Properties loadProperties( String filename )
330 throws VerificationException
331 {
332 Properties properties = new Properties();
333
334 try
335 {
336 File propertiesFile = new File( getBasedir(), filename );
337 if ( propertiesFile.exists() )
338 {
339 FileInputStream fis = new FileInputStream( propertiesFile );
340 try
341 {
342 properties.load( fis );
343 }
344 finally
345 {
346 fis.close();
347 }
348 }
349 }
350 catch ( FileNotFoundException e )
351 {
352 throw new VerificationException( "Error reading properties file", e );
353 }
354 catch ( IOException e )
355 {
356 throw new VerificationException( "Error reading properties file", e );
357 }
358
359 return properties;
360 }
361
362
363
364
365
366
367
368
369
370
371
372 public List<String> loadLines( String filename, String encoding )
373 throws IOException
374 {
375 List<String> lines = new ArrayList<String>();
376
377 File file = new File( getBasedir(), filename );
378
379 BufferedReader reader = null;
380 try
381 {
382 if ( StringUtils.isNotEmpty( encoding ) )
383 {
384 reader = new BufferedReader( new InputStreamReader( new FileInputStream( file ), encoding ) );
385 }
386 else
387 {
388 reader = new BufferedReader( new FileReader( file ) );
389 }
390
391 String line;
392 while ( ( line = reader.readLine() ) != null )
393 {
394 if ( line.length() > 0 )
395 {
396 lines.add( line );
397 }
398 }
399 }
400 finally
401 {
402 IOUtil.close( reader );
403 }
404
405 return lines;
406 }
407
408 public List<String> loadFile( String basedir, String filename, boolean hasCommand )
409 throws VerificationException
410 {
411 return loadFile( new File( basedir, filename ), hasCommand );
412 }
413
414 public List<String> loadFile( File file, boolean hasCommand )
415 throws VerificationException
416 {
417 List<String> lines = new ArrayList<String>();
418
419 BufferedReader reader = null;
420
421 if ( file.exists() )
422 {
423 try
424 {
425 reader = new BufferedReader( new FileReader( file ) );
426
427 String line = reader.readLine();
428
429 while ( line != null )
430 {
431 line = line.trim();
432
433 if ( !line.startsWith( "#" ) && line.length() != 0 )
434 {
435 lines.addAll( replaceArtifacts( line, hasCommand ) );
436 }
437 line = reader.readLine();
438 }
439
440 reader.close();
441 }
442 catch ( FileNotFoundException e )
443 {
444 throw new VerificationException( e );
445 }
446 catch ( IOException e )
447 {
448 throw new VerificationException( e );
449 }
450 finally
451 {
452 IOUtil.close( reader );
453 }
454 }
455
456 return lines;
457 }
458
459 private static final String MARKER = "${artifact:";
460
461 private List<String> replaceArtifacts( String line, boolean hasCommand )
462 {
463 int index = line.indexOf( MARKER );
464 if ( index >= 0 )
465 {
466 String newLine = line.substring( 0, index );
467 index = line.indexOf( "}", index );
468 if ( index < 0 )
469 {
470 throw new IllegalArgumentException( "line does not contain ending artifact marker: '" + line + "'" );
471 }
472 String artifact = line.substring( newLine.length() + MARKER.length(), index );
473
474 newLine += getArtifactPath( artifact );
475 newLine += line.substring( index + 1 );
476
477 List<String> l = new ArrayList<String>();
478 l.add( newLine );
479
480 int endIndex = newLine.lastIndexOf( '/' );
481
482 String command = null;
483 String filespec;
484 if ( hasCommand )
485 {
486 int startIndex = newLine.indexOf( ' ' );
487
488 command = newLine.substring( 0, startIndex );
489
490 filespec = newLine.substring( startIndex + 1, endIndex );
491 }
492 else
493 {
494 filespec = newLine;
495 }
496
497 File dir = new File( filespec );
498 addMetadataToList( dir, hasCommand, l, command );
499 addMetadataToList( dir.getParentFile(), hasCommand, l, command );
500
501 return l;
502 }
503 else
504 {
505 return Collections.singletonList( line );
506 }
507 }
508
509 private static void addMetadataToList( File dir, boolean hasCommand, List<String> l, String command )
510 {
511 if ( dir.exists() && dir.isDirectory() )
512 {
513 String[] files = dir.list( new FilenameFilter()
514 {
515 public boolean accept( File dir, String name )
516 {
517 return name.startsWith( "maven-metadata" ) && name.endsWith( ".xml" );
518
519 }
520 } );
521
522 for ( String file : files )
523 {
524 if ( hasCommand )
525 {
526 l.add( command + " " + new File( dir, file ).getPath() );
527 }
528 else
529 {
530 l.add( new File( dir, file ).getPath() );
531 }
532 }
533 }
534 }
535
536 private String getArtifactPath( String artifact )
537 {
538 StringTokenizer tok = new StringTokenizer( artifact, ":" );
539 if ( tok.countTokens() != 4 )
540 {
541 throw new IllegalArgumentException( "Artifact must have 4 tokens: '" + artifact + "'" );
542 }
543
544 String[] a = new String[4];
545 for ( int i = 0; i < 4; i++ )
546 {
547 a[i] = tok.nextToken();
548 }
549
550 String org = a[0];
551 String name = a[1];
552 String version = a[2];
553 String ext = a[3];
554 return getArtifactPath( org, name, version, ext );
555 }
556
557 public String getArtifactPath( String org, String name, String version, String ext )
558 {
559 return getArtifactPath( org, name, version, ext, null );
560 }
561
562
563
564
565
566
567
568
569
570
571
572
573 public String getArtifactPath( String gid, String aid, String version, String ext, String classifier )
574 {
575 if ( classifier != null && classifier.length() == 0 )
576 {
577 classifier = null;
578 }
579 if ( "maven-plugin".equals( ext ) )
580 {
581 ext = "jar";
582 }
583 if ( "coreit-artifact".equals( ext ) )
584 {
585 ext = "jar";
586 classifier = "it";
587 }
588 if ( "test-jar".equals( ext ) )
589 {
590 ext = "jar";
591 classifier = "tests";
592 }
593
594 String repositoryPath;
595 if ( "legacy".equals( localRepoLayout ) )
596 {
597 repositoryPath = gid + "/" + ext + "s/" + aid + "-" + version + "." + ext;
598 }
599 else if ( "default".equals( localRepoLayout ) )
600 {
601 repositoryPath = gid.replace( '.', '/' );
602 repositoryPath = repositoryPath + "/" + aid + "/" + version;
603 repositoryPath = repositoryPath + "/" + aid + "-" + version;
604 if ( classifier != null )
605 {
606 repositoryPath = repositoryPath + "-" + classifier;
607 }
608 repositoryPath = repositoryPath + "." + ext;
609 }
610 else
611 {
612 throw new IllegalStateException( "Unknown layout: " + localRepoLayout );
613 }
614
615 return localRepo + "/" + repositoryPath;
616 }
617
618 public List<String> getArtifactFileNameList( String org, String name, String version, String ext )
619 {
620 List<String> files = new ArrayList<String>();
621 String artifactPath = getArtifactPath( org, name, version, ext );
622 File dir = new File( artifactPath );
623 files.add( artifactPath );
624 addMetadataToList( dir, false, files, null );
625 addMetadataToList( dir.getParentFile(), false, files, null );
626 return files;
627 }
628
629
630
631
632
633
634
635
636
637
638 public String getArtifactMetadataPath( String gid, String aid, String version )
639 {
640 return getArtifactMetadataPath( gid, aid, version, "maven-metadata-local.xml" );
641 }
642
643
644
645
646
647
648
649
650
651
652
653 public String getArtifactMetadataPath( String gid, String aid, String version, String filename )
654 {
655 StringBuilder buffer = new StringBuilder( 256 );
656
657 buffer.append( localRepo );
658 buffer.append( '/' );
659
660 if ( "default".equals( localRepoLayout ) )
661 {
662 buffer.append( gid.replace( '.', '/' ) );
663 buffer.append( '/' );
664
665 if ( aid != null )
666 {
667 buffer.append( aid );
668 buffer.append( '/' );
669
670 if ( version != null )
671 {
672 buffer.append( version );
673 buffer.append( '/' );
674 }
675 }
676
677 buffer.append( filename );
678 }
679 else
680 {
681 throw new IllegalStateException( "Unsupported repository layout: " + localRepoLayout );
682 }
683
684 return buffer.toString();
685 }
686
687
688
689
690
691
692
693
694
695 public String getArtifactMetadataPath( String gid, String aid )
696 {
697 return getArtifactMetadataPath( gid, aid, null );
698 }
699
700 public void executeHook( String filename )
701 throws VerificationException
702 {
703 try
704 {
705 File f = new File( getBasedir(), filename );
706
707 if ( !f.exists() )
708 {
709 return;
710 }
711
712 List<String> lines = loadFile( f, true );
713
714 for ( String line1 : lines )
715 {
716 String line = resolveCommandLineArg( line1 );
717
718 executeCommand( line );
719 }
720 }
721 catch ( VerificationException e )
722 {
723 throw e;
724 }
725 catch ( Exception e )
726 {
727 throw new VerificationException( e );
728 }
729 }
730
731 private void executeCommand( String line )
732 throws VerificationException
733 {
734 int index = line.indexOf( " " );
735
736 String cmd;
737
738 String args = null;
739
740 if ( index >= 0 )
741 {
742 cmd = line.substring( 0, index );
743
744 args = line.substring( index + 1 );
745 }
746 else
747 {
748 cmd = line;
749 }
750
751 if ( "rm".equals( cmd ) )
752 {
753 System.out.println( "Removing file: " + args );
754
755 File f = new File( args );
756
757 if ( f.exists() && !f.delete() )
758 {
759 throw new VerificationException( "Error removing file - delete failed" );
760 }
761 }
762 else if ( "rmdir".equals( cmd ) )
763 {
764 System.out.println( "Removing directory: " + args );
765
766 try
767 {
768 File f = new File( args );
769
770 FileUtils.deleteDirectory( f );
771 }
772 catch ( IOException e )
773 {
774 throw new VerificationException( "Error removing directory - delete failed" );
775 }
776 }
777 else if ( "svn".equals( cmd ) )
778 {
779 launchSubversion( line, getBasedir() );
780 }
781 else
782 {
783 throw new VerificationException( "unknown command: " + cmd );
784 }
785 }
786
787 public static void launchSubversion( String line, String basedir )
788 throws VerificationException
789 {
790 try
791 {
792 Commandline cli = new Commandline( line );
793
794 cli.setWorkingDirectory( basedir );
795
796 Writer logWriter = new FileWriter( new File( basedir, LOG_FILENAME ) );
797
798 StreamConsumer out = new WriterStreamConsumer( logWriter );
799
800 StreamConsumer err = new WriterStreamConsumer( logWriter );
801
802 System.out.println( "Command: " + CommandLineUtils.toString( cli.getCommandline() ) );
803
804 int ret = CommandLineUtils.executeCommandLine( cli, out, err );
805
806 logWriter.close();
807
808 if ( ret > 0 )
809 {
810 System.err.println( "Exit code: " + ret );
811
812 throw new VerificationException();
813 }
814 }
815 catch ( CommandLineException e )
816 {
817 throw new VerificationException( e );
818 }
819 catch ( IOException e )
820 {
821 throw new VerificationException( e );
822 }
823 }
824
825 private static String retrieveLocalRepo( String settingsXmlPath )
826 throws VerificationException
827 {
828 UserModelReader userModelReader = new UserModelReader();
829
830 String userHome = System.getProperty( "user.home" );
831
832 File userXml;
833
834 String repo = null;
835
836 if ( settingsXmlPath != null )
837 {
838 System.out.println( "Using settings from " + settingsXmlPath );
839 userXml = new File( settingsXmlPath );
840 }
841 else
842 {
843 userXml = new File( userHome, ".m2/settings.xml" );
844 }
845
846 if ( userXml.exists() )
847 {
848 userModelReader.parse( userXml );
849
850 String localRepository = userModelReader.getLocalRepository();
851 if ( localRepository != null )
852 {
853 repo = new File( localRepository ).getAbsolutePath();
854 }
855 }
856
857 return repo;
858 }
859
860 public void deleteArtifact( String org, String name, String version, String ext )
861 throws IOException
862 {
863 List<String> files = getArtifactFileNameList( org, name, version, ext );
864 for ( String fileName : files )
865 {
866 FileUtils.forceDelete( new File( fileName ) );
867 }
868 }
869
870
871
872
873
874
875
876
877 public void deleteArtifacts( String gid )
878 throws IOException
879 {
880 String path;
881 if ( "default".equals( localRepoLayout ) )
882 {
883 path = gid.replace( '.', '/' );
884 }
885 else if ( "legacy".equals( localRepoLayout ) )
886 {
887 path = gid;
888 }
889 else
890 {
891 throw new IllegalStateException( "Unsupported repository layout: " + localRepoLayout );
892 }
893
894 FileUtils.deleteDirectory( new File( localRepo, path ) );
895 }
896
897
898
899
900
901
902
903
904
905
906 public void deleteArtifacts( String gid, String aid, String version )
907 throws IOException
908 {
909 String path;
910 if ( "default".equals( localRepoLayout ) )
911 {
912 path = gid.replace( '.', '/' ) + '/' + aid + '/' + version;
913 }
914 else
915 {
916 throw new IllegalStateException( "Unsupported repository layout: " + localRepoLayout );
917 }
918
919 FileUtils.deleteDirectory( new File( localRepo, path ) );
920 }
921
922
923
924
925
926
927
928
929 public void deleteDirectory( String path )
930 throws IOException
931 {
932 FileUtils.deleteDirectory( new File( getBasedir(), path ) );
933 }
934
935
936
937
938
939
940
941
942
943 public void writeFile( String path, String contents )
944 throws IOException
945 {
946 FileUtils.fileWrite( new File( getBasedir(), path ).getAbsolutePath(), "UTF-8", contents );
947 }
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963 public File filterFile( String srcPath, String dstPath, String fileEncoding, Map<String, String> filterProperties )
964 throws IOException
965 {
966 File srcFile = new File( getBasedir(), srcPath );
967 String data = FileUtils.fileRead( srcFile, fileEncoding );
968
969 for ( String token : filterProperties.keySet() )
970 {
971 String value = String.valueOf( filterProperties.get( token ) );
972 data = StringUtils.replace( data, token, value );
973 }
974
975 File dstFile = new File( getBasedir(), dstPath );
976
977 dstFile.getParentFile().mkdirs();
978 FileUtils.fileWrite( dstFile.getPath(), fileEncoding, data );
979
980 return dstFile;
981 }
982
983
984
985
986
987
988
989 @SuppressWarnings( { "rawtypes", "unchecked" } )
990 public File filterFile( String srcPath, String dstPath, String fileEncoding, Properties filterProperties )
991 throws IOException
992 {
993 return filterFile( srcPath, dstPath, fileEncoding, (Map) filterProperties );
994 }
995
996
997
998
999
1000
1001
1002
1003 public Properties newDefaultFilterProperties()
1004 {
1005 Properties filterProperties = new Properties();
1006
1007 String basedir = new File( getBasedir() ).getAbsolutePath();
1008 filterProperties.put( "@basedir@", basedir );
1009
1010
1011
1012
1013
1014 String baseurl = basedir;
1015 if ( !baseurl.startsWith( "/" ) )
1016 {
1017 baseurl = '/' + baseurl;
1018 }
1019 baseurl = "file://" + baseurl.replace( '\\', '/' );
1020 filterProperties.put( "@baseurl@", baseurl );
1021
1022 return filterProperties;
1023 }
1024
1025 public void assertFilePresent( String file )
1026 {
1027 try
1028 {
1029 verifyExpectedResult( file, true );
1030 }
1031 catch ( VerificationException e )
1032 {
1033 Assert.fail( e.getMessage() );
1034 }
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 public void assertFileMatches( String file, String regex )
1046 {
1047 assertFilePresent( file );
1048 try
1049 {
1050 String content = FileUtils.fileRead( file );
1051 if ( !Pattern.matches( regex, content ) )
1052 {
1053 Assert.fail( "Content of " + file + " does not match " + regex );
1054 }
1055 }
1056 catch ( IOException e )
1057 {
1058 Assert.fail( e.getMessage() );
1059 }
1060 }
1061
1062 public void assertFileNotPresent( String file )
1063 {
1064 try
1065 {
1066 verifyExpectedResult( file, false );
1067 }
1068 catch ( VerificationException e )
1069 {
1070 Assert.fail( e.getMessage() );
1071 }
1072 }
1073
1074 private void verifyArtifactPresence( boolean wanted, String org, String name, String version, String ext )
1075 {
1076 List<String> files = getArtifactFileNameList( org, name, version, ext );
1077 for ( String fileName : files )
1078 {
1079 try
1080 {
1081 verifyExpectedResult( fileName, wanted );
1082 }
1083 catch ( VerificationException e )
1084 {
1085 Assert.fail( e.getMessage() );
1086 }
1087 }
1088 }
1089
1090 public void assertArtifactPresent( String org, String name, String version, String ext )
1091 {
1092 verifyArtifactPresence( true, org, name, version, ext );
1093 }
1094
1095 public void assertArtifactNotPresent( String org, String name, String version, String ext )
1096 {
1097 verifyArtifactPresence( false, org, name, version, ext );
1098 }
1099
1100 private void verifyExpectedResult( String line )
1101 throws VerificationException
1102 {
1103 boolean wanted = true;
1104 if ( line.startsWith( "!" ) )
1105 {
1106 line = line.substring( 1 );
1107 wanted = false;
1108 }
1109
1110 verifyExpectedResult( line, wanted );
1111 }
1112
1113 private void verifyExpectedResult( String line, boolean wanted )
1114 throws VerificationException
1115 {
1116 if ( line.indexOf( "!/" ) > 0 )
1117 {
1118 String urlString = "jar:file:" + getBasedir() + "/" + line;
1119
1120 InputStream is = null;
1121 try
1122 {
1123 URL url = new URL( urlString );
1124
1125 is = url.openStream();
1126
1127 if ( is == null )
1128 {
1129 if ( wanted )
1130 {
1131 throw new VerificationException( "Expected JAR resource was not found: " + line );
1132 }
1133 }
1134 else
1135 {
1136 if ( !wanted )
1137 {
1138 throw new VerificationException( "Unwanted JAR resource was found: " + line );
1139 }
1140 }
1141 }
1142 catch ( MalformedURLException e )
1143 {
1144 throw new VerificationException( "Error looking for JAR resource", e );
1145 }
1146 catch ( IOException e )
1147 {
1148 if ( wanted )
1149 {
1150 throw new VerificationException( "Error looking for JAR resource: " + line );
1151 }
1152 }
1153 finally
1154 {
1155 if ( is != null )
1156 {
1157 try
1158 {
1159 is.close();
1160 }
1161 catch ( IOException e )
1162 {
1163 System.err.println( "WARN: error closing stream: " + e );
1164 }
1165 }
1166 }
1167 }
1168 else
1169 {
1170 File expectedFile = new File( line );
1171
1172
1173 if ( !expectedFile.isAbsolute() && !expectedFile.getPath().startsWith( File.separator ) )
1174 {
1175 expectedFile = new File( getBasedir(), line );
1176 }
1177
1178 if ( line.indexOf( '*' ) > -1 )
1179 {
1180 File parent = expectedFile.getParentFile();
1181
1182 if ( !parent.exists() )
1183 {
1184 if ( wanted )
1185 {
1186 throw new VerificationException(
1187 "Expected file pattern was not found: " + expectedFile.getPath() );
1188 }
1189 }
1190 else
1191 {
1192 String shortNamePattern = expectedFile.getName().replaceAll( "\\*", ".*" );
1193
1194 String[] candidates = parent.list();
1195
1196 boolean found = false;
1197
1198 if ( candidates != null )
1199 {
1200 for ( String candidate : candidates )
1201 {
1202 if ( candidate.matches( shortNamePattern ) )
1203 {
1204 found = true;
1205 break;
1206 }
1207 }
1208 }
1209
1210 if ( !found && wanted )
1211 {
1212 throw new VerificationException(
1213 "Expected file pattern was not found: " + expectedFile.getPath() );
1214 }
1215 else if ( found && !wanted )
1216 {
1217 throw new VerificationException( "Unwanted file pattern was found: " + expectedFile.getPath() );
1218 }
1219 }
1220 }
1221 else
1222 {
1223 if ( !expectedFile.exists() )
1224 {
1225 if ( wanted )
1226 {
1227 throw new VerificationException( "Expected file was not found: " + expectedFile.getPath() );
1228 }
1229 }
1230 else
1231 {
1232 if ( !wanted )
1233 {
1234 throw new VerificationException( "Unwanted file was found: " + expectedFile.getPath() );
1235 }
1236 }
1237 }
1238 }
1239 }
1240
1241
1242
1243
1244
1245 public void executeGoal( String goal )
1246 throws VerificationException
1247 {
1248 executeGoal( goal, environmentVariables );
1249 }
1250
1251 public void executeGoal( String goal, Map<String, String> envVars )
1252 throws VerificationException
1253 {
1254 executeGoals( Arrays.asList( goal ), envVars );
1255 }
1256
1257 public void executeGoals( List<String> goals )
1258 throws VerificationException
1259 {
1260 executeGoals( goals, environmentVariables );
1261 }
1262
1263 public String getExecutable()
1264 {
1265
1266
1267
1268 String mavenHome = defaultMavenHome;
1269
1270 if ( mavenHome != null )
1271 {
1272 return mavenHome + "/bin/mvn";
1273 }
1274 else
1275 {
1276 File f = new File( System.getProperty( "user.home" ), "m2/bin/mvn" );
1277
1278 if ( f.exists() )
1279 {
1280 return f.getAbsolutePath();
1281 }
1282 else
1283 {
1284 return "mvn";
1285 }
1286 }
1287 }
1288
1289 public void executeGoals( List<String> goals, Map<String, String> envVars )
1290 throws VerificationException
1291 {
1292 List<String> allGoals = new ArrayList<String>();
1293
1294 if ( autoclean )
1295 {
1296
1297
1298
1299 allGoals.add( "org.apache.maven.plugins:maven-clean-plugin:clean" );
1300 }
1301
1302 allGoals.addAll( goals );
1303
1304 List<String> args = new ArrayList<String>();
1305
1306 int ret;
1307
1308 File logFile = new File( getBasedir(), getLogFileName() );
1309
1310 for ( Object cliOption : cliOptions )
1311 {
1312 String key = String.valueOf( cliOption );
1313
1314 String resolvedArg = resolveCommandLineArg( key );
1315
1316 try
1317 {
1318 args.addAll( Arrays.asList( CommandLineUtils.translateCommandline( resolvedArg ) ) );
1319 }
1320 catch ( Exception e )
1321 {
1322 e.printStackTrace();
1323 }
1324 }
1325
1326 Collections.addAll( args, defaultCliOptions );
1327
1328 if ( this.mavenDebug )
1329 {
1330 args.add( "--debug" );
1331 }
1332
1333
1334
1335
1336
1337
1338
1339 boolean useMavenRepoLocal = Boolean.valueOf( verifierProperties.getProperty( "use.mavenRepoLocal", "true" ) );
1340
1341 if ( useMavenRepoLocal )
1342 {
1343 args.add( "-Dmaven.repo.local=" + localRepo );
1344 }
1345
1346 args.addAll( allGoals );
1347
1348 try
1349 {
1350 String[] cliArgs = args.toArray( new String[args.size()] );
1351
1352 MavenLauncher launcher = getMavenLauncher( envVars );
1353
1354 ret = launcher.run( cliArgs, systemProperties, getBasedir(), logFile );
1355 }
1356 catch ( LauncherException e )
1357 {
1358 throw new VerificationException( "Failed to execute Maven: " + e.getMessage(), e );
1359 }
1360 catch ( IOException e )
1361 {
1362 throw new VerificationException( e );
1363 }
1364
1365 if ( ret > 0 )
1366 {
1367 System.err.println( "Exit code: " + ret );
1368
1369 throw new VerificationException(
1370 "Exit code was non-zero: " + ret + "; command line and log = \n" + new File( defaultMavenHome,
1371 "bin/mvn" ) + " "
1372 + StringUtils.join( args.iterator(), " " ) + "\n" + getLogContents( logFile ) );
1373 }
1374 }
1375
1376 private MavenLauncher getMavenLauncher( Map<String, String> envVars )
1377 throws LauncherException
1378 {
1379 boolean fork;
1380 if ( forkJvm != null )
1381 {
1382 fork = forkJvm;
1383 }
1384 else if ( ( envVars.isEmpty() && "auto".equalsIgnoreCase( forkMode ) )
1385 || "embedded".equalsIgnoreCase( forkMode ) )
1386 {
1387 fork = false;
1388
1389 try
1390 {
1391 initEmbeddedLauncher();
1392 }
1393 catch ( Exception e )
1394 {
1395 fork = true;
1396 }
1397 }
1398 else
1399 {
1400 fork = true;
1401 }
1402
1403 if ( !fork )
1404 {
1405 if ( !envVars.isEmpty() )
1406 {
1407 throw new LauncherException( "Environment variables are not supported in embedded runtime" );
1408 }
1409
1410 initEmbeddedLauncher();
1411
1412 return embeddedLauncher;
1413 }
1414 else
1415 {
1416 return new ForkedLauncher( defaultMavenHome, envVars, debugJvm );
1417 }
1418 }
1419
1420 private void initEmbeddedLauncher()
1421 throws LauncherException
1422 {
1423 if ( embeddedLauncher == null )
1424 {
1425 if ( StringUtils.isEmpty( defaultMavenHome ) )
1426 {
1427 embeddedLauncher = Embedded3xLauncher.createFromClasspath();
1428 }
1429 else
1430 {
1431 embeddedLauncher =
1432 Embedded3xLauncher.createFromMavenHome( defaultMavenHome, defaultClassworldConf, getClasspath() );
1433 }
1434 }
1435 }
1436
1437 private List<URL> getClasspath()
1438 throws LauncherException
1439 {
1440 if ( defaultClasspath == null )
1441 {
1442 return null;
1443 }
1444 ArrayList<URL> classpath = new ArrayList<URL>();
1445 StringTokenizer st = new StringTokenizer( defaultClasspath, File.pathSeparator );
1446 while ( st.hasMoreTokens() )
1447 {
1448 try
1449 {
1450 classpath.add( new File( st.nextToken() ).toURI().toURL() );
1451 }
1452 catch ( MalformedURLException e )
1453 {
1454 throw new LauncherException( "Invalid launcher classpath " + defaultClasspath, e );
1455 }
1456 }
1457 return classpath;
1458 }
1459
1460 public String getMavenVersion()
1461 throws VerificationException
1462 {
1463 try
1464 {
1465 return getMavenLauncher( Collections.<String, String>emptyMap() ).getMavenVersion();
1466 }
1467 catch ( LauncherException e )
1468 {
1469 throw new VerificationException( e );
1470 }
1471 catch ( IOException e )
1472 {
1473 throw new VerificationException( e );
1474 }
1475 }
1476
1477 private static String getLogContents( File logFile )
1478 {
1479 try
1480 {
1481 return FileUtils.fileRead( logFile );
1482 }
1483 catch ( IOException e )
1484 {
1485
1486 return "(Error reading log contents: " + e.getMessage() + ")";
1487 }
1488 }
1489
1490 private String resolveCommandLineArg( String key )
1491 {
1492 String result = key.replaceAll( "\\$\\{basedir\\}", getBasedir() );
1493 if ( result.contains( "\\\\" ) )
1494 {
1495 result = result.replaceAll( "\\\\", "\\" );
1496 }
1497 result = result.replaceAll( "\\/\\/", "\\/" );
1498
1499 return result;
1500 }
1501
1502 private static List<String> discoverIntegrationTests( String directory )
1503 throws VerificationException
1504 {
1505 try
1506 {
1507 ArrayList<String> tests = new ArrayList<String>();
1508
1509 List<File> subTests = FileUtils.getFiles( new File( directory ), "**/goals.txt", null );
1510
1511 for ( File testCase : subTests )
1512 {
1513 tests.add( testCase.getParent() );
1514 }
1515
1516 return tests;
1517 }
1518 catch ( IOException e )
1519 {
1520 throw new VerificationException( directory + " is not a valid test case container", e );
1521 }
1522 }
1523
1524 private void displayLogFile()
1525 {
1526 System.out.println( "Log file contents:" );
1527 BufferedReader reader = null;
1528 try
1529 {
1530 reader = new BufferedReader( new FileReader( new File( getBasedir(), getLogFileName() ) ) );
1531 String line = reader.readLine();
1532 while ( line != null )
1533 {
1534 System.out.println( line );
1535 line = reader.readLine();
1536 }
1537 reader.close();
1538 }
1539 catch ( FileNotFoundException e )
1540 {
1541 System.err.println( "Error: " + e );
1542 }
1543 catch ( IOException e )
1544 {
1545 System.err.println( "Error: " + e );
1546 }
1547 finally
1548 {
1549 IOUtil.close( reader );
1550 }
1551 }
1552
1553
1554
1555
1556
1557 public static void main( String args[] )
1558 throws VerificationException
1559 {
1560 String basedir = System.getProperty( "user.dir" );
1561
1562 List<String> tests = null;
1563
1564 List<String> argsList = new ArrayList<String>();
1565
1566 String settingsFile = null;
1567
1568
1569 for ( int i = 0; i < args.length; i++ )
1570 {
1571 if ( args[i].startsWith( "-D" ) )
1572 {
1573 int index = args[i].indexOf( "=" );
1574 if ( index >= 0 )
1575 {
1576 System.setProperty( args[i].substring( 2, index ), args[i].substring( index + 1 ) );
1577 }
1578 else
1579 {
1580 System.setProperty( args[i].substring( 2 ), "true" );
1581 }
1582 }
1583 else if ( "-s".equals( args[i] ) || "--settings".equals( args[i] ) )
1584 {
1585 if ( i == args.length - 1 )
1586 {
1587
1588 throw new IllegalStateException( "missing argument to -s" );
1589 }
1590 i += 1;
1591
1592 settingsFile = args[i];
1593 }
1594 else if ( args[i].startsWith( "-" ) )
1595 {
1596 System.out.println( "skipping unrecognised argument: " + args[i] );
1597 }
1598 else
1599 {
1600 argsList.add( args[i] );
1601 }
1602 }
1603
1604 if ( argsList.size() == 0 )
1605 {
1606 if ( FileUtils.fileExists( basedir + File.separator + "integration-tests.txt" ) )
1607 {
1608 try
1609 {
1610 tests = FileUtils.loadFile( new File( basedir, "integration-tests.txt" ) );
1611 }
1612 catch ( IOException e )
1613 {
1614 System.err.println( "Unable to load integration tests file" );
1615
1616 System.err.println( e.getMessage() );
1617
1618 System.exit( 2 );
1619 }
1620 }
1621 else
1622 {
1623 tests = discoverIntegrationTests( "." );
1624 }
1625 }
1626 else
1627 {
1628 tests = new ArrayList<String>( argsList.size() );
1629 NumberFormat fmt = new DecimalFormat( "0000" );
1630 for ( String test : argsList )
1631 {
1632 if ( test.endsWith( "," ) )
1633 {
1634 test = test.substring( 0, test.length() - 1 );
1635 }
1636
1637 if ( StringUtils.isNumeric( test ) )
1638 {
1639
1640 test = "it" + fmt.format( Integer.valueOf( test ) );
1641 tests.add( test.trim() );
1642 }
1643 else if ( "it".startsWith( test ) )
1644 {
1645 test = test.trim();
1646 if ( test.length() > 0 )
1647 {
1648 tests.add( test );
1649 }
1650 }
1651 else if ( FileUtils.fileExists( test ) && new File( test ).isDirectory() )
1652 {
1653 tests.addAll( discoverIntegrationTests( test ) );
1654 }
1655 else
1656 {
1657 System.err.println(
1658 "[WARNING] rejecting " + test + " as an invalid test or test source directory" );
1659 }
1660 }
1661 }
1662
1663 if ( tests.size() == 0 )
1664 {
1665 System.out.println( "No tests to run" );
1666 }
1667
1668 int exitCode = 0;
1669
1670 List<String> failed = new ArrayList<String>();
1671 for ( String test : tests )
1672 {
1673 System.out.print( test + "... " );
1674
1675 String dir = basedir + "/" + test;
1676
1677 if ( !new File( dir, "goals.txt" ).exists() )
1678 {
1679 System.err.println( "Test " + test + " in " + dir + " does not exist" );
1680
1681 System.exit( 2 );
1682 }
1683
1684 Verifier verifier = new Verifier( dir );
1685 verifier.findLocalRepo( settingsFile );
1686
1687 System.out.println( "Using default local repository: " + verifier.localRepo );
1688
1689 try
1690 {
1691 runIntegrationTest( verifier );
1692 }
1693 catch ( Throwable e )
1694 {
1695 verifier.resetStreams();
1696
1697 System.out.println( "FAILED" );
1698
1699 verifier.displayStreamBuffers();
1700
1701 System.out.println( ">>>>>> Error Stacktrace:" );
1702 e.printStackTrace( System.out );
1703 System.out.println( "<<<<<< Error Stacktrace" );
1704
1705 verifier.displayLogFile();
1706
1707 exitCode = 1;
1708
1709 failed.add( test );
1710 }
1711 }
1712
1713 System.out.println( tests.size() - failed.size() + "/" + tests.size() + " passed" );
1714 if ( !failed.isEmpty() )
1715 {
1716 System.out.println( "Failed tests: " + failed );
1717 }
1718
1719 System.exit( exitCode );
1720 }
1721
1722 private void findLocalRepo( String settingsFile )
1723 throws VerificationException
1724 {
1725 if ( localRepo == null )
1726 {
1727 localRepo = System.getProperty( "maven.repo.local" );
1728 }
1729
1730 if ( localRepo == null )
1731 {
1732 localRepo = retrieveLocalRepo( settingsFile );
1733 }
1734
1735 if ( localRepo == null )
1736 {
1737 localRepo = System.getProperty( "user.home" ) + "/.m2/repository";
1738 }
1739
1740 File repoDir = new File( localRepo );
1741
1742 if ( !repoDir.exists() )
1743 {
1744
1745 repoDir.mkdirs();
1746 }
1747
1748
1749 localRepo = repoDir.getAbsolutePath();
1750
1751 localRepoLayout = System.getProperty( "maven.repo.local.layout", "default" );
1752 }
1753
1754 private static void runIntegrationTest( Verifier verifier )
1755 throws VerificationException
1756 {
1757 verifier.executeHook( "prebuild-hook.txt" );
1758
1759 Properties properties = verifier.loadProperties( "system.properties" );
1760
1761 Properties controlProperties = verifier.loadProperties( "verifier.properties" );
1762
1763 boolean chokeOnErrorOutput = Boolean.valueOf( controlProperties.getProperty( "failOnErrorOutput", "true" ) );
1764
1765 List<String> goals = verifier.loadFile( verifier.getBasedir(), "goals.txt", false );
1766
1767 List<String> cliOptions = verifier.loadFile( verifier.getBasedir(), "cli-options.txt", false );
1768
1769 verifier.setCliOptions( cliOptions );
1770
1771 verifier.setSystemProperties( properties );
1772
1773 verifier.setVerifierProperties( controlProperties );
1774
1775 verifier.executeGoals( goals );
1776
1777 verifier.executeHook( "postbuild-hook.txt" );
1778
1779 System.out.println( "*** Verifying: fail when [ERROR] detected? " + chokeOnErrorOutput + " ***" );
1780
1781 verifier.verify( chokeOnErrorOutput );
1782
1783 verifier.resetStreams();
1784
1785 System.out.println( "OK" );
1786 }
1787
1788 public void assertArtifactContents( String org, String artifact, String version, String type, String contents )
1789 throws IOException
1790 {
1791 String fileName = getArtifactPath( org, artifact, version, type );
1792 Assert.assertEquals( contents, FileUtils.fileRead( fileName ) );
1793 }
1794
1795 static class UserModelReader
1796 extends DefaultHandler
1797 {
1798 private String localRepository;
1799
1800 private StringBuffer currentBody = new StringBuffer();
1801
1802 public void parse( File file )
1803 throws VerificationException
1804 {
1805 try
1806 {
1807 SAXParserFactory saxFactory = SAXParserFactory.newInstance();
1808
1809 SAXParser parser = saxFactory.newSAXParser();
1810
1811 InputSource is = new InputSource( new FileInputStream( file ) );
1812
1813 parser.parse( is, this );
1814 }
1815 catch ( FileNotFoundException e )
1816 {
1817 throw new VerificationException( "file not found path : " + file.getAbsolutePath(), e );
1818 }
1819 catch ( IOException e )
1820 {
1821 throw new VerificationException( " IOException path : " + file.getAbsolutePath(), e );
1822 }
1823 catch ( ParserConfigurationException e )
1824 {
1825 throw new VerificationException( e );
1826 }
1827 catch ( SAXException e )
1828 {
1829 throw new VerificationException( "Parsing exception for file " + file.getAbsolutePath(), e );
1830 }
1831 }
1832
1833 public void warning( SAXParseException spe )
1834 {
1835 printParseError( "Warning", spe );
1836 }
1837
1838 public void error( SAXParseException spe )
1839 {
1840 printParseError( "Error", spe );
1841 }
1842
1843 public void fatalError( SAXParseException spe )
1844 {
1845 printParseError( "Fatal Error", spe );
1846 }
1847
1848 private void printParseError( String type, SAXParseException spe )
1849 {
1850 System.err.println(
1851 type + " [line " + spe.getLineNumber() + ", row " + spe.getColumnNumber() + "]: " + spe.getMessage() );
1852 }
1853
1854 public String getLocalRepository()
1855 {
1856 return localRepository;
1857 }
1858
1859 public void characters( char[] ch, int start, int length )
1860 throws SAXException
1861 {
1862 currentBody.append( ch, start, length );
1863 }
1864
1865 public void endElement( String uri, String localName, String rawName )
1866 throws SAXException
1867 {
1868 if ( "localRepository".equals( rawName ) )
1869 {
1870 if ( notEmpty( currentBody.toString() ) )
1871 {
1872 localRepository = currentBody.toString().trim();
1873 }
1874 else
1875 {
1876 throw new SAXException(
1877 "Invalid mavenProfile entry. Missing one or more " + "fields: {localRepository}." );
1878 }
1879 }
1880
1881 currentBody = new StringBuffer();
1882 }
1883
1884 private boolean notEmpty( String test )
1885 {
1886 return test != null && test.trim().length() > 0;
1887 }
1888
1889 public void reset()
1890 {
1891 currentBody = null;
1892 localRepository = null;
1893 }
1894 }
1895
1896 public List<String> getCliOptions()
1897 {
1898 return cliOptions;
1899 }
1900
1901 public void setCliOptions( List<String> cliOptions )
1902 {
1903 this.cliOptions = cliOptions;
1904 }
1905
1906 public void addCliOption( String option )
1907 {
1908 cliOptions.add( option );
1909 }
1910
1911 public Properties getSystemProperties()
1912 {
1913 return systemProperties;
1914 }
1915
1916 public void setSystemProperties( Properties systemProperties )
1917 {
1918 this.systemProperties = systemProperties;
1919 }
1920
1921 public void setSystemProperty( String key, String value )
1922 {
1923 if ( value != null )
1924 {
1925 systemProperties.setProperty( key, value );
1926 }
1927 else
1928 {
1929 systemProperties.remove( key );
1930 }
1931 }
1932
1933 public Map<String, String> getEnvironmentVariables()
1934 {
1935 return environmentVariables;
1936 }
1937
1938 public void setEnvironmentVariables( Map<String, String> environmentVariables )
1939 {
1940 this.environmentVariables = environmentVariables;
1941 }
1942
1943 public void setEnvironmentVariable( String key, String value )
1944 {
1945 if ( value != null )
1946 {
1947 environmentVariables.put( key, value );
1948 }
1949 else
1950 {
1951 environmentVariables.remove( key );
1952 }
1953 }
1954
1955 public Properties getVerifierProperties()
1956 {
1957 return verifierProperties;
1958 }
1959
1960 public void setVerifierProperties( Properties verifierProperties )
1961 {
1962 this.verifierProperties = verifierProperties;
1963 }
1964
1965 public boolean isAutoclean()
1966 {
1967 return autoclean;
1968 }
1969
1970 public void setAutoclean( boolean autoclean )
1971 {
1972 this.autoclean = autoclean;
1973 }
1974
1975 public String getBasedir()
1976 {
1977 return basedir;
1978 }
1979
1980
1981
1982
1983
1984
1985
1986 public String getLogFileName()
1987 {
1988 return this.logFileName;
1989 }
1990
1991
1992
1993
1994
1995
1996
1997
1998 public void setLogFileName( String logFileName )
1999 {
2000 if ( StringUtils.isEmpty( logFileName ) )
2001 {
2002 throw new IllegalArgumentException( "log file name unspecified" );
2003 }
2004 this.logFileName = logFileName;
2005 }
2006
2007 public void setDebug( boolean debug )
2008 {
2009 this.debug = debug;
2010
2011 if ( !debug )
2012 {
2013 System.setOut( new PrintStream( outStream ) );
2014
2015 System.setErr( new PrintStream( errStream ) );
2016 }
2017 }
2018
2019 public boolean isMavenDebug()
2020 {
2021 return mavenDebug;
2022 }
2023
2024 public void setMavenDebug( boolean mavenDebug )
2025 {
2026 this.mavenDebug = mavenDebug;
2027 }
2028
2029 public void setForkJvm( boolean forkJvm )
2030 {
2031 this.forkJvm = forkJvm;
2032 }
2033
2034 public boolean isDebugJvm()
2035 {
2036 return debugJvm;
2037 }
2038
2039 public void setDebugJvm( boolean debugJvm )
2040 {
2041 this.debugJvm = debugJvm;
2042 }
2043
2044 public String getLocalRepoLayout()
2045 {
2046 return localRepoLayout;
2047 }
2048
2049 public void setLocalRepoLayout( String localRepoLayout )
2050 {
2051 this.localRepoLayout = localRepoLayout;
2052 }
2053
2054 public String getLocalRepository()
2055 {
2056 return localRepo;
2057 }
2058 }