1   package org.apache.maven.artifact.resolver;
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.util.ArrayList;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.LinkedHashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
33  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
34  import org.apache.maven.artifact.metadata.ResolutionGroup;
35  import org.apache.maven.artifact.repository.ArtifactRepository;
36  import org.apache.maven.artifact.versioning.ArtifactVersion;
37  import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
38  import org.codehaus.plexus.component.repository.ComponentDescriptor;
39  
40  // It would be cool if there was a hook that i could use to setup a test environment.
41  // I want to setup a local/remote repositories for testing but i don't want to have
42  // to change them when i change the layout of the repositories. So i want to generate
43  // the structure i want to test by using the artifact handler manager which dictates
44  // the layout used for a particular artifact type.
45  
46  /**
47   * @author Jason van Zyl
48   */
49  public class ArtifactResolverTest
50      extends AbstractArtifactComponentTestCase
51  {
52      private DefaultArtifactResolver artifactResolver;
53  
54      private Artifact projectArtifact;
55  
56      @Override
57      protected void setUp()
58          throws Exception
59      {
60          super.setUp();
61  
62          artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class );
63  
64          projectArtifact = createLocalArtifact( "project", "3.0" );
65      }
66      
67      @Override
68      protected void tearDown()
69          throws Exception
70      {
71          artifactFactory = null;
72          projectArtifact = null;
73          super.tearDown();
74      }
75  
76      @Override
77      protected String component()
78      {
79          return "resolver";
80      }
81  
82      public void testResolutionOfASingleArtifactWhereTheArtifactIsPresentInTheLocalRepository()
83          throws Exception
84      {
85          Artifact a = createLocalArtifact( "a", "1.0" );
86  
87          artifactResolver.resolve( a, remoteRepositories(), localRepository() );
88  
89          assertLocalArtifactPresent( a );
90      }
91  
92      public void testResolutionOfASingleArtifactWhereTheArtifactIsNotPresentLocallyAndMustBeRetrievedFromTheRemoteRepository()
93          throws Exception
94      {
95          Artifact b = createRemoteArtifact( "b", "1.0-SNAPSHOT" );
96          deleteLocalArtifact( b );
97          artifactResolver.resolve( b, remoteRepositories(), localRepository() );
98          assertLocalArtifactPresent( b );
99      }
100 
101     @Override
102     protected Artifact createArtifact( String groupId, String artifactId, String version, String type )
103         throws Exception
104     {
105         // for the anonymous classes
106         return super.createArtifact( groupId, artifactId, version, type );
107     }
108 
109     public void testTransitiveResolutionWhereAllArtifactsArePresentInTheLocalRepository()
110         throws Exception
111     {
112         Artifact g = createLocalArtifact( "g", "1.0" );
113 
114         Artifact h = createLocalArtifact( "h", "1.0" );
115 
116         ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(), localRepository(), null );
117 
118         printErrors( result );
119 
120         assertEquals( 2, result.getArtifacts().size() );
121 
122         assertTrue( result.getArtifacts().contains( g ) );
123 
124         assertTrue( result.getArtifacts().contains( h ) );
125 
126         assertLocalArtifactPresent( g );
127 
128         assertLocalArtifactPresent( h );
129     }
130 
131     public void testTransitiveResolutionWhereAllArtifactsAreNotPresentInTheLocalRepositoryAndMustBeRetrievedFromTheRemoteRepository()
132         throws Exception
133     {
134         Artifact i = createRemoteArtifact( "i", "1.0-SNAPSHOT" );
135         deleteLocalArtifact( i );
136 
137         Artifact j = createRemoteArtifact( "j", "1.0-SNAPSHOT" );
138         deleteLocalArtifact( j );
139 
140         ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( i ), projectArtifact, remoteRepositories(), localRepository(), null );
141 
142         printErrors( result );
143 
144         assertEquals( 2, result.getArtifacts().size() );
145 
146         assertTrue( result.getArtifacts().contains( i ) );
147 
148         assertTrue( result.getArtifacts().contains( j ) );
149 
150         assertLocalArtifactPresent( i );
151 
152         assertLocalArtifactPresent( j );
153     }
154 
155     public void testResolutionFailureWhenArtifactNotPresentInRemoteRepository()
156         throws Exception
157     {
158         Artifact k = createArtifact( "k", "1.0" );
159 
160         try
161         {
162             artifactResolver.resolve( k, remoteRepositories(), localRepository() );
163             fail( "Resolution succeeded when it should have failed" );
164         }
165         catch ( ArtifactNotFoundException expected )
166         {
167             assertTrue( true );
168         }
169     }
170 
171     public void testResolutionOfAnArtifactWhereOneRemoteRepositoryIsBadButOneIsGood()
172         throws Exception
173     {
174         Artifact l = createRemoteArtifact( "l", "1.0-SNAPSHOT" );
175         deleteLocalArtifact( l );
176 
177         List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
178         repositories.add( remoteRepository() );
179         repositories.add( badRemoteRepository() );
180 
181         artifactResolver.resolve( l, repositories, localRepository() );
182 
183         assertLocalArtifactPresent( l );
184     }
185 
186     public void testTransitiveResolutionOrder()
187         throws Exception
188     {
189         Artifact m = createLocalArtifact( "m", "1.0" );
190 
191         Artifact n = createLocalArtifact( "n", "1.0" );
192 
193         ArtifactMetadataSource mds = new ArtifactMetadataSource()
194         {
195             public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
196                                              List<ArtifactRepository> remoteRepositories )
197                 throws ArtifactMetadataRetrievalException
198             {
199                 Set dependencies = new HashSet();
200 
201                 return new ResolutionGroup( artifact, dependencies, remoteRepositories );
202             }
203 
204             public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact,
205                                                                     ArtifactRepository localRepository,
206                                                                     List<ArtifactRepository> remoteRepositories )
207                 throws ArtifactMetadataRetrievalException
208             {
209                 throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
210             }
211 
212             public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
213                                                                                             Artifact artifact,
214                                                                                             ArtifactRepository localRepository,
215                                                                                             ArtifactRepository remoteRepository )
216                 throws ArtifactMetadataRetrievalException
217             {
218                 throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
219             }
220 
221             public ResolutionGroup retrieve( MetadataResolutionRequest request )
222                 throws ArtifactMetadataRetrievalException
223             {
224                 return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
225             }
226 
227             public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
228                 throws ArtifactMetadataRetrievalException
229             {
230                 return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
231             }
232         };
233 
234         ArtifactResolutionResult result = null;
235 
236         Set set = new LinkedHashSet();
237         set.add( n );
238         set.add( m );
239 
240         result =
241             artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
242 
243         printErrors( result );
244 
245         Iterator i = result.getArtifacts().iterator();
246         assertEquals( "n should be first", n, i.next() );
247         assertEquals( "m should be second", m, i.next() );
248 
249         // inverse order
250         set = new LinkedHashSet();
251         set.add( m );
252         set.add( n );
253 
254         result =
255             artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
256 
257         printErrors( result );
258 
259         i = result.getArtifacts().iterator();
260         assertEquals( "m should be first", m, i.next() );
261         assertEquals( "n should be second", n, i.next() );
262     }
263 
264     private void printErrors( ArtifactResolutionResult result )
265     {
266         if ( result.hasMissingArtifacts() )
267         {
268             for ( Artifact artifact : result.getMissingArtifacts() )
269             {
270                 System.err.println( "Missing: " + artifact );
271             }
272         }
273 
274         if ( result.hasExceptions() )
275         {
276             for ( Exception e : result.getExceptions() )
277             {
278                 e.printStackTrace();
279             }
280         }
281     }
282 
283 }