fix(coverage): generating lcov was causing issues (#1734)
* examples/bzlmod - bazel coverage
//tests:version_3_10_takes_3_9_subprocess_test was always failing due to
.coveragerc generated file not being unique
* generating the locv report resulted in messages going to stdout/stderr
that resulted in test failures. To fix this, we run with --quiet. If
VERBOSE_COVERAGE is defined we will output to stderr.
Reproduction steps:
```bash
git co main
cd examples/bzlmod
bazel coverage //tests/...
# failures occur
```
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 8649797..30138d3 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -59,7 +59,7 @@
build_targets: ["..."]
test_targets: ["..."]
.coverage_targets_example_bzlmod: &coverage_targets_example_bzlmod
- coverage_targets: ["//:test"]
+ coverage_targets: ["..."]
.coverage_targets_example_bzlmod_build_file_generation: &coverage_targets_example_bzlmod_build_file_generation
coverage_targets: ["//:bzlmod_build_file_generation_test"]
.coverage_targets_example_multi_python: &coverage_targets_example_multi_python
@@ -218,7 +218,7 @@
integration_test_bzlmod_ubuntu_min:
<<: *minimum_supported_version
<<: *reusable_build_test_all
- <<: *coverage_targets_example_bzlmod
+ coverage_targets: ["//:test"]
name: "examples/bzlmod: Ubuntu, minimum Bazel"
working_directory: examples/bzlmod
platform: ubuntu2004
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 51c7c6f..87d7955 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,10 @@
* (bzlmod) pip.parse now does not fail with an empty `requirements.txt`.
* (py_wheel) Wheels generated by `py_wheel` now preserve executable bits when
being extracted by `installer` and/or `pip`.
+* (coverage) During the running of lcov, the stdout/stderr was causing test
+ failures. By default, suppress output when generating lcov. This can be
+ overridden by setting 'VERBOSE_COVERAGE'. This change only affect bazel
+ 7.x.x and above.
### Added
diff --git a/python/private/python_bootstrap_template.txt b/python/private/python_bootstrap_template.txt
index 59313cf..49f4cb5 100644
--- a/python/private/python_bootstrap_template.txt
+++ b/python/private/python_bootstrap_template.txt
@@ -20,6 +20,7 @@
import os
import subprocess
+import uuid
def IsRunningFromZip():
return %is_zipfile%
@@ -93,6 +94,10 @@
if os.environ.get("VERBOSE_COVERAGE"):
print(*args, file=sys.stderr)
+def IsVerboseCoverage():
+ """Returns True if VERBOSE_COVERAGE is non-empty in the environment."""
+ return os.environ.get("VERBOSE_COVERAGE")
+
def FindCoverageEntryPoint(module_space):
cov_tool = '%coverage_tool%'
if cov_tool:
@@ -389,8 +394,8 @@
runfiles directory if set.
"""
# We need for coveragepy to use relative paths. This can only be configured
- # via an rc file, so we need to make one.
- rcfile_name = os.path.join(os.environ['COVERAGE_DIR'], '.coveragerc')
+ unique_id = uuid.uuid4()
+ rcfile_name = os.path.join(os.environ['COVERAGE_DIR'], ".coveragerc_{}".format(unique_id))
with open(rcfile_name, "w") as rcfile:
rcfile.write('''[run]
relative_files = True
@@ -415,18 +420,20 @@
PrintVerboseCoverage('Converting coveragepy database to lcov:', output_filename)
# Run coveragepy again to convert its .coverage database file into lcov.
+ # Under normal conditions running lcov outputs to stdout/stderr, which causes problems for `coverage`.
+ params = [python_program, coverage_entrypoint, "lcov", "--rcfile=" + rcfile_name, "-o", output_filename, "--quiet"]
+ kparams = {"env": env, "cwd": workspace, "stdout": subprocess.DEVNULL, "stderr": subprocess.DEVNULL}
+ if IsVerboseCoverage():
+ # reconnect stdout/stderr to lcov generation. Should be useful for debugging `coverage` issues.
+ params.remove("--quiet")
+ kparams['stdout'] = sys.stderr
+ kparams['stderr'] = sys.stderr
+
ret_code = subprocess.call(
- [
- python_program,
- coverage_entrypoint,
- "lcov",
- "--rcfile=" + rcfile_name,
- "-o",
- output_filename
- ],
- env=env,
- cwd=workspace
+ params,
+ **kparams
) or ret_code
+
try:
os.unlink(rcfile_name)
except OSError as err: