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