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
66 @PlexusTest
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 void testResolveRangeWithManagedVersion() throws ArtifactResolutionException, InvalidVersionSpecificationException {
297 ArtifactSpec a = createArtifactSpec("a", "1.0");
298 ArtifactSpec b = a.addDependency("b", "[1.0,3.0]");
299
300 ArtifactSpec managedB = createArtifactSpec("b", "5.0");
301
302 ArtifactResolutionResult res = collect(a, managedB.artifact);
303 assertEquals(
304 createSet(new Object[] {a.artifact, managedB.artifact}), res.getArtifacts(), "Check artifact list");
305 assertEquals("5.0", getArtifact("b", res.getArtifacts()).getVersion(), "Check version");
306 }
307
308 @Test
309 void testCompatibleRanges() throws ArtifactResolutionException, InvalidVersionSpecificationException {
310 ArtifactSpec a = createArtifactSpec("a", "1.0");
311 ArtifactSpec b = a.addDependency("b", "1.0");
312 a.addDependency("c", "[2.0,2.5]");
313 b.addDependency("c", "[1.0,3.0]");
314 ArtifactSpec c = createArtifactSpec("c", "2.5");
315
316 ArtifactResolutionResult res = collect(a);
317
318 assertEquals(
319 createSet(new Object[] {a.artifact, b.artifact, c.artifact}),
320 res.getArtifacts(),
321 "Check artifact list");
322 assertEquals("2.5", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
323 }
324
325 @Test
326 void testIncompatibleRanges() throws ArtifactResolutionException, InvalidVersionSpecificationException {
327 ArtifactSpec a = createArtifactSpec("a", "1.0");
328 ArtifactSpec b = a.addDependency("b", "1.0");
329 a.addDependency("c", "[2.4,3.0]");
330
331 b.addDependency("c", "[1.0,2.0]");
332
333 ArtifactResolutionResult res = collect(a);
334
335 assertTrue(res.hasVersionRangeViolations());
336 }
337
338 @Test
339 void testUnboundedRangeWhenVersionUnavailable()
340 throws ArtifactResolutionException, InvalidVersionSpecificationException {
341 ArtifactSpec a = createArtifactSpec("a", "1.0");
342 ArtifactSpec b = a.addDependency("b", "1.0");
343 a.addDependency("c", "[2.0,]");
344 b.addDependency("c", "[1.0,]");
345
346 ArtifactResolutionResult res = collect(a);
347
348 assertTrue(res.hasVersionRangeViolations());
349 }
350
351 @Test
352 void testUnboundedRangeBelowLastRelease() throws ArtifactResolutionException, InvalidVersionSpecificationException {
353 ArtifactSpec a = createArtifactSpec("a", "1.0");
354 createArtifactSpec("c", "1.5");
355 ArtifactSpec c = createArtifactSpec("c", "2.0");
356 createArtifactSpec("c", "1.1");
357 a.addDependency("c", "[1.0,)");
358
359 ArtifactResolutionResult res = collect(a);
360
361 assertEquals(createSet(new Object[] {a.artifact, c.artifact}), res.getArtifacts(), "Check artifact list");
362 assertEquals("2.0", getArtifact("c", res.getArtifacts()).getVersion(), "Check version");
363 }
364
365 @Test
366 void testUnboundedRangeAboveLastRelease() throws ArtifactResolutionException, InvalidVersionSpecificationException {
367 ArtifactSpec a = createArtifactSpec("a", "1.0");
368 createArtifactSpec("c", "2.0");
369 a.addDependency("c", "[10.0,)");
370
371 ArtifactResolutionResult res = collect(a);
372
373 assertTrue(res.hasVersionRangeViolations());
374 }
375
376 @Test
377 void testResolveManagedVersion() throws ArtifactResolutionException, InvalidVersionSpecificationException {
378 ArtifactSpec a = createArtifactSpec("a", "1.0");
379 a.addDependency("b", "3.0", Artifact.SCOPE_RUNTIME);
380
381 Artifact managedVersion = createArtifactSpec("b", "5.0").artifact;
382 Artifact modifiedB = createArtifactSpec("b", "5.0", Artifact.SCOPE_RUNTIME).artifact;
383
384 ArtifactResolutionResult res = collect(a, managedVersion);
385 assertEquals(createSet(new Object[] {a.artifact, modifiedB}), res.getArtifacts(), "Check artifact list");
386 }
387
388 @Test
389 void testCollectChangesVersionOfOriginatingArtifactIfInDependencyManagementHasDifferentVersion()
390 throws ArtifactResolutionException, InvalidVersionSpecificationException {
391 ArtifactSpec a = createArtifactSpec("a", "1.0");
392
393 Artifact artifact = projectArtifact.artifact;
394 Artifact managedVersion = createArtifactSpec(artifact.getArtifactId(), "2.0").artifact;
395
396 ArtifactResolutionResult result = collect(a, managedVersion);
397
398 assertEquals("1.0", artifact.getVersion(), "collect has modified version in originating artifact");
399
400 Artifact resolvedArtifact = result.getArtifacts().iterator().next();
401
402 assertEquals("1.0", resolvedArtifact.getVersion(), "Resolved version don't match original artifact version");
403 }
404
405 @Test
406 void testResolveCompileScopeOverTestScope()
407 throws ArtifactResolutionException, InvalidVersionSpecificationException {
408 ArtifactSpec a = createArtifactSpec("a", "1.0");
409 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_TEST);
410
411 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
412
413 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
414
415 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
416 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
417 Artifact artifact = getArtifact("c", res.getArtifacts());
418
419
420 assertEquals(Artifact.SCOPE_TEST, artifact.getScope(), "Check artifactScope");
421 }
422
423 @Test
424 void testResolveRuntimeScopeOverTestScope()
425 throws ArtifactResolutionException, InvalidVersionSpecificationException {
426 ArtifactSpec a = createArtifactSpec("a", "1.0");
427 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_TEST);
428
429 a.addDependency("c", "2.0", Artifact.SCOPE_RUNTIME);
430
431 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_RUNTIME).artifact;
432
433 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
434 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
435 Artifact artifact = getArtifact("c", res.getArtifacts());
436
437
438 assertEquals(Artifact.SCOPE_TEST, artifact.getScope(), "Check artifactScope");
439 }
440
441 @Test
442 void testResolveCompileScopeOverRuntimeScope()
443 throws ArtifactResolutionException, InvalidVersionSpecificationException {
444 ArtifactSpec root = createArtifactSpec("root", "1.0");
445 ArtifactSpec a = root.addDependency("a", "1.0");
446 root.addDependency("c", "3.0", Artifact.SCOPE_RUNTIME);
447
448 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
449
450 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
451
452 ArtifactResolutionResult res = collect(createSet(new Object[] {root.artifact}));
453 assertEquals(
454 createSet(new Object[] {a.artifact, root.artifact, modifiedC}),
455 res.getArtifacts(),
456 "Check artifact list");
457 Artifact artifact = getArtifact("c", res.getArtifacts());
458 assertEquals(Artifact.SCOPE_COMPILE, artifact.getScope(), "Check artifactScope");
459 }
460
461 @Test
462 void testResolveCompileScopeOverProvidedScope()
463 throws ArtifactResolutionException, InvalidVersionSpecificationException {
464 ArtifactSpec a = createArtifactSpec("a", "1.0");
465 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_PROVIDED);
466
467 a.addDependency("c", "2.0", Artifact.SCOPE_COMPILE);
468
469 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_COMPILE).artifact;
470
471 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
472 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
473 Artifact artifact = getArtifact("c", res.getArtifacts());
474
475
476 assertEquals(Artifact.SCOPE_PROVIDED, artifact.getScope(), "Check artifactScope");
477 }
478
479 @Test
480 void testResolveRuntimeScopeOverProvidedScope()
481 throws ArtifactResolutionException, InvalidVersionSpecificationException {
482 ArtifactSpec a = createArtifactSpec("a", "1.0");
483 ArtifactSpec c = createArtifactSpec("c", "3.0", Artifact.SCOPE_PROVIDED);
484
485 a.addDependency("c", "2.0", Artifact.SCOPE_RUNTIME);
486
487 Artifact modifiedC = createArtifactSpec("c", "3.0", Artifact.SCOPE_RUNTIME).artifact;
488
489 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, c.artifact}));
490 assertEquals(createSet(new Object[] {a.artifact, modifiedC}), res.getArtifacts(), "Check artifact list");
491 Artifact artifact = getArtifact("c", res.getArtifacts());
492
493
494 assertEquals(Artifact.SCOPE_PROVIDED, artifact.getScope(), "Check artifactScope");
495 }
496
497 @Test
498 void testProvidedScopeNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
499 ArtifactSpec a = createArtifactSpec("a", "1.0", Artifact.SCOPE_PROVIDED);
500 ArtifactSpec b = createArtifactSpec("b", "1.0");
501 b.addDependency("c", "3.0", Artifact.SCOPE_PROVIDED);
502
503 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
504 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
505 }
506
507 @Test
508 void testOptionalNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
509 ArtifactSpec a = createArtifactSpec("a", "1.0");
510 ArtifactSpec b = createArtifactSpec("b", "1.0");
511 b.addDependency("c", "3.0", true);
512
513 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
514 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
515 }
516
517 @Test
518 void testOptionalIncludedAtRoot() throws ArtifactResolutionException, InvalidVersionSpecificationException {
519 ArtifactSpec a = createArtifactSpec("a", "1.0");
520
521 ArtifactSpec b = createArtifactSpec("b", "1.0", true);
522
523 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
524 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
525 }
526
527 @Test
528 void testScopeUpdate() throws InvalidVersionSpecificationException, ArtifactResolutionException {
529
530 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
531 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE);
532 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE);
533 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE);
534 checkScopeUpdate(Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE);
535
536
537 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
538 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
539 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
540 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
541 checkScopeUpdate(Artifact.SCOPE_PROVIDED, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
542
543
544 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
545 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME);
546 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
547 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
548 checkScopeUpdate(Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME);
549
550
551 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
552 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
553 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
554 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
555 checkScopeUpdate(Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
556
557
558 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE);
559 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED);
560 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME);
561 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM);
562 checkScopeUpdate(Artifact.SCOPE_TEST, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST);
563 }
564
565 private void checkScopeUpdate(String farthestScope, String nearestScope, String expectedScope)
566 throws ArtifactResolutionException, InvalidVersionSpecificationException {
567 checkScopeUpdateDirect(farthestScope, nearestScope, expectedScope);
568 checkScopeUpdateTransitively(farthestScope, nearestScope, expectedScope);
569 }
570
571 private void checkScopeUpdateTransitively(String farthestScope, String nearestScope, String expectedScope)
572 throws ArtifactResolutionException, InvalidVersionSpecificationException {
573 ArtifactSpec a = createArtifactSpec("a", "1.0");
574 ArtifactSpec b = createArtifactSpec("b", "1.0", nearestScope);
575 ArtifactSpec c = createArtifactSpec("c", "1.0");
576 a.addDependency(c);
577 ArtifactSpec dNearest = createArtifactSpec("d", "2.0");
578 b.addDependency(dNearest);
579 ArtifactSpec dFarthest = createArtifactSpec("d", "3.0", farthestScope);
580 c.addDependency(dFarthest);
581
582
583 if (!Artifact.SCOPE_SYSTEM.equals(nearestScope) && !Artifact.SCOPE_PROVIDED.equals(nearestScope)) {
584 checkScopeUpdate(a, b, expectedScope, "2.0");
585 }
586 }
587
588 private void checkScopeUpdateDirect(String farthestScope, String nearestScope, String expectedScope)
589 throws ArtifactResolutionException, InvalidVersionSpecificationException {
590 ArtifactSpec a = createArtifactSpec("a", "1.0");
591 ArtifactSpec b = createArtifactSpec("b", "1.0");
592 ArtifactSpec c = createArtifactSpec("c", "1.0");
593 a.addDependency(c);
594 ArtifactSpec dNearest = createArtifactSpec("d", "2.0", nearestScope);
595 b.addDependency(dNearest);
596 ArtifactSpec dFarthest = createArtifactSpec("d", "3.0", farthestScope);
597 c.addDependency(dFarthest);
598
599 checkScopeUpdate(a, b, expectedScope, "2.0");
600 }
601
602 private void checkScopeUpdate(ArtifactSpec a, ArtifactSpec b, String expectedScope, String expectedVersion)
603 throws ArtifactResolutionException, InvalidVersionSpecificationException {
604 ScopeArtifactFilter filter;
605 if (Artifact.SCOPE_PROVIDED.equals(expectedScope)) {
606 filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE);
607 } else if (Artifact.SCOPE_SYSTEM.equals(expectedScope)) {
608 filter = new ScopeArtifactFilter(Artifact.SCOPE_COMPILE);
609 } else {
610 filter = new ScopeArtifactFilter(expectedScope);
611 }
612
613 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}), filter);
614 Artifact artifact = getArtifact("d", res.getArtifacts());
615 assertNotNull(artifact, "MNG-1895 Dependency was not added to resolution");
616 assertEquals(expectedScope, artifact.getScope(), "Check artifactScope");
617 assertEquals(expectedVersion, artifact.getVersion(), "Check version");
618
619 ArtifactSpec d = createArtifactSpec("d", "1.0");
620 res = collect(createSet(new Object[] {a.artifact, b.artifact, d.artifact}), filter);
621 artifact = getArtifact("d", res.getArtifacts());
622 assertNotNull(artifact, "MNG-1895 Dependency was not added to resolution");
623 assertEquals(d.artifact.getScope(), artifact.getScope(), "Check artifactScope");
624 assertEquals("1.0", artifact.getVersion(), "Check version");
625 }
626
627 @Test
628 @Disabled
629 void testOptionalNotTransitiveButVersionIsInfluential()
630 throws ArtifactResolutionException, InvalidVersionSpecificationException {
631 ArtifactSpec a = createArtifactSpec("a", "1.0");
632 ArtifactSpec b = createArtifactSpec("b", "1.0");
633 b.addDependency("c", "3.0", true);
634 ArtifactSpec d = a.addDependency("d", "1.0");
635 ArtifactSpec e = d.addDependency("e", "1.0");
636 e.addDependency("c", "2.0");
637
638 ArtifactSpec c = createArtifactSpec("c", "3.0");
639
640 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
641 assertEquals(
642 createSet(new Object[] {a.artifact, b.artifact, c.artifact, d.artifact, e.artifact}),
643 res.getArtifacts(),
644 "Check artifact list");
645 Artifact artifact = getArtifact("c", res.getArtifacts());
646 assertEquals("3.0", artifact.getVersion(), "Check version");
647 }
648
649 @Test
650 void testTestScopeNotTransitive() throws ArtifactResolutionException, InvalidVersionSpecificationException {
651 ArtifactSpec a = createArtifactSpec("a", "1.0", Artifact.SCOPE_TEST);
652 ArtifactSpec b = createArtifactSpec("b", "1.0");
653 b.addDependency("c", "3.0", Artifact.SCOPE_TEST);
654
655 ArtifactResolutionResult res = collect(createSet(new Object[] {a.artifact, b.artifact}));
656 assertEquals(createSet(new Object[] {a.artifact, b.artifact}), res.getArtifacts(), "Check artifact list");
657 }
658
659 @Test
660 void testSnapshotNotIncluded() throws ArtifactResolutionException, InvalidVersionSpecificationException {
661 ArtifactSpec a = createArtifactSpec("a", "1.0");
662 a.addDependency("b", "[1.0,)");
663 createArtifactSpec("b", "1.0-SNAPSHOT");
664
665 ArtifactResolutionResult res = collect(a);
666
667 assertTrue(res.hasVersionRangeViolations());
668
669
670
671
672
673
674 }
675
676 @Test
677 @Disabled("that one does not work")
678 void testOverConstrainedVersionException()
679 throws ArtifactResolutionException, InvalidVersionSpecificationException {
680 ArtifactSpec a = createArtifactSpec("a", "1.0");
681 a.addDependency("b", "[1.0, 2.0)");
682 a.addDependency("c", "[3.3.0,4.0.0)");
683
684 ArtifactSpec b = createArtifactSpec("b", "1.0.0");
685 b.addDependency("c", "3.3.0-v3346");
686
687 ArtifactSpec c = createArtifactSpec("c", "3.2.1-v3235e");
688
689 OverConstrainedVersionException e = assertThrows(
690 OverConstrainedVersionException.class, () -> collect(createSet(new Object[] {a.artifact})));
691 assertTrue(e.getMessage().contains("[3.2.1-v3235e, 3.3.0-v3346]"), "Versions unordered");
692 assertTrue(e.getMessage().contains("Path to dependency:"), "DependencyTrail unresolved");
693 }
694
695 private Artifact getArtifact(String id, Set artifacts) {
696 for (Object artifact : artifacts) {
697 Artifact a = (Artifact) artifact;
698 if (a.getArtifactId().equals(id) && a.getGroupId().equals(GROUP_ID)) {
699 return a;
700 }
701 }
702 return null;
703 }
704
705 private ArtifactResolutionResult collect(Set<Artifact> artifacts) throws ArtifactResolutionException {
706 return collect(artifacts, null);
707 }
708
709 private ArtifactResolutionResult collect(Set<Artifact> artifacts, ArtifactFilter filter)
710 throws ArtifactResolutionException {
711 return artifactCollector.collect(
712 artifacts, projectArtifact.artifact, null, null, null, source, filter, Collections.emptyList(), null);
713 }
714
715 private ArtifactResolutionResult collect(ArtifactSpec a) throws ArtifactResolutionException {
716 return artifactCollector.collect(
717 Collections.singleton(a.artifact),
718 projectArtifact.artifact,
719 null,
720 null,
721 null,
722 source,
723 null,
724 Collections.emptyList(),
725 null);
726 }
727
728 private ArtifactResolutionResult collect(ArtifactSpec a, ArtifactFilter filter) throws ArtifactResolutionException {
729 return artifactCollector.collect(
730 Collections.singleton(a.artifact),
731 projectArtifact.artifact,
732 null,
733 null,
734 null,
735 source,
736 filter,
737 Collections.emptyList(),
738 null);
739 }
740
741 private ArtifactResolutionResult collect(ArtifactSpec a, Artifact managedVersion)
742 throws ArtifactResolutionException {
743 Map<String, Artifact> managedVersions =
744 Collections.singletonMap(managedVersion.getDependencyConflictId(), managedVersion);
745 return artifactCollector.collect(
746 Collections.singleton(a.artifact),
747 projectArtifact.artifact,
748 managedVersions,
749 null,
750 null,
751 source,
752 null,
753 Collections.emptyList(),
754 null);
755 }
756
757 private ArtifactSpec createArtifactSpec(String id, String version) throws InvalidVersionSpecificationException {
758 return createArtifactSpec(id, version, Artifact.SCOPE_COMPILE);
759 }
760
761 private ArtifactSpec createArtifactSpec(String id, String version, boolean optional)
762 throws InvalidVersionSpecificationException {
763 return createArtifactSpec(id, version, Artifact.SCOPE_COMPILE, null, optional);
764 }
765
766 private ArtifactSpec createArtifactSpec(String id, String version, String scope)
767 throws InvalidVersionSpecificationException {
768 return createArtifactSpec(id, version, scope, null, false);
769 }
770
771 private ArtifactSpec createArtifactSpec(
772 String id, String version, String scope, String inheritedScope, boolean optional)
773 throws InvalidVersionSpecificationException {
774 VersionRange versionRange = VersionRange.createFromVersionSpec(version);
775 Artifact artifact = artifactFactory.createDependencyArtifact(
776 GROUP_ID, id, versionRange, "jar", null, scope, inheritedScope, optional);
777 ArtifactSpec spec = null;
778 if (artifact != null) {
779 spec = new ArtifactSpec();
780 spec.artifact = artifact;
781 source.addArtifact(spec);
782 }
783 return spec;
784 }
785
786 @SuppressWarnings("unchecked")
787 private static Set<Artifact> createSet(Object[] x) {
788 return new LinkedHashSet(Arrays.asList(x));
789 }
790
791 private class ArtifactSpec {
792 private Artifact artifact;
793
794 private Set<Artifact> dependencies = new HashSet<>();
795
796 public ArtifactSpec addDependency(String id, String version) throws InvalidVersionSpecificationException {
797 return addDependency(id, version, Artifact.SCOPE_COMPILE);
798 }
799
800 public ArtifactSpec addDependency(String id, String version, String scope)
801 throws InvalidVersionSpecificationException {
802 return addDependency(id, version, scope, false);
803 }
804
805 private ArtifactSpec addDependency(ArtifactSpec dep) throws InvalidVersionSpecificationException {
806 if (dep != null) {
807 dependencies.add(dep.artifact);
808 }
809 return dep;
810 }
811
812 private ArtifactSpec addDependency(String id, String version, String scope, boolean optional)
813 throws InvalidVersionSpecificationException {
814 ArtifactSpec dep = createArtifactSpec(id, version, scope, artifact.getScope(), optional);
815 return addDependency(dep);
816 }
817
818 public ArtifactSpec addDependency(String id, String version, boolean optional)
819 throws InvalidVersionSpecificationException {
820 return addDependency(id, version, Artifact.SCOPE_COMPILE, optional);
821 }
822 }
823
824 private class Source implements ArtifactMetadataSource {
825 private Map<String, ArtifactSpec> artifacts = new HashMap<>();
826
827 private Map<String, List<ArtifactVersion>> versions = new HashMap<>();
828
829 public ResolutionGroup retrieve(
830 Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories)
831 throws ArtifactMetadataRetrievalException {
832 String key = getKey(artifact);
833
834 ArtifactSpec a = (ArtifactSpec) artifacts.get(key);
835 try {
836 return new ResolutionGroup(
837 artifact,
838 createArtifacts(
839 artifactFactory, a.dependencies, artifact.getScope(), artifact.getDependencyFilter()),
840 Collections.emptyList());
841 } catch (InvalidVersionSpecificationException e) {
842 throw new ArtifactMetadataRetrievalException("Invalid version creating artifacts", e, artifact);
843 }
844 }
845
846 private String getKey(Artifact artifact) {
847 return artifact.getDependencyConflictId();
848 }
849
850 private Set<Artifact> createArtifacts(
851 ArtifactFactory artifactFactory,
852 Set<Artifact> dependencies,
853 String inheritedScope,
854 ArtifactFilter dependencyFilter)
855 throws InvalidVersionSpecificationException {
856 Set<Artifact> projectArtifacts = new HashSet<>();
857
858 for (Artifact d : dependencies) {
859 VersionRange versionRange;
860 if (d.getVersionRange() != null) {
861 versionRange = d.getVersionRange();
862 } else {
863 versionRange = VersionRange.createFromVersionSpec(d.getVersion());
864 }
865 Artifact artifact;
866 if (d.getScope().equals(Artifact.SCOPE_TEST) || d.getScope().equals(Artifact.SCOPE_PROVIDED)) {
867
868 artifact = artifactFactory.createArtifact(
869 d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getScope(), d.getType());
870 } else {
871 artifact = artifactFactory.createDependencyArtifact(
872 d.getGroupId(),
873 d.getArtifactId(),
874 versionRange,
875 d.getType(),
876 d.getClassifier(),
877 d.getScope(),
878 inheritedScope,
879 d.isOptional());
880 }
881
882 if (artifact != null && (dependencyFilter == null || dependencyFilter.include(artifact))) {
883 artifact.setDependencyFilter(dependencyFilter);
884
885 projectArtifacts.add(artifact);
886 }
887 }
888
889 return projectArtifacts;
890 }
891
892 public void addArtifact(ArtifactSpec spec) {
893 artifacts.put(getKey(spec.artifact), spec);
894
895 String key = spec.artifact.getDependencyConflictId();
896 List<ArtifactVersion> artifactVersions = versions.computeIfAbsent(key, k -> new ArrayList<>());
897 if (spec.artifact.getVersion() != null) {
898 artifactVersions.add(new DefaultArtifactVersion(spec.artifact.getVersion()));
899 }
900 }
901
902 public List<ArtifactVersion> retrieveAvailableVersions(
903 Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories)
904 throws ArtifactMetadataRetrievalException {
905 return retrieveAvailableVersions(artifact);
906 }
907
908 public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
909 Artifact artifact, ArtifactRepository localRepository, ArtifactRepository remoteRepository)
910 throws ArtifactMetadataRetrievalException {
911 return retrieveAvailableVersions(artifact);
912 }
913
914 private List<ArtifactVersion> retrieveAvailableVersions(Artifact artifact) {
915 List<ArtifactVersion> artifactVersions = versions.get(artifact.getDependencyConflictId());
916 if (artifactVersions == null) {
917 artifactVersions = Collections.emptyList();
918 }
919 return artifactVersions;
920 }
921
922 public ResolutionGroup retrieve(MetadataResolutionRequest request) throws ArtifactMetadataRetrievalException {
923 return retrieve(request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories());
924 }
925
926 public List<ArtifactVersion> retrieveAvailableVersions(MetadataResolutionRequest request)
927 throws ArtifactMetadataRetrievalException {
928 return retrieveAvailableVersions(
929 request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories());
930 }
931 }
932 }