summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/multimethod.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/test/multimethod.py')
-rw-r--r--lib/spack/spack/test/multimethod.py207
1 files changed, 78 insertions, 129 deletions
diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py
index 4677a412bf..1e0cee71c7 100644
--- a/lib/spack/spack/test/multimethod.py
+++ b/lib/spack/spack/test/multimethod.py
@@ -4,13 +4,23 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Test for multi_method dispatch."""
+import os
+import sys
+
import pytest
import spack.platforms
import spack.repo
+import spack.spec
from spack.multimethod import NoSuchMethodError
-pytestmark = pytest.mark.usefixtures('mock_packages')
+pytestmark = [
+ pytest.mark.usefixtures('mock_packages', 'config'),
+ pytest.mark.skipif(
+ os.environ.get('SPACK_TEST_SOLVER') == 'original' or sys.platform == 'win32',
+ reason='The original concretizer cannot concretize most of the specs'
+ )
+]
@pytest.fixture(scope='module',
@@ -25,142 +35,81 @@ def pkg_name(request):
def test_no_version_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '@2.0')
+ spec = spack.spec.Spec(pkg_name + '@2.0').concretized()
with pytest.raises(NoSuchMethodError):
- pkg.no_version_2()
-
-
-def test_one_version_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '@1.0')
- assert pkg.no_version_2() == 1
-
- pkg = spack.repo.get(pkg_name + '@3.0')
- assert pkg.no_version_2() == 3
-
- pkg = spack.repo.get(pkg_name + '@4.0')
- assert pkg.no_version_2() == 4
-
-
-def test_version_overlap(pkg_name):
- pkg = spack.repo.get(pkg_name + '@2.0')
- assert pkg.version_overlap() == 1
-
- pkg = spack.repo.get(pkg_name + '@5.0')
- assert pkg.version_overlap() == 2
-
-
-def test_mpi_version(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich@3.0.4')
- assert pkg.mpi_version() == 3
-
- pkg = spack.repo.get(pkg_name + '^mpich2@1.2')
- assert pkg.mpi_version() == 2
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.0')
- assert pkg.mpi_version() == 1
-
-
-def test_undefined_mpi_version(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich@0.4')
- assert pkg.mpi_version() == 1
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.4')
- assert pkg.mpi_version() == 1
-
-
-def test_default_works(pkg_name):
- pkg = spack.repo.get(pkg_name + '%gcc')
- assert pkg.has_a_default() == 'gcc'
-
- pkg = spack.repo.get(pkg_name + '%intel')
- assert pkg.has_a_default() == 'intel'
-
- pkg = spack.repo.get(pkg_name + '%pgi')
- assert pkg.has_a_default() == 'default'
+ spec.package.no_version_2()
+
+
+@pytest.mark.parametrize('constraint_str,method_name,expected_result', [
+ # Only one version match these constraints
+ ('@1.0', 'no_version_2', 1),
+ ('@3.0', 'no_version_2', 3),
+ ('@4.0', 'no_version_2', 4),
+ # These constraints overlap, in which case the first match wins
+ ('@2.0', 'version_overlap', 1),
+ ('@5.0', 'version_overlap', 2),
+ # These constraints are on the version of a virtual dependency
+ ('^mpich@3.0.4', 'mpi_version', 3),
+ ('^mpich2@1.2', 'mpi_version', 2),
+ ('^mpich@1.0', 'mpi_version', 1),
+ # Undefined mpi versions
+ ('^mpich@0.4', 'mpi_version', 1),
+ ('^mpich@1.4', 'mpi_version', 1),
+ # Constraints on compilers with a default
+ ('%gcc', 'has_a_default', 'gcc'),
+ ('%clang', 'has_a_default', 'clang'),
+ ('%apple-clang os=elcapitan', 'has_a_default', 'default'),
+ # Constraints on dependencies
+ ('^zmpi', 'different_by_dep', 'zmpi'),
+ ('^mpich', 'different_by_dep', 'mpich'),
+ # Constraints on virtual dependencies
+ ('^mpich2', 'different_by_virtual_dep', 2),
+ ('^mpich@1.0', 'different_by_virtual_dep', 1),
+ # Multimethod with base classes
+ ('@1', 'base_method', 'base_method'),
+ # Boolean
+ ('', 'boolean_true_first', 'True'),
+ ('', 'boolean_false_first', 'True')
+])
+def test_multimethod_calls(pkg_name, constraint_str, method_name, expected_result):
+ s = spack.spec.Spec(pkg_name + constraint_str).concretized()
+ msg = "Method {0} from {1} is giving a wrong result".format(method_name, s)
+ assert getattr(s.package, method_name)() == expected_result, msg
def test_target_match(pkg_name):
platform = spack.platforms.host()
targets = list(platform.targets.values())
for target in targets[:-1]:
- pkg = spack.repo.get(pkg_name + ' target=' + target.name)
- assert pkg.different_by_target() == target.name
+ s = spack.spec.Spec(pkg_name + ' target=' + target.name).concretized()
+ assert s.package.different_by_target() == target.name
- pkg = spack.repo.get(pkg_name + ' target=' + targets[-1].name)
+ s = spack.spec.Spec(pkg_name + ' target=' + targets[-1].name).concretized()
if len(targets) == 1:
- assert pkg.different_by_target() == targets[-1].name
+ assert s.package.different_by_target() == targets[-1].name
else:
with pytest.raises(NoSuchMethodError):
- pkg.different_by_target()
-
-
-def test_dependency_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '^zmpi')
- assert pkg.different_by_dep() == 'zmpi'
-
- pkg = spack.repo.get(pkg_name + '^mpich')
- assert pkg.different_by_dep() == 'mpich'
-
- # If we try to switch on some entirely different dep, it's ambiguous,
- # but should take the first option
- pkg = spack.repo.get(pkg_name + '^foobar')
- assert pkg.different_by_dep() == 'mpich'
-
-
-def test_virtual_dep_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich2')
- assert pkg.different_by_virtual_dep() == 2
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.0')
- assert pkg.different_by_virtual_dep() == 1
-
-
-def test_multimethod_with_base_class(pkg_name):
- pkg = spack.repo.get(pkg_name + '@3')
- assert pkg.base_method() == pkg.spec.name
-
- pkg = spack.repo.get(pkg_name + '@1')
- assert pkg.base_method() == "base_method"
-
-
-def test_multimethod_inherited_and_overridden():
- pkg = spack.repo.get('multimethod-inheritor@1.0')
- assert pkg.inherited_and_overridden() == 'inheritor@1.0'
-
- pkg = spack.repo.get('multimethod-inheritor@2.0')
- assert pkg.inherited_and_overridden() == 'base@2.0'
-
- pkg = spack.repo.get('multimethod@1.0')
- assert pkg.inherited_and_overridden() == 'base@1.0'
-
- pkg = spack.repo.get('multimethod@2.0')
- assert pkg.inherited_and_overridden() == 'base@2.0'
-
-
-def test_multimethod_diamond_inheritance():
- pkg = spack.repo.get('multimethod-diamond@1.0')
- assert pkg.diamond_inheritance() == 'base_package'
-
- pkg = spack.repo.get('multimethod-base@1.0')
- assert pkg.diamond_inheritance() == 'base_package'
-
- pkg = spack.repo.get('multimethod-diamond@2.0')
- assert pkg.diamond_inheritance() == 'first_parent'
-
- pkg = spack.repo.get('multimethod-inheritor@2.0')
- assert pkg.diamond_inheritance() == 'first_parent'
-
- pkg = spack.repo.get('multimethod-diamond@3.0')
- assert pkg.diamond_inheritance() == 'second_parent'
-
- pkg = spack.repo.get('multimethod-diamond-parent@3.0')
- assert pkg.diamond_inheritance() == 'second_parent'
-
- pkg = spack.repo.get('multimethod-diamond@4.0')
- assert pkg.diamond_inheritance() == 'subclass'
-
-
-def test_multimethod_boolean(pkg_name):
- pkg = spack.repo.get(pkg_name)
- assert pkg.boolean_true_first() == 'True'
- assert pkg.boolean_false_first() == 'True'
+ s.package.different_by_target()
+
+
+@pytest.mark.parametrize('spec_str,method_name,expected_result', [
+ # This is overridden in the second case
+ ('multimethod@3', 'base_method', 'multimethod'),
+ ('multimethod-inheritor@3', 'base_method', 'multimethod-inheritor'),
+ # Here we have a mix of inherited and overridden methods
+ ('multimethod-inheritor@1.0', 'inherited_and_overridden', 'inheritor@1.0'),
+ ('multimethod-inheritor@2.0', 'inherited_and_overridden', 'base@2.0'),
+ ('multimethod@1.0', 'inherited_and_overridden', 'base@1.0'),
+ ('multimethod@2.0', 'inherited_and_overridden', 'base@2.0'),
+ # Diamond-like inheritance (even though the MRO linearize everything)
+ ('multimethod-diamond@1.0', 'diamond_inheritance', 'base_package'),
+ ('multimethod-base@1.0', 'diamond_inheritance', 'base_package'),
+ ('multimethod-diamond@2.0', 'diamond_inheritance', 'first_parent'),
+ ('multimethod-inheritor@2.0', 'diamond_inheritance', 'first_parent'),
+ ('multimethod-diamond@3.0', 'diamond_inheritance', 'second_parent'),
+ ('multimethod-diamond-parent@3.0', 'diamond_inheritance', 'second_parent'),
+ ('multimethod-diamond@4.0', 'diamond_inheritance', 'subclass'),
+])
+def test_multimethod_calls_and_inheritance(spec_str, method_name, expected_result):
+ s = spack.spec.Spec(spec_str).concretized()
+ assert getattr(s.package, method_name)() == expected_result