Skip to content

Commit

Permalink
bazel: make coverage great again (#415). (#781)
Browse files Browse the repository at this point in the history
* Get rid of custom Bazel build. Now that we have a single test binary,
  we can completely bypass "bazel coverage", instead doing an
  unsandboxed "build test" with --coverage added to --cxxopt/--linkopt.
  We then have the .gcda from the single run in bazel-out/ and can run
  gcovr on it.

* Document how to do coverage runs locally (i.e. not in the CI Docker
  image).
  • Loading branch information
htuch authored and mattklein123 committed Apr 18, 2017
1 parent 44b154b commit c140172
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 27 deletions.
12 changes: 12 additions & 0 deletions bazel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
11 changes: 0 additions & 11 deletions ci/build_container/build_container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 0 additions & 1 deletion ci/build_setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
33 changes: 18 additions & 15 deletions test/run_envoy_bazel_coverage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,30 @@ 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

# 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
Expand All @@ -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 \
Expand Down

0 comments on commit c140172

Please sign in to comment.