Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'