View Javadoc
1   package org.apache.maven.shared.dependency.analyzer;
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.util.Arrays;
24  import java.util.Collections;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Properties;
28  import java.util.Set;
29  
30  import org.apache.maven.artifact.Artifact;
31  import org.apache.maven.artifact.DefaultArtifact;
32  import org.apache.maven.artifact.handler.ArtifactHandler;
33  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
34  import org.apache.maven.artifact.versioning.VersionRange;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.shared.invoker.InvocationRequest;
37  import org.apache.maven.shared.invoker.InvocationResult;
38  import org.apache.maven.shared.test.plugin.BuildTool;
39  import org.apache.maven.shared.test.plugin.ProjectTool;
40  import org.apache.maven.shared.test.plugin.RepositoryTool;
41  import org.apache.maven.shared.test.plugin.TestToolsException;
42  import org.codehaus.plexus.PlexusTestCase;
43  
44  /**
45   * Tests <code>DefaultProjectDependencyAnalyzer</code>.
46   * 
47   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
48   * @version $Id: DefaultProjectDependencyAnalyzerTest.java 1635191 2014-10-29 16:33:52Z andham $
49   * @see DefaultProjectDependencyAnalyzer
50   */
51  public class DefaultProjectDependencyAnalyzerTest
52      extends PlexusTestCase
53  {
54      // fields -----------------------------------------------------------------
55  
56      private BuildTool buildTool;
57  
58      private ProjectTool projectTool;
59  
60      private ProjectDependencyAnalyzer analyzer;
61  
62      private static File localRepo;
63  
64      // TestCase methods -------------------------------------------------------
65  
66      /*
67       * @see org.codehaus.plexus.PlexusTestCase#setUp()
68       */
69      protected void setUp()
70          throws Exception
71      {
72          super.setUp();
73  
74          buildTool = (BuildTool) lookup( BuildTool.ROLE );
75  
76          projectTool = (ProjectTool) lookup( ProjectTool.ROLE );
77  
78          if ( localRepo == null )
79          {
80              RepositoryTool repositoryTool = (RepositoryTool) lookup( RepositoryTool.ROLE );
81              localRepo = repositoryTool.findLocalRepositoryDirectory().getAbsoluteFile();
82              System.out.println( "Local repository: " + localRepo );
83          }
84  
85          analyzer = (ProjectDependencyAnalyzer) lookup( ProjectDependencyAnalyzer.ROLE );
86      }
87  
88      // tests ------------------------------------------------------------------
89  
90      public void testPom()
91          throws TestToolsException, ProjectDependencyAnalyzerException
92      {
93          compileProject( "pom/pom.xml" );
94  
95          MavenProject project = getProject( "pom/pom.xml" );
96  
97          ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
98  
99          ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
100 
101         assertEquals( expectedAnalysis, actualAnalysis );
102     }
103 
104     public void testJarWithNoDependencies()
105         throws TestToolsException, ProjectDependencyAnalyzerException
106     {
107         compileProject( "jarWithNoDependencies/pom.xml" );
108 
109         MavenProject project = getProject( "jarWithNoDependencies/pom.xml" );
110 
111         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
112 
113         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
114 
115         assertEquals( expectedAnalysis, actualAnalysis );
116     }
117 
118     public void testJarWithCompileDependency()
119         throws TestToolsException, ProjectDependencyAnalyzerException
120     {
121         compileProject( "jarWithCompileDependency/pom.xml" );
122 
123         MavenProject project2 = getProject( "jarWithCompileDependency/project2/pom.xml" );
124 
125         if ( project2.getBuild().getOutputDirectory().contains( "${" ) )
126         {
127             // if Maven version used as dependency is upgraded to >= 2.2.0 
128             throw new TestToolsException( "output directory was not interpolated: "
129                 + project2.getBuild().getOutputDirectory() );
130         }
131 
132         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
133 
134         Artifact project1 =
135             createArtifact( "org.apache.maven.shared.dependency-analyzer.tests", "jarWithCompileDependency1", "jar",
136                             "1.0", "compile" );
137         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
138         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
139 
140         assertEquals( expectedAnalysis, actualAnalysis );
141     }
142 
143     public void testJarWithTestDependency()
144         throws TestToolsException, ProjectDependencyAnalyzerException
145     {
146         compileProject( "jarWithTestDependency/pom.xml" );
147 
148         MavenProject project2 = getProject( "jarWithTestDependency/project2/pom.xml" );
149 
150         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
151 
152         Artifact project1 =
153             createArtifact( "org.apache.maven.shared.dependency-analyzer.tests", "jarWithTestDependency1", "jar",
154                             "1.0", "test" );
155         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
156 
157         Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "test" );
158         Set<Artifact> unusedDeclaredArtifacts = Collections.singleton( junit );
159 
160         ProjectDependencyAnalysis expectedAnalysis =
161             new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, unusedDeclaredArtifacts );
162 
163         assertEquals( expectedAnalysis, actualAnalysis );
164 
165         // MSHARED-253: force used dependency (which is actually used but not detected)
166         ProjectDependencyAnalysis forcedAnalysis =
167             actualAnalysis.forceDeclaredDependenciesUsage( new String[] { "junit:junit" } );
168 
169         usedDeclaredArtifacts = new HashSet<Artifact>( Arrays.asList( project1, junit ) );
170         expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
171 
172         assertEquals( expectedAnalysis, forcedAnalysis );
173 
174         try
175         {
176             forcedAnalysis.forceDeclaredDependenciesUsage( new String[]{ "junit:junit" } );
177             fail( "failure expected since junit dependency is declared-used" );
178         }
179         catch( ProjectDependencyAnalyzerException pdae )
180         {
181             assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
182                                                         + "declared but already detected as used: [junit:junit]" ) );
183         }
184 
185         try
186         {
187             forcedAnalysis.forceDeclaredDependenciesUsage( new String[]{ "undefined:undefined" } );
188             fail( "failure expected since undefined dependency is not declared" );
189         }
190         catch( ProjectDependencyAnalyzerException pdae )
191         {
192             assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
193                                                         + "not declared: [undefined:undefined]" ) );
194         }
195     }
196 
197     public void testJarWithXmlTransitiveDependency()
198         throws TestToolsException, ProjectDependencyAnalyzerException
199     {
200         compileProject( "jarWithXmlTransitiveDependency/pom.xml" );
201 
202         MavenProject project = getProject( "jarWithXmlTransitiveDependency/pom.xml" );
203 
204         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
205 
206         Artifact jdom = createArtifact( "dom4j", "dom4j", "jar", "1.6.1", "compile" );
207         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( jdom );
208 
209         ProjectDependencyAnalysis expectedAnalysis =
210             new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
211 
212         // MSHARED-47: usedUndeclaredArtifacts=[xml-apis:xml-apis:jar:1.0.b2:compile]
213         //assertEquals( expectedAnalysis, actualAnalysis );
214     }
215 
216     public void testMultimoduleProject()
217         throws TestToolsException, ProjectDependencyAnalyzerException
218     {
219         compileProject( "multimoduleProject/pom.xml" );
220 
221         // difficult to create multi-module project with Maven 2.x, so here's hacky solution
222         // to get a inter-module dependency
223         MavenProject project = getProject( "multimoduleProject/module2/pom.xml" );
224         @SuppressWarnings( "unchecked" )
225         Set<Artifact> dependencyArtifacts = project.getArtifacts();
226         for ( Artifact artifact : dependencyArtifacts )
227         {
228             if ( artifact.getArtifactId().equals( "test-module1" ) )
229             {
230                 File dir = getTestFile( "target/test-classes/", "multimoduleProject/module1/target/classes/" );
231                 artifact.setFile( dir );
232             }
233         }
234 
235         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
236 
237         Artifact junit = createArtifact( "org.apache.maven.its.dependency", "test-module1", "jar", "1.0", "compile" );
238         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( junit );
239 
240         ProjectDependencyAnalysis expectedAnalysis =
241             new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
242 
243         assertEquals( expectedAnalysis, actualAnalysis );
244     }
245 
246     // private methods --------------------------------------------------------
247 
248     private void compileProject( String pomPath )
249         throws TestToolsException
250     {
251         File pom = getTestFile( "target/test-classes/", pomPath );
252         Properties properties = new Properties();
253         List<String> goals = Arrays.asList( "clean", "install" );
254         File log = new File( pom.getParentFile(), "build.log" );
255 
256         // TODO: don't install test artifacts to local repository
257         InvocationRequest request = buildTool.createBasicInvocationRequest( pom, properties, goals, log );
258         request.setLocalRepositoryDirectory( localRepo );
259         InvocationResult result = buildTool.executeMaven( request );
260 
261         assertNull( "Error compiling test project", result.getExecutionException() );
262         assertEquals( "Error compiling test project", 0, result.getExitCode() );
263     }
264 
265     private MavenProject getProject( String pomPath )
266         throws TestToolsException
267     {
268         File pom = getTestFile( "target/test-classes/", pomPath );
269 
270         return projectTool.readProjectWithDependencies( pom );
271     }
272 
273     private Artifact createArtifact( String groupId, String artifactId, String type, String version, String scope )
274     {
275         VersionRange versionRange = VersionRange.createFromVersion( version );
276         ArtifactHandler handler = new DefaultArtifactHandler();
277 
278         return new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, handler );
279     }
280 }