From d49cbbf1d94416aae8751805fff59f7143d857b8 Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Wed, 8 Dec 2021 13:18:13 -0500 Subject: [PATCH 01/11] added __main__ to allow testflo to be run via 'python -m testflo'. This is in preparation for support for the new coverage package --- testflo/__main__.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 testflo/__main__.py diff --git a/testflo/__main__.py b/testflo/__main__.py new file mode 100644 index 0000000..7fa44db --- /dev/null +++ b/testflo/__main__.py @@ -0,0 +1,5 @@ +"""This file makes testflo runnable using 'python -m testflo'.""" +from testflo.main import main + +if __name__ == "__main__": + raise SystemExit(main()) From 0273f89dac7a5a5e7d7960b7e0523171e70bdaff Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Thu, 30 Dec 2021 16:05:46 -0500 Subject: [PATCH 02/11] still needs a little cleanup of .coverage* file --- setup.py | 4 +-- testflo/__init__.py | 2 +- testflo/cover.py | 56 ++++++++++++++++++++++++++++++++++-------- testflo/isolatedrun.py | 7 ++++++ testflo/mpirun.py | 7 ++++++ 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/setup.py b/setup.py index d66b2f2..d7d19fe 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import re __version__ = re.findall( - r"""__version__ = ["']+([0-9\.]*)["']+""", + r"""__version__ = ["']+([0-9\.\-dev]*)["']+""", open('testflo/__init__.py').read(), )[0] @@ -86,7 +86,7 @@ ], license='Apache 2.0', install_requires=[ - 'coverage<5.0' + 'coverage>=6.2' ], packages=['testflo'], entry_points=""" diff --git a/testflo/__init__.py b/testflo/__init__.py index 62adf65..fedbd84 100644 --- a/testflo/__init__.py +++ b/testflo/__init__.py @@ -1 +1 @@ -__version__ = '1.4.7-dev' +__version__ = '1.4.8' diff --git a/testflo/cover.py b/testflo/cover.py index 48ca7f3..3f6ac16 100644 --- a/testflo/cover.py +++ b/testflo/cover.py @@ -1,30 +1,65 @@ """ Methods to provide code coverage using coverage.py. """ +try: + import coverage +except ImportError: + coverage = None +else: + coverage.process_startup() + import os +import shutil import sys import webbrowser -try: - from coverage import coverage -except ImportError: - coverage = None +_covrc_template = """ +[run] +branch = False +parallel = True +concurrency = multiprocessing +source_pkgs = %s +omit = %s + +[report] +ignore_errors = True +skip_empty = True +omit = %s + + +[html] +skip_empty = True +""" # use to hold a global coverage obj _coverobj = None +def _to_ini(lst): + return ','.join(lst) + + def setup_coverage(options): global _coverobj if _coverobj is None and (options.coverage or options.coveragehtml): + # os.environ['COVERAGE_DEBUG_FILE'] = 'cov.debug' + # os.environ['COVERAGE_DEBUG'] = '' + os.environ['COVERAGE_RUN'] = 'true' + os.environ['COVERAGE_RCFILE'] = rcfile = os.path.join(os.getcwd(), '_coveragerc_') + os.environ['COVERAGE_FILE'] = covfile = os.path.join(os.getcwd(), '.coverage') + os.environ['COVERAGE_PROCESS_START'] = rcfile if not coverage: raise RuntimeError("coverage has not been installed.") if not options.coverpkgs: raise RuntimeError("No packages specified for coverage. " "Use the --coverpkg option to add a package.") - _coverobj = coverage(data_suffix=True, source=options.coverpkgs, - omit=options.cover_omits) + with open(rcfile, 'w') as f: + content = _covrc_template % (_to_ini(options.coverpkgs), _to_ini(options.cover_omits), + _to_ini(options.cover_omits)) + print(content) + f.write(content) + _coverobj = coverage.Coverage(data_file=covfile, data_suffix=True, config_file=rcfile) return _coverobj def start_coverage(): @@ -66,10 +101,6 @@ def finalize_coverage(options): _coverobj.combine() - # write combined data to default filename (as used by coveralls) - # (NOTE: get_data() returns None, so using data attribute) - _coverobj.data.write_file('.coverage') - if options.coverage: _coverobj.report(morfs=morfs) else: @@ -81,3 +112,8 @@ def finalize_coverage(options): os.system('open %s' % outfile) else: webbrowser.get().open(outfile) + + fname = _coverobj.get_data().data_filename() + covfile = os.environ['COVERAGE_FILE'] + if fname != covfile: + os.rename(fname, covfile) diff --git a/testflo/isolatedrun.py b/testflo/isolatedrun.py index 65637bd..6ad8b19 100644 --- a/testflo/isolatedrun.py +++ b/testflo/isolatedrun.py @@ -5,6 +5,13 @@ """ if __name__ == '__main__': + try: + import coverage + except ImportError: + pass + else: + coverage.process_startup() + import sys import os import traceback diff --git a/testflo/mpirun.py b/testflo/mpirun.py index 42fb195..e02cd5d 100644 --- a/testflo/mpirun.py +++ b/testflo/mpirun.py @@ -6,6 +6,13 @@ """ if __name__ == '__main__': + try: + import coverage + except ImportError: + pass + else: + coverage.process_startup() + import sys import os import traceback From 00f29a4bf94ee732202cf0abab834d22f14e2e37 Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Tue, 4 Jan 2022 09:55:37 -0500 Subject: [PATCH 03/11] working --- testflo/cover.py | 32 +++++++++++++++++--------------- testflo/isolatedrun.py | 3 --- testflo/main.py | 25 ++++++++++++------------- testflo/mpirun.py | 36 ++++++++++++++++-------------------- 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/testflo/cover.py b/testflo/cover.py index 3f6ac16..9cc72fe 100644 --- a/testflo/cover.py +++ b/testflo/cover.py @@ -1,6 +1,11 @@ """ Methods to provide code coverage using coverage.py. """ +import os +import sys +import shutil +import webbrowser + try: import coverage except ImportError: @@ -8,12 +13,6 @@ else: coverage.process_startup() - -import os -import shutil -import sys -import webbrowser - _covrc_template = """ [run] branch = False @@ -43,11 +42,16 @@ def _to_ini(lst): def setup_coverage(options): global _coverobj if _coverobj is None and (options.coverage or options.coveragehtml): - # os.environ['COVERAGE_DEBUG_FILE'] = 'cov.debug' - # os.environ['COVERAGE_DEBUG'] = '' + oldcov = os.path.join(os.getcwd(), '.coverage') + if os.path.isfile(oldcov): + os.remove(oldcov) + covdir = os.path.join(os.getcwd(), '_covdir') + if os.path.isdir('_covdir'): + shutil.rmtree('_covdir') + os.mkdir('_covdir') os.environ['COVERAGE_RUN'] = 'true' - os.environ['COVERAGE_RCFILE'] = rcfile = os.path.join(os.getcwd(), '_coveragerc_') - os.environ['COVERAGE_FILE'] = covfile = os.path.join(os.getcwd(), '.coverage') + os.environ['COVERAGE_RCFILE'] = rcfile = os.path.join(covdir, '_coveragerc_') + os.environ['COVERAGE_FILE'] = covfile = os.path.join(covdir, '.coverage') os.environ['COVERAGE_PROCESS_START'] = rcfile if not coverage: raise RuntimeError("coverage has not been installed.") @@ -57,7 +61,6 @@ def setup_coverage(options): with open(rcfile, 'w') as f: content = _covrc_template % (_to_ini(options.coverpkgs), _to_ini(options.cover_omits), _to_ini(options.cover_omits)) - print(content) f.write(content) _coverobj = coverage.Coverage(data_file=covfile, data_suffix=True, config_file=rcfile) return _coverobj @@ -100,6 +103,7 @@ def finalize_coverage(options): morfs = list(find_files(dirs, match='*.py', exclude=excl)) _coverobj.combine() + _coverobj.save() if options.coverage: _coverobj.report(morfs=morfs) @@ -113,7 +117,5 @@ def finalize_coverage(options): else: webbrowser.get().open(outfile) - fname = _coverobj.get_data().data_filename() - covfile = os.environ['COVERAGE_FILE'] - if fname != covfile: - os.rename(fname, covfile) + shutil.copy(_coverobj.get_data().data_filename(), + os.path.join(os.getcwd(), '.coverage')) diff --git a/testflo/isolatedrun.py b/testflo/isolatedrun.py index 6ad8b19..4fa11ed 100644 --- a/testflo/isolatedrun.py +++ b/testflo/isolatedrun.py @@ -17,7 +17,6 @@ import traceback from testflo.test import Test - from testflo.cover import save_coverage from testflo.qman import get_client_queue from testflo.options import get_options @@ -36,8 +35,6 @@ test.status = 'FAIL' test.err_msg = traceback.format_exc() - save_coverage() - except: test.err_msg = traceback.format_exc() test.status = 'FAIL' diff --git a/testflo/main.py b/testflo/main.py index 3b5d4a5..1560a88 100644 --- a/testflo/main.py +++ b/testflo/main.py @@ -154,17 +154,6 @@ def dir_exclude(d): if not options.test_glob: options.test_glob = ['test*'] - def func_matcher(funcname): - for pattern in options.excludes: - if fnmatchcase(funcname, pattern): - return False - - for pattern in options.test_glob: - if fnmatchcase(funcname, pattern): - return True - - return False - if options.benchmark: options.num_procs = 1 options.isolated = True @@ -173,8 +162,18 @@ def func_matcher(funcname): dir_exclude=dir_exclude) benchmark_file = open(options.benchmarkfile, 'a') else: - discoverer = TestDiscoverer(options, dir_exclude=dir_exclude, - func_match=func_matcher) + def func_matcher(funcname): + for pattern in options.excludes: + if fnmatchcase(funcname, pattern): + return False + + for pattern in options.test_glob: + if fnmatchcase(funcname, pattern): + return True + + return False + + discoverer = TestDiscoverer(options, dir_exclude=dir_exclude, func_match=func_matcher) benchmark_file = open(os.devnull, 'a') retval = 0 diff --git a/testflo/mpirun.py b/testflo/mpirun.py index e02cd5d..a98d48a 100644 --- a/testflo/mpirun.py +++ b/testflo/mpirun.py @@ -19,7 +19,6 @@ from mpi4py import MPI from testflo.test import Test - from testflo.cover import setup_coverage, save_coverage from testflo.qman import get_client_queue from testflo.options import get_options @@ -30,7 +29,6 @@ os.environ['TESTFLO_QUEUE'] = '' options = get_options() - setup_coverage(options) try: try: @@ -42,25 +40,23 @@ print(traceback.format_exc()) test.status = 'FAIL' test.err_msg = traceback.format_exc() + else: + # collect results + results = comm.gather(test, root=0) + if comm.rank == 0: + if not all([isinstance(r, Test) for r in results]): + print("\nNot all results gathered are Test objects. " + "You may have out-of-sync collective MPI calls.\n") + total_mem_usage = sum(r.memory_usage for r in results if isinstance(r, Test)) + test.memory_usage = total_mem_usage - # collect results - results = comm.gather(test, root=0) - if comm.rank == 0: - if not all([isinstance(r, Test) for r in results]): - print("\nNot all results gathered are Test objects. " - "You may have out-of-sync collective MPI calls.\n") - total_mem_usage = sum(r.memory_usage for r in results if isinstance(r, Test)) - test.memory_usage = total_mem_usage - - # check for errors and record error message - for r in results: - if test.status != 'FAIL' and r.status in ('SKIP', 'FAIL'): - test.err_msg = r.err_msg - test.status = r.status - if r.status == 'FAIL': - break - - save_coverage() + # check for errors and record error message + for r in results: + if test.status != 'FAIL' and r.status in ('SKIP', 'FAIL'): + test.err_msg = r.err_msg + test.status = r.status + if r.status == 'FAIL': + break except Exception: test.err_msg = traceback.format_exc() From 31a0594d42126a31ca409f49167a25c5aa05abdf Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Tue, 4 Jan 2022 10:52:21 -0500 Subject: [PATCH 04/11] added cleanup code --- testflo/main.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/testflo/main.py b/testflo/main.py index 1560a88..e3ebd1d 100644 --- a/testflo/main.py +++ b/testflo/main.py @@ -29,6 +29,8 @@ def get_iter(self, input_iter) import time import warnings import multiprocessing +import atexit +import shutil from fnmatch import fnmatch, fnmatchcase @@ -41,7 +43,6 @@ def get_iter(self, input_iter) from testflo.filters import TimeFilter, FailFilter from testflo.util import read_config_file, read_test_file -from testflo.cover import setup_coverage, finalize_coverage from testflo.options import get_options from testflo.qman import get_server_queue @@ -144,7 +145,15 @@ def dir_exclude(d): return True return False - setup_coverage(options) + if options.coverage or options.coveragehtml: + os.environ['TESTFLO_MAIN_PID'] = str(os.getpid()) + def _rmcovdir(): + if os.getpid() == int(os.environ.get('TESTFLO_MAIN_PID', '0')): + if os.path.isdir('_covdir'): + shutil.rmtree('_covdir') + atexit.register(_rmcovdir) + from testflo.cover import setup_coverage, finalize_coverage + setup_coverage(options) if options.noreport: report_file = open(os.devnull, 'a') From b991c92645ee370ea58ad12b2edae04771dd3cb0 Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Tue, 4 Jan 2022 13:30:10 -0500 Subject: [PATCH 05/11] cleanup --- RELEASE_NOTES.md | 15 ++++++++++++--- testflo/main.py | 15 ++++++++++----- testflo/mpirun.py | 3 +++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e4844b6..38a602f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,14 +1,23 @@ +# RELEASE NOTES + +*********************** +# testflo version 1.4.7 +October 13, 2021 + +- setting N_PROCS=1 will now run under MPI in OpenMDAO [#60](https://github.com/OpenMDAO/testflo/pull/60) +- fixed version regex (old one couldn't handle *-dev versions [#59](https://github.com/OpenMDAO/testflo/pull/59) + *********************** # testflo version 1.4.6 October 13, 2021 -- fix for bad testcase comm [#55](https://github.com/OpenMDAO/testflo/pull/55) +- fix for bad testcase comm [#55](https://github.com/OpenMDAO/testflo/pull/55) *********************** # testflo version 1.4.5.1 April 13, 2021 -- fixes places in the code that weren't properly handling Windows file paths that included a colon. +- fixes places in the code that weren't properly handling Windows file paths that included a colon. *********************** # testflo version 1.4.5 @@ -36,7 +45,7 @@ Jun 10, 2020 - issue happened when a test function has a decorator that doesn't rename the wrapped function to match the parent TestCase attribute - added `--excludes` option to add glob patterns to exclude test functions - fixed dryrun output to include only test specs - - This change now allows you to pipe the output from `--dryrun` into a file you can later run using `-t`, making it easier to assemble custom lists of tests to run. + - This change now allows you to pipe the output from `--dryrun` into a file you can later run using `-t`, making it easier to assemble custom lists of tests to run. - declare support for more Python versions *********************** diff --git a/testflo/main.py b/testflo/main.py index e3ebd1d..5f5323f 100644 --- a/testflo/main.py +++ b/testflo/main.py @@ -147,12 +147,19 @@ def dir_exclude(d): if options.coverage or options.coveragehtml: os.environ['TESTFLO_MAIN_PID'] = str(os.getpid()) - def _rmcovdir(): + # some coverage files aren't written until atexit of their processes, so put our finalize + # routine in atexit before their Coverage._atexit methods are registered so ours will be + # executed *after* theirs. + def _finalize(): if os.getpid() == int(os.environ.get('TESTFLO_MAIN_PID', '0')): + from testflo.cover import finalize_coverage + finalize_coverage(options) + # clean up the temporary dir where we store the interim coverage files from all + # of the processes. if os.path.isdir('_covdir'): shutil.rmtree('_covdir') - atexit.register(_rmcovdir) - from testflo.cover import setup_coverage, finalize_coverage + atexit.register(_finalize) + from testflo.cover import setup_coverage setup_coverage(options) if options.noreport: @@ -235,8 +242,6 @@ def func_matcher(funcname): retval = run_pipeline(tests, pipeline, options.disallow_skipped) - finalize_coverage(options) - if manager is not None: manager.shutdown() diff --git a/testflo/mpirun.py b/testflo/mpirun.py index a98d48a..044100f 100644 --- a/testflo/mpirun.py +++ b/testflo/mpirun.py @@ -17,6 +17,9 @@ import os import traceback + # when testing OpenMDAO, make sure that MPI is active + os.environ['OPENMDAO_USE_MPI'] = '1' + from mpi4py import MPI from testflo.test import Test from testflo.qman import get_client_queue From 84f297db8ccd536152e79a57f3c111492b199310 Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Tue, 4 Jan 2022 13:58:21 -0500 Subject: [PATCH 06/11] checked against version 6.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d7d19fe..5f8b80d 100644 --- a/setup.py +++ b/setup.py @@ -86,7 +86,7 @@ ], license='Apache 2.0', install_requires=[ - 'coverage>=6.2' + 'coverage>=6.0' ], packages=['testflo'], entry_points=""" From 18e920b09fbef2e98ab2d1f6b7d2e2cf3dcfae3a Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Wed, 5 Jan 2022 10:57:49 -0500 Subject: [PATCH 07/11] made it read existing .coveragerc before generating our temp config --- testflo/cover.py | 72 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/testflo/cover.py b/testflo/cover.py index 9cc72fe..5696e0e 100644 --- a/testflo/cover.py +++ b/testflo/cover.py @@ -8,35 +8,64 @@ try: import coverage + from coverage.config import HandyConfigParser except ImportError: coverage = None else: coverage.process_startup() -_covrc_template = """ -[run] -branch = False -parallel = True -concurrency = multiprocessing -source_pkgs = %s -omit = %s - - -[report] -ignore_errors = True -skip_empty = True -omit = %s - - -[html] -skip_empty = True -""" # use to hold a global coverage obj _coverobj = None def _to_ini(lst): - return ','.join(lst) + if lst: + return ','.join(lst) + return '' + + +def _write_temp_config(options, rcfile): + """ + Read any .coveragerc file if it exists, and override parts of it then generate our temp config. + + Parameters + ---------- + options : cmd line options + Options from the command line parser. + rcfile : str + The name of our temporary coverage config file. + """ + tmp_cfg = { + 'run': { + 'branch': False, + 'parallel': True, + 'concurrency': 'multiprocessing', + }, + 'report': { + 'ignore_errors': True, + 'skip_empty': True, + }, + 'html': { + 'skip_empty': True, + } + } + + if options.coverpkgs: + tmp_cfg['run']['source_pkgs'] = _to_ini(options.coverpkgs) + + if options.cover_omits: + tmp_cfg['run']['omit'] = _to_ini(options.cover_omits) + tmp_cfg['report']['omit'] = _to_ini(options.cover_omits) + + cfgparser = HandyConfigParser(our_file=True) + + if os.path.isfile('.coveragerc'): + cfgparser.read(['.coveragerc']) + + cfgparser.read_dict(tmp_cfg) + + with open(rcfile, 'w') as f: + cfgparser.write(f) def setup_coverage(options): @@ -58,10 +87,7 @@ def setup_coverage(options): if not options.coverpkgs: raise RuntimeError("No packages specified for coverage. " "Use the --coverpkg option to add a package.") - with open(rcfile, 'w') as f: - content = _covrc_template % (_to_ini(options.coverpkgs), _to_ini(options.cover_omits), - _to_ini(options.cover_omits)) - f.write(content) + _write_temp_config(options, rcfile) _coverobj = coverage.Coverage(data_file=covfile, data_suffix=True, config_file=rcfile) return _coverobj From 86aba1daabce748973fa40874909b971d4dc93df Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Wed, 12 Jan 2022 10:10:57 -0500 Subject: [PATCH 08/11] added TESTFLO_RUNNING env var --- testflo/main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testflo/main.py b/testflo/main.py index 5f5323f..fbbbb80 100644 --- a/testflo/main.py +++ b/testflo/main.py @@ -145,6 +145,9 @@ def dir_exclude(d): return True return False + # set this so code will know when it's running under testflo + os.environ['TESTFLO_RUNNING'] = '1' + if options.coverage or options.coveragehtml: os.environ['TESTFLO_MAIN_PID'] = str(os.getpid()) # some coverage files aren't written until atexit of their processes, so put our finalize From 0cd283461b60a6f7aeaff526d78cb64cf82e081f Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Wed, 10 Aug 2022 12:32:20 -0400 Subject: [PATCH 09/11] tweaking coverage --- testflo/cover.py | 10 +++++----- testflo/isolatedrun.py | 2 +- testflo/test.py | 4 ---- testflo/util.py | 7 +------ 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/testflo/cover.py b/testflo/cover.py index 5696e0e..128eb85 100644 --- a/testflo/cover.py +++ b/testflo/cover.py @@ -71,6 +71,11 @@ def _write_temp_config(options, rcfile): def setup_coverage(options): global _coverobj if _coverobj is None and (options.coverage or options.coveragehtml): + if not coverage: + raise RuntimeError("coverage has not been installed.") + if not options.coverpkgs: + raise RuntimeError("No packages specified for coverage. " + "Use the --coverpkg option to add a package.") oldcov = os.path.join(os.getcwd(), '.coverage') if os.path.isfile(oldcov): os.remove(oldcov) @@ -82,11 +87,6 @@ def setup_coverage(options): os.environ['COVERAGE_RCFILE'] = rcfile = os.path.join(covdir, '_coveragerc_') os.environ['COVERAGE_FILE'] = covfile = os.path.join(covdir, '.coverage') os.environ['COVERAGE_PROCESS_START'] = rcfile - if not coverage: - raise RuntimeError("coverage has not been installed.") - if not options.coverpkgs: - raise RuntimeError("No packages specified for coverage. " - "Use the --coverpkg option to add a package.") _write_temp_config(options, rcfile) _coverobj = coverage.Coverage(data_file=covfile, data_suffix=True, config_file=rcfile) return _coverobj diff --git a/testflo/isolatedrun.py b/testflo/isolatedrun.py index 4fa11ed..c7ff4b0 100644 --- a/testflo/isolatedrun.py +++ b/testflo/isolatedrun.py @@ -8,7 +8,7 @@ try: import coverage except ImportError: - pass + coverage = None else: coverage.process_startup() diff --git a/testflo/test.py b/testflo/test.py index de8e3bc..a5a533d 100644 --- a/testflo/test.py +++ b/testflo/test.py @@ -286,8 +286,6 @@ def run(self, queue=None): sys.stdout = outstream sys.stderr = errstream - start_coverage() - self.start_time = time.time() # if there's a module setup, run it @@ -343,8 +341,6 @@ def run(self, queue=None): self.load = os.getloadavg() finally: - stop_coverage() - sys.stderr = old_err sys.stdout = old_out diff --git a/testflo/util.py b/testflo/util.py index 9eabd2e..7fdfaea 100644 --- a/testflo/util.py +++ b/testflo/util.py @@ -383,12 +383,7 @@ def get_module(fname): else: raise ImportError("can't import %s" % modpath) - start_coverage() - - try: - mod = try_import(fname, modpath) - finally: - stop_coverage() + mod = try_import(fname, modpath) return fname, mod From 3467c51926673fde1b6f5433fcc121358ab10104 Mon Sep 17 00:00:00 2001 From: Bret Naylor Date: Thu, 18 Aug 2022 15:39:18 -0400 Subject: [PATCH 10/11] sort the coverage output --- testflo/cover.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testflo/cover.py b/testflo/cover.py index 128eb85..c88cde9 100644 --- a/testflo/cover.py +++ b/testflo/cover.py @@ -44,6 +44,7 @@ def _write_temp_config(options, rcfile): 'report': { 'ignore_errors': True, 'skip_empty': True, + 'sort': '-cover', }, 'html': { 'skip_empty': True, From 14fa535a3751155260d43bcaef854a13cdd5efc5 Mon Sep 17 00:00:00 2001 From: swryan Date: Wed, 25 Oct 2023 15:20:26 -0400 Subject: [PATCH 11/11] clean up after merge --- testflo/mpirun.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testflo/mpirun.py b/testflo/mpirun.py index 051bce6..044100f 100644 --- a/testflo/mpirun.py +++ b/testflo/mpirun.py @@ -38,7 +38,7 @@ comm = MPI.COMM_WORLD test = Test(sys.argv[1], options) test.nocapture = True # so we don't lose stdout - tests = test.run() + test.run() except: print(traceback.format_exc()) test.status = 'FAIL' @@ -70,4 +70,4 @@ sys.stderr.flush() if comm.rank == 0: - queue.put(tests) + queue.put(test)