Skip to content

Commit

Permalink
Collect C++ lcov coverage if runtime object not in runfiles (#15299)
Browse files Browse the repository at this point in the history
Before this commit, collecting C++ coverage in lcov format would fail
at the llvm-cov export step if a shared library listed in the
runtime_objects_list.txt was not contained in the runfiles of the top-
level target. This can happen e.g. if a cc_library depends on a
java_binary that has a cc_binary shared library in its resources.

This is fixed by not including objects that don't exist at runtime
in the llvm-cov invocation.

Fixes #15121.

Closes #15118.

PiperOrigin-RevId: 442799461
  • Loading branch information
fmeum authored May 9, 2022
1 parent c73f43d commit 307162d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
72 changes: 71 additions & 1 deletion src/test/shell/bazel/bazel_coverage_cc_test_llvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,77 @@ LH:5
LF:7
end_of_record"

assert_equals "$(cat $(get_coverage_file_path_from_test_log))" "$expected_result"
assert_equals "$expected_result" "$(cat $(get_coverage_file_path_from_test_log))"
}

function test_cc_test_with_runtime_objects_not_in_runfiles() {
local -r llvm_profdata="/usr/bin/llvm-profdata-9"
if [[ ! -x ${llvm_profdata} ]]; then
return
fi

local -r clang="/usr/bin/clang-9"
if [[ ! -x ${clang} ]]; then
return
fi

local -r llvm_cov="/usr/bin/llvm-cov-9"
if [[ ! -x ${llvm_cov} ]]; then
return
fi

cat << EOF > BUILD
cc_test(
name = "main",
srcs = ["main.cpp"],
data = [":jar"],
)
java_binary(
name = "jar",
resources = [":shared_lib"],
create_executable = False,
)
cc_binary(
name = "shared_lib",
linkshared = True,
)
EOF

cat << EOF > main.cpp
#include <iostream>
int main(int argc, char const *argv[])
{
if (argc < 5) {
std::cout << "Hello World!" << std::endl;
}
}
EOF


BAZEL_USE_LLVM_NATIVE_COVERAGE=1 GCOV=$llvm_profdata CC=$clang \
BAZEL_LLVM_COV=$llvm_cov bazel coverage --experimental_generate_llvm_lcov \
--test_output=all --instrument_test_targets \
//:main &>$TEST_log || fail "Coverage for //:main failed"

local expected_result="SF:main.cpp
FN:4,main
FNDA:1,main
FNF:1
FNH:1
DA:4,1
DA:5,1
DA:6,1
DA:7,1
DA:8,1
LH:5
LF:5
end_of_record"

assert_equals "$expected_result" "$(cat $(get_coverage_file_path_from_test_log))"
}


run_suite "test tests"
2 changes: 2 additions & 0 deletions tools/test/collect_cc_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ function llvm_coverage_lcov() {
while read -r line; do
if [[ ${line: -24} == "runtime_objects_list.txt" ]]; then
while read -r line_runtime_object; do
if [[ -e "${RUNFILES_DIR}/${TEST_WORKSPACE}/${line_runtime_object}" ]]; then
object_param+=" -object ${RUNFILES_DIR}/${TEST_WORKSPACE}/${line_runtime_object}"
fi
done < "${line}"
fi
done < "${COVERAGE_MANIFEST}"
Expand Down

0 comments on commit 307162d

Please sign in to comment.