tests: each mock package now has its own class (#16157)
Packages in Spack are classes, and we need to be able to execute class methods on mock packages. The previous design used instances of a single MockPackage class; this version gives each package its own class that can spider depenencies. This allows us to implement class methods like `possible_dependencies()` on mock packages. This design change moves mock package creation into the `MockPackageMultiRepo`, and mock packages now *must* be created from a repo. This is required for us to mock `possible_dependencies()`, which needs to be able to get dependency packages from the package repo. Changes include: * `MockPackage` is now `MockPackageBase` * `MockPackageBase` instances must now be created with `MockPackageMultiRepo.add_package()` * add `possible_dependencies()` method to `MockPackageBase` * refactor tests to use new code structure * move package mocking infrastructure into `spack.util.mock_package`, as it's becoming a more sophisticated class and it gets lots in `conftest.py`
This commit is contained in:
parent
433a0b243f
commit
c6ada206af
9 changed files with 279 additions and 153 deletions
|
@ -18,7 +18,7 @@
|
||||||
import spack.paths as spack_paths
|
import spack.paths as spack_paths
|
||||||
import spack.repo as repo
|
import spack.repo as repo
|
||||||
from spack.spec import Spec
|
from spack.spec import Spec
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
import spack.util.executable as exe
|
import spack.util.executable as exe
|
||||||
import spack.util.spack_yaml as syaml
|
import spack.util.spack_yaml as syaml
|
||||||
import spack.util.gpg
|
import spack.util.gpg
|
||||||
|
@ -101,15 +101,14 @@ def test_specs_staging(config):
|
||||||
"""
|
"""
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
|
|
||||||
g = MockPackage('g', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
f = MockPackage('f', [], [])
|
g = mock_repo.add_package('g', [], [])
|
||||||
e = MockPackage('e', [], [])
|
f = mock_repo.add_package('f', [], [])
|
||||||
d = MockPackage('d', [f, g], [default, default])
|
e = mock_repo.add_package('e', [], [])
|
||||||
c = MockPackage('c', [], [])
|
d = mock_repo.add_package('d', [f, g], [default, default])
|
||||||
b = MockPackage('b', [d, e], [default, default])
|
c = mock_repo.add_package('c', [], [])
|
||||||
a = MockPackage('a', [b, c], [default, default])
|
b = mock_repo.add_package('b', [d, e], [default, default])
|
||||||
|
mock_repo.add_package('a', [b, c], [default, default])
|
||||||
mock_repo = MockPackageMultiRepo([a, b, c, d, e, f, g])
|
|
||||||
|
|
||||||
with repo.swap(mock_repo):
|
with repo.swap(mock_repo):
|
||||||
spec_a = Spec('a')
|
spec_a = Spec('a')
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
from spack.stage import stage_prefix
|
from spack.stage import stage_prefix
|
||||||
|
|
||||||
from spack.spec_list import SpecListError
|
from spack.spec_list import SpecListError
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
import spack.util.spack_json as sjson
|
import spack.util.spack_json as sjson
|
||||||
|
|
||||||
|
|
||||||
|
@ -733,10 +733,10 @@ def create_v1_lockfile_dict(roots, all_specs):
|
||||||
def test_read_old_lock_and_write_new(tmpdir):
|
def test_read_old_lock_and_write_new(tmpdir):
|
||||||
build_only = ('build',)
|
build_only = ('build',)
|
||||||
|
|
||||||
y = MockPackage('y', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
x = MockPackage('x', [y], [build_only])
|
y = mock_repo.add_package('y', [], [])
|
||||||
|
mock_repo.add_package('x', [y], [build_only])
|
||||||
|
|
||||||
mock_repo = MockPackageMultiRepo([x, y])
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
x = Spec('x')
|
x = Spec('x')
|
||||||
x.concretize()
|
x.concretize()
|
||||||
|
@ -765,9 +765,9 @@ def test_read_old_lock_creates_backup(tmpdir):
|
||||||
"""When reading a version-1 lockfile, make sure that a backup of that file
|
"""When reading a version-1 lockfile, make sure that a backup of that file
|
||||||
is created.
|
is created.
|
||||||
"""
|
"""
|
||||||
y = MockPackage('y', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
|
y = mock_repo.add_package('y', [], [])
|
||||||
|
|
||||||
mock_repo = MockPackageMultiRepo([y])
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
y = Spec('y')
|
y = Spec('y')
|
||||||
y.concretize()
|
y.concretize()
|
||||||
|
@ -796,11 +796,10 @@ def test_indirect_build_dep():
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
build_only = ('build',)
|
build_only = ('build',)
|
||||||
|
|
||||||
z = MockPackage('z', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
y = MockPackage('y', [z], [build_only])
|
z = mock_repo.add_package('z', [], [])
|
||||||
x = MockPackage('x', [y], [default])
|
y = mock_repo.add_package('y', [z], [build_only])
|
||||||
|
mock_repo.add_package('x', [y], [default])
|
||||||
mock_repo = MockPackageMultiRepo([x, y, z])
|
|
||||||
|
|
||||||
def noop(*args):
|
def noop(*args):
|
||||||
pass
|
pass
|
||||||
|
@ -838,11 +837,10 @@ def test_store_different_build_deps():
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
build_only = ('build',)
|
build_only = ('build',)
|
||||||
|
|
||||||
z = MockPackage('z', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
y = MockPackage('y', [z], [build_only])
|
z = mock_repo.add_package('z', [], [])
|
||||||
x = MockPackage('x', [y, z], [default, build_only])
|
y = mock_repo.add_package('y', [z], [build_only])
|
||||||
|
mock_repo.add_package('x', [y, z], [default, build_only])
|
||||||
mock_repo = MockPackageMultiRepo([x, y, z])
|
|
||||||
|
|
||||||
def noop(*args):
|
def noop(*args):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
from spack.package_prefs import PackagePrefs
|
from spack.package_prefs import PackagePrefs
|
||||||
from spack.spec import Spec, CompilerSpec, ConflictsInSpecError
|
from spack.spec import Spec, CompilerSpec, ConflictsInSpecError
|
||||||
from spack.version import ver
|
from spack.version import ver
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
import spack.compilers
|
import spack.compilers
|
||||||
import spack.platforms.test
|
import spack.platforms.test
|
||||||
|
|
||||||
|
@ -235,10 +235,10 @@ def test_architecture_deep_inheritance(self):
|
||||||
"""
|
"""
|
||||||
default_dep = ('link', 'build')
|
default_dep = ('link', 'build')
|
||||||
|
|
||||||
bazpkg = MockPackage('bazpkg', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
barpkg = MockPackage('barpkg', [bazpkg], [default_dep])
|
bazpkg = mock_repo.add_package('bazpkg', [], [])
|
||||||
foopkg = MockPackage('foopkg', [barpkg], [default_dep])
|
barpkg = mock_repo.add_package('barpkg', [bazpkg], [default_dep])
|
||||||
mock_repo = MockPackageMultiRepo([foopkg, barpkg, bazpkg])
|
mock_repo.add_package('foopkg', [barpkg], [default_dep])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = Spec('foopkg %clang@3.3 os=CNL target=footar' +
|
spec = Spec('foopkg %clang@3.3 os=CNL target=footar' +
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
import tempfile
|
import tempfile
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
|
|
||||||
import ordereddict_backport
|
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
import ruamel.yaml as yaml
|
import ruamel.yaml as yaml
|
||||||
|
@ -38,11 +37,8 @@
|
||||||
import spack.util.gpg
|
import spack.util.gpg
|
||||||
|
|
||||||
from spack.util.pattern import Bunch
|
from spack.util.pattern import Bunch
|
||||||
from spack.dependency import Dependency
|
|
||||||
from spack.fetch_strategy import FetchStrategyComposite, URLFetchStrategy
|
from spack.fetch_strategy import FetchStrategyComposite, URLFetchStrategy
|
||||||
from spack.fetch_strategy import FetchError
|
from spack.fetch_strategy import FetchError
|
||||||
from spack.spec import Spec
|
|
||||||
from spack.version import Version
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -1004,75 +1000,6 @@ def installation_dir_with_headers(tmpdir_factory):
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
##########
|
|
||||||
# Mock packages
|
|
||||||
##########
|
|
||||||
|
|
||||||
|
|
||||||
class MockPackage(object):
|
|
||||||
def __init__(self, name, dependencies, dependency_types, conditions=None,
|
|
||||||
versions=None):
|
|
||||||
self.name = name
|
|
||||||
self.spec = None
|
|
||||||
self.dependencies = ordereddict_backport.OrderedDict()
|
|
||||||
self._installed_upstream = False
|
|
||||||
|
|
||||||
assert len(dependencies) == len(dependency_types)
|
|
||||||
for dep, dtype in zip(dependencies, dependency_types):
|
|
||||||
d = Dependency(self, Spec(dep.name), type=dtype)
|
|
||||||
if not conditions or dep.name not in conditions:
|
|
||||||
self.dependencies[dep.name] = {Spec(name): d}
|
|
||||||
else:
|
|
||||||
dep_conditions = conditions[dep.name]
|
|
||||||
dep_conditions = dict(
|
|
||||||
(Spec(x), Dependency(self, Spec(y), type=dtype))
|
|
||||||
for x, y in dep_conditions.items())
|
|
||||||
self.dependencies[dep.name] = dep_conditions
|
|
||||||
|
|
||||||
if versions:
|
|
||||||
self.versions = versions
|
|
||||||
else:
|
|
||||||
versions = list(Version(x) for x in [1, 2, 3])
|
|
||||||
self.versions = dict((x, {'preferred': False}) for x in versions)
|
|
||||||
|
|
||||||
self.variants = {}
|
|
||||||
self.provided = {}
|
|
||||||
self.conflicts = {}
|
|
||||||
self.patches = {}
|
|
||||||
|
|
||||||
def provides(self, vname):
|
|
||||||
return vname in self.provided
|
|
||||||
|
|
||||||
@property
|
|
||||||
def virtuals_provided(self):
|
|
||||||
return [v.name for v, c in self.provided]
|
|
||||||
|
|
||||||
|
|
||||||
class MockPackageMultiRepo(object):
|
|
||||||
def __init__(self, packages):
|
|
||||||
self.spec_to_pkg = dict((x.name, x) for x in packages)
|
|
||||||
self.spec_to_pkg.update(
|
|
||||||
dict(('mockrepo.' + x.name, x) for x in packages))
|
|
||||||
|
|
||||||
def get(self, spec):
|
|
||||||
if not isinstance(spec, spack.spec.Spec):
|
|
||||||
spec = Spec(spec)
|
|
||||||
return self.spec_to_pkg[spec.name]
|
|
||||||
|
|
||||||
def get_pkg_class(self, name):
|
|
||||||
return self.spec_to_pkg[name]
|
|
||||||
|
|
||||||
def exists(self, name):
|
|
||||||
return name in self.spec_to_pkg
|
|
||||||
|
|
||||||
def is_virtual(self, name):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def repo_for_pkg(self, name):
|
|
||||||
import collections
|
|
||||||
Repo = collections.namedtuple('Repo', ['namespace'])
|
|
||||||
return Repo('mockrepo')
|
|
||||||
|
|
||||||
##########
|
##########
|
||||||
# Specs of various kind
|
# Specs of various kind
|
||||||
##########
|
##########
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
import spack.database
|
import spack.database
|
||||||
import spack.package
|
import spack.package
|
||||||
import spack.spec
|
import spack.spec
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
from spack.util.executable import Executable
|
from spack.util.executable import Executable
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,11 +73,11 @@ def test_installed_upstream(upstream_and_downstream_db):
|
||||||
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
||||||
|
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
x = MockPackage('x', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
z = MockPackage('z', [], [])
|
x = mock_repo.add_package('x', [], [])
|
||||||
y = MockPackage('y', [z], [default])
|
z = mock_repo.add_package('z', [], [])
|
||||||
w = MockPackage('w', [x, y], [default, default])
|
y = mock_repo.add_package('y', [z], [default])
|
||||||
mock_repo = MockPackageMultiRepo([w, x, y, z])
|
mock_repo.add_package('w', [x, y], [default, default])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = spack.spec.Spec('w')
|
spec = spack.spec.Spec('w')
|
||||||
|
@ -116,9 +116,9 @@ def test_removed_upstream_dep(upstream_and_downstream_db):
|
||||||
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
||||||
|
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
z = MockPackage('z', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
y = MockPackage('y', [z], [default])
|
z = mock_repo.add_package('z', [], [])
|
||||||
mock_repo = MockPackageMultiRepo([y, z])
|
mock_repo.add_package('y', [z], [default])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = spack.spec.Spec('y')
|
spec = spack.spec.Spec('y')
|
||||||
|
@ -150,8 +150,8 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db):
|
||||||
upstream_write_db, upstream_db, upstream_layout,\
|
upstream_write_db, upstream_db, upstream_layout,\
|
||||||
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
downstream_db, downstream_layout = (upstream_and_downstream_db)
|
||||||
|
|
||||||
x = MockPackage('x', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
mock_repo = MockPackageMultiRepo([x])
|
mock_repo.add_package('x', [], [])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = spack.spec.Spec('x')
|
spec = spack.spec.Spec('x')
|
||||||
|
@ -183,8 +183,8 @@ def test_cannot_write_upstream(tmpdir_factory, test_store, gen_mock_layout):
|
||||||
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b']]
|
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b']]
|
||||||
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/']]
|
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/']]
|
||||||
|
|
||||||
x = MockPackage('x', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
mock_repo = MockPackageMultiRepo([x])
|
mock_repo.add_package('x', [], [])
|
||||||
|
|
||||||
# Instantiate the database that will be used as the upstream DB and make
|
# Instantiate the database that will be used as the upstream DB and make
|
||||||
# sure it has an index file
|
# sure it has an index file
|
||||||
|
@ -209,11 +209,10 @@ def test_recursive_upstream_dbs(tmpdir_factory, test_store, gen_mock_layout):
|
||||||
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/', '/rc/']]
|
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/', '/rc/']]
|
||||||
|
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
z = MockPackage('z', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
y = MockPackage('y', [z], [default])
|
z = mock_repo.add_package('z', [], [])
|
||||||
x = MockPackage('x', [y], [default])
|
y = mock_repo.add_package('y', [z], [default])
|
||||||
|
mock_repo.add_package('x', [y], [default])
|
||||||
mock_repo = MockPackageMultiRepo([x, y, z])
|
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = spack.spec.Spec('x')
|
spec = spack.spec.Spec('x')
|
||||||
|
@ -675,7 +674,7 @@ def test_115_reindex_with_packages_not_in_repo(mutable_database):
|
||||||
# Dont add any package definitions to this repository, the idea is that
|
# Dont add any package definitions to this repository, the idea is that
|
||||||
# packages should not have to be defined in the repository once they
|
# packages should not have to be defined in the repository once they
|
||||||
# are installed
|
# are installed
|
||||||
with spack.repo.swap(MockPackageMultiRepo([])):
|
with spack.repo.swap(MockPackageMultiRepo()):
|
||||||
spack.store.store.reindex()
|
spack.store.store.reindex()
|
||||||
_check_db_sanity(mutable_database)
|
_check_db_sanity(mutable_database)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
from spack.spec import Spec
|
from spack.spec import Spec
|
||||||
from spack.dependency import all_deptypes, Dependency, canonical_deptype
|
from spack.dependency import all_deptypes, Dependency, canonical_deptype
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
|
|
||||||
|
|
||||||
def check_links(spec_to_check):
|
def check_links(spec_to_check):
|
||||||
|
@ -69,12 +69,12 @@ def test_test_deptype():
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
test_only = ('test',)
|
test_only = ('test',)
|
||||||
|
|
||||||
x = MockPackage('x', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
z = MockPackage('z', [], [])
|
x = mock_repo.add_package('x', [], [])
|
||||||
y = MockPackage('y', [z], [test_only])
|
z = mock_repo.add_package('z', [], [])
|
||||||
w = MockPackage('w', [x, y], [test_only, default])
|
y = mock_repo.add_package('y', [z], [test_only])
|
||||||
|
w = mock_repo.add_package('w', [x, y], [test_only, default])
|
||||||
|
|
||||||
mock_repo = MockPackageMultiRepo([w, x, y, z])
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = Spec('w')
|
spec = Spec('w')
|
||||||
spec.concretize(tests=(w.name,))
|
spec.concretize(tests=(w.name,))
|
||||||
|
@ -93,8 +93,9 @@ def test_installed_deps():
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
build_only = ('build',)
|
build_only = ('build',)
|
||||||
|
|
||||||
e = MockPackage('e', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
d = MockPackage('d', [], [])
|
e = mock_repo.add_package('e', [], [])
|
||||||
|
d = mock_repo.add_package('d', [], [])
|
||||||
c_conditions = {
|
c_conditions = {
|
||||||
d.name: {
|
d.name: {
|
||||||
'c': 'd@2'
|
'c': 'd@2'
|
||||||
|
@ -103,11 +104,10 @@ def test_installed_deps():
|
||||||
'c': 'e@2'
|
'c': 'e@2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = MockPackage('c', [d, e], [build_only, default],
|
c = mock_repo.add_package('c', [d, e], [build_only, default],
|
||||||
conditions=c_conditions)
|
conditions=c_conditions)
|
||||||
b = MockPackage('b', [d, e], [default, default])
|
b = mock_repo.add_package('b', [d, e], [default, default])
|
||||||
a = MockPackage('a', [b, c], [default, default])
|
mock_repo.add_package('a', [b, c], [default, default])
|
||||||
mock_repo = MockPackageMultiRepo([a, b, c, d, e])
|
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
c_spec = Spec('c')
|
c_spec = Spec('c')
|
||||||
|
@ -133,10 +133,10 @@ def test_specify_preinstalled_dep():
|
||||||
"""
|
"""
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
|
|
||||||
c = MockPackage('c', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
b = MockPackage('b', [c], [default])
|
c = mock_repo.add_package('c', [], [])
|
||||||
a = MockPackage('a', [b], [default])
|
b = mock_repo.add_package('b', [c], [default])
|
||||||
mock_repo = MockPackageMultiRepo([a, b, c])
|
mock_repo.add_package('a', [b], [default])
|
||||||
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
b_spec = Spec('b')
|
b_spec = Spec('b')
|
||||||
|
@ -161,15 +161,15 @@ def test_conditional_dep_with_user_constraints():
|
||||||
"""
|
"""
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
|
|
||||||
y = MockPackage('y', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
|
y = mock_repo.add_package('y', [], [])
|
||||||
x_on_y_conditions = {
|
x_on_y_conditions = {
|
||||||
y.name: {
|
y.name: {
|
||||||
'x@2:': 'y'
|
'x@2:': 'y'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x = MockPackage('x', [y], [default], conditions=x_on_y_conditions)
|
mock_repo.add_package('x', [y], [default], conditions=x_on_y_conditions)
|
||||||
|
|
||||||
mock_repo = MockPackageMultiRepo([x, y])
|
|
||||||
with spack.repo.swap(mock_repo):
|
with spack.repo.swap(mock_repo):
|
||||||
spec = Spec('x ^y@2')
|
spec = Spec('x ^y@2')
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
from spack import repo
|
from spack import repo
|
||||||
from spack.spec import Spec, save_dependency_spec_yamls
|
from spack.spec import Spec, save_dependency_spec_yamls
|
||||||
from spack.util.spack_yaml import syaml_dict
|
from spack.util.spack_yaml import syaml_dict
|
||||||
from spack.test.conftest import MockPackage, MockPackageMultiRepo
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
|
|
||||||
|
|
||||||
def check_yaml_round_trip(spec):
|
def check_yaml_round_trip(spec):
|
||||||
|
@ -301,15 +301,14 @@ def test_save_dependency_spec_yamls_subset(tmpdir, config):
|
||||||
|
|
||||||
default = ('build', 'link')
|
default = ('build', 'link')
|
||||||
|
|
||||||
g = MockPackage('g', [], [])
|
mock_repo = MockPackageMultiRepo()
|
||||||
f = MockPackage('f', [], [])
|
g = mock_repo.add_package('g', [], [])
|
||||||
e = MockPackage('e', [], [])
|
f = mock_repo.add_package('f', [], [])
|
||||||
d = MockPackage('d', [f, g], [default, default])
|
e = mock_repo.add_package('e', [], [])
|
||||||
c = MockPackage('c', [], [])
|
d = mock_repo.add_package('d', [f, g], [default, default])
|
||||||
b = MockPackage('b', [d, e], [default, default])
|
c = mock_repo.add_package('c', [], [])
|
||||||
a = MockPackage('a', [b, c], [default, default])
|
b = mock_repo.add_package('b', [d, e], [default, default])
|
||||||
|
mock_repo.add_package('a', [b, c], [default, default])
|
||||||
mock_repo = MockPackageMultiRepo([a, b, c, d, e, f, g])
|
|
||||||
|
|
||||||
with repo.swap(mock_repo):
|
with repo.swap(mock_repo):
|
||||||
spec_a = Spec('a')
|
spec_a = Spec('a')
|
||||||
|
|
43
lib/spack/spack/test/util/mock_package.py
Normal file
43
lib/spack/spack/test/util/mock_package.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
import spack.repo
|
||||||
|
from spack.util.mock_package import MockPackageMultiRepo
|
||||||
|
|
||||||
|
|
||||||
|
def test_mock_package_possible_dependencies():
|
||||||
|
mock_repo = MockPackageMultiRepo()
|
||||||
|
e = mock_repo.add_package('e')
|
||||||
|
d = mock_repo.add_package('d', [e])
|
||||||
|
c = mock_repo.add_package('c', [d])
|
||||||
|
b = mock_repo.add_package('b', [d])
|
||||||
|
a = mock_repo.add_package('a', [b, c])
|
||||||
|
|
||||||
|
with spack.repo.swap(mock_repo):
|
||||||
|
assert set(a.possible_dependencies()) == set(['a', 'b', 'c', 'd', 'e'])
|
||||||
|
assert set(b.possible_dependencies()) == set(['b', 'd', 'e'])
|
||||||
|
assert set(c.possible_dependencies()) == set(['c', 'd', 'e'])
|
||||||
|
assert set(d.possible_dependencies()) == set(['d', 'e'])
|
||||||
|
assert set(e.possible_dependencies()) == set(['e'])
|
||||||
|
|
||||||
|
assert set(
|
||||||
|
a.possible_dependencies(transitive=False)) == set(['a', 'b', 'c'])
|
||||||
|
assert set(
|
||||||
|
b.possible_dependencies(transitive=False)) == set(['b', 'd'])
|
||||||
|
assert set(
|
||||||
|
c.possible_dependencies(transitive=False)) == set(['c', 'd'])
|
||||||
|
assert set(
|
||||||
|
d.possible_dependencies(transitive=False)) == set(['d', 'e'])
|
||||||
|
assert set(
|
||||||
|
e.possible_dependencies(transitive=False)) == set(['e'])
|
||||||
|
|
||||||
|
|
||||||
|
def test_mock_repo_is_virtual():
|
||||||
|
mock_repo = MockPackageMultiRepo()
|
||||||
|
|
||||||
|
# current implementation is always false
|
||||||
|
assert mock_repo.is_virtual("foo") is False
|
||||||
|
assert mock_repo.is_virtual("bar") is False
|
||||||
|
assert mock_repo.is_virtual("baz") is False
|
161
lib/spack/spack/util/mock_package.py
Normal file
161
lib/spack/spack/util/mock_package.py
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
"""Infrastructure used by tests for mocking packages and repos."""
|
||||||
|
|
||||||
|
import ordereddict_backport
|
||||||
|
|
||||||
|
import spack.util.naming
|
||||||
|
from spack.dependency import Dependency
|
||||||
|
from spack.spec import Spec
|
||||||
|
from spack.version import Version
|
||||||
|
|
||||||
|
__all__ = ["MockPackageMultiRepo"]
|
||||||
|
|
||||||
|
|
||||||
|
class MockPackageBase(object):
|
||||||
|
"""Internal base class for mocking ``spack.package.PackageBase``.
|
||||||
|
|
||||||
|
Use ``MockPackageMultiRepo.add_package()`` to create new instances.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def __init__(self, dependencies, dependency_types,
|
||||||
|
conditions=None, versions=None):
|
||||||
|
"""Instantiate a new MockPackageBase.
|
||||||
|
|
||||||
|
This is not for general use; it needs to be constructed by a
|
||||||
|
``MockPackageMultiRepo``, as we need to know about *all* packages
|
||||||
|
to find possible depenencies.
|
||||||
|
|
||||||
|
"""
|
||||||
|
self.spec = None
|
||||||
|
self._installed_upstream = False
|
||||||
|
|
||||||
|
def provides(self, vname):
|
||||||
|
return vname in self.provided
|
||||||
|
|
||||||
|
@property
|
||||||
|
def virtuals_provided(self):
|
||||||
|
return [v.name for v, c in self.provided]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def possible_dependencies(
|
||||||
|
cls, transitive=True, deptype='all', visited=None, virtuals=None):
|
||||||
|
visited = {} if visited is None else visited
|
||||||
|
|
||||||
|
for name, conditions in cls.dependencies.items():
|
||||||
|
# check whether this dependency could be of the type asked for
|
||||||
|
types = [dep.type for cond, dep in conditions.items()]
|
||||||
|
types = set.union(*types)
|
||||||
|
if not any(d in types for d in deptype):
|
||||||
|
continue
|
||||||
|
|
||||||
|
visited.setdefault(cls.name, set())
|
||||||
|
for dep_name in cls.dependencies:
|
||||||
|
if dep_name in visited:
|
||||||
|
continue
|
||||||
|
|
||||||
|
visited.setdefault(dep_name, set())
|
||||||
|
|
||||||
|
if not transitive:
|
||||||
|
continue
|
||||||
|
|
||||||
|
cls._repo.get(dep_name).possible_dependencies(
|
||||||
|
transitive, deptype, visited, virtuals)
|
||||||
|
|
||||||
|
return visited
|
||||||
|
|
||||||
|
|
||||||
|
class MockPackageMultiRepo(object):
|
||||||
|
"""Mock package repository, mimicking ``spack.repo.Repo``."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.spec_to_pkg = {}
|
||||||
|
|
||||||
|
def get(self, spec):
|
||||||
|
if not isinstance(spec, spack.spec.Spec):
|
||||||
|
spec = Spec(spec)
|
||||||
|
return self.spec_to_pkg[spec.name]
|
||||||
|
|
||||||
|
def get_pkg_class(self, name):
|
||||||
|
return self.spec_to_pkg[name]
|
||||||
|
|
||||||
|
def exists(self, name):
|
||||||
|
return name in self.spec_to_pkg
|
||||||
|
|
||||||
|
def is_virtual(self, name):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def repo_for_pkg(self, name):
|
||||||
|
import collections
|
||||||
|
Repo = collections.namedtuple('Repo', ['namespace'])
|
||||||
|
return Repo('mockrepo')
|
||||||
|
|
||||||
|
def add_package(self, name, dependencies=None, dependency_types=None,
|
||||||
|
conditions=None):
|
||||||
|
"""Factory method for creating mock packages.
|
||||||
|
|
||||||
|
This creates a new subclass of ``MockPackageBase``, ensures that its
|
||||||
|
``name`` and ``__name__`` properties are set up correctly, and
|
||||||
|
returns a new instance.
|
||||||
|
|
||||||
|
We use a factory function here because many functions and properties
|
||||||
|
of packages need to be class functions.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): name of the new package
|
||||||
|
dependencies (list): list of mock packages to be dependencies
|
||||||
|
for this new package (optional; no deps if not provided)
|
||||||
|
dependency_type (list): list of deptypes for each dependency
|
||||||
|
(optional; will be default_deptype if not provided)
|
||||||
|
conditions (list): condition specs for each dependency (optional)
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not dependencies:
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
if not dependency_types:
|
||||||
|
dependency_types = [
|
||||||
|
spack.dependency.default_deptype] * len(dependencies)
|
||||||
|
|
||||||
|
assert len(dependencies) == len(dependency_types)
|
||||||
|
|
||||||
|
# new class for the mock package
|
||||||
|
class MockPackage(MockPackageBase):
|
||||||
|
pass
|
||||||
|
MockPackage.__name__ = spack.util.naming.mod_to_class(name)
|
||||||
|
MockPackage.name = name
|
||||||
|
MockPackage._repo = self
|
||||||
|
|
||||||
|
# set up dependencies
|
||||||
|
MockPackage.dependencies = ordereddict_backport.OrderedDict()
|
||||||
|
for dep, dtype in zip(dependencies, dependency_types):
|
||||||
|
d = Dependency(MockPackage, Spec(dep.name), type=dtype)
|
||||||
|
if not conditions or dep.name not in conditions:
|
||||||
|
MockPackage.dependencies[dep.name] = {Spec(name): d}
|
||||||
|
else:
|
||||||
|
dep_conditions = conditions[dep.name]
|
||||||
|
dep_conditions = dict(
|
||||||
|
(Spec(x), Dependency(MockPackage, Spec(y), type=dtype))
|
||||||
|
for x, y in dep_conditions.items())
|
||||||
|
MockPackage.dependencies[dep.name] = dep_conditions
|
||||||
|
|
||||||
|
# each package has some fake versions
|
||||||
|
versions = list(Version(x) for x in [1, 2, 3])
|
||||||
|
MockPackage.versions = dict(
|
||||||
|
(x, {'preferred': False}) for x in versions
|
||||||
|
)
|
||||||
|
|
||||||
|
MockPackage.variants = {}
|
||||||
|
MockPackage.provided = {}
|
||||||
|
MockPackage.conflicts = {}
|
||||||
|
MockPackage.patches = {}
|
||||||
|
|
||||||
|
mock_package = MockPackage(
|
||||||
|
dependencies, dependency_types, conditions, versions)
|
||||||
|
self.spec_to_pkg[name] = mock_package
|
||||||
|
self.spec_to_pkg["mockrepo." + name] = mock_package
|
||||||
|
|
||||||
|
return mock_package
|
Loading…
Reference in a new issue