From 9b8aaaa7abbf36d937dbf7160caa2d9c7c92871f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Wed, 5 Feb 2025 22:06:38 +0100 Subject: solver3: Reject reverse conflicts on install We forgot this in the previous iteration. This makes the reasoning in the test cases much nicer and apt-test's mantic-to-noble-jak.edsp now finishes rather than running into the timeout (potentially forever). --- apt-pkg/solver3.cc | 9 +++++++++ test/integration/test-bug-64141-install-dependencies-for-on-hold | 2 +- .../test-bug-960705-propagate-protected-to-satisfied-depends | 7 ++----- test/integration/test-multiarch-allowed | 6 +++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 2d9e92c99..8af3275eb 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -382,6 +382,15 @@ bool APT::Solver::Propagate() for (auto &clause : (*this)[var].clauses) if (not AddWork(Work{clause.get(), depth()})) return false; + for (auto rclause : (*this)[var].rclauses) + { + if (not rclause->negative || rclause->optional || rclause->reason.empty()) + continue; + if (unlikely(debug >= 3)) + std::cerr << "Propagate " << var.toString(cache) << " to NOT " << rclause->reason.toString(cache) << " for dep " << const_cast(rclause)->toString(cache) << std::endl; + if (not Enqueue(rclause->reason, false, var)) + return false; + } } else if ((*this)[var].decision == Decision::MUSTNOT) { diff --git a/test/integration/test-bug-64141-install-dependencies-for-on-hold b/test/integration/test-bug-64141-install-dependencies-for-on-hold index 1ad1952f7..ddfad92af 100755 --- a/test/integration/test-bug-64141-install-dependencies-for-on-hold +++ b/test/integration/test-bug-64141-install-dependencies-for-on-hold @@ -34,7 +34,7 @@ After this operation, 0 B of additional disk space will be used. E: Trivial Only specified but this is not a trivial operation.' aptget dist-upgrade --trivial-only --solver 3.0 testfailure aptget dist-upgrade --trivial-only --solver 3.0 -o debug::apt::solver=2 -testsuccess grep -Fx "Branch failed: Conflict: apt:$native -> apt:$native=0.8.10 -> not oldcrap:$native=1-1 but oldcrap:$native -> oldcrap:$native=1-1" rootdir/tmp/testfailure.output +testsuccess grep -Fx "[0] Reject:apt:$native=0.8.10 (oldcrap:$native -> oldcrap:$native=1-1)" rootdir/tmp/testfailure.output allowremovemanual diff --git a/test/integration/test-bug-960705-propagate-protected-to-satisfied-depends b/test/integration/test-bug-960705-propagate-protected-to-satisfied-depends index a203fe06e..1e59967e4 100755 --- a/test/integration/test-bug-960705-propagate-protected-to-satisfied-depends +++ b/test/integration/test-bug-960705-propagate-protected-to-satisfied-depends @@ -28,12 +28,9 @@ Solving dependencies...Install foobar:amd64 () [0] Install:foo:amd64 (foobar:amd64=1 -> requires-foo:amd64) [0] Install:foo:amd64=1 (foobar:amd64=1 -> requires-foo:amd64 -> foo:amd64) [0] Install:foo-depends:amd64 (foobar:amd64=1 -> requires-foo:amd64 -> foo:amd64) +[0] Reject:conflicts-foo:amd64 (foobar:amd64=1 -> requires-foo:amd64 -> foo:amd64 -> foo:amd64=1) +[0] Reject:conflicts-foo:amd64=1 (foobar:amd64=1 -> requires-foo:amd64 -> foo:amd64 -> foo:amd64=1) [0] Install:foo-depends:amd64=1 (foobar:amd64=1 -> requires-foo:amd64 -> foo:amd64 -> foo-depends:amd64) -Item (2@0) foobar:amd64=1 -> | conflicts-foo:amd64 | fine-foo:amd64 -[1] Install:conflicts-foo:amd64 (foobar:amd64=1) -[1] Install:conflicts-foo:amd64=1 (foobar:amd64=1 -> conflicts-foo:amd64) -[0] Reject:conflicts-foo:amd64 () -[0] Reject:conflicts-foo:amd64=1 (not conflicts-foo:amd64) Item (1@0) foobar:amd64=1 -> | conflicts-foo:amd64 | fine-foo:amd64 [0] Install:fine-foo:amd64 (foobar:amd64=1) [0] Install:fine-foo:amd64=1 (foobar:amd64=1 -> fine-foo:amd64) diff --git a/test/integration/test-multiarch-allowed b/test/integration/test-multiarch-allowed index fb8cb653d..0e3903f1b 100755 --- a/test/integration/test-multiarch-allowed +++ b/test/integration/test-multiarch-allowed @@ -64,18 +64,18 @@ Inst needsfoo:i386 (1 unstable [i386]) Conf foo:i386 (1 unstable [i386]) Conf needsfoo:i386 (1 unstable [i386])' aptget install needsfoo:i386 -s # FIXME: same problem, but two different unmet dependency messages depending on install order -testfailuremsg "E: Conflict: foo:amd64=1 -> not foo:i386=1 -> not foo:i386 but needsfoo:i386=1 -> foo:i386" aptget install needsfoo:i386 foo:amd64 -s --solver 3.0 +testfailuremsg "E: Conflict: needsfoo:i386=1 -> foo:i386 but foo:amd64=1 -> not foo:i386" aptget install needsfoo:i386 foo:amd64 -s --solver 3.0 testfailureequal "$BADPREFIX The following packages have unmet dependencies: foo : Conflicts: foo:i386 but 1 is to be installed foo:i386 : Conflicts: foo but 1 is to be installed E: Unable to correct problems, you have held broken packages." aptget install needsfoo:i386 foo:amd64 -s --solver internal -testfailuremsg "E: Conflict: foo:amd64=1 -> not foo:i386=1 -> not foo:i386 but needsfoo:i386=1 -> foo:i386" aptget install foo:amd64 needsfoo:i386 -s --solver 3.0 +testfailuremsg "E: Conflict: needsfoo:i386=1 -> foo:i386 but foo:amd64=1 -> not foo:i386" aptget install foo:amd64 needsfoo:i386 -s --solver 3.0 testfailureequal "$BADPREFIX The following packages have unmet dependencies: needsfoo:i386 : Depends: foo:i386 but it is not installable E: Unable to correct problems, you have held broken packages." aptget install foo:amd64 needsfoo:i386 -s --solver internal -testfailuremsg "E: Conflict: foo:i386=1 -> not foo:amd64=1 -> not foo:amd64 but needsfoo:amd64=1 -> foo:amd64" aptget install needsfoo foo:i386 -s --solver 3.0 +testfailuremsg "E: Conflict: needsfoo:amd64=1 -> foo:amd64 but foo:i386=1 -> not foo:amd64" aptget install needsfoo foo:i386 -s --solver 3.0 testfailureequal "$BADPREFIX The following packages have unmet dependencies: foo : Conflicts: foo:i386 but 1 is to be installed -- cgit v1.2.3-70-g09d2