Skip to content

fix(coverage): handle nested coverage collection#3823

Merged
aignas merged 2 commits into
bazel-contrib:mainfrom
gergondet-woven:fix/nested-coverage-collection
Jun 16, 2026
Merged

fix(coverage): handle nested coverage collection#3823
aignas merged 2 commits into
bazel-contrib:mainfrom
gergondet-woven:fix/nested-coverage-collection

Conversation

@gergondet-woven

Copy link
Copy Markdown

We discovered that when a py_test invokes py_binary, coverage information collected by those binaries is lost and only the coverage of the test itself appears.

It turns out that each binary writes to the same coverage file and only the last one is included in the report.

This PR makes the lcov_path unique, ensuring the coverage is collected for every binary that might be launched in such a setup.

I have setup https://github.com/gergondet-woven/repro-rules_python-coverage-issue to show the issue.

In this repo, a py_binary is launched through a py_test and we would expect coverage information generated by the binary to surface in the coverage report but it doesn't with the current release:

Before the patch:

# Generate coverage information
bazel coverage --combined_report=lcov //...
# Generate the report
genhtml --ignore-errors category --branch-coverage --output ~/genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
# (snip)
Overall coverage rate:
  lines......: 30.0% (3 of 10 lines)
# Looking into the report, neither coverage for the library function
# called by the binary nor the binary code itself is collected

After applying the patch:

Overall coverage rate:
  lines......: 100.0% (11 of 11 lines)

However, I am not sure how/if this can be properly tested within rules_python itself.

We discovered that when a py_test invokes py_binary, coverage
information collected by those binaries is lost and only the coverage of
the test itself appears.

It turns out that each binary writes to the same coverage file and only
the last one is included in the report.

This PR makes the lcov_path unique, ensuring the coverage is collected
for every binary that might be launched in such a setup.

I have setup
https://github.com/gergondet-woven/repro-rules_python-coverage-issue to
show the issue.

In this repo, a py_binary is launched through a py_test and we would
expect coverage information generated by the binary to surface in the
coverage report but it doesn't with the current release:

Before the patch:

```
# Generate coverage information
bazel coverage --combined_report=lcov //...
# Generate the report
genhtml --ignore-errors category --branch-coverage --output ~/genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
# (snip)
Overall coverage rate:
  lines......: 30.0% (3 of 10 lines)
# Looking into the report, neither coverage for the library function
# called by the binary nor the binary code itself is collected
```

After applying the patch:

```
Overall coverage rate:
  lines......: 100.0% (11 of 11 lines)
```

However, I am not sure how/if this can be properly tested within rules_python itself.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the coverage collection in stage2_bootstrap_template.py to append a unique identifier to the generated LCOV report filename (pylcov_{}.dat), which helps prevent potential file name collisions. There are no review comments, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@aignas aignas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you!

This needs to be verified but we could do:

  • Have a py_test.
  • Have a rule that transitions the target to set the instrumentation flags.
  • Have a wrapper test rule that ensures that the coverage file is as expected.

I think we can merge this now and the tests can be added as a followup PR.

@aignas aignas added this pull request to the merge queue Jun 16, 2026
@aignas aignas removed this pull request from the merge queue due to a manual request Jun 16, 2026
@aignas aignas added this pull request to the merge queue Jun 16, 2026
Merged via the queue into bazel-contrib:main with commit 6ce7840 Jun 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants