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