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.plugin.surefire;
20  
21  import java.io.File;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.LinkedHashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.stream.Collectors;
29  
30  import org.apache.maven.RepositoryUtils;
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.DefaultArtifact;
33  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
34  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
35  import org.apache.maven.artifact.versioning.VersionRange;
36  import org.apache.maven.model.Dependency;
37  import org.apache.maven.model.Plugin;
38  import org.apache.maven.plugin.MojoExecutionException;
39  import org.eclipse.aether.RepositorySystem;
40  import org.eclipse.aether.RepositorySystemSession;
41  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
42  import org.eclipse.aether.resolution.ArtifactRequest;
43  import org.eclipse.aether.resolution.ArtifactResult;
44  import org.eclipse.aether.resolution.DependencyRequest;
45  import org.eclipse.aether.resolution.DependencyResolutionException;
46  import org.eclipse.aether.resolution.DependencyResult;
47  import org.junit.jupiter.api.Disabled;
48  import org.junit.jupiter.api.Test;
49  import org.mockito.ArgumentCaptor;
50  
51  import static java.util.Collections.singletonList;
52  import static java.util.Collections.singletonMap;
53  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
54  import static org.apache.maven.plugin.surefire.SurefireDependencyResolver.PROVIDER_GROUP_ID;
55  import static org.assertj.core.api.Assertions.assertThat;
56  import static org.assertj.core.api.Assertions.assertThatThrownBy;
57  import static org.junit.jupiter.api.Assertions.assertThrows;
58  import static org.mockito.ArgumentMatchers.any;
59  import static org.mockito.ArgumentMatchers.eq;
60  import static org.mockito.Mockito.mock;
61  import static org.mockito.Mockito.verify;
62  import static org.mockito.Mockito.verifyNoMoreInteractions;
63  import static org.mockito.Mockito.when;
64  
65  /**
66   *
67   */
68  public class SurefireDependencyResolverTest {
69  
70      @Test
71      public void shouldNotBeWithinRangeNullArtifact() {
72          boolean result = SurefireDependencyResolver.isWithinVersionSpec(null, "[4.7,)");
73          assertThat(result).isFalse();
74      }
75  
76      @Test
77      public void shouldNotBeWithinRange() throws InvalidVersionSpecificationException {
78          Artifact api = createArtifact("junit", "junit", "4.6");
79          boolean result = SurefireDependencyResolver.isWithinVersionSpec(api, "[4.7,)");
80          assertThat(result).isFalse();
81      }
82  
83      @Test
84      public void shouldBeWithinRange() throws InvalidVersionSpecificationException {
85          Artifact api = createArtifact("junit", "junit", "4.7");
86          boolean result = SurefireDependencyResolver.isWithinVersionSpec(api, "[4.7,)");
87          assertThat(result).isTrue();
88      }
89  
90      @Test
91      public void shouldBeFarWithinRange() throws InvalidVersionSpecificationException {
92          Artifact api = createArtifact("junit", "junit", "4.13");
93          boolean result = SurefireDependencyResolver.isWithinVersionSpec(api, "[4.7,)");
94          assertThat(result).isTrue();
95      }
96  
97      @Test
98      public void shouldBeFailWithinRange() throws InvalidVersionSpecificationException {
99          Artifact api = createArtifact("junit", "junit", "");
100         RuntimeException ex = assertThrows(
101                 RuntimeException.class, () -> SurefireDependencyResolver.isWithinVersionSpec(api, "[4.7,)"));
102         assertThat(ex.getMessage()).contains("Bug in plugin. Please report with stacktrace");
103     }
104 
105     @Test
106     @Disabled("old not executing tests - to review")
107     public void testResolveArtifact()
108             throws InvalidVersionSpecificationException, MojoExecutionException, DependencyResolutionException {
109 
110         Artifact provider = createArtifact("surefire-junit-platform");
111         RepositorySystem repositorySystem = mock(RepositorySystem.class);
112         RepositorySystemSession session = mock(RepositorySystemSession.class);
113         ArgumentCaptor<DependencyRequest> requestCaptor = ArgumentCaptor.forClass(DependencyRequest.class);
114 
115         DependencyResult result = new DependencyResult(new DependencyRequest());
116         when(repositorySystem.resolveDependencies(eq(session), requestCaptor.capture()))
117                 .thenReturn(result);
118 
119         SurefireDependencyResolver surefireDependencyResolver = new SurefireDependencyResolver(repositorySystem);
120         surefireDependencyResolver.resolveArtifacts(session, Collections.emptyList(), provider);
121 
122         DependencyRequest value = requestCaptor.getValue();
123         assertThat(value).isNotNull();
124         org.eclipse.aether.graph.Dependency requestDependency =
125                 value.getCollectRequest().getRoot();
126         assertThat(requestDependency.getArtifact().getGroupId()).isEqualTo(provider.getGroupId());
127         assertThat(requestDependency.getArtifact().getArtifactId()).isEqualTo(provider.getArtifactId());
128         assertThat(requestDependency.getArtifact().getVersion()).isEqualTo(provider.getVersion());
129         assertThat(requestDependency.getArtifact().getExtension()).isEqualTo(provider.getType());
130     }
131 
132     @Test
133     public void testGetProviderClasspath() throws Exception {
134 
135         Artifact commonJunit4 = createArtifact("common-junit4");
136         Artifact api = createArtifact("surefire-api");
137         Artifact provider = createArtifact("surefire-junit-platform");
138         Artifact ext = createArtifact("org.apiguardian", "apiguardian-api");
139         Artifact logger = createArtifact("surefire-logger-api");
140 
141         Set<Artifact> providerArtifacts = new LinkedHashSet<>();
142         providerArtifacts.add(commonJunit4);
143         providerArtifacts.add(api);
144         providerArtifacts.add(provider);
145         providerArtifacts.add(ext);
146         providerArtifacts.add(logger);
147 
148         List<ArtifactResult> artifactResults = providerArtifacts.stream()
149                 .map(RepositoryUtils::toArtifact)
150                 .map(a -> new ArtifactResult(new ArtifactRequest()).setArtifact(a))
151                 .collect(Collectors.toList());
152 
153         DependencyResult result = new DependencyResult(new DependencyRequest());
154         result.setArtifactResults(artifactResults);
155 
156         RepositorySystem repositorySystem = mock(RepositorySystem.class);
157         RepositorySystemSession session = mock(RepositorySystemSession.class);
158 
159         when(session.getArtifactTypeRegistry()).thenReturn(mock(ArtifactTypeRegistry.class));
160         when(repositorySystem.resolveDependencies(eq(session), any())).thenReturn(result);
161 
162         SurefireDependencyResolver surefireDependencyResolver = new SurefireDependencyResolver(repositorySystem);
163         Set<Artifact> classpath = surefireDependencyResolver.getProviderClasspath(
164                 session, Collections.emptyList(), "surefire-junit-platform", "1");
165 
166         assertThat(classpath).hasSize(5);
167 
168         Iterator<Artifact> it = classpath.iterator();
169 
170         // result should be ordered
171         assertThat(it.next()).isEqualTo(provider);
172         assertThat(it.next()).isEqualTo(api);
173         assertThat(it.next()).isEqualTo(logger);
174         assertThat(it.next()).isEqualTo(commonJunit4);
175         assertThat(it.next()).isEqualTo(ext);
176     }
177 
178     @Test
179     public void testGetProviderClasspathShouldPropagateTheResolutionException() throws Exception {
180 
181         RepositorySystem repositorySystem = mock(RepositorySystem.class);
182         RepositorySystemSession session = mock(RepositorySystemSession.class);
183         when(session.getArtifactTypeRegistry()).thenReturn(mock(ArtifactTypeRegistry.class));
184 
185         DependencyResolutionException dependencyResolutionException =
186                 new DependencyResolutionException(new DependencyResult(new DependencyRequest()), new Exception());
187         when(repositorySystem.resolveDependencies(eq(session), any())).thenThrow(dependencyResolutionException);
188 
189         SurefireDependencyResolver surefireDependencyResolver = new SurefireDependencyResolver(repositorySystem);
190 
191         assertThatThrownBy(() -> surefireDependencyResolver.getProviderClasspath(
192                         session, Collections.emptyList(), "surefire-junit-platform", "1"))
193                 .isInstanceOf(MojoExecutionException.class)
194                 .hasCause(dependencyResolutionException);
195     }
196 
197     @Test
198     public void testResolvePluginDependencies() throws Exception {
199         Dependency providerAsDependency = new Dependency();
200         providerAsDependency.setGroupId(PROVIDER_GROUP_ID);
201         providerAsDependency.setArtifactId("surefire-shadefire");
202         providerAsDependency.setVersion("1");
203 
204         Artifact providerAsArtifact = createArtifact("surefire-shadefire");
205 
206         Plugin plugin = mock(Plugin.class);
207         when(plugin.getDependencies()).thenReturn(singletonList(providerAsDependency));
208 
209         RepositorySystem repositorySystem = mock(RepositorySystem.class);
210         RepositorySystemSession session = mock(RepositorySystemSession.class);
211         when(session.getArtifactTypeRegistry()).thenReturn(mock(ArtifactTypeRegistry.class));
212 
213         ArtifactResult artifactResult =
214                 new ArtifactResult(new ArtifactRequest().setArtifact(RepositoryUtils.toArtifact(providerAsArtifact)));
215         artifactResult.setArtifact(RepositoryUtils.toArtifact(providerAsArtifact));
216         DependencyResult result = new DependencyResult(new DependencyRequest());
217         result.setArtifactResults(Collections.singletonList(artifactResult));
218 
219         when(repositorySystem.resolveDependencies(eq(session), any())).thenReturn(result);
220 
221         Map<String, Artifact> pluginResolvedDependencies =
222                 singletonMap(PROVIDER_GROUP_ID + ":surefire-shadefire", providerAsArtifact);
223 
224         SurefireDependencyResolver surefireDependencyResolver = new SurefireDependencyResolver(repositorySystem);
225 
226         Map<String, Artifact> providers = surefireDependencyResolver.resolvePluginDependencies(
227                 session, Collections.emptyList(), plugin, pluginResolvedDependencies);
228 
229         assertThat(providers.values()).hasSize(1).containsOnly(providerAsArtifact);
230 
231         verify(repositorySystem).resolveDependencies(eq(session), any());
232         verifyNoMoreInteractions(repositorySystem);
233     }
234 
235     private static Artifact createArtifact(String artifactId) throws InvalidVersionSpecificationException {
236         return createArtifact(PROVIDER_GROUP_ID, artifactId);
237     }
238 
239     private static Artifact createArtifact(String groupId, String artifactId)
240             throws InvalidVersionSpecificationException {
241         return createArtifact(groupId, artifactId, "1");
242     }
243 
244     private static Artifact createArtifact(String groupId, String artifactId, String version)
245             throws InvalidVersionSpecificationException {
246         VersionRange versionSpec = createFromVersionSpec(version);
247         DefaultArtifact defaultArtifact = new DefaultArtifact(
248                 groupId, artifactId, versionSpec, null, "jar", null, new DefaultArtifactHandler("jar"));
249         defaultArtifact.setFile(new File(""));
250         return defaultArtifact;
251     }
252 }