Test-Builder refactor: move do_test from PackageBase to PackageTest

This commit is contained in:
Tamara Dahlgren 2024-11-18 17:15:40 -08:00
parent 9a604bf615
commit 2f7d8947ba
No known key found for this signature in database
GPG Key ID: 1DFB48B82B5BB5C4
6 changed files with 62 additions and 59 deletions

View File

@ -13,6 +13,7 @@
import spack.config
import spack.error
import spack.install_test
import spack.multimethod
import spack.package_base
import spack.phase_callbacks

View File

@ -23,6 +23,7 @@
from llnl.util.tty.color import colorize
import spack.build_environment
import spack.compilers
import spack.config
import spack.error
import spack.package_base
@ -352,15 +353,45 @@ def handle_failures(self):
if self.test_failures:
raise TestFailure(self.test_failures)
def stand_alone_tests(self, kwargs):
def stand_alone_tests(self, dirty=False, externals=False):
"""Run the package's stand-alone tests.
Args:
kwargs (dict): arguments to be used by the test process
"""
import spack.build_environment
spack.build_environment.start_build_process(self.pkg, test_process, kwargs)
Raises:
AttributeError: required test_requires_compiler attribute is missing
"""
pkg = self.pkg
spec = pkg.spec
pkg_spec = spec.format("{name}-{version}-{hash:7}")
if not hasattr(pkg, "test_requires_compiler"):
raise AttributeError(
f"Cannot run tests for {pkg_spec}: missing required "
"test_requires_compiler attribute"
)
if pkg.test_requires_compiler:
compilers = spack.compilers.compilers_for_spec(
spec.compiler, arch_spec=spec.architecture
)
if not compilers:
tty.error(
f"Skipping tests for package {pkg_spec}\n"
f"Package test requires missing compiler {spec.compiler}"
)
return
kwargs = {
"dirty": dirty,
"fake": False,
"context": "test",
"externals": externals,
"verbose": tty.is_verbose(),
}
spack.build_environment.start_build_process(pkg, test_process, kwargs)
def parts(self) -> int:
"""The total number of (checked) test parts."""
@ -810,7 +841,7 @@ def __init__(self, specs, alias=None):
# even if they contain the same spec
self.specs = [spec.copy() for spec in specs]
self.current_test_spec = None # spec currently tested, can be virtual
self.current_base_spec = None # spec currently running do_test
self.current_base_spec = None # spec currently running tests
self.alias = alias
self._hash = None
@ -834,10 +865,6 @@ def content_hash(self):
self._hash = b32_hash
return self._hash
# TODO/TLD: Finish this
def _run_test(self, pkg, dirty, externals):
pkg.do_test(dirty=dirty, externals=externals)
def set_current_specs(self, base_spec: spack.spec.Spec, test_spec: spack.spec.Spec):
self.current_base_spec = base_spec
self.current_test_spec = test_spec
@ -851,16 +878,15 @@ def __call__(self, *args, **kwargs):
externals = kwargs.get("externals", False)
for spec in self.specs:
pkg = spec.package
try:
if spec.package.test_suite:
if pkg.test_suite:
raise TestSuiteSpecError(
"Package {} cannot be run in two test suites at once".format(
spec.package.name
)
f"Package {pkg.name} cannot be run in two test suites at once"
)
# Set up the test suite to know which test is running
spec.package.test_suite = self
pkg.test_suite = self
self.set_current_specs(spec, spec)
# setup per-test directory in the stage dir
@ -870,8 +896,7 @@ def __call__(self, *args, **kwargs):
fs.mkdirp(test_dir)
# run the package tests
# TLD spec.package.do_test(dirty=dirty, externals=externals)
self._run_test(spec.package, dirty=dirty, externals=externals)
pkg.tester.stand_alone_tests(dirty=dirty, externals=externals)
# Clean up on success
if remove_directory:

View File

@ -1943,29 +1943,6 @@ def _resource_stage(self, resource):
resource_stage_folder = "-".join(pieces)
return resource_stage_folder
def do_test(self, dirty=False, externals=False):
if self.test_requires_compiler:
compilers = spack.compilers.compilers_for_spec(
self.spec.compiler, arch_spec=self.spec.architecture
)
if not compilers:
tty.error(
"Skipping tests for package %s\n"
% self.spec.format("{name}-{version}-{hash:7}")
+ "Package test requires missing compiler %s" % self.spec.compiler
)
return
kwargs = {
"dirty": dirty,
"fake": False,
"context": "test",
"externals": externals,
"verbose": tty.is_verbose(),
}
self.tester.stand_alone_tests(kwargs)
def unit_test_check(self):
"""Hook for unit tests to assert things about package internals.

View File

@ -204,7 +204,7 @@ def extract_package_from_signature(self, instance, *args, **kwargs):
class TestInfoCollector(InfoCollector):
"""Collect information for the PackageBase.do_test method.
"""Collect information for the PackageTest.stand_alone_tests method.
Args:
specs: specs whose install information will be recorded
@ -214,7 +214,7 @@ class TestInfoCollector(InfoCollector):
dir: str
def __init__(self, specs: List[spack.spec.Spec], record_directory: str):
super().__init__(spack.package_base.PackageBase, "do_test", specs)
super().__init__(spack.install_test.PackageTest, "stand_alone_tests", specs)
self.dir = record_directory
def on_success(self, pkg, kwargs, package_record):
@ -233,7 +233,7 @@ def fetch_log(self, pkg: spack.package_base.PackageBase):
return f"Cannot open log for {pkg.spec.cshort_spec}"
def extract_package_from_signature(self, instance, *args, **kwargs):
return instance
return instance.pkg
@contextlib.contextmanager

View File

@ -17,7 +17,6 @@
import llnl.util.filesystem as fs
import spack.compilers
import spack.deptypes as dt
import spack.error
import spack.install_test
@ -262,7 +261,7 @@ def test_package_tester_fails():
s = spack.spec.Spec("pkg-a")
pkg = BaseTestPackage(s)
with pytest.raises(ValueError, match="without concrete version"):
pkg.tester()
pkg.tester
def test_package_fetcher_fails():
@ -270,18 +269,3 @@ def test_package_fetcher_fails():
pkg = BaseTestPackage(s)
with pytest.raises(ValueError, match="without concrete version"):
pkg.fetcher
def test_package_test_no_compilers(mock_packages, monkeypatch, capfd):
def compilers(compiler, arch_spec):
return None
monkeypatch.setattr(spack.compilers, "compilers_for_spec", compilers)
s = spack.spec.Spec("pkg-a")
pkg = BaseTestPackage(s)
pkg.test_requires_compiler = True
pkg.do_test()
error = capfd.readouterr()[1]
assert "Skipping tests for package" in error
assert "test requires missing compiler" in error

View File

@ -10,6 +10,7 @@
from llnl.util.filesystem import join_path, mkdirp, touch
import spack.compilers
import spack.config
import spack.install_test
import spack.spec
@ -525,3 +526,18 @@ def test_packagetest_fails(mock_packages):
pkg = MyPackage(s)
with pytest.raises(ValueError, match="require a concrete package"):
spack.install_test.PackageTest(pkg)
def test_package_test_no_compilers(mock_packages, config, monkeypatch, capfd):
s = spack.spec.Spec("libdwarf").concretized()
def compilers(compiler, arch_spec):
return None
monkeypatch.setattr(spack.compilers, "compilers_for_spec", compilers)
s.package.test_requires_compiler = True
s.package.tester.stand_alone_tests()
error = capfd.readouterr()[1]
assert "Skipping tests for package" in error
assert "test requires missing compiler" in error