blob: d627c99202c5d7e49220a48841c5b44434183096 [file] [log] [blame]
Googlerfff72a72018-08-30 17:42:10 -07001#!/bin/bash
2#
3# Copyright 2018 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# modify_execution_info_test.sh: tests of the --modify_execution_info flag.
18
Benjamin Peterson804406f2018-10-11 08:39:35 -070019# --- begin runfiles.bash initialization ---
20# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
21set -euo pipefail
22if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
23 if [[ -f "$0.runfiles_manifest" ]]; then
24 export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
25 elif [[ -f "$0.runfiles/MANIFEST" ]]; then
26 export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
27 elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
28 export RUNFILES_DIR="$0.runfiles"
29 fi
30fi
31if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
32 source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
33elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
34 source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
35 "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
36else
37 echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
38 exit 1
39fi
40# --- end runfiles.bash initialization ---
41
42source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \
Googlerfff72a72018-08-30 17:42:10 -070043 || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
44
Benjamin Peterson804406f2018-10-11 08:39:35 -070045case "$(uname -s | tr [:upper:] [:lower:])" in
46msys*|mingw*|cygwin*)
47 declare -r is_windows=true
48 ;;
49*)
50 declare -r is_windows=false
51 ;;
52esac
53
54if "$is_windows"; then
55 export MSYS_NO_PATHCONV=1
56 export MSYS2_ARG_CONV_EXCL="*"
57fi
58
Googlerfff72a72018-08-30 17:42:10 -070059#### HELPER FUNCTIONS ##################################################
60
Laszlo Csomorf57c3062019-01-16 05:06:00 -080061if ! type try_with_timeout >&/dev/null; then
62 # Bazel's testenv.sh defines try_with_timeout but the Google-internal version
63 # uses a different testenv.sh.
64 function try_with_timeout() { $* ; }
65fi
66
Googlerfff72a72018-08-30 17:42:10 -070067function set_up() {
68 cd ${WORKSPACE_DIR}
69}
70
71function tear_down() {
Laszlo Csomorf57c3062019-01-16 05:06:00 -080072 try_with_timeout bazel shutdown
Googlerfff72a72018-08-30 17:42:10 -070073}
74
75#### TESTS #############################################################
76
77function test_aquery_respects_modify_execution_info_changes {
78 local pkg="${FUNCNAME[0]}"
79 mkdir -p "$pkg" || fail "mkdir -p $pkg"
80 cat > "$pkg/BUILD" <<'EOF'
81genrule(name = "bar", outs = ["bar_out.txt"], cmd = "touch $(OUTS)")
82EOF
83 bazel aquery --output=text "//$pkg:bar" \
84 --modify_execution_info=Genrule=+requires-x \
85 > output1 2> "$TEST_log" || fail "Expected success"
86 assert_contains "ExecutionInfo: {requires-x: ''}" output1
87
88 bazel aquery --output=text "//$pkg:bar" \
89 --modify_execution_info=Genrule=+requires-y \
90 > output2 2> "$TEST_log" || fail "Expected success"
91 assert_contains "ExecutionInfo: {requires-y: ''}" output2
92}
93
94function test_modify_execution_info_multiple {
95 local pkg="${FUNCNAME[0]}"
96 mkdir -p "$pkg" || fail "mkdir -p $pkg"
97 cat > "$pkg/BUILD" <<'EOF'
98genrule(
99 name = "bar",
100 outs = ["bar_out.txt"],
101 cmd = "touch $(OUTS)",
102 tags = ["requires-x"],
103)
104cc_binary(name="zero", srcs=["zero.cc"])
105EOF
106 echo "int main(void) {}" > "$pkg/zero.cc"
107
108 # multiple elements in the value list that match the same mnemonic.
109 bazel aquery --output=text "//$pkg:bar" \
110 --modify_execution_info=Genrule=+requires-y,Genrule=+requires-z \
111 > output 2> "$TEST_log" || fail "Expected success"
112 assert_contains "ExecutionInfo: {requires-x: '', requires-y: '', "\
113"requires-z: ''}" output
114
115 # multiple elements in the value list, the first of which adds an
116 # ExecutionInfo and the second of which removes it.
117 bazel aquery --output=text "//$pkg:bar" \
118 --modify_execution_info=Genrule=+requires-z,.*=-requires-z \
119 > output 2> "$TEST_log" || fail "Expected success"
120 assert_contains "ExecutionInfo: {requires-x: ''}" output
121
122 # multiple elements in the value list, the first of which removes an
123 # ExecutionInfo (previously absent) and the second of which adds it.
124 bazel aquery --output=text "//$pkg:bar" \
125 --modify_execution_info=Genrule=-requires-z,.*=+requires-z \
126 > output 2> "$TEST_log" || fail "Expected success"
127 assert_contains "ExecutionInfo: {requires-x: '', requires-z: ''}" output
128
129 # multiple elements in the value list, the first of which removes an
130 # ExecutionInfo (previously present) and the second of which adds it back.
131 bazel aquery --output=text "//$pkg:bar" \
132 --modify_execution_info=Genrule=-requires-x,.*=+requires-x \
133 > output 2> "$TEST_log" || fail "Expected success"
134 assert_contains "ExecutionInfo: {requires-x: ''}" output
135
136 # multiple elements with multiple values
137 bazel aquery --output=text "//$pkg:all" \
138 --modify_execution_info=Genrule=-requires-x,Genrule=+requires-z,\
139Genrule=+requires-a,CppCompile=+requires-b,CppCompile=+requires-c \
140 > output 2> "$TEST_log" || fail "Expected success"
141 assert_contains "ExecutionInfo: {requires-a: '', requires-z: ''}" output
Benjamin Peterson804406f2018-10-11 08:39:35 -0700142 assert_contains "ExecutionInfo: {requires-b: '', requires-c: ''" output
Googlerfff72a72018-08-30 17:42:10 -0700143
144 # negative lookahead
145 bazel aquery --output=text "//$pkg:all" \
146 --modify_execution_info='(?!Genrule).*=+requires-a,(?!CppCompile).*=+requires-z' \
147 > output 2> "$TEST_log" || fail "Expected success"
148 assert_contains "ExecutionInfo: {requires-x: '', requires-z: ''}" output
Benjamin Peterson804406f2018-10-11 08:39:35 -0700149 assert_contains "ExecutionInfo: {requires-a: ''" output
Googlerfff72a72018-08-30 17:42:10 -0700150}
151
152function test_modify_execution_info_various_types() {
Benjamin Peterson804406f2018-10-11 08:39:35 -0700153 if [[ "$PRODUCT_NAME" = "bazel" ]]; then
Tony Aiuto320bc942021-01-14 07:43:21 -0800154 cat "$(rlocation "io_bazel/src/test/shell/integration/rules_proto_stanza.txt")" >>WORKSPACE
155 cat >> WORKSPACE << EOF
Yannic Bonenberger5e571d22020-02-13 07:29:58 -0800156load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
157rules_proto_dependencies()
158rules_proto_toolchains()
159
160# @com_google_protobuf//:protoc depends on @io_bazel//third_party/zlib.
Benjamin Peterson804406f2018-10-11 08:39:35 -0700161new_local_repository(
Yannic Bonenberger5e571d22020-02-13 07:29:58 -0800162 name = "io_bazel",
Yun Peng9d308492023-08-08 00:49:00 -0700163 path = "$(dirname $(dirname $(dirname $(rlocation io_bazel/third_party/zlib/BUILD))))",
Yannic Bonenberger5e571d22020-02-13 07:29:58 -0800164 build_file_content = "# Intentionally left empty.",
165 workspace_file_content = "workspace(name = 'io_bazel')",
Benjamin Peterson804406f2018-10-11 08:39:35 -0700166)
167EOF
168 fi
Googlerfff72a72018-08-30 17:42:10 -0700169 local pkg="${FUNCNAME[0]}"
170 mkdir -p "$pkg" || fail "mkdir -p $pkg"
gregce72e559d2020-08-12 12:10:14 -0700171 echo "load('//$pkg:shell.bzl', 'starlark_shell')" > "$pkg/BUILD"
Googlerfff72a72018-08-30 17:42:10 -0700172 cat >> "$pkg/BUILD" <<'EOF'
Richard Levasseur0c617b32023-09-13 11:37:17 -0700173load("@rules_python//python:py_binary.bzl", "py_binary")
174
gregce72e559d2020-08-12 12:10:14 -0700175starlark_shell(
Googlerfff72a72018-08-30 17:42:10 -0700176 name = "shelly",
177 output = "ok.txt",
178)
179
180cc_binary(name="zero", srcs=["zero.cc"])
181
182sh_test(name="test_a", srcs=["a.sh"])
183
184java_library(name = "javalib", srcs = ["HelloWorld.java"])
185
186action_listener(
187 name = "al",
188 extra_actions = [":echo-filename"],
Benjamin Peterson804406f2018-10-11 08:39:35 -0700189 mnemonics = ["Javac"],
190 visibility = ["//visibility:public"],
Googlerfff72a72018-08-30 17:42:10 -0700191)
192
adonovan73402fa2020-11-09 10:51:37 -0800193extra_action(name = "echo-filename", cmd = "echo Hi \\$(EXTRA_ACTION_FILE)")
Googlerfff72a72018-08-30 17:42:10 -0700194
195py_binary(name = "pybar", srcs=["pybar.py"],)
196
197proto_library(name = "proto", srcs=["foo.proto"])
198EOF
199 cat > "$pkg/shell.bzl" <<'EOF'
200def _impl(ctx):
201 ctx.actions.run_shell(
202 outputs = [ ctx.outputs.output ],
203 command = "touch %s" % ctx.outputs.output.path,
204 )
205
gregce72e559d2020-08-12 12:10:14 -0700206starlark_shell = rule(
Googlerfff72a72018-08-30 17:42:10 -0700207 _impl,
208 attrs = {
209 "output": attr.output(mandatory=True),
210 }
211)
212EOF
213 cat > "$pkg/a.sh" <<'EOF'
214#!/bin/sh
215exit 0
216EOF
217 chmod 755 "$pkg/a.sh"
218 echo "int main(void) {}" > "$pkg/zero.cc"
219 echo "public class HelloWorld {}" > "$pkg/HelloWorld.java"
220 echo 'print("Hi")' > "$pkg/pybar.py"
221 echo 'syntax="proto2"; package foo;' > "$pkg/foo.proto"
222
223 bazel aquery --output=text "//$pkg:all" \
224 --experimental_action_listener=$pkg:al \
225 --modify_execution_info=\
226echo.*=+requires-extra-action,\
227.*Proto.*=+requires-proto,\
228CppCompile=+requires-cpp-compile,\
229CppLink=+requires-cpp-link,\
230TestRunner=+requires-test-runner,\
231Turbine=+requires-turbine,\
232JavaSourceJar=+requires-java-source-jar,\
233Javac=+requires-javac,\
Richard Levasseur7a230fd2022-06-17 14:19:32 -0700234Py.*=+requires-py,\
laurentlb47e88542019-07-01 09:29:04 -0700235Action=+requires-action \
Googlerfff72a72018-08-30 17:42:10 -0700236 > output 2> "$TEST_log" || fail "Expected success"
237
238 # There are sometimes other elements in ExecutionInfo, e.g. requires-darwin
239 # for obj-c, supports-workers for java. Since testing for these combinations
240 # would be brittle, irrelevant to the operation of the flag, and in some
241 # cases platform-dependent, we just search for the key itself, not the whole
242 # ExecutionInfo: {...} line.
laurentlb47e88542019-07-01 09:29:04 -0700243 assert_contains "requires-action: ''" output
Googlerfff72a72018-08-30 17:42:10 -0700244 assert_contains "requires-cpp-compile: ''" output
245 assert_contains "requires-cpp-link: ''" output
246 assert_contains "requires-extra-action: ''" output
247 assert_contains "requires-test-runner: ''" output
248 assert_contains "requires-javac: ''" output
249 assert_contains "requires-turbine: ''" output
250 assert_contains "requires-java-source-jar: ''" output
251 assert_contains "requires-proto: ''" output # GenProtoDescriptorSet should match
Benjamin Peterson804406f2018-10-11 08:39:35 -0700252 if [[ "$PRODUCT_NAME" != "bazel" ]]; then
Richard Levasseur7a230fd2022-06-17 14:19:32 -0700253 assert_contains "requires-py: ''" output
Benjamin Peterson804406f2018-10-11 08:39:35 -0700254 fi
Googlerfff72a72018-08-30 17:42:10 -0700255}
256
Googlercfe03182019-03-09 07:42:11 -0800257# Regression test for b/127874955. We use --output=textproto since --output=text
258# sorts the execution info.
259function test_modify_execution_info_deterministic_order() {
260 local pkg="${FUNCNAME[0]}"
261 mkdir -p "$pkg/x" "$pkg/y" || fail "mkdir failed"
262 touch "$pkg/BUILD"
263 cat > "$pkg/build_defs.bzl" <<'EOF' || fail "Couldn't cat"
264def _rule_x_impl(ctx):
265 output = ctx.outputs.out
266 ctx.actions.run_shell(
267 outputs = [output],
268 command = "touch %s" % output.path,
269 mnemonic = "RuleX",
270 execution_requirements = {"requires-x": ""},
271 )
272
273rule_x = rule(outputs = {"out": "%{name}.out"}, implementation = _rule_x_impl)
274
275def _rule_y_impl(ctx):
276 output = ctx.outputs.out
277 ctx.actions.run_shell(
278 outputs = [output],
279 command = "touch %s" % output.path,
280 mnemonic = "RuleY",
281 execution_requirements = {"requires-y": ""},
282 )
283
284rule_y = rule(outputs = {"out": "%{name}.out"}, implementation = _rule_y_impl)
285EOF
286 echo "load('//$pkg:build_defs.bzl', 'rule_x')" > "$pkg/x/BUILD"
287 echo 'rule_x(name = "x")' >> "$pkg/x/BUILD"
288 echo "load('//$pkg:build_defs.bzl', 'rule_y')" > "$pkg/y/BUILD"
289 echo 'rule_y(name = "y")' >> "$pkg/y/BUILD"
290
291 mod='Rule(X|Y)=+requires-x,Rule(X|Y)=+requires-y'
292
293 bazel aquery "//$pkg/x" --output=textproto --modify_execution_info="$mod" \
294 > output1 2> "$TEST_log" || fail "Expected success"
295
296 bazel shutdown >& "$TEST_log" || fail "Couldn't shutdown"
297
298 bazel aquery "//$pkg/y" --modify_execution_info="$mod" \
299 >& "$TEST_log" || fail "Expected success"
300
301 bazel aquery "//$pkg/x" --output=textproto --modify_execution_info="$mod" \
302 > output2 2> "$TEST_log" || fail "Expected success"
303
304 assert_equals "$(cat output1)" "$(cat output2)"
305}
306
Googlerab96caa2019-04-22 12:07:07 -0700307# Regression test for b/130762259.
308function test_modify_execution_info_changes_test_runner_cache_key() {
309 local pkg="${FUNCNAME[0]}"
310 mkdir -p "$pkg"
311 echo "sh_test(name = 'test', srcs = ['test.sh'])" > "$pkg/BUILD"
312 touch "$pkg/test.sh"
313
314 bazel aquery "mnemonic(TestRunner,//$pkg:test)" --output=text \
315 --modify_execution_info= \
316 2> "$TEST_log" | grep ActionKey > key1 || fail "Expected success"
317
318 bazel aquery "mnemonic(TestRunner,//$pkg:test)" --output=text \
319 --modify_execution_info=TestRunner=+requires-x \
320 2> "$TEST_log" | grep ActionKey > key2 || fail "Expected success"
321
322 assert_not_equals "$(cat key1)" "$(cat key2)"
323}
324
Googlerfff72a72018-08-30 17:42:10 -0700325run_suite "Integration tests of the --modify_execution_info option."