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