summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTamara Dahlgren <35777542+tldahlgren@users.noreply.github.com>2024-03-12 07:39:18 -0700
committerGitHub <noreply@github.com>2024-03-12 15:39:18 +0100
commit1e9c46296c352cf0179706382facfc3f37675a32 (patch)
tree46a809b342558aecb108a0c1d86b54d661f81317 /lib
parent48183b37beadd6bcd57d39d58b3cd8c825dab583 (diff)
downloadspack-1e9c46296c352cf0179706382facfc3f37675a32.tar.gz
spack-1e9c46296c352cf0179706382facfc3f37675a32.tar.bz2
spack-1e9c46296c352cf0179706382facfc3f37675a32.tar.xz
spack-1e9c46296c352cf0179706382facfc3f37675a32.zip
perl testing: refactor stand-alone testing into base class (#43044)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/build_systems/perlpackage.rst66
-rw-r--r--lib/spack/spack/build_systems/perl.py59
-rw-r--r--lib/spack/spack/test/cmd/test.py1
3 files changed, 124 insertions, 2 deletions
diff --git a/lib/spack/docs/build_systems/perlpackage.rst b/lib/spack/docs/build_systems/perlpackage.rst
index 49fb874525..fcfecf59f4 100644
--- a/lib/spack/docs/build_systems/perlpackage.rst
+++ b/lib/spack/docs/build_systems/perlpackage.rst
@@ -173,6 +173,72 @@ arguments to ``Makefile.PL`` or ``Build.PL`` by overriding
]
+^^^^^^^
+Testing
+^^^^^^^
+
+``PerlPackage`` provides a simple stand-alone test of the successfully
+installed package to confirm that installed perl module(s) can be used.
+These tests can be performed any time after the installation using
+``spack -v test run``. (For more information on the command, see
+:ref:`cmd-spack-test-run`.)
+
+The base class automatically detects perl modules based on the presence
+of ``*.pm`` files under the package's library directory. For example,
+the files under ``perl-bignum``'s perl library are:
+
+.. code-block:: console
+
+ $ find . -name "*.pm"
+ ./bigfloat.pm
+ ./bigrat.pm
+ ./Math/BigFloat/Trace.pm
+ ./Math/BigInt/Trace.pm
+ ./Math/BigRat/Trace.pm
+ ./bigint.pm
+ ./bignum.pm
+
+
+which results in the package having the ``use_modules`` property containing:
+
+.. code-block:: python
+
+ use_modules = [
+ "bigfloat",
+ "bigrat",
+ "Math::BigFloat::Trace",
+ "Math::BigInt::Trace",
+ "Math::BigRat::Trace",
+ "bigint",
+ "bignum",
+ ]
+
+.. note::
+
+ This list can often be used to catch missing dependencies.
+
+If the list is somehow wrong, you can provide the names of the modules
+yourself by overriding ``use_modules`` like so:
+
+ .. code-block:: python
+
+ use_modules = ["bigfloat", "bigrat", "bigint", "bignum"]
+
+If you only want a subset of the automatically detected modules to be
+tested, you could instead define the ``skip_modules`` property on the
+package. So, instead of overriding ``use_modules`` as shown above, you
+could define the following:
+
+ .. code-block:: python
+
+ skip_modules = [
+ "Math::BigFloat::Trace",
+ "Math::BigInt::Trace",
+ "Math::BigRat::Trace",
+ ]
+
+for the same use tests.
+
^^^^^^^^^^^^^^^^^^^^^
Alternatives to Spack
^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/spack/build_systems/perl.py b/lib/spack/spack/build_systems/perl.py
index ff28bfe672..773a6a98e6 100644
--- a/lib/spack/spack/build_systems/perl.py
+++ b/lib/spack/spack/build_systems/perl.py
@@ -4,12 +4,15 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import inspect
import os
+from typing import Iterable
-from llnl.util.filesystem import filter_file
+from llnl.util.filesystem import filter_file, find
+from llnl.util.lang import memoized
import spack.builder
import spack.package_base
from spack.directives import build_system, extends
+from spack.install_test import SkipTest, test_part
from spack.util.executable import Executable
from ._checks import BaseBuilder, execute_build_time_tests
@@ -28,6 +31,58 @@ class PerlPackage(spack.package_base.PackageBase):
extends("perl", when="build_system=perl")
+ @property
+ @memoized
+ def _platform_dir(self):
+ """Name of platform-specific module subdirectory."""
+ perl = self.spec["perl"].command
+ options = "-E", "use Config; say $Config{archname}"
+ out = perl(*options, output=str.split, error=str.split)
+ return out.strip()
+
+ @property
+ def use_modules(self) -> Iterable[str]:
+ """Names of the package's perl modules."""
+ module_files = find(self.prefix.lib, ["*.pm"], recursive=True)
+
+ # Drop the platform directory, if present
+ if self._platform_dir:
+ platform_dir = self._platform_dir + os.sep
+ module_files = [m.replace(platform_dir, "") for m in module_files]
+
+ # Drop the extension and library path
+ prefix = self.prefix.lib + os.sep
+ modules = [os.path.splitext(m)[0].replace(prefix, "") for m in module_files]
+
+ # Drop the perl subdirectory as well
+ return ["::".join(m.split(os.sep)[1:]) for m in modules]
+
+ @property
+ def skip_modules(self) -> Iterable[str]:
+ """Names of modules that should be skipped when running tests.
+
+ These are a subset of use_modules.
+
+ Returns:
+ List of strings of module names.
+ """
+ return []
+
+ def test_use(self):
+ """Test 'use module'"""
+ if not self.use_modules:
+ raise SkipTest("Test requires use_modules package property.")
+
+ perl = self.spec["perl"].command
+ for module in self.use_modules:
+ if module in self.skip_modules:
+ continue
+
+ with test_part(self, f"test_use-{module}", purpose=f"checking use of {module}"):
+ options = ["-we", f'use strict; use {module}; print("OK\n")']
+ out = perl(*options, output=str.split, error=str.split)
+ assert "OK" in out
+
@spack.builder.builder("perl")
class PerlBuilder(BaseBuilder):
@@ -52,7 +107,7 @@ class PerlBuilder(BaseBuilder):
phases = ("configure", "build", "install")
#: Names associated with package methods in the old build-system format
- legacy_methods = ("configure_args", "check")
+ legacy_methods = ("configure_args", "check", "test_use")
#: Names associated with package attributes in the old build-system format
legacy_attributes = ()
diff --git a/lib/spack/spack/test/cmd/test.py b/lib/spack/spack/test/cmd/test.py
index 3ed5077c78..0dab458739 100644
--- a/lib/spack/spack/test/cmd/test.py
+++ b/lib/spack/spack/test/cmd/test.py
@@ -221,6 +221,7 @@ def test_test_list_all(mock_packages):
[
"fail-test-audit",
"mpich",
+ "perl-extension",
"printing-package",
"py-extension1",
"py-extension2",