aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorLászló Csomor <laszlocsomor@users.noreply.github.com>2019-03-19 07:52:56 +0100
committerGitHub <noreply@github.com>2019-03-19 07:52:56 +0100
commit2d1669ed882652e5fc695bb99c77442a9273ff56 (patch)
tree8ce783e1fb9a63e86e73abbba0246de5fbe99bd3 /tests
parentdb27394846f9beda839c10fa1e37a00a2a193235 (diff)
downloadbazel-skylib-2d1669ed882652e5fc695bb99c77442a9273ff56.tar.gz
write_file: add rule and tests (#122)
This PR adds two new rules: write_file and write_xfile. Both rules solve a common problem: to write a text file with user-defined contents. The problem is routinely solved using a genrule. That however requires Bash, since genrules execute Bash commands. Requiring Bash is a problem on Windows. The new rules do not require any shell. The only difference between the rules is that write_xfile creates an executable file while write_file doesn't. See https://github.com/bazelbuild/bazel/issues/4319
Diffstat (limited to 'tests')
-rw-r--r--tests/write_file/BUILD117
-rwxr-xr-xtests/write_file/write_file_tests.sh66
2 files changed, 183 insertions, 0 deletions
diff --git a/tests/write_file/BUILD b/tests/write_file/BUILD
new file mode 100644
index 0000000..52d7992
--- /dev/null
+++ b/tests/write_file/BUILD
@@ -0,0 +1,117 @@
+# This package aids testing the 'write_file' rule.
+#
+# The package contains 4 write_file rules:
+# - 'write_empty_text' and 'write_empty_bin' write an empty text and an empty
+# executable file respectively
+# - 'write_nonempty_text' and 'write_nonempty_bin' write a non-empty text and
+# a non-empty executable file (a shell script) respectively
+#
+# The 'bin_empty' and 'bin_nonempty' rules are sh_binary rules. They use
+# the 'write_empty_bin' and 'write_nonempty_bin' rules respectively. The
+# sh_binary rule requires its source to be executable, so building these two
+# rules successfully means that 'write_file' managed to make its output
+# executable.
+#
+# The 'run_executables' genrule runs the 'bin_empty' and 'bin_nonempty'
+# binaries, partly to ensure they can be run, and partly so we can observe their
+# output and assert the contents in the 'write_file_tests' test.
+#
+# The 'file_deps' filegroup depends on 'write_empty_text'. The filegroup rule
+# uses the DefaultInfo.files field from its dependencies. When we data-depend on
+# the filegroup from 'write_file_tests', we transitively data-depend on the
+# DefaultInfo.files of the 'write_empty_text' rule.
+#
+# The 'write_file_tests' test is the actual integration test. It data-depends
+# on:
+# - the 'run_executables' rule, to get the outputs of 'bin_empty' and
+# 'bin_nonempty'
+# - the 'file_deps' rule, and by nature of using a filegroup, we get the files
+# from the DefaultInfo.files of the 'write_file' rule, and thereby assert that
+# that field contains the output file of the rule
+# - the 'write_nonempty_text' rule, and thereby on the DefaultInfo.runfiles
+# field of it, so we assert that that field contains the output file of the
+# rule
+
+load("//rules:write_file.bzl", "write_file")
+
+package(default_testonly = 1)
+
+sh_test(
+ name = "write_file_tests",
+ srcs = ["write_file_tests.sh"],
+ data = [
+ ":run_executables",
+ # Use DefaultInfo.files from 'write_empty_text' (via 'file_deps').
+ ":file_deps",
+ # Use DefaultInfo.runfiles from 'write_nonempty_text'.
+ ":write_nonempty_text",
+ "//tests:unittest.bash",
+ ],
+ deps = ["@bazel_tools//tools/bash/runfiles"],
+)
+
+filegroup(
+ name = "file_deps",
+ # Use DefaultInfo.files from 'write_empty_text'.
+ srcs = [":write_empty_text"],
+)
+
+# If 'run_executables' is built, then 'bin_nonempty' and 'bin_empty' are
+# executable, asserting that write_file makes the output executable.
+genrule(
+ name = "run_executables",
+ outs = [
+ "empty-bin-out.txt",
+ "nonempty-bin-out.txt",
+ ],
+ cmd = ("$(location :bin_empty) > $(location empty-bin-out.txt) && " +
+ "$(location :bin_nonempty) > $(location nonempty-bin-out.txt)"),
+ output_to_bindir = 1,
+ tools = [
+ ":bin_empty",
+ ":bin_nonempty",
+ ],
+)
+
+# If 'bin_empty' is built, then 'write_empty_bin' made its output executable.
+sh_binary(
+ name = "bin_empty",
+ srcs = [":write_empty_bin"],
+)
+
+# If 'bin_nonempty' is built, then 'write_nonempty_bin' made its output
+# executable.
+sh_binary(
+ name = "bin_nonempty",
+ srcs = [":write_nonempty_bin"],
+)
+
+write_file(
+ name = "write_empty_text",
+ out = "out/empty.txt",
+)
+
+write_file(
+ name = "write_nonempty_text",
+ out = "out/nonempty.txt",
+ content = [
+ "aaa",
+ "bbb",
+ ],
+)
+
+write_file(
+ name = "write_empty_bin",
+ out = "out/empty.sh",
+ is_executable = True,
+)
+
+write_file(
+ name = "write_nonempty_bin",
+ out = "out/nonempty.sh",
+ content = [
+ "#!/bin/bash",
+ "echo potato",
+ ],
+ is_executable = True,
+)
diff --git a/tests/write_file/write_file_tests.sh b/tests/write_file/write_file_tests.sh
new file mode 100755
index 0000000..2464230
--- /dev/null
+++ b/tests/write_file/write_file_tests.sh
@@ -0,0 +1,66 @@
+# 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.
+
+# --- begin runfiles.bash initialization ---
+# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
+set -euo pipefail
+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 bazel_skylib/tests/unittest.bash)" \
+ || { echo "Could not source bazel_skylib/tests/unittest.bash" >&2; exit 1; }
+
+function assert_empty_file() {
+ local -r path="$1"
+ # Not using 'du' to check the file is empty, because it doesn't work on CI.
+ [[ "$(echo -n "($(cat "$path"))")" = "()" ]]
+}
+
+function test_write_empty_text() {
+ assert_empty_file "$(rlocation bazel_skylib/tests/write_file/out/empty.txt)"
+}
+
+function test_write_nonempty_text() {
+ cat "$(rlocation bazel_skylib/tests/write_file/out/nonempty.txt)" >"$TEST_log"
+ expect_log '^aaa$'
+ expect_log '^bbb$'
+}
+
+function test_write_empty_bin() {
+ assert_empty_file "$(rlocation bazel_skylib/tests/write_file/empty-bin-out.txt)"
+}
+
+function test_write_nonempty_bin() {
+ cat "$(rlocation bazel_skylib/tests/write_file/nonempty-bin-out.txt)" >"$TEST_log"
+ expect_log '^potato$'
+}
+
+run_suite "write_file_tests test suite"