diff options
-rw-r--r-- | lib/spack/spack/solver/asp.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/solver/concretize.lp | 21 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 20 |
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) |