View Javadoc

1   package org.codehaus.mojo.exec;
2   
3   /*
4    * Copyright 2005-2006 The Codehaus.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import org.apache.maven.artifact.repository.ArtifactRepository;
20  import org.apache.maven.artifact.repository.DefaultArtifactRepository;
21  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
22  import org.apache.maven.plugin.MojoExecutionException;
23  import org.apache.maven.plugin.AbstractMojo;
24  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
25  import org.apache.maven.project.MavenProject;
26  import org.apache.maven.project.MavenProjectBuilder;
27  import org.apache.maven.monitor.logging.DefaultLog;
28  import org.codehaus.plexus.util.StringOutputStream;
29  import org.codehaus.plexus.logging.Logger;
30  import org.codehaus.plexus.logging.console.ConsoleLogger;
31  
32  import java.io.File;
33  import java.io.PrintStream;
34  
35  /**
36   * @author Jerome Lacoste <jerome@coffeebreaks.org>
37   * @version $Id: ExecJavaMojoTest.java 10761 2009-09-24 09:38:21Z stephenconnolly $
38   */
39  public class ExecJavaMojoTest
40      extends AbstractMojoTestCase
41  {
42  
43      /*
44      This one won't work yet
45      public void xxtestSimpleRunPropertiesAndArguments()
46          throws MojoExecutionException, Exception
47      {
48          File pom = new File( getBasedir(), "src/test/projects/project2/pom.xml" );
49  
50          String output = execute( pom, "java" );
51  
52          System.out.println(output);
53  
54          assertEquals( -1, output.trim().indexOf( "ERROR" ) );
55      }
56      */
57  
58      /**
59       * Check that a simple execution with no arguments and no system properties produces the expected result
60       * <p/>
61       * we load the config from a pom file and fill up the MavenProject property ourselves
62       */
63      public void testSimpleRun()
64          throws Exception
65      {
66          File pom = new File( getBasedir(), "src/test/projects/project4/pom.xml" );
67  
68          String output = execute( pom, "java" );
69  
70          assertEquals( "Hello" + System.getProperty( "line.separator" ), output );
71      }
72  
73      /**
74       * MEXEC-10 Check that an execution with no arguments and an system property with no value
75       * produces the expected result
76       * <p/>
77       * we load the config from a pom file and fill up the MavenProject property ourselves
78       */
79      public void testEmptySystemProperty()
80          throws Exception
81      {
82          File pom = new File( getBasedir(), "src/test/projects/project5/pom.xml" );
83  
84          assertNull( "System property not yet created",
85                       System.getProperty( "project5.property.with.no.value" ) );
86  
87          execute( pom, "java" );
88  
89          assertEquals( "System property now empty",
90                         "",
91                         System.getProperty( "project5.property.with.no.value" ) );
92      }
93  
94      /**
95       * MEXEC-29 exec:java throws NPE if the mainClass main method has not a correct signature
96       * <p/>
97       */
98      public void testIncorrectMainMethodSignature()
99          throws Exception
100     {
101         File pom = new File( getBasedir(), "src/test/projects/project12/pom.xml" );
102 
103         try {
104             String output = execute( pom, "java" );
105         } catch (MojoExecutionException e) {
106             assertTrue( stringContains( e.getMessage(), "The specified mainClass doesn't contain a main method with appropriate signature." ) );
107         }
108 
109     }
110 
111 // this test doesn't work as the classpath passed to the project when executing the POM isn't the same as when maven is executed from within the project dir
112 // Should be moved as an integration-test
113 /*
114     public void testSetClasspathScopeToTest()
115         throws Exception
116     {
117         File pom = new File( getBasedir(), "src/test/projects/project14/pom.xml" );
118 
119         String output = execute( pom, "java" );
120 
121         assertEquals( "Hello" + System.getProperty( "line.separator" ), output );
122     }
123 */
124     
125     // java 1.4 compatibility
126     private boolean stringContains( String str, String sequence )
127     {
128         return str.indexOf( sequence ) != -1;
129     }
130 
131     /**
132      * For cases where the Java code spawns Threads and main returns soon.
133      * See <a href="http://jira.codehaus.org/browse/MEXEC-6">MEXEC-6</a>.
134      */
135     public void testWaitNoDaemonThreads()
136         throws Exception
137     {
138         File pom = new File( getBasedir(), "src/test/projects/project7/pom.xml" );
139 
140         String output = execute( pom, "java" );
141 
142         assertEquals( MainWithThreads.ALL_EXITED, output.trim() );
143     }
144 
145     /**
146      * For cases where the Java code spawns Threads and main returns soon, but code contains non interruptible threads.
147      * User is required to timeout the execution, otherwise it will hang.
148      * See <a href="http://jira.codehaus.org/browse/MEXEC-15">MEXEC-15</a>.
149      */
150     public void testWaitNonInterruptibleDaemonThreads()
151         throws Exception
152     {
153         File pom = new File( getBasedir(), "src/test/projects/project9/pom.xml" );
154 
155         String output = execute( pom, "java" );
156 
157         assertEquals( MainWithThreads.TIMER_IGNORED, output.trim() );
158     }
159 
160     /**
161      * See <a href="http://jira.codehaus.org/browse/MEXEC-15">MEXEC-15</a>.
162      * FIXME: this sometimes fail with unit.framework.ComparisonFailure: expected:<...> but was:<...3(f)>
163      */
164     public void testUncooperativeThread()
165         throws Exception
166     {
167         File pom = new File( getBasedir(), "src/test/projects/project10/pom.xml" );
168         String output = execute( pom, "java" );
169         // note: execute() will wait a little bit before returning the output,
170         // thereby allowing the stop()'ed thread to output the final "(f)".
171         assertEquals( MainUncooperative.SUCCESS, output.trim() );
172     }
173 
174     /**
175      * See <a href="http://jira.codehaus.org/browse/MEXEC-17">MEXEC-17</a>.
176      */
177     /**
178     This test doesn't work because the sun.tools.javac.Main class referenced in the
179     project pom is found even if the system scope dependencies are not added by the plugin.
180     The class was probably loaded by another plugin ?!
181 
182     To fix the test we have to:
183     - maybe use a different system scope dependency/class to load.
184     - find a different way to test.
185 
186     When ran manually, the test works though (i.e. removing the code that manually adds
187     the system scope dependencies make the test fail).
188 
189     public void testSystemDependencyFound()
190         throws Exception
191     {
192         File pom = new File( getBasedir(), "src/test/projects/project11/pom.xml" );
193 
194         String output = execute( pom, "java" );
195 
196         assertEquals( FindClassInClasspath.FOUND_ALL, output.trim() );
197     }
198     */
199 
200     /**
201      * Test the commandline parsing facilities of the {@link AbstractExecMojo} class
202      */
203     public void testRunWithArgs() throws Exception
204     {
205 
206         String resultString = execute( new File( getBasedir(), "src/test/projects/project8/pom.xml" ), "java" );
207 
208         String LS = System.getProperty("line.separator");
209         String expectedResult = "Hello" + LS + "Arg1" + LS +"Arg2a Arg2b" + LS;
210         assertEquals( expectedResult, resultString );
211     }
212 
213     /**
214      * @return output from System.out during mojo execution
215      */
216     private String execute( File pom, String goal ) throws Exception {
217 
218         ExecJavaMojo mojo;
219         mojo = (ExecJavaMojo) lookupMojo( goal, pom );
220 
221         setUpProject( pom, mojo );
222 
223         MavenProject project = (MavenProject) getVariableValueFromObject( mojo, "project" );
224 
225         // why isn't this set up by the harness based on the default-value?  TODO get to bottom of this!
226         setVariableValueToObject( mojo, "includeProjectDependencies", Boolean.TRUE );
227         setVariableValueToObject( mojo, "killAfter", new Long( -1 ) );
228         setVariableValueToObject( mojo, "cleanupDaemonThreads", Boolean.TRUE );
229         setVariableValueToObject( mojo, "classpathScope", "compile" );
230 
231         assertNotNull( mojo );
232         assertNotNull( project );
233 
234         // trap System.out
235         PrintStream out = System.out;
236         StringOutputStream stringOutputStream = new StringOutputStream();
237         System.setOut( new PrintStream( stringOutputStream ) );
238         // ensure we don't log unnecessary stuff which would interfere with assessing success of tests
239         mojo.setLog( new DefaultLog( new ConsoleLogger( Logger.LEVEL_ERROR, "exec:java" ) ) );
240 
241         try
242         {
243             mojo.execute();
244         }
245         finally
246         {
247             // see testUncooperativeThread() for explaination
248             Thread.sleep( 300 ); // time seems about right
249             System.setOut( out );
250         }
251 
252         return stringOutputStream.toString();
253     }
254 
255     private void setUpProject( File pomFile, AbstractMojo mojo )
256         throws Exception
257     {
258         MavenProjectBuilder builder = (MavenProjectBuilder) lookup( MavenProjectBuilder.ROLE );
259 
260         ArtifactRepositoryLayout localRepositoryLayout =
261             (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
262 
263         String path = "src/test/repository";
264 
265         ArtifactRepository localRepository = new DefaultArtifactRepository( "local", "file://" +
266             new File( path ).getAbsolutePath(), localRepositoryLayout );
267 
268         MavenProject project = builder.buildWithDependencies( pomFile, localRepository, null );
269         // this gets the classes for these tests of this mojo (exec plugin) onto the project classpath for the test
270         project.getBuild().setOutputDirectory( new File( "target/test-classes" ).getAbsolutePath() );
271         setVariableValueToObject( mojo, "project", project );
272     }
273 }