blob: 1e87c3fdaeda6121f64b9ce0669fdad7b61cce4f [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2015 The Bazel Authors. All rights reserved.
Ulf Adams3b2ac8e2015-04-23 19:09:50 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.analysis;
15
16import static com.google.common.truth.Truth.assertThat;
lberkiaea56b32017-05-30 12:35:33 +020017import static com.google.common.truth.Truth.assertWithMessage;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000018
Lukacs Berki7894c182016-05-10 12:07:01 +000019import com.google.common.collect.ImmutableMap;
lberki3c2c8212020-10-21 04:00:04 -070020import com.google.common.collect.Iterables;
21import com.google.devtools.build.lib.analysis.AspectCollection.AspectDeps;
Florian Weikertcca703a2015-12-07 09:56:38 +000022import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000023import com.google.devtools.build.lib.analysis.util.TestAspects;
ulfjack904a8d62018-05-29 05:17:35 -070024import com.google.devtools.build.lib.causes.Cause;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000025import com.google.devtools.build.lib.cmdline.Label;
Ulf Adams2ac20962016-02-01 13:04:54 +000026import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Dmitry Lomovb487ac62015-11-09 13:09:12 +000027import com.google.devtools.build.lib.packages.Aspect;
Dmitry Lomov15756522016-12-16 16:52:37 +000028import com.google.devtools.build.lib.packages.AspectDescriptor;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000029import com.google.devtools.build.lib.packages.NativeAspectClass;
Ulf Adams2ac20962016-02-01 13:04:54 +000030import com.google.devtools.build.lib.packages.NoSuchPackageException;
31import com.google.devtools.build.lib.packages.NoSuchTargetException;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000032import com.google.devtools.build.lib.packages.Target;
Greg Estrend5353252016-08-11 22:13:31 +000033import com.google.devtools.build.lib.util.OrderedSetMultimap;
janakrd0a3c5e2018-08-09 15:59:24 -070034import java.util.Map;
35import java.util.function.Function;
36import java.util.stream.Collectors;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000037import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
40import org.junit.runners.JUnit4;
41
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000042/**
43 * Tests for {@link DependencyResolver}.
44 *
jhorvitze68a7d02021-04-26 11:49:28 -070045 * <p>These use custom rules so that all usual and unusual cases related to aspect processing can be
46 * tested.
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000047 *
48 * <p>It would be nicer is we didn't have a Skyframe executor, if we didn't have that, we'd need a
49 * way to create a configuration, a package manager and a whole lot of other things, so it's just
50 * easier this way.
51 */
52@RunWith(JUnit4.class)
Florian Weikertcca703a2015-12-07 09:56:38 +000053public class DependencyResolverTest extends AnalysisTestCase {
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000054 private DependencyResolver dependencyResolver;
55
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000056 @Before
jhorvitze68a7d02021-04-26 11:49:28 -070057 public final void createResolver() {
mjhalupka5d7fa7b2018-03-22 13:37:38 -070058 dependencyResolver =
59 new DependencyResolver() {
janakr9fcef032018-01-23 13:38:24 -080060 @Override
janakrd0a3c5e2018-08-09 15:59:24 -070061 protected Map<Label, Target> getTargets(
lberki4cd44472019-02-06 08:36:34 -080062 OrderedSetMultimap<DependencyKind, Label> labelMap,
adgar412e03c2020-05-07 08:20:55 -070063 TargetAndConfiguration fromNode,
lberki4cd44472019-02-06 08:36:34 -080064 NestedSetBuilder<Cause> rootCauses) {
65 return labelMap.values().stream()
janakrd0a3c5e2018-08-09 15:59:24 -070066 .distinct()
67 .collect(
68 Collectors.toMap(
69 Function.identity(),
70 label -> {
71 try {
72 return packageManager.getTarget(reporter, label);
73 } catch (NoSuchPackageException
74 | NoSuchTargetException
75 | InterruptedException e) {
76 throw new IllegalStateException(e);
77 }
78 }));
janakr9fcef032018-01-23 13:38:24 -080079 }
janakr9fcef032018-01-23 13:38:24 -080080 };
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000081 }
82
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000083 private void pkg(String name, String... contents) throws Exception {
jhorvitze68a7d02021-04-26 11:49:28 -070084 scratch.file(name + "/BUILD", contents);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000085 }
86
John Cater2a546592020-05-19 04:48:52 -070087 private OrderedSetMultimap<DependencyKind, DependencyKey> dependentNodeMap(
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +000088 String targetName, NativeAspectClass aspect) throws Exception {
dannark90e2b4b2018-06-27 13:35:04 -070089 Target target =
90 packageManager.getTarget(reporter, Label.parseAbsolute(targetName, ImmutableMap.of()));
lberki102256f2019-02-08 01:34:23 -080091
jhorvitze68a7d02021-04-26 11:49:28 -070092 return dependencyResolver.dependentNodeMap(
93 new TargetAndConfiguration(target, getTargetConfiguration()),
94 getHostConfiguration(),
95 aspect != null ? Aspect.forNative(aspect) : null,
96 ImmutableMap.of(),
97 /*toolchainContexts=*/ null,
98 /*useToolchainTransition=*/ false,
99 /*trimmingTransitionFactory=*/ null);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000100 }
101
jhorvitze68a7d02021-04-26 11:49:28 -0700102 private static void assertDep(
John Cater2a546592020-05-19 04:48:52 -0700103 OrderedSetMultimap<DependencyKind, DependencyKey> dependentNodeMap,
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000104 String attrName,
105 String dep,
Dmitry Lomove8040172016-04-06 14:53:43 +0000106 AspectDescriptor... aspects) {
lberki102256f2019-02-08 01:34:23 -0800107 DependencyKind kind = null;
108 for (DependencyKind candidate : dependentNodeMap.keySet()) {
109 if (candidate.getAttribute() != null && candidate.getAttribute().getName().equals(attrName)) {
110 kind = candidate;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000111 break;
112 }
113 }
114
lberki102256f2019-02-08 01:34:23 -0800115 assertWithMessage("Attribute '" + attrName + "' not found").that(kind).isNotNull();
John Cater2a546592020-05-19 04:48:52 -0700116 DependencyKey dependency = null;
117 for (DependencyKey depCandidate : dependentNodeMap.get(kind)) {
lberki102256f2019-02-08 01:34:23 -0800118 if (depCandidate.getLabel().toString().equals(dep)) {
119 dependency = depCandidate;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000120 break;
121 }
122 }
123
lberkiaea56b32017-05-30 12:35:33 +0200124 assertWithMessage("Dependency '" + dep + "' on attribute '" + attrName + "' not found")
125 .that(dependency)
126 .isNotNull();
lberki3c2c8212020-10-21 04:00:04 -0700127 assertThat(Iterables.transform(dependency.getAspects().getUsedAspects(), AspectDeps::getAspect))
128 .containsExactlyElementsIn(aspects);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000129 }
130
131 @Test
132 public void hasAspectsRequiredByRule() throws Exception {
gregceb87a41f32017-11-29 07:46:25 -0800133 setRulesAvailableInTests(TestAspects.ASPECT_REQUIRING_RULE, TestAspects.BASE_RULE);
jhorvitze68a7d02021-04-26 11:49:28 -0700134 pkg("a", "aspect(name='a', foo=[':b'])", "aspect(name='b', foo=[])");
John Cater2a546592020-05-19 04:48:52 -0700135 OrderedSetMultimap<DependencyKind, DependencyKey> map = dependentNodeMap("//a:a", null);
jhorvitze68a7d02021-04-26 11:49:28 -0700136 assertDep(map, "foo", "//a:b", new AspectDescriptor(TestAspects.SIMPLE_ASPECT));
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000137 }
138
139 @Test
140 public void hasAspectsRequiredByAspect() throws Exception {
gregceb87a41f32017-11-29 07:46:25 -0800141 setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE);
jhorvitze68a7d02021-04-26 11:49:28 -0700142 pkg("a", "simple(name='a', foo=[':b'])", "simple(name='b', foo=[])");
John Cater2a546592020-05-19 04:48:52 -0700143 OrderedSetMultimap<DependencyKind, DependencyKey> map =
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000144 dependentNodeMap("//a:a", TestAspects.ATTRIBUTE_ASPECT);
jhorvitze68a7d02021-04-26 11:49:28 -0700145 assertDep(map, "foo", "//a:b", new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT));
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000146 }
147
148 @Test
Dmitry Lomovbb5901b2016-09-27 08:49:26 +0000149 public void hasAllAttributesAspect() throws Exception {
gregceb87a41f32017-11-29 07:46:25 -0800150 setRulesAvailableInTests(TestAspects.BASE_RULE, TestAspects.SIMPLE_RULE);
jhorvitze68a7d02021-04-26 11:49:28 -0700151 pkg("a", "simple(name='a', foo=[':b'])", "simple(name='b', foo=[])");
John Cater2a546592020-05-19 04:48:52 -0700152 OrderedSetMultimap<DependencyKind, DependencyKey> map =
Dmitry Lomovbb5901b2016-09-27 08:49:26 +0000153 dependentNodeMap("//a:a", TestAspects.ALL_ATTRIBUTES_ASPECT);
jhorvitze68a7d02021-04-26 11:49:28 -0700154 assertDep(map, "foo", "//a:b", new AspectDescriptor(TestAspects.ALL_ATTRIBUTES_ASPECT));
Dmitry Lomovbb5901b2016-09-27 08:49:26 +0000155 }
156
157 @Test
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000158 public void hasAspectDependencies() throws Exception {
gregceb87a41f32017-11-29 07:46:25 -0800159 setRulesAvailableInTests(TestAspects.BASE_RULE);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000160 pkg("a", "base(name='a')");
161 pkg("extra", "base(name='extra')");
John Cater2a546592020-05-19 04:48:52 -0700162 OrderedSetMultimap<DependencyKind, DependencyKey> map =
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000163 dependentNodeMap("//a:a", TestAspects.EXTRA_ATTRIBUTE_ASPECT);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000164 assertDep(map, "$dep", "//extra:extra");
165 }
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000166}