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