From 4d9df551ca1dafee097a58c7bbd1351291362ced Mon Sep 17 00:00:00 2001 From: Gregory Becker <becker33@llnl.gov> Date: Fri, 17 Jan 2020 13:30:40 -0800 Subject: [PATCH] tests occur in temporary directory, can be kept for debugging --- lib/spack/spack/build_environment.py | 5 ++++- lib/spack/spack/cmd/test.py | 4 +++- lib/spack/spack/package.py | 21 +++++++++++++++++++-- lib/spack/spack/report.py | 19 +++++++++++-------- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 9d9e03c1c1..ab4c5d69fd 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -857,6 +857,9 @@ def child_process(child_pipe, input_stream): if input_stream is not None: sys.stdin = input_stream + # Record starting directory + start_dir = os.getcwd() + try: if not fake: setup_package(pkg, dirty=dirty, context=context) @@ -885,7 +888,7 @@ def child_process(child_pipe, input_stream): test_log = None if context == 'test': - test_log = os.path.join(os.getcwd(), pkg.test_log_name) + test_log = os.path.join(start_dir, pkg.test_log_name) # make a pickleable exception to send to parent. msg = "%s: %s" % (exc_type.__name__, str(exc)) diff --git a/lib/spack/spack/cmd/test.py b/lib/spack/spack/cmd/test.py index 175ad1ecd9..c89bead6b6 100644 --- a/lib/spack/spack/cmd/test.py +++ b/lib/spack/spack/cmd/test.py @@ -22,6 +22,8 @@ def setup_parser(subparser): + subparser.add_argument('--keep-tmpdir', action='store_true', + help='Keep testing directory for debuggin') subparser.add_argument( '--log-format', default=None, @@ -100,6 +102,6 @@ def test(parser, args): with reporter('test'): if args.smoke_test: for spec in specs_to_test: - spec.package.do_test() + spec.package.do_test(not args.keep_tmpdir) else: raise NotImplementedError diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index b15ab324b3..ec3067edce 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -1580,7 +1580,7 @@ def do_install(self, **kwargs): def test_log_name(self): return 'test-%s' % self.spec.format('{name}-{hash:7}') - def do_test(self, dirty=False): + def do_test(self, remove_directory=False, dirty=False): test_log_file = os.path.join(os.getcwd(), self.test_log_name) def test_process(): @@ -1588,9 +1588,18 @@ def test_process(): with logger.force_echo(): tty.msg('Testing package %s' % self.spec.format('{name}-{hash:7}')) + + # use debug print levels for log file to record commands old_debug = tty.is_debug() tty.set_debug(True) + + # setup test directory + alltestsdir = os.path.join(os.getcwd(), 'spack-tests') + testdir = os.path.join(alltestsdir, + self.spec.format('{name}-{hash}')) try: + mkdirp(testdir) + os.chdir(testdir) self.test() except Exception as e: # Catch the error and print a summary to the log file @@ -1614,7 +1623,15 @@ def test_process(): globals(), locals()) else: raise exc_type(*args).with_traceback(traceback) - tty.set_debug(old_debug) + finally: + # reset debug level + tty.set_debug(old_debug) + + # cleanup test directory + if remove_directory: + shutil.rmtree(testdir) + if not os.listdir(alltestsdir): + shutil.rmtree(alltestsdir) spack.build_environment.fork( self, test_process, dirty=dirty, fake=False, context='test') diff --git a/lib/spack/spack/report.py b/lib/spack/spack/report.py index bf19304301..a62f0d9ab4 100644 --- a/lib/spack/spack/report.py +++ b/lib/spack/spack/report.py @@ -34,10 +34,10 @@ ] -def fetch_package_log_by_type(pkg, do_fn): +def fetch_log(pkg, do_fn, dir): log_files = { 'do_install': pkg.build_log_path, - 'do_test': os.path.join(os.getcwd(), pkg.test_log_name), + 'do_test': os.path.join(dir, pkg.test_log_name), } try: with codecs.open(log_files[do_fn.__name__], 'r', 'utf-8') as f: @@ -63,7 +63,7 @@ class InfoCollector(object): specs (list of Spec): specs whose install information will be recorded """ - def __init__(self, wrap_class, do_fn, specs): + def __init__(self, wrap_class, do_fn, specs, dir): #: Class for which to wrap a function self.wrap_class = wrap_class #: Action to be reported on @@ -75,6 +75,8 @@ def __init__(self, wrap_class, do_fn, specs): #: This is where we record the data that will be included #: in our report. self.specs = [] + #: Record directory for test log paths + self.dir = dir def __enter__(self): # Initialize the spec report with the data that is available upfront. @@ -152,7 +154,7 @@ def wrapper(instance, *args, **kwargs): try: value = _install_task(instance, *args, **kwargs) package['result'] = 'success' - package['stdout'] = fetch_package_log_by_type(pkg, do_fn) + package['stdout'] = fetch_log(pkg, do_fn, self.dir) package['installed_from_binary_cache'] = \ pkg.installed_from_binary_cache if do_fn.__name__ == 'do_install' and installed_on_entry: @@ -163,7 +165,7 @@ def wrapper(instance, *args, **kwargs): # didn't work correctly) package['result'] = 'failure' package['message'] = e.message or 'Installation failure' - package['stdout'] = fetch_package_log_by_type(pkg, do_fn) + package['stdout'] = fetch_log(pkg, do_fn, self.dir) package['stdout'] += package['message'] package['exception'] = e.traceback @@ -171,7 +173,7 @@ def wrapper(instance, *args, **kwargs): # Everything else is an error (the installation # failed outside of the child process) package['result'] = 'error' - package['stdout'] = fetch_package_log_by_type(pkg, do_fn) + package['stdout'] = fetch_log(pkg, do_fn, self.dir) package['message'] = str(e) or 'Unknown error' package['exception'] = traceback.format_exc() @@ -269,6 +271,7 @@ def __init__(self, function, format_name, args): def __call__(self, type): self.type = type + self.dir = os.getcwd() return self def concretization_report(self, msg): @@ -276,8 +279,8 @@ def concretization_report(self, msg): def __enter__(self): if self.format_name: - # Start the collector and patch PackageInstaller._install_task - self.collector = InfoCollector(self.function, self.specs) + # Start the collector and patch self.function on appropriate class + self.collector = InfoCollector(self.function, self.specs, self.dir) self.collector.__enter__() def __exit__(self, exc_type, exc_val, exc_tb): -- GitLab