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