Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(coverage): generating lcov was causing issues #1734

Merged
merged 10 commits into from
Feb 5, 2024
4 changes: 2 additions & 2 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ buildifier:
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
Expand Down Expand Up @@ -218,7 +218,7 @@ tasks:
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
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ A brief description of the categories of changes:
* (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

Expand Down
31 changes: 19 additions & 12 deletions python/private/python_bootstrap_template.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ del sys.path[0]

import os
import subprocess
import uuid

def IsRunningFromZip():
return %is_zipfile%
Expand Down Expand Up @@ -93,6 +94,10 @@ def PrintVerboseCoverage(*args):
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:
Expand Down Expand Up @@ -389,8 +394,8 @@ def _RunForCoverage(python_program, main_filename, args, env,
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))
aignas marked this conversation as resolved.
Show resolved Hide resolved
with open(rcfile_name, "w") as rcfile:
rcfile.write('''[run]
relative_files = True
Expand All @@ -415,18 +420,20 @@ relative_files = True

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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding a comment into why this behaviour is as is would be great.

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:
Expand Down
Loading