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