1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  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,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.dependency.its;
20  
21  import java.io.File;
22  import java.net.MalformedURLException;
23  import java.util.ArrayList;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Properties;
27  
28  import org.apache.maven.project.MavenProject;
29  import org.apache.maven.shared.invoker.InvocationRequest;
30  import org.apache.maven.shared.invoker.InvocationResult;
31  import org.apache.maven.shared.test.plugin.BuildTool;
32  import org.apache.maven.shared.test.plugin.PluginTestTool;
33  import org.apache.maven.shared.test.plugin.ProjectTool;
34  import org.apache.maven.shared.test.plugin.TestToolsException;
35  import org.codehaus.classworlds.ClassRealm;
36  import org.codehaus.plexus.PlexusContainer;
37  import org.codehaus.plexus.PlexusTestCase;
38  import org.codehaus.plexus.util.StringUtils;
39  
40  /**
41   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
42   *         Copied from the Eclipse
43   *         AbstractEclipsePluginTestCase v2.4
44   * @version $Id: AbstractDependencyPluginITCase.java 556442
45   *          2007-07-15 20:20:23Z dantran $
46   */
47  public abstract class AbstractDependencyPluginITCase
48      extends PlexusTestCase
49  {
50  
51      private BuildTool buildTool;
52  
53      private ProjectTool projectTool;
54  
55      /**
56       * Test repository directory.
57       */
58      protected static File localRepositoryDirectory = getTestFile( "target/test-classes/m2repo" );
59  
60      /**
61       * Pom File
62       */
63      protected static File PomFile = new File( getBasedir(), "pom.xml" );
64  
65      /**
66       * Group-Id for running test builds.
67       */
68      protected static final String GROUP_ID = "org.apache.maven.plugins";
69  
70      /**
71       * Artifact-Id for running test builds.
72       */
73      protected static final String ARTIFACT_ID = "maven-dependency-plugin";
74  
75      /**
76       * Version under which the plugin was installed to the
77       * test-time local repository for running test builds.
78       */
79      protected static final String VERSION = "test";
80  
81      private static final String BUILD_OUTPUT_DIRECTORY = "target/surefire-reports/build-output";
82  
83      private static boolean installed = false;
84  
85      /**
86       * @see org.codehaus.plexus.PlexusTestCase#setUp()
87       */
88      protected void setUp ()
89          throws Exception
90      {
91          if ( !installed )
92          {
93              System.out
94                  .println( "*** Running test builds; output will be directed to: " + BUILD_OUTPUT_DIRECTORY + "\n" );
95          }
96  
97          super.setUp();
98  
99          buildTool = (BuildTool) lookup( BuildTool.ROLE, "default" );
100 
101         projectTool = (ProjectTool) lookup( ProjectTool.ROLE, "default" );
102 
103         String mavenHome = System.getProperty( "maven.home" );
104 
105         // maven.home is set by surefire when the test is
106         // run with maven, but better make the test run in
107         // IDEs without
108         // the need of additional properties
109         if ( mavenHome == null )
110         {
111             String path = System.getProperty( "java.library.path" );
112             String[] paths = StringUtils.split( path, System.getProperty( "path.separator" ) );
113             for ( int j = 0; j < paths.length; j++ )
114             {
115                 String pt = paths[j];
116                 if ( new File( pt, "mvn" ).exists() )
117                 {
118                     System.setProperty( "maven.home", new File( pt ).getAbsoluteFile().getParent() );
119                     break;
120                 }
121 
122             }
123         }
124 
125         System.setProperty( "MAVEN_TERMINATE_CMD", "on" );
126 
127         synchronized ( AbstractDependencyPluginITCase.class )
128         {
129             if ( !installed )
130             {
131                 PluginTestTool pluginTestTool = (PluginTestTool) lookup( PluginTestTool.ROLE, "default" );
132 
133                 localRepositoryDirectory = pluginTestTool
134                     .preparePluginForUnitTestingWithMavenBuilds( PomFile, "test", localRepositoryDirectory );
135 
136                 System.out.println( "*** Installed test-version of the Dependency plugin to: "
137                     + localRepositoryDirectory + "\n" );
138 
139                 installed = true;
140             }
141         }
142 
143     }
144 
145     /**
146      * @see org.codehaus.plexus.PlexusTestCase#tearDown()
147      */
148     protected void tearDown ()
149         throws Exception
150     {
151         super.tearDown();
152 
153         List containers = new ArrayList();
154 
155         containers.add( getContainer() );
156 
157         for ( Iterator iter = containers.iterator(); iter.hasNext(); )
158         {
159             PlexusContainer container = (PlexusContainer) iter.next();
160 
161             if ( container != null )
162             {
163                 container.dispose();
164 
165                 ClassRealm realm = container.getContainerRealm();
166 
167                 if ( realm != null )
168                 {
169                     realm.getWorld().disposeRealm( realm.getId() );
170                 }
171             }
172         }
173     }
174 
175     /**
176      * Execute the plugin with no properties
177      * 
178      * @param projectName project directory
179      * @param goalList comma separated list of goals to
180      *            execute
181      * @throws Exception any exception generated during test
182      */
183     protected void testProject ( String projectName, String goalList )
184         throws Exception
185     {
186         Properties props = new Properties();
187         testProject( projectName, props, goalList );
188     }
189 
190     /**
191      * Execute the plugin.
192      * 
193      * @param projectName project directory
194      * @param properties additional properties
195      * @param goalList comma separated list of goals to
196      *            execute
197      * @throws Exception any exception generated during test
198      */
199     protected void testProject ( String projectName, Properties properties, String goalList )
200         throws Exception
201     {
202         File theBasedir = getTestFile( "target/test-classes/its/" + projectName );
203 
204         File pom = new File( theBasedir, "pom.xml" );
205 
206         String[] goal = goalList.split( "," );
207 
208         List goals = new ArrayList();
209 
210         for ( int i = 0; i < goal.length; i++ )
211         {
212             goals.add( goal[i] );
213         }
214 
215         executeMaven( pom, properties, goals );
216 
217         // MavenProject project = readProject( pom );
218 
219         /*
220          * String outputDirPath = IdeUtils.getPluginSetting(
221          * project, "maven-dependency-plugin", "outputDir",
222          * null ); File outputDir; File projectOutputDir =
223          * basedir;
224          * 
225          * if ( outputDirPath == null ) { outputDir =
226          * basedir; } else { outputDir = new File( basedir,
227          * outputDirPath ); outputDir.mkdirs();
228          * projectOutputDir = new File( outputDir,
229          * project.getArtifactId() ); }
230          */
231     }
232 
233     protected File getOutputDirectory ( String projectName )
234     {
235         return getTestFile( "target/test-classes/projects/" + projectName );
236     }
237 
238     protected void executeMaven ( File pom, Properties properties, List goals )
239         throws TestToolsException, ExecutionFailedException
240     {
241         executeMaven( pom, properties, goals, true );
242     }
243 
244     protected void executeMaven ( File pom, Properties properties, List goals, boolean switchLocalRepo )
245         throws TestToolsException, ExecutionFailedException
246     {
247         // insert the test property to activate the test
248         // profile
249         properties.setProperty( "test", "true" );
250         new File( BUILD_OUTPUT_DIRECTORY ).mkdirs();
251 
252         NullPointerException npe = new NullPointerException();
253         StackTraceElement[] trace = npe.getStackTrace();
254 
255         File buildLog = null;
256 
257         for ( int i = 0; i < trace.length; i++ )
258         {
259             StackTraceElement element = trace[i];
260 
261             String methodName = element.getMethodName();
262 
263             if ( methodName.startsWith( "test" ) && !methodName.equals( "testProject" ) )
264             {
265                 String classname = element.getClassName();
266 
267                 buildLog = new File( BUILD_OUTPUT_DIRECTORY, classname + "_" + element.getMethodName() + ".build.log" );
268 
269                 break;
270             }
271         }
272 
273         if ( buildLog == null )
274         {
275             buildLog = new File( BUILD_OUTPUT_DIRECTORY, "unknown.build.log" );
276         }
277 
278         InvocationRequest request = buildTool.createBasicInvocationRequest( pom, properties, goals, buildLog );
279         request.setUpdateSnapshots( false );
280         request.setShowErrors( true );
281 
282         request.setDebug( true );
283 
284         if ( switchLocalRepo )
285         {
286             request.setLocalRepositoryDirectory( localRepositoryDirectory );
287         }
288 
289         InvocationResult result = buildTool.executeMaven( request );
290 
291         if ( result.getExitCode() != 0 )
292         {
293             String buildLogUrl = buildLog.getAbsolutePath();
294 
295             try
296             {
297                 
298                 buildLogUrl = buildLog.toURI().toURL().toExternalForm();
299             }
300             catch ( MalformedURLException e )
301             {
302             }
303 
304             throw new ExecutionFailedException( "Failed to execute build.\nPOM: " + pom + "\nGoals: "
305                 + StringUtils.join( goals.iterator(), ", " ) + "\nExit Code: " + result.getExitCode() + "\nError: "
306                 + result.getExecutionException() + "\nBuild Log: " + buildLogUrl + "\n", result );
307         }
308     }
309 
310     protected MavenProject readProject ( File pom )
311         throws TestToolsException
312     {
313         return projectTool.readProject( pom, localRepositoryDirectory );
314     }
315 
316     protected String getPluginCLISpecification ()
317     {
318         String pluginSpec = GROUP_ID + ":" + ARTIFACT_ID + ":";
319 
320         // String pluginVersion = System.getProperty(
321         // "pluginVersion" );
322         //        
323         // if ( pluginVersion != null )
324         // {
325         // pluginSpec += pluginVersion + ":";
326         // }
327         //
328         // System.out.println( "\n\nUsing Eclipse plugin
329         // version: " + pluginVersion + "\n\n" );
330 
331         // try using the test-version installed during
332         // setUp()
333         pluginSpec += VERSION + ":";
334 
335         return pluginSpec;
336     }
337 }