blob: 6025381b300ff5756f382564e957df0aa3b7af16 [file] [log] [blame]
Googlerceddfb12023-08-18 15:25:03 -07001#!/bin/bash
2#
3# Copyright 2023 The Bazel Authors. All rights reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17# Test rule transition can inspect configurable attribute.
18
19# --- begin runfiles.bash initialization ---
20# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
21if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
22 if [[ -f "$0.runfiles_manifest" ]]; then
23 export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
24 elif [[ -f "$0.runfiles/MANIFEST" ]]; then
25 export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
26 elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
27 export RUNFILES_DIR="$0.runfiles"
28 fi
29fi
30if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
31 source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
32elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
33 source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
34 "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
35else
36 echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
37 exit 1
38fi
39# --- end runfiles.bash initialization ---
40
41source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \
42 || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
43
44function set_up() {
45 create_new_workspace
46}
47
48function create_transitions() {
49 local pkg="${1}"
50 mkdir -p "${pkg}"
51 cat > "${pkg}/def.bzl" <<EOF
52
53load("//third_party/bazel_skylib/rules:common_settings.bzl", "BuildSettingInfo")
54
55example_package = "${pkg}"
56
57def _transition_impl(settings, attr):
58 if getattr(attr, "apply_transition") and settings["//%s:transition_input_flag" % example_package]:
59 return {"//%s:transition_output_flag" % example_package: True}
60 return {"//%s:transition_output_flag" % example_package: False}
61
62example_transition = transition(
63 implementation = _transition_impl,
64 inputs = ["//%s:transition_input_flag" % example_package],
65 outputs = ["//%s:transition_output_flag" % example_package],
66)
67
68def _rule_impl(ctx):
69 print("Flag value for %s: %s" % (
70 ctx.label.name,
71 ctx.attr._transition_output_flag[BuildSettingInfo].value,
72 ))
73
74transition_attached = rule(
75 implementation = _rule_impl,
76 cfg = example_transition,
77 attrs = {
78 "apply_transition": attr.bool(default = False),
79 "deps": attr.label_list(),
80 "_transition_output_flag": attr.label(default = "//%s:transition_output_flag" % example_package),
81 "_allowlist_function_transition": attr.label(
82 default = "//tools/allowlists/function_transition_allowlist:function_transition_allowlist",
83 ),
84 },
85)
86
87transition_not_attached = rule(
88 implementation = _rule_impl,
89 attrs = {
90 "deps": attr.label_list(),
91 "_transition_output_flag": attr.label(default = "//%s:transition_output_flag" % example_package),
92 },
93)
94EOF
95}
96
97function create_rules_with_incoming_transition_and_selects() {
98 local pkg="${1}"
99 mkdir -p "${pkg}"
100 cat > "${pkg}/BUILD" <<EOF
101load(
102 "//${pkg}:def.bzl",
103 "transition_attached",
104 "transition_not_attached",
105)
106load("//third_party/bazel_skylib/rules:common_settings.bzl", "bool_flag")
107
108bool_flag(
109 name = "transition_input_flag",
110 build_setting_default = True,
111)
112
113bool_flag(
114 name = "transition_output_flag",
115 build_setting_default = False,
116)
117
118config_setting(
119 name = "select_setting",
120 flag_values = {":transition_input_flag": "True"},
121)
122
123# All should print "False" if
124# "--no//${pkg}:transition_input_flag" is
125# specified on the command line
126
127# bazel build :top_level will print the results for all of the targets below
128
129transition_attached(
130 name = "top_level",
131 apply_transition = select({
132 ":select_setting": True,
133 "//conditions:default": False,
134 }),
135 deps = [
136 ":transition_attached_dep",
137 ":transition_not_attached_dep",
138 ],
139)
140
141# Should print "False"
142transition_attached(
143 apply_transition = False,
144 name = "transition_attached_dep",
145 deps = [
146 ":transition_not_attached_dep_of_dep",
147 ],
148)
149
150# Should print "True" when building top_level, "False" otherwise
151transition_not_attached(
152 name = "transition_not_attached_dep",
153)
154
155# Should print "False"
156transition_not_attached(
157 name = "transition_not_attached_dep_of_dep",
158)
159EOF
160}
161
162function test_rule_transition_can_inspect_configure_attributes(){
163 local -r pkg="${FUNCNAME[0]}"
164 create_transitions "${pkg}"
165 create_rules_with_incoming_transition_and_selects "${pkg}"
166
167 bazel build "//${pkg}:top_level" &> $TEST_log || fail "Build failed"
168
169 expect_log 'Flag value for transition_not_attached_dep: True'
170 expect_log 'Flag value for transition_not_attached_dep_of_dep: False'
171 expect_log 'Flag value for transition_attached_dep: False'
172 expect_log 'Flag value for top_level: True'
173}
174
175function test_rule_transition_can_inspect_configure_attributes_with_flag(){
176 local -r pkg="${FUNCNAME[0]}"
177
178 create_transitions "${pkg}"
179 create_rules_with_incoming_transition_and_selects "${pkg}"
180
181 bazel build --no//${pkg}:transition_input_flag "//${pkg}:top_level" &> $TEST_log || fail "Build failed"
182
183 expect_log 'Flag value for transition_not_attached_dep: False'
184 expect_log 'Flag value for transition_not_attached_dep_of_dep: False'
185 expect_log 'Flag value for transition_attached_dep: False'
186 expect_log 'Flag value for top_level: False'
187}
188
189function test_rule_transition_can_not_inspect_configure_attribute() {
190 local -r pkg="${FUNCNAME[0]}"
191
192 # create transition definition
193 mkdir -p "${pkg}"
194 cat > "${pkg}/def.bzl" <<EOF
195
196load("//third_party/bazel_skylib/rules:common_settings.bzl", "BuildSettingInfo")
197
198example_package = "${pkg}"
199
200def _transition_impl(settings, attr):
201 if getattr(attr, "apply_transition") and settings["//%s:transition_input_flag" % example_package]:
202 return {"//%s:transition_output_flag" % example_package: True}
203 return {
204 "//%s:transition_output_flag" % example_package: False,
205 "//%s:transition_input_flag" % example_package: False
206 }
207
208example_transition = transition(
209 implementation = _transition_impl,
210 inputs = ["//%s:transition_input_flag" % example_package],
211 outputs = [
212 "//%s:transition_output_flag" % example_package,
213 "//%s:transition_input_flag" % example_package,
214 ],
215)
216
217def _rule_impl(ctx):
218 print("Flag value for %s: %s" % (
219 ctx.label.name,
220 ctx.attr._transition_output_flag[BuildSettingInfo].value,
221 ))
222
223transition_attached = rule(
224 implementation = _rule_impl,
225 cfg = example_transition,
226 attrs = {
227 "apply_transition": attr.bool(default = False),
228 "deps": attr.label_list(),
229 "_transition_output_flag": attr.label(default = "//%s:transition_output_flag" % example_package),
230 "_allowlist_function_transition": attr.label(
231 default = "//tools/allowlists/function_transition_allowlist:function_transition_allowlist",
232 ),
233 },
234)
235EOF
236
237 # create rules with transition attached
238 cat > "${pkg}/BUILD" <<EOF
239load(
240 "//${pkg}:def.bzl",
241 "transition_attached",
242)
243load("//third_party/bazel_skylib/rules:common_settings.bzl", "bool_flag")
244
245bool_flag(
246 name = "transition_input_flag",
247 build_setting_default = True,
248)
249
250bool_flag(
251 name = "transition_output_flag",
252 build_setting_default = False,
253)
254
255config_setting(
256 name = "select_setting",
257 flag_values = {":transition_input_flag": "True"},
258)
259
260# All should print "False" if
261# "--no//${pkg}:transition_input_flag" is
262# specified on the command line
263
264# bazel build :top_level will print the results for all of the targets below
265
266transition_attached(
267 name = "top_level",
268 apply_transition = select({
269 ":select_setting": True,
270 "//conditions:default": False,
271 }),
272)
273EOF
274 bazel build "//${pkg}:top_level" &> $TEST_log && fail "Build did NOT complete successfully"
275 expect_log "No attribute 'apply_transition'. Either this attribute does not exist for this rule or the attribute was not resolved because it is set by a select that reads flags the transition may set."
276}
277
278run_suite "rule transition tests"