Skip to content

Commit

Permalink
Forward lookup of "test_log_file" and "test_failures" (spack#34882)
Browse files Browse the repository at this point in the history
* Forward lookup of "test_log_file" and "test_failures"
  refers spack#34531
  closes spack#34487
  fixes spack#34440
* Add unit test
* py-libensemble: fix tests
* Support stand-alone tests with cached files as install-time tests

Co-authored-by: Tamara Dahlgren <dahlgren1@llnl.gov>
  • Loading branch information
2 people authored and techxdave committed Feb 17, 2023
1 parent 855c70d commit ebddf80
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 24 deletions.
7 changes: 6 additions & 1 deletion lib/spack/spack/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ def __init__(self, wrapped_pkg_object, root_builder):
new_cls = type(
new_cls_name,
bases,
{"run_tests": property(lambda x: x.wrapped_package_object.run_tests)},
{
"run_tests": property(lambda x: x.wrapped_package_object.run_tests),
"test_log_file": property(lambda x: x.wrapped_package_object.test_log_file),
"test_failures": property(lambda x: x.wrapped_package_object.test_failures),
"test_suite": property(lambda x: x.wrapped_package_object.test_suite),
},
)
new_cls.__module__ = package_cls.__module__
self.__class__ = new_cls
Expand Down
22 changes: 17 additions & 5 deletions lib/spack/spack/install_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

import spack.error
import spack.paths
import spack.util.prefix
import spack.util.spack_json as sjson
from spack.spec import Spec
from spack.util.prefix import Prefix

test_suite_filename = "test_suite.lock"
results_filename = "results.txt"
Expand Down Expand Up @@ -145,6 +145,7 @@ def __init__(self, specs, alias=None):

self.alias = alias
self._hash = None
self._stage = None

self.fails = 0

Expand Down Expand Up @@ -247,8 +248,19 @@ def ensure_stage(self):

@property
def stage(self):
"""The root test suite stage directory."""
return spack.util.prefix.Prefix(os.path.join(get_test_stage_dir(), self.content_hash))
"""The root test suite stage directory.
Returns:
str: the spec's test stage directory path
"""
if not self._stage:
self._stage = Prefix(fs.join_path(get_test_stage_dir(), self.content_hash))
return self._stage

@stage.setter
def stage(self, value):
"""Set the value of a non-default stage directory."""
self._stage = value if isinstance(value, Prefix) else Prefix(value)

@property
def results_file(self):
Expand Down Expand Up @@ -299,7 +311,7 @@ def test_dir_for_spec(self, spec):
Returns:
str: the spec's test stage directory path
"""
return self.stage.join(self.test_pkg_id(spec))
return Prefix(self.stage.join(self.test_pkg_id(spec)))

@classmethod
def tested_file_name(cls, spec):
Expand All @@ -322,7 +334,7 @@ def tested_file_for_spec(self, spec):
Returns:
str: the spec's test status file path
"""
return self.stage.join(self.tested_file_name(spec))
return fs.join_path(self.stage, self.tested_file_name(spec))

@property
def current_test_cache_dir(self):
Expand Down
48 changes: 32 additions & 16 deletions lib/spack/spack/package_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,12 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
#: List of test failures encountered during a smoke/install test run.
test_failures = None

#: TestSuite instance used to manage smoke/install tests for one or more
#: specs.
#: TestSuite instance used to manage smoke/install tests for one or more specs.
test_suite = None

#: Path to the log file used for tests
test_log_file = None

def __init__(self, spec):
# this determines how the package should be built.
self.spec = spec
Expand Down Expand Up @@ -1884,7 +1886,10 @@ def _setup_test(self, verbose, externals):
pkg_id = self.test_suite.test_pkg_id(self.spec)
else:
self.test_log_file = fsys.join_path(self.stage.path, _spack_install_test_log)
self.test_suite = TestSuite([self.spec])
self.test_suite.stage = self.stage.path
pkg_id = self.spec.format("{name}-{version}-{hash:7}")

fsys.touch(self.test_log_file) # Otherwise log_parse complains

with tty.log.log_output(self.test_log_file, verbose) as logger:
Expand Down Expand Up @@ -2441,6 +2446,11 @@ def run_test_callbacks(builder, method_names, callback_type="install"):
with builder.pkg._setup_test(verbose=False, externals=False) as logger:
# Report running each of the methods in the build log
print_test_message(logger, "Running {0}-time tests".format(callback_type), True)
builder.pkg.test_suite.current_test_spec = builder.pkg.spec
builder.pkg.test_suite.current_base_spec = builder.pkg.spec

if "test" in method_names:
_copy_cached_test_files(builder.pkg, builder.pkg.spec)

for name in method_names:
try:
Expand Down Expand Up @@ -2489,6 +2499,25 @@ def print_test_message(logger, msg, verbose):
tty.msg(msg)


def _copy_cached_test_files(pkg, spec):
"""Copy any cached stand-alone test-related files."""

# copy installed test sources cache into test cache dir
if spec.concrete:
cache_source = spec.package.install_test_root
cache_dir = pkg.test_suite.current_test_cache_dir
if os.path.isdir(cache_source) and not os.path.exists(cache_dir):
fsys.install_tree(cache_source, cache_dir)

# copy test data into test data dir
data_source = Prefix(spec.package.package_dir).test
data_dir = pkg.test_suite.current_test_data_dir
if os.path.isdir(data_source) and not os.path.exists(data_dir):
# We assume data dir is used read-only
# maybe enforce this later
shutil.copytree(data_source, data_dir)


def test_process(pkg, kwargs):
verbose = kwargs.get("verbose", False)
externals = kwargs.get("externals", False)
Expand Down Expand Up @@ -2527,20 +2556,7 @@ def test_process(pkg, kwargs):
except spack.repo.UnknownPackageError:
continue

# copy installed test sources cache into test cache dir
if spec.concrete:
cache_source = spec_pkg.install_test_root
cache_dir = pkg.test_suite.current_test_cache_dir
if os.path.isdir(cache_source) and not os.path.exists(cache_dir):
fsys.install_tree(cache_source, cache_dir)

# copy test data into test data dir
data_source = Prefix(spec_pkg.package_dir).test
data_dir = pkg.test_suite.current_test_data_dir
if os.path.isdir(data_source) and not os.path.exists(data_dir):
# We assume data dir is used read-only
# maybe enforce this later
shutil.copytree(data_source, data_dir)
_copy_cached_test_files(pkg, spec)

# grab the function for each method so we can call
# it with the package
Expand Down
14 changes: 14 additions & 0 deletions lib/spack/spack/test/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,17 @@ def test_monkey_patching_wrapped_pkg():
s.package.run_tests = True
assert builder.pkg.run_tests is True
assert builder.pkg_with_dispatcher.run_tests is True


@pytest.mark.regression("34440")
@pytest.mark.usefixtures("builder_test_repository", "config", "working_env")
def test_monkey_patching_test_log_file():
s = spack.spec.Spec("old-style-autotools").concretized()
builder = spack.builder.create(s.package)
assert s.package.test_log_file is None
assert builder.pkg.test_log_file is None
assert builder.pkg_with_dispatcher.test_log_file is None

s.package.test_log_file = "/some/file"
assert builder.pkg.test_log_file == "/some/file"
assert builder.pkg_with_dispatcher.test_log_file == "/some/file"
6 changes: 4 additions & 2 deletions var/spack/repos/builtin/packages/py-libensemble/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def run_tutorial_tests(self, exe):
)

if not os.path.isfile(join_path(test_dir, exe)):
print("Skipping {0} test".format(exe))
print("SKIPPED: {0} test does not exist".format(exe))
return

self.run_test(
Expand All @@ -91,4 +91,6 @@ def run_tutorial_tests(self, exe):
)

def test(self):
self.run_tutorial_tests("test_uniform_sampling.py")
super(__class__, self).test()
for tutorial in ["test_uniform_sampling.py", "test_1d_sampling.py"]:
self.run_tutorial_tests(tutorial)

0 comments on commit ebddf80

Please sign in to comment.