diff --git a/bazel/README.md b/bazel/README.md index 397ed2bbb98dd..458f8a5cf5687 100644 --- a/bazel/README.md +++ b/bazel/README.md @@ -115,6 +115,18 @@ One caveat to note is that the Git SHA1 is truncated to 16 bytes today as a result of the workaround in place for https://github.com/bazelbuild/bazel/issues/2805. +# Coverage builds + +To generate coverage results, make sure you have `gcov` 3.3 in your `PATH` (or +set `GCOVR` to point at it). Then run: + +``` +test/run_envoy_bazel_coverage.sh +``` + +The summary results are printed to the standard output and the full coverage +report is available in `generated/coverage/coverage.html`. + # Adding or maintaining Envoy build rules See the [developer guide for writing Envoy Bazel rules](DEVELOPER.md). diff --git a/ci/build_container/build_container.sh b/ci/build_container/build_container.sh index 314319e13bb37..fd5419e364dca 100755 --- a/ci/build_container/build_container.sh +++ b/ci/build_container/build_container.sh @@ -20,17 +20,6 @@ apt-get update apt-get install -y bazel rm -rf /var/lib/apt/lists/* -# Build a version of Bazel suitable for C++ code coverage collection. See -# https://github.com/bazelbuild/bazel/issues/1118 for why we need this. This is the envoy-coverage -# branch on the cloned repository. -git clone https://github.com/htuch/bazel.git /tmp/bazel-coverage -pushd /tmp/bazel-coverage -git checkout 63f0542560773e973c9963845d5bbc30be75441a -bazel build --spawn_strategy=standalone --genrule_strategy=standalone //src:bazel -cp bazel-bin/src/bazel /usr/bin/bazel-coverage -popd -rm -rf /root/.cache /tmp/bazel-coverage - # virtualenv pip install virtualenv diff --git a/ci/build_setup.sh b/ci/build_setup.sh index 583a6bef25323..a19d0e71c7a02 100755 --- a/ci/build_setup.sh +++ b/ci/build_setup.sh @@ -44,7 +44,6 @@ then export USER=bazel export TEST_TMPDIR=/build/tmp export BAZEL="bazel" - export BAZEL_COVERAGE="bazel-coverage" # Not sandboxing, since non-privileged Docker can't do nested namespaces. BAZEL_OPTIONS="--package_path %workspace%:/source" export BAZEL_QUERY_OPTIONS="${BAZEL_OPTIONS}" diff --git a/test/run_envoy_bazel_coverage.sh b/test/run_envoy_bazel_coverage.sh index b9a8cf7c2c0c0..6330a01aeefd1 100755 --- a/test/run_envoy_bazel_coverage.sh +++ b/test/run_envoy_bazel_coverage.sh @@ -4,7 +4,7 @@ set -e [[ -z "${SRCDIR}" ]] && SRCDIR="${PWD}" [[ -z "${REAL_SRCDIR}" ]] && REAL_SRCDIR="${SRCDIR}" -[[ -z "${GCOVR_DIR}" ]] && GCOVR_DIR="${SRCDIR}/bazel-envoy" +[[ -z "${GCOVR_DIR}" ]] && GCOVR_DIR="${SRCDIR}/bazel-$(basename "${SRCDIR}")" [[ -z "${TESTLOGS_DIR}" ]] && TESTLOGS_DIR="${SRCDIR}/bazel-testlogs" [[ -z "${BAZEL_COVERAGE}" ]] && BAZEL_COVERAGE=bazel [[ -z "${GCOVR}" ]] && GCOVR=gcovr @@ -12,20 +12,22 @@ set -e # Make sure //test/coverage is up-to-date. (BAZEL_BIN="${BAZEL_COVERAGE}" "${REAL_SRCDIR}"/test/coverage/gen_build.sh) -# Run all tests under bazel coverage. -"${BAZEL_COVERAGE}" coverage //test/coverage:coverage_tests ${BAZEL_BUILD_OPTIONS} \ - --cache_test_results=no --instrumentation_filter="" \ - --test_output=all \ - --coverage_support=@bazel_tools//tools/coverage:coverage_support - -# Cleanup any artifacts from previous coverage runs. -rm -f $(find "${GCOVR_DIR}" -name "*.gcda" -o -name "*.gcov") - -# Unpack .gcda.gcno from coverage run. This needs to be done in the Envoy source directory with -# bazel-out/ underneath it since gcov expects files to be available at their relative build -# location. This can be done somewhere else, e.g. /tmp, but it involves complex copying or -# symlinking of files to that location. -(cd "${GCOVR_DIR}"; tar -xvf "${TESTLOGS_DIR}"/test/coverage/coverage_tests/coverage.dat) +echo "Cleaning .gcda/.gcov from previous coverage runs..." +for f in $(find -L "${GCOVR_DIR}" -name "*.gcda" -o -name "*.gcov") +do + rm -f "${f}" +done +echo "Cleanup completed." + +# Run all tests under "bazel test", no sandbox. We're going to generate the +# .gcda inplace in the bazel-out/ directory. This is in contrast to the "bazel +# coverage" method, which is currently broken for C++ (see +# https://github.com/bazelbuild/bazel/issues/1118). This works today as we have +# a single coverage test binary and do not require the "bazel coverage" support +# for collecting multiple traces and glueing them together. +"${BAZEL_COVERAGE}" test //test/coverage:coverage_tests ${BAZEL_BUILD_OPTIONS} \ + --cache_test_results=no --cxxopt="--coverage" --linkopt="--coverage" \ + --test_output=all --strategy=Genrule=standalone --spawn_strategy=standalone # The Bazel build has a lot of whack in it, in particular generated files, headers from external # deps, etc. So, we exclude this from gcov to avoid false reporting of these files in the html and @@ -41,6 +43,7 @@ COVERAGE_SUMMAY="${COVERAGE_DIR}/coverage_summary.txt" # gcovr is extremely picky about where it is run and where the paths of the # original source are relative to its execution location. cd "${SRCDIR}" +echo "Running gcovr..." time "${GCOVR}" --gcov-exclude="${GCOVR_EXCLUDE_REGEX}" \ --exclude-directories=".*/external/.*" --object-directory="${GCOVR_DIR}" -r "${SRCDIR}" \ --html --html-details --exclude-unreachable-branches --print-summary \