blob: b231b7c576977eb9e2c9a472a6cbb540b91f2a95 [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;
Florian Weikertfd735f32015-11-27 17:32:23 +000017import static org.junit.Assert.assertNotNull;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000018
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.ListMultimap;
Michael Staibb7aacc62015-07-16 08:11:14 +000021import com.google.common.testing.EqualsTester;
22import com.google.common.testing.NullPointerTester;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000023import com.google.devtools.build.lib.analysis.DependencyResolver.Dependency;
Michael Staibb7aacc62015-07-16 08:11:14 +000024import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000025import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
Florian Weikertcca703a2015-12-07 09:56:38 +000026import com.google.devtools.build.lib.analysis.util.AnalysisTestCase;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000027import com.google.devtools.build.lib.analysis.util.TestAspects;
28import com.google.devtools.build.lib.analysis.util.TestAspects.AspectRequiringRule;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000029import com.google.devtools.build.lib.cmdline.Label;
Dmitry Lomovb487ac62015-11-09 13:09:12 +000030import com.google.devtools.build.lib.packages.Aspect;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000031import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000032import com.google.devtools.build.lib.packages.NativeAspectClass;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000033import com.google.devtools.build.lib.packages.NoSuchThingException;
34import com.google.devtools.build.lib.packages.Target;
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000035import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
36
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
42import javax.annotation.Nullable;
43
44/**
45 * Tests for {@link DependencyResolver}.
46 *
47 * <p>These use custom rules so that all usual and unusual cases related to aspect processing can
48 * be tested.
49 *
50 * <p>It would be nicer is we didn't have a Skyframe executor, if we didn't have that, we'd need a
51 * way to create a configuration, a package manager and a whole lot of other things, so it's just
52 * easier this way.
53 */
54@RunWith(JUnit4.class)
Florian Weikertcca703a2015-12-07 09:56:38 +000055public class DependencyResolverTest extends AnalysisTestCase {
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000056 private DependencyResolver dependencyResolver;
57
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000058 @Before
Florian Weikertfd735f32015-11-27 17:32:23 +000059 public final void createResolver() throws Exception {
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000060 dependencyResolver = new DependencyResolver() {
61 @Override
62 protected void invalidVisibilityReferenceHook(TargetAndConfiguration node, Label label) {
63 throw new IllegalStateException();
64 }
65
66 @Override
67 protected void invalidPackageGroupReferenceHook(TargetAndConfiguration node, Label label) {
68 throw new IllegalStateException();
69 }
70
71 @Nullable
72 @Override
73 protected Target getTarget(Label label) throws NoSuchThingException {
74 try {
75 return packageManager.getTarget(reporter, label);
76 } catch (InterruptedException e) {
77 throw new IllegalStateException(e);
78 }
79 }
80 };
81 }
82
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000083 private void pkg(String name, String... contents) throws Exception {
Ulf Adams01f1b462015-04-27 09:52:33 +000084 scratch.file("" + name + "/BUILD", contents);
Ulf Adams3b2ac8e2015-04-23 19:09:50 +000085 }
86
87 @SafeVarargs
88 private final void setRules(RuleDefinition... rules) throws Exception {
89 ConfiguredRuleClassProvider.Builder builder =
90 new ConfiguredRuleClassProvider.Builder();
91 TestRuleClassProvider.addStandardRules(builder);
92 for (RuleDefinition rule : rules) {
93 builder.addRuleDefinition(rule);
94 }
95
96 useRuleClassProvider(builder.build());
97 update();
98 }
99
Dmitry Lomov6231d082015-11-02 17:17:20 +0000100 private <T extends ConfiguredNativeAspectFactory>
101 ListMultimap<Attribute, Dependency> dependentNodeMap(
102 String targetName, Class<T> aspect) throws Exception {
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000103 Target target = packageManager.getTarget(reporter, Label.parseAbsolute(targetName));
104 return dependencyResolver.dependentNodeMap(
105 new TargetAndConfiguration(target, getTargetConfiguration()),
Greg Estren00049432015-08-25 16:43:47 +0000106 getHostConfiguration(),
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000107 aspect != null ? new Aspect(new NativeAspectClass<T>(aspect)) : null,
Marian Lobur42020002015-09-02 12:22:46 +0000108 ImmutableSet.<ConfigMatchingProvider>of());
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000109 }
110
111 @SafeVarargs
112 private final void assertDep(
113 ListMultimap<Attribute, Dependency> dependentNodeMap,
114 String attrName,
115 String dep,
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000116 Aspect... aspects) {
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000117 Attribute attr = null;
118 for (Attribute candidate : dependentNodeMap.keySet()) {
119 if (candidate.getName().equals(attrName)) {
120 attr = candidate;
121 break;
122 }
123 }
124
125 assertNotNull("Attribute '" + attrName + "' not found", attr);
126 Dependency dependency = null;
127 for (Dependency candidate : dependentNodeMap.get(attr)) {
128 if (candidate.getLabel().toString().equals(dep)) {
129 dependency = candidate;
130 break;
131 }
132 }
133
134 assertNotNull("Dependency '" + dep + "' on attribute '" + attrName + "' not found", dependency);
135 assertThat(dependency.getAspects()).containsExactly((Object[]) aspects);
136 }
137
138 @Test
139 public void hasAspectsRequiredByRule() throws Exception {
140 setRules(new AspectRequiringRule(), new TestAspects.BaseRule());
141 pkg("a",
142 "aspect(name='a', foo=[':b'])",
143 "aspect(name='b', foo=[])");
144 ListMultimap<Attribute, Dependency> map = dependentNodeMap("//a:a", null);
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000145 assertDep(
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000146 map, "foo", "//a:b", new Aspect(new NativeAspectClass(TestAspects.SimpleAspect.class)));
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000147 }
148
149 @Test
150 public void hasAspectsRequiredByAspect() throws Exception {
151 setRules(new TestAspects.BaseRule(), new TestAspects.SimpleRule());
152 pkg("a",
153 "simple(name='a', foo=[':b'])",
154 "simple(name='b', foo=[])");
155 ListMultimap<Attribute, Dependency> map =
156 dependentNodeMap("//a:a", TestAspects.AttributeAspect.class);
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000157 assertDep(
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000158 map, "foo", "//a:b", new Aspect(new NativeAspectClass(TestAspects.AttributeAspect.class)));
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000159 }
160
161 @Test
162 public void hasAspectDependencies() throws Exception {
163 setRules(new TestAspects.BaseRule());
164 pkg("a", "base(name='a')");
165 pkg("extra", "base(name='extra')");
166 ListMultimap<Attribute, Dependency> map =
167 dependentNodeMap("//a:a", TestAspects.ExtraAttributeAspect.class);
168 assertDep(map, "$dep", "//extra:extra");
169 }
Michael Staibb7aacc62015-07-16 08:11:14 +0000170
171 @Test
172 public void constructorsForDependencyPassNullableTester() throws Exception {
173 update();
174
175 new NullPointerTester()
176 .setDefault(Label.class, Label.parseAbsolute("//a"))
177 .setDefault(BuildConfiguration.class, getTargetConfiguration())
178 .setDefault(ImmutableSet.class, ImmutableSet.of())
179 .testAllPublicConstructors(Dependency.class);
180 }
181
182 @Test
183 public void equalsOnDependencyPassesEqualsTester() throws Exception {
184 update();
185
186 Label a = Label.parseAbsolute("//a");
187 Label aExplicit = Label.parseAbsolute("//a:a");
188 Label b = Label.parseAbsolute("//b");
189
190 BuildConfiguration host = getHostConfiguration();
191 BuildConfiguration target = getTargetConfiguration();
192
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000193 ImmutableSet<Aspect> twoAspects =
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000194 ImmutableSet.of(
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000195 new Aspect(new NativeAspectClass(TestAspects.SimpleAspect.class)),
196 new Aspect(new NativeAspectClass(TestAspects.AttributeAspect.class)));
197 ImmutableSet<Aspect> inverseAspects =
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000198 ImmutableSet.of(
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000199 new Aspect(new NativeAspectClass(TestAspects.AttributeAspect.class)),
200 new Aspect(new NativeAspectClass(TestAspects.SimpleAspect.class)));
201 ImmutableSet<Aspect> differentAspects =
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000202 ImmutableSet.of(
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000203 new Aspect(new NativeAspectClass(TestAspects.AttributeAspect.class)),
204 new Aspect(new NativeAspectClass(TestAspects.ErrorAspect.class)));
Michael Staibb7aacc62015-07-16 08:11:14 +0000205
206 new EqualsTester()
207 .addEqualityGroup(
208 // base set: //a, host configuration, normal aspect set
209 new Dependency(a, host, twoAspects),
210 new Dependency(aExplicit, host, twoAspects),
211 new Dependency(a, host, inverseAspects),
212 new Dependency(aExplicit, host, inverseAspects))
213 .addEqualityGroup(
214 // base set but with label //b
215 new Dependency(b, host, twoAspects),
216 new Dependency(b, host, inverseAspects))
217 .addEqualityGroup(
218 // base set but with target configuration
219 new Dependency(a, target, twoAspects),
220 new Dependency(aExplicit, target, twoAspects),
221 new Dependency(a, target, inverseAspects),
222 new Dependency(aExplicit, target, inverseAspects))
223 .addEqualityGroup(
224 // base set but with null configuration
Greg Estren00049432015-08-25 16:43:47 +0000225 new Dependency(a, (BuildConfiguration) null, twoAspects),
226 new Dependency(aExplicit, (BuildConfiguration) null, twoAspects),
227 new Dependency(a, (BuildConfiguration) null, inverseAspects),
228 new Dependency(aExplicit, (BuildConfiguration) null, inverseAspects))
Michael Staibb7aacc62015-07-16 08:11:14 +0000229 .addEqualityGroup(
230 // base set but with different aspects
231 new Dependency(a, host, differentAspects),
232 new Dependency(aExplicit, host, differentAspects))
233 .addEqualityGroup(
234 // base set but with label //b and target configuration
235 new Dependency(b, target, twoAspects),
236 new Dependency(b, target, inverseAspects))
237 .addEqualityGroup(
238 // base set but with label //b and null configuration
Greg Estren00049432015-08-25 16:43:47 +0000239 new Dependency(b, (BuildConfiguration) null, twoAspects),
240 new Dependency(b, (BuildConfiguration) null, inverseAspects))
Michael Staibb7aacc62015-07-16 08:11:14 +0000241 .addEqualityGroup(
242 // base set but with label //b and different aspects
243 new Dependency(b, host, differentAspects))
244 .addEqualityGroup(
245 // base set but with target configuration and different aspects
246 new Dependency(a, target, differentAspects),
247 new Dependency(aExplicit, target, differentAspects))
248 .addEqualityGroup(
249 // base set but with null configuration and different aspects
Greg Estren00049432015-08-25 16:43:47 +0000250 new Dependency(a, (BuildConfiguration) null, differentAspects),
251 new Dependency(aExplicit, (BuildConfiguration) null, differentAspects))
Michael Staibb7aacc62015-07-16 08:11:14 +0000252 .addEqualityGroup(
253 // inverse of base set: //b, target configuration, different aspects
254 new Dependency(b, target, differentAspects))
255 .addEqualityGroup(
256 // inverse of base set: //b, null configuration, different aspects
Greg Estren00049432015-08-25 16:43:47 +0000257 new Dependency(b, (BuildConfiguration) null, differentAspects))
Michael Staibb7aacc62015-07-16 08:11:14 +0000258 .testEquals();
259 }
Ulf Adams3b2ac8e2015-04-23 19:09:50 +0000260}