diff options
Diffstat (limited to 'lib/spack/spack/test/multimethod.py')
-rw-r--r-- | lib/spack/spack/test/multimethod.py | 207 |
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 |