blob: 34fcd7f40d1b956399681d5a4f11b58d1ef83916 [file] [log] [blame]
#!/bin/bash
#
# Copyright 2021 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.
set -eu
# Load the test setup defined in the parent directory
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CURRENT_DIR}/../integration_test_setup.sh" \
|| { echo "integration_test_setup.sh not found!" >&2; exit 1; }
# Returns the path of the code coverage report that was generated by Bazel by
# looking at the current $TEST_log. The method fails if TEST_log does not
# contain any coverage report for a passed test.
function get_coverage_file_path_from_test_log() {
local ending_part="$(sed -n -e '/PASSED/,$p' "$TEST_log")"
local coverage_file_path=$(grep -Eo "/[/a-zA-Z0-9\.\_\-]+\.dat$" <<< "$ending_part")
[[ -e "$coverage_file_path" ]] || fail "Coverage output file does not exist!"
echo "$coverage_file_path"
}
function set_up() {
touch WORKSPACE
}
function test_starlark_rule_without_lcov_merger() {
cat <<EOF > rules.bzl
def _impl(ctx):
output = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(output, """\
#!/bin/bash
if [[ ! -r extra ]]; then
echo "extra file not found" >&2
exit 1
fi
if [[ -z \$COVERAGE ]]; then
echo "COVERAGE environment variable not set, coverage not run."
exit 1
fi
""", is_executable = True)
extra_file = ctx.actions.declare_file("extra")
ctx.actions.write(extra_file, "extra")
return [DefaultInfo(executable=output, runfiles=ctx.runfiles(files=[extra_file]))]
custom_test = rule(
implementation = _impl,
test = True,
)
EOF
cat <<EOF > BUILD
load(":rules.bzl", "custom_test")
custom_test(name = "foo_test")
EOF
bazel coverage //:foo_test --combined_report=lcov > $TEST_log \
|| fail "Coverage run failed but should have succeeded."
}
function test_starlark_rule_without_lcov_merger_failing_test() {
cat <<EOF > rules.bzl
def _impl(ctx):
executable = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(executable, "exit 1", is_executable = True)
return [
DefaultInfo(
executable = executable,
)
]
custom_test = rule(
implementation = _impl,
test = True,
)
EOF
cat <<EOF > BUILD
load(":rules.bzl", "custom_test")
custom_test(name = "foo_test")
EOF
if bazel coverage //:foo_test > $TEST_log; then
fail "Coverage run succeeded but should have failed."
fi
}
function test_starlark_rule_with_custom_lcov_merger() {
cat <<EOF > lcov_merger.sh
for var in "\$@"
do
if [[ "\$var" == "--output_file="* ]]; then
path="\${var##--output_file=}"
mkdir -p "\$(dirname \$path)"
echo lcov_merger_called >> \$path
exit 0
fi
done
EOF
chmod +x lcov_merger.sh
cat <<EOF > rules.bzl
def _impl(ctx):
output = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(output, "", is_executable = True)
return [DefaultInfo(executable=output)]
custom_test = rule(
implementation = _impl,
test = True,
attrs = {
"_lcov_merger": attr.label(default = ":lcov_merger", cfg = "exec"),
},
)
EOF
cat <<EOF > BUILD
load(":rules.bzl", "custom_test")
sh_binary(
name = "lcov_merger",
srcs = ["lcov_merger.sh"],
)
custom_test(name = "foo_test")
EOF
bazel coverage --test_output=all //:foo_test --combined_report=lcov > $TEST_log \
|| fail "Coverage run failed but should have succeeded."
local coverage_file_path="$( get_coverage_file_path_from_test_log )"
cat $coverage_file_path
grep "lcov_merger_called" "$coverage_file_path" \
|| fail "Coverage report did not contain evidence of custom lcov_merger."
}
function test_starlark_rule_with_configuration_field_lcov_merger_coverage_enabled() {
cat <<EOF > lcov_merger.sh
for var in "\$@"
do
if [[ "\$var" == "--output_file="* ]]; then
path="\${var##--output_file=}"
mkdir -p "\$(dirname \$path)"
echo lcov_merger_called >> \$path
exit 0
fi
done
EOF
chmod +x lcov_merger.sh
cat <<EOF > rules.bzl
def _impl(ctx):
output = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(output, "", is_executable = True)
return [DefaultInfo(executable=output)]
custom_test = rule(
implementation = _impl,
test = True,
attrs = {
"_lcov_merger": attr.label(
default = configuration_field(fragment = "coverage", name = "output_generator"),
cfg = "exec"
),
},
fragments = ["coverage"],
)
EOF
cat <<EOF > BUILD
load(":rules.bzl", "custom_test")
sh_binary(
name = "lcov_merger",
srcs = ["lcov_merger.sh"],
)
custom_test(name = "foo_test")
EOF
bazel coverage --test_output=all //:foo_test --combined_report=lcov --coverage_output_generator=//:lcov_merger > $TEST_log \
|| fail "Coverage run failed but should have succeeded."
local coverage_file_path="$( get_coverage_file_path_from_test_log )"
cat $coverage_file_path
grep "lcov_merger_called" "$coverage_file_path" \
|| fail "Coverage report did not contain evidence of custom lcov_merger."
}
function test_starlark_rule_with_configuration_field_lcov_merger_coverage_disabled() {
cat <<EOF > rules.bzl
def _impl(ctx):
if ctx.attr._lcov_merger:
fail("Expected _lcov_merger to be None if coverage is not collected")
output = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(output, "", is_executable = True)
return [DefaultInfo(executable=output)]
custom_test = rule(
implementation = _impl,
test = True,
attrs = {
"_lcov_merger": attr.label(
default = configuration_field(fragment = "coverage", name = "output_generator"),
cfg = "exec"
),
},
fragments = ["coverage"],
)
EOF
cat <<EOF > BUILD
load(":rules.bzl", "custom_test")
custom_test(name = "foo_test")
EOF
bazel test --test_output=all //:foo_test > $TEST_log \
|| fail "Test run failed but should have succeeded."
}
run_suite "test tests"