001 package org.codehaus.mojo.exec;
002
003 /*
004 * Copyright 2005-2006 The Codehaus.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import org.apache.maven.artifact.repository.ArtifactRepository;
020 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
021 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
022 import org.apache.maven.plugin.MojoExecutionException;
023 import org.apache.maven.plugin.AbstractMojo;
024 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
025 import org.apache.maven.project.MavenProject;
026 import org.apache.maven.project.MavenProjectBuilder;
027 import org.apache.maven.monitor.logging.DefaultLog;
028 import org.codehaus.plexus.util.StringOutputStream;
029 import org.codehaus.plexus.logging.Logger;
030 import org.codehaus.plexus.logging.console.ConsoleLogger;
031
032 import java.io.File;
033 import java.io.PrintStream;
034
035 /**
036 * @author Jerome Lacoste <jerome@coffeebreaks.org>
037 * @version $Id: ExecJavaMojoTest.java 10761 2009-09-24 09:38:21Z stephenconnolly $
038 */
039 public class ExecJavaMojoTest
040 extends AbstractMojoTestCase
041 {
042
043 /*
044 This one won't work yet
045 public void xxtestSimpleRunPropertiesAndArguments()
046 throws MojoExecutionException, Exception
047 {
048 File pom = new File( getBasedir(), "src/test/projects/project2/pom.xml" );
049
050 String output = execute( pom, "java" );
051
052 System.out.println(output);
053
054 assertEquals( -1, output.trim().indexOf( "ERROR" ) );
055 }
056 */
057
058 /**
059 * Check that a simple execution with no arguments and no system properties produces the expected result
060 * <p/>
061 * we load the config from a pom file and fill up the MavenProject property ourselves
062 */
063 public void testSimpleRun()
064 throws Exception
065 {
066 File pom = new File( getBasedir(), "src/test/projects/project4/pom.xml" );
067
068 String output = execute( pom, "java" );
069
070 assertEquals( "Hello" + System.getProperty( "line.separator" ), output );
071 }
072
073 /**
074 * MEXEC-10 Check that an execution with no arguments and an system property with no value
075 * produces the expected result
076 * <p/>
077 * we load the config from a pom file and fill up the MavenProject property ourselves
078 */
079 public void testEmptySystemProperty()
080 throws Exception
081 {
082 File pom = new File( getBasedir(), "src/test/projects/project5/pom.xml" );
083
084 assertNull( "System property not yet created",
085 System.getProperty( "project5.property.with.no.value" ) );
086
087 execute( pom, "java" );
088
089 assertEquals( "System property now empty",
090 "",
091 System.getProperty( "project5.property.with.no.value" ) );
092 }
093
094 /**
095 * MEXEC-29 exec:java throws NPE if the mainClass main method has not a correct signature
096 * <p/>
097 */
098 public void testIncorrectMainMethodSignature()
099 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 }