Relax architecture compatibility check (#15972)

* Relax architecture compatibility check
* Add test coverage for the spack.abi module
This commit is contained in:
Dennis Klein 2020-07-24 19:00:55 +02:00 committed by GitHub
parent 99c46e8186
commit 0c63c94103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 8 deletions

View File

@ -18,10 +18,13 @@ class ABI(object):
"""This class provides methods to test ABI compatibility between specs. """This class provides methods to test ABI compatibility between specs.
The current implementation is rather rough and could be improved.""" The current implementation is rather rough and could be improved."""
def architecture_compatible(self, parent, child): def architecture_compatible(self, target, constraint):
"""Return true if parent and child have ABI compatible targets.""" """Return true if architecture of target spec is ABI compatible
return not parent.architecture or not child.architecture or \ to the architecture of constraint spec. If either the target
parent.architecture == child.architecture or constraint specs have no architecture, target is also defined
as architecture ABI compatible to constraint."""
return not target.architecture or not constraint.architecture or \
target.architecture.satisfies(constraint.architecture)
@memoized @memoized
def _gcc_get_libstdcxx_version(self, version): def _gcc_get_libstdcxx_version(self, version):
@ -107,8 +110,8 @@ def compiler_compatible(self, parent, child, **kwargs):
return True return True
return False return False
def compatible(self, parent, child, **kwargs): def compatible(self, target, constraint, **kwargs):
"""Returns true iff a parent and child spec are ABI compatible""" """Returns true if target spec is ABI compatible to constraint spec"""
loosematch = kwargs.get('loose', False) loosematch = kwargs.get('loose', False)
return self.architecture_compatible(parent, child) and \ return self.architecture_compatible(target, constraint) and \
self.compiler_compatible(parent, child, loose=loosematch) self.compiler_compatible(target, constraint, loose=loosematch)

View File

@ -0,0 +1,66 @@
# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
""" Test ABI compatibility helpers"""
import pytest
from spack.abi import ABI
from spack.spec import Spec
@pytest.mark.parametrize(
'target,constraint,expected',
[
('foo', 'bar', True),
('platform=linux', 'foo', True),
('foo', 'arch=linux-fedora31-x86_64', True),
('arch=linux-fedora31-skylake', 'arch=linux-fedora31-skylake', True),
('arch=linux-fedora31-skylake', 'arch=linux-fedora31-x86_64', False),
('platform=linux os=fedora31', 'arch=linux-fedora31-x86_64', True),
('platform=linux', 'arch=linux-fedora31-x86_64', True),
('platform=linux os=fedora31', 'platform=linux', True),
('platform=darwin', 'arch=linux-fedora31-x86_64', False),
('os=fedora31', 'platform=linux', False), # TODO should be true ?
])
def test_architecture_compatibility(target, constraint, expected):
assert ABI().architecture_compatible(Spec(target),
Spec(constraint)) == expected
@pytest.mark.parametrize(
'target,constraint,loose,expected',
[
('foo', 'bar', False, True),
('%gcc', 'foo', False, True),
('foo', '%gcc', False, True),
('%gcc', '%gcc', False, True),
('%gcc', '%intel', False, False),
('%gcc', '%clang', False, False),
('%gcc@9.1', '%gcc@9.2', False, False), # TODO should be true ?
('%gcc@9.2.1', '%gcc@9.2.2', False, False), # TODO should be true ?
('%gcc@4.9', '%gcc@9.2', False, False),
('%clang@5', '%clang@6', False, False),
('%gcc@9.1', '%gcc@9.2', True, True),
('%gcc@9.2.1', '%gcc@9.2.2', True, True),
('%gcc@4.9', '%gcc@9.2', True, True),
('%clang@5', '%clang@6', True, True),
])
def test_compiler_compatibility(target, constraint, loose, expected):
assert ABI().compiler_compatible(Spec(target),
Spec(constraint),
loose=loose) == expected
@pytest.mark.parametrize('target,constraint,loose,expected', [
('foo', 'bar', False, True),
('%gcc', 'platform=linux', False, True),
('%gcc@9.2.1', '%gcc@8.3.1 platform=linux', False, False),
('%gcc@9.2.1', '%gcc@8.3.1 platform=linux', True, True),
('%gcc@9.2.1 arch=linux-fedora31-skylake', '%gcc@9.2.1 platform=linux',
False, True),
])
def test_compatibility(target, constraint, loose, expected):
assert ABI().compatible(Spec(target), Spec(constraint),
loose=loose) == expected