Testing: use spack.store.use_store everywhere (#21656)
Keep spack.store.store and spack.store.db consistent in unit tests * Remove calls to monkeypatch for spack.store.store and spack.store.db: tests that used these called one or the other, which lead to inconsistencies (the tests passed regardless but were fragile as a result) * Fixtures making use of monkeypatch with mock_store now use the updated use_store function, which sets store.store and store.db consistently * subprocess_context.TestState now transfers the serializes and restores spack.store.store (without the monkeypatch changes this would have created inconsistencies)
This commit is contained in:
parent
cbcf8d208b
commit
f2e3edf6db
11 changed files with 178 additions and 176 deletions
|
@ -1089,6 +1089,8 @@ def relocate_package(spec, allow_root):
|
|||
"""
|
||||
Relocate the given package
|
||||
"""
|
||||
import spack.hooks.sbang as sbang
|
||||
|
||||
workdir = str(spec.prefix)
|
||||
buildinfo = read_buildinfo_file(workdir)
|
||||
new_layout_root = str(spack.store.layout.root)
|
||||
|
@ -1127,7 +1129,6 @@ def relocate_package(spec, allow_root):
|
|||
prefix_to_prefix_bin = OrderedDict({})
|
||||
|
||||
if old_sbang_install_path:
|
||||
import spack.hooks.sbang as sbang
|
||||
prefix_to_prefix_text[old_sbang_install_path] = sbang.sbang_install_path()
|
||||
|
||||
prefix_to_prefix_text[old_prefix] = new_prefix
|
||||
|
@ -1141,7 +1142,6 @@ def relocate_package(spec, allow_root):
|
|||
# sbang was a bash script, and it lived in the spack prefix. It is
|
||||
# now a POSIX script that lives in the install prefix. Old packages
|
||||
# will have the old sbang location in their shebangs.
|
||||
import spack.hooks.sbang as sbang
|
||||
orig_sbang = '#!/bin/bash {0}/bin/sbang'.format(old_spack_prefix)
|
||||
new_sbang = sbang.sbang_shebang_line()
|
||||
prefix_to_prefix_text[orig_sbang] = new_sbang
|
||||
|
@ -1160,7 +1160,7 @@ def is_backup_file(file):
|
|||
if not is_backup_file(text_name):
|
||||
text_names.append(text_name)
|
||||
|
||||
# If we are not installing back to the same install tree do the relocation
|
||||
# If we are not installing back to the same install tree do the relocation
|
||||
if old_layout_root != new_layout_root:
|
||||
files_to_relocate = [os.path.join(workdir, filename)
|
||||
for filename in buildinfo.get('relocate_binaries')
|
||||
|
|
|
@ -158,6 +158,8 @@ def __init__(
|
|||
):
|
||||
self.root = root
|
||||
self.unpadded_root = unpadded_root or root
|
||||
self.projections = projections
|
||||
self.hash_length = hash_length
|
||||
self.db = spack.database.Database(
|
||||
root, upstream_dbs=retrieve_upstream_dbs())
|
||||
self.layout = spack.directory_layout.YamlDirectoryLayout(
|
||||
|
@ -167,6 +169,27 @@ def reindex(self):
|
|||
"""Convenience function to reindex the store DB with its own layout."""
|
||||
return self.db.reindex(self.layout)
|
||||
|
||||
def serialize(self):
|
||||
"""Return a pickle-able object that can be used to reconstruct
|
||||
a store.
|
||||
"""
|
||||
return (
|
||||
self.root, self.unpadded_root, self.projections, self.hash_length
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def deserialize(token):
|
||||
"""Return a store reconstructed from a token created by
|
||||
the serialize method.
|
||||
|
||||
Args:
|
||||
token: return value of the serialize method
|
||||
|
||||
Returns:
|
||||
Store object reconstructed from the token
|
||||
"""
|
||||
return Store(*token)
|
||||
|
||||
|
||||
def _store():
|
||||
"""Get the singleton store instance."""
|
||||
|
@ -240,7 +263,7 @@ def use_store(store_or_path):
|
|||
Returns:
|
||||
Store object associated with the context manager's store
|
||||
"""
|
||||
global store
|
||||
global store, db, layout, root, unpadded_root
|
||||
|
||||
# Normalize input arguments
|
||||
temporary_store = store_or_path
|
||||
|
@ -248,8 +271,14 @@ def use_store(store_or_path):
|
|||
temporary_store = Store(store_or_path)
|
||||
|
||||
# Swap the store with the one just constructed and return it
|
||||
_ = store.db
|
||||
original_store, store = store, temporary_store
|
||||
db, layout = store.db, store.layout
|
||||
root, unpadded_root = store.root, store.unpadded_root
|
||||
|
||||
yield temporary_store
|
||||
|
||||
# Restore the original store
|
||||
store = original_store
|
||||
db, layout = original_store.db, original_store.layout
|
||||
root, unpadded_root = original_store.root, original_store.unpadded_root
|
||||
|
|
|
@ -93,18 +93,21 @@ def __init__(self):
|
|||
self.config = spack.config.config
|
||||
self.platform = spack.architecture.platform
|
||||
self.test_patches = store_patches()
|
||||
|
||||
# TODO: transfer spack.store.store? note that you should not
|
||||
# transfer spack.store.store and spack.store.db: 'db' is a
|
||||
# shortcut that accesses the store (so transferring both can
|
||||
# create an inconsistency). Some tests set 'db' directly, and
|
||||
# others set 'store'
|
||||
self.store_token = spack.store.store.serialize()
|
||||
|
||||
def restore(self):
|
||||
if _serialize:
|
||||
spack.repo.path = spack.repo._path(self.repo_dirs)
|
||||
spack.config.config = self.config
|
||||
spack.architecture.platform = self.platform
|
||||
|
||||
new_store = spack.store.Store.deserialize(self.store_token)
|
||||
spack.store.store = new_store
|
||||
spack.store.root = new_store.root
|
||||
spack.store.unpadded_root = new_store.unpadded_root
|
||||
spack.store.db = new_store.db
|
||||
spack.store.layout = new_store.layout
|
||||
|
||||
self.test_patches.restore()
|
||||
|
||||
|
||||
|
|
|
@ -493,40 +493,39 @@ def test_update_sbang(tmpdir, test_mirror):
|
|||
'${name}', '${version}',
|
||||
'${architecture}-${compiler.name}-${compiler.version}-${hash}'
|
||||
)
|
||||
# Save the original store and layout before we touch ANYTHING.
|
||||
real_store, real_layout = spack.store.store, spack.store.layout
|
||||
|
||||
spec_str = 'old-sbang'
|
||||
# Concretize a package with some old-fashioned sbang lines.
|
||||
sspec = Spec('old-sbang')
|
||||
sspec.concretize()
|
||||
old_spec = Spec(spec_str).concretized()
|
||||
old_spec_hash_str = '/{0}'.format(old_spec.dag_hash())
|
||||
|
||||
# Need a fake mirror with *function* scope.
|
||||
mirror_dir = test_mirror
|
||||
mirror_url = 'file://{0}'.format(mirror_dir)
|
||||
|
||||
# Assumes all commands will concretize sspec the same way.
|
||||
install_cmd('--no-cache', sspec.name)
|
||||
# Assume all commands will concretize old_spec the same way.
|
||||
install_cmd('--no-cache', old_spec.name)
|
||||
|
||||
# Create a buildcache with the installed spec.
|
||||
buildcache_cmd('create', '-u', '-a', '-d', mirror_dir,
|
||||
'/%s' % sspec.dag_hash())
|
||||
buildcache_cmd('create', '-u', '-a', '-d', mirror_dir, old_spec_hash_str)
|
||||
|
||||
# Need to force an update of the buildcache index
|
||||
buildcache_cmd('update-index', '-d', 'file://%s' % mirror_dir)
|
||||
buildcache_cmd('update-index', '-d', mirror_url)
|
||||
|
||||
# Uninstall the original package.
|
||||
uninstall_cmd('-y', '/%s' % sspec.dag_hash())
|
||||
uninstall_cmd('-y', old_spec_hash_str)
|
||||
|
||||
try:
|
||||
# New install tree locations...
|
||||
# Too fine-grained to do be done in a fixture
|
||||
newtree_dir = tmpdir.join('newtree')
|
||||
spack.store.store = spack.store.Store(str(newtree_dir))
|
||||
spack.store.layout = YamlDirectoryLayout(
|
||||
str(newtree_dir), path_scheme=scheme
|
||||
)
|
||||
# Switch the store to the new install tree locations
|
||||
newtree_dir = tmpdir.join('newtree')
|
||||
s = spack.store.Store(str(newtree_dir))
|
||||
s.layout = YamlDirectoryLayout(str(newtree_dir), path_scheme=scheme)
|
||||
|
||||
with spack.store.use_store(s):
|
||||
new_spec = Spec('old-sbang')
|
||||
new_spec.concretize()
|
||||
assert new_spec.dag_hash() == old_spec.dag_hash()
|
||||
|
||||
# Install package from buildcache
|
||||
buildcache_cmd('install', '-a', '-u', '-f', sspec.name)
|
||||
buildcache_cmd('install', '-a', '-u', '-f', new_spec.name)
|
||||
|
||||
# Continue blowing away caches
|
||||
bindist.clear_spec_cache()
|
||||
|
@ -537,23 +536,19 @@ def test_update_sbang(tmpdir, test_mirror):
|
|||
#!/usr/bin/env python
|
||||
|
||||
{1}
|
||||
'''.format(sbang.sbang_shebang_line(), sspec.prefix.bin)
|
||||
'''.format(sbang.sbang_shebang_line(), new_spec.prefix.bin)
|
||||
sbang_style_2_expected = '''{0}
|
||||
#!/usr/bin/env python
|
||||
|
||||
{1}
|
||||
'''.format(sbang.sbang_shebang_line(), sspec.prefix.bin)
|
||||
'''.format(sbang.sbang_shebang_line(), new_spec.prefix.bin)
|
||||
|
||||
installed_script_style_1_path = sspec.prefix.bin.join('sbang-style-1.sh')
|
||||
installed_script_style_1_path = new_spec.prefix.bin.join('sbang-style-1.sh')
|
||||
assert sbang_style_1_expected == \
|
||||
open(str(installed_script_style_1_path)).read()
|
||||
|
||||
installed_script_style_2_path = sspec.prefix.bin.join('sbang-style-2.sh')
|
||||
installed_script_style_2_path = new_spec.prefix.bin.join('sbang-style-2.sh')
|
||||
assert sbang_style_2_expected == \
|
||||
open(str(installed_script_style_2_path)).read()
|
||||
|
||||
uninstall_cmd('-y', '/%s' % sspec.dag_hash())
|
||||
|
||||
finally:
|
||||
spack.store.store = real_store
|
||||
spack.store.layout = real_layout
|
||||
uninstall_cmd('-y', '/%s' % new_spec.dag_hash())
|
||||
|
|
|
@ -23,7 +23,7 @@ def ensure_module_files_are_there(
|
|||
):
|
||||
"""Generate module files for module tests."""
|
||||
module = spack.main.SpackCommand('module')
|
||||
with spack.store.use_store(mock_store):
|
||||
with spack.store.use_store(str(mock_store)):
|
||||
with spack.config.use_configuration(*mock_configuration_scopes):
|
||||
with spack.repo.use_repositories(mock_repo_path):
|
||||
module('tcl', 'refresh', '-y')
|
||||
|
|
|
@ -2,36 +2,30 @@
|
|||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import pytest
|
||||
|
||||
import spack.spec
|
||||
import spack.store
|
||||
|
||||
|
||||
def test_set_install_hash_length(mock_packages, mutable_config, monkeypatch,
|
||||
tmpdir):
|
||||
# spack.store.layout caches initial config values, so we monkeypatch
|
||||
mutable_config.set('config:install_hash_length', 5)
|
||||
@pytest.mark.parametrize('hash_length', [1, 2, 3, 4, 5, 9])
|
||||
@pytest.mark.use_fixtures('mock_packages')
|
||||
def test_set_install_hash_length(hash_length, mutable_config, tmpdir):
|
||||
mutable_config.set('config:install_hash_length', hash_length)
|
||||
mutable_config.set('config:install_tree', {'root': str(tmpdir)})
|
||||
monkeypatch.setattr(spack.store, 'store', spack.store._store())
|
||||
|
||||
spec = spack.spec.Spec('libelf').concretized()
|
||||
prefix = spec.prefix
|
||||
hash = prefix.rsplit('-')[-1]
|
||||
|
||||
assert len(hash) == 5
|
||||
|
||||
mutable_config.set('config:install_hash_length', 9)
|
||||
monkeypatch.setattr(spack.store, 'store', spack.store._store())
|
||||
|
||||
spec = spack.spec.Spec('libelf').concretized()
|
||||
prefix = spec.prefix
|
||||
hash = prefix.rsplit('-')[-1]
|
||||
|
||||
assert len(hash) == 9
|
||||
# The call below is to reinitialize the directory layout associated
|
||||
# with the store according to the configuration changes above (i.e.
|
||||
# with the shortened hash)
|
||||
store = spack.store._store()
|
||||
with spack.store.use_store(store):
|
||||
spec = spack.spec.Spec('libelf').concretized()
|
||||
prefix = spec.prefix
|
||||
hash_str = prefix.rsplit('-')[-1]
|
||||
assert len(hash_str) == hash_length
|
||||
|
||||
|
||||
def test_set_install_hash_length_upper_case(mock_packages, mutable_config,
|
||||
monkeypatch, tmpdir):
|
||||
# spack.store.layout caches initial config values, so we monkeypatch
|
||||
@pytest.mark.use_fixtures('mock_packages')
|
||||
def test_set_install_hash_length_upper_case(mutable_config, tmpdir):
|
||||
mutable_config.set('config:install_hash_length', 5)
|
||||
mutable_config.set(
|
||||
'config:install_tree',
|
||||
|
@ -42,10 +36,12 @@ def test_set_install_hash_length_upper_case(mock_packages, mutable_config,
|
|||
}
|
||||
}
|
||||
)
|
||||
monkeypatch.setattr(spack.store, 'store', spack.store._store())
|
||||
|
||||
spec = spack.spec.Spec('libelf').concretized()
|
||||
prefix = spec.prefix
|
||||
hash = prefix.rsplit('-')[-1]
|
||||
|
||||
assert len(hash) == 5
|
||||
# The call below is to reinitialize the directory layout associated
|
||||
# with the store according to the configuration changes above (i.e.
|
||||
# with the shortened hash and projection)
|
||||
store = spack.store._store()
|
||||
with spack.store.use_store(store):
|
||||
spec = spack.spec.Spec('libelf').concretized()
|
||||
prefix = spec.prefix
|
||||
hash_str = prefix.rsplit('-')[-1]
|
||||
assert len(hash_str) == 5
|
||||
|
|
|
@ -563,12 +563,10 @@ def _install(spec):
|
|||
pkg = spack.repo.get(s)
|
||||
pkg.do_install(fake=True, explicit=True)
|
||||
|
||||
# Transaction used to avoid repeated writes.
|
||||
with mock_db.write_transaction():
|
||||
_install('mpileaks ^mpich')
|
||||
_install('mpileaks ^mpich2')
|
||||
_install('mpileaks ^zmpi')
|
||||
_install('externaltest')
|
||||
_install('mpileaks ^mpich')
|
||||
_install('mpileaks ^mpich2')
|
||||
_install('mpileaks ^zmpi')
|
||||
_install('externaltest')
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
|
@ -605,7 +603,7 @@ def mock_store(tmpdir_factory, mock_repo_path, mock_configuration_scopes,
|
|||
# Make the DB filesystem read-only to ensure we can't modify entries
|
||||
store_path.join('.spack-db').chmod(mode=0o555, rec=1)
|
||||
|
||||
yield store
|
||||
yield store_path
|
||||
|
||||
store_path.join('.spack-db').chmod(mode=0o755, rec=1)
|
||||
|
||||
|
@ -613,10 +611,9 @@ def mock_store(tmpdir_factory, mock_repo_path, mock_configuration_scopes,
|
|||
@pytest.fixture(scope='function')
|
||||
def database(mock_store, mock_packages, config, monkeypatch):
|
||||
"""This activates the mock store, packages, AND config."""
|
||||
monkeypatch.setattr(spack.store, 'store', mock_store)
|
||||
yield mock_store.db
|
||||
# Force reading the database again between tests
|
||||
mock_store.db.last_seen_verifier = ''
|
||||
with spack.store.use_store(str(mock_store)) as store:
|
||||
yield store.db
|
||||
store.db.last_seen_verifier = ''
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
@ -687,20 +684,15 @@ def disable_compiler_execution(monkeypatch, request):
|
|||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def install_mockery(tmpdir, config, mock_packages, monkeypatch):
|
||||
def install_mockery(temporary_store, config, mock_packages):
|
||||
"""Hooks a fake install directory, DB, and stage directory into Spack."""
|
||||
monkeypatch.setattr(
|
||||
spack.store, 'store', spack.store.Store(str(tmpdir.join('opt'))))
|
||||
|
||||
# We use a fake package, so temporarily disable checksumming
|
||||
with spack.config.override('config:checksum', False):
|
||||
yield
|
||||
|
||||
tmpdir.join('opt').remove()
|
||||
|
||||
# Also wipe out any cached prefix failure locks (associated with
|
||||
# the session-scoped mock archive).
|
||||
for pkg_id in list(spack.store.db._prefix_failures.keys()):
|
||||
for pkg_id in list(temporary_store.db._prefix_failures.keys()):
|
||||
lock = spack.store.db._prefix_failures.pop(pkg_id, None)
|
||||
if lock:
|
||||
try:
|
||||
|
@ -709,24 +701,29 @@ def install_mockery(tmpdir, config, mock_packages, monkeypatch):
|
|||
pass
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def temporary_store(tmpdir):
|
||||
"""Hooks a temporary empty store for the test function."""
|
||||
temporary_store_path = tmpdir.join('opt')
|
||||
with spack.store.use_store(str(temporary_store_path)) as s:
|
||||
yield s
|
||||
temporary_store_path.remove()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def install_mockery_mutable_config(
|
||||
tmpdir, mutable_config, mock_packages, monkeypatch):
|
||||
temporary_store, mutable_config, mock_packages
|
||||
):
|
||||
"""Hooks a fake install directory, DB, and stage directory into Spack.
|
||||
|
||||
This is specifically for tests which want to use 'install_mockery' but
|
||||
also need to modify configuration (and hence would want to use
|
||||
'mutable config'): 'install_mockery' does not support this.
|
||||
"""
|
||||
monkeypatch.setattr(
|
||||
spack.store, 'store', spack.store.Store(str(tmpdir.join('opt'))))
|
||||
|
||||
# We use a fake package, so temporarily disable checksumming
|
||||
with spack.config.override('config:checksum', False):
|
||||
yield
|
||||
|
||||
tmpdir.join('opt').remove()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def mock_fetch(mock_archive, monkeypatch):
|
||||
|
|
|
@ -37,16 +37,6 @@
|
|||
pytestmark = pytest.mark.db
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def test_store(tmpdir):
|
||||
real_store = spack.store.store
|
||||
spack.store.store = spack.store.Store(str(tmpdir.join('test_store')))
|
||||
|
||||
yield
|
||||
|
||||
spack.store.store = real_store
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def upstream_and_downstream_db(tmpdir_factory, gen_mock_layout):
|
||||
mock_db_root = str(tmpdir_factory.mktemp('mock_db_root'))
|
||||
|
@ -180,8 +170,8 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db):
|
|||
spack.store.db = orig_db
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('config')
|
||||
def test_cannot_write_upstream(tmpdir_factory, test_store, gen_mock_layout):
|
||||
@pytest.mark.usefixtures('config', 'temporary_store')
|
||||
def test_cannot_write_upstream(tmpdir_factory, gen_mock_layout):
|
||||
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b']]
|
||||
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/']]
|
||||
|
||||
|
@ -205,8 +195,8 @@ def test_cannot_write_upstream(tmpdir_factory, test_store, gen_mock_layout):
|
|||
upstream_dbs[0].add(spec, layouts[1])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('config')
|
||||
def test_recursive_upstream_dbs(tmpdir_factory, test_store, gen_mock_layout):
|
||||
@pytest.mark.usefixtures('config', 'temporary_store')
|
||||
def test_recursive_upstream_dbs(tmpdir_factory, gen_mock_layout):
|
||||
roots = [str(tmpdir_factory.mktemp(x)) for x in ['a', 'b', 'c']]
|
||||
layouts = [gen_mock_layout(x) for x in ['/ra/', '/rb/', '/rc/']]
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
This test verifies that the Spack directory layout works properly.
|
||||
"""
|
||||
import os
|
||||
import os.path
|
||||
import pytest
|
||||
|
||||
import spack.paths
|
||||
|
@ -19,16 +20,6 @@
|
|||
max_packages = 10
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def layout_and_dir(tmpdir):
|
||||
"""Returns a directory layout and the corresponding directory."""
|
||||
layout = YamlDirectoryLayout(str(tmpdir))
|
||||
old_layout = spack.store.layout
|
||||
spack.store.layout = layout
|
||||
yield layout, str(tmpdir)
|
||||
spack.store.layout = old_layout
|
||||
|
||||
|
||||
def test_yaml_directory_layout_parameters(tmpdir, config):
|
||||
"""This tests the various parameters that can be used to configure
|
||||
the install location """
|
||||
|
@ -84,14 +75,14 @@ def test_yaml_directory_layout_parameters(tmpdir, config):
|
|||
projections=projections_package7)
|
||||
|
||||
|
||||
def test_read_and_write_spec(layout_and_dir, config, mock_packages):
|
||||
def test_read_and_write_spec(temporary_store, config, mock_packages):
|
||||
"""This goes through each package in spack and creates a directory for
|
||||
it. It then ensures that the spec for the directory's
|
||||
installed package can be read back in consistently, and
|
||||
finally that the directory can be removed by the directory
|
||||
layout.
|
||||
"""
|
||||
layout, tmpdir = layout_and_dir
|
||||
layout = temporary_store.layout
|
||||
packages = list(spack.repo.path.all_packages())[:max_packages]
|
||||
|
||||
for pkg in packages:
|
||||
|
@ -114,7 +105,7 @@ def test_read_and_write_spec(layout_and_dir, config, mock_packages):
|
|||
|
||||
# Ensure directory has been created in right place.
|
||||
assert os.path.isdir(install_dir)
|
||||
assert install_dir.startswith(str(tmpdir))
|
||||
assert install_dir.startswith(temporary_store.root)
|
||||
|
||||
# Ensure spec file exists when directory is created
|
||||
assert os.path.isfile(spec_path)
|
||||
|
@ -160,7 +151,7 @@ def test_read_and_write_spec(layout_and_dir, config, mock_packages):
|
|||
assert not os.path.exists(install_dir)
|
||||
|
||||
|
||||
def test_handle_unknown_package(layout_and_dir, config, mock_packages):
|
||||
def test_handle_unknown_package(temporary_store, config, mock_packages):
|
||||
"""This test ensures that spack can at least do *some*
|
||||
operations with packages that are installed but that it
|
||||
does not know about. This is actually not such an uncommon
|
||||
|
@ -171,7 +162,7 @@ def test_handle_unknown_package(layout_and_dir, config, mock_packages):
|
|||
information about installed packages' specs to uninstall
|
||||
or query them again if the package goes away.
|
||||
"""
|
||||
layout, _ = layout_and_dir
|
||||
layout = temporary_store.layout
|
||||
mock_db = spack.repo.RepoPath(spack.paths.mock_packages_path)
|
||||
|
||||
not_in_mock = set.difference(
|
||||
|
@ -209,9 +200,9 @@ def test_handle_unknown_package(layout_and_dir, config, mock_packages):
|
|||
assert spec.dag_hash() == spec_from_file.dag_hash()
|
||||
|
||||
|
||||
def test_find(layout_and_dir, config, mock_packages):
|
||||
def test_find(temporary_store, config, mock_packages):
|
||||
"""Test that finding specs within an install layout works."""
|
||||
layout, _ = layout_and_dir
|
||||
layout = temporary_store.layout
|
||||
packages = list(spack.repo.path.all_packages())[:max_packages]
|
||||
|
||||
# Create install prefixes for all packages in the list
|
||||
|
|
|
@ -183,70 +183,70 @@ def test_flatten_deps(
|
|||
assert os.path.isdir(dependency_dir)
|
||||
|
||||
|
||||
def test_installed_upstream_external(
|
||||
tmpdir_factory, install_mockery, mock_fetch, gen_mock_layout,
|
||||
monkeypatch):
|
||||
"""Check that when a dependency package is recorded as installed in
|
||||
an upstream database that it is not reinstalled.
|
||||
@pytest.fixture()
|
||||
def install_upstream(tmpdir_factory, gen_mock_layout, install_mockery):
|
||||
"""Provides a function that installs a specified set of specs to an
|
||||
upstream database. The function returns a store which points to the
|
||||
upstream, as well as the upstream layout (for verifying that dependent
|
||||
installs are using the upstream installs).
|
||||
"""
|
||||
mock_db_root = str(tmpdir_factory.mktemp('mock_db_root'))
|
||||
prepared_db = spack.database.Database(mock_db_root)
|
||||
|
||||
upstream_layout = gen_mock_layout('/a/')
|
||||
|
||||
dependency = spack.spec.Spec('externaltool')
|
||||
dependency.concretize()
|
||||
prepared_db.add(dependency, upstream_layout)
|
||||
def _install_upstream(*specs):
|
||||
for spec_str in specs:
|
||||
s = spack.spec.Spec(spec_str).concretized()
|
||||
prepared_db.add(s, upstream_layout)
|
||||
|
||||
downstream_db_root = str(
|
||||
tmpdir_factory.mktemp('mock_downstream_db_root'))
|
||||
db_for_test = spack.database.Database(
|
||||
downstream_db_root, upstream_dbs=[prepared_db])
|
||||
monkeypatch.setattr(spack.store, 'db', db_for_test)
|
||||
dependent = spack.spec.Spec('externaltest')
|
||||
dependent.concretize()
|
||||
downstream_root = str(tmpdir_factory.mktemp('mock_downstream_db_root'))
|
||||
db_for_test = spack.database.Database(
|
||||
downstream_root, upstream_dbs=[prepared_db]
|
||||
)
|
||||
store = spack.store.Store(downstream_root)
|
||||
store.db = db_for_test
|
||||
return store, upstream_layout
|
||||
|
||||
new_dependency = dependent['externaltool']
|
||||
assert new_dependency.external
|
||||
assert new_dependency.prefix == '/path/to/external_tool'
|
||||
|
||||
dependent.package.do_install()
|
||||
|
||||
assert not os.path.exists(new_dependency.prefix)
|
||||
assert os.path.exists(dependent.prefix)
|
||||
return _install_upstream
|
||||
|
||||
|
||||
def test_installed_upstream(tmpdir_factory, install_mockery, mock_fetch,
|
||||
gen_mock_layout, monkeypatch):
|
||||
def test_installed_upstream_external(install_upstream, mock_fetch):
|
||||
"""Check that when a dependency package is recorded as installed in
|
||||
an upstream database that it is not reinstalled.
|
||||
an upstream database that it is not reinstalled.
|
||||
"""
|
||||
mock_db_root = str(tmpdir_factory.mktemp('mock_db_root'))
|
||||
prepared_db = spack.database.Database(mock_db_root)
|
||||
s, _ = install_upstream('externaltool')
|
||||
with spack.store.use_store(s):
|
||||
dependent = spack.spec.Spec('externaltest')
|
||||
dependent.concretize()
|
||||
|
||||
upstream_layout = gen_mock_layout('/a/')
|
||||
new_dependency = dependent['externaltool']
|
||||
assert new_dependency.external
|
||||
assert new_dependency.prefix == '/path/to/external_tool'
|
||||
|
||||
dependency = spack.spec.Spec('dependency-install')
|
||||
dependency.concretize()
|
||||
prepared_db.add(dependency, upstream_layout)
|
||||
dependent.package.do_install()
|
||||
|
||||
downstream_db_root = str(
|
||||
tmpdir_factory.mktemp('mock_downstream_db_root'))
|
||||
db_for_test = spack.database.Database(
|
||||
downstream_db_root, upstream_dbs=[prepared_db])
|
||||
monkeypatch.setattr(spack.store, 'db', db_for_test)
|
||||
dependent = spack.spec.Spec('dependent-install')
|
||||
dependent.concretize()
|
||||
assert not os.path.exists(new_dependency.prefix)
|
||||
assert os.path.exists(dependent.prefix)
|
||||
|
||||
new_dependency = dependent['dependency-install']
|
||||
assert new_dependency.package.installed_upstream
|
||||
assert (new_dependency.prefix ==
|
||||
upstream_layout.path_for_spec(dependency))
|
||||
|
||||
dependent.package.do_install()
|
||||
def test_installed_upstream(install_upstream, mock_fetch):
|
||||
"""Check that when a dependency package is recorded as installed in
|
||||
an upstream database that it is not reinstalled.
|
||||
"""
|
||||
s, upstream_layout = install_upstream('dependency-install')
|
||||
with spack.store.use_store(s):
|
||||
dependency = spack.spec.Spec('dependency-install').concretized()
|
||||
dependent = spack.spec.Spec('dependent-install').concretized()
|
||||
|
||||
assert not os.path.exists(new_dependency.prefix)
|
||||
assert os.path.exists(dependent.prefix)
|
||||
new_dependency = dependent['dependency-install']
|
||||
assert new_dependency.package.installed_upstream
|
||||
assert (new_dependency.prefix ==
|
||||
upstream_layout.path_for_spec(dependency))
|
||||
|
||||
dependent.package.do_install()
|
||||
|
||||
assert not os.path.exists(new_dependency.prefix)
|
||||
assert os.path.exists(dependent.prefix)
|
||||
|
||||
|
||||
@pytest.mark.disable_clean_stage_check
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
|
||||
from spack import *
|
||||
|
||||
import spack.paths
|
||||
import spack.store
|
||||
|
||||
|
||||
class OldSbang(Package):
|
||||
"""Toy package for testing the old sbang replacement problem"""
|
||||
|
@ -22,12 +23,12 @@ def install(self, spec, prefix):
|
|||
#!/usr/bin/env python
|
||||
|
||||
{1}
|
||||
'''.format(spack.paths.prefix, prefix.bin)
|
||||
'''.format(spack.paths.prefix, prefix.bin)
|
||||
sbang_style_2 = '''#!/bin/sh {0}/bin/sbang
|
||||
#!/usr/bin/env python
|
||||
|
||||
{1}
|
||||
'''.format(spack.store.unpadded_root, prefix.bin)
|
||||
'''.format(spack.store.unpadded_root, prefix.bin)
|
||||
with open('%s/sbang-style-1.sh' % self.prefix.bin, 'w') as f:
|
||||
f.write(sbang_style_1)
|
||||
|
||||
|
|
Loading…
Reference in a new issue