blob: ed29252ec54c5d69514d47ba98b97336fdbbb6e1 [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
154 # proto_library requires this external workspace.
155 cat >> WORKSPACE << EOF
156new_local_repository(
157 name = "com_google_protobuf",
158 path = "$(dirname $(rlocation io_bazel/third_party/protobuf/3.6.1/BUILD))",
159 build_file = "$(rlocation io_bazel/third_party/protobuf/3.6.1/BUILD)",
160)
161EOF
162 fi
Googlerfff72a72018-08-30 17:42:10 -0700163 local pkg="${FUNCNAME[0]}"
164 mkdir -p "$pkg" || fail "mkdir -p $pkg"
165 echo "load('//$pkg:shell.bzl', 'skylark_shell')" > "$pkg/BUILD"
166 cat >> "$pkg/BUILD" <<'EOF'
167skylark_shell(
168 name = "shelly",
169 output = "ok.txt",
170)
171
172cc_binary(name="zero", srcs=["zero.cc"])
173
174sh_test(name="test_a", srcs=["a.sh"])
175
176java_library(name = "javalib", srcs = ["HelloWorld.java"])
177
178action_listener(
179 name = "al",
180 extra_actions = [":echo-filename"],
Benjamin Peterson804406f2018-10-11 08:39:35 -0700181 mnemonics = ["Javac"],
182 visibility = ["//visibility:public"],
Googlerfff72a72018-08-30 17:42:10 -0700183)
184
185extra_action(name = "echo-filename", cmd = "echo Hi \$(EXTRA_ACTION_FILE)")
186
187py_binary(name = "pybar", srcs=["pybar.py"],)
188
189proto_library(name = "proto", srcs=["foo.proto"])
190EOF
191 cat > "$pkg/shell.bzl" <<'EOF'
192def _impl(ctx):
193 ctx.actions.run_shell(
194 outputs = [ ctx.outputs.output ],
195 command = "touch %s" % ctx.outputs.output.path,
196 )
197
198skylark_shell = rule(
199 _impl,
200 attrs = {
201 "output": attr.output(mandatory=True),
202 }
203)
204EOF
205 cat > "$pkg/a.sh" <<'EOF'
206#!/bin/sh
207exit 0
208EOF
209 chmod 755 "$pkg/a.sh"
210 echo "int main(void) {}" > "$pkg/zero.cc"
211 echo "public class HelloWorld {}" > "$pkg/HelloWorld.java"
212 echo 'print("Hi")' > "$pkg/pybar.py"
213 echo 'syntax="proto2"; package foo;' > "$pkg/foo.proto"
214
215 bazel aquery --output=text "//$pkg:all" \
216 --experimental_action_listener=$pkg:al \
217 --modify_execution_info=\
218echo.*=+requires-extra-action,\
219.*Proto.*=+requires-proto,\
220CppCompile=+requires-cpp-compile,\
221CppLink=+requires-cpp-link,\
222TestRunner=+requires-test-runner,\
223Turbine=+requires-turbine,\
224JavaSourceJar=+requires-java-source-jar,\
225Javac=+requires-javac,\
226PyTinypar=+requires-py-tinypar,\
laurentlb47e88542019-07-01 09:29:04 -0700227Action=+requires-action \
Googlerfff72a72018-08-30 17:42:10 -0700228 > output 2> "$TEST_log" || fail "Expected success"
229
230 # There are sometimes other elements in ExecutionInfo, e.g. requires-darwin
231 # for obj-c, supports-workers for java. Since testing for these combinations
232 # would be brittle, irrelevant to the operation of the flag, and in some
233 # cases platform-dependent, we just search for the key itself, not the whole
234 # ExecutionInfo: {...} line.
laurentlb47e88542019-07-01 09:29:04 -0700235 assert_contains "requires-action: ''" output
Googlerfff72a72018-08-30 17:42:10 -0700236 assert_contains "requires-cpp-compile: ''" output
237 assert_contains "requires-cpp-link: ''" output
238 assert_contains "requires-extra-action: ''" output
239 assert_contains "requires-test-runner: ''" output
240 assert_contains "requires-javac: ''" output
241 assert_contains "requires-turbine: ''" output
242 assert_contains "requires-java-source-jar: ''" output
243 assert_contains "requires-proto: ''" output # GenProtoDescriptorSet should match
Benjamin Peterson804406f2018-10-11 08:39:35 -0700244 if [[ "$PRODUCT_NAME" != "bazel" ]]; then
245 # Python rules generate some cpp actions and local actions, but py-tinypar
246 # is the main unique-to-python rule which runs remotely for a py_binary.
247 assert_contains "requires-py-tinypar: ''" output
248 fi
Googlerfff72a72018-08-30 17:42:10 -0700249}
250
Googlercfe03182019-03-09 07:42:11 -0800251# Regression test for b/127874955. We use --output=textproto since --output=text
252# sorts the execution info.
253function test_modify_execution_info_deterministic_order() {
254 local pkg="${FUNCNAME[0]}"
255 mkdir -p "$pkg/x" "$pkg/y" || fail "mkdir failed"
256 touch "$pkg/BUILD"
257 cat > "$pkg/build_defs.bzl" <<'EOF' || fail "Couldn't cat"
258def _rule_x_impl(ctx):
259 output = ctx.outputs.out
260 ctx.actions.run_shell(
261 outputs = [output],
262 command = "touch %s" % output.path,
263 mnemonic = "RuleX",
264 execution_requirements = {"requires-x": ""},
265 )
266
267rule_x = rule(outputs = {"out": "%{name}.out"}, implementation = _rule_x_impl)
268
269def _rule_y_impl(ctx):
270 output = ctx.outputs.out
271 ctx.actions.run_shell(
272 outputs = [output],
273 command = "touch %s" % output.path,
274 mnemonic = "RuleY",
275 execution_requirements = {"requires-y": ""},
276 )
277
278rule_y = rule(outputs = {"out": "%{name}.out"}, implementation = _rule_y_impl)
279EOF
280 echo "load('//$pkg:build_defs.bzl', 'rule_x')" > "$pkg/x/BUILD"
281 echo 'rule_x(name = "x")' >> "$pkg/x/BUILD"
282 echo "load('//$pkg:build_defs.bzl', 'rule_y')" > "$pkg/y/BUILD"
283 echo 'rule_y(name = "y")' >> "$pkg/y/BUILD"
284
285 mod='Rule(X|Y)=+requires-x,Rule(X|Y)=+requires-y'
286
287 bazel aquery "//$pkg/x" --output=textproto --modify_execution_info="$mod" \
288 > output1 2> "$TEST_log" || fail "Expected success"
289
290 bazel shutdown >& "$TEST_log" || fail "Couldn't shutdown"
291
292 bazel aquery "//$pkg/y" --modify_execution_info="$mod" \
293 >& "$TEST_log" || fail "Expected success"
294
295 bazel aquery "//$pkg/x" --output=textproto --modify_execution_info="$mod" \
296 > output2 2> "$TEST_log" || fail "Expected success"
297
298 assert_equals "$(cat output1)" "$(cat output2)"
299}
300
Googlerab96caa2019-04-22 12:07:07 -0700301# Regression test for b/130762259.
302function test_modify_execution_info_changes_test_runner_cache_key() {
303 local pkg="${FUNCNAME[0]}"
304 mkdir -p "$pkg"
305 echo "sh_test(name = 'test', srcs = ['test.sh'])" > "$pkg/BUILD"
306 touch "$pkg/test.sh"
307
308 bazel aquery "mnemonic(TestRunner,//$pkg:test)" --output=text \
309 --modify_execution_info= \
310 2> "$TEST_log" | grep ActionKey > key1 || fail "Expected success"
311
312 bazel aquery "mnemonic(TestRunner,//$pkg:test)" --output=text \
313 --modify_execution_info=TestRunner=+requires-x \
314 2> "$TEST_log" | grep ActionKey > key2 || fail "Expected success"
315
316 assert_not_equals "$(cat key1)" "$(cat key2)"
317}
318
Googlerfff72a72018-08-30 17:42:10 -0700319run_suite "Integration tests of the --modify_execution_info option."