summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-11-05 17:52:44 +0100
committerGitHub <noreply@github.com>2021-11-05 10:52:44 -0600
commit0feb5ec70a379545fbb13206e2a9a2d1dfc622ef (patch)
tree3f4cc3593feae9251ac1b5103b0591b75258e991
parent178e15c39df43d70d59c558b0aa8278fc5544323 (diff)
downloadspack-0feb5ec70a379545fbb13206e2a9a2d1dfc622ef.tar.gz
spack-0feb5ec70a379545fbb13206e2a9a2d1dfc622ef.tar.bz2
spack-0feb5ec70a379545fbb13206e2a9a2d1dfc622ef.tar.xz
spack-0feb5ec70a379545fbb13206e2a9a2d1dfc622ef.zip
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.
-rw-r--r--lib/spack/spack/solver/asp.py2
-rw-r--r--lib/spack/spack/solver/concretize.lp21
-rw-r--r--lib/spack/spack/test/concretize.py20
3 files changed, 42 insertions, 1 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 4a8a3fbbc5..c1c3cb33a9 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1617,7 +1617,7 @@ class SpackSolverSetup(object):
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.
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index d0a8a8a308..8ad2a9a78a 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -8,6 +8,22 @@
%=============================================================================
%-----------------------------------------------------------------------------
+% 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.
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index bbe84b8a7e..54d886a55b 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1324,3 +1324,23 @@ class TestConcretize(object):
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)