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