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 org.apache.commons.lang.SystemUtils;
23  import org.apache.maven.artifact.Artifact;
24  import org.apache.maven.artifact.DefaultArtifact;
25  import org.apache.maven.artifact.handler.ArtifactHandler;
26  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
27  import org.apache.maven.artifact.versioning.VersionRange;
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.ProjectTool;
33  import org.apache.maven.shared.test.plugin.RepositoryTool;
34  import org.apache.maven.shared.test.plugin.TestToolsException;
35  import org.codehaus.plexus.PlexusTestCase;
36  import java.io.File;
37  import java.util.Arrays;
38  import java.util.Collections;
39  import java.util.HashSet;
40  import java.util.List;
41  import java.util.Properties;
42  import java.util.Set;
43  
44  /**
45   * Tests <code>DefaultProjectDependencyAnalyzer</code>.
46   *
47   * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
48   * @version $Id: DefaultProjectDependencyAnalyzerTest.java 1722332 2015-12-30 14:17:31Z 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()
82                                        .getAbsoluteFile();
83              System.out.println( "Local repository: " + localRepo );
84          }
85  
86          analyzer = (ProjectDependencyAnalyzer) lookup( ProjectDependencyAnalyzer.ROLE );
87      }
88  
89      // tests ------------------------------------------------------------------
90  
91      public void testPom()
92          throws TestToolsException, ProjectDependencyAnalyzerException
93      {
94          compileProject( "pom/pom.xml" );
95  
96          MavenProject project = getProject( "pom/pom.xml" );
97  
98          ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
99  
100         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
101 
102         assertEquals( expectedAnalysis, actualAnalysis );
103     }
104 
105     public void testJarWithNoDependencies()
106         throws TestToolsException, ProjectDependencyAnalyzerException
107     {
108         compileProject( "jarWithNoDependencies/pom.xml" );
109 
110         MavenProject project = getProject( "jarWithNoDependencies/pom.xml" );
111 
112         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
113 
114         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
115 
116         assertEquals( expectedAnalysis, actualAnalysis );
117     }
118 
119     public void testJava8methodRefs()
120         throws TestToolsException, ProjectDependencyAnalyzerException
121     {
122         if ( !SystemUtils.isJavaVersionAtLeast( 180 ) )
123         {
124             return;
125         }
126 
127         // Only visible through constant pool analysis (supported for JDK8+)
128         compileProject( "java8methodRefs/pom.xml" );
129 
130         MavenProject project = getProject( "java8methodRefs/pom.xml" );
131 
132         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
133 
134         Artifact project1 = createArtifact( "commons-io", "commons-io", "jar", "2.4", "compile" );
135         Artifact project2 = createArtifact( "commons-lang", "commons-lang", "jar", "2.6", "compile" );
136         Set<Artifact> usedDeclaredArtifacts = new HashSet<Artifact>( Arrays.asList( project1, project2 ) );
137 
138         ProjectDependencyAnalysis expectedAnalysis =
139             new ProjectDependencyAnalysis( usedDeclaredArtifacts, new HashSet<Artifact>(), new HashSet<Artifact>() );
140 
141         assertEquals( expectedAnalysis, actualAnalysis );
142     }
143 
144 
145     public void testInlinedStaticReference()
146         throws TestToolsException, ProjectDependencyAnalyzerException
147     {
148         if ( !SystemUtils.isJavaVersionAtLeast( 180 ) )
149         {
150             return;
151         }
152 
153         // Only visible through constant pool analysis (supported for JDK8+)
154         compileProject( "inlinedStaticReference/pom.xml" );
155 
156         MavenProject project = getProject( "inlinedStaticReference/pom.xml" );
157 
158         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
159 
160         Artifact project1 = createArtifact( "dom4j", "dom4j", "jar", "1.6.1", "compile" );
161         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
162 
163         ProjectDependencyAnalysis expectedAnalysis =
164             new ProjectDependencyAnalysis( usedDeclaredArtifacts, new HashSet<Artifact>(), new HashSet<Artifact>() );
165 
166         assertEquals( expectedAnalysis, actualAnalysis );
167     }
168 
169     public void testJarWithCompileDependency()
170         throws TestToolsException, ProjectDependencyAnalyzerException
171     {
172         compileProject( "jarWithCompileDependency/pom.xml" );
173 
174         MavenProject project2 = getProject( "jarWithCompileDependency/project2/pom.xml" );
175 
176         if ( project2.getBuild().getOutputDirectory().contains( "${" ) )
177         {
178             // if Maven version used as dependency is upgraded to >= 2.2.0 
179             throw new TestToolsException( "output directory was not interpolated: " + project2.getBuild()
180                                                                                               .getOutputDirectory() );
181         }
182 
183         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
184 
185         Artifact project1 =
186             createArtifact( "org.apache.maven.shared.dependency-analyzer.tests", "jarWithCompileDependency1", "jar",
187                             "1.0", "compile" );
188         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
189         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
190 
191         assertEquals( expectedAnalysis, actualAnalysis );
192     }
193 
194     public void testForceDeclaredDependenciesUsage()
195         throws TestToolsException, ProjectDependencyAnalyzerException
196     {
197         compileProject( "jarWithTestDependency/pom.xml" );
198 
199         MavenProject project2 = getProject( "jarWithTestDependency/project2/pom.xml" );
200 
201         ProjectDependencyAnalysis analysis = analyzer.analyze( project2 );
202 
203         try
204         {
205             analysis.forceDeclaredDependenciesUsage( new String[] {
206                 "org.apache.maven.shared.dependency-analyzer.tests:jarWithTestDependency1" } );
207             fail( "failure expected since junit dependency is declared-used" );
208         }
209         catch ( ProjectDependencyAnalyzerException pdae )
210         {
211             assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
212                 + "declared but already detected as used: "
213                 + "[org.apache.maven.shared.dependency-analyzer.tests:jarWithTestDependency1]" ) );
214         }
215 
216         try
217         {
218             analysis.forceDeclaredDependenciesUsage( new String[]{ "undefined:undefined" } );
219             fail( "failure expected since undefined dependency is not declared" );
220         }
221         catch ( ProjectDependencyAnalyzerException pdae )
222         {
223             assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
224                 + "not declared: [undefined:undefined]" ) );
225         }
226     }
227 
228     public void testJarWithTestDependency()
229         throws TestToolsException, ProjectDependencyAnalyzerException
230     {
231         compileProject( "jarWithTestDependency/pom.xml" );
232 
233         MavenProject project2 = getProject( "jarWithTestDependency/project2/pom.xml" );
234 
235         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
236 
237         Artifact project1 =
238             createArtifact( "org.apache.maven.shared.dependency-analyzer.tests", "jarWithTestDependency1", "jar", "1.0",
239                             "test" );
240         Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "test" );
241 
242         ProjectDependencyAnalysis expectedAnalysis;
243         if ( SystemUtils.isJavaVersionAtLeast( 180 ) )
244         {
245             Set<Artifact> usedDeclaredArtifacts = new HashSet<Artifact>( Arrays.asList( project1, junit ) );
246             expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
247         }
248         else
249         {
250             // With JDK 7 and earlier, not all deps are identified correctly
251             Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
252             Set<Artifact> unusedDeclaredArtifacts = Collections.singleton( junit );
253             expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, unusedDeclaredArtifacts );
254         }
255 
256         assertEquals( expectedAnalysis, actualAnalysis );
257     }
258 
259     public void testJarWithXmlTransitiveDependency()
260         throws TestToolsException, ProjectDependencyAnalyzerException
261     {
262         compileProject( "jarWithXmlTransitiveDependency/pom.xml" );
263 
264         MavenProject project = getProject( "jarWithXmlTransitiveDependency/pom.xml" );
265 
266         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
267 
268         Artifact jdom = createArtifact( "dom4j", "dom4j", "jar", "1.6.1", "compile" );
269         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( jdom );
270 
271         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
272 
273         // MSHARED-47: usedUndeclaredArtifacts=[xml-apis:xml-apis:jar:1.0.b2:compile]
274         //assertEquals( expectedAnalysis, actualAnalysis );
275     }
276 
277     public void testMultimoduleProject()
278         throws TestToolsException, ProjectDependencyAnalyzerException
279     {
280         compileProject( "multimoduleProject/pom.xml" );
281 
282         // difficult to create multi-module project with Maven 2.x, so here's hacky solution
283         // to get a inter-module dependency
284         MavenProject project = getProject( "multimoduleProject/module2/pom.xml" );
285         @SuppressWarnings( "unchecked" ) Set<Artifact> dependencyArtifacts = project.getArtifacts();
286         for ( Artifact artifact : dependencyArtifacts )
287         {
288             if ( artifact.getArtifactId()
289                          .equals( "test-module1" ) )
290             {
291                 File dir = getTestFile( "target/test-classes/", "multimoduleProject/module1/target/classes/" );
292                 artifact.setFile( dir );
293             }
294         }
295 
296         ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
297 
298         Artifact junit = createArtifact( "org.apache.maven.its.dependency", "test-module1", "jar", "1.0", "compile" );
299         Set<Artifact> usedDeclaredArtifacts = Collections.singleton( junit );
300 
301         ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null );
302 
303         assertEquals( expectedAnalysis, actualAnalysis );
304     }
305 
306     // private methods --------------------------------------------------------
307 
308     private void compileProject( String pomPath )
309         throws TestToolsException
310     {
311         File pom = getTestFile( "target/test-classes/", pomPath );
312         Properties properties = new Properties();
313         List<String> goals = Arrays.asList( "clean", "install" );
314         File log = new File( pom.getParentFile(), "build.log" );
315 
316         // TODO: don't install test artifacts to local repository
317         InvocationRequest request = buildTool.createBasicInvocationRequest( pom, properties, goals, log );
318         request.setLocalRepositoryDirectory( localRepo );
319         InvocationResult result = buildTool.executeMaven( request );
320 
321         assertNull( "Error compiling test project", result.getExecutionException() );
322         assertEquals( "Error compiling test project", 0, result.getExitCode() );
323     }
324 
325     private MavenProject getProject( String pomPath )
326         throws TestToolsException
327     {
328         File pom = getTestFile( "target/test-classes/", pomPath );
329 
330         return projectTool.readProjectWithDependencies( pom );
331     }
332 
333     private Artifact createArtifact( String groupId, String artifactId, String type, String version, String scope )
334     {
335         VersionRange versionRange = VersionRange.createFromVersion( version );
336         ArtifactHandler handler = new DefaultArtifactHandler();
337 
338         return new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, handler );
339     }
340 }