blob: 68dbf72d2fe855b79153217215759298a6acaf13 [file] [log] [blame]
John Caterdfce7402018-07-17 13:23:44 -07001// Copyright 2018 The Bazel Authors. All rights reserved.
2//
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.
14
15package com.google.devtools.build.lib.skyframe;
16
17import static com.google.common.truth.Truth.assertThat;
18import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
19
20import com.google.auto.value.AutoValue;
21import com.google.common.collect.ImmutableList;
22import com.google.common.collect.ImmutableMap;
23import com.google.devtools.build.lib.analysis.BlazeDirectories;
24import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
25import com.google.devtools.build.lib.analysis.util.AnalysisMock;
26import com.google.devtools.build.lib.rules.platform.ToolchainTestCase;
27import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil.InvalidConstraintValueException;
28import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
29import com.google.devtools.build.skyframe.EvaluationResult;
30import com.google.devtools.build.skyframe.SkyFunction;
31import com.google.devtools.build.skyframe.SkyFunctionException;
32import com.google.devtools.build.skyframe.SkyFunctionName;
33import com.google.devtools.build.skyframe.SkyKey;
34import com.google.devtools.build.skyframe.SkyValue;
35import java.util.List;
36import javax.annotation.Nullable;
37import org.junit.Test;
38import org.junit.runner.RunWith;
39import org.junit.runners.JUnit4;
40
41/** Tests for {@link ConstraintValueLookupUtil}. */
42@RunWith(JUnit4.class)
43public class ConstraintValueLookupUtilTest extends ToolchainTestCase {
44
45 /**
46 * An {@link AnalysisMock} that injects {@link GetConstraintValueInfoFunction} into the Skyframe
47 * executor.
48 */
49 private static final class AnalysisMockWithGetPlatformInfoFunction extends AnalysisMock.Delegate {
50 AnalysisMockWithGetPlatformInfoFunction() {
51 super(AnalysisMock.get());
52 }
53
54 @Override
55 public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(
56 BlazeDirectories directories) {
57 return ImmutableMap.<SkyFunctionName, SkyFunction>builder()
58 .putAll(super.getSkyFunctions(directories))
59 .put(GET_CONSTRAINT_VALUE_INFO_FUNCTION, new GetConstraintValueInfoFunction())
60 .build();
61 }
62 }
63
64 @Override
65 protected AnalysisMock getAnalysisMock() {
66 return new AnalysisMockWithGetPlatformInfoFunction();
67 }
68
69 @Test
70 public void testConstraintValueLookup() throws Exception {
71 ConfiguredTargetKey linuxKey =
jcater83221e32020-05-28 11:37:39 -070072 ConfiguredTargetKey.builder()
73 .setLabel(makeLabel("//constraints:linux"))
74 .setConfigurationKey(targetConfigKey)
75 .build();
John Caterdfce7402018-07-17 13:23:44 -070076 ConfiguredTargetKey macKey =
jcater83221e32020-05-28 11:37:39 -070077 ConfiguredTargetKey.builder()
78 .setLabel(makeLabel("//constraints:mac"))
79 .setConfigurationKey(targetConfigKey)
80 .build();
John Caterdfce7402018-07-17 13:23:44 -070081 GetConstraintValueInfoKey key =
82 GetConstraintValueInfoKey.create(ImmutableList.of(linuxKey, macKey));
83
84 EvaluationResult<GetConstraintValueInfoValue> result = getConstraintValueInfo(key);
85
86 assertThatEvaluationResult(result).hasNoError();
87 assertThatEvaluationResult(result).hasEntryThat(key).isNotNull();
88
89 List<ConstraintValueInfo> constraintValues = result.get(key).constraintValues();
90 assertThat(constraintValues).contains(linuxConstraint);
91 assertThat(constraintValues).contains(macConstraint);
92 assertThat(constraintValues).hasSize(2);
93 }
94
95 @Test
96 public void testConstraintValueLookup_targetNotConstraintValue() throws Exception {
97 scratch.file("invalid/BUILD", "filegroup(name = 'not_a_constraint')");
98
99 ConfiguredTargetKey targetKey =
jcater83221e32020-05-28 11:37:39 -0700100 ConfiguredTargetKey.builder()
101 .setLabel(makeLabel("//invalid:not_a_constraint"))
102 .setConfigurationKey(targetConfigKey)
103 .build();
John Caterdfce7402018-07-17 13:23:44 -0700104 GetConstraintValueInfoKey key = GetConstraintValueInfoKey.create(ImmutableList.of(targetKey));
105
106 EvaluationResult<GetConstraintValueInfoValue> result = getConstraintValueInfo(key);
107
108 assertThatEvaluationResult(result).hasError();
109 assertThatEvaluationResult(result)
110 .hasErrorEntryForKeyThat(key)
111 .hasExceptionThat()
112 .isInstanceOf(InvalidConstraintValueException.class);
113 assertThatEvaluationResult(result)
114 .hasErrorEntryForKeyThat(key)
115 .hasExceptionThat()
116 .hasMessageThat()
117 .contains("//invalid:not_a_constraint");
118 }
119
120 @Test
121 public void testConstraintValueLookup_targetDoesNotExist() throws Exception {
122 ConfiguredTargetKey targetKey =
jcater83221e32020-05-28 11:37:39 -0700123 ConfiguredTargetKey.builder()
124 .setLabel(makeLabel("//fake:missing"))
125 .setConfigurationKey(targetConfigKey)
126 .build();
John Caterdfce7402018-07-17 13:23:44 -0700127 GetConstraintValueInfoKey key = GetConstraintValueInfoKey.create(ImmutableList.of(targetKey));
128
129 EvaluationResult<GetConstraintValueInfoValue> result = getConstraintValueInfo(key);
130
131 assertThatEvaluationResult(result).hasError();
132 assertThatEvaluationResult(result)
133 .hasErrorEntryForKeyThat(key)
134 .hasExceptionThat()
135 .isInstanceOf(InvalidConstraintValueException.class);
136 assertThatEvaluationResult(result)
137 .hasErrorEntryForKeyThat(key)
138 .hasExceptionThat()
139 .hasMessageThat()
Klaus Aehligca5565a2019-05-07 05:43:58 -0700140 .contains("no such package 'fake': BUILD file not found");
John Caterdfce7402018-07-17 13:23:44 -0700141 }
142
143 // Calls ConstraintValueLookupUtil.getConstraintValueInfo.
144 private static final SkyFunctionName GET_CONSTRAINT_VALUE_INFO_FUNCTION =
145 SkyFunctionName.createHermetic("GET_CONSTRAINT_VALUE_INFO_FUNCTION");
146
147 @AutoValue
148 abstract static class GetConstraintValueInfoKey implements SkyKey {
149 @Override
150 public SkyFunctionName functionName() {
151 return GET_CONSTRAINT_VALUE_INFO_FUNCTION;
152 }
153
154 abstract Iterable<ConfiguredTargetKey> constraintValueKeys();
155
156 public static GetConstraintValueInfoKey create(
157 Iterable<ConfiguredTargetKey> constraintValueKeys) {
158 return new AutoValue_ConstraintValueLookupUtilTest_GetConstraintValueInfoKey(
159 constraintValueKeys);
160 }
161 }
162
163 EvaluationResult<GetConstraintValueInfoValue> getConstraintValueInfo(
164 GetConstraintValueInfoKey key) throws InterruptedException {
165 try {
166 // Must re-enable analysis for Skyframe functions that create configured targets.
167 skyframeExecutor.getSkyframeBuildView().enableAnalysis(true);
168 return SkyframeExecutorTestUtils.evaluate(
169 skyframeExecutor, key, /*keepGoing=*/ false, reporter);
170 } finally {
171 skyframeExecutor.getSkyframeBuildView().enableAnalysis(false);
172 }
173 }
174
175 @AutoValue
176 abstract static class GetConstraintValueInfoValue implements SkyValue {
177 abstract List<ConstraintValueInfo> constraintValues();
178
179 static GetConstraintValueInfoValue create(List<ConstraintValueInfo> constraintValues) {
180 return new AutoValue_ConstraintValueLookupUtilTest_GetConstraintValueInfoValue(
181 constraintValues);
182 }
183 }
184
185 private static final class GetConstraintValueInfoFunction implements SkyFunction {
186
187 @Nullable
188 @Override
189 public SkyValue compute(SkyKey skyKey, Environment env)
190 throws SkyFunctionException, InterruptedException {
191 GetConstraintValueInfoKey key = (GetConstraintValueInfoKey) skyKey;
192 try {
193 List<ConstraintValueInfo> constraintValues =
194 ConstraintValueLookupUtil.getConstraintValueInfo(key.constraintValueKeys(), env);
195 if (env.valuesMissing()) {
196 return null;
197 }
198 return GetConstraintValueInfoValue.create(constraintValues);
199 } catch (InvalidConstraintValueException e) {
200 throw new GetConstraintValueInfoFunctionException(e);
201 }
202 }
203
204 @Nullable
205 @Override
206 public String extractTag(SkyKey skyKey) {
207 return null;
208 }
209 }
210
211 private static class GetConstraintValueInfoFunctionException extends SkyFunctionException {
212 public GetConstraintValueInfoFunctionException(InvalidConstraintValueException e) {
213 super(e, Transience.PERSISTENT);
214 }
215 }
216}