summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-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)