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.project;
20  
21  import java.io.File;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.concurrent.atomic.AtomicReference;
25  
26  import org.apache.maven.artifact.InvalidRepositoryException;
27  import org.apache.maven.bridge.MavenRepositorySystem;
28  import org.apache.maven.model.Dependency;
29  import org.apache.maven.model.Parent;
30  import org.apache.maven.model.resolution.ModelResolver;
31  import org.apache.maven.model.resolution.UnresolvableModelException;
32  import org.eclipse.aether.DefaultRepositorySystemSession;
33  import org.eclipse.aether.RepositorySystem;
34  import org.eclipse.aether.impl.RemoteRepositoryManager;
35  import org.eclipse.aether.repository.RemoteRepository;
36  import org.junit.jupiter.api.Test;
37  
38  import static org.codehaus.plexus.testing.PlexusExtension.getBasedir;
39  import static org.hamcrest.MatcherAssert.assertThat;
40  import static org.hamcrest.Matchers.containsString;
41  import static org.junit.jupiter.api.Assertions.assertEquals;
42  import static org.junit.jupiter.api.Assertions.assertNotNull;
43  import static org.junit.jupiter.api.Assertions.assertThrows;
44  
45  /**
46   * Test cases for the project {@code ModelResolver} implementation.
47   *
48   * @since 3.5.0
49   */
50  class ProjectModelResolverTest extends AbstractMavenProjectTestCase {
51  
52      /**
53       * Creates a new {@code ProjectModelResolverTest} instance.
54       */
55      public ProjectModelResolverTest() {
56          super();
57      }
58  
59      @Test
60      void testResolveParentThrowsUnresolvableModelExceptionWhenNotFound() throws Exception {
61          final Parent parent = new Parent();
62          parent.setGroupId("org.apache");
63          parent.setArtifactId("apache");
64          parent.setVersion("0");
65  
66          UnresolvableModelException e = assertThrows(
67                  UnresolvableModelException.class,
68                  () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()),
69                  "Expected 'UnresolvableModelException' not thrown.");
70          assertNotNull(e.getMessage());
71          assertThat(e.getMessage(), containsString("Could not find artifact org.apache:apache:pom:0 in central"));
72      }
73  
74      @Test
75      void testResolveParentThrowsUnresolvableModelExceptionWhenNoMatchingVersionFound() throws Exception {
76          final Parent parent = new Parent();
77          parent.setGroupId("org.apache");
78          parent.setArtifactId("apache");
79          parent.setVersion("[2.0,2.1)");
80  
81          UnresolvableModelException e = assertThrows(
82                  UnresolvableModelException.class,
83                  () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()),
84                  "Expected 'UnresolvableModelException' not thrown.");
85          assertEquals("No versions matched the requested parent version range '[2.0,2.1)'", e.getMessage());
86      }
87  
88      @Test
89      void testResolveParentThrowsUnresolvableModelExceptionWhenUsingRangesWithoutUpperBound() throws Exception {
90          final Parent parent = new Parent();
91          parent.setGroupId("org.apache");
92          parent.setArtifactId("apache");
93          parent.setVersion("[1,)");
94  
95          UnresolvableModelException e = assertThrows(
96                  UnresolvableModelException.class,
97                  () -> newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()),
98                  "Expected 'UnresolvableModelException' not thrown.");
99          assertEquals("The requested parent version range '[1,)' does not specify an upper bound", e.getMessage());
100     }
101 
102     @Test
103     void testResolveParentSuccessfullyResolvesExistingParentWithoutRange() throws Exception {
104         final Parent parent = new Parent();
105         parent.setGroupId("org.apache");
106         parent.setArtifactId("apache");
107         parent.setVersion("1");
108 
109         assertNotNull(this.newModelResolver().resolveModel(parent.getDelegate(), new AtomicReference<>()));
110         assertEquals("1", parent.getVersion());
111     }
112 
113     @Test
114     void testResolveParentSuccessfullyResolvesExistingParentUsingHighestVersion() throws Exception {
115         final Parent parent = new Parent();
116         parent.setGroupId("org.apache");
117         parent.setArtifactId("apache");
118         parent.setVersion("(,2.0)");
119 
120         AtomicReference<org.apache.maven.api.model.Parent> modified = new AtomicReference<>();
121         assertNotNull(this.newModelResolver().resolveModel(parent.getDelegate(), modified));
122         assertEquals("1", modified.get().getVersion());
123     }
124 
125     @Test
126     void testResolveDependencyThrowsUnresolvableModelExceptionWhenNotFound() throws Exception {
127         final Dependency dependency = new Dependency();
128         dependency.setGroupId("org.apache");
129         dependency.setArtifactId("apache");
130         dependency.setVersion("0");
131 
132         UnresolvableModelException e = assertThrows(
133                 UnresolvableModelException.class,
134                 () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()),
135                 "Expected 'UnresolvableModelException' not thrown.");
136         assertNotNull(e.getMessage());
137         assertThat(e.getMessage(), containsString("Could not find artifact org.apache:apache:pom:0 in central"));
138     }
139 
140     @Test
141     void testResolveDependencyThrowsUnresolvableModelExceptionWhenNoMatchingVersionFound() throws Exception {
142         final Dependency dependency = new Dependency();
143         dependency.setGroupId("org.apache");
144         dependency.setArtifactId("apache");
145         dependency.setVersion("[2.0,2.1)");
146 
147         UnresolvableModelException e = assertThrows(
148                 UnresolvableModelException.class,
149                 () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()),
150                 "Expected 'UnresolvableModelException' not thrown.");
151         assertEquals("No versions matched the requested dependency version range '[2.0,2.1)'", e.getMessage());
152     }
153 
154     @Test
155     void testResolveDependencyThrowsUnresolvableModelExceptionWhenUsingRangesWithoutUpperBound() throws Exception {
156         final Dependency dependency = new Dependency();
157         dependency.setGroupId("org.apache");
158         dependency.setArtifactId("apache");
159         dependency.setVersion("[1,)");
160 
161         UnresolvableModelException e = assertThrows(
162                 UnresolvableModelException.class,
163                 () -> newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()),
164                 "Expected 'UnresolvableModelException' not thrown.");
165         assertEquals("The requested dependency version range '[1,)' does not specify an upper bound", e.getMessage());
166     }
167 
168     @Test
169     void testResolveDependencySuccessfullyResolvesExistingDependencyWithoutRange() throws Exception {
170         final Dependency dependency = new Dependency();
171         dependency.setGroupId("org.apache");
172         dependency.setArtifactId("apache");
173         dependency.setVersion("1");
174 
175         assertNotNull(this.newModelResolver().resolveModel(dependency.getDelegate(), new AtomicReference<>()));
176         assertEquals("1", dependency.getVersion());
177     }
178 
179     @Test
180     void testResolveDependencySuccessfullyResolvesExistingDependencyUsingHighestVersion() throws Exception {
181         final Dependency dependency = new Dependency();
182         dependency.setGroupId("org.apache");
183         dependency.setArtifactId("apache");
184         dependency.setVersion("(,2.0)");
185 
186         AtomicReference<org.apache.maven.api.model.Dependency> modified = new AtomicReference<>();
187         assertNotNull(this.newModelResolver().resolveModel(dependency.getDelegate(), modified));
188         assertEquals("1", modified.get().getVersion());
189     }
190 
191     private ModelResolver newModelResolver() throws Exception {
192         final File localRepo = new File(this.getLocalRepository().getBasedir());
193         final DefaultRepositorySystemSession repoSession = new DefaultRepositorySystemSession(h -> false);
194         repoSession.setLocalRepositoryManager(new LegacyLocalRepositoryManager(localRepo));
195 
196         return new ProjectModelResolver(
197                 repoSession,
198                 null,
199                 getContainer().lookup(RepositorySystem.class),
200                 getContainer().lookup(RemoteRepositoryManager.class),
201                 this.getRemoteRepositories(),
202                 ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT,
203                 null,
204                 null);
205     }
206 
207     private List<RemoteRepository> getRemoteRepositories() throws InvalidRepositoryException {
208         final File repoDir = new File(getBasedir(), "src/test/remote-repo").getAbsoluteFile();
209         final RemoteRepository remoteRepository = new RemoteRepository.Builder(
210                         MavenRepositorySystem.DEFAULT_REMOTE_REPO_ID,
211                         "default",
212                         repoDir.toURI().toASCIIString())
213                 .build();
214 
215         return Collections.singletonList(remoteRepository);
216     }
217 }