Make bazel_cc_code_coverage_test more robust against GCC version differences (#16254)
* -fprofile-dir shouldn't be used because on the g++ command line because it
has different behaviour with different versions (w.r.t. where the output
gcda file ends up).
* The gcda and gcno files may end up in the same directory as the object file
or in the current working directory.
* The output of the gcov call in collect_cc_coverage may be
"*.gcda.gcov.json.gz" or "*.gcov.json.gz" (as well as the original text file
for much older GCC versions).
Also re-enable the test for Ubuntu 20.04 pre and postsubmits.
Fixes #16229
Closes #16235.
PiperOrigin-RevId: 473218955
Change-Id: I1f4887f251da8f56f8ea525c1a1410e6257bf31b
Co-authored-by: Charles Mita <cmita@google.com>
diff --git a/src/test/shell/bazel/bazel_cc_code_coverage_test.sh b/src/test/shell/bazel/bazel_cc_code_coverage_test.sh
index 66d2327..3748bae 100755
--- a/src/test/shell/bazel/bazel_cc_code_coverage_test.sh
+++ b/src/test/shell/bazel/bazel_cc_code_coverage_test.sh
@@ -107,24 +107,44 @@
EOF
generate_and_execute_instrumented_binary coverage_srcs/test \
- "$COVERAGE_DIR_VAR/coverage_srcs" \
coverage_srcs/a.h coverage_srcs/a.cc \
coverage_srcs/b.h \
coverage_srcs/t.cc
- # g++ generates the notes files in the current directory. The documentation
- # (https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files)
- # says they are placed in the same directory as the object file, but they
- # are not. Therefore we move them in the same directory.
- agcno=$(ls *a.gcno)
- tgcno=$(ls *t.gcno)
- mv $agcno coverage_srcs/$agcno
- mv $tgcno coverage_srcs/$tgcno
+ # Prior to version 11, g++ generates the notes files in the current directory
+ # instead of next to the object file despite the documentation indicating otherwise:
+ # https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files
+ # This is fixed in g++ 11 so we have to handle both cases.
+
+ local not_found=0
+ ls coverage_srcs/*a.gcno > /dev/null 2>&1 || not_found=$?
+ if [[ $not_found -ne 0 ]]; then
+ agcno=$(ls *a.gcno)
+ tgcno=$(ls *t.gcno)
+ agcda=$(ls *a.gcda)
+ tgcda=$(ls *t.gcda)
+ mv $agcno coverage_srcs/$agcno
+ mv $tgcno coverage_srcs/$tgcno
+ mv $agcda coverage_srcs/$agcda
+ mv $tgcda coverage_srcs/$tgcda
+ fi
+ agcno=$(ls coverage_srcs/*a.gcno)
+ tgcno=$(ls coverage_srcs/*t.gcno)
+ agcda=$(ls coverage_srcs/*a.gcda)
+ tgcda=$(ls coverage_srcs/*t.gcda)
+ # Even though gcov expects the gcda files to be next to the gcno files,
+ # during Bazel execution this will not be the case. collect_cc_coverage.sh
+ # expects them to be in the COVERAGE_DIR and will move the gcno files itself.
+ # We cannot use -fprofile-dir during compilation because this causes the
+ # filenames to undergo mangling; see
+ # https://github.com/bazelbuild/bazel/issues/16229
+ mv $agcda "$COVERAGE_DIR_VAR/$agcda"
+ mv $tgcda "$COVERAGE_DIR_VAR/$tgcda"
# All generated .gcno files need to be in the manifest otherwise
# the coverage report will be incomplete.
- echo "coverage_srcs/$tgcno" >> "$COVERAGE_MANIFEST_VAR"
- echo "coverage_srcs/$agcno" >> "$COVERAGE_MANIFEST_VAR"
+ echo "$tgcno" >> "$COVERAGE_MANIFEST_VAR"
+ echo "$agcno" >> "$COVERAGE_MANIFEST_VAR"
}
# Generates and executes an instrumented binary:
@@ -138,17 +158,7 @@
# - path_to_binary destination of the binary produced by g++
function generate_and_execute_instrumented_binary() {
local path_to_binary="${1}"; shift
- local gcda_directory="${1}"; shift
- # -fprofile-arcs Instruments $path_to_binary. During execution the binary
- # records code coverage information.
- # -ftest-coverage Produces a notes (.gcno) file that coverage utilities
- # (e.g. gcov, lcov) can use to show a coverage report.
- # -fprofile-dir Sets the directory where the profile data (gcda) appears.
- #
- # The profile data files need to be at a specific location where the C++
- # coverage scripts expects them to be ($COVERAGE_DIR/path/to/sources/).
- g++ -fprofile-arcs -ftest-coverage \
- -fprofile-dir="$gcda_directory" \
+ g++ -coverage \
"$@" -o "$path_to_binary" \
|| fail "Couldn't produce the instrumented binary for $@ \
with path_to_binary $path_to_binary"
@@ -274,6 +284,7 @@
function test_cc_test_coverage_gcov() {
+ local -r gcov_location=$(which gcov)
"$gcov_location" -version | grep "LLVM" && \
echo "gcov LLVM version not supported. Skipping test." && return
# gcov -v | grep "gcov" outputs a line that looks like this:
@@ -316,8 +327,16 @@
fail "Number of lines in C++ gcov coverage output file is "\
"$nr_lines and different than 17"
else
- agcda=$(ls $COVERAGE_DIR_VAR/*a.gcda.gcov.json.gz)
- tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcda.gcov.json.gz)
+ # There may or may not be "gcda" in the extension.
+ local not_found=0
+ ls $COVERAGE_DIR_VAR/*.gcda.gcov.json.gz > /dev/null 2>&1 || not_found=$?
+ if [[ $not_found -ne 0 ]]; then
+ agcda=$(ls $COVERAGE_DIR_VAR/*a.gcov.json.gz)
+ tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcov.json.gz)
+ else
+ agcda=$(ls $COVERAGE_DIR_VAR/*a.gcda.gcov.json.gz)
+ tgcda=$(ls $COVERAGE_DIR_VAR/*t.gcda.gcov.json.gz)
+ fi
output_file_json="output_file.json"
zcat $agcda $tgcda > $output_file_json
@@ -332,4 +351,4 @@
fi
}
-run_suite "Testing tools/test/collect_cc_coverage.sh"
\ No newline at end of file
+run_suite "Testing tools/test/collect_cc_coverage.sh"