1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl.collect;
20
21 import java.io.IOException;
22 import java.util.*;
23 import java.util.concurrent.atomic.AtomicReference;
24
25 import org.eclipse.aether.DefaultRepositorySystemSession;
26 import org.eclipse.aether.RepositorySystemSession;
27 import org.eclipse.aether.artifact.Artifact;
28 import org.eclipse.aether.artifact.ArtifactProperties;
29 import org.eclipse.aether.artifact.DefaultArtifact;
30 import org.eclipse.aether.collection.CollectRequest;
31 import org.eclipse.aether.collection.CollectResult;
32 import org.eclipse.aether.collection.DependencyCollectionContext;
33 import org.eclipse.aether.collection.DependencyCollectionException;
34 import org.eclipse.aether.collection.DependencyManagement;
35 import org.eclipse.aether.collection.DependencyManager;
36 import org.eclipse.aether.graph.DefaultDependencyNode;
37 import org.eclipse.aether.graph.Dependency;
38 import org.eclipse.aether.graph.DependencyCycle;
39 import org.eclipse.aether.graph.DependencyNode;
40 import org.eclipse.aether.graph.Exclusion;
41 import org.eclipse.aether.impl.ArtifactDescriptorReader;
42 import org.eclipse.aether.internal.impl.IniArtifactDescriptorReader;
43 import org.eclipse.aether.internal.test.util.DependencyGraphParser;
44 import org.eclipse.aether.internal.test.util.TestUtils;
45 import org.eclipse.aether.repository.RemoteRepository;
46 import org.eclipse.aether.resolution.ArtifactDescriptorException;
47 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
48 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
49 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
50 import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
51 import org.eclipse.aether.util.graph.manager.DefaultDependencyManager;
52 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
53 import org.eclipse.aether.util.graph.manager.TransitiveDependencyManager;
54 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
55 import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
56 import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
57 import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
58 import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
59 import org.eclipse.aether.util.graph.version.HighestVersionFilter;
60 import org.junit.jupiter.api.BeforeEach;
61 import org.junit.jupiter.api.Test;
62
63 import static java.util.Collections.singletonList;
64 import static java.util.Objects.requireNonNull;
65 import static org.junit.jupiter.api.Assertions.*;
66
67
68
69
70 public abstract class DependencyCollectorDelegateTestSupport {
71
72 protected DefaultRepositorySystemSession session;
73
74 protected DependencyGraphParser parser;
75
76 protected RemoteRepository repository;
77
78 protected DependencyCollectorDelegate collector;
79
80 protected IniArtifactDescriptorReader newReader(String prefix) {
81 return new IniArtifactDescriptorReader("artifact-descriptions/" + prefix);
82 }
83
84 protected Dependency newDep(String coords) {
85 return newDep(coords, "");
86 }
87
88 protected Dependency newDep(String coords, String scope) {
89 return new Dependency(new DefaultArtifact(coords), scope);
90 }
91
92 @BeforeEach
93 void setup() {
94 session = TestUtils.newSession();
95 parser = new DependencyGraphParser("artifact-descriptions/");
96 repository = new RemoteRepository.Builder("id", "default", "file:///").build();
97 collector = setupCollector(newReader(""));
98 }
99
100 protected abstract DependencyCollectorDelegate setupCollector(ArtifactDescriptorReader artifactDescriptorReader);
101
102 private static void assertEqualSubtree(DependencyNode expected, DependencyNode actual) {
103 assertEqualSubtree(expected, actual, new LinkedList<>());
104 }
105
106 private static void assertEqualSubtree(
107 DependencyNode expected, DependencyNode actual, LinkedList<DependencyNode> parents) {
108 assertEquals(expected.getDependency(), actual.getDependency(), "path: " + parents);
109
110 if (actual.getDependency() != null) {
111 Artifact artifact = actual.getDependency().getArtifact();
112 for (DependencyNode parent : parents) {
113 if (parent.getDependency() != null
114 && artifact.equals(parent.getDependency().getArtifact())) {
115 return;
116 }
117 }
118 }
119
120 parents.addLast(expected);
121
122 assertEquals(
123 expected.getChildren().size(),
124 actual.getChildren().size(),
125 "path: " + parents + ", expected: " + expected.getChildren() + ", actual: " + actual.getChildren());
126
127 Iterator<DependencyNode> iterator1 = expected.getChildren().iterator();
128 Iterator<DependencyNode> iterator2 = actual.getChildren().iterator();
129
130 while (iterator1.hasNext()) {
131 assertEqualSubtree(iterator1.next(), iterator2.next(), parents);
132 }
133
134 parents.removeLast();
135 }
136
137 protected Dependency dep(DependencyNode root, int... coords) {
138 return path(root, coords).getDependency();
139 }
140
141 protected DependencyNode path(DependencyNode root, int... coords) {
142 try {
143 DependencyNode node = root;
144 for (int coord : coords) {
145 node = node.getChildren().get(coord);
146 }
147
148 return node;
149 } catch (IndexOutOfBoundsException | NullPointerException e) {
150 throw new IllegalArgumentException("illegal coordinates for child", e);
151 }
152 }
153
154 @Test
155 void testInterruption() throws Exception {
156 Dependency dependency = newDep("gid:aid:ext:ver", "compile");
157 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
158 AtomicReference<Object> cause = new AtomicReference<>(null);
159 Thread t = new Thread(() -> {
160 Thread.currentThread().interrupt();
161 try {
162 collector.collectDependencies(session, request);
163 fail("We should throw");
164 } catch (DependencyCollectionException e) {
165 cause.set(e.getCause());
166 }
167 });
168 t.start();
169 t.join();
170 assertTrue(cause.get() instanceof InterruptedException, String.valueOf(cause.get()));
171 }
172
173 @Test
174 void testSimpleCollection() throws DependencyCollectionException {
175 Dependency dependency = newDep("gid:aid:ext:ver", "compile");
176 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
177 CollectResult result = collector.collectDependencies(session, request);
178
179 assertEquals(0, result.getExceptions().size());
180
181 DependencyNode root = result.getRoot();
182 Dependency newDependency = root.getDependency();
183
184 assertEquals(dependency, newDependency);
185 assertEquals(dependency.getArtifact(), newDependency.getArtifact());
186
187 assertEquals(1, root.getChildren().size());
188
189 Dependency expect = newDep("gid:aid2:ext:ver", "compile");
190 assertEquals(expect, root.getChildren().get(0).getDependency());
191 }
192
193 @Test
194 void testMissingDependencyDescription() {
195 CollectRequest request = new CollectRequest(newDep("missing:description:ext:ver"), singletonList(repository));
196 try {
197 collector.collectDependencies(session, request);
198 fail("expected exception");
199 } catch (DependencyCollectionException e) {
200 CollectResult result = e.getResult();
201 assertSame(request, result.getRequest());
202 assertNotNull(result.getExceptions());
203 assertEquals(1, result.getExceptions().size());
204
205 assertTrue(result.getExceptions().get(0) instanceof ArtifactDescriptorException);
206
207 assertEquals(request.getRoot(), result.getRoot().getDependency());
208 }
209 }
210
211 @Test
212 void testDuplicates() throws DependencyCollectionException {
213 Dependency dependency = newDep("duplicate:transitive:ext:dependency");
214 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
215
216 CollectResult result = collector.collectDependencies(session, request);
217
218 assertEquals(0, result.getExceptions().size());
219
220 DependencyNode root = result.getRoot();
221 Dependency newDependency = root.getDependency();
222
223 assertEquals(dependency, newDependency);
224 assertEquals(dependency.getArtifact(), newDependency.getArtifact());
225
226 assertEquals(2, root.getChildren().size());
227
228 Dependency dep = newDep("gid:aid:ext:ver", "compile");
229 assertEquals(dep, dep(root, 0));
230
231 dep = newDep("gid:aid2:ext:ver", "compile");
232 assertEquals(dep, dep(root, 1));
233 assertEquals(dep, dep(root, 0, 0));
234 assertEquals(dep(root, 1), dep(root, 0, 0));
235 }
236
237 @Test
238 void testEqualSubtree() throws IOException, DependencyCollectionException {
239 DependencyNode root = parser.parseResource("expectedSubtreeComparisonResult.txt");
240 Dependency dependency = root.getDependency();
241 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
242
243 CollectResult result = collector.collectDependencies(session, request);
244 assertEqualSubtree(root, result.getRoot());
245 }
246
247 @Test
248 void testCyclicDependencies() throws Exception {
249 DependencyNode root = parser.parseResource("cycle.txt");
250 CollectRequest request = new CollectRequest(root.getDependency(), singletonList(repository));
251 CollectResult result = collector.collectDependencies(session, request);
252 assertEqualSubtree(root, result.getRoot());
253 }
254
255 @Test
256 void testCyclicDependenciesBig() throws Exception {
257 CollectRequest request = new CollectRequest(newDep("1:2:pom:5.50-SNAPSHOT"), singletonList(repository));
258 collector = setupCollector(newReader("cycle-big/"));
259 CollectResult result = collector.collectDependencies(session, request);
260 assertNotNull(result.getRoot());
261
262 }
263
264 @Test
265 void testCyclicProjects() throws Exception {
266 CollectRequest request = new CollectRequest(newDep("test:a:2"), singletonList(repository));
267 collector = setupCollector(newReader("versionless-cycle/"));
268 CollectResult result = collector.collectDependencies(session, request);
269 DependencyNode root = result.getRoot();
270 DependencyNode a1 = path(root, 0, 0);
271 assertEquals("a", a1.getArtifact().getArtifactId());
272 assertEquals("1", a1.getArtifact().getVersion());
273 for (DependencyNode child : a1.getChildren()) {
274 assertNotEquals("1", child.getArtifact().getVersion());
275 }
276
277 assertEquals(1, result.getCycles().size());
278 DependencyCycle cycle = result.getCycles().get(0);
279 assertEquals(Collections.emptyList(), cycle.getPrecedingDependencies());
280 assertEquals(
281 Arrays.asList(root.getDependency(), path(root, 0).getDependency(), a1.getDependency()),
282 cycle.getCyclicDependencies());
283 }
284
285 @Test
286 void testCyclicProjects_ConsiderLabelOfRootlessGraph() throws Exception {
287 Dependency dep = newDep("gid:aid:ver", "compile");
288 CollectRequest request = new CollectRequest()
289 .addDependency(dep)
290 .addRepository(repository)
291 .setRootArtifact(dep.getArtifact());
292 CollectResult result = collector.collectDependencies(session, request);
293 DependencyNode root = result.getRoot();
294 DependencyNode a1 = root.getChildren().get(0);
295 assertEquals("aid", a1.getArtifact().getArtifactId());
296 assertEquals("ver", a1.getArtifact().getVersion());
297 DependencyNode a2 = a1.getChildren().get(0);
298 assertEquals("aid2", a2.getArtifact().getArtifactId());
299 assertEquals("ver", a2.getArtifact().getVersion());
300
301 assertEquals(1, result.getCycles().size());
302 DependencyCycle cycle = result.getCycles().get(0);
303 assertEquals(Collections.emptyList(), cycle.getPrecedingDependencies());
304 assertEquals(
305 Arrays.asList(new Dependency(dep.getArtifact(), null), a1.getDependency()),
306 cycle.getCyclicDependencies());
307 }
308
309 @Test
310 void testPartialResultOnError() throws IOException {
311 DependencyNode root = parser.parseResource("expectedPartialSubtreeOnError.txt");
312
313 Dependency dependency = root.getDependency();
314 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
315
316 CollectResult result;
317 try {
318 collector.collectDependencies(session, request);
319 fail("expected exception ");
320 } catch (DependencyCollectionException e) {
321 result = e.getResult();
322
323 assertSame(request, result.getRequest());
324 assertNotNull(result.getExceptions());
325 assertEquals(1, result.getExceptions().size());
326
327 assertTrue(result.getExceptions().get(0) instanceof ArtifactDescriptorException);
328
329 assertEqualSubtree(root, result.getRoot());
330 }
331 }
332
333 @Test
334 void testCollectMultipleDependencies() throws DependencyCollectionException {
335 Dependency root1 = newDep("gid:aid:ext:ver", "compile");
336 Dependency root2 = newDep("gid:aid2:ext:ver", "compile");
337 List<Dependency> dependencies = Arrays.asList(root1, root2);
338 CollectRequest request = new CollectRequest(dependencies, null, singletonList(repository));
339 CollectResult result = collector.collectDependencies(session, request);
340
341 assertEquals(0, result.getExceptions().size());
342 assertEquals(2, result.getRoot().getChildren().size());
343 assertEquals(root1, dep(result.getRoot(), 0));
344
345 assertEquals(1, path(result.getRoot(), 0).getChildren().size());
346 assertEquals(root2, dep(result.getRoot(), 0, 0));
347
348 assertEquals(0, path(result.getRoot(), 1).getChildren().size());
349 assertEquals(root2, dep(result.getRoot(), 1));
350 }
351
352 @Test
353 void testArtifactDescriptorResolutionNotRestrictedToRepoHostingSelectedVersion() throws Exception {
354 RemoteRepository repo2 = new RemoteRepository.Builder("test", "default", "file:///").build();
355
356 final List<RemoteRepository> repos = new ArrayList<>();
357
358 collector = setupCollector(new ArtifactDescriptorReader() {
359 @Override
360 public ArtifactDescriptorResult readArtifactDescriptor(
361 RepositorySystemSession session, ArtifactDescriptorRequest request) {
362 repos.addAll(request.getRepositories());
363 return new ArtifactDescriptorResult(request);
364 }
365 });
366
367 List<Dependency> dependencies = singletonList(newDep("verrange:parent:jar:1[1,)", "compile"));
368 CollectRequest request = new CollectRequest(dependencies, null, Arrays.asList(repository, repo2));
369 CollectResult result = collector.collectDependencies(session, request);
370
371 assertEquals(0, result.getExceptions().size());
372 assertEquals(2, repos.size());
373 assertEquals("id", repos.get(0).getId());
374 assertEquals("test", repos.get(1).getId());
375 }
376
377 @Test
378 void testManagedVersionScope() throws DependencyCollectionException {
379 Dependency dependency = newDep("managed:aid:ext:ver");
380 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
381
382 session.setDependencyManager(new ClassicDependencyManager(null));
383
384 CollectResult result = collector.collectDependencies(session, request);
385
386 assertEquals(0, result.getExceptions().size());
387
388 DependencyNode root = result.getRoot();
389
390 assertEquals(dependency, dep(root));
391 assertEquals(dependency.getArtifact(), dep(root).getArtifact());
392
393 assertEquals(1, root.getChildren().size());
394 Dependency expect = newDep("gid:aid:ext:ver", "compile");
395 assertEquals(expect, dep(root, 0));
396
397 assertEquals(1, path(root, 0).getChildren().size());
398 expect = newDep("gid:aid2:ext:managedVersion", "managedScope");
399 assertEquals(expect, dep(root, 0, 0));
400 }
401
402 @Test
403 void testDependencyManagement() throws IOException, DependencyCollectionException {
404 collector = setupCollector(newReader("managed/"));
405
406 DependencyNode root = parser.parseResource("expectedSubtreeComparisonResult.txt");
407 TestDependencyManager depMgmt = new TestDependencyManager();
408 depMgmt.add(dep(root, 0), "managed", null, null);
409 depMgmt.add(dep(root, 0, 1), "managed", "managed", null);
410 depMgmt.add(dep(root, 1), null, null, "managed");
411 session.setDependencyManager(depMgmt);
412
413
414
415 CollectRequest request = new CollectRequest(dep(root), singletonList(repository));
416 CollectResult result = collector.collectDependencies(session, request);
417
418 DependencyNode node = result.getRoot();
419 assertEquals("managed", dep(node, 0, 1).getArtifact().getVersion());
420 assertEquals("managed", dep(node, 0, 1).getScope());
421
422 assertEquals("managed", dep(node, 1).getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null));
423 assertEquals("managed", dep(node, 0, 0).getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null));
424 }
425
426 @Test
427 void testDependencyManagement_VerboseMode() throws Exception {
428 String depId = "gid:aid2:ext";
429 TestDependencyManager depMgmt = new TestDependencyManager();
430 depMgmt.version(depId, "managedVersion");
431 depMgmt.scope(depId, "managedScope");
432 depMgmt.optional(depId, Boolean.TRUE);
433 depMgmt.path(depId, "managedPath");
434 depMgmt.exclusions(depId, new Exclusion("gid", "aid", "*", "*"));
435 session.setDependencyManager(depMgmt);
436 session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE);
437
438 CollectRequest request = new CollectRequest().setRoot(newDep("gid:aid:ver"));
439 CollectResult result = collector.collectDependencies(session, request);
440 DependencyNode node = result.getRoot().getChildren().get(0);
441 assertEquals(
442 DependencyNode.MANAGED_VERSION
443 | DependencyNode.MANAGED_SCOPE
444 | DependencyNode.MANAGED_OPTIONAL
445 | DependencyNode.MANAGED_PROPERTIES
446 | DependencyNode.MANAGED_EXCLUSIONS,
447 node.getManagedBits());
448 assertEquals("ver", DependencyManagerUtils.getPremanagedVersion(node));
449 assertEquals("compile", DependencyManagerUtils.getPremanagedScope(node));
450 assertEquals(Boolean.FALSE, DependencyManagerUtils.getPremanagedOptional(node));
451 }
452
453 @Test
454 void testDependencyManagement_TransitiveDependencyManager() throws DependencyCollectionException, IOException {
455 collector = setupCollector(newReader("managed/"));
456 parser = new DependencyGraphParser("artifact-descriptions/managed/");
457 session.setDependencyManager(new TransitiveDependencyManager(null));
458 final Dependency root = newDep("gid:root:ext:ver", "compile");
459 CollectRequest request = new CollectRequest(root, singletonList(repository));
460 request.addManagedDependency(newDep("gid:root:ext:must-retain-core-management"));
461 CollectResult result = collector.collectDependencies(session, request);
462
463 final DependencyNode expectedTree = parser.parseResource("management-tree.txt");
464 assertEqualSubtree(expectedTree, result.getRoot());
465
466
467 final CollectRequest rootArtifactRequest = new CollectRequest();
468 rootArtifactRequest.setRepositories(singletonList(repository));
469 rootArtifactRequest.setRootArtifact(new DefaultArtifact("gid:root:ext:ver"));
470 rootArtifactRequest.addDependency(newDep("gid:direct:ext:ver", "compile"));
471 rootArtifactRequest.addManagedDependency(newDep("gid:root:ext:must-retain-core-management"));
472 rootArtifactRequest.addManagedDependency(newDep("gid:direct:ext:must-retain-core-management"));
473 rootArtifactRequest.addManagedDependency(newDep("gid:transitive-1:ext:managed-by-root"));
474 session.setDependencyManager(new TransitiveDependencyManager(null));
475 result = collector.collectDependencies(session, rootArtifactRequest);
476 assertEqualSubtree(expectedTree, toDependencyResult(result.getRoot(), "compile", null));
477 }
478
479 @Test
480 void testDependencyManagement_DefaultDependencyManager() throws DependencyCollectionException, IOException {
481 collector = setupCollector(newReader("managed/"));
482 parser = new DependencyGraphParser("artifact-descriptions/managed/");
483 session.setDependencyManager(new DefaultDependencyManager(null));
484 final Dependency root = newDep("gid:root:ext:ver", "compile");
485 CollectRequest request = new CollectRequest(root, singletonList(repository));
486 request.addManagedDependency(newDep("gid:root:ext:must-not-manage-root"));
487 request.addManagedDependency(newDep("gid:direct:ext:managed-by-dominant-request"));
488 CollectResult result = collector.collectDependencies(session, request);
489
490 final DependencyNode expectedTree = parser.parseResource("default-management-tree.txt");
491 assertEqualSubtree(expectedTree, result.getRoot());
492
493
494 final CollectRequest rootArtifactRequest = new CollectRequest();
495 rootArtifactRequest.setRepositories(singletonList(repository));
496 rootArtifactRequest.setRootArtifact(new DefaultArtifact("gid:root:ext:ver"));
497 rootArtifactRequest.addDependency(newDep("gid:direct:ext:ver", "compile"));
498 rootArtifactRequest.addManagedDependency(newDep("gid:root:ext:must-not-manage-root"));
499 rootArtifactRequest.addManagedDependency(newDep("gid:direct:ext:managed-by-dominant-request"));
500 rootArtifactRequest.addManagedDependency(newDep("gid:transitive-1:ext:managed-by-root"));
501 session.setDependencyManager(new DefaultDependencyManager(null));
502 result = collector.collectDependencies(session, rootArtifactRequest);
503 assertEqualSubtree(expectedTree, toDependencyResult(result.getRoot(), "compile", null));
504 }
505
506 @Test
507 void testTransitiveDepsUseRangesDirtyTree() throws DependencyCollectionException, IOException {
508
509
510
511
512
513 DependencyNode root = parser.parseResource(getTransitiveDepsUseRangesDirtyTreeResource());
514 Dependency dependency = root.getDependency();
515 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
516
517 CollectResult result = collector.collectDependencies(session, request);
518 assertEqualSubtree(root, result.getRoot());
519 }
520
521 protected abstract String getTransitiveDepsUseRangesDirtyTreeResource();
522
523 @Test
524 void testTransitiveDepsUseRangesAndRelocationDirtyTree() throws DependencyCollectionException, IOException {
525
526
527
528
529
530 DependencyNode root = parser.parseResource(getTransitiveDepsUseRangesAndRelocationDirtyTreeResource());
531 Dependency dependency = root.getDependency();
532 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
533
534 CollectResult result = collector.collectDependencies(session, request);
535 assertEqualSubtree(root, result.getRoot());
536 }
537
538 protected abstract String getTransitiveDepsUseRangesAndRelocationDirtyTreeResource();
539
540 private DependencyNode toDependencyResult(
541 final DependencyNode root, final String rootScope, final Boolean optional) {
542
543 assertNull(root.getDependency(), "Expected root artifact resolution result.");
544 final DefaultDependencyNode defaultNode =
545 new DefaultDependencyNode(new Dependency(root.getArtifact(), rootScope));
546
547 defaultNode.setChildren(root.getChildren());
548
549 if (optional != null) {
550 defaultNode.setOptional(optional);
551 }
552
553 return defaultNode;
554 }
555
556 @Test
557 void testVersionFilter() throws Exception {
558 session.setVersionFilter(new HighestVersionFilter());
559 CollectRequest request = new CollectRequest().setRoot(newDep("gid:aid:1"));
560 CollectResult result = collector.collectDependencies(session, request);
561 assertEquals(1, result.getRoot().getChildren().size());
562 }
563
564 @Test
565 void testDescriptorDependenciesEmpty() throws Exception {
566 collector = setupCollector(newReader("dependencies-empty/"));
567
568 session.setDependencyGraphTransformer(new ConflictResolver(
569 new NearestVersionSelector(),
570 new JavaScopeSelector(),
571 new SimpleOptionalitySelector(),
572 new JavaScopeDeriver()));
573
574 DependencyNode root = parser.parseResource("expectedSubtreeOnDescriptorDependenciesEmptyLeft.txt");
575 Dependency dependency = root.getDependency();
576 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
577 CollectResult result = collector.collectDependencies(session, request);
578 assertEqualSubtree(root, result.getRoot());
579
580 root = parser.parseResource("expectedSubtreeOnDescriptorDependenciesEmptyRight.txt");
581 dependency = root.getDependency();
582 request = new CollectRequest(dependency, singletonList(repository));
583 result = collector.collectDependencies(session, request);
584 assertEqualSubtree(root, result.getRoot());
585 }
586
587 static class TestDependencyManager implements DependencyManager {
588
589 private final Map<String, String> versions = new HashMap<>();
590
591 private final Map<String, String> scopes = new HashMap<>();
592
593 private final Map<String, Boolean> optionals = new HashMap<>();
594
595 private final Map<String, String> paths = new HashMap<>();
596
597 private final Map<String, Collection<Exclusion>> exclusions = new HashMap<>();
598
599 public void add(Dependency d, String version, String scope, String localPath) {
600 String id = toKey(d);
601 version(id, version);
602 scope(id, scope);
603 path(id, localPath);
604 }
605
606 public void version(String id, String version) {
607 versions.put(id, version);
608 }
609
610 public void scope(String id, String scope) {
611 scopes.put(id, scope);
612 }
613
614 public void optional(String id, Boolean optional) {
615 optionals.put(id, optional);
616 }
617
618 public void path(String id, String path) {
619 paths.put(id, path);
620 }
621
622 public void exclusions(String id, Exclusion... exclusions) {
623 this.exclusions.put(id, exclusions != null ? Arrays.asList(exclusions) : null);
624 }
625
626 @Override
627 public DependencyManagement manageDependency(Dependency dependency) {
628 requireNonNull(dependency, "dependency cannot be null");
629 String id = toKey(dependency);
630 DependencyManagement mgmt = new DependencyManagement();
631 mgmt.setVersion(versions.get(id));
632 mgmt.setScope(scopes.get(id));
633 mgmt.setOptional(optionals.get(id));
634 String path = paths.get(id);
635 if (path != null) {
636 mgmt.setProperties(Collections.singletonMap(ArtifactProperties.LOCAL_PATH, path));
637 }
638 mgmt.setExclusions(exclusions.get(id));
639 return mgmt;
640 }
641
642 private String toKey(Dependency dependency) {
643 return ArtifactIdUtils.toVersionlessId(dependency.getArtifact());
644 }
645
646 @Override
647 public DependencyManager deriveChildManager(DependencyCollectionContext context) {
648 requireNonNull(context, "context cannot be null");
649 return this;
650 }
651 }
652 }