This fixes a case inside _slot_operator_update_probe where it would select an inappropriate replacement_parent of a lower version than desired. The problem is solved by rejecting replacement_parent if its version is lower than the existing parent, and a downgrade is not desired.
X-Gentoo-Bug: 528610 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=528610 --- pym/_emerge/depgraph.py | 8 +++ ..._slot_operator_update_probe_parent_downgrade.py | 68 ++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 pym/portage/tests/resolver/test_slot_operator_update_probe_parent_downgrade.py diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 94eaed8..2a839d0 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -1659,6 +1659,7 @@ class depgraph(object): debug = "--debug" in self._frozen_config.myopts selective = "selective" in self._dynamic_config.myparams want_downgrade = None + want_downgrade_parent = None def check_reverse_dependencies(existing_pkg, candidate_pkg, replacement_parent=None): @@ -1706,6 +1707,13 @@ class depgraph(object): for replacement_parent in self._iter_similar_available(dep.parent, dep.parent.slot_atom, autounmask_level=autounmask_level): + if replacement_parent < dep.parent: + if want_downgrade_parent is None: + want_downgrade_parent = self._downgrade_probe( + dep.parent) + if not want_downgrade_parent: + continue + if not check_reverse_dependencies(dep.parent, replacement_parent): continue diff --git a/pym/portage/tests/resolver/test_slot_operator_update_probe_parent_downgrade.py b/pym/portage/tests/resolver/test_slot_operator_update_probe_parent_downgrade.py new file mode 100644 index 0000000..2ec15b6 --- /dev/null +++ b/pym/portage/tests/resolver/test_slot_operator_update_probe_parent_downgrade.py @@ -0,0 +1,68 @@ +# Copyright 2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.tests.resolver.ResolverPlayground import \ + ResolverPlayground, ResolverPlaygroundTestCase + +class SlotOperatorUpdateProbeParentDowngradeTestCase(TestCase): + + def testSlotOperatorUpdateProbeParentDowngrade(self): + + ebuilds = { + "net-nds/openldap-2.4.40-r3": { + "EAPI": "5", + "RDEPEND": "<sys-libs/db-6.0:= " + \ + "|| ( sys-libs/db:5.3 sys-libs/db:5.1 )" + }, + "net-nds/openldap-2.4.40": { + "EAPI": "5", + "RDEPEND": "sys-libs/db" + }, + "sys-libs/db-6.0": { + "SLOT": "6.0", + }, + "sys-libs/db-5.3": { + "SLOT": "5.3", + }, + } + + installed = { + "net-nds/openldap-2.4.40-r3": { + "EAPI": "5", + "RDEPEND": "<sys-libs/db-6.0:5.3/5.3= " + \ + "|| ( sys-libs/db:5.3 sys-libs/db:5.1 )" + }, + "sys-libs/db-6.0": { + "SLOT": "6.0", + }, + "sys-libs/db-5.3": { + "SLOT": "5.3", + }, + } + + world = ( + "net-nds/openldap", + ) + + test_cases = ( + # bug 528610 - openldap rebuild was triggered + # inappropriately, due to slot_operator_update_probe + # selecting an inappropriate replacement parent of + # a lower version than desired. + ResolverPlaygroundTestCase( + ["@world"], + success = True, + options = { "--update": True, "--deep": True }, + mergelist = []), + ) + + playground = ResolverPlayground(ebuilds=ebuilds, + installed=installed, world=world, debug=False) + try: + for test_case in test_cases: + playground.run_TestCase(test_case) + self.assertEqual(test_case.test_success, + True, test_case.fail_msg) + finally: + playground.cleanup() -- 2.0.4