aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLászló Csomor <laszlocsomor@users.noreply.github.com>2019-05-21 14:46:09 +0200
committerGitHub <noreply@github.com>2019-05-21 14:46:09 +0200
commitbf8a55b6687fc93c003d07505d886bbd1a7ff39a (patch)
tree482111c3e6f6234583b5851b46ce1eacc885d2e4 /tests
parentc5852220719bc29fdb256612adc4adde26b30b6c (diff)
downloadbazel-skylib-bf8a55b6687fc93c003d07505d886bbd1a7ff39a.tar.gz
run_binary: runs an executable as an action (#153)
This rule is an alternative for genrule(): it can run a binary with the desired arguments, environment, inputs, and outputs, as a single build action, without shelling out to Bash. Fixes https://github.com/bazelbuild/bazel-skylib/issues/149
Diffstat (limited to 'tests')
-rw-r--r--tests/run_binary/BUILD166
-rw-r--r--tests/run_binary/printargs.cc36
2 files changed, 202 insertions, 0 deletions
diff --git a/tests/run_binary/BUILD b/tests/run_binary/BUILD
new file mode 100644
index 0000000..d780f60
--- /dev/null
+++ b/tests/run_binary/BUILD
@@ -0,0 +1,166 @@
+load("//rules:diff_test.bzl", "diff_test")
+load("//rules:run_binary.bzl", "run_binary")
+load("//rules:write_file.bzl", "write_file")
+
+package(
+ default_testonly = 1,
+ default_visibility = ["//visibility:private"],
+)
+
+diff_test(
+ name = "run_script_test",
+ file1 = ":run_script.out",
+ file2 = ":run_script_expected",
+)
+
+# Generate this file with write_file instead of checking it in to the source
+# tree. This ensures line endings are consistent across "run_script.expected"
+# and "run_script.out".
+write_file(
+ name = "run_script_expected",
+ out = "run_script.expected",
+ content = [
+ "arg1=(foo)",
+ "arg2=(bar)",
+ "ENV_LOCATION=(a tests/run_binary/BUILD)",
+ "ENV_LOCATIONS=(b\\ tests/run_binary/BUILD tests/run_binary/printargs.cc)",
+ "ENV_COMPLEX=(xx/yy \\\"zz)",
+ "ENV_PATH_BASH=($PATH)",
+ "ENV_PATH_CMD=(%PATH%)",
+ # Can't prevent "echo" from adding a newline on Windows, so let's add
+ # one to the expected output too.
+ "",
+ ],
+)
+
+run_binary(
+ name = "run_script",
+ srcs = [
+ "BUILD",
+ ":dummy_srcs",
+ ],
+ outs = ["run_script.out"],
+ # Not testing any complex arguments here, because Windows .bat file argument
+ # escaping is different from most MSVC-built Windows binaries. We test
+ # argument escaping in "run_bin".
+ args = [
+ "foo",
+ "bar",
+ ],
+ # Test complex environment variables. They are location-expanded but not
+ # Bash-tokenized, and should appear the same for Windows .bat files and Bash
+ # .sh scripts.
+ env = {
+ # Testing $(location) expansion only on source files so the result is
+ # predictable. The path of generated files depends on the target
+ # platform.
+ "ENV_LOCATION": "a $(location BUILD)",
+ "ENV_LOCATIONS": "b\\ $(locations :dummy_srcs)",
+ "ENV_COMPLEX": "xx/yy \\\"zz",
+ "ENV_PATH_BASH": "$PATH",
+ "ENV_PATH_CMD": "%PATH%",
+ "OUT": "$(location run_script.out)",
+ },
+ tool = ":script",
+)
+
+write_file(
+ name = "script",
+ # On Windows we need the ".bat" extension.
+ # On other platforms the extension doesn't matter.
+ # Therefore we can use ".bat" on every platform.
+ out = "script.bat",
+ content = select({
+ "@bazel_tools//src/conditions:host_windows": [
+ "@echo>%OUT% arg1=(%1)",
+ "@echo>>%OUT% arg2=(%2)",
+ "@echo>>%OUT% ENV_LOCATION=(%ENV_LOCATION%)",
+ "@echo>>%OUT% ENV_LOCATIONS=(%ENV_LOCATIONS%)",
+ "@echo>>%OUT% ENV_COMPLEX=(%ENV_COMPLEX%)",
+ "@echo>>%OUT% ENV_PATH_BASH=(%ENV_PATH_BASH%)",
+ "@echo>>%OUT% ENV_PATH_CMD=(%ENV_PATH_CMD%)",
+ ],
+ "//conditions:default": [
+ "#!/bin/bash",
+ "echo > \"$OUT\" \"arg1=($1)\"",
+ "echo >> \"$OUT\" \"arg2=($2)\"",
+ "echo >> \"$OUT\" \"ENV_LOCATION=($ENV_LOCATION)\"",
+ "echo >> \"$OUT\" \"ENV_LOCATIONS=($ENV_LOCATIONS)\"",
+ "echo >> \"$OUT\" \"ENV_COMPLEX=($ENV_COMPLEX)\"",
+ "echo >> \"$OUT\" \"ENV_PATH_BASH=($ENV_PATH_BASH)\"",
+ "echo >> \"$OUT\" \"ENV_PATH_CMD=($ENV_PATH_CMD)\"",
+ ],
+ }),
+ is_executable = True,
+)
+
+diff_test(
+ name = "run_bin_test",
+ file1 = ":run_bin.out",
+ file2 = ":run_bin_expected",
+)
+
+# Generate this file with write_file instead of checking it in to the source
+# tree. This ensures line endings are consistent across "run_bin.expected"
+# and "run_bin.out".
+write_file(
+ name = "run_bin_expected",
+ out = "run_bin.expected",
+ content = [
+ "arg1=(a b)",
+ "arg2=(\"c d\")",
+ "arg3=(e\\ f)",
+ "arg4=(xx/yy\\ \\\"zz)",
+ "arg5=(tests/run_binary/BUILD)",
+ "arg6=(tests/run_binary/BUILD tests/run_binary/printargs.cc)",
+ "arg7=('tests/run_binary/BUILD $tests/run_binary/BUILD')",
+ "arg8=($PATH)",
+ "arg9=($$PATH)",
+ "arg10=(${PATH})",
+ # Add trailing newline, as printed by printargs.
+ "",
+ ],
+)
+
+run_binary(
+ name = "run_bin",
+ srcs = [
+ "BUILD",
+ ":dummy_srcs",
+ ],
+ outs = ["run_bin.out"],
+ # Test complex arguments here. They are location-expanded but not
+ # Bash-tokenized, and should appear the same on every platform.
+ args = [
+ "a b",
+ "\"c d\"",
+ "e\\ f",
+ "xx/yy\\ \\\"zz",
+ # Testing $(location) expansion only on source files so the result is
+ # predictable. The path of generated files depends on the target
+ # platform.
+ "$(location BUILD)",
+ "$(locations :dummy_srcs)",
+ "'$(location BUILD) $$(location BUILD)'",
+ "$PATH",
+ "$$PATH",
+ "${PATH}",
+ ],
+ # Not testing any complex envvars here, because we already did in
+ # "run_script".
+ env = {"OUT": "$(location run_bin.out)"},
+ tool = ":printargs",
+)
+
+filegroup(
+ name = "dummy_srcs",
+ srcs = [
+ "BUILD",
+ "printargs.cc",
+ ],
+)
+
+cc_binary(
+ name = "printargs",
+ srcs = ["printargs.cc"],
+)
diff --git a/tests/run_binary/printargs.cc b/tests/run_binary/printargs.cc
new file mode 100644
index 0000000..64eedf2
--- /dev/null
+++ b/tests/run_binary/printargs.cc
@@ -0,0 +1,36 @@
+// Copyright 2019 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.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, char** argv) {
+ char* out_path = getenv("OUT");
+ if (!out_path || !*out_path) {
+ fprintf(stderr, "ERROR(" __FILE__ ":%d): envvar OUT is undefined\n",
+ __LINE__);
+ return 1;
+ }
+ FILE* f = fopen(out_path, "wt");
+ if (!f) {
+ fprintf(stderr, "ERROR(" __FILE__ ":%d): could not open output file '%s'\n",
+ __LINE__, out_path);
+ return 1;
+ }
+ for (int i = 1; i < argc; ++i) {
+ fprintf(f, "arg%d=(%s)\n", i, argv[i]);
+ }
+ fclose(f);
+ return 0;
+}