ASP-based solver: discard unknown packages from reuse (#30357)

* ASP-based solver: discard unknown packages from reuse

This is an add-on to #28259 that cover for the case of
a single package.py being removed from a repository,
rather than an entire custom repository being removed.

* Add unit test
This commit is contained in:
Massimiliano Culpo 2022-04-28 19:40:28 +02:00 committed by GitHub
parent 1006dd54de
commit 6a9df34abd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 3 deletions

View file

@ -1661,8 +1661,8 @@ def _facts_from_concrete_spec(self, spec, possible):
if spec.name in possible and h not in self.seen_hashes: if spec.name in possible and h not in self.seen_hashes:
try: try:
# Only consider installed packages for repo we know # Only consider installed packages for repo we know
spack.repo.path.repo_for_pkg(spec) spack.repo.path.get(spec)
except spack.repo.UnknownNamespaceError: except (spack.repo.UnknownNamespaceError, spack.repo.UnknownPackageError):
return return
# this indicates that there is a spec like this installed # this indicates that there is a spec like this installed
@ -2053,6 +2053,8 @@ def build_specs(self, function_tuples):
# namespace assignment is done after the fact, as it is not # namespace assignment is done after the fact, as it is not
# currently part of the solve # currently part of the solve
for spec in self._specs.values(): for spec in self._specs.values():
if spec.namespace:
continue
repo = spack.repo.path.repo_for_pkg(spec) repo = spack.repo.path.repo_for_pkg(spec)
spec.namespace = repo.namespace spec.namespace = repo.namespace
@ -2062,7 +2064,7 @@ def build_specs(self, function_tuples):
# inject patches -- note that we' can't use set() to unique the # inject patches -- note that we' can't use set() to unique the
# roots here, because the specs aren't complete, and the hash # roots here, because the specs aren't complete, and the hash
# function will loop forever. # function will loop forever.
roots = [spec.root for spec in self._specs.values()] roots = [spec.root for spec in self._specs.values() if not spec.root.installed]
roots = dict((id(r), r) for r in roots) roots = dict((id(r), r) for r in roots)
for root in roots.values(): for root in roots.values():
spack.spec.Spec.inject_patches_variant(root) spack.spec.Spec.inject_patches_variant(root)

View file

@ -3,6 +3,7 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os import os
import shutil
import sys import sys
import jinja2 import jinja2
@ -1645,3 +1646,22 @@ def test_reuse_with_unknown_namespace_dont_raise(
with spack.config.override("concretizer:reuse", True): with spack.config.override("concretizer:reuse", True):
s = Spec('c').concretized() s = Spec('c').concretized()
assert s.namespace == 'builtin.mock' assert s.namespace == 'builtin.mock'
@pytest.mark.regression('28259')
def test_reuse_with_unknown_package_dont_raise(
self, additional_repo_with_c, mutable_mock_repo, monkeypatch
):
s = Spec('c').concretized()
assert s.namespace == 'myrepo'
s.package.do_install(fake=True, explicit=True)
# Here we delete the package.py instead of removing the repo and we
# make it such that "c" doesn't exist in myrepo
del sys.modules['spack.pkg.myrepo.c']
c_dir = os.path.join(additional_repo_with_c.root, 'packages', 'c')
shutil.rmtree(c_dir)
monkeypatch.setattr(additional_repo_with_c, 'exists', lambda x: False)
with spack.config.override("concretizer:reuse", True):
s = Spec('c').concretized()
assert s.namespace == 'builtin.mock'