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 java.io.File;
23  import java.io.IOException;
24  import java.net.URI;
25  import java.net.URISyntaxException;
26  import java.net.URL;
27  import java.util.Arrays;
28  import java.util.Collections;
29  import java.util.Properties;
30  
31  import org.apache.maven.shared.utils.Os;
32  import org.apache.maven.shared.utils.StringUtils;
33  import org.junit.Test;
34  
35  import static org.junit.Assert.assertEquals;
36  
37  public class DefaultInvokerTest
38  {
39  
40      @Test
41      public void testBuildShouldSucceed()
42          throws MavenInvocationException, URISyntaxException
43      {
44          File basedir = getBasedirForBuild();
45  
46          Invoker invoker = newInvoker();
47  
48          InvocationRequest request = new DefaultInvocationRequest();
49          request.setBaseDirectory( basedir );
50          request.setDebug( true );
51          request.setGoals( Arrays.asList( "clean", "package" ) );
52          request.setProperties( getProperties() );
53  
54          InvocationResult result = invoker.execute( request );
55  
56          assertEquals( 0, result.getExitCode() );
57      }
58  
59      @Test
60      public void testBuildShouldFail()
61          throws MavenInvocationException, URISyntaxException
62      {
63          File basedir = getBasedirForBuild();
64  
65          Invoker invoker = newInvoker();
66  
67          InvocationRequest request = new DefaultInvocationRequest();
68          request.setBaseDirectory( basedir );
69          request.setDebug( true );
70          request.setGoals( Arrays.asList( "clean", "package" ) );
71          request.setProperties( getProperties() );
72  
73          InvocationResult result = invoker.execute( request );
74  
75          assertEquals( 1, result.getExitCode() );
76      }
77  
78      @Test
79      public void testBuildShouldTimeout()
80          throws MavenInvocationException, URISyntaxException
81      {
82          File basedir = getBasedirForBuild();
83  
84          Invoker invoker = newInvoker();
85  
86          InvocationRequest request = new DefaultInvocationRequest();
87          request.setBaseDirectory( basedir );
88          request.setDebug( true );
89          request.setGoals( Arrays.asList( "clean", "package" ) );
90          request.setTimeoutInSeconds( 4 );
91          request.setProperties( getProperties() );
92  
93          InvocationResult result = invoker.execute( request );
94  
95          // We check the exception to be sure the failure is based on timeout.
96          assertEquals( "Error while executing external command, process killed.",
97                        result.getExecutionException().getMessage() );
98  
99          // WARN - Windows issue MSHARED-867 - Maven and child surefire test process stays alive on Windows
100         // workaround implemented in this test to timeout test after 15 sec
101         // please also check timeout logic in maven-shared-utils
102 
103         // exitCode can't be used cause in case of an timeout it's not correctly
104         // set in DefaultInvoker. Need to think about this.
105         // assertEquals( 1, result.getExitCode() );
106     }
107 
108     @Test
109     public void testSpacePom()
110         throws Exception
111     {
112         logTestStart();
113 
114         File basedir = getBasedirForBuild();
115 
116         Invoker invoker = newInvoker();
117 
118         InvocationRequest request = new DefaultInvocationRequest();
119         request.setBaseDirectory( basedir );
120         request.setPomFileName( "pom with spaces.xml" );
121         request.setDebug( true );
122         request.setGoals( Collections.singletonList( "clean" ) );
123         request.setProperties( getProperties() );
124         
125         InvocationResult result = invoker.execute( request );
126 
127         assertEquals( 0, result.getExitCode() );
128     }
129 
130     @Test
131     public void testSpaceAndSpecialCharPom()
132         throws Exception
133     {
134         logTestStart();
135 
136         File basedir = getBasedirForBuild();
137 
138         Invoker invoker = newInvoker();
139 
140         InvocationRequest request = new DefaultInvocationRequest();
141         request.setBaseDirectory( basedir );
142         request.setPomFileName( "pom with spaces & special char.xml" );
143         request.setDebug( true );
144         request.setGoals( Collections.singletonList( "clean" ) );
145         request.setProperties( getProperties() );
146 
147         InvocationResult result = invoker.execute( request );
148 
149         assertEquals( 0, result.getExitCode() );
150     }
151 
152     @Test
153     public void testSpaceSettings()
154         throws Exception
155     {
156         logTestStart();
157 
158         File basedir = getBasedirForBuild();
159 
160         Invoker invoker = newInvoker();
161 
162         InvocationRequest request = new DefaultInvocationRequest();
163         request.setBaseDirectory( basedir );
164         request.setUserSettingsFile( new File( basedir, "settings with spaces.xml" ) );
165         request.setDebug( true );
166         request.setGoals( Collections.singletonList( "validate" ) );
167         request.setProperties( getProperties() );
168 
169         InvocationResult result = invoker.execute( request );
170 
171         assertEquals( 0, result.getExitCode() );
172     }
173 
174     @Test
175     public void testSpaceLocalRepo()
176         throws Exception
177     {
178         logTestStart();
179 
180         File basedir = getBasedirForBuild();
181 
182         Invoker invoker = newInvoker();
183 
184         InvocationRequest request = new DefaultInvocationRequest();
185         request.setBaseDirectory( basedir );
186         request.setLocalRepositoryDirectory( new File( basedir, "repo with spaces" ) );
187         request.setDebug( true );
188         request.setGoals( Collections.singletonList( "validate" ) );
189         request.setProperties( getProperties() );
190 
191         InvocationResult result = invoker.execute( request );
192 
193         assertEquals( 0, result.getExitCode() );
194     }
195 
196     @Test
197     public void testSpaceProperties()
198         throws Exception
199     {
200         logTestStart();
201 
202         File basedir = getBasedirForBuild();
203 
204         Invoker invoker = newInvoker();
205 
206         InvocationRequest request = new DefaultInvocationRequest();
207         request.setBaseDirectory( basedir );
208 
209         Properties props = getProperties();
210         props.setProperty( "key", "value with spaces" );
211         props.setProperty( "key with spaces", "value" );
212         request.setProperties( props );
213         request.setDebug( true );
214         request.setGoals( Collections.singletonList( "validate" ) );
215 
216         InvocationResult result = invoker.execute( request );
217 
218         assertEquals( 0, result.getExitCode() );
219     }
220 
221     @Test
222     public void testPomOutsideProject() throws Exception
223     {
224         logTestStart();
225 
226         File testDir = getBasedirForBuild();
227 
228         File basedir = new File( testDir, "project" );
229         File pom = new File(testDir, "temp/pom.xml" );
230 
231         Invoker invoker = newInvoker();
232 
233         InvocationRequest request = new DefaultInvocationRequest();
234         request.setBaseDirectory( basedir );
235         request.setPomFile( pom );
236         request.setGoals( Collections.singletonList( "validate" ) );
237 
238         InvocationResult result = invoker.execute( request );
239 
240         assertEquals( 0, result.getExitCode() );
241     }
242 
243     @Test
244     public void testMavenWrapperInProject() throws Exception
245     {
246         File basedir = getBasedirForBuild();
247 
248         Invoker invoker = newInvoker();
249 
250         InvocationRequest request = new DefaultInvocationRequest();
251         request.setBaseDirectory( basedir );
252         request.setGoals( Collections.singletonList( "test-wrapper-goal" ) );
253         request.setMavenExecutable( new File( "./mvnw" ) );
254 
255         final StringBuilder outlines = new StringBuilder();
256         request.setOutputHandler( new InvocationOutputHandler()
257         {
258             @Override
259             public void consumeLine( String line )
260             {
261                 outlines.append( line );
262             }
263         } );
264 
265 
266         InvocationResult result = invoker.execute( request );
267 
268         assertEquals( 0, result.getExitCode() );
269         if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
270         {
271             assertEquals( "Windows Wrapper executed", outlines.toString() );
272         }
273         else
274         {
275             assertEquals( "Unix Wrapper executed", outlines.toString() );
276         }
277     }
278 
279     private Invoker newInvoker()
280     {
281         Invoker invoker = new DefaultInvoker();
282 
283         invoker.setMavenHome( findMavenHome() );
284 
285         InvokerLogger logger = new SystemOutLogger();
286         logger.setThreshold( InvokerLogger.DEBUG );
287         invoker.setLogger( logger );
288 
289         invoker.setLocalRepositoryDirectory( findLocalRepo() );
290 
291         return invoker;
292     }
293 
294     private File findMavenHome()
295     {
296         String mavenHome = System.getProperty( "maven.home" );
297 
298         if ( mavenHome == null )
299         {
300             throw new IllegalStateException( "Cannot find Maven application "
301                 + "directory. Specify 'maven.home' system property" );
302         }
303 
304         return new File( mavenHome );
305     }
306 
307     private File findLocalRepo()
308     {
309         String basedir = System.getProperty( "maven.repo.local", "" );
310 
311         if ( StringUtils.isNotEmpty( basedir ) )
312         {
313             return new File( basedir );
314         }
315 
316         return null;
317     }
318 
319     private File getBasedirForBuild()
320         throws URISyntaxException
321     {
322         StackTraceElement element = new NullPointerException().getStackTrace()[1];
323         String methodName = element.getMethodName();
324 
325         String dirName = StringUtils.addAndDeHump( methodName );
326 
327         ClassLoader cloader = Thread.currentThread().getContextClassLoader();
328         URL dirResource = cloader.getResource( dirName );
329 
330         if ( dirResource == null )
331         {
332             throw new IllegalStateException( "Project: " + dirName + " for test method: " + methodName
333                 + " is missing." );
334         }
335 
336         return new File( new URI( dirResource.toString() ).getPath() );
337     }
338 
339     // this is just a debugging helper for separating unit test output...
340     private void logTestStart()
341     {
342         NullPointerException npe = new NullPointerException();
343         StackTraceElement element = npe.getStackTrace()[1];
344 
345         System.out.println( "Starting: " + element.getMethodName() );
346     }
347     
348     private Properties getProperties()
349     {
350         Properties properties = new Properties();
351         if ( !System.getProperty( "java.version" ).startsWith( "1." ) )
352         {
353             properties.put( "maven.compiler.source", "1.7" );
354             properties.put( "maven.compiler.target", "1.7" );
355         }
356         
357         String httpProtocols = System.getProperty( "https.protocols" );
358         if ( httpProtocols != null )
359         {
360             properties.put( "https.protocols", httpProtocols );
361         }
362         return properties;
363     }
364 }