concretize.lp: impose a lower bound on the number of version facts if a solution exists (#31142)

* concretize.lp: impose a lower bound on the number of version facts if a valid version exists

fixes #30864

* Add a unit test
This commit is contained in:
Massimiliano Culpo 2022-06-16 18:25:56 +02:00 committed by GitHub
parent 6f1e3a4ad3
commit 895ceeda38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -120,6 +120,11 @@ version_weight(Package, Weight)
{ version(Package, Version) : version_satisfies(Package, Constraint, Version) } { version(Package, Version) : version_satisfies(Package, Constraint, Version) }
:- node_version_satisfies(Package, Constraint). :- node_version_satisfies(Package, Constraint).
% If there is at least a version that satisfy the constraint, impose a lower
% bound on the choice rule to avoid false positives with the error below
1 { version(Package, Version) : version_satisfies(Package, Constraint, Version) }
:- node_version_satisfies(Package, Constraint), version_satisfies(Package, Constraint, _).
% More specific error message if the version cannot satisfy some constraint % More specific error message if the version cannot satisfy some constraint
% Otherwise covered by `no_version_error` and `versions_conflict_error`. % Otherwise covered by `no_version_error` and `versions_conflict_error`.
error(1, "No valid version for '{0}' satisfies '@{1}'", Package, Constraint) error(1, "No valid version for '{0}' satisfies '@{1}'", Package, Constraint)

View File

@ -1732,3 +1732,24 @@ def test_best_effort_coconcretize_preferences(
if expected_spec in spec: if expected_spec in spec:
counter += 1 counter += 1
assert counter == occurances, concrete_specs assert counter == occurances, concrete_specs
@pytest.mark.regression('30864')
def test_misleading_error_message_on_version(self, mutable_database):
# For this bug to be triggered we need a reusable dependency
# that is not optimal in terms of optimization scores.
# We pick an old version of "b"
import spack.solver.asp
if spack.config.get('config:concretizer') == 'original':
pytest.skip('Original concretizer cannot reuse')
reusable_specs = [
spack.spec.Spec('non-existing-conditional-dep@1.0').concretized()
]
root_spec = spack.spec.Spec('non-existing-conditional-dep@2.0')
with spack.config.override("concretizer:reuse", True):
solver = spack.solver.asp.Solver()
setup = spack.solver.asp.SpackSolverSetup()
with pytest.raises(spack.solver.asp.UnsatisfiableSpecError,
match="'dep-with-variants' satisfies '@999'"):
solver.driver.solve(setup, [root_spec], reuse=reusable_specs)

View File

@ -0,0 +1,16 @@
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack.package import *
class NonExistingConditionalDep(Package):
"""Simple package with no source and one dependency"""
homepage = "http://www.example.com"
version('2.0')
version('1.0')
depends_on('dep-with-variants@999', when='@2.0')