From e69bc5948fc4c0be0d6bf3ed324c83bfd3491a8c Mon Sep 17 00:00:00 2001 From: Yu Feng Date: Mon, 13 Jan 2020 21:45:26 -0800 Subject: [PATCH] Fix coverage-5.x incompatibility. coverage-5.x switched to an implementation the preemptively creates coverage data files. We need to play along. I think this is compatible with coverage 4.x because we still call the write function; but most devs will get coverage 5.x when they update runtests, so it shouldn't matter much even if it is broken. Added travis tests too. --- .travis.yml | 2 ++ runtests/coverage.py | 28 +++++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index aede337..176f46a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,8 +27,10 @@ script: # regular unit tests #------------------- - python ./run-tests.py runtests/tests/test_regular.py + - python ./run-tests.py runtests/tests/test_regular.py --with-coverage - python ./run-mpitests.py --single runtests/tests/test_regular.py - python ./run-mpitests.py runtests/mpi/tests/test_mpiworld.py + - python ./run-mpitests.py runtests/tests/test_regular.py --with-coverage # expecting a failure for uncollective - if python ./run-mpitests.py runtests/mpi/tests/test_uncollective.py; then false; fi; diff --git a/runtests/coverage.py b/runtests/coverage.py index 2edd0be..c100330 100644 --- a/runtests/coverage.py +++ b/runtests/coverage.py @@ -3,6 +3,7 @@ import os import coverage import shutil +import glob class Coverage(object): """ @@ -44,13 +45,27 @@ def __init__(self, source, with_coverage=False, html_cov=False, if not os.path.exists(self.config_file): self.config_file = None + if self.comm: + if self.comm.rank == 0: + self.tmpdir = tempfile.mkdtemp() + else: + self.tmpdir = None + self.tmpdir = self.comm.bcast(self.tmpdir) + self.tmp_datafile = "coverage.%d" % self.comm.rank + else: + self.tmpdir = tempfile.mkdtemp() + self.tmp_datafile = "coverage" + def __enter__(self): if not self.with_coverage: self.cov = None return else: - self.cov = coverage.coverage(source=[self.source], config_file=self.config_file) + self.cov = coverage.coverage(source=[self.source], + config_file=self.config_file, + data_file=os.path.join(self.tmpdir, self.tmp_datafile) + ) self.cov.start() def __exit__(self, type, value, tb): @@ -61,7 +76,7 @@ def __exit__(self, type, value, tb): # with only one rank, just write out the coverage if self.comm is None or self.comm.size == 1: - self.cov.get_data().write_file(os.path.join(self.root, self.cov.config.data_file)) + self.cov.get_data().write() self.report(self.cov) # parallel -- combine coverage from all ranks @@ -75,17 +90,16 @@ def __exit__(self, type, value, tb): try: # write coverage data file - filename = os.path.join(tmpdir, '.coverage.%d' % os.getpid()) - self.cov.get_data().write_file(filename) + self.cov.get_data().write() # now combine from each rank and save self.comm.barrier() if self.comm.rank == 0: # write out combined data - combined_cov = coverage.coverage(config_file=self.config_file, data_file='.coverage') - combined_cov.combine(data_paths=[tmpdir]) - combined_cov.get_data().write_file(os.path.join(self.root, self.cov.config.data_file)) + combined_cov = coverage.coverage(config_file=self.config_file) + combined_cov.combine(data_paths=glob.glob(os.path.join(self.tmpdir, '*'))) + combined_cov.get_data().write() # and report self.report(combined_cov)