From 0678d5df90f8cb9207536d77f00cb8a0eee6a373 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Sun, 31 Jan 2021 11:31:57 +0100 Subject: repo: generalize "swap" context manager to also accept paths The method is now called "use_repositories" and makes it clear in the docstring that it accepts as arguments either Repo objects or paths. Since there was some duplication between this contextmanager and "use_repo" in the testing framework, remove the latter and use spack.repo.use_repositories across the entire code base. Make a few adjustment to MockPackageMultiRepo, since it was stating in the docstring that it was supposed to mock spack.repo.Repo and was instead mocking spack.repo.RepoPath. (cherry picked from commit 1a8963b0f4c11c4b7ddd347e6cd95cdc68ddcbe0) --- lib/spack/spack/repo.py | 45 +++++++++++++++++++------------ lib/spack/spack/test/cmd/ci.py | 2 +- lib/spack/spack/test/cmd/env.py | 12 ++++----- lib/spack/spack/test/cmd/module.py | 4 +-- lib/spack/spack/test/cmd/pkg.py | 2 +- lib/spack/spack/test/concretize.py | 2 +- lib/spack/spack/test/conftest.py | 24 ++++++----------- lib/spack/spack/test/database.py | 12 ++++----- lib/spack/spack/test/directory_layout.py | 2 +- lib/spack/spack/test/installer.py | 4 +-- lib/spack/spack/test/package_sanity.py | 2 +- lib/spack/spack/test/spec_dag.py | 8 +++--- lib/spack/spack/test/spec_yaml.py | 2 +- lib/spack/spack/test/test_activations.py | 2 +- lib/spack/spack/test/util/mock_package.py | 2 +- lib/spack/spack/util/mock_package.py | 7 +++++ 16 files changed, 71 insertions(+), 61 deletions(-) diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py index 4af7b382f0..52b44e0120 100644 --- a/lib/spack/spack/repo.py +++ b/lib/spack/spack/repo.py @@ -1255,23 +1255,6 @@ def set_path(repo): return append -@contextlib.contextmanager -def swap(repo_path): - """Temporarily use another RepoPath.""" - global path - - # swap out _path for repo_path - saved = path - remove_from_meta = set_path(repo_path) - - yield - - # restore _path and sys.meta_path - if remove_from_meta: - sys.meta_path.remove(repo_path) - path = saved - - @contextlib.contextmanager def additional_repository(repository): """Adds temporarily a repository to the default one. @@ -1284,6 +1267,34 @@ def additional_repository(repository): path.remove(repository) +@contextlib.contextmanager +def use_repositories(*paths_and_repos): + """Use the repositories passed as arguments within the context manager. + + Args: + *paths_and_repos: paths to the repositories to be used, or + already constructed Repo objects + + Returns: + Corresponding RepoPath object + """ + global path + + # Construct a temporary RepoPath object from + temporary_repositories = RepoPath(*paths_and_repos) + + # Swap the current repository out + saved = path + remove_from_meta = set_path(temporary_repositories) + + yield temporary_repositories + + # Restore _path and sys.meta_path + if remove_from_meta: + sys.meta_path.remove(temporary_repositories) + path = saved + + class RepoError(spack.error.SpackError): """Superclass for repository-related errors.""" diff --git a/lib/spack/spack/test/cmd/ci.py b/lib/spack/spack/test/cmd/ci.py index 4d8468c66c..16af0e99e6 100644 --- a/lib/spack/spack/test/cmd/ci.py +++ b/lib/spack/spack/test/cmd/ci.py @@ -73,7 +73,7 @@ and then 'd', 'b', and 'a' to be put in the next three stages, respectively. b = mock_repo.add_package('b', [d, e], [default, default]) mock_repo.add_package('a', [b, c], [default, default]) - with repo.swap(mock_repo): + with repo.use_repositories(mock_repo): spec_a = Spec('a') spec_a.concretize() diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index c2d75d9d1f..72f1b86347 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -330,7 +330,7 @@ def test_env_status_broken_view( # switch to a new repo that doesn't include the installed package # test that Spack detects the missing package and warns the user new_repo = MockPackageMultiRepo() - with spack.repo.swap(new_repo): + with spack.repo.use_repositories(new_repo): output = env('status') assert 'In environment test' in output assert 'Environment test includes out of date' in output @@ -351,7 +351,7 @@ def test_env_activate_broken_view( # switch to a new repo that doesn't include the installed package # test that Spack detects the missing package and fails gracefully new_repo = MockPackageMultiRepo() - with spack.repo.swap(new_repo): + with spack.repo.use_repositories(new_repo): with pytest.raises(SpackCommandError): env('activate', '--sh', 'test') @@ -929,7 +929,7 @@ def test_read_old_lock_and_write_new(tmpdir): y = mock_repo.add_package('y', [], []) mock_repo.add_package('x', [y], [build_only]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): x = Spec('x') x.concretize() @@ -960,7 +960,7 @@ def test_read_old_lock_creates_backup(tmpdir): mock_repo = MockPackageMultiRepo() y = mock_repo.add_package('y', [], []) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): y = Spec('y') y.concretize() @@ -997,7 +997,7 @@ def test_indirect_build_dep(): pass setattr(mock_repo, 'dump_provenance', noop) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): x_spec = Spec('x') x_concretized = x_spec.concretized() @@ -1038,7 +1038,7 @@ def test_store_different_build_deps(): pass setattr(mock_repo, 'dump_provenance', noop) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): y_spec = Spec('y ^z@3') y_concretized = y_spec.concretized() diff --git a/lib/spack/spack/test/cmd/module.py b/lib/spack/spack/test/cmd/module.py index c3fe279306..9a34368fce 100644 --- a/lib/spack/spack/test/cmd/module.py +++ b/lib/spack/spack/test/cmd/module.py @@ -10,7 +10,7 @@ import pytest import spack.main import spack.modules -from spack.test.conftest import use_store, use_configuration, use_repo +from spack.test.conftest import use_store, use_configuration module = spack.main.SpackCommand('module') @@ -23,7 +23,7 @@ def ensure_module_files_are_there( module = spack.main.SpackCommand('module') with use_store(mock_store): with use_configuration(mock_configuration): - with use_repo(mock_repo_path): + with spack.repo.use_repositories(mock_repo_path): module('tcl', 'refresh', '-y') diff --git a/lib/spack/spack/test/cmd/pkg.py b/lib/spack/spack/test/cmd/pkg.py index ca9e3a1a3e..52127e8605 100644 --- a/lib/spack/spack/test/cmd/pkg.py +++ b/lib/spack/spack/test/cmd/pkg.py @@ -82,7 +82,7 @@ def mock_pkg_git_repo(tmpdir_factory): git('-c', 'commit.gpgsign=false', 'commit', '-m', 'change pkg-b, remove pkg-c, add pkg-d') - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): yield mock_repo_packages diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index a54a65970f..e5eaa7b7fb 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -304,7 +304,7 @@ class TestConcretize(object): barpkg = mock_repo.add_package('barpkg', [bazpkg], [default_dep]) mock_repo.add_package('foopkg', [barpkg], [default_dep]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = Spec('foopkg %gcc@4.5.0 os=CNL target=nocona' + ' ^barpkg os=SuSE11 ^bazpkg os=be') spec.concretize() diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index d4f38f2c1b..f214c78c18 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -382,19 +382,12 @@ def use_store(store): spack.store.store = saved -@contextlib.contextmanager -def use_repo(repo): - """Context manager to swap out the global Spack repo path.""" - with spack.repo.swap(repo): - yield - - # # Test-specific fixtures # @pytest.fixture(scope='session') def mock_repo_path(): - yield spack.repo.RepoPath(spack.paths.mock_packages_path) + yield spack.repo.Repo(spack.paths.mock_packages_path) def _pkg_install_fn(pkg, spec, prefix): @@ -411,15 +404,15 @@ def mock_pkg_install(monkeypatch): @pytest.fixture(scope='function') def mock_packages(mock_repo_path, mock_pkg_install): """Use the 'builtin.mock' repository instead of 'builtin'""" - with use_repo(mock_repo_path): - yield mock_repo_path + with spack.repo.use_repositories(mock_repo_path) as mock_repo: + yield mock_repo @pytest.fixture(scope='function') def mutable_mock_repo(mock_repo_path): """Function-scoped mock packages, for tests that need to modify them.""" - mock_repo_path = spack.repo.RepoPath(spack.paths.mock_packages_path) - with use_repo(mock_repo_path): + mock_repo = spack.repo.Repo(spack.paths.mock_packages_path) + with spack.repo.use_repositories(mock_repo) as mock_repo_path: yield mock_repo_path @@ -644,7 +637,7 @@ def mock_store(tmpdir_factory, mock_repo_path, mock_configuration, if not os.path.exists(str(store_cache.join('.spack-db'))): with use_configuration(mock_configuration): with use_store(store): - with use_repo(mock_repo_path): + with spack.repo.use_repositories(mock_repo_path): _populate(store.db) store_path.copy(store_cache, mode=True, stat=True) @@ -674,7 +667,7 @@ def mutable_mock_store(tmpdir_factory, mock_repo_path, mock_configuration, if not os.path.exists(str(store_cache.join('.spack-db'))): with use_configuration(mock_configuration): with use_store(store): - with use_repo(mock_repo_path): + with spack.repo.use_repositories(mock_repo_path): _populate(store.db) store_path.copy(store_cache, mode=True, stat=True) @@ -1250,8 +1243,7 @@ repo: namespace: mock_test_repo """) - repo = spack.repo.RepoPath(str(repodir)) - with spack.repo.swap(repo): + with spack.repo.use_repositories(str(repodir)) as repo: yield repo, repodir shutil.rmtree(str(repodir)) diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py index 4682c9850d..8e0eac7cc0 100644 --- a/lib/spack/spack/test/database.py +++ b/lib/spack/spack/test/database.py @@ -81,7 +81,7 @@ def test_installed_upstream(upstream_and_downstream_db): y = mock_repo.add_package('y', [z], [default]) mock_repo.add_package('w', [x, y], [default, default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = spack.spec.Spec('w') spec.concretize() @@ -122,7 +122,7 @@ def test_removed_upstream_dep(upstream_and_downstream_db): z = mock_repo.add_package('z', [], []) mock_repo.add_package('y', [z], [default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = spack.spec.Spec('y') spec.concretize() @@ -155,7 +155,7 @@ def test_add_to_upstream_after_downstream(upstream_and_downstream_db): mock_repo = MockPackageMultiRepo() mock_repo.add_package('x', [], []) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = spack.spec.Spec('x') spec.concretize() @@ -197,7 +197,7 @@ def test_cannot_write_upstream(tmpdir_factory, test_store, gen_mock_layout): upstream_dbs = spack.store._construct_upstream_dbs_from_install_roots( [roots[1]], _test=True) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = spack.spec.Spec('x') spec.concretize() @@ -216,7 +216,7 @@ def test_recursive_upstream_dbs(tmpdir_factory, test_store, gen_mock_layout): y = mock_repo.add_package('y', [z], [default]) mock_repo.add_package('x', [y], [default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = spack.spec.Spec('x') spec.concretize() db_c = spack.database.Database(roots[2]) @@ -694,7 +694,7 @@ def test_115_reindex_with_packages_not_in_repo(mutable_database): # Dont add any package definitions to this repository, the idea is that # packages should not have to be defined in the repository once they # are installed - with spack.repo.swap(MockPackageMultiRepo()): + with spack.repo.use_repositories(MockPackageMultiRepo()): spack.store.store.reindex() _check_db_sanity(mutable_database) diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py index 3a144621eb..3cb976a077 100644 --- a/lib/spack/spack/test/directory_layout.py +++ b/lib/spack/spack/test/directory_layout.py @@ -194,7 +194,7 @@ def test_handle_unknown_package(layout_and_dir, config, mock_packages): layout.create_install_directory(spec) installed_specs[spec] = layout.path_for_spec(spec) - with spack.repo.swap(mock_db): + with spack.repo.use_repositories(mock_db): # Now check that even without the package files, we know # enough to read a spec from the spec file. for spec, path in installed_specs.items(): diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py index 3bf818544e..590c4a4a1a 100644 --- a/lib/spack/spack/test/installer.py +++ b/lib/spack/spack/test/installer.py @@ -474,14 +474,14 @@ def test_packages_needed_to_bootstrap_compiler_packages(install_mockery, assert packages -def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_repo_path): +def test_dump_packages_deps_ok(install_mockery, tmpdir, mock_packages): """Test happy path for dump_packages with dependencies.""" spec_name = 'simple-inheritance' spec = spack.spec.Spec(spec_name).concretized() inst.dump_packages(spec, str(tmpdir)) - repo = mock_repo_path.repos[0] + repo = mock_packages.repos[0] dest_pkg = repo.filename_for_package_name(spec_name) assert os.path.isfile(dest_pkg) diff --git a/lib/spack/spack/test/package_sanity.py b/lib/spack/spack/test/package_sanity.py index d50169a1a4..ded4d1c485 100644 --- a/lib/spack/spack/test/package_sanity.py +++ b/lib/spack/spack/test/package_sanity.py @@ -73,7 +73,7 @@ def test_repo_getpkg_names_and_classes(): def test_get_all_mock_packages(): """Get the mock packages once each too.""" db = spack.repo.RepoPath(spack.paths.mock_packages_path) - with spack.repo.swap(db): + with spack.repo.use_repositories(db): check_repo() diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py index 2ac5bec4d9..854495988b 100644 --- a/lib/spack/spack/test/spec_dag.py +++ b/lib/spack/spack/test/spec_dag.py @@ -75,7 +75,7 @@ w->y deptypes are (link, build), w->x and y->z deptypes are (test) y = mock_repo.add_package('y', [z], [test_only]) w = mock_repo.add_package('w', [x, y], [test_only, default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = Spec('w') spec.concretize(tests=(w.name,)) @@ -114,7 +114,7 @@ def test_installed_deps(): b = mock_repo.add_package('b', [d, e], [default, default]) mock_repo.add_package('a', [b, c], [default, default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): c_spec = Spec('c') c_spec.concretize() assert c_spec['d'].version == spack.version.Version('2') @@ -143,7 +143,7 @@ def test_specify_preinstalled_dep(): b = mock_repo.add_package('b', [c], [default]) mock_repo.add_package('a', [b], [default]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): b_spec = Spec('b') b_spec.concretize() for spec in b_spec.traverse(): @@ -186,7 +186,7 @@ def test_conditional_dep_with_user_constraints(spec_str, expr_str, expected): } mock_repo.add_package('x', [y], [default], conditions=x_on_y_conditions) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(mock_repo): spec = Spec(spec_str) spec.concretize() diff --git a/lib/spack/spack/test/spec_yaml.py b/lib/spack/spack/test/spec_yaml.py index 12a3982f06..b32fe09e03 100644 --- a/lib/spack/spack/test/spec_yaml.py +++ b/lib/spack/spack/test/spec_yaml.py @@ -315,7 +315,7 @@ def test_save_dependency_spec_yamls_subset(tmpdir, config): b = mock_repo.add_package('b', [d, e], [default, default]) mock_repo.add_package('a', [b, c], [default, default]) - with repo.swap(mock_repo): + with repo.use_repositories(mock_repo): spec_a = Spec('a') spec_a.concretize() b_spec = spec_a['b'] diff --git a/lib/spack/spack/test/test_activations.py b/lib/spack/spack/test/test_activations.py index d1780b8963..e8ce6c55ed 100644 --- a/lib/spack/spack/test/test_activations.py +++ b/lib/spack/spack/test/test_activations.py @@ -54,7 +54,7 @@ def builtin_and_mock_packages(): repo_dirs = [spack.paths.packages_path, spack.paths.mock_packages_path] path = RepoPath(*repo_dirs) - with spack.repo.swap(path): + with spack.repo.use_repositories(path): yield diff --git a/lib/spack/spack/test/util/mock_package.py b/lib/spack/spack/test/util/mock_package.py index 376ac581bd..cca55bb534 100644 --- a/lib/spack/spack/test/util/mock_package.py +++ b/lib/spack/spack/test/util/mock_package.py @@ -15,7 +15,7 @@ def test_mock_package_possible_dependencies(): b = mock_repo.add_package('b', [d]) a = mock_repo.add_package('a', [b, c]) - with spack.repo.swap(mock_repo): + with spack.repo.use_repositories(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']) diff --git a/lib/spack/spack/util/mock_package.py b/lib/spack/spack/util/mock_package.py index 5286b50464..734a93c469 100644 --- a/lib/spack/spack/util/mock_package.py +++ b/lib/spack/spack/util/mock_package.py @@ -8,6 +8,7 @@ import ordereddict_backport import spack.util.naming +import spack.provider_index from spack.dependency import Dependency from spack.spec import Spec from spack.version import Version @@ -80,6 +81,8 @@ class MockPackageMultiRepo(object): def __init__(self): self.spec_to_pkg = {} + self.namespace = '' + self.full_namespace = 'spack.pkg.mock' def get(self, spec): if not isinstance(spec, spack.spec.Spec): @@ -171,3 +174,7 @@ class MockPackageMultiRepo(object): self.spec_to_pkg["mockrepo." + name] = mock_package return mock_package + + @property + def provider_index(self): + return spack.provider_index.ProviderIndex() -- cgit v1.2.3-60-g2f50