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