Prevent additional properties to be in the answer set when reusing specs (#27240)

* Prevent additional properties to be in the answer set when reusing specs

fixes #27237

The mechanism to reuse concrete specs relies on imposing
the set of constraints stemming from the concrete spec
being reused.

We also need to prevent that other constraints get added
to this set.
This commit is contained in:
Massimiliano Culpo 2021-11-05 17:52:44 +01:00 committed by GitHub
parent 178e15c39d
commit 0feb5ec70a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 1 deletions

View File

@ -1617,7 +1617,7 @@ def define_installed_packages(self, specs, possible):
index = spack.binary_distribution.update_cache_and_get_specs()
for spec in index:
self._facts_from_concrete_spec(spec, possible)
except spack.binary_distribution.FetchCacheError:
except (spack.binary_distribution.FetchCacheError, IndexError):
# this is raised when no mirrors had indices.
# TODO: update mirror configuration so it can indicate that the source cache
# TODO: (or any mirror really) doesn't have binaries.

View File

@ -7,6 +7,22 @@
% This logic program implements Spack's concretizer
%=============================================================================
%-----------------------------------------------------------------------------
% Generic constraints on nodes
%-----------------------------------------------------------------------------
% each node must have a single version
:- not 1 { version(Package, _) } 1, node(Package).
% each node must have a single platform, os and target
:- not 1 { node_platform(Package, _) } 1, node(Package).
:- not 1 { node_os(Package, _) } 1, node(Package).
:- not 1 { node_target(Package, _) } 1, node(Package).
% each node has a single compiler associated with it
:- not 1 { node_compiler(Package, _) } 1, node(Package).
:- not 1 { node_compiler_version(Package, _, _) } 1, node(Package).
%-----------------------------------------------------------------------------
% Version semantics
%-----------------------------------------------------------------------------
@ -79,6 +95,11 @@ attr(Name, A1) :- impose(ID), imposed_constraint(ID, Name, A1).
attr(Name, A1, A2) :- impose(ID), imposed_constraint(ID, Name, A1, A2).
attr(Name, A1, A2, A3) :- impose(ID), imposed_constraint(ID, Name, A1, A2, A3).
% we cannot have additional variant values when we are working with concrete specs
:- node(Package), hash(Package, Hash),
variant_value(Package, Variant, Value),
not imposed_constraint(Hash, "variant_value", Package, Variant, Value).
#defined condition/1.
#defined condition_requirement/3.
#defined condition_requirement/4.

View File

@ -1324,3 +1324,23 @@ def test_non_default_provider_of_multiple_virtuals(self):
if pkg.name == 'low-priority-provider':
continue
assert pkg not in s
@pytest.mark.regression('27237')
@pytest.mark.parametrize('spec_str,expect_installed', [
('mpich', True),
('mpich+debug', False),
('mpich~debug', True)
])
def test_concrete_specs_are_not_modified_on_reuse(
self, mutable_database, spec_str, expect_installed
):
if spack.config.get('config:concretizer') == 'original':
pytest.skip('Original concretizer cannot reuse specs')
# Test the internal consistency of solve + DAG reconstruction
# when reused specs are added to the mix. This prevents things
# like additional constraints being added to concrete specs in
# the answer set produced by clingo.
s = spack.spec.Spec(spec_str).concretized(reuse=True)
assert s.package.installed is expect_installed
assert s.satisfies(spec_str, strict=True)