blob: 48920e79647d3afc26ec2c1f37299c95858d3984 [file] [log] [blame]
juliexxiadeb028e2019-01-05 17:19:21 -08001// 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.
14package com.google.devtools.build.lib.analysis;
15
Googler35f81b42023-07-11 08:49:47 -070016import static com.google.common.collect.Iterables.getOnlyElement;
juliexxiadeb028e2019-01-05 17:19:21 -080017import static com.google.common.truth.Truth.assertThat;
Googler068d8452022-08-26 03:17:07 -070018import static com.google.devtools.build.lib.bazel.bzlmod.BzlmodTestUtil.createModuleKey;
juliexxiadeb028e2019-01-05 17:19:21 -080019
Googler068d8452022-08-26 03:17:07 -070020import com.google.common.collect.ImmutableList;
juliexxia22de6cd2019-01-09 07:25:23 -080021import com.google.common.collect.ImmutableMap;
gregce11f25402021-07-08 07:14:10 -070022import com.google.common.collect.ImmutableSet;
Googler35f81b42023-07-11 08:49:47 -070023import com.google.common.eventbus.Subscribe;
jhorvitz33f76482021-10-28 10:13:26 -070024import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
gregce06b76c92020-06-19 14:46:56 -070025import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
gregce11f25402021-07-08 07:14:10 -070026import com.google.devtools.build.lib.analysis.test.TestConfiguration.TestOptions;
juliexxiadeb028e2019-01-05 17:19:21 -080027import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
twigg4970e0f2021-03-31 15:34:49 -070028import com.google.devtools.build.lib.analysis.util.DummyTestFragment;
29import com.google.devtools.build.lib.analysis.util.DummyTestFragment.DummyTestOptions;
juliexxia22de6cd2019-01-09 07:25:23 -080030import com.google.devtools.build.lib.cmdline.Label;
gregce06b76c92020-06-19 14:46:56 -070031import com.google.devtools.build.lib.packages.Rule;
John Cater525227e2021-07-27 10:53:43 -070032import com.google.devtools.build.lib.packages.RuleTransitionData;
gregce7fc9ae72020-04-24 10:54:14 -070033import com.google.devtools.build.lib.rules.cpp.CppOptions;
gregce06b76c92020-06-19 14:46:56 -070034import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
gregced6795462020-12-14 11:06:45 -080035import com.google.devtools.build.lib.testutil.TestConstants;
juliexxia6778a052019-04-09 08:25:05 -070036import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
gregcefe644be2021-11-01 12:12:02 -070037import com.google.devtools.build.lib.vfs.ModifiedFileSet;
38import com.google.devtools.build.lib.vfs.PathFragment;
39import com.google.devtools.build.lib.vfs.Root;
gregce11f25402021-07-08 07:14:10 -070040import com.google.testing.junit.testparameterinjector.TestParameterInjector;
41import com.google.testing.junit.testparameterinjector.TestParameters;
Googler35f81b42023-07-11 08:49:47 -070042import java.util.ArrayList;
juliexxiaa13f5902020-12-10 09:19:01 -080043import java.util.List;
44import java.util.Map;
Googler1d4cecf2022-07-27 00:04:12 -070045import java.util.regex.Pattern;
juliexxiadeb028e2019-01-05 17:19:21 -080046import org.junit.Test;
47import org.junit.runner.RunWith;
juliexxiadeb028e2019-01-05 17:19:21 -080048
juliexxia1a70c272019-04-09 09:33:23 -070049/** Tests for StarlarkRuleTransitionProvider. */
gregce11f25402021-07-08 07:14:10 -070050@RunWith(TestParameterInjector.class)
jhorvitz2dd65662021-11-04 16:31:24 -070051public final class StarlarkRuleTransitionProviderTest extends BuildViewTestCase {
jhorvitz2dd65662021-11-04 16:31:24 -070052
juliexxia6778a052019-04-09 08:25:05 -070053 @Override
brandjon232a6b82020-06-08 12:32:49 -070054 protected ConfiguredRuleClassProvider createRuleClassProvider() {
juliexxia6778a052019-04-09 08:25:05 -070055 ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
56 TestRuleClassProvider.addStandardRules(builder);
gregce4ed65b02020-11-18 07:06:25 -080057 builder.addConfigurationFragment(DummyTestFragment.class);
juliexxia6778a052019-04-09 08:25:05 -070058 return builder.build();
59 }
60
aiuto50226ac2020-06-14 21:28:27 -070061 private void writeAllowlistFile() throws Exception {
cmita83563582021-06-15 01:57:45 -070062 scratch.overwriteFile(
cushon1812caf2020-06-24 10:54:19 -070063 "tools/allowlists/function_transition_allowlist/BUILD",
juliexxia30976d82019-03-12 10:59:26 -070064 "package_group(",
cushon1812caf2020-06-24 10:54:19 -070065 " name = 'function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -070066 " packages = [",
67 " '//test/...',",
68 " ],",
69 ")");
70 }
71
juliexxiadeb028e2019-01-05 17:19:21 -080072 @Test
juliexxiaeee87e92019-04-30 13:21:42 -070073 public void testBadReturnTypeFromTransition() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -070074 writeAllowlistFile();
juliexxiaeee87e92019-04-30 13:21:42 -070075 scratch.file(
76 "test/transitions.bzl",
77 "def _impl(settings, attr):",
78 " return 'cpu=k8'",
79 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -070080 " outputs = ['//command_line_option:foo'])");
juliexxiaeee87e92019-04-30 13:21:42 -070081 scratch.file(
82 "test/rules.bzl",
83 "load('//test:transitions.bzl', 'my_transition')",
84 "def _impl(ctx):",
85 " return []",
86 "my_rule = rule(",
87 " implementation = _impl,",
88 " cfg = my_transition,",
89 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -070090 " '_allowlist_function_transition': attr.label(",
91 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiaeee87e92019-04-30 13:21:42 -070092 " ),",
93 " })");
94 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
95
Googler35f81b42023-07-11 08:49:47 -070096 var collector = new AnalysisRootCauseCollector();
97 eventBus.register(collector);
juliexxiaeee87e92019-04-30 13:21:42 -070098 reporter.removeHandler(failFastHandler);
99 getConfiguredTarget("//test");
adonovand07bf132021-01-08 09:10:22 -0800100 assertContainsEvent("transition function returned string, want dict or list of dicts");
Googler35f81b42023-07-11 08:49:47 -0700101
102 // Verifies that the AnalysisRootCauseEvent has a no associated configuration. In this case,
103 // the error occurs during a transition, so no configuration has been determined.
104 AnalysisRootCauseEvent rootCause = getOnlyElement(collector.rootCauses);
105 assertThat(rootCause.getConfigurations()).isEmpty();
juliexxiaeee87e92019-04-30 13:21:42 -0700106 }
107
108 @Test
juliexxiadeb028e2019-01-05 17:19:21 -0800109 public void testOutputOnlyTransition() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700110 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800111 scratch.file(
112 "test/transitions.bzl",
113 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -0700114 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800115 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700116 " outputs = ['//command_line_option:foo'])");
juliexxiadeb028e2019-01-05 17:19:21 -0800117 scratch.file(
118 "test/rules.bzl",
119 "load('//test:transitions.bzl', 'my_transition')",
120 "def _impl(ctx):",
121 " return []",
juliexxia30976d82019-03-12 10:59:26 -0700122 "my_rule = rule(",
123 " implementation = _impl,",
124 " cfg = my_transition,",
125 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700126 " '_allowlist_function_transition': attr.label(",
127 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700128 " ),",
129 " })");
juliexxiadeb028e2019-01-05 17:19:21 -0800130 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
131
twigg4970e0f2021-03-31 15:34:49 -0700132 useConfiguration("--foo=pre-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800133
jhorvitz33f76482021-10-28 10:13:26 -0700134 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
twigg4970e0f2021-03-31 15:34:49 -0700135 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
136 .isEqualTo("post-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800137 }
138
139 @Test
140 public void testInputAndOutputTransition() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700141 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800142 scratch.file(
143 "test/transitions.bzl",
144 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -0700145 " return {'//command_line_option:foo': ",
Googler3d389d42023-05-02 03:41:03 -0700146 " settings['//command_line_option:foo'].replace('pre', 'post')}",
juliexxiadeb028e2019-01-05 17:19:21 -0800147 "my_transition = transition(",
148 " implementation = _impl,",
twigg4970e0f2021-03-31 15:34:49 -0700149 " inputs = ['//command_line_option:foo'],",
150 " outputs = ['//command_line_option:foo'],",
juliexxiadeb028e2019-01-05 17:19:21 -0800151 ")");
152
153 scratch.file(
154 "test/rules.bzl",
155 "load('//test:transitions.bzl', 'my_transition')",
156 "def _impl(ctx):",
157 " return []",
juliexxia30976d82019-03-12 10:59:26 -0700158 "my_rule = rule(",
159 " implementation = _impl,",
160 " cfg = my_transition,",
161 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700162 " '_allowlist_function_transition': attr.label(",
163 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700164 " ),",
165 " })");
juliexxiadeb028e2019-01-05 17:19:21 -0800166
167 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
168
twigg4970e0f2021-03-31 15:34:49 -0700169 useConfiguration("--foo=pre-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800170
jhorvitz33f76482021-10-28 10:13:26 -0700171 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
twigg4970e0f2021-03-31 15:34:49 -0700172 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
Googler3d389d42023-05-02 03:41:03 -0700173 .isEqualTo("post-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800174 }
175
176 @Test
177 public void testBuildSettingCannotTransition() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700178 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800179 scratch.file(
180 "test/transitions.bzl",
181 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -0700182 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800183 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700184 " outputs = ['//command_line_option:foo'])");
juliexxiadeb028e2019-01-05 17:19:21 -0800185 scratch.file(
186 "test/rules.bzl",
187 "load('//test:transitions.bzl', 'my_transition')",
188 "def _impl(ctx):",
189 " return []",
190 "my_rule = rule(",
191 " implementation = _impl,",
192 " cfg = my_transition,",
juliexxia30976d82019-03-12 10:59:26 -0700193 " build_setting = config.string(),",
194 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700195 " '_allowlist_function_transition': attr.label(",
196 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700197 " ),",
198 " })");
juliexxiadeb028e2019-01-05 17:19:21 -0800199 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
200
201 reporter.removeHandler(failFastHandler);
202 getConfiguredTarget("//test");
203 assertContainsEvent(
204 "Build setting rules cannot use the `cfg` param to apply transitions to themselves");
205 }
206
207 @Test
208 public void testBadCfgInput() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700209 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800210 scratch.file(
211 "test/rules.bzl",
212 "def _impl(ctx):",
213 " return []",
214 "my_rule = rule(",
215 " implementation = _impl,",
216 " cfg = 'my_transition',",
juliexxia30976d82019-03-12 10:59:26 -0700217 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700218 " '_allowlist_function_transition': attr.label(",
219 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700220 " ),",
221 " })");
juliexxiadeb028e2019-01-05 17:19:21 -0800222 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
223
224 reporter.removeHandler(failFastHandler);
225 getConfiguredTarget("//test");
226 assertContainsEvent(
227 "`cfg` must be set to a transition object initialized by the transition() function.");
228 }
229
230 @Test
231 public void testMultipleReturnConfigs() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700232 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800233 scratch.file(
234 "test/transitions.bzl",
235 "def _impl(settings, attr):",
juliexxiaeee87e92019-04-30 13:21:42 -0700236 " return [",
twigg4970e0f2021-03-31 15:34:49 -0700237 " {'//command_line_option:foo': 'split_one'},",
238 " {'//command_line_option:foo': 'split_two'},",
juliexxiaeee87e92019-04-30 13:21:42 -0700239 " ]",
juliexxiadeb028e2019-01-05 17:19:21 -0800240 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700241 " outputs = ['//command_line_option:foo'])");
juliexxiadeb028e2019-01-05 17:19:21 -0800242 scratch.file(
243 "test/rules.bzl",
244 "load('//test:transitions.bzl', 'my_transition')",
245 "def _impl(ctx):",
246 " return []",
juliexxia30976d82019-03-12 10:59:26 -0700247 "my_rule = rule(",
248 " implementation = _impl,",
249 " cfg = my_transition,",
250 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700251 " '_allowlist_function_transition': attr.label(",
252 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700253 " ),",
254 " })");
juliexxiadeb028e2019-01-05 17:19:21 -0800255 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
256
juliexxia03ff8782019-03-20 13:03:27 -0700257 reporter.removeHandler(failFastHandler);
juliexxiafb45b602019-04-01 12:10:30 -0700258 getConfiguredTarget("//test");
juliexxia03ff8782019-03-20 13:03:27 -0700259 assertContainsEvent(
260 "Rule transition only allowed to return a single transitioned configuration.");
juliexxiadeb028e2019-01-05 17:19:21 -0800261 }
juliexxiadeb028e2019-01-05 17:19:21 -0800262 @Test
263 public void testCanDoBadStuffWithParameterizedTransitionsAndSelects() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700264 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800265 scratch.file(
266 "test/transitions.bzl",
267 "def _impl(settings, attr):",
268 " if (attr.my_configurable_attr):",
twigg4970e0f2021-03-31 15:34:49 -0700269 " return {'//command_line_option:foo': 'true'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800270 " else:",
twigg4970e0f2021-03-31 15:34:49 -0700271 " return {'//command_line_option:foo': 'false'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800272 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700273 " outputs = ['//command_line_option:foo'])");
juliexxiadeb028e2019-01-05 17:19:21 -0800274 scratch.file(
275 "test/rules.bzl",
276 "load('//test:transitions.bzl', 'my_transition')",
277 "def _impl(ctx):",
278 " return []",
279 "my_rule = rule(",
280 " implementation = _impl,",
281 " cfg = my_transition,",
juliexxia30976d82019-03-12 10:59:26 -0700282 " attrs = {",
283 " 'my_configurable_attr': attr.bool(default = False),",
cushon1812caf2020-06-24 10:54:19 -0700284 " '_allowlist_function_transition': attr.label(",
285 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700286 " ),",
287 " },",
juliexxiadeb028e2019-01-05 17:19:21 -0800288 ")");
289 scratch.file(
290 "test/BUILD",
291 "load('//test:rules.bzl', 'my_rule')",
292 "my_rule(",
293 " name = 'test',",
294 " my_configurable_attr = select({",
295 " '//conditions:default': False,",
296 " ':true-config': True,",
297 " })",
298 ")",
299 "config_setting(",
300 " name = 'true-config',",
twigg4970e0f2021-03-31 15:34:49 -0700301 " values = {'foo': 'true'},",
juliexxiadeb028e2019-01-05 17:19:21 -0800302 ")");
303
juliexxia03ff8782019-03-20 13:03:27 -0700304 reporter.removeHandler(failFastHandler);
juliexxiafb45b602019-04-01 12:10:30 -0700305 getConfiguredTarget("//test");
juliexxia03ff8782019-03-20 13:03:27 -0700306 assertContainsEvent(
307 "No attribute 'my_configurable_attr'. "
Googlerceddfb12023-08-18 15:25:03 -0700308 + "Either this attribute does not exist for this rule or the attribute "
309 + "was not resolved because it is set by a select that reads flags the transition "
310 + "may set.");
juliexxiadeb028e2019-01-05 17:19:21 -0800311 }
312
313 @Test
314 public void testLabelTypedAttrReturnsLabelNotDep() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700315 writeAllowlistFile();
juliexxiadeb028e2019-01-05 17:19:21 -0800316 scratch.file(
317 "test/transitions.bzl",
318 "def _impl(settings, attr):",
319 " if attr.dict_attr[Label('//test:key')] == 'value':",
twigg4970e0f2021-03-31 15:34:49 -0700320 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800321 " else:",
twigg4970e0f2021-03-31 15:34:49 -0700322 " return {'//command_line_option:foo': 'uh-oh'}",
juliexxiadeb028e2019-01-05 17:19:21 -0800323 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700324 " outputs = ['//command_line_option:foo'])");
juliexxiadeb028e2019-01-05 17:19:21 -0800325 scratch.file(
326 "test/rules.bzl",
327 "load('//test:transitions.bzl', 'my_transition')",
328 "def _impl(ctx):",
329 " return []",
330 "my_rule = rule(",
331 " implementation = _impl,",
332 " cfg = my_transition,",
juliexxia30976d82019-03-12 10:59:26 -0700333 " attrs = {",
334 " 'dict_attr': attr.label_keyed_string_dict(),",
cushon1812caf2020-06-24 10:54:19 -0700335 " '_allowlist_function_transition': attr.label(",
336 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700337 " ),",
338 " },",
juliexxiadeb028e2019-01-05 17:19:21 -0800339 ")",
340 "simple_rule = rule(_impl)");
341 scratch.file(
342 "test/BUILD",
343 "load('//test:rules.bzl', 'my_rule', 'simple_rule')",
344 "my_rule(",
345 " name = 'test',",
346 " dict_attr = {':key': 'value'},",
347 ")",
348 "simple_rule(name = 'key')");
349
twigg4970e0f2021-03-31 15:34:49 -0700350 useConfiguration("--foo=pre-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800351
jhorvitz33f76482021-10-28 10:13:26 -0700352 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
twigg4970e0f2021-03-31 15:34:49 -0700353 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
354 .isEqualTo("post-transition");
juliexxiadeb028e2019-01-05 17:19:21 -0800355 }
356
juliexxiadb566782019-04-12 10:48:07 -0700357 private static final String CUTE_ANIMAL_DEFAULT =
358 "cows produce more milk when they listen to soothing music";
359
juliexxia30976d82019-03-12 10:59:26 -0700360 private void writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700361 writeAllowlistFile();
juliexxia30976d82019-03-12 10:59:26 -0700362 scratch.file(
363 "test/rules.bzl",
364 "load('//test:transitions.bzl', 'my_transition')",
365 "def _rule_impl(ctx):",
366 " return []",
367 "my_rule = rule(",
368 " implementation = _rule_impl,",
369 " cfg = my_transition,",
370 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700371 " '_allowlist_function_transition': attr.label(",
372 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700373 " ),",
374 " },",
375 ")");
376
377 scratch.file(
378 "test/build_settings.bzl",
379 "def _impl(ctx):",
380 " return []",
381 "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True))");
382
383 scratch.file(
384 "test/BUILD",
385 "load('//test:rules.bzl', 'my_rule')",
386 "load('//test:build_settings.bzl', 'string_flag')",
387 "my_rule(name = 'test')",
388 "string_flag(",
389 " name = 'cute-animal-fact',",
juliexxiadb566782019-04-12 10:48:07 -0700390 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
juliexxia30976d82019-03-12 10:59:26 -0700391 ")");
392 }
393
juliexxiadeb028e2019-01-05 17:19:21 -0800394 @Test
juliexxia03ff8782019-03-20 13:03:27 -0700395 public void testTransitionOnBuildSetting_fromDefault() throws Exception {
juliexxia03ff8782019-03-20 13:03:27 -0700396 scratch.file(
397 "test/transitions.bzl",
398 "def _transition_impl(settings, attr):",
399 " return {'//test:cute-animal-fact': 'puffins mate for life'}",
400 "my_transition = transition(",
401 " implementation = _transition_impl,",
402 " inputs = [],",
403 " outputs = ['//test:cute-animal-fact']",
404 ")");
405 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
406
jhorvitz33f76482021-10-28 10:13:26 -0700407 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxia03ff8782019-03-20 13:03:27 -0700408 assertThat(
409 configuration
410 .getOptions()
411 .getStarlarkOptions()
Googler08463dc2023-01-20 08:02:19 -0800412 .get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxia03ff8782019-03-20 13:03:27 -0700413 .isEqualTo("puffins mate for life");
414 }
415
416 @Test
417 public void testTransitionOnBuildSetting_fromCommandLine() throws Exception {
juliexxia22de6cd2019-01-09 07:25:23 -0800418 scratch.file(
419 "test/transitions.bzl",
420 "def _transition_impl(settings, attr):",
421 " return {'//test:cute-animal-fact': 'puffins mate for life'}",
422 "my_transition = transition(",
423 " implementation = _transition_impl,",
424 " inputs = [],",
425 " outputs = ['//test:cute-animal-fact']",
426 ")");
427 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
428
429 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "cats can't taste sugar"));
juliexxia03ff8782019-03-20 13:03:27 -0700430
jhorvitz33f76482021-10-28 10:13:26 -0700431 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxia22de6cd2019-01-09 07:25:23 -0800432 assertThat(
433 configuration
434 .getOptions()
435 .getStarlarkOptions()
Googler08463dc2023-01-20 08:02:19 -0800436 .get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxia22de6cd2019-01-09 07:25:23 -0800437 .isEqualTo("puffins mate for life");
438 }
439
juliexxia22de6cd2019-01-09 07:25:23 -0800440 @Test
juliexxia03ff8782019-03-20 13:03:27 -0700441 public void testTransitionOnBuildSetting_badValue() throws Exception {
juliexxia22de6cd2019-01-09 07:25:23 -0800442 scratch.file(
443 "test/transitions.bzl",
444 "def _transition_impl(settings, attr):",
445 " return {'//test:cute-animal-fact': 24}",
446 "my_transition = transition(",
447 " implementation = _transition_impl,",
448 " inputs = [],",
449 " outputs = ['//test:cute-animal-fact']",
450 ")");
451 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
452
453 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "cats can't taste sugar"));
juliexxia03ff8782019-03-20 13:03:27 -0700454
juliexxiafb45b602019-04-01 12:10:30 -0700455 reporter.removeHandler(failFastHandler);
juliexxiab75e45302019-05-24 07:48:39 -0700456 getConfiguredTarget("//test");
juliexxiafb45b602019-04-01 12:10:30 -0700457 assertContainsEvent(
458 "expected value of type 'string' for " + "//test:cute-animal-fact, but got 24 (int)");
juliexxia22de6cd2019-01-09 07:25:23 -0800459 }
460
juliexxia22de6cd2019-01-09 07:25:23 -0800461 @Test
juliexxia03ff8782019-03-20 13:03:27 -0700462 public void testTransitionOnBuildSetting_noSuchTarget() throws Exception {
juliexxia22de6cd2019-01-09 07:25:23 -0800463 scratch.file(
464 "test/transitions.bzl",
465 "def _transition_impl(settings, attr):",
466 " return {'//test:i-am-not-real': 'imaginary-friend'}",
467 "my_transition = transition(",
468 " implementation = _transition_impl,",
469 " inputs = [],",
470 " outputs = ['//test:i-am-not-real']",
471 ")");
472 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
473
juliexxiafb45b602019-04-01 12:10:30 -0700474 reporter.removeHandler(failFastHandler);
juliexxiab75e45302019-05-24 07:48:39 -0700475 getConfiguredTarget("//test");
juliexxiafb45b602019-04-01 12:10:30 -0700476 assertContainsEvent(
477 "no such target '//test:i-am-not-real': target "
478 + "'i-am-not-real' not declared in package 'test'");
juliexxia03ff8782019-03-20 13:03:27 -0700479 }
480
481 @Test
juliexxiab75e45302019-05-24 07:48:39 -0700482 public void testTransitionOnBuildSetting_noSuchPackage() throws Exception {
juliexxiab75e45302019-05-24 07:48:39 -0700483 scratch.file(
484 "test/transitions.bzl",
485 "def _transition_impl(settings, attr):",
486 " return {'//i-am-not-real': 'imaginary-friend'}",
487 "my_transition = transition(",
488 " implementation = _transition_impl,",
489 " inputs = [],",
490 " outputs = ['//i-am-not-real']",
491 ")");
492 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
493
494 reporter.removeHandler(failFastHandler);
495 getConfiguredTarget("//test");
Googler2f7d9652022-07-22 18:05:47 -0700496 assertContainsEvent(
497 "no such package 'i-am-not-real': BUILD file not found in any of the following"
498 + " directories");
juliexxiab75e45302019-05-24 07:48:39 -0700499 }
500
501 @Test
juliexxia03ff8782019-03-20 13:03:27 -0700502 public void testTransitionOnBuildSetting_notABuildSetting() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700503 writeAllowlistFile();
juliexxia03ff8782019-03-20 13:03:27 -0700504 scratch.file(
505 "test/transitions.bzl",
506 "def _transition_impl(settings, attr):",
507 " return {'//test:cute-animal-fact': 'puffins mate for life'}",
508 "my_transition = transition(",
509 " implementation = _transition_impl,",
510 " inputs = [],",
511 " outputs = ['//test:cute-animal-fact']",
512 ")");
513 scratch.file(
514 "test/rules.bzl",
515 "load('//test:transitions.bzl', 'my_transition')",
516 "def _rule_impl(ctx):",
517 " return []",
518 "my_rule = rule(",
519 " implementation = _rule_impl,",
520 " cfg = my_transition,",
521 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700522 " '_allowlist_function_transition': attr.label(",
523 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia03ff8782019-03-20 13:03:27 -0700524 " ),",
525 " },",
526 ")");
527 scratch.file(
528 "test/build_settings.bzl",
529 "def _impl(ctx):",
530 " return []",
531 "non_build_setting = rule(implementation = _impl)");
532 scratch.file(
533 "test/BUILD",
534 "load('//test:rules.bzl', 'my_rule')",
535 "load('//test:build_settings.bzl', 'non_build_setting')",
536 "my_rule(name = 'test')",
537 "non_build_setting(name = 'cute-animal-fact')");
538
juliexxiafb45b602019-04-01 12:10:30 -0700539 reporter.removeHandler(failFastHandler);
540 getConfiguredTarget("//test");
541 assertContainsEvent(
542 "attempting to transition on '//test:cute-animal-fact' which is not a build setting");
juliexxia22de6cd2019-01-09 07:25:23 -0800543 }
544
juliexxia22de6cd2019-01-09 07:25:23 -0800545 @Test
juliexxiadb566782019-04-12 10:48:07 -0700546 public void testTransitionOnBuildSetting_dontStoreDefault() throws Exception {
juliexxiadb566782019-04-12 10:48:07 -0700547 scratch.file(
548 "test/transitions.bzl",
549 "def _transition_impl(settings, attr):",
550 " return {'//test:cute-animal-fact': '" + CUTE_ANIMAL_DEFAULT + "'}",
551 "my_transition = transition(",
552 " implementation = _transition_impl,",
553 " inputs = [],",
554 " outputs = ['//test:cute-animal-fact']",
555 ")");
556 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
557
558 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "cats can't taste sugar"));
559
jhorvitz33f76482021-10-28 10:13:26 -0700560 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxiadb566782019-04-12 10:48:07 -0700561 assertThat(configuration.getOptions().getStarlarkOptions())
Googler08463dc2023-01-20 08:02:19 -0800562 .doesNotContainKey(Label.parseCanonicalUnchecked("//test:cute-animal-fact"));
juliexxiadb566782019-04-12 10:48:07 -0700563 }
564
565 @Test
Googler1d4cecf2022-07-27 00:04:12 -0700566 public void testTransitionOnBuildSetting_readingUnreadableBuildSetting() throws Exception {
567 scratch.file(
568 "test/transitions.bzl",
569 "def _transition_impl(settings, attr):",
570 " old_value = settings['//command_line_option:unreadable_by_starlark']",
571 " fail('This line should be unreachable.')",
572 "my_transition = transition(implementation = _transition_impl,",
573 " inputs = ['//command_line_option:unreadable_by_starlark'],",
574 " outputs = ['//command_line_option:unreadable_by_starlark'],",
575 ")");
576 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
577
578 reporter.removeHandler(failFastHandler);
579 getConfiguredTarget("//test");
580 assertContainsEvent(
581 Pattern.compile(
582 "test/transitions.bzl:1:5: before calling _transition_impl: Input build setting"
583 + " //command_line_option:unreadable_by_starlark is of type class"
584 + " \\S*UnreadableStringBox, which is unreadable in Starlark. Please submit a"
585 + " feature request."));
586 }
587
588 @Test
589 public void testTransitionOnBuildSetting_writingUnreadableBuildSetting() throws Exception {
590 scratch.file(
591 "test/transitions.bzl",
592 "def _transition_impl(settings, attr):",
593 " return {",
594 " '//command_line_option:unreadable_by_starlark': 'post-transition',",
595 " }",
596 "my_transition = transition(implementation = _transition_impl,",
597 " inputs = [],",
598 " outputs = ['//command_line_option:unreadable_by_starlark'],",
599 ")");
600 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
601
602 useConfiguration("--unreadable_by_starlark=pre-transition");
603
604 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
605 assertThat(configuration.getOptions().get(DummyTestOptions.class).unreadableByStarlark)
606 .isEqualTo(DummyTestOptions.UnreadableStringBox.create("post-transition"));
607 }
608
609 @Test
juliexxia1a70c272019-04-09 09:33:23 -0700610 public void testTransitionReadsBuildSetting_fromDefault() throws Exception {
juliexxia22de6cd2019-01-09 07:25:23 -0800611 scratch.file(
612 "test/transitions.bzl",
613 "def _transition_impl(settings, attr):",
Googler3d389d42023-05-02 03:41:03 -0700614 " new_value = settings['//test:cute-animal-fact'].replace('cows', 'platypuses')",
615 " return {'//test:cute-animal-fact': new_value}",
juliexxia22de6cd2019-01-09 07:25:23 -0800616 "my_transition = transition(",
617 " implementation = _transition_impl,",
618 " inputs = ['//test:cute-animal-fact'],",
juliexxia1a70c272019-04-09 09:33:23 -0700619 " outputs = ['//test:cute-animal-fact']",
620 ")");
621 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
622
jhorvitz33f76482021-10-28 10:13:26 -0700623 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxia1a70c272019-04-09 09:33:23 -0700624 assertThat(
625 configuration
626 .getOptions()
627 .getStarlarkOptions()
Googler08463dc2023-01-20 08:02:19 -0800628 .get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
Googler3d389d42023-05-02 03:41:03 -0700629 .isEqualTo("platypuses produce more milk when they listen to soothing music");
juliexxia1a70c272019-04-09 09:33:23 -0700630 }
631
632 @Test
633 public void testTransitionReadsBuildSetting_fromCommandLine() throws Exception {
juliexxia1a70c272019-04-09 09:33:23 -0700634 scratch.file(
635 "test/transitions.bzl",
636 "def _transition_impl(settings, attr):",
Googler3d389d42023-05-02 03:41:03 -0700637 " now_true = settings['//test:cute-animal-fact'].replace('FALSE', 'TRUE')",
638 " return {'//test:cute-animal-fact': now_true}",
juliexxia1a70c272019-04-09 09:33:23 -0700639 "my_transition = transition(",
640 " implementation = _transition_impl,",
641 " inputs = ['//test:cute-animal-fact'],",
642 " outputs = ['//test:cute-animal-fact']",
643 ")");
644 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
645
Googler3d389d42023-05-02 03:41:03 -0700646 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "rats are ticklish <- FALSE"));
juliexxia1a70c272019-04-09 09:33:23 -0700647
jhorvitz33f76482021-10-28 10:13:26 -0700648 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxia1a70c272019-04-09 09:33:23 -0700649 assertThat(
650 configuration
651 .getOptions()
652 .getStarlarkOptions()
Googler08463dc2023-01-20 08:02:19 -0800653 .get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxia1a70c272019-04-09 09:33:23 -0700654 .isEqualTo("rats are ticklish <- TRUE");
655 }
656
657 @Test
658 public void testTransitionReadsBuildSetting_notABuildSetting() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700659 writeAllowlistFile();
juliexxia1a70c272019-04-09 09:33:23 -0700660 scratch.file(
661 "test/transitions.bzl",
662 "def _transition_impl(settings, attr):",
663 " return {'//test:cute-animal-fact': 'puffins mate for life'}",
664 "my_transition = transition(",
665 " implementation = _transition_impl,",
666 " inputs = ['//test:cute-animal-fact'],",
667 " outputs = ['//test:cute-animal-fact']",
668 ")");
669 scratch.file(
670 "test/rules.bzl",
671 "load('//test:transitions.bzl', 'my_transition')",
672 "def _rule_impl(ctx):",
673 " return []",
674 "my_rule = rule(",
675 " implementation = _rule_impl,",
676 " cfg = my_transition,",
677 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700678 " '_allowlist_function_transition': attr.label(",
679 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia1a70c272019-04-09 09:33:23 -0700680 " ),",
681 " },",
682 ")");
683 scratch.file(
684 "test/build_settings.bzl",
685 "def _impl(ctx):",
686 " return []",
687 "non_build_setting = rule(implementation = _impl)");
688 scratch.file(
689 "test/BUILD",
690 "load('//test:rules.bzl', 'my_rule')",
691 "load('//test:build_settings.bzl', 'non_build_setting')",
692 "my_rule(name = 'test')",
693 "non_build_setting(name = 'cute-animal-fact')");
694
695 reporter.removeHandler(failFastHandler);
696 getConfiguredTarget("//test");
697 assertContainsEvent(
698 "attempting to transition on '//test:cute-animal-fact' which is not a build setting");
699 }
700
701 @Test
702 public void testTransitionReadsBuildSetting_noSuchTarget() throws Exception {
juliexxia1a70c272019-04-09 09:33:23 -0700703 scratch.file(
704 "test/transitions.bzl",
705 "def _transition_impl(settings, attr):",
706 " return {'//test:cute-animal-fact': settings['//test:cute-animal-fact']+' <- TRUE'}",
707 "my_transition = transition(",
708 " implementation = _transition_impl,",
709 " inputs = ['//test:i-am-not-real'],",
710 " outputs = ['//test:cute-animal-fact']",
juliexxia22de6cd2019-01-09 07:25:23 -0800711 ")");
712 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
713
juliexxia03ff8782019-03-20 13:03:27 -0700714 reporter.removeHandler(failFastHandler);
juliexxiafb45b602019-04-01 12:10:30 -0700715 getConfiguredTarget("//test");
juliexxia03ff8782019-03-20 13:03:27 -0700716 assertContainsEvent(
juliexxia1a70c272019-04-09 09:33:23 -0700717 "no such target '//test:i-am-not-real': target "
718 + "'i-am-not-real' not declared in package 'test'");
juliexxia922312f2019-03-12 08:44:33 -0700719 }
juliexxia1a568242019-02-15 09:16:46 -0800720
721 @Test
juliexxiab63a4a92019-06-14 12:05:18 -0700722 public void testAliasedBuildSetting() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700723 scratch.file(
724 "test/transitions.bzl",
725 "def _transition_impl(settings, attr):",
726 " return {'//test:fact': 'puffins mate for life'}",
727 "my_transition = transition(",
728 " implementation = _transition_impl,",
729 " inputs = [],",
730 " outputs = ['//test:fact']",
731 ")");
732 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
733 scratch.overwriteFile(
734 "test/BUILD",
735 "load('//test:rules.bzl', 'my_rule')",
736 "load('//test:build_settings.bzl', 'string_flag')",
737 "my_rule(name = 'test')",
738 "alias(name = 'fact', actual = ':cute-animal-fact')",
739 "string_flag(",
740 " name = 'cute-animal-fact',",
741 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
742 ")");
743
744 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "rats are ticklish"));
745
746 ImmutableMap<Label, Object> starlarkOptions =
747 getConfiguration(getConfiguredTarget("//test")).getOptions().getStarlarkOptions();
Googler08463dc2023-01-20 08:02:19 -0800748 assertThat(starlarkOptions.get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxiab63a4a92019-06-14 12:05:18 -0700749 .isEqualTo("puffins mate for life");
Googler08463dc2023-01-20 08:02:19 -0800750 assertThat(starlarkOptions).doesNotContainKey(Label.parseCanonicalUnchecked("//test:fact"));
juliexxiab63a4a92019-06-14 12:05:18 -0700751 assertThat(starlarkOptions.keySet())
Googler08463dc2023-01-20 08:02:19 -0800752 .containsExactly(Label.parseCanonicalUnchecked("//test:cute-animal-fact"));
juliexxiab63a4a92019-06-14 12:05:18 -0700753 }
754
755 @Test
756 public void testAliasedBuildSetting_chainedAliases() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700757 scratch.file(
758 "test/transitions.bzl",
759 "def _transition_impl(settings, attr):",
760 " return {'//test:fact': 'puffins mate for life'}",
761 "my_transition = transition(",
762 " implementation = _transition_impl,",
763 " inputs = [],",
764 " outputs = ['//test:fact']",
765 ")");
766 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
767 scratch.overwriteFile(
768 "test/BUILD",
769 "load('//test:rules.bzl', 'my_rule')",
770 "load('//test:build_settings.bzl', 'string_flag')",
771 "my_rule(name = 'test')",
772 "alias(name = 'fact', actual = ':alias2')",
773 "alias(name = 'alias2', actual = ':cute-animal-fact')",
774 "string_flag(",
775 " name = 'cute-animal-fact',",
776 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
777 ")");
778
779 useConfiguration(ImmutableMap.of("//test:cute-animal-fact", "rats are ticklish"));
780
jhorvitz33f76482021-10-28 10:13:26 -0700781 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
juliexxiab63a4a92019-06-14 12:05:18 -0700782 assertThat(
783 configuration
784 .getOptions()
785 .getStarlarkOptions()
Googler08463dc2023-01-20 08:02:19 -0800786 .get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxiab63a4a92019-06-14 12:05:18 -0700787 .isEqualTo("puffins mate for life");
788 }
789
790 @Test
791 public void testAliasedBuildSetting_configuredActualValue() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700792 scratch.file(
793 "test/transitions.bzl",
794 "def _transition_impl(settings, attr):",
795 " return {'//test:fact': 'puffins mate for life'}",
796 "my_transition = transition(",
797 " implementation = _transition_impl,",
798 " inputs = [],",
799 " outputs = ['//test:fact']",
800 ")");
801 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
802 scratch.overwriteFile(
803 "test/BUILD",
804 "load('//test:rules.bzl', 'my_rule')",
805 "load('//test:build_settings.bzl', 'string_flag')",
806 "my_rule(name = 'test')",
807 "alias(",
808 " name = 'fact',",
809 " actual = select({",
810 " '//conditions:default': ':cute-animal-fact',",
811 " ':true-config': 'other-cute-animal-fact',",
812 " })",
813 ")",
814 "config_setting(",
815 " name = 'true-config',",
twigg4970e0f2021-03-31 15:34:49 -0700816 " values = {'foo': 'true'},",
juliexxiab63a4a92019-06-14 12:05:18 -0700817 ")",
818 "string_flag(",
819 " name = 'cute-animal-fact',",
820 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
821 ")",
822 "string_flag(",
823 " name = 'other-cute-animal-fact',",
824 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
825 ")");
826
827 reporter.removeHandler(failFastHandler);
828 getConfiguredTarget("//test");
829 assertContainsEvent(
830 "attempting to transition on aliased build setting '//test:fact', the actual value of"
831 + " which uses select().");
832 }
833
834 @Test
835 public void testAliasedBuildSetting_cyclicalAliases() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700836 scratch.file(
837 "test/transitions.bzl",
838 "def _transition_impl(settings, attr):",
839 " return {'//test:alias1': 'puffins mate for life'}",
840 "my_transition = transition(",
841 " implementation = _transition_impl,",
842 " inputs = [],",
843 " outputs = ['//test:alias1']",
844 ")");
845 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
846 scratch.overwriteFile(
847 "test/BUILD",
848 "load('//test:rules.bzl', 'my_rule')",
849 "load('//test:build_settings.bzl', 'string_flag')",
850 "my_rule(name = 'test')",
851 "alias(name = 'alias1', actual = ':alias2')",
852 "alias(name = 'alias2', actual = ':alias1')");
853
854 reporter.removeHandler(failFastHandler);
855 getConfiguredTarget("//test");
Googler2f7d9652022-07-22 18:05:47 -0700856 assertContainsEvent(
857 "Dependency cycle involving '//test:alias1' detected in aliased build settings");
juliexxiab63a4a92019-06-14 12:05:18 -0700858 }
859
860 @Test
861 public void testAliasedBuildSetting_setAliasAndActual() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700862 scratch.file(
863 "test/transitions.bzl",
864 "def _transition_impl(settings, attr):",
865 " return {",
866 " '//test:alias': 'puffins mate for life',",
867 " '//test:actual': 'cats cannot taste sugar',",
868 "}",
869 "my_transition = transition(",
870 " implementation = _transition_impl,",
871 " inputs = [],",
872 " outputs = [",
873 " '//test:alias',",
874 " '//test:actual',",
875 " ]",
876 ")");
877 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
878 scratch.overwriteFile(
879 "test/BUILD",
880 "load('//test:rules.bzl', 'my_rule')",
881 "load('//test:build_settings.bzl', 'string_flag')",
882 "my_rule(name = 'test')",
883 "alias(name = 'alias', actual = ':actual')",
884 "string_flag(",
885 " name = 'actual',",
886 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
887 ")");
888
889 reporter.removeHandler(failFastHandler);
890 getConfiguredTarget("//test");
Googler2f7d9652022-07-22 18:05:47 -0700891 assertContainsEvent(
892 "Dependency cycle involving '//test:actual' detected in aliased build settings");
juliexxiab63a4a92019-06-14 12:05:18 -0700893 }
894
895 @Test
896 public void testAliasedBuildSetting_outputReturnMismatch() throws Exception {
juliexxiab63a4a92019-06-14 12:05:18 -0700897 scratch.file(
898 "test/transitions.bzl",
899 "def _transition_impl(settings, attr):",
900 " return {",
901 " '//test:actual': 'cats cannot taste sugar',",
902 "}",
903 "my_transition = transition(",
904 " implementation = _transition_impl,",
905 " inputs = [],",
906 " outputs = [",
907 " '//test:alias',",
908 " ]",
909 ")");
910 writeRulesBuildSettingsAndBUILDforBuildSettingTransitionTests();
911 scratch.overwriteFile(
912 "test/BUILD",
913 "load('//test:rules.bzl', 'my_rule')",
914 "load('//test:build_settings.bzl', 'string_flag')",
915 "my_rule(name = 'test')",
916 "alias(name = 'alias', actual = ':actual')",
917 "string_flag(",
918 " name = 'actual',",
919 " build_setting_default = '" + CUTE_ANIMAL_DEFAULT + "',",
920 ")");
921
922 reporter.removeHandler(failFastHandler);
923 getConfiguredTarget("//test");
924 assertContainsEvent("transition function returned undeclared output '//test:actual'");
925 }
926
927 @Test
juliexxia1a568242019-02-15 09:16:46 -0800928 public void testOneParamTransitionFunctionApiFails() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700929 writeAllowlistFile();
juliexxia1a568242019-02-15 09:16:46 -0800930 scratch.file(
931 "test/transitions.bzl",
932 "def _impl(settings):",
twigg4970e0f2021-03-31 15:34:49 -0700933 " return {'//command_line_option:foo': 'post-transition'}",
juliexxia1a568242019-02-15 09:16:46 -0800934 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -0700935 " outputs = ['//command_line_option:foo'])");
juliexxia1a568242019-02-15 09:16:46 -0800936 scratch.file(
937 "test/rules.bzl",
938 "load('//test:transitions.bzl', 'my_transition')",
939 "def _impl(ctx):",
940 " return []",
juliexxia30976d82019-03-12 10:59:26 -0700941 "my_rule = rule(",
942 " implementation = _impl,",
943 " cfg = my_transition,",
944 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700945 " '_allowlist_function_transition': attr.label(",
946 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700947 " ),",
948 " },",
949 ")");
juliexxia1a568242019-02-15 09:16:46 -0800950 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
951
juliexxia03ff8782019-03-20 13:03:27 -0700952 reporter.removeHandler(failFastHandler);
juliexxiafb45b602019-04-01 12:10:30 -0700953 getConfiguredTarget("//test");
adonovan40446b82020-04-22 06:59:42 -0700954 assertContainsEvent("_impl() accepts no more than 1 positional argument but got 2");
juliexxia1a568242019-02-15 09:16:46 -0800955 }
juliexxiaff93b192019-02-19 08:02:19 -0800956
957 @Test
958 public void testCannotTransitionOnExperimentalFlag() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -0700959 writeAllowlistFile();
juliexxiaff93b192019-02-19 08:02:19 -0800960 scratch.file(
961 "test/transitions.bzl",
962 "def _impl(settings, attr):",
juliexxiad17649a2020-05-26 10:48:04 -0700963 " return {'//command_line_option:experimental_something_something': True}",
juliexxiaff93b192019-02-19 08:02:19 -0800964 "my_transition = transition(implementation = _impl, inputs = [],",
juliexxiad17649a2020-05-26 10:48:04 -0700965 " outputs = ['//command_line_option:experimental_something_something'])");
juliexxiaff93b192019-02-19 08:02:19 -0800966 scratch.file(
967 "test/rules.bzl",
968 "load('//test:transitions.bzl', 'my_transition')",
969 "def _impl(ctx):",
970 " return []",
juliexxia30976d82019-03-12 10:59:26 -0700971 "my_rule = rule(",
972 " implementation = _impl,",
973 " cfg = my_transition,",
974 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -0700975 " '_allowlist_function_transition': attr.label(",
976 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700977 " ),",
978 " },",
979 ")");
juliexxiaff93b192019-02-19 08:02:19 -0800980 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
981
982 reporter.removeHandler(failFastHandler);
983 getConfiguredTarget("//test");
984 assertContainsEvent("Cannot transition on --experimental_* or --incompatible_* options");
985 }
juliexxia30976d82019-03-12 10:59:26 -0700986
987 @Test
aiuto50226ac2020-06-14 21:28:27 -0700988 public void testCannotTransitionWithoutAllowlist() throws Exception {
cmita83563582021-06-15 01:57:45 -0700989 scratch.overwriteFile(
cushon1812caf2020-06-24 10:54:19 -0700990 "tools/allowlists/function_transition_allowlist/BUILD",
juliexxia30976d82019-03-12 10:59:26 -0700991 "package_group(",
cushon1812caf2020-06-24 10:54:19 -0700992 " name = 'function_transition_allowlist',",
juliexxia30976d82019-03-12 10:59:26 -0700993 " packages = [],",
994 ")");
995 scratch.file(
996 "test/transitions.bzl",
997 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -0700998 " return {'//command_line_option:foo': 'post-transition'}",
juliexxia30976d82019-03-12 10:59:26 -0700999 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -07001000 " outputs = ['//command_line_option:foo'])");
juliexxia30976d82019-03-12 10:59:26 -07001001 scratch.file(
1002 "test/rules.bzl",
1003 "load('//test:transitions.bzl', 'my_transition')",
1004 "def _impl(ctx):",
1005 " return []",
1006 "my_rule = rule(",
1007 " implementation = _impl,",
1008 " cfg = my_transition,",
1009 ")");
1010 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1011
twigg4970e0f2021-03-31 15:34:49 -07001012 useConfiguration("--foo=pre-transition");
juliexxia30976d82019-03-12 10:59:26 -07001013
1014 reporter.removeHandler(failFastHandler);
1015 getConfiguredTarget("//test");
aiuto50226ac2020-06-14 21:28:27 -07001016 assertContainsEvent("Use of Starlark transition without allowlist");
juliexxia30976d82019-03-12 10:59:26 -07001017 }
juliexxiac33f0c82019-03-25 16:37:41 -07001018
1019 @Test
1020 public void testNoNullOptionValues() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001021 writeAllowlistFile();
juliexxiac33f0c82019-03-25 16:37:41 -07001022 scratch.file(
1023 "test/transitions.bzl",
1024 "def _impl(settings, attr):",
juliexxia6778a052019-04-09 08:25:05 -07001025 " if settings['//command_line_option:nullable_option'] == None:",
twigg4970e0f2021-03-31 15:34:49 -07001026 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiac33f0c82019-03-25 16:37:41 -07001027 " else:",
twigg4970e0f2021-03-31 15:34:49 -07001028 " return {'//command_line_option:foo': settings['//command_line_option:foo']}",
juliexxiac33f0c82019-03-25 16:37:41 -07001029 "my_transition = transition(implementation = _impl,",
1030 " inputs = [",
twigg4970e0f2021-03-31 15:34:49 -07001031 " '//command_line_option:foo',",
juliexxia6778a052019-04-09 08:25:05 -07001032 " '//command_line_option:nullable_option'",
juliexxiac33f0c82019-03-25 16:37:41 -07001033 " ],",
twigg4970e0f2021-03-31 15:34:49 -07001034 " outputs = ['//command_line_option:foo'])");
juliexxiac33f0c82019-03-25 16:37:41 -07001035 scratch.file(
1036 "test/rules.bzl",
1037 "load('//test:transitions.bzl', 'my_transition')",
1038 "def _impl(ctx):",
1039 " return []",
1040 "my_rule = rule(",
1041 " implementation = _impl,",
1042 " cfg = my_transition,",
1043 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001044 " '_allowlist_function_transition': attr.label(",
1045 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiac33f0c82019-03-25 16:37:41 -07001046 " ),",
1047 " })");
1048 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1049
twigg4970e0f2021-03-31 15:34:49 -07001050 useConfiguration("--nullable_option=", "--foo=pre-transition");
juliexxiac33f0c82019-03-25 16:37:41 -07001051
jhorvitz33f76482021-10-28 10:13:26 -07001052 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
twigg4970e0f2021-03-31 15:34:49 -07001053 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
1054 .isEqualTo("post-transition");
juliexxiac33f0c82019-03-25 16:37:41 -07001055 }
juliexxiad21fa422019-03-28 09:59:26 -07001056
1057 @Test
aiuto50226ac2020-06-14 21:28:27 -07001058 public void testAllowlistOnRuleNotTargets() throws Exception {
1059 // allowlists //test/...
1060 writeAllowlistFile();
juliexxiad21fa422019-03-28 09:59:26 -07001061 scratch.file(
1062 "test/transitions.bzl",
1063 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -07001064 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiad21fa422019-03-28 09:59:26 -07001065 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -07001066 " outputs = ['//command_line_option:foo'])");
juliexxiad21fa422019-03-28 09:59:26 -07001067 scratch.file(
1068 "test/rules.bzl",
1069 "load('//test:transitions.bzl', 'my_transition')",
1070 "def _impl(ctx):",
1071 " return []",
1072 "my_rule = rule(",
1073 " implementation = _impl,",
1074 " cfg = my_transition,",
1075 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001076 " '_allowlist_function_transition': attr.label(",
1077 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiad21fa422019-03-28 09:59:26 -07001078 " ),",
1079 " })");
1080 scratch.file(
1081 "neverland/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1082 scratch.file("test/BUILD");
twigg4970e0f2021-03-31 15:34:49 -07001083 useConfiguration("--foo=pre-transition");
juliexxiad21fa422019-03-28 09:59:26 -07001084
jhorvitz33f76482021-10-28 10:13:26 -07001085 BuildConfigurationValue configuration =
1086 getConfiguration(getConfiguredTarget("//neverland:test"));
twigg4970e0f2021-03-31 15:34:49 -07001087 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
1088 .isEqualTo("post-transition");
juliexxiad21fa422019-03-28 09:59:26 -07001089 }
1090
Googlerfe8275d2021-02-05 16:36:38 -08001091 // TODO(blaze-configurability): We probably want to eventually turn this off. Flip this test when
1092 // this isn't allowed anymore.
juliexxiad21fa422019-03-28 09:59:26 -07001093 @Test
aiuto50226ac2020-06-14 21:28:27 -07001094 public void testAllowlistOnTargetsStillWorks() throws Exception {
1095 // allowlists //test/...
1096 writeAllowlistFile();
juliexxiad21fa422019-03-28 09:59:26 -07001097 scratch.file(
1098 "neverland/transitions.bzl",
1099 "def _impl(settings, attr):",
twigg4970e0f2021-03-31 15:34:49 -07001100 " return {'//command_line_option:foo': 'post-transition'}",
juliexxiad21fa422019-03-28 09:59:26 -07001101 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -07001102 " outputs = ['//command_line_option:foo'])");
juliexxiad21fa422019-03-28 09:59:26 -07001103 scratch.file(
1104 "neverland/rules.bzl",
1105 "load('//neverland:transitions.bzl', 'my_transition')",
1106 "def _impl(ctx):",
1107 " return []",
1108 "my_rule = rule(",
1109 " implementation = _impl,",
1110 " cfg = my_transition,",
1111 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001112 " '_allowlist_function_transition': attr.label(",
1113 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiad21fa422019-03-28 09:59:26 -07001114 " ),",
1115 " })");
1116 scratch.file(
1117 "test/BUILD", "load('//neverland:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1118 scratch.file("neverland/BUILD");
twigg4970e0f2021-03-31 15:34:49 -07001119 useConfiguration("--foo=pre-transition");
juliexxiad21fa422019-03-28 09:59:26 -07001120
jhorvitz33f76482021-10-28 10:13:26 -07001121 BuildConfigurationValue configuration = getConfiguration(getConfiguredTarget("//test"));
twigg4970e0f2021-03-31 15:34:49 -07001122 assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
1123 .isEqualTo("post-transition");
juliexxiad21fa422019-03-28 09:59:26 -07001124 }
juliexxiabdc6c102019-05-20 11:58:02 -07001125
juliexxiabdc6c102019-05-20 11:58:02 -07001126 @Test
gregce11f25402021-07-08 07:14:10 -07001127 @TestParameters({
1128 "{"
1129 + "returnLine: 'return []',"
1130 + "returnLine: 'return {}',"
1131 + "returnLine: 'return None',"
1132 + "returnLine: 'pass',"
1133 + "}"
1134 })
1135 public void noopReturnValues(String returnLine) throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001136 writeAllowlistFile();
juliexxiabdc6c102019-05-20 11:58:02 -07001137 scratch.file(
1138 "test/transitions.bzl",
1139 "def _impl(settings, attr):",
gregce11f25402021-07-08 07:14:10 -07001140 " " + returnLine,
juliexxiabdc6c102019-05-20 11:58:02 -07001141 "my_transition = transition(implementation = _impl, inputs = [],",
twigg4970e0f2021-03-31 15:34:49 -07001142 " outputs = ['//command_line_option:foo'])");
juliexxiabdc6c102019-05-20 11:58:02 -07001143 scratch.file(
1144 "test/rules.bzl",
1145 "load('//test:transitions.bzl', 'my_transition')",
1146 "def _impl(ctx):",
1147 " return []",
1148 "my_rule = rule(",
1149 " implementation = _impl,",
1150 " cfg = my_transition,",
1151 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001152 " '_allowlist_function_transition': attr.label(",
1153 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiabdc6c102019-05-20 11:58:02 -07001154 " ),",
1155 " })");
1156 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
gregce11f25402021-07-08 07:14:10 -07001157 // --trim_test_configuration means only the top-level configuration has TestOptions.
1158 assertConfigurationsEqual(
1159 getConfiguration(getConfiguredTarget("//test")),
1160 targetConfig,
1161 ImmutableSet.of(TestOptions.class));
juliexxiabdc6c102019-05-20 11:58:02 -07001162 }
gregcef0a40ac2020-03-31 14:11:30 -07001163
1164 @Test
1165 public void composingTransitionReportsAllStarlarkErrors() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001166 writeAllowlistFile();
gregcef0a40ac2020-03-31 14:11:30 -07001167 scratch.file(
1168 "test/build_settings.bzl",
1169 "def _impl(ctx):",
1170 " return []",
1171 "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True))");
1172 scratch.file(
1173 "test/transitions.bzl",
gregce11f25402021-07-08 07:14:10 -07001174 "def _attr_impl(settings, attr):",
1175 " return {'//test:attr_transition_output_flag1': 'not default'}",
1176 "attr_transition = transition(implementation = _attr_impl, inputs = [],",
1177 " outputs = [",
1178 " '//test:attr_transition_output_flag1',",
1179 " '//test:attr_transition_output_flag2',",
1180 " ])",
1181 "def _self_impl(settings, attr):",
1182 " return {'//test:self_transition_output_flag1': 'not default'}",
1183 "self_transition = transition(implementation = _self_impl, inputs = [],",
1184 " outputs = [",
1185 " '//test:self_transition_output_flag1',",
1186 " '//test:self_transition_output_flag2',",
1187 " ])");
gregcef0a40ac2020-03-31 14:11:30 -07001188 scratch.file(
1189 "test/rules.bzl",
1190 "load('//test:transitions.bzl', 'attr_transition', 'self_transition')",
1191 "def _impl(ctx):",
1192 " return []",
1193 "rule_with_attr_transition = rule(",
1194 " implementation = _impl,",
1195 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001196 " '_allowlist_function_transition': attr.label(",
1197 " default = '//tools/allowlists/function_transition_allowlist'),",
gregcef0a40ac2020-03-31 14:11:30 -07001198 " 'deps': attr.label_list(cfg = attr_transition),",
1199 " })",
1200 "rule_with_self_transition = rule(",
1201 " implementation = _impl,",
1202 " cfg = self_transition,",
1203 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001204 " '_allowlist_function_transition': attr.label(",
1205 " default = '//tools/allowlists/function_transition_allowlist'),",
gregcef0a40ac2020-03-31 14:11:30 -07001206 " })");
1207 scratch.file(
1208 "test/BUILD",
1209 "load('//test:rules.bzl', 'rule_with_attr_transition', 'rule_with_self_transition')",
1210 "load('//test:build_settings.bzl', 'string_flag')",
gregce11f25402021-07-08 07:14:10 -07001211 "string_flag(name = 'attr_transition_output_flag1', build_setting_default='')",
1212 "string_flag(name = 'attr_transition_output_flag2', build_setting_default='')",
1213 "string_flag(name = 'self_transition_output_flag1', build_setting_default='')",
1214 "string_flag(name = 'self_transition_output_flag2', build_setting_default='')",
gregcef0a40ac2020-03-31 14:11:30 -07001215 "rule_with_attr_transition(name = 'buildme', deps = [':adep'])",
1216 "rule_with_self_transition(name = 'adep')");
1217
1218 reporter.removeHandler(failFastHandler);
1219 getConfiguredTarget("//test:buildme");
1220 assertContainsEvent(
gregce11f25402021-07-08 07:14:10 -07001221 "transition outputs [//test:attr_transition_output_flag2] were not defined by transition "
gregcef0a40ac2020-03-31 14:11:30 -07001222 + "function");
Googlerfa28cf22023-07-11 09:50:38 -07001223 // While _self_impl is in error as it does not define //test:self_transition_output_flag2,
1224 // evaluation stops at the faulty _attr_impl definition so it does not cause an error.
gregcef0a40ac2020-03-31 14:11:30 -07001225 }
juliexxiabf57d6b2020-04-14 07:36:59 -07001226
1227 @Test
1228 public void testTransitionOnDefine() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001229 writeAllowlistFile();
juliexxiabf57d6b2020-04-14 07:36:59 -07001230 scratch.file(
1231 "test/transitions.bzl",
1232 "def _impl(settings, attr):",
1233 " return {'//command_line_option:define': 'chonky=true'}",
1234 "my_transition = transition(implementation = _impl, inputs = [],",
1235 " outputs = ['//command_line_option:define'])");
1236 scratch.file(
1237 "test/rules.bzl",
1238 "load('//test:transitions.bzl', 'my_transition')",
1239 "def _impl(ctx):",
1240 " return []",
1241 "my_rule = rule(",
1242 " implementation = _impl,",
1243 " cfg = my_transition,",
1244 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001245 " '_allowlist_function_transition': attr.label(",
1246 " default = '//tools/allowlists/function_transition_allowlist',",
juliexxiabf57d6b2020-04-14 07:36:59 -07001247 " ),",
1248 " })");
1249 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1250
1251 reporter.removeHandler(failFastHandler);
1252 getConfiguredTarget("//test");
1253 assertContainsEvent("Starlark transition on --define not supported - try using build settings");
1254 }
gregce7fc9ae72020-04-24 10:54:14 -07001255
1256 @Test
1257 public void successfulTypeConversionOfNativeListOption() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001258 writeAllowlistFile();
gregce7fc9ae72020-04-24 10:54:14 -07001259 scratch.file(
1260 "test/transitions.bzl",
1261 "def _impl(settings, attr):",
1262 " return {'//command_line_option:platforms': ['//test:my_platform']}",
1263 "my_transition = transition(implementation = _impl, inputs = [],",
1264 " outputs = ['//command_line_option:platforms'])");
1265 scratch.file(
1266 "test/rules.bzl",
1267 "load('//test:transitions.bzl', 'my_transition')",
1268 "def _impl(ctx):",
1269 " return []",
1270 "my_rule = rule(",
1271 " implementation = _impl,",
1272 " cfg = my_transition,",
1273 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001274 " '_allowlist_function_transition': attr.label(",
1275 " default = '//tools/allowlists/function_transition_allowlist',",
gregce7fc9ae72020-04-24 10:54:14 -07001276 " ),",
1277 " })");
1278 scratch.file(
1279 "test/BUILD",
1280 "load('//test:rules.bzl', 'my_rule')",
1281 "platform(name = 'my_platform')",
1282 "my_rule(name = 'test')");
1283
1284 getConfiguredTarget("//test");
1285 assertNoEvents();
1286 }
1287
Googler068d8452022-08-26 03:17:07 -07001288 @Test
1289 public void successfulTypeConversionOfNativeListOption_unambiguousLabels() throws Exception {
Googlerd51144c2023-10-13 03:20:20 -07001290 setBuildLanguageOptions("--incompatible_unambiguous_label_stringification");
Googler068d8452022-08-26 03:17:07 -07001291
1292 scratch.overwriteFile("MODULE.bazel", "bazel_dep(name='rules_x',version='1.0')");
1293 registry.addModule(createModuleKey("rules_x", "1.0"), "module(name='rules_x', version='1.0')");
1294 scratch.file("modules/rules_x~1.0/WORKSPACE");
1295 scratch.file("modules/rules_x~1.0/BUILD");
1296 scratch.file(
1297 "modules/rules_x~1.0/defs.bzl",
1298 "def _tr_impl(settings, attr):",
1299 " return {'//command_line_option:platforms': [Label('@@//test:my_platform')]}",
1300 "my_transition = transition(implementation = _tr_impl, inputs = [],",
1301 " outputs = ['//command_line_option:platforms'])",
1302 "def _impl(ctx):",
1303 " pass",
1304 "my_rule = rule(",
1305 " implementation = _impl,",
1306 " cfg = my_transition,",
1307 " attrs = {",
1308 " '_allowlist_function_transition': attr.label(",
1309 " default = '@@//tools/allowlists/function_transition_allowlist',",
1310 " ),",
1311 " })");
1312
1313 scratch.overwriteFile(
1314 "tools/allowlists/function_transition_allowlist/BUILD",
1315 "package_group(",
1316 " name = 'function_transition_allowlist',",
1317 " packages = [",
1318 " '//...',",
1319 " ],",
1320 ")");
1321
1322 scratch.file(
1323 "test/BUILD",
1324 "load('@rules_x//:defs.bzl', 'my_rule')",
1325 "platform(name = 'my_platform')",
1326 "my_rule(name = 'test')");
1327
Googlerd51144c2023-10-13 03:20:20 -07001328 invalidatePackages();
1329
Googler068d8452022-08-26 03:17:07 -07001330 getConfiguredTarget("//test");
1331 assertNoEvents();
1332 }
1333
juliexxia1cf37462020-10-20 14:48:10 -07001334 // Regression test for b/170729565
1335 @Test
1336 public void testSetBooleanNativeOptionWithStarlarkBoolean() throws Exception {
1337 writeAllowlistFile();
1338 scratch.file(
1339 "test/transitions.bzl",
1340 "def _impl(settings, attr):",
1341 " return {'//command_line_option:bool': True}",
1342 "my_transition = transition(implementation = _impl, inputs = [],",
1343 " outputs = ['//command_line_option:bool'])");
1344 scratch.file(
1345 "test/rules.bzl",
1346 "load('//test:transitions.bzl', 'my_transition')",
1347 "def _impl(ctx):",
1348 " return []",
1349 "my_rule = rule(",
1350 " implementation = _impl,",
1351 " cfg = my_transition,",
1352 " attrs = {",
1353 " '_allowlist_function_transition': attr.label(",
1354 " default = '//tools/allowlists/function_transition_allowlist',",
1355 " ),",
1356 " })");
1357 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1358 useConfiguration("--bool=false");
1359 ConfiguredTarget ct = getConfiguredTarget("//test");
1360 assertNoEvents();
1361 assertThat(getConfiguration(ct).getOptions().get(DummyTestOptions.class).bool).isTrue();
1362 }
1363
1364 // Regression test for b/170729565
1365 @Test
1366 public void testSetBooleanNativeOptionWithItself() throws Exception {
1367 writeAllowlistFile();
1368 scratch.file(
1369 "test/transitions.bzl",
1370 "def _impl(settings, attr):",
1371 " return {'//command_line_option:bool': settings['//command_line_option:bool']}",
1372 "my_transition = transition(implementation = _impl,",
1373 " inputs = ['//command_line_option:bool'],",
1374 " outputs = ['//command_line_option:bool'])");
1375 scratch.file(
1376 "test/rules.bzl",
1377 "load('//test:transitions.bzl', 'my_transition')",
1378 "def _impl(ctx):",
1379 " return []",
1380 "my_rule = rule(",
1381 " implementation = _impl,",
1382 " cfg = my_transition,",
1383 " attrs = {",
1384 " '_allowlist_function_transition': attr.label(",
1385 " default = '//tools/allowlists/function_transition_allowlist',",
1386 " ),",
1387 " })");
1388 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1389 useConfiguration("--bool=false");
1390 ConfiguredTarget ct = getConfiguredTarget("//test");
1391 assertNoEvents();
1392 assertThat(getConfiguration(ct).getOptions().get(DummyTestOptions.class).bool).isFalse();
1393 }
1394
gregce7fc9ae72020-04-24 10:54:14 -07001395 @Test
1396 public void failedTypeConversionOfNativeListOption() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001397 writeAllowlistFile();
gregce7fc9ae72020-04-24 10:54:14 -07001398 scratch.file(
1399 "test/transitions.bzl",
1400 "def _impl(settings, attr):",
1401 " return {'//command_line_option:platforms': ['this is not a valid label::']}",
1402 "my_transition = transition(implementation = _impl, inputs = [],",
1403 " outputs = ['//command_line_option:platforms'])");
1404 scratch.file(
1405 "test/rules.bzl",
1406 "load('//test:transitions.bzl', 'my_transition')",
1407 "def _impl(ctx):",
1408 " return []",
1409 "my_rule = rule(",
1410 " implementation = _impl,",
1411 " cfg = my_transition,",
1412 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001413 " '_allowlist_function_transition': attr.label(",
1414 " default = '//tools/allowlists/function_transition_allowlist',",
gregce7fc9ae72020-04-24 10:54:14 -07001415 " ),",
1416 " })");
1417 scratch.file(
1418 "test/BUILD",
1419 "load('//test:rules.bzl', 'my_rule')",
1420 "platform(name = 'my_platform')",
1421 "my_rule(name = 'test')");
1422
1423 reporter.removeHandler(failFastHandler);
1424 getConfiguredTarget("//test");
1425 assertContainsEvent("invalid target name ':': target names may not contain ':'");
1426 }
1427
1428 @Test
1429 public void successfulTypeConversionOfNativeListOptionEmptyList() throws Exception {
aiuto50226ac2020-06-14 21:28:27 -07001430 writeAllowlistFile();
gregce7fc9ae72020-04-24 10:54:14 -07001431 scratch.file(
1432 "test/transitions.bzl",
1433 "def _impl(settings, attr):",
1434 " return {'//command_line_option:fission': []}",
1435 "my_transition = transition(implementation = _impl, inputs = [],",
1436 " outputs = ['//command_line_option:fission'])");
1437 scratch.file(
1438 "test/rules.bzl",
1439 "load('//test:transitions.bzl', 'my_transition')",
1440 "def _impl(ctx):",
1441 " return []",
1442 "my_rule = rule(",
1443 " implementation = _impl,",
1444 " cfg = my_transition,",
1445 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001446 " '_allowlist_function_transition': attr.label(",
1447 " default = '//tools/allowlists/function_transition_allowlist',",
gregce7fc9ae72020-04-24 10:54:14 -07001448 " ),",
1449 " })");
1450 scratch.file(
1451 "test/BUILD",
1452 "load('//test:rules.bzl', 'my_rule')",
1453 "platform(name = 'my_platform')",
1454 "my_rule(name = 'test')");
1455
1456 ConfiguredTarget ct = getConfiguredTarget("//test");
1457 assertNoEvents();
1458 assertThat(getConfiguration(ct).getOptions().get(CppOptions.class).fissionModes).isEmpty();
1459 }
gregce06b76c92020-06-19 14:46:56 -07001460
1461 @Test
Tobiced45af2021-05-04 00:50:06 -07001462 public void failedTypeConversionOfNativeListOptionNone() throws Exception {
1463 writeAllowlistFile();
1464 scratch.file(
1465 "test/transitions.bzl",
1466 "def _impl(settings, attr):",
1467 " return {'//command_line_option:copt': None}",
1468 "my_transition = transition(implementation = _impl, inputs = [],",
1469 " outputs = ['//command_line_option:copt'])");
1470 scratch.file(
1471 "test/rules.bzl",
1472 "load('//test:transitions.bzl', 'my_transition')",
1473 "def _impl(ctx):",
1474 " return []",
1475 "my_rule = rule(",
1476 " implementation = _impl,",
1477 " cfg = my_transition,",
1478 " attrs = {",
1479 " '_allowlist_function_transition': attr.label(",
1480 " default = '//tools/allowlists/function_transition_allowlist',",
1481 " ),",
1482 " })");
1483 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1484
1485 reporter.removeHandler(failFastHandler);
1486 getConfiguredTarget("//test");
1487 assertContainsEvent(
1488 "'None' value not allowed for List-type option 'copt'. Please use '[]' instead if trying"
1489 + " to set option to empty value.");
1490 }
1491
1492 @Test
gregce06b76c92020-06-19 14:46:56 -07001493 public void starlarkPatchTransitionRequiredFragments() throws Exception {
1494 // All Starlark rule transitions are patch transitions, while all Starlark attribute transitions
1495 // are split transitions.
1496 writeAllowlistFile();
1497 scratch.file(
1498 "test/transitions.bzl",
1499 "def _impl(settings, attr):",
1500 " return {'//command_line_option:copt': []}", // --copt is a C++ option.
1501 "my_transition = transition(implementation = _impl, inputs = [],",
1502 " outputs = ['//command_line_option:copt'])");
1503 scratch.file(
1504 "test/rules.bzl",
1505 "load('//test:transitions.bzl', 'my_transition')",
1506 "def _impl(ctx):",
1507 " return []",
1508 "my_rule = rule(",
1509 " implementation = _impl,",
1510 " cfg = my_transition,",
1511 " attrs = {",
cushon1812caf2020-06-24 10:54:19 -07001512 " '_allowlist_function_transition': attr.label(",
1513 " default = '//tools/allowlists/function_transition_allowlist',",
gregce06b76c92020-06-19 14:46:56 -07001514 " ),",
1515 " })");
1516 scratch.file(
1517 "test/BUILD",
1518 "load('//test:rules.bzl', 'my_rule')",
1519 "platform(name = 'my_platform')",
1520 "my_rule(name = 'test')");
1521
1522 ConfiguredTargetAndData ct = getConfiguredTargetAndData("//test");
1523 assertNoEvents();
Googlerf5924702022-12-08 14:55:42 -08001524 Rule testTarget = (Rule) ct.getTargetForTesting();
gregce06b76c92020-06-19 14:46:56 -07001525 ConfigurationTransition ruleTransition =
John Cater525227e2021-07-27 10:53:43 -07001526 testTarget
1527 .getRuleClassObject()
1528 .getTransitionFactory()
Googlerceddfb12023-08-18 15:25:03 -07001529 .create(RuleTransitionData.create(testTarget, null, ""));
jhorvitz115da042021-08-16 18:50:06 -07001530 RequiredConfigFragmentsProvider.Builder requiredFragments =
1531 RequiredConfigFragmentsProvider.builder();
jhorvitz2dd65662021-11-04 16:31:24 -07001532 ruleTransition.addRequiredFragments(
gregcea9206eb2021-11-08 11:26:35 -08001533 requiredFragments, ct.getConfiguration().getBuildOptionDetails());
jhorvitz2e723f22021-08-20 17:09:30 -07001534 assertThat(requiredFragments.build().getOptionsClasses()).containsExactly(CppOptions.class);
gregce06b76c92020-06-19 14:46:56 -07001535 }
janakrca6209f2020-11-13 19:17:27 -08001536
1537 /**
1538 * Unit test for an invalid output directory from a mnemonic via a dep transition. Integration
1539 * test for top-level transition in //src/test/shell/integration:starlark_configurations_test#
1540 * test_invalid_mnemonic_from_transition_top_level. Has to be an integration test because the
1541 * error is emitted in BuildTool.
1542 */
1543 @Test
1544 public void invalidMnemonicFromDepTransition() throws Exception {
1545 writeAllowlistFile();
1546 scratch.file(
1547 "test/transitions.bzl",
1548 "def _impl(settings, attr):",
1549 " return {'//command_line_option:cpu': '//bad:cpu'}",
1550 "my_transition = transition(implementation = _impl, inputs = [],",
1551 " outputs = ['//command_line_option:cpu'])");
1552 scratch.file(
1553 "test/rules.bzl",
1554 "load('//test:transitions.bzl', 'my_transition')",
1555 "def _impl(ctx):",
1556 " return []",
1557 "my_rule = rule(",
1558 " implementation = _impl,",
1559 " cfg = my_transition,",
1560 " attrs = {",
1561 " '_allowlist_function_transition': attr.label(",
1562 " default = '//tools/allowlists/function_transition_allowlist',",
1563 " ),",
1564 " })");
1565 scratch.file(
1566 "test/BUILD",
1567 "load('//test:rules.bzl', 'my_rule')",
1568 "my_rule(name = 'bottom')",
1569 "genrule(name = 'test', srcs = [':bottom'], outs = ['out'], cmd = 'touch $@')");
1570 reporter.removeHandler(failFastHandler);
1571 assertThat(getConfiguredTarget("//test:test")).isNull();
Googler4dc0d112023-09-13 14:04:10 -07001572 assertContainsEvent("'//bad:cpu' is invalid as part of a path: must not contain /");
janakrca6209f2020-11-13 19:17:27 -08001573 }
juliexxiaa13f5902020-12-10 09:19:01 -08001574
1575 @Test
1576 public void testTransitionOnAllowMultiplesBuildSettingRequiresList() throws Exception {
juliexxiaa13f5902020-12-10 09:19:01 -08001577 scratch.file(
1578 "test/transitions.bzl",
1579 "def _transition_impl(settings, attr):",
1580 " return {'//test:cute-animal-fact': 'puffins mate for life'}",
1581 "my_transition = transition(",
1582 " implementation = _transition_impl,",
1583 " inputs = [],",
1584 " outputs = ['//test:cute-animal-fact']",
1585 ")");
1586 writeAllowlistFile();
1587 scratch.file(
1588 "test/rules.bzl",
1589 "load('//test:transitions.bzl', 'my_transition')",
1590 "def _rule_impl(ctx):",
1591 " return []",
1592 "my_rule = rule(",
1593 " implementation = _rule_impl,",
1594 " cfg = my_transition,",
1595 " attrs = {",
1596 " '_allowlist_function_transition': attr.label(",
1597 " default = '//tools/allowlists/function_transition_allowlist',",
1598 " ),",
1599 " },",
1600 ")");
1601 scratch.file(
1602 "test/build_settings.bzl",
1603 "def _impl(ctx):",
1604 " return []",
1605 "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True,"
1606 + " allow_multiple=True))");
1607 scratch.file(
1608 "test/BUILD",
1609 "load('//test:rules.bzl', 'my_rule')",
1610 "load('//test:build_settings.bzl', 'string_flag')",
1611 "my_rule(name = 'test')",
1612 "string_flag(",
1613 " name = 'cute-animal-fact',",
1614 " build_setting_default = \"cats can't taste sugar\",",
1615 ")");
1616
1617 reporter.removeHandler(failFastHandler);
1618 getConfiguredTarget("//test");
1619 assertContainsEvent(
1620 "'//test:cute-animal-fact' allows multiple values and must be set in transition using a"
1621 + " starlark list instead of single value");
1622 }
1623
1624 @Test
1625 public void testTransitionOnAllowMultiplesBuildSetting() throws Exception {
juliexxiaa13f5902020-12-10 09:19:01 -08001626 scratch.file(
1627 "test/transitions.bzl",
1628 "def _transition_impl(settings, attr):",
1629 " return {'//test:cute-animal-fact': ['puffins mate for life']}",
1630 "my_transition = transition(",
1631 " implementation = _transition_impl,",
1632 " inputs = [],",
1633 " outputs = ['//test:cute-animal-fact']",
1634 ")");
1635 writeAllowlistFile();
1636 scratch.file(
1637 "test/rules.bzl",
1638 "load('//test:transitions.bzl', 'my_transition')",
1639 "def _rule_impl(ctx):",
1640 " return []",
1641 "my_rule = rule(",
1642 " implementation = _rule_impl,",
1643 " cfg = my_transition,",
1644 " attrs = {",
1645 " '_allowlist_function_transition': attr.label(",
1646 " default = '//tools/allowlists/function_transition_allowlist',",
1647 " ),",
1648 " },",
1649 ")");
1650 scratch.file(
1651 "test/build_settings.bzl",
1652 "def _impl(ctx):",
1653 " return []",
1654 "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True,"
1655 + " allow_multiple=True))");
1656 scratch.file(
1657 "test/BUILD",
1658 "load('//test:rules.bzl', 'my_rule')",
1659 "load('//test:build_settings.bzl', 'string_flag')",
1660 "my_rule(name = 'test')",
1661 "string_flag(",
1662 " name = 'cute-animal-fact',",
1663 " build_setting_default = \"cats can't taste sugar\",",
1664 ")");
1665
1666 Map<Label, Object> starlarkOptions =
1667 getConfiguration(getConfiguredTarget("//test")).getOptions().getStarlarkOptions();
1668 assertNoEvents();
1669 assertThat(
Googler08463dc2023-01-20 08:02:19 -08001670 (List<?>) starlarkOptions.get(Label.parseCanonicalUnchecked("//test:cute-animal-fact")))
juliexxiaa13f5902020-12-10 09:19:01 -08001671 .containsExactly("puffins mate for life");
1672 }
gregced6795462020-12-14 11:06:45 -08001673
Fabian Meumertzheim5dcefe12022-09-23 08:20:21 -07001674 @Test
1675 public void testTransitionOnAllowMultiplesBuildSettingAlwaysSeesListValue() throws Exception {
1676 scratch.file(
1677 "test/transitions.bzl",
1678 "def _transition_impl(settings, attr):",
1679 " setting_type = type(settings['//test:multiple_flag'])",
1680 " if setting_type != type([]):",
1681 " fail('Expected setting to be a list, got %s' % setting_type)",
1682 " return {}",
1683 "my_transition = transition(",
1684 " implementation = _transition_impl,",
1685 " inputs = ['//test:multiple_flag'],",
1686 " outputs = ['//test:multiple_flag']",
1687 ")");
1688 writeAllowlistFile();
1689 scratch.file(
1690 "test/rules.bzl",
1691 "load('//test:transitions.bzl', 'my_transition')",
1692 "def _rule_impl(ctx):",
1693 " return []",
1694 "my_rule = rule(",
1695 " implementation = _rule_impl,",
1696 " cfg = my_transition,",
1697 " attrs = {",
1698 " '_allowlist_function_transition': attr.label(",
1699 " default = '//tools/allowlists/function_transition_allowlist',",
1700 " ),",
1701 " },",
1702 ")");
1703 scratch.file(
1704 "test/build_settings.bzl",
1705 "def _impl(ctx):",
1706 " return []",
1707 "string_flag = rule(implementation = _impl, build_setting = config.string(flag=True,"
1708 + " allow_multiple=True))");
1709 scratch.file(
1710 "test/BUILD",
1711 "load('//test:rules.bzl', 'my_rule')",
1712 "load('//test:build_settings.bzl', 'string_flag')",
1713 "my_rule(name = 'test')",
1714 "string_flag(",
1715 " name = 'multiple_flag',",
1716 " build_setting_default = '',",
1717 ")");
1718
1719 // Starlark option at is default value.
1720 getConfiguredTarget("//test");
1721
1722 useConfiguration(ImmutableMap.of("//test:multiple_flag", ImmutableList.of("foo")));
1723 getConfiguredTarget("//test");
1724
1725 useConfiguration(ImmutableMap.of("//test:multiple_flag", ImmutableList.of("foo", "bar")));
1726 getConfiguredTarget("//test");
1727 }
1728
gregced6795462020-12-14 11:06:45 -08001729 /**
1730 * Changing --cpu implicitly changes the target platform. Test that the old value of --platforms
1731 * gets cleared out (platform mappings can then kick in to set --platforms correctly).
1732 */
1733 @Test
1734 public void testImplicitPlatformsChange() throws Exception {
1735 scratch.file("platforms/BUILD", "platform(name = 'my_platform', constraint_values = [])");
1736 scratch.file(
1737 "test/transitions.bzl",
1738 "def _transition_impl(settings, attr):",
1739 " return {'//command_line_option:cpu': 'ppc'}",
1740 "my_transition = transition(",
1741 " implementation = _transition_impl,",
1742 " inputs = [],",
1743 " outputs = ['//command_line_option:cpu']",
1744 ")");
1745 writeAllowlistFile();
1746 scratch.file(
1747 "test/rules.bzl",
1748 "load('//test:transitions.bzl', 'my_transition')",
1749 "def _rule_impl(ctx):",
1750 " return []",
1751 "my_rule = rule(",
1752 " implementation = _rule_impl,",
1753 " cfg = my_transition,",
1754 " attrs = {",
1755 " '_allowlist_function_transition': attr.label(",
1756 " default = '//tools/allowlists/function_transition_allowlist',",
1757 " ),",
1758 " },",
1759 ")");
1760 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1761
1762 useConfiguration("--platforms=//platforms:my_platform");
1763 // When --platforms is empty and no platform mapping triggers, PlatformMappingValue sets
1764 // --platforms to PlatformOptions.computeTargetPlatform(), which defaults to the host.
1765 assertThat(
1766 getConfiguration(getConfiguredTarget("//test:test"))
1767 .getOptions()
1768 .get(PlatformOptions.class)
1769 .platforms)
1770 .containsExactly(
Googler08463dc2023-01-20 08:02:19 -08001771 Label.parseCanonicalUnchecked(
Googler34697842022-08-09 07:04:42 -07001772 TestConstants.LOCAL_CONFIG_PLATFORM_PACKAGE_ROOT + ":host"));
gregced6795462020-12-14 11:06:45 -08001773 }
1774
1775 @Test
1776 public void testExplicitPlatformsChange() throws Exception {
1777 scratch.file(
1778 "platforms/BUILD",
1779 "platform(name = 'my_platform', constraint_values = [])",
1780 "platform(name = 'my_other_platform', constraint_values = [])");
1781 scratch.file(
1782 "test/transitions.bzl",
1783 "def _transition_impl(settings, attr):",
1784 " return {",
1785 " '//command_line_option:cpu': 'ppc',",
1786 " '//command_line_option:platforms': ['//platforms:my_other_platform']",
1787 " }",
1788 "my_transition = transition(",
1789 " implementation = _transition_impl,",
1790 " inputs = [],",
1791 " outputs = [",
1792 " '//command_line_option:cpu',",
1793 " '//command_line_option:platforms'",
1794 " ]",
1795 ")");
1796 writeAllowlistFile();
1797 scratch.file(
1798 "test/rules.bzl",
1799 "load('//test:transitions.bzl', 'my_transition')",
1800 "def _rule_impl(ctx):",
1801 " return []",
1802 "my_rule = rule(",
1803 " implementation = _rule_impl,",
1804 " cfg = my_transition,",
1805 " attrs = {",
1806 " '_allowlist_function_transition': attr.label(",
1807 " default = '//tools/allowlists/function_transition_allowlist',",
1808 " ),",
1809 " },",
1810 ")");
1811 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1812
1813 useConfiguration("--platforms=//platforms:my_platform");
1814 assertThat(
1815 getConfiguration(getConfiguredTarget("//test:test"))
1816 .getOptions()
1817 .get(PlatformOptions.class)
1818 .platforms)
Googler08463dc2023-01-20 08:02:19 -08001819 .containsExactly(Label.parseCanonicalUnchecked("//platforms:my_other_platform"));
gregced6795462020-12-14 11:06:45 -08001820 }
1821
1822 /* If the transition doesn't change --cpu, it doesn't constitute a platform change. */
1823 @Test
1824 public void testNoPlatformChange() throws Exception {
1825 scratch.file("platforms/BUILD", "platform(name = 'my_platform', constraint_values = [])");
1826 scratch.file(
1827 "test/transitions.bzl",
1828 "def _transition_impl(settings, attr):",
1829 " return {",
twigg4970e0f2021-03-31 15:34:49 -07001830 " '//command_line_option:foo': 'blah',",
gregced6795462020-12-14 11:06:45 -08001831 " }",
1832 "my_transition = transition(",
1833 " implementation = _transition_impl,",
1834 " inputs = [],",
1835 " outputs = [",
twigg4970e0f2021-03-31 15:34:49 -07001836 " '//command_line_option:foo',",
gregced6795462020-12-14 11:06:45 -08001837 " ]",
1838 ")");
1839 writeAllowlistFile();
1840 scratch.file(
1841 "test/rules.bzl",
1842 "load('//test:transitions.bzl', 'my_transition')",
1843 "def _rule_impl(ctx):",
1844 " return []",
1845 "my_rule = rule(",
1846 " implementation = _rule_impl,",
1847 " cfg = my_transition,",
1848 " attrs = {",
1849 " '_allowlist_function_transition': attr.label(",
1850 " default = '//tools/allowlists/function_transition_allowlist',",
1851 " ),",
1852 " },",
1853 ")");
1854 scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
1855
1856 useConfiguration("--platforms=//platforms:my_platform");
1857 assertThat(
1858 getConfiguration(getConfiguredTarget("//test:test"))
1859 .getOptions()
1860 .get(PlatformOptions.class)
1861 .platforms)
Googler08463dc2023-01-20 08:02:19 -08001862 .containsExactly(Label.parseCanonicalUnchecked("//platforms:my_platform"));
gregced6795462020-12-14 11:06:45 -08001863 }
gregcefe644be2021-11-01 12:12:02 -07001864
1865 @Test
1866 public void testTransitionsStillTriggerWhenOnlyRuleAttributesChange() throws Exception {
1867 scratch.file(
1868 "test/defs.bzl",
1869 "def _transition_impl(settings, attr):",
1870 " return {",
1871 " '//command_line_option:foo': attr.my_attr,",
1872 " }",
1873 "_my_transition = transition(",
1874 " implementation = _transition_impl,",
1875 " inputs = [],",
1876 " outputs = [",
1877 " '//command_line_option:foo',",
1878 " ]",
1879 ")",
1880 "def _rule_impl(ctx):",
1881 " return []",
1882 "my_rule = rule(",
1883 " implementation = _rule_impl,",
1884 " cfg = _my_transition,",
1885 " attrs = {",
1886 " 'my_attr': attr.string(),",
1887 " '_allowlist_function_transition': attr.label(",
1888 " default = '//tools/allowlists/function_transition_allowlist',",
1889 " ),",
1890 " },",
1891 ")");
1892 writeAllowlistFile();
1893
1894 scratch.file(
1895 "test/BUILD",
1896 "load('//test:defs.bzl', 'my_rule')",
1897 "my_rule(",
1898 " name = 'buildme',",
1899 " my_attr = 'first build',",
1900 ")");
1901 assertThat(
1902 getConfiguration(getConfiguredTarget("//test:buildme"))
1903 .getOptions()
1904 .get(DummyTestOptions.class)
1905 .foo)
1906 .isEqualTo("first build");
1907
1908 scratch.overwriteFile(
1909 "test/BUILD",
1910 "load('//test:defs.bzl', 'my_rule')",
1911 "my_rule(",
1912 " name = 'buildme',",
1913 " my_attr = 'second build',",
1914 ")");
1915 skyframeExecutor.invalidateFilesUnderPathForTesting(
1916 reporter,
1917 ModifiedFileSet.builder().modify(PathFragment.create("test/BUILD")).build(),
1918 Root.fromPath(rootDirectory));
1919
1920 assertThat(
1921 getConfiguration(getConfiguredTarget("//test:buildme"))
1922 .getOptions()
1923 .get(DummyTestOptions.class)
1924 .foo)
1925 .isEqualTo("second build");
1926 }
Googler35f81b42023-07-11 08:49:47 -07001927
1928 private static class AnalysisRootCauseCollector {
1929 private final ArrayList<AnalysisRootCauseEvent> rootCauses = new ArrayList<>();
1930
1931 @Subscribe
1932 public void rootCause(AnalysisRootCauseEvent event) {
1933 rootCauses.add(event);
1934 }
1935 }
juliexxiadeb028e2019-01-05 17:19:21 -08001936}