diff --git a/site/docs/creating-workers.md b/site/docs/creating-workers.md index 26539295032e5e..0d7d8e154e3583 100644 --- a/site/docs/creating-workers.md +++ b/site/docs/creating-workers.md @@ -167,12 +167,13 @@ level of the build, this might be the attribute definition: "worker": attr.label( default = Label("//work:worker"), executable = True, - cfg = "host", + cfg = "exec", ) ``` -`cfg = "host"` indicates that the worker should be built to run on your host -platform. +`cfg = "exec"` indicates that the worker should be built to run on your +execution platform rather than on the target platform (i.e., the worker is used +as tool during the build). ### Work action requirements diff --git a/site/docs/skylark/aspects.md b/site/docs/skylark/aspects.md index 55ad41547e4f7b..486a5b4eb5f0e7 100644 --- a/site/docs/skylark/aspects.md +++ b/site/docs/skylark/aspects.md @@ -281,7 +281,7 @@ demonstrates how you could pass in a tool to an aspect: '_protoc' : attr.label( default = Label('//tools:protoc'), executable = True, - cfg = "host" + cfg = "exec" ) } ... diff --git a/src/embedded_tools.bzl b/src/embedded_tools.bzl index 3abe906b49c93c..a139b872665e45 100644 --- a/src/embedded_tools.bzl +++ b/src/embedded_tools.bzl @@ -35,7 +35,7 @@ embedded_tools = rule( "out": attr.output(mandatory = True), "tool": attr.label( executable = True, - cfg = "host", + cfg = "exec", allow_files = True, default = Label("//src:create_embedded_tools_sh"), ), diff --git a/src/main/res/winsdk_toolchain.bzl b/src/main/res/winsdk_toolchain.bzl index fa2a9560fe27fd..7a9217d455a021 100644 --- a/src/main/res/winsdk_toolchain.bzl +++ b/src/main/res/winsdk_toolchain.bzl @@ -62,7 +62,7 @@ windows_resource_compiler_toolchain = rule( "rc_exe": attr.label( allow_files = True, executable = True, - cfg = "host", + cfg = "exec", doc = "Label of the resource compiler (or a wrapper script)", ), }, diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/function_wrap_multiple_lines_test/input.bzl b/src/test/java/com/google/devtools/build/skydoc/testdata/function_wrap_multiple_lines_test/input.bzl index bdb2a08d5bebf9..1991ec3de6dd5f 100644 --- a/src/test/java/com/google/devtools/build/skydoc/testdata/function_wrap_multiple_lines_test/input.bzl +++ b/src/test/java/com/google/devtools/build/skydoc/testdata/function_wrap_multiple_lines_test/input.bzl @@ -47,7 +47,7 @@ dependencies here. "Xwatchconversion": attr.bool(default = False, doc = "Don't delete temporary lexers generated from combined grammars."), "_tool": attr.label( executable = True, - cfg = "host", + cfg = "exec", ), }, ) diff --git a/src/test/java/com/google/devtools/build/skydoc/testdata/misc_apis_test/input.bzl b/src/test/java/com/google/devtools/build/skydoc/testdata/misc_apis_test/input.bzl index 86dea8b4268d88..c0e602e6c9e045 100644 --- a/src/test/java/com/google/devtools/build/skydoc/testdata/misc_apis_test/input.bzl +++ b/src/test/java/com/google/devtools/build/skydoc/testdata/misc_apis_test/input.bzl @@ -44,7 +44,7 @@ A list of dependencies. doc = "The location of the tool to use.", allow_files = True, default = Label("//foo/bar/baz:target"), - cfg = "host", + cfg = "exec", executable = True, ), "out": attr.output( diff --git a/src/test/py/bazel/bazel_windows_cpp_test.py b/src/test/py/bazel/bazel_windows_cpp_test.py index 95f1280cfa9f7a..0b1d5fd6521354 100644 --- a/src/test/py/bazel/bazel_windows_cpp_test.py +++ b/src/test/py/bazel/bazel_windows_cpp_test.py @@ -861,7 +861,7 @@ def testCcCompileWithTreeArtifactAsSource(self): ' attrs = {', ' "_tool": attr.label(', ' executable = True,', - ' cfg = "host",', + ' cfg = "exec",', ' allow_files = True,', ' default = Label("//:genccs"),', ' )', diff --git a/src/test/py/bazel/bazel_windows_test.py b/src/test/py/bazel/bazel_windows_test.py index b102bbba96b91e..126ecffcba54fa 100644 --- a/src/test/py/bazel/bazel_windows_test.py +++ b/src/test/py/bazel/bazel_windows_test.py @@ -177,7 +177,7 @@ def testRunPowershellInAction(self): ' "out": attr.output(mandatory = True),', ' "tool": attr.label(', ' executable = True,', - ' cfg = "host",', + ' cfg = "exec",', ' allow_files = True,', ' default = Label("//:write.bat"),', ' ),', diff --git a/src/test/py/bazel/native_test.bzl b/src/test/py/bazel/native_test.bzl index 4b087cbdf09295..20e5dce70b7911 100644 --- a/src/test/py/bazel/native_test.bzl +++ b/src/test/py/bazel/native_test.bzl @@ -68,7 +68,7 @@ exe_test = rule( attrs = { "src": attr.label( allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, ), }, diff --git a/src/test/shell/bazel/apple/apple_common.sh b/src/test/shell/bazel/apple/apple_common.sh new file mode 100644 index 00000000000000..0207023a070fb2 --- /dev/null +++ b/src/test/shell/bazel/apple/apple_common.sh @@ -0,0 +1,203 @@ +#!/bin/bash +# +# Copyright 2022 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Common Bash functions to test Apple rules in Bazel. +# + +function make_starlark_apple_binary_rule_in() { + local dir="$1"; shift + + # All of the attributes below, except for `stamp`, are required as part of the + # implied contract of `apple_common.link_multi_arch_binary` since it asks for + # attributes directly from the rule context. As these requirements are changed + # from implied attributes to function arguments, they can be removed. + cat >> "${dir}/starlark_apple_binary.bzl" < 1: + apple_env = {} + xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig] + apple_env.update(apple_common.apple_host_system_env(xcode_config)) + apple_env.update( + apple_common.target_apple_env( + xcode_config, + ctx.fragments.apple.single_arch_platform, + ), + ) + args = ctx.actions.args() + args.add('-create') + args.add_all(lipo_inputs) + args.add('-output', processed_binary) + ctx.actions.run( + arguments = [args], + env = apple_env, + executable = '/usr/bin/lipo', + execution_requirements = xcode_config.execution_info(), + inputs = lipo_inputs, + outputs = [processed_binary], + ) + else: + ctx.actions.symlink( + target_file = lipo_inputs[0], + output = processed_binary, + ) + return [ + DefaultInfo(files = depset([processed_binary])), + OutputGroupInfo(**link_result.output_groups), + link_result.debug_outputs_provider, + ] + +starlark_apple_binary = rule( + attrs = { + "_child_configuration_dummy": attr.label( + cfg = apple_common.multi_arch_split, + default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), + ), + "_xcode_config": attr.label( + default = configuration_field( + fragment = "apple", + name = "xcode_config_label", + ), + ), + "_xcrunwrapper": attr.label( + cfg = "exec", + default = Label("@bazel_tools//tools/objc:xcrunwrapper"), + executable = True, + ), + "binary_type": attr.string(default = "executable"), + "bundle_loader": attr.label(), + "deps": attr.label_list( + cfg = apple_common.multi_arch_split, + ), + "dylibs": attr.label_list(), + "linkopts": attr.string_list(), + "minimum_os_version": attr.string(), + "platform_type": attr.string(), + "stamp": attr.int(default = -1, values = [-1, 0, 1]), + }, + fragments = ["apple", "objc", "cpp"], + implementation = _starlark_apple_binary_impl, + outputs = { + # Provided for compatibility with apple_binary tests only. + "lipobin": "%{name}_lipobin", + }, +) +EOF +} + +function make_starlark_apple_static_library_rule_in() { + local dir="$1"; shift + + # All of the attributes below are required as part of the implied contract of + # `apple_common.link_multi_arch_static_library` since it asks for attributes + # directly from the rule context. As these requirements are changed from + # implied attributes to function arguments, they can be removed. + cat >> "${dir}/starlark_apple_static_library.bzl" < 1: + apple_env = {} + xcode_config = ctx.attr._xcode_config[apple_common.XcodeVersionConfig] + apple_env.update(apple_common.apple_host_system_env(xcode_config)) + apple_env.update( + apple_common.target_apple_env( + xcode_config, + ctx.fragments.apple.single_arch_platform, + ), + ) + args = ctx.actions.args() + args.add('-create') + args.add_all(lipo_inputs) + args.add('-output', processed_library) + ctx.actions.run( + arguments = [args], + env = apple_env, + executable = '/usr/bin/lipo', + execution_requirements = xcode_config.execution_info(), + inputs = lipo_inputs, + outputs = [processed_library], + ) + else: + ctx.actions.symlink( + target_file = lipo_inputs[0], + output = processed_library, + ) + providers = [ + DefaultInfo(files = depset(files_to_build), runfiles = runfiles), + link_result.objc, + link_result.output_groups, + ] + return providers + +starlark_apple_static_library = rule( + _starlark_apple_static_library_impl, + attrs = { + '_child_configuration_dummy': attr.label( + cfg = apple_common.multi_arch_split, + default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), + ), + '_xcode_config': attr.label( + default = configuration_field( + fragment = "apple", + name = "xcode_config_label", + ), + ), + '_xcrunwrapper': attr.label( + executable = True, + cfg = 'exec', + default = Label("@bazel_tools//tools/objc:xcrunwrapper"), + ), + 'additional_linker_inputs': attr.label_list( + allow_files = True, + ), + 'avoid_deps': attr.label_list( + cfg = apple_common.multi_arch_split, + default = [], + ), + 'deps': attr.label_list( + cfg = apple_common.multi_arch_split, + ), + 'linkopts': attr.string_list(), + 'platform_type': attr.string(), + 'minimum_os_version': attr.string(), + }, + outputs = { + 'lipo_archive': '%{name}_lipo.a', + }, + cfg = apple_common.apple_crosstool_transition, + fragments = ['apple', 'objc', 'cpp',], +) +EOF +} diff --git a/src/test/shell/bazel/bazel_rules_test.sh b/src/test/shell/bazel/bazel_rules_test.sh index 5807d4fd45085e..f4d69224e261e4 100755 --- a/src/test/shell/bazel/bazel_rules_test.sh +++ b/src/test/shell/bazel/bazel_rules_test.sh @@ -583,7 +583,7 @@ out_rule = rule(_out_rule, attrs = { "_hello_bin": attr.label( default = ":hello_bin", executable = True, - cfg = "host", + cfg = "exec", ), }) EOF diff --git a/src/test/shell/bazel/cc_integration_test.sh b/src/test/shell/bazel/cc_integration_test.sh index db4fbb46f965e5..b86d97c8a0e06d 100755 --- a/src/test/shell/bazel/cc_integration_test.sh +++ b/src/test/shell/bazel/cc_integration_test.sh @@ -700,11 +700,11 @@ def _tree_art_impl(ctx): tree_art_rule = rule(implementation = _tree_art_impl, attrs = { "_makes_tree" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//${package}:makes_tree_artifacts.sh"), "_write" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//${package}:write.sh")}) diff --git a/src/test/shell/bazel/remote/build_without_the_bytes_test.sh b/src/test/shell/bazel/remote/build_without_the_bytes_test.sh new file mode 100755 index 00000000000000..6257b3b557375f --- /dev/null +++ b/src/test/shell/bazel/remote/build_without_the_bytes_test.sh @@ -0,0 +1,1414 @@ +#!/bin/bash +# +# Copyright 2016 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Tests build without the bytes. + +set -euo pipefail + +# --- begin runfiles.bash initialization --- +if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then + if [[ -f "$0.runfiles_manifest" ]]; then + export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest" + elif [[ -f "$0.runfiles/MANIFEST" ]]; then + export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST" + elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then + export RUNFILES_DIR="$0.runfiles" + fi +fi +if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then + source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash" +elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then + source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \ + "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)" +else + echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash" + exit 1 +fi +# --- end runfiles.bash initialization --- + +source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \ + || { echo "integration_test_setup.sh not found!" >&2; exit 1; } +source "$(rlocation "io_bazel/src/test/shell/bazel/remote/remote_utils.sh")" \ + || { echo "remote_utils.sh not found!" >&2; exit 1; } + +function set_up() { + start_worker +} + +function tear_down() { + bazel clean >& $TEST_log + stop_worker +} + +case "$(uname -s | tr [:upper:] [:lower:])" in +msys*|mingw*|cygwin*) + declare -r is_windows=true + ;; +*) + declare -r is_windows=false + ;; +esac + +if "$is_windows"; then + export MSYS_NO_PATHCONV=1 + export MSYS2_ARG_CONV_EXCL="*" + declare -r EXE_EXT=".exe" +else + declare -r EXE_EXT="" +fi + +function test_cc_tree() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + mkdir -p a + cat > a/BUILD < a/tree.bzl <& "$TEST_log" \ + || fail "Failed to build //a:tree_cc with minimal downloads" +} + +function test_cc_include_scanning_and_minimal_downloads() { + cat > BUILD <<'EOF' +cc_binary( +name = 'bin', +srcs = ['bin.cc', ':header.h'], +) + +genrule( +name = 'gen', +outs = ['header.h'], +cmd = 'touch $@', +) +EOF + cat > bin.cc <& $TEST_log \ + || fail "Failed to populate remote cache" + bazel clean >& $TEST_log || fail "Failed to clean" + cat > bin.cc <& $TEST_log \ + || fail "Failed to build with --remote_download_minimal" +} + +function test_downloads_minimal() { + # Test that genrule outputs are not downloaded when using + # --remote_download_minimal + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) + +genrule( + name = "foobar", + srcs = [":foo"], + outs = ["foobar.txt"], + cmd = "cat $(location :foo) > \"$@\" && echo \"bar\" >> \"$@\"", +) +EOF + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:foobar || fail "Failed to build //a:foobar" + + (! [[ -f bazel-bin/a/foo.txt ]] && ! [[ -f bazel-bin/a/foobar.txt ]]) \ + || fail "Expected no files to have been downloaded" +} + +function test_downloads_minimal_failure() { + # Test that outputs of failing actions are downloaded when using + # --remote_download_minimal + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "fail", + srcs = [], + outs = ["fail.txt"], + cmd = "echo \"foo\" > \"$@\" && exit 1", +) +EOF + + bazel build \ + --spawn_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:fail && fail "Expected test failure" || true + + [[ -f bazel-bin/a/fail.txt ]] \ + || fail "Expected fail.txt of failing target //a:fail to be downloaded" +} + +function test_downloads_minimal_prefetch() { + # Test that when using --remote_download_minimal a remote-only output that's + # an input to a local action is downloaded lazily before executing the local action. + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "remote", + srcs = [], + outs = ["remote.txt"], + cmd = "echo -n \"remote\" > \"$@\"", +) + +genrule( + name = "local", + srcs = [":remote"], + outs = ["local.txt"], + cmd = "cat $(location :remote) > \"$@\" && echo -n \"local\" >> \"$@\"", + tags = ["no-remote"], +) +EOF + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:remote || fail "Failed to build //a:remote" + + (! [[ -f bazel-bin/a/remote.txt ]]) \ + || fail "Expected bazel-bin/a/remote.txt to have not been downloaded" + + bazel build \ + --genrule_strategy=remote,local \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:local || fail "Failed to build //a:local" + + localtxt="bazel-bin/a/local.txt" + [[ $(< ${localtxt}) == "remotelocal" ]] \ + || fail "Unexpected contents in " ${localtxt} ": " $(< ${localtxt}) + + [[ -f bazel-bin/a/remote.txt ]] \ + || fail "Expected bazel-bin/a/remote.txt to be downloaded" +} + +function test_download_outputs_invalidation() { + # Test that when changing values of --remote_download_minimal all actions are + # invalidated. + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "remote", + srcs = [], + outs = ["remote.txt"], + cmd = "echo -n \"remote\" > \"$@\"", +) +EOF + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:remote >& $TEST_log || fail "Failed to build //a:remote" + + expect_log "2 processes: 1 internal, 1 remote" + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_outputs=all \ + //a:remote >& $TEST_log || fail "Failed to build //a:remote" + + # Changing --remote_download_outputs to "all" should invalidate SkyFrames in-memory + # caching and make it re-run the action. + expect_log "2 processes: 1 remote cache hit, 1 internal" +} + +function test_downloads_minimal_native_prefetch() { + # Test that when using --remote_download_outputs=minimal a remotely stored output + # that's an input to a native action (ctx.actions.expand_template) is staged lazily for action + # execution. + mkdir -p a + cat > a/substitute_username.bzl <<'EOF' +def _substitute_username_impl(ctx): + ctx.actions.expand_template( + template = ctx.file.template, + output = ctx.outputs.out, + substitutions = { + "{USERNAME}": ctx.attr.username, + }, + ) + +substitute_username = rule( + implementation = _substitute_username_impl, + attrs = { + "username": attr.string(mandatory = True), + "template": attr.label( + allow_single_file = True, + mandatory = True, + ), + }, + outputs = {"out": "%{name}.txt"}, +) +EOF + + cat > a/BUILD <<'EOF' +load(":substitute_username.bzl", "substitute_username") +genrule( + name = "generate-template", + cmd = "echo -n \"Hello {USERNAME}!\" > $@", + outs = ["template.txt"], + srcs = [], +) + +substitute_username( + name = "substitute-buchgr", + username = "buchgr", + template = ":generate-template", +) +EOF + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:substitute-buchgr >& $TEST_log || fail "Failed to build //a:substitute-buchgr" + + # The genrule //a:generate-template should run remotely and //a:substitute-buchgr + # should be a native action running locally. + expect_log "3 processes: 2 internal, 1 remote" + + outtxt="bazel-bin/a/substitute-buchgr.txt" + [[ $(< ${outtxt}) == "Hello buchgr!" ]] \ + || fail "Unexpected contents in "${outtxt}":" $(< ${outtxt}) + + [[ -f bazel-bin/a/template.txt ]] \ + || fail "Expected bazel-bin/a/template.txt to be downloaded" +} + +function test_downloads_minimal_hit_action_cache() { + # Test that remote metadata is saved and action cache is hit across server restarts when using + # --remote_download_minimal + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) + +genrule( + name = "foobar", + srcs = [":foo"], + outs = ["foobar.txt"], + cmd = "cat $(location :foo) > \"$@\" && echo \"bar\" >> \"$@\"", +) +EOF + + bazel build \ + --experimental_ui_debug_all_events \ + --experimental_action_cache_store_output_metadata \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:foobar >& $TEST_log || fail "Failed to build //a:foobar" + + expect_log "START.*: \[.*\] Executing genrule //a:foobar" + + (! [[ -e bazel-bin/a/foo.txt ]] && ! [[ -e bazel-bin/a/foobar.txt ]]) \ + || fail "Expected no files to have been downloaded" + + assert_equals "" "$(ls bazel-bin/a)" + + bazel shutdown + + bazel build \ + --experimental_ui_debug_all_events \ + --experimental_action_cache_store_output_metadata \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:foobar >& $TEST_log || fail "Failed to build //a:foobar" + + expect_not_log "START.*: \[.*\] Executing genrule //a:foobar" +} + +function test_downloads_toplevel() { + # Test that when using --remote_download_outputs=toplevel only the output of the + # toplevel target is being downloaded. + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) + +genrule( + name = "foobar", + srcs = [":foo"], + outs = ["foobar.txt"], + cmd = "cat $(location :foo) > \"$@\" && echo \"bar\" >> \"$@\"", +) +EOF + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:foobar || fail "Failed to build //a:foobar" + + (! [[ -f bazel-bin/a/foo.txt ]]) \ + || fail "Expected intermediate output bazel-bin/a/foo.txt to not be downloaded" + + [[ -f bazel-bin/a/foobar.txt ]] \ + || fail "Expected toplevel output bazel-bin/a/foobar.txt to be downloaded" + + + # Delete the file to test that the action is re-run + rm -f bazel-bin/a/foobar.txt + + bazel build \ + --genrule_strategy=remote \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:foobar >& $TEST_log || fail "Failed to build //a:foobar" + + expect_log "2 processes: 1 remote cache hit, 1 internal" + + [[ -f bazel-bin/a/foobar.txt ]] \ + || fail "Expected toplevel output bazel-bin/a/foobar.txt to be re-downloaded" +} + +function test_downloads_toplevel_runfiles() { + # Test that --remote_download_toplevel fetches only the top level binaries + # and generated runfiles. + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + mkdir -p a + + cat > a/create_bar.tmpl <<'EOF' +#!/bin/sh +echo "bar runfiles" +exit 0 +EOF + + cat > a/foo.cc <<'EOF' +#include +int main() { std::cout << "foo" << std::endl; return 0; } +EOF + + cat > a/BUILD <<'EOF' +genrule( + name = "bar", + srcs = ["create_bar.tmpl"], + outs = ["create_bar.sh"], + cmd = "cat $(location create_bar.tmpl) > \"$@\"", +) + +cc_binary( + name = "foo", + srcs = ["foo.cc"], + data = [":bar"], +) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:foo || fail "Failed to build //a:foobar" + + [[ -f bazel-bin/a/foo${EXE_EXT} ]] \ + || fail "Expected toplevel output bazel-bin/a/foo${EXE_EXT} to be downloaded" + + [[ -f bazel-bin/a/create_bar.sh ]] \ + || fail "Expected runfile bazel-bin/a/create_bar.sh to be downloaded" +} + +# Test that --remote_download_toplevel fetches inputs to symlink actions. In +# particular, cc_binary links against a symlinked imported .so file, and only +# the symlink is in the runfiles. +function test_downloads_toplevel_symlinks() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + mkdir -p a + + cat > a/bar.cc <<'EOF' +int f() { + return 42; +} +EOF + + cat > a/foo.cc <<'EOF' +extern int f(); +int main() { return f() == 42 ? 0 : 1; } +EOF + + cat > a/BUILD <<'EOF' +cc_binary( + name = "foo", + srcs = ["foo.cc"], + deps = [":libbar_lib"], +) + +cc_import( + name = "libbar_lib", + shared_library = ":libbar.so", +) + +cc_binary( + name = "libbar.so", + srcs = ["bar.cc"], + linkshared = 1, + linkstatic = 1, +) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:foo || fail "Failed to build //a:foobar" + + ./bazel-bin/a/foo${EXE_EXT} || fail "bazel-bin/a/foo${EXE_EXT} failed to run" +} + +function test_symlink_outputs_not_allowed_with_minimial() { + mkdir -p a + cat > a/input.txt <<'EOF' +Input file +EOF + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = ["input.txt"], + outs = ["output.txt", "output_symlink"], + cmd = "cp $< $(location :output.txt) && ln -s output.txt $(location output_symlink)", +) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:foo >& $TEST_log && fail "Expected failure to build //a:foo" + expect_log "Symlinks in action outputs are not yet supported" +} + +# Regression test that --remote_download_toplevel does not crash when the +# top-level output is a tree artifact. +function test_downloads_toplevel_tree_artifact() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + mkdir -p a + + # We need the top-level output to be a tree artifact generated by a template + # action. This is one way to do that: generate a tree artifact of C++ source + # files, and then compile them with a cc_library / cc_binary rule. + # + # The default top-level output of a cc_binary is the final binary, which is + # not what we want. Instead, we use --output_groups=compilation_outputs to + # fetch the .o files as the top-level outputs. + + cat > a/gentree.bzl <<'EOF' +def _gentree(ctx): + out = ctx.actions.declare_directory("dir.cc") + ctx.actions.run_shell( + outputs = [out], + command = "mkdir -p %s && echo 'int main(int c, char** v){return 1;}' > %s/foo.cc" % + (out.path, out.path), + ) + return DefaultInfo(files = depset([out])) + +gentree = rule(implementation = _gentree) +EOF + + cat > a/BUILD <<'EOF' +load(":gentree.bzl", "gentree") +gentree(name = "tree") +cc_binary(name = "main", srcs = [":tree"]) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + --output_groups=compilation_outputs \ + //a:main || fail "Failed to build //a:main" +} + +function test_downloads_toplevel_src_runfiles() { + # Test that using --remote_download_toplevel with a non-generated (source) + # runfile dependency works. + mkdir -p a + cat > a/create_foo.sh <<'EOF' +#!/bin/sh +echo "foo runfiles" +exit 0 +EOF + chmod +x a/create_foo.sh + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = [], + tools = ["create_foo.sh"], + outs = ["foo.txt"], + cmd = "./$(location create_foo.sh) > \"$@\"", +) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:foo || fail "Failed to build //a:foobar" + + [[ -f bazel-bin/a/foo.txt ]] \ + || fail "Expected toplevel output bazel-bin/a/foo.txt to be downloaded" +} + +function test_download_toplevel_test_rule() { + # Test that when using --remote_download_toplevel with bazel test only + # the test.log and test.xml file are downloaded but not the test binary. + # However when building a test then the test binary should be downloaded. + + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + + mkdir -p a + cat > a/BUILD < a/test.cc < +int main() { std::cout << "Hello test!" << std::endl; return 0; } +EOF + + # When invoking bazel test only test.log and test.xml should be downloaded. + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:test >& $TEST_log || fail "Failed to test //a:test with remote execution" + + (! [[ -f bazel-bin/a/test ]]) \ + || fail "Expected test binary bazel-bin/a/test to not be downloaded" + + [[ -f bazel-testlogs/a/test/test.log ]] \ + || fail "Expected toplevel output bazel-testlogs/a/test/test.log to be downloaded" + + [[ -f bazel-testlogs/a/test/test.xml ]] \ + || fail "Expected toplevel output bazel-testlogs/a/test/test.log to be downloaded" + + bazel clean + + # When invoking bazel build the test binary should be downloaded. + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:test >& $TEST_log || fail "Failed to build //a:test with remote execution" + + ([[ -f bazel-bin/a/test ]]) \ + || fail "Expected test binary bazel-bin/a/test to be downloaded" +} + +function test_downloads_minimal_bep() { + # Test that when using --remote_download_minimal all URI's in the BEP + # are rewritten as bytestream://.. + mkdir -p a + cat > a/success.sh <<'EOF' +#!/bin/sh +exit 0 +EOF + chmod 755 a/success.sh + cat > a/BUILD <<'EOF' +sh_test( + name = "success_test", + srcs = ["success.sh"], +) + +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) +EOF + + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --build_event_text_file=$TEST_log \ + //a:foo //a:success_test || fail "Failed to test //a:foo //a:success_test" + + expect_not_log 'uri:.*file://' + expect_log "uri:.*bytestream://localhost" +} + +function test_bytestream_uri_prefix() { + # Test that when --remote_bytestream_uri_prefix is set, bytestream:// + # URIs do not contain the hostname that's part of --remote_executor. + # They should use a fixed value instead. + mkdir -p a + cat > a/success.sh <<'EOF' +#!/bin/sh +exit 0 +EOF + chmod 755 a/success.sh + cat > a/BUILD <<'EOF' +sh_test( + name = "success_test", + srcs = ["success.sh"], +) + +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) +EOF + + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --remote_bytestream_uri_prefix=example.com/my-instance-name \ + --build_event_text_file=$TEST_log \ + //a:foo //a:success_test || fail "Failed to test //a:foo //a:success_test" + + expect_not_log 'uri:.*file://' + expect_log "uri:.*bytestream://example.com/my-instance-name/blobs" +} + +# This test is derivative of test_bep_output_groups in +# build_event_stream_test.sh, which verifies that successful output groups' +# artifacts appear in BEP when a top-level target fails to build. +function test_downloads_minimal_bep_partially_failed_target() { + # Test that when using --remote_download_minimal all URI's in the BEP + # are rewritten as bytestream://.. *even when* a target fails to be built and + # some output groups within that target are successfully built. + mkdir -p outputgroups + cat > outputgroups/rules.bzl < outputgroups/BUILD < semifailingaspect.bzl <<'EOF' +def _semifailing_aspect_impl(target, ctx): + if not ctx.rule.attr.outs: + return struct(output_groups = {}) + bad_outputs = list() + good_outputs = list() + for out in ctx.rule.attr.outs: + if out.name[0] == "f": + aspect_out = ctx.actions.declare_file(out.name + ".aspect.bad") + bad_outputs.append(aspect_out) + cmd = "false" + else: + aspect_out = ctx.actions.declare_file(out.name + ".aspect.good") + good_outputs.append(aspect_out) + cmd = "echo %s > %s" % (out.name, aspect_out.path) + ctx.actions.run_shell( + inputs = [], + outputs = [aspect_out], + command = cmd, + ) + return [OutputGroupInfo(**{ + "bad-aspect-out": depset(bad_outputs), + "good-aspect-out": depset(good_outputs), + })] + +semifailing_aspect = aspect(implementation = _semifailing_aspect_impl) +EOF + mkdir -p semifailingpkg/ + cat > semifailingpkg/BUILD <<'EOF' +genrule( + name = "semifail", + outs = ["out1.txt", "out2.txt", "failingout1.txt"], + cmd = "for f in $(OUTS); do echo foo > $(RULEDIR)/$$f; done" +) +EOF + + # In semifailingaspect.bzl, the `semifailing_aspect` definition defines two + # output groups: good-aspect-out and bad-aspect-out. We expect the artifacts + # produced by good-aspect-out to have bytestream URIs in BEP. + bazel build //semifailingpkg:semifail \ + --remote_executor=grpc://localhost:${worker_port} \ + --keep_going \ + --remote_download_minimal \ + --build_event_text_file=$TEST_log \ + --aspects=semifailingaspect.bzl%semifailing_aspect \ + --output_groups=good-aspect-out,bad-aspect-out \ + && fail "expected failure" || true + + expect_not_log 'uri:.*file://' + expect_log "uri:.*bytestream://localhost" +} + +function test_downloads_minimal_stable_status() { + # Regression test for #8385 + + mkdir -p a + cat > a/BUILD <<'EOF' +genrule( + name = "foo", + srcs = [], + outs = ["foo.txt"], + cmd = "echo \"foo\" > \"$@\"", +) +EOF + +cat > status.sh << 'EOF' +#!/bin/sh +echo "STABLE_FOO 1" +EOF +chmod +x status.sh + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --workspace_status_command=status.sh \ + //a:foo || "Failed to build //a:foo" + +cat > status.sh << 'EOF' +#!/bin/sh +echo "STABLE_FOO 2" +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --workspace_status_command=status.sh \ + //a:foo || "Failed to build //a:foo" +} + +function test_testxml_download_toplevel() { + # Test that a test action generating its own test.xml file works with + # --remote_download_toplevel. + mkdir -p a + + cat > a/test.sh <<'EOF' +#!/bin/sh + +cat > "$XML_OUTPUT_FILE" < + + + + test_case succeeded. + + + +EOF2 +EOF + + chmod +x a/test.sh + + cat > a/BUILD < BUILD <<'EOF' +genrule( + name = 'g', + outs = ['out'], + cmd = "touch $@", +) +EOF + bazel build + mkdir $(bazel info bazel-genfiles)/out + touch $(bazel info bazel-genfiles)/out/f + bazel build \ + --remote_download_toplevel \ + --remote_executor=grpc://localhost:${worker_port} \ + //:g \ + || fail "should have worked" +} + +function test_prefetcher_change_permission() { + # test that prefetcher change permission for downloaded files and directories to 0555. + touch WORKSPACE + + cat > rules.bzl <<'EOF' +def _gen_output_dir_impl(ctx): + output_dir = ctx.actions.declare_directory(ctx.attr.outdir) + ctx.actions.run_shell( + outputs = [output_dir], + inputs = [], + command = """ + mkdir -p $1/sub + echo "Shuffle, duffle, muzzle, muff" > $1/sub/bar + """, + arguments = [output_dir.path], + ) + return DefaultInfo(files = depset(direct = [output_dir])) + +gen_output_dir = rule( + implementation = _gen_output_dir_impl, + attrs = { + "outdir": attr.string(mandatory = True), + }, +) +EOF + + cat > BUILD <<'EOF' +load("rules.bzl", "gen_output_dir") + +genrule( + name = "input-file", + srcs = [], + outs = ["file"], + cmd = "echo 'input' > $@", +) + +gen_output_dir( + name = "input-tree", + outdir = "tree", +) + +genrule( + name = "test", + srcs = [":input-file", ":input-tree"], + outs = ["out"], + cmd = "touch $@", + tags = ["no-remote"], +) +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //:test >& $TEST_log \ + || fail "Failed to build" + + ls -l bazel-bin/file >& $TEST_log + expect_log "-r-xr-xr-x" + + ls -ld bazel-bin/tree >& $TEST_log + expect_log "dr-xr-xr-x" + + ls -ld bazel-bin/tree/sub >& $TEST_log + expect_log "dr-xr-xr-x" + + ls -l bazel-bin/tree/sub/bar >& $TEST_log + expect_log "-r-xr-xr-x" +} + +function test_remote_cache_intermediate_outputs_toplevel() { + # test that remote cache is hit when intermediate output is not executable in remote download toplevel mode + touch WORKSPACE + cat > BUILD <<'EOF' +genrule( + name = "dep", + srcs = [], + outs = ["dep"], + cmd = "echo 'dep' > $@", +) + +genrule( + name = "test", + srcs = [":dep"], + outs = ["out"], + cmd = "cat $(SRCS) > $@", +) +EOF + + bazel build \ + --remote_cache=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //:test >& $TEST_log || fail "Failed to build //:test" + + bazel clean + + bazel build \ + --remote_cache=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //:test >& $TEST_log || fail "Failed to build //:test" + + expect_log "2 remote cache hit" +} + +function test_remote_download_toplevel_with_non_toplevel_unused_inputs_list() { + # Test that --remote_download_toplevel should download non-toplevel + # unused_inputs_list for starlark action. See #11732. + + touch WORKSPACE + + cat > test.bzl <<'EOF' +def _test_rule_impl(ctx): + inputs = ctx.files.inputs + output = ctx.outputs.out + unused_inputs_list = ctx.actions.declare_file(ctx.label.name + ".unused") + arguments = [] + arguments += [output.path] + arguments += [unused_inputs_list.path] + for input in inputs: + arguments += [input.path] + ctx.actions.run( + inputs = inputs, + outputs = [output, unused_inputs_list], + arguments = arguments, + executable = ctx.executable._executable, + unused_inputs_list = unused_inputs_list, + ) + +test_rule = rule( + implementation = _test_rule_impl, + attrs = { + "inputs": attr.label_list(allow_files = True), + "out": attr.output(), + "_executable": attr.label(executable = True, cfg = "exec", default = "//:exe"), + }, +) +EOF + + cat > BUILD <<'EOF' +load(":test.bzl", "test_rule") + +test_rule( + name = "test_non_toplevel", + inputs = ["1.txt", "2.txt"], + out = "3.txt", +) + +sh_binary( + name = "exe", + srcs = ["a.sh"], +) + +genrule( + name = "test", + srcs = [":test_non_toplevel"], + outs = ["4.txt"], + cmd = "cat $< > $@", +) +EOF + + cat > a.sh <<'EOF' +#!/bin/sh + +output="$1" +shift +unused="$1" +shift +inp0="$1" +shift + +cat "$inp0" > "$output" +echo "$1" > "$unused" +EOF + + chmod a+x a.sh + + touch 1.txt 2.txt + + CACHEDIR=$(mktemp -d) + + bazel build --disk_cache="$CACHEDIR" --remote_download_toplevel :test || fail "Failed to build :test" + + bazel clean || fail "Failed to clean" + + bazel build --disk_cache="$CACHEDIR" --remote_download_toplevel :test >& $TEST_log + + expect_log "INFO: Build completed successfully" +} + +# Test that when testing with --remote_download_minimal, Bazel doesn't +# regenerate the test.xml if the action actually produced it. See +# https://github.com/bazelbuild/bazel/issues/12554 +function test_remote_download_minimal_with_test_xml_generation() { + mkdir -p a + + cat > a/BUILD <<'EOF' +sh_test( + name = "test0", + srcs = ["test.sh"], +) + +java_test( + name = "test1", + srcs = ["JavaTest.java"], + test_class = "JavaTest", +) +EOF + + cat > a/test.sh <<'EOF' +#!/bin/bash +echo 'Hello' +EOF + chmod a+x a/test.sh + + cat > a/JavaTest.java <<'EOF' +import org.junit.Test; + +public class JavaTest { + @Test + public void test() {} +} +EOF + + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:test0 //a:test1 >& $TEST_log || fail "Failed to build" + + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:test0 >& $TEST_log || fail "Failed to test" + # 2 remote spawns: 1 for executing the test, 1 for generating the test.xml + expect_log "2 processes: 2 remote" + + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:test1 >& $TEST_log || fail "Failed to test" + # only 1 remote spawn: test.xml is generated by junit + expect_log "2 processes: 1 internal, 1 remote" +} + +function test_output_file_permission() { + # Test that permission of output files are always 0555 + + mkdir -p a + cat > a/BUILD <& $TEST_log || fail "Failed to build" + + ls -l bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" + + ls -l bazel-bin/a/foo >& $TEST_log + expect_log "-r-xr-xr-x" + + cat bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" + + bazel clean >& $TEST_log || fail "Failed to clean" + + # normal remote execution + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + //a:bar >& $TEST_log || fail "Failed to build" + + ls -l bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" + + ls -l bazel-bin/a/foo >& $TEST_log + expect_log "-r-xr-xr-x" + + cat bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" + + bazel clean >& $TEST_log || fail "Failed to clean" + + # build without bytes + bazel build \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:bar >& $TEST_log || fail "Failed to build" + + ls -l bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" + + ls -l bazel-bin/a/foo >& $TEST_log + expect_log "-r-xr-xr-x" + + cat bazel-bin/a/bar >& $TEST_log + expect_log "-r-xr-xr-x" +} + +function test_download_toplevel_when_turn_remote_cache_off() { + download_toplevel_when_turn_remote_cache_off +} + +function test_download_toplevel_when_turn_remote_cache_off_with_metadata() { + download_toplevel_when_turn_remote_cache_off --experimental_action_cache_store_output_metadata +} + +function download_toplevel_when_turn_remote_cache_off() { + # Test that BwtB doesn't cause build failure if remote cache is disabled in a following build. + # See https://github.com/bazelbuild/bazel/issues/13882. + + cat > .bazelrc < a/BUILD <<'EOF' +genrule( + name = "producer", + outs = ["a.txt", "b.txt"], + cmd = "touch $(OUTS)", +) +genrule( + name = "consumer", + outs = ["out.txt"], + srcs = [":b.txt", "in.txt"], + cmd = "cat $(SRCS) > $@", +) +EOF + echo 'foo' > a/in.txt + + # populate the cache + bazel build \ + --remote_cache=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + //a:consumer >& $TEST_log || fail "Failed to populate the cache" + + bazel clean >& $TEST_log || fail "Failed to clean" + + # download top level outputs + bazel build \ + --remote_cache=grpc://localhost:${worker_port} \ + --remote_download_toplevel \ + "$@" \ + //a:consumer >& $TEST_log || fail "Failed to download outputs" + [[ -f bazel-bin/a/a.txt ]] || [[ -f bazel-bin/a/b.txt ]] \ + && fail "Expected outputs of producer are not downloaded" + + # build without remote cache + echo 'bar' > a/in.txt + bazel build \ + --remote_download_toplevel \ + "$@" \ + //a:consumer >& $TEST_log || fail "Failed to build without remote cache" +} + +function test_download_top_level_remote_execution_after_local_fetches_inputs() { + if [[ "$PLATFORM" == "darwin" ]]; then + # TODO(b/37355380): This test is disabled due to RemoteWorker not supporting + # setting SDKROOT and DEVELOPER_DIR appropriately, as is required of + # action executors in order to select the appropriate Xcode toolchain. + return 0 + fi + mkdir a + cat > a/BUILD <<'EOF' +genrule(name="dep", srcs=["not_used"], outs=["dep.c"], cmd="touch $@") +cc_library(name="foo", srcs=["dep.c"]) +EOF + echo hello > a/not_used + bazel build \ + --experimental_ui_debug_all_events \ + --remote_executor=grpc://localhost:"${worker_port}" \ + --remote_download_toplevel \ + --genrule_strategy=local \ + //a:dep >& "${TEST_log}" || fail "Expected success" + expect_log "START.*: \[.*\] Executing genrule //a:dep" + + echo there > a/not_used + # Local compilation requires now remote dep.c to successfully download. + bazel build \ + --experimental_ui_debug_all_events \ + --remote_executor=grpc://localhost:"${worker_port}" \ + --remote_download_toplevel \ + --genrule_strategy=remote \ + --strategy=CppCompile=local \ + //a:foo >& "${TEST_log}" || fail "Expected success" + + expect_log "START.*: \[.*\] Executing genrule //a:dep" +} + +function test_remote_download_regex() { + mkdir -p a + + cat > a/BUILD <<'EOF' +java_library( + name = "lib", + srcs = ["Library.java"], +) +java_test( + name = "test", + srcs = ["JavaTest.java"], + test_class = "JavaTest", + deps = [":lib"], +) +EOF + + cat > a/Library.java <<'EOF' +public class Library { + public static boolean TEST = true; +} +EOF + + cat > a/JavaTest.java <<'EOF' +import org.junit.Assert; +import org.junit.Test; +public class JavaTest { + @Test + public void test() { Assert.assertTrue(Library.TEST); } +} +EOF + bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + //a:test >& $TEST_log || fail "Failed to build" + + [[ ! -e "bazel-bin/a/liblib.jar" ]] || fail "bazel-bin/a/liblib.jar shouldn't exist" + [[ ! -e "bazel-bin/a/liblib.jdeps" ]] || fail "bazel-bin/a/liblib.jdeps shouldn't exist" + + bazel clean && bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --experimental_remote_download_regex=".*" \ + //a:test >& $TEST_log || fail "Failed to build" + + [[ -e "bazel-bin/a/liblib.jar" ]] || fail "bazel-bin/a/liblib.jar file does not exist!" + [[ -e "bazel-bin/a/liblib.jdeps" ]] || fail "bazel-bin/a/liblib.jdeps file does not exist!" + + bazel clean && bazel test \ + --remote_executor=grpc://localhost:${worker_port} \ + --remote_download_minimal \ + --experimental_remote_download_regex=".*jar$" \ + //a:test >& $TEST_log || fail "Failed to build" + + [[ -e "bazel-bin/a/liblib.jar" ]] || fail "bazel-bin/a/liblib.jar file does not exist!" + [[ ! -e "bazel-bin/a/liblib.jdeps" ]] || fail "bazel-bin/a/liblib.jdeps shouldn't exist" +} + +run_suite "Build without the Bytes tests" diff --git a/src/test/shell/bazel/starlark_rule_test.sh b/src/test/shell/bazel/starlark_rule_test.sh index 0b6d81e57b364b..bdcdbeb16ba3a9 100755 --- a/src/test/shell/bazel/starlark_rule_test.sh +++ b/src/test/shell/bazel/starlark_rule_test.sh @@ -120,7 +120,7 @@ def _impl(ctx): foo = rule( implementation = _impl, attrs = { - "tool": attr.label(allow_single_file = True, executable = True, cfg = "host"), + "tool": attr.label(allow_single_file = True, executable = True, cfg = "exec"), "out": attr.output(mandatory = True), }, ) diff --git a/src/test/shell/integration/action_aspect_test.sh b/src/test/shell/integration/action_aspect_test.sh index 069c0fa5fbc507..a7a20dac99b980 100755 --- a/src/test/shell/integration/action_aspect_test.sh +++ b/src/test/shell/integration/action_aspect_test.sh @@ -110,11 +110,11 @@ def _actions_test_impl(target, ctx): tree_art_rule = rule(implementation = _tree_art_impl, attrs = { "_makes_tree" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//package:makes_tree_artifacts.sh"), "_write" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//package:write.sh")}) @@ -200,11 +200,11 @@ def _actions_test_impl(target, ctx): tree_art_rule = rule(implementation = _tree_art_impl, attrs = { "_makes_tree" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//package:makes_tree_artifacts.sh"), "_write" : attr.label(allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//package:write.sh")}) @@ -382,7 +382,7 @@ aspect_b = aspect( attrs = { "_write": attr.label( allow_single_file = True, - cfg = "host", + cfg = "exec", executable = True, default = "//${package}:write.sh") } diff --git a/src/test/shell/integration/py_args_escaping_test.sh b/src/test/shell/integration/py_args_escaping_test.sh index b4c91bef5f413c..e209c12da41b37 100755 --- a/src/test/shell/integration/py_args_escaping_test.sh +++ b/src/test/shell/integration/py_args_escaping_test.sh @@ -303,7 +303,7 @@ def _impl(ctx): run_host_configured = rule( implementation = _impl, attrs = { - "tool": attr.label(executable = True, cfg = "host"), + "tool": attr.label(executable = True, cfg = "exec"), "out": attr.output(), }, ) diff --git a/src/test/shell/integration/run_test.sh b/src/test/shell/integration/run_test.sh index ccf64d9fc00701..e41791009379f0 100755 --- a/src/test/shell/integration/run_test.sh +++ b/src/test/shell/integration/run_test.sh @@ -403,7 +403,7 @@ def _tool_impl(ctx): arguments = [f.path] ) return DefaultInfo(files = depset([f])) -my_tool_rule = rule(_tool_impl, attrs = { 'tool' : attr.label(executable = True, cfg = "host") }) +my_tool_rule = rule(_tool_impl, attrs = { 'tool' : attr.label(executable = True, cfg = "exec") }) EOF cat > a/BUILD <