1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.repository.legacy.resolver;
20
21 import javax.inject.Inject;
22
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedHashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.artifact.factory.ArtifactFactory;
35 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
36 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
37 import org.apache.maven.artifact.metadata.ResolutionGroup;
38 import org.apache.maven.artifact.repository.ArtifactRepository;
39 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
40 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
41 import org.apache.maven.artifact.resolver.CyclicDependencyException;
42 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
43 import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
44 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
45 import org.apache.maven.artifact.versioning.ArtifactVersion;
46 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
47 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
48 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
49 import org.apache.maven.artifact.versioning.VersionRange;
50 import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
51 import org.codehaus.plexus.testing.PlexusTest;
52 import org.junit.jupiter.api.BeforeEach;
53 import org.junit.jupiter.api.Disabled;
54 import org.junit.jupiter.api.Test;
55
56 import static org.junit.jupiter.api.Assertions.assertEquals;
57 import static org.junit.jupiter.api.Assertions.assertNotNull;
58 import static org.junit.jupiter.api.Assertions.assertThrows;
59 import static org.junit.jupiter.api.Assertions.assertTrue;
60
61
62
63
64
65 @PlexusTest
66 @Deprecated
67 class DefaultArtifactCollectorTest {
68 @Inject
69 private LegacyArtifactCollector artifactCollector;
70
71 @Inject
72 private ArtifactFactory artifactFactory;
73
74 private ArtifactSpec projectArtifact;
75
76 private Source source;
77
78 private static final String GROUP_ID = "test";
79
80 @BeforeEach
81 void setUp() throws Exception {
82 source = new Source();
83
84 projectArtifact = createArtifactSpec("project", "1.0", null);
85 }
86
87 @Test
88 @Disabled("works, but we don't fail on cycles presently")
89 void testCircularDependencyNotIncludingCurrentProject()
90 throws ArtifactResolutionException, InvalidVersionSpecificationException {
91 ArtifactSpec a = createArtifactSpec("a", "1.0");
92 ArtifactSpec b = a.addDependency("b", "1.0");
93 b.addDependency("a", "1.0");
94 assertThrows(
95 CyclicDependencyException.class,
96 () -> collect(a),
97 "Should have failed on cyclic dependency not involving project");
98 }
99
100 @Test
101 @Disabled("works, but we don't fail on cycles presently")
102 void testCircularDependencyIncludingCurrentProject()
103 throws ArtifactResolutionException, InvalidVersionSpecificationException {
104 ArtifactSpec a = createArtifactSpec("a", "1.0");
105 ArtifactSpec b = a.addDependency("b", "1.0");
106 b.addDependency("project", "1.0");
107 assertThrows(
108 CyclicDependencyException.class,
109 () -> collect(a),
110 "Should have failed on cyclic dependency not involving project");
111 }
112
113 @Test
114 void testResolveWithFilter() throws ArtifactResolutionException, InvalidVersionSpecificationException {
115 ArtifactSpec a = createArtifactSpec("a", "1.0");
116 ArtifactSpec b = a.addDependency("b", "1.0");
117 ArtifactSpec c = a.addDependency("c", "3.0");
118
119 b.addDependency("c", "2.0");
120 ArtifactSpec d = b.addDependency("d", "4.0");
121
122 ArtifactResolutionResult res = collect(a);
123 assertEquals(
124 createSet(new Object[] {a.artifact, b.artifact, c.artifact, d.artifact}),
125 res.getArtifacts(),
126 "Check artifact list");
127
128 ArtifactFilter filter = new ExclusionSetFilter(new String[] {"b"});
129 res = collect(a, filter);
130 assertEquals(createSet(new Object[] {a.artifact, c.artifact}), res.getArtifacts(), "Check artifact list");
131 }
132
133 @Test
134 void testResolveCorrectDependenciesWhenDifferentDependenciesOnNearest()
135 throws ArtifactResolutionException, InvalidVersionSpecificationException {
136 ArtifactSpec a = createArtifactSpec("a", "1.0");
137 ArtifactSpec b = a.addDependency("b", "1.0");
138 ArtifactSpec c2 = b.addDependency("c", "2.0");
139 c2.addDependency("d", "1.0");
140
141 ArtifactSpec e = createArtifactSpec("e", "1.0");
142 ArtifactSpec c1 = e.addDependency("c", "1.0");
143 ArtifactSpec f = c1.addDependency("f", "1.0");
144
145 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, e.artifact}));
146 assertEquals(
147 createSet(new Object[] {a.artifact, b.artifact, e.artifact, c1.artifact, f.artifact}),
148 res.getArtifacts(),
149 "Check artifact list");
150 assertEquals("1.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
151 }
152
153 @Test
154 @Disabled
155 void testResolveCorrectDependenciesWhenDifferentDependenciesOnNewest()
156 throws ArtifactResolutionException, InvalidVersionSpecificationException {
157
158 ArtifactSpec a = createArtifactSpec("a", "1.0");
159 ArtifactSpec b = a.addDependency("b", "1.0");
160 ArtifactSpec c2 = b.addDependency("c", "2.0");
161 ArtifactSpec d = c2.addDependency("d", "1.0");
162
163 ArtifactSpec e = createArtifactSpec("e", "1.0");
164 ArtifactSpec c1 = e.addDependency("c", "1.0");
165 c1.addDependency("f", "1.0");
166
167 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, e.artifact}));
168 assertEquals(
169 createSet(new Object[] {a.artifact, b.artifact, e.artifact, c2.artifact, d.artifact}),
170 res.getArtifacts(),
171 "Check artifact list");
172 assertEquals("2.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
173 }
174
175 @Test
176 @Disabled
177 void testResolveCorrectDependenciesWhenDifferentDependenciesOnNewestVersionReplaced()
178 throws ArtifactResolutionException, InvalidVersionSpecificationException {
179
180 ArtifactSpec a = createArtifactSpec("a", "1.0");
181 ArtifactSpec b1 = a.addDependency("b", "1.0");
182 ArtifactSpec c = a.addDependency("c", "1.0");
183 ArtifactSpec d2 = b1.addDependency("d", "2.0");
184 d2.addDependency("h", "1.0");
185 ArtifactSpec d1 = c.addDependency("d", "1.0");
186 ArtifactSpec b2 = c.addDependency("b", "2.0");
187 ArtifactSpec e = b2.addDependency("e", "1.0");
188 ArtifactSpec g = d1.addDependency("g", "1.0");
189
190 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact}));
191 Object[] artifacts = new Object[] {a.artifact, c.artifact, d1.artifact, b2.artifact, e.artifact, g.artifact};
192 assertEquals(createSet(artifacts), res.getArtifacts(), "Check artifact list");
193 assertEquals("1.0", getArtifact("d", res.getArtifacts()).getVersion(), "Check version");
194 assertEquals("2.0", getArtifact("b", res.getArtifacts()).getVersion(), "Check version");
195 }
196
197 @Test
198 void testResolveNearestNewestIsNearest() throws ArtifactResolutionException, InvalidVersionSpecificationException {
199 ArtifactSpec a = createArtifactSpec("a", "1.0");
200 ArtifactSpec b = a.addDependency("b", "1.0");
201 ArtifactSpec c = a.addDependency("c", "3.0");
202
203 b.addDependency("c", "2.0");
204
205 ArtifactResolutionResult res = collect(a);
206 assertEquals(
207 createSet(new Object[] {a.artifact, b.artifact, c.artifact}),
208 res.getArtifacts(),
209 "Check artifact list");
210 assertEquals("3.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
211 }
212
213 @Test
214 void testResolveNearestOldestIsNearest() throws ArtifactResolutionException, InvalidVersionSpecificationException {
215 ArtifactSpec a = createArtifactSpec("a", "1.0");
216 ArtifactSpec b = a.addDependency("b", "1.0");
217 ArtifactSpec c = a.addDependency("c", "2.0");
218
219 b.addDependency("c", "3.0");
220
221 ArtifactResolutionResult res = collect(a);
222 assertEquals(
223 createSet(new Object[] {a.artifact, b.artifact, c.artifact}),
224 res.getArtifacts(),
225 "Check artifact list");
226 assertEquals("2.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
227 }
228
229 @Test
230 void testResolveLocalNewestIsLocal() throws ArtifactResolutionException, InvalidVersionSpecificationException {
231 ArtifactSpec a = createArtifactSpec("a", "1.0");
232 a.addDependency("b", "2.0");
233 ArtifactSpec b = createArtifactSpec("b", "3.0");
234
235 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
236 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
237 assertEquals("3.0", getArtifact("b", res.getArtifacts()).getVersion(), "Check version");
238 }
239
240 @Test
241 void testResolveLocalOldestIsLocal() throws ArtifactResolutionException, InvalidVersionSpecificationException {
242 ArtifactSpec a = createArtifactSpec("a", "1.0");
243 a.addDependency("b", "3.0");
244 ArtifactSpec b = createArtifactSpec("b", "2.0");
245
246 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
247 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
248 assertEquals("2.0", getArtifact("b", res.getArtifacts()).getVersion(), "Check version");
249 }
250
251 @Test
252 void testResolveLocalWithNewerVersionButLesserScope()
253 throws ArtifactResolutionException, InvalidVersionSpecificationException {
254 ArtifactSpec a = createArtifactSpec("commons-logging", "1.0");
255 a.addDependency("junit", "3.7");
256 ArtifactSpec b = createArtifactSpec("junit", "3.8.1", Artifact.SCOPE_TEST);
257
258 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
259 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
260 assertEquals("3.8.1", getArtifact("junit", res.getArtifacts()).getVersion(), "Check version");
261 assertEquals(
262 Artifact.SCOPE_TEST, getArtifact("junit", res.getArtifacts()).getScope(), "Check artifactScope");
263 }
264
265 @Test
266 void testResolveLocalWithNewerVersionButLesserScopeResolvedFirst()
267 throws ArtifactResolutionException, InvalidVersionSpecificationException {
268 ArtifactSpec b = createArtifactSpec("junit", "3.8.1", Artifact.SCOPE_TEST);
269 ArtifactSpec a = createArtifactSpec("commons-logging", "1.0");
270 a.addDependency("junit", "3.7");
271
272 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
273 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
274 assertEquals("3.8.1", getArtifact("junit", res.getArtifacts()).getVersion(), "Check version");
275 assertEquals(
276 Artifact.SCOPE_TEST, getArtifact("junit", res.getArtifacts()).getScope(), "Check artifactScope");
277 }
278
279 @Test
280 void testResolveNearestWithRanges() throws ArtifactResolutionException, InvalidVersionSpecificationException {
281 ArtifactSpec a = createArtifactSpec("a", "1.0");
282 ArtifactSpec b = a.addDependency("b", "1.0");
283 ArtifactSpec c = a.addDependency("c", "2.0");
284
285 b.addDependency("c", "[1.0,3.0]");
286
287 ArtifactResolutionResult res = collect(a);
288 assertEquals(
289 createSet(new Object[] {a.artifact, b.artifact, c.artifact}),
290 res.getArtifacts(),
291 "Check artifact list");
292 assertEquals("2.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
293 }
294
295 @Test
296 @SuppressWarnings("checkstyle:UnusedLocalVariable")
297 void testResolveRangeWithManagedVersion() throws ArtifactResolutionException, InvalidVersionSpecificationException {
298 ArtifactSpec a = createArtifactSpec("a", "1.0");
299 ArtifactSpec b = a.addDependency("b", "[1.0,3.0]");
300
301 ArtifactSpec managedB = createArtifactSpec("b", "5.0");
302
303 ArtifactResolutionResult res = collect(a, managedB.artifact);
304 assertEquals(
305 createSet(new Object[] {a.artifact, managedB.artifact}), res.getArtifacts(), "Check artifact list");
306 assertEquals("5.0", getArtifact("b", res.getArtifacts()).getVersion(), "Check version");
307 }
308
309 @Test
310 void testCompatibleRanges() throws ArtifactResolutionException, InvalidVersionSpecificationException {
311 ArtifactSpec a = createArtifactSpec("a", "1.0");
312 ArtifactSpec b = a.addDependency("b", "1.0");
313 a.addDependency("c", "[2.0,2.5]");
314 b.addDependency("c", "[1.0,3.0]");
315 ArtifactSpec c = createArtifactSpec("c", "2.5");
316
317 ArtifactResolutionResult res = collect(a);
318
319 assertEquals(
320 createSet(new Object[] {a.artifact, b.artifact, c.artifact}),
321 res.getArtifacts(),
322 "Check artifact list");
323 assertEquals("2.5", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
324 }
325
326 @Test
327 void testIncompatibleRanges() throws ArtifactResolutionException, InvalidVersionSpecificationException {
328 ArtifactSpec a = createArtifactSpec("a", "1.0");
329 ArtifactSpec b = a.addDependency("b", "1.0");
330 a.addDependency("c", "[2.4,3.0]");
331
332 b.addDependency("c", "[1.0,2.0]");
333
334 ArtifactResolutionResult res = collect(a);
335
336 assertTrue(res.hasVersionRangeViolations());
337 }
338
339 @Test
340 void testUnboundedRangeWhenVersionUnavailable()
341 throws ArtifactResolutionException, InvalidVersionSpecificationException {
342 ArtifactSpec a = createArtifactSpec("a", "1.0");
343 ArtifactSpec b = a.addDependency("b", "1.0");
344 a.addDependency("c", "[2.0,]");
345 b.addDependency("c", "[1.0,]");
346
347 ArtifactResolutionResult res = collect(a);
348
349 assertTrue(res.hasVersionRangeViolations());
350 }
351
352 @Test
353 void testUnboundedRangeBelowLastRelease() throws ArtifactResolutionException, InvalidVersionSpecificationException {
354 ArtifactSpec a = createArtifactSpec("a", "1.0");
355 createArtifactSpec("c", "1.5");
356 ArtifactSpec c = createArtifactSpec("c", "2.0");
357 createArtifactSpec("c", "1.1");
358 a.addDependency("c", "[1.0,)");
359
360 ArtifactResolutionResult res = collect(a);
361
362 assertEquals(createSet(new Object[] {a.artifact, c.artifact}), res.getArtifacts(), "Check artifact list");
363 assertEquals("2.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
364 }
365
366 @Test
367 void testUnboundedRangeAboveLastRelease() throws ArtifactResolutionException, InvalidVersionSpecificationException {
368 ArtifactSpec a = createArtifactSpec("a", "1.0");
369 createArtifactSpec("c", "2.0");
370 a.addDependency("c", "[10.0,)");
371
372 ArtifactResolutionResult res = collect(a);
373
374 assertTrue(res.hasVersionRangeViolations());
375 }
376
377 @Test
378 void testResolveManagedVersion() throws ArtifactResolutionException, InvalidVersionSpecificationException {
379 ArtifactSpec a = createArtifactSpec("a", "1.0");
380 a.addDependency("b", "3.0", Artifact.SCOPE_RUNTIME);
381
382 Artifact managedVersion = createArtifactSpec("b", "5.0").artifact;
383 Artifact modifiedB = createArtifactSpec("b", "5.0", Artifact.SCOPE_RUNTIME).artifact;
384
385 ArtifactResolutionResult res = collect(a, managedVersion);
386 assertEquals(createSet(new Object[] {a.artifact, modifiedB}), res.getArtifacts(), "Check artifact list");
387 }
388
389 @Test
390 void testCollectChangesVersionOfOriginatingArtifactIfInDependencyManagementHasDifferentVersion()
391 throws ArtifactResolutionException, InvalidVersionSpecificationException {
392 ArtifactSpec a = createArtifactSpec("a", "1.0");
393
394 Artifact artifact = projectArtifact.artifact;
395 Artifact managedVersion = createArtifactSpec(artifact.getArtifactId(), "2.0").artifact;
396
397 ArtifactResolutionResult result = collect(a, managedVersion);
398
399 assertEquals("1.0", artifact.getVersion(), "collect has modified version in originating artifact");
400
401 Artifact resolvedArtifact = result.getArtifacts().iterator().next();
402
403 assertEquals("1.0", resolvedArtifact.getVersion(), "Resolved version don't match original artifact version");
404 }
405
406 @Test
407 void testResolveCompileScopeOverTestScope()
408 throws ArtifactResolutionException, InvalidVersionSpecificationException {
409 ArtifactSpec a = createArtifactSpec("a", "1.0");
410 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_TEST);
411
412 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
413
414 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
415
416 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
417 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
418 Artifact artifact = getArtifact("c", res.getArtifacts());
419
420
421 assertEquals(Artifact.SCOPE_TEST, artifact.getScope(), "Check artifactScope");
422 }
423
424 @Test
425 void testResolveRuntimeScopeOverTestScope()
426 throws ArtifactResolutionException, InvalidVersionSpecificationException {
427 ArtifactSpec a = createArtifactSpec("a", "1.0");
428 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_TEST);
429
430 a.addDependency("c", "2.0", Artifact.SCOPE_RUNTIME);
431
432 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_RUNTIME).artifact;
433
434 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
435 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
436 Artifact artifact = getArtifact("c", res.getArtifacts());
437
438
439 assertEquals(Artifact.SCOPE_TEST, artifact.getScope(), "Check artifactScope");
440 }
441
442 @Test
443 void testResolveCompileScopeOverRuntimeScope()
444 throws ArtifactResolutionException, InvalidVersionSpecificationException {
445 ArtifactSpec root = createArtifactSpec("root", "1.0");
446 ArtifactSpec a = root.addDependency("a", "1.0");
447 root.addDependency("c", "3.0", Artifact.SCOPE_RUNTIME);
448
449 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
450
451 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
452
453 ArtifactResolutionResult res = collect(createSet(new Object[] {root.artifact}));
454 assertEquals(
455 createSet(new Object[] {a.artifact, root.artifact, modifiedC}),
456 res.getArtifacts(),
457 "Check artifact list");
458 Artifact artifact = getArtifact("c", res.getArtifacts());
459 assertEquals(Artifact.SCOPE_COMPILE, artifact.getScope(), "Check artifactScope");
460 }
461
462 @Test
463 void testResolveCompileScopeOverProvidedScope()
464 throws ArtifactResolutionException, InvalidVersionSpecificationException {
465 ArtifactSpec a = createArtifactSpec("a", "1.0");
466 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_PROVIDED);
467
468 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
469
470 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
471
472 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
473 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
474 Artifact artifact = getArtifact("c", res.getArtifacts());
475
476
477 assertEquals(Artifact.SCOPE_PROVIDED, artifact.getScope(), "Check artifactScope");
478 }
479
480 @Test
481 void testResolveRuntimeScopeOverProvidedScope()
482 throws ArtifactResolutionException, InvalidVersionSpecificationException {
483 ArtifactSpec a = createArtifactSpec("a", "1.0");
484 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_PROVIDED);
485
486 a.addDependency("c", "2.0", Artifact.SCOPE_RUNTIME);
487
488 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_RUNTIME).artifact;
489
490 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
491 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
492 Artifact artifact = getArtifact("c", res.getArtifacts());
493
494
495 assertEquals(Artifact.SCOPE_PROVIDED, artifact.getScope(), "Check artifactScope");
496 }
497
498 @Test
499 void testProvidedScopeNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
500 ArtifactSpec a = createArtifactSpec("a", "1.0", Artifact.SCOPE_PROVIDED);
501 ArtifactSpec b = createArtifactSpec("b", "1.0");
502 b.addDependency("c", "3.0", Artifact.SCOPE_PROVIDED);
503
504 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
505 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
506 }
507
508 @Test
509 void testOptionalNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
510 ArtifactSpec a = createArtifactSpec("a", "1.0");
511 ArtifactSpec b = createArtifactSpec("b", "1.0");
512 b.addDependency("c", "3.0", true);
513
514 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
515 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
516 }
517
518 @Test
519 void testOptionalIncludedAtRoot() throws ArtifactResolutionException, InvalidVersionSpecificationException {
520 ArtifactSpec a = createArtifactSpec("a", "1.0");
521
522 ArtifactSpec b = createArtifactSpec("b", "1.0", true);
523
524 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
525 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
526 }
527
528 @Test
529 void testScopeUpdate() throws InvalidVersionSpecificationException, ArtifactResolutionException {
530
531 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
532 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE);
533 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE);
534 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE);
535 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE);
536
537
538 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
539 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
540 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
541 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
542 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
543
544
545 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
546 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME);
547 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
548 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
549 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME);
550
551
552 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
553 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
554 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
555 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
556 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
557
558
559 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
560 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
561 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
562 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
563 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
564 }
565
566 private void checkScopeUpdate(String farthestScope, String nearestScope, String expectedScope)
567 throws ArtifactResolutionException, InvalidVersionSpecificationException {
568 checkScopeUpdateDirect(farthestScope, nearestScope, expectedScope);
569 checkScopeUpdateTransitively(farthestScope, nearestScope, expectedScope);
570 }
571
572 private void checkScopeUpdateTransitively(String farthestScope, String nearestScope, String expectedScope)
573 throws ArtifactResolutionException, InvalidVersionSpecificationException {
574 ArtifactSpec a = createArtifactSpec("a", "1.0");
575 ArtifactSpec b = createArtifactSpec("b", "1.0", nearestScope);
576 ArtifactSpec c = createArtifactSpec("c", "1.0");
577 a.addDependency(c);
578 ArtifactSpec dNearest = createArtifactSpec("d", "2.0");
579 b.addDependency(dNearest);
580 ArtifactSpec dFarthest = createArtifactSpec("d", "3.0", farthestScope);
581 c.addDependency(dFarthest);
582
583
584 if (!Artifact.SCOPE_SYSTEM.equals(nearestScope) && !Artifact.SCOPE_PROVIDED.equals(nearestScope)) {
585 checkScopeUpdate(a, b, expectedScope, "2.0");
586 }
587 }
588
589 private void checkScopeUpdateDirect(String farthestScope, String nearestScope, String expectedScope)
590 throws ArtifactResolutionException, InvalidVersionSpecificationException {
591 ArtifactSpec a = createArtifactSpec("a", "1.0");
592 ArtifactSpec b = createArtifactSpec("b", "1.0");
593 ArtifactSpec c = createArtifactSpec("c", "1.0");
594 a.addDependency(c);
595 ArtifactSpec dNearest = createArtifactSpec("d", "2.0", nearestScope);
596 b.addDependency(dNearest);
597 ArtifactSpec dFarthest = createArtifactSpec("d", "3.0", farthestScope);
598 c.addDependency(dFarthest);
599
600 checkScopeUpdate(a, b, expectedScope, "2.0");
601 }
602
603 private void checkScopeUpdate(ArtifactSpec a, ArtifactSpec b, String expectedScope, String expectedVersion)
604 throws ArtifactResolutionException, InvalidVersionSpecificationException {
605 ScopeArtifactFilter filter;
606 if (Artifact.SCOPE_PROVIDED.equals(expectedScope)) {
607 filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE);
608 } else if (Artifact.SCOPE_SYSTEM.equals(expectedScope)) {
609 filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE);
610 } else {
611 filter = new ScopeArtifactFilter(expectedScope);
612 }
613
614 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}), filter);
615 Artifact artifact = getArtifact("d", res.getArtifacts());
616 assertNotNull(artifact, "MNG-1895 Dependency was not added to resolution");
617 assertEquals(expectedScope, artifact.getScope(), "Check artifactScope");
618 assertEquals(expectedVersion, artifact.getVersion(), "Check version");
619
620 ArtifactSpec d = createArtifactSpec("d", "1.0");
621 res = collect(createSet(new Object[] {a.artifact, b.artifact, d.artifact}), filter);
622 artifact = getArtifact("d", res.getArtifacts());
623 assertNotNull(artifact, "MNG-1895 Dependency was not added to resolution");
624 assertEquals(d.artifact.getScope(), artifact.getScope(), "Check artifactScope");
625 assertEquals("1.0", artifact.getVersion(), "Check version");
626 }
627
628 @Test
629 @Disabled
630 void testOptionalNotTransitiveButVersionIsInfluential()
631 throws ArtifactResolutionException, InvalidVersionSpecificationException {
632 ArtifactSpec a = createArtifactSpec("a", "1.0");
633 ArtifactSpec b = createArtifactSpec("b", "1.0");
634 b.addDependency("c", "3.0", true);
635 ArtifactSpec d = a.addDependency("d", "1.0");
636 ArtifactSpec e = d.addDependency("e", "1.0");
637 e.addDependency("c", "2.0");
638
639 ArtifactSpec c = createArtifactSpec("c", "3.0");
640
641 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
642 assertEquals(
643 createSet(new Object[] {a.artifact, b.artifact, c.artifact, d.artifact, e.artifact}),
644 res.getArtifacts(),
645 "Check artifact list");
646 Artifact artifact = getArtifact("c", res.getArtifacts());
647 assertEquals("3.0", artifact.getVersion(), "Check version");
648 }
649
650 @Test
651 void testTestScopeNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
652 ArtifactSpec a = createArtifactSpec("a", "1.0", Artifact.SCOPE_TEST);
653 ArtifactSpec b = createArtifactSpec("b", "1.0");
654 b.addDependency("c", "3.0", Artifact.SCOPE_TEST);
655
656 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
657 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
658 }
659
660 @Test
661 void testSnapshotNotIncluded() throws ArtifactResolutionException, InvalidVersionSpecificationException {
662 ArtifactSpec a = createArtifactSpec("a", "1.0");
663 a.addDependency("b", "[1.0,)");
664 createArtifactSpec("b", "1.0-SNAPSHOT");
665
666 ArtifactResolutionResult res = collect(a);
667
668 assertTrue(res.hasVersionRangeViolations());
669
670
671
672
673
674
675 }
676
677 @Test
678 @Disabled("that one does not work")
679 @SuppressWarnings("checkstyle:UnusedLocalVariable")
680 void testOverConstrainedVersionException()
681 throws ArtifactResolutionException, InvalidVersionSpecificationException {
682 ArtifactSpec a = createArtifactSpec("a", "1.0");
683 a.addDependency("b", "[1.0, 2.0)");
684 a.addDependency("c", "[3.3.0,4.0.0)");
685
686 ArtifactSpec b = createArtifactSpec("b", "1.0.0");
687 b.addDependency("c", "3.3.0-v3346");
688
689 ArtifactSpec c = createArtifactSpec("c", "3.2.1-v3235e");
690
691 OverConstrainedVersionException e = assertThrows(
692 OverConstrainedVersionException.class, () -> collect(createSet(new Object[] {a.artifact})));
693 assertTrue(e.getMessage().contains("[3.2.1-v3235e, 3.3.0-v3346]"), "Versions unordered");
694 assertTrue(e.getMessage().contains("Path to dependency:"), "DependencyTrail unresolved");
695 }
696
697 private Artifact getArtifact(String id, Set artifacts) {
698 for (Object artifact : artifacts) {
699 Artifact a = (Artifact) artifact;
700 if (a.getArtifactId().equals(id) && a.getGroupId().equals(GROUP_ID)) {
701 return a;
702 }
703 }
704 return null;
705 }
706
707 private ArtifactResolutionResult collect(Set<Artifact> artifacts) throws ArtifactResolutionException {
708 return collect(artifacts, null);
709 }
710
711 private ArtifactResolutionResult collect(Set<Artifact> artifacts, ArtifactFilter filter)
712 throws ArtifactResolutionException {
713 return artifactCollector.collect(
714 artifacts, projectArtifact.artifact, null, null, null, source, filter, Collections.emptyList(), null);
715 }
716
717 private ArtifactResolutionResult collect(ArtifactSpec a) throws ArtifactResolutionException {
718 return artifactCollector.collect(
719 Collections.singleton(a.artifact),
720 projectArtifact.artifact,
721 null,
722 null,
723 null,
724 source,
725 null,
726 Collections.emptyList(),
727 null);
728 }
729
730 private ArtifactResolutionResult collect(ArtifactSpec a, ArtifactFilter filter) throws ArtifactResolutionException {
731 return artifactCollector.collect(
732 Collections.singleton(a.artifact),
733 projectArtifact.artifact,
734 null,
735 null,
736 null,
737 source,
738 filter,
739 Collections.emptyList(),
740 null);
741 }
742
743 private ArtifactResolutionResult collect(ArtifactSpec a, Artifact managedVersion)
744 throws ArtifactResolutionException {
745 Map<String, Artifact> managedVersions =
746 Collections.singletonMap(managedVersion.getDependencyConflictId(), managedVersion);
747 return artifactCollector.collect(
748 Collections.singleton(a.artifact),
749 projectArtifact.artifact,
750 managedVersions,
751 null,
752 null,
753 source,
754 null,
755 Collections.emptyList(),
756 null);
757 }
758
759 private ArtifactSpec createArtifactSpec(String id, String version) throws InvalidVersionSpecificationException {
760 return createArtifactSpec(id, version, Artifact.SCOPE_COMPILE);
761 }
762
763 private ArtifactSpec createArtifactSpec(String id, String version, boolean optional)
764 throws InvalidVersionSpecificationException {
765 return createArtifactSpec(id, version, Artifact.SCOPE_COMPILE, null, optional);
766 }
767
768 private ArtifactSpec createArtifactSpec(String id, String version, String scope)
769 throws InvalidVersionSpecificationException {
770 return createArtifactSpec(id, version, scope, null, false);
771 }
772
773 private ArtifactSpec createArtifactSpec(
774 String id, String version, String scope, String inheritedScope, boolean optional)
775 throws InvalidVersionSpecificationException {
776 VersionRange versionRange = VersionRange.createFromVersionSpec(version);
777 Artifact artifact = artifactFactory.createDependencyArtifact(
778 GROUP_ID, id, versionRange, "jar", null, scope, inheritedScope, optional);
779 ArtifactSpec spec = null;
780 if (artifact != null) {
781 spec = new ArtifactSpec();
782 spec.artifact = artifact;
783 source.addArtifact(spec);
784 }
785 return spec;
786 }
787
788 @SuppressWarnings("unchecked")
789 private static Set<Artifact> createSet(Object[] x) {
790 return new LinkedHashSet(Arrays.asList(x));
791 }
792
793 private class ArtifactSpec {
794 private Artifact artifact;
795
796 private Set<Artifact> dependencies = new HashSet<>();
797
798 public ArtifactSpec addDependency(String id, String version) throws InvalidVersionSpecificationException {
799 return addDependency(id, version, Artifact.SCOPE_COMPILE);
800 }
801
802 public ArtifactSpec addDependency(String id, String version, String scope)
803 throws InvalidVersionSpecificationException {
804 return addDependency(id, version, scope, false);
805 }
806
807 private ArtifactSpec addDependency(ArtifactSpec dep) throws InvalidVersionSpecificationException {
808 if (dep != null) {
809 dependencies.add(dep.artifact);
810 }
811 return dep;
812 }
813
814 private ArtifactSpec addDependency(String id, String version, String scope, boolean optional)
815 throws InvalidVersionSpecificationException {
816 ArtifactSpec dep = createArtifactSpec(id, version, scope, artifact.getScope(), optional);
817 return addDependency(dep);
818 }
819
820 public ArtifactSpec addDependency(String id, String version, boolean optional)
821 throws InvalidVersionSpecificationException {
822 return addDependency(id, version, Artifact.SCOPE_COMPILE, optional);
823 }
824 }
825
826 private class Source implements ArtifactMetadataSource {
827 private Map<String, ArtifactSpec> artifacts = new HashMap<>();
828
829 private Map<String, List<ArtifactVersion>> versions = new HashMap<>();
830
831 @Override
832 public ResolutionGroup retrieve(
833 Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories)
834 throws ArtifactMetadataRetrievalException {
835 String key = getKey(artifact);
836
837 ArtifactSpec a = artifacts.get(key);
838 try {
839 return new ResolutionGroup(
840 artifact,
841 createArtifacts(
842 artifactFactory, a.dependencies, artifact.getScope(), artifact.getDependencyFilter()),
843 Collections.emptyList());
844 } catch (InvalidVersionSpecificationException e) {
845 throw new ArtifactMetadataRetrievalException("Invalid version creating artifacts", e, artifact);
846 }
847 }
848
849 private String getKey(Artifact artifact) {
850 return artifact.getDependencyConflictId();
851 }
852
853 private Set<Artifact> createArtifacts(
854 ArtifactFactory artifactFactory,
855 Set<Artifact> dependencies,
856 String inheritedScope,
857 ArtifactFilter dependencyFilter)
858 throws InvalidVersionSpecificationException {
859 Set<Artifact> projectArtifacts = new HashSet<>();
860
861 for (Artifact d : dependencies) {
862 VersionRange versionRange;
863 if (d.getVersionRange() != null) {
864 versionRange = d.getVersionRange();
865 } else {
866 versionRange = VersionRange.createFromVersionSpec(d.getVersion());
867 }
868 Artifact artifact;
869 if (d.getScope().equals(Artifact.SCOPE_TEST) || d.getScope().equals(Artifact.SCOPE_PROVIDED)) {
870
871 artifact = artifactFactory.createArtifact(
872 d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getScope(), d.getType());
873 } else {
874 artifact = artifactFactory.createDependencyArtifact(
875 d.getGroupId(),
876 d.getArtifactId(),
877 versionRange,
878 d.getType(),
879 d.getClassifier(),
880 d.getScope(),
881 inheritedScope,
882 d.isOptional());
883 }
884
885 if (artifact != null && (dependencyFilter == null || dependencyFilter.include(artifact))) {
886 artifact.setDependencyFilter(dependencyFilter);
887
888 projectArtifacts.add(artifact);
889 }
890 }
891
892 return projectArtifacts;
893 }
894
895 public void addArtifact(ArtifactSpec spec) {
896 artifacts.put(getKey(spec.artifact), spec);
897
898 String key = spec.artifact.getDependencyConflictId();
899 List<ArtifactVersion> artifactVersions = versions.computeIfAbsent(key, k -> new ArrayList<>());
900 if (spec.artifact.getVersion() != null) {
901 artifactVersions.add(new DefaultArtifactVersion(spec.artifact.getVersion()));
902 }
903 }
904
905 @Override
906 public List<ArtifactVersion> retrieveAvailableVersions(
907 Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories)
908 throws ArtifactMetadataRetrievalException {
909 return retrieveAvailableVersions(artifact);
910 }
911
912 @Override
913 public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
914 Artifact artifact, ArtifactRepository localRepository, ArtifactRepository remoteRepository)
915 throws ArtifactMetadataRetrievalException {
916 return retrieveAvailableVersions(artifact);
917 }
918
919 private List<ArtifactVersion> retrieveAvailableVersions(Artifact artifact) {
920 List<ArtifactVersion> artifactVersions = versions.get(artifact.getDependencyConflictId());
921 if (artifactVersions == null) {
922 artifactVersions = Collections.emptyList();
923 }
924 return artifactVersions;
925 }
926
927 @Override
928 public ResolutionGroup retrieve(MetadataResolutionRequest request) throws ArtifactMetadataRetrievalException {
929 return retrieve(request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories());
930 }
931
932 @Override
933 public List<ArtifactVersion> retrieveAvailableVersions(MetadataResolutionRequest request)
934 throws ArtifactMetadataRetrievalException {
935 return retrieveAvailableVersions(
936 request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories());
937 }
938 }
939 }