Skip to content

Commit

Permalink
Fixed gcovr report reading and added coverage method to bug manager (
Browse files Browse the repository at this point in the history
…fixes #158) (#168)

* fixed API migration bugs

* added files_to_instrument parameter to Bug.coverage method

* added missing imports

* added mktemp method to container manager

* bug fix: tweaked gcovr to write to temporary file; avoids corrupted XML outputs

* bumped version to 2.0.4
  • Loading branch information
ChrisTimperley authored Mar 24, 2018
1 parent 3cf2fb4 commit ed7f199
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 19 deletions.
4 changes: 2 additions & 2 deletions bugzoo/core/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ class TestSuiteCoverage(object):
@staticmethod
def from_dict(d: dict) -> 'TestSuiteCoverage':
coverage_by_test = {}
for test_coverage_dict in d:
for test_coverage_dict in d.values():
test_coverage = TestCoverage.from_dict(test_coverage_dict)
coverage_by_test[test_coverage.test] = test_coverage
return ProjectCoverageMap(coverage_by_test)
return TestSuiteCoverage(coverage_by_test)

@staticmethod
def from_file(fn: str) -> 'TestSuiteCoverage':
Expand Down
21 changes: 18 additions & 3 deletions bugzoo/mgr/bug.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Iterator
from typing import Iterator, Optional, List
import os

import docker
import textwrap
Expand Down Expand Up @@ -185,10 +186,21 @@ def validate(self, bug: Bug, verbose: bool = True) -> bool:

return validated

def coverage(self, bug: Bug) -> TestSuiteCoverage:
def coverage(self,
bug: Bug,
files_to_instrument: Optional[List[str]] = None
) -> TestSuiteCoverage:
"""
Provides coverage information for each test within the test suite
for the program associated with this bug.
Parameters:
bug: the bug for which to compute coverage.
files_to_instrument: an optional list of files that should be
instrumented before generating the coverage report.
Returns:
a test suite coverage report for the given bug.
"""
# determine the location of the coverage map on disk
fn = os.path.join(self.__installation.coverage_path,
Expand All @@ -201,9 +213,12 @@ def coverage(self, bug: Bug) -> TestSuiteCoverage:
# if we don't have coverage information, compute it
try:
mgr_ctr = self.__installation.containers
mgr_cov = self.__installation.coverage
container = None
container = mgr_ctr.provision(bug)
coverage = mgr_ctr.coverage(container)
coverage = mgr_cov.coverage(container,
bug.tests,
files_to_instrument=files_to_instrument)

# save to disk
with open(fn, 'w') as f:
Expand Down
14 changes: 14 additions & 0 deletions bugzoo/mgr/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,20 @@ def provision(self,
self.__containers[uid] = container
return container

def mktemp(self,
container: Container
) -> str:
"""
Creates a named temporary file within a given container.
Returns:
the absolute path to the created temporary file.
"""
response = self.command(container, "mktemp")
assert response.code == 0, "failed to create temporary file"
fn = response.output.strip()
return fn

def ip_address(self,
container: Container,
raise_error: bool = False
Expand Down
37 changes: 24 additions & 13 deletions bugzoo/mgr/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ def _from_gcovr_xml_string(self,
dir_source = container.bug.source_dir # TODO port
# getting a list of all files in source directory to later use for resolving path
resp = mgr_ctr.command(container, "find {} -type f".format(dir_source))
all_files = resp.output.split('\n')

all_files = [fn.strip() for fn in resp.output.split('\n')]

def has_file(fn_rel: str) -> bool:
fn_abs = os.path.join(dir_source, fn_rel)
Expand Down Expand Up @@ -233,7 +232,7 @@ def extract(self,
"""
logger = self.__logger.getChild(container.id)
mgr_ctr = self.__installation.containers
logger.debug("Starting to extract coverage info")
logger.debug("Extracting coverage information")

if not instrumented_files:
instrumented_files = set()
Expand All @@ -243,17 +242,29 @@ def extract(self,
dir_source = container.bug.source_dir # TODO port
t_start = timer()
logger.debug("Running gcovr.")
fn_temp_ctr = mgr_ctr.mktemp(container)
cmd = 'gcovr -o "{}" -x -d -r .'.format(fn_temp_ctr)
response = mgr_ctr.command(container,
'gcovr -x -d -r .',
context=dir_source)
logger.debug("gcovr returned. Seconds passed: %.2f", timer() - t_start)
assert response.code == 0
response = response.output
cmd,
context=dir_source,
verbose=True)
logger.debug("Finished running gcovr (took %.2f seconds).", timer() - t_start)
assert response.code == 0, "failed to run gcovr"

# copy the contents of the temporary file to the host machine
(_, fn_temp_host) = tempfile.mkstemp(suffix='.bugzoo')
try:
mgr_ctr.copy_from(container, fn_temp_ctr, fn_temp_host)
with open(fn_temp_host, 'r') as fh:
report = fh.read()
finally:
os.remove(fn_temp_host)

t_start = timer()
logger.debug("Parsing gcovr xml.")
res = self._from_gcovr_xml_string(response,
instrumented_files,
container)
logger.debug("Finished parsing gcovr xml. Seconds passed: %.2f", timer() - t_start)
logger.debug("Parsing gcovr XML report.")
res = self._from_gcovr_xml_string(report,
instrumented_files,
container)
logger.debug("Finished parsing gcovr XML report (took %.2f seconds).", timer() - t_start)
logger.debug("Finished extracting coverage information")
return res
2 changes: 1 addition & 1 deletion bugzoo/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.0.3'
__version__ = '2.0.4'

0 comments on commit ed7f199

Please sign in to comment.