Skip to content

Commit

Permalink
Python coverage: experimental first steps
Browse files Browse the repository at this point in the history
- Add lcov_merger as an attribute to the py_test rule so that it does
  not immediately fall over
- Add a small section to python_stub_template.txt to perform minimal
  setup for coverage integration

I was able to get this to work manually by using a modified version of
coverage.py, see:
nedbat/coveragepy#863

Note that the patch does not work out of the box.

It's basically ~impossible to add integration tests until we get a
working version of coverage.py, but this is the minimum change required
in Bazel to get a basic working version.

Closes #10433.

PiperOrigin-RevId: 291166690
  • Loading branch information
ulfjack authored and copybara-github committed Jan 23, 2020
1 parent 21f633c commit b01c859
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
attr("$launcher", LABEL)
.cfg(HostTransition.createFactory())
.value(env.getToolsLabel("//tools/launcher:launcher")))
.add(attr(":lcov_merger", LABEL).value(BaseRuleClasses.getCoverageOutputGeneratorLabel()))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,26 @@ def Main():
program = python_program = FindPythonBinary(module_space)
if python_program is None:
raise AssertionError('Could not find python binary: ' + PYTHON_BINARY)
args = [python_program, main_filename] + args

cov_tool = os.environ.get('PYTHON_COVERAGE')
if cov_tool:
# Inhibit infinite recursion:
del os.environ['PYTHON_COVERAGE']
if not os.path.exists(cov_tool):
raise EnvironmentError('Python coverage tool %s not found.' % cov_tool)
args = [python_program, cov_tool, 'run', '-a', '--branch', main_filename] + args
# coverage library expects sys.path[0] to contain the library, and replaces
# it with the directory of the program it starts. Our actual sys.path[0] is
# the runfiles directory, which must not be replaced.
# CoverageScript.do_execute() undoes this sys.path[0] setting.
#
# Update sys.path such that python finds the coverage package. The coverage
# entry point is coverage.coverage_main, so we need to do twice the dirname.
new_env['PYTHONPATH'] = \
new_env['PYTHONPATH'] + ':' + os.path.dirname(os.path.dirname(cov_tool))
new_env['PYTHON_LCOV_FILE'] = os.environ.get('COVERAGE_DIR') + '/pylcov.dat'
else:
args = [python_program, main_filename] + args

os.environ.update(new_env)

Expand Down

0 comments on commit b01c859

Please sign in to comment.