From d3bb62244d40117feb64472441d06f3611374b78 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 21 May 2025 12:59:38 -0700 Subject: [PATCH] Fix and document coverage support for test rules The LCOV merger needs to be able to run on the test action's execution platform. Closes #25996. PiperOrigin-RevId: 761635843 Change-Id: Idfd35f3fdb389e57066ad22487432a6571c3eba1 --- site/en/extending/rules.md | 37 +++++++++++++++++++ .../builtins_bzl/common/cc/semantics.bzl | 6 ++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/site/en/extending/rules.md b/site/en/extending/rules.md index c72395e4ed8d1b..94c7fc033bc265 100644 --- a/site/en/extending/rules.md +++ b/site/en/extending/rules.md @@ -968,6 +968,43 @@ like `srcs` in `dependency_attributes` instead of `source_attributes`, but it avoids the need for explicit coverage configuration for all rules in the dependency chain.) +#### Test rules + +Test rules require additional setup to generate coverage reports. The rule +itself has to add the following implicit attributes: + +```python +my_test = rule( + ..., + attrs = { + ..., + # Implicit dependencies used by Bazel to generate coverage reports. + "_lcov_merger": attr.label( + default = configuration_field(fragment = "coverage", name = "output_generator"), + executable = True, + cfg = config.exec(exec_group = "test"), + ), + "_collect_cc_coverage": attr.label( + default = "@bazel_tools//tools/test:collect_cc_coverage", + executable = True, + cfg = config.exec(exec_group = "test"), + ) + }, + test = True, +) +``` + +By using `configuration_field`, the dependency on the Java LCOV merger tool can +be avoided as long as coverage is not requested. + +When the test is run, it should emit coverage information in the form of one or +more [LCOV files] +(https://manpages.debian.org/unstable/lcov/geninfo.1.en.html#TRACEFILE_FORMAT) +with unique names into the directory specified by the `COVERAGE_DIR` environment +variable. Bazel will then merge these files into a single LCOV file using the +`_lcov_merger` tool. If present, it will also collect C/C++ coverage using the +`_collect_cc_coverage` tool. + ### Validation Actions Sometimes you need to validate something about the build, and the diff --git a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl index 251476abdb3cf9..617bae9c2ec7d4 100644 --- a/src/main/starlark/builtins_bzl/common/cc/semantics.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/semantics.bzl @@ -14,6 +14,8 @@ """Semantics for Bazel cc rules""" +_config = _builtins.toplevel.config + # Point virtual includes symlinks to the source root for better IDE integration. # See https://github.com/bazelbuild/bazel/pull/20540. # TODO: b/320980684 - Add a test that fails if this is flipped to True. @@ -78,12 +80,12 @@ def _get_coverage_attrs(): "_lcov_merger": attr.label( default = configuration_field(fragment = "coverage", name = "output_generator"), executable = True, - cfg = "exec", + cfg = _config.exec(exec_group = "test"), ), "_collect_cc_coverage": attr.label( default = "@bazel_tools//tools/test:collect_cc_coverage", executable = True, - cfg = "exec", + cfg = _config.exec(exec_group = "test"), ), }