From: Zac Medico Date: Fri, 2 Aug 2013 08:24:32 +0000 (-0700) Subject: Avoid some missed updates when backtracking. X-Git-Tag: v2.2.0_alpha192~24 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9b6f69e2a66c0f1d1d6545208edb3c45eacfd845;p=portage.git Avoid some missed updates when backtracking. This avoids unnecessarily missed updates like the following: WARNING: One or more updates have been skipped due to a dependency conflict: dev-util/boost-build:0 (dev-util/boost-build-1.53.0::gentoo, ebuild scheduled for merge) conflicts with =dev-util/boost-build-1.52.0-r1 required by (dev-libs/boost-1.52.0-r6::gentoo, installed) !!! The following update(s) have been skipped due to unsatisfied dependencies !!! triggered by backtracking: dev-libs/boost:0 --- diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 76fda2c0c..39ae3eab8 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -6,6 +6,7 @@ from __future__ import print_function, unicode_literals import errno import io import logging +import operator import stat import sys import textwrap @@ -983,17 +984,9 @@ class depgraph(object): backtrack_data.append((to_be_masked, conflict_atoms)) if len(backtrack_data) > 1: - # NOTE: Generally, we prefer to mask the higher - # version since this solves common cases in which a - # lower version is needed so that all dependencies - # will be satisfied (bug #337178). However, if - # existing_node happens to be installed then we - # mask that since this is a common case that is - # triggered when --update is not enabled. - if existing_node.installed: - pass - elif any(pkg > existing_node for pkg in conflict_pkgs): - backtrack_data.reverse() + # In order to avoid a missed update, first mask lower + # versions that conflict with higher versions. + backtrack_data.sort(key=operator.itemgetter(0), reverse=True) to_be_masked = backtrack_data[-1][0] diff --git a/pym/portage/tests/resolver/test_backtracking.py b/pym/portage/tests/resolver/test_backtracking.py index 53899eb48..9dc37aca9 100644 --- a/pym/portage/tests/resolver/test_backtracking.py +++ b/pym/portage/tests/resolver/test_backtracking.py @@ -67,37 +67,6 @@ class BacktrackingTestCase(TestCase): finally: playground.cleanup() - - def testBacktrackingGoodVersionFirst(self): - """ - When backtracking due to slot conflicts, we masked the version that has been pulled - in first. This is not always a good idea. Mask the highest version instead. - """ - - ebuilds = { - "dev-libs/A-1": { "DEPEND": "=dev-libs/C-1 dev-libs/B" }, - "dev-libs/B-1": { "DEPEND": "=dev-libs/C-1" }, - "dev-libs/B-2": { "DEPEND": "=dev-libs/C-2" }, - "dev-libs/C-1": { }, - "dev-libs/C-2": { }, - } - - test_cases = ( - ResolverPlaygroundTestCase( - ["dev-libs/A"], - mergelist = ["dev-libs/C-1", "dev-libs/B-1", "dev-libs/A-1",], - success = True), - ) - - playground = ResolverPlayground(ebuilds=ebuilds) - - 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() - def testBacktrackWithoutUpdates(self): """ If --update is not given we might have to mask the old installed version later. diff --git a/pym/portage/tests/resolver/test_slot_conflict_mask_update.py b/pym/portage/tests/resolver/test_slot_conflict_mask_update.py new file mode 100644 index 000000000..a90eeac29 --- /dev/null +++ b/pym/portage/tests/resolver/test_slot_conflict_mask_update.py @@ -0,0 +1,41 @@ +# Copyright 2013 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 SlotConflictMaskUpdateTestCase(TestCase): + + def testBacktrackingGoodVersionFirst(self): + """ + When backtracking due to slot conflicts, we masked the version that has been pulled + in first. This is not always a good idea. Mask the highest version instead. + """ + + + self.todo = True + + ebuilds = { + "dev-libs/A-1": { "DEPEND": "=dev-libs/C-1 dev-libs/B" }, + "dev-libs/B-1": { "DEPEND": "=dev-libs/C-1" }, + "dev-libs/B-2": { "DEPEND": "=dev-libs/C-2" }, + "dev-libs/C-1": { }, + "dev-libs/C-2": { }, + } + + test_cases = ( + ResolverPlaygroundTestCase( + ["dev-libs/A"], + mergelist = ["dev-libs/C-1", "dev-libs/B-1", "dev-libs/A-1",], + success = True), + ) + + playground = ResolverPlayground(ebuilds=ebuilds) + + 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() diff --git a/pym/portage/tests/resolver/test_slot_conflict_update.py b/pym/portage/tests/resolver/test_slot_conflict_update.py new file mode 100644 index 000000000..331e5788b --- /dev/null +++ b/pym/portage/tests/resolver/test_slot_conflict_update.py @@ -0,0 +1,98 @@ +# Copyright 2013 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 SlotConflictUpdateTestCase(TestCase): + + def testSlotConflictUpdate(self): + + ebuilds = { + + "app-text/podofo-0.9.2" : { + "EAPI": "5", + "RDEPEND" : "dev-util/boost-build" + }, + + "dev-cpp/libcmis-0.3.1" : { + "EAPI": "5", + "RDEPEND" : "dev-libs/boost:=" + }, + + "dev-libs/boost-1.53.0" : { + "EAPI": "5", + "SLOT": "0/1.53", + "RDEPEND" : "=dev-util/boost-build-1.53.0" + }, + + "dev-libs/boost-1.52.0" : { + "EAPI": "5", + "SLOT": "0/1.52", + "RDEPEND" : "=dev-util/boost-build-1.52.0" + }, + + "dev-util/boost-build-1.53.0" : { + "EAPI": "5", + "SLOT": "0" + }, + + "dev-util/boost-build-1.52.0" : { + "EAPI": "5", + "SLOT": "0" + }, + + + } + + installed = { + + "app-text/podofo-0.9.2" : { + "EAPI": "5", + "RDEPEND" : "dev-util/boost-build" + }, + + "dev-cpp/libcmis-0.3.1" : { + "EAPI": "5", + "RDEPEND" : "dev-libs/boost:0/1.52=" + }, + + "dev-util/boost-build-1.52.0" : { + "EAPI": "5", + "SLOT": "0" + }, + + "dev-libs/boost-1.52.0" : { + "EAPI": "5", + "SLOT": "0/1.52", + "RDEPEND" : "=dev-util/boost-build-1.52.0" + } + + } + + world = ["dev-cpp/libcmis", "dev-libs/boost", "app-text/podofo"] + + test_cases = ( + + # In order to avoid a missed update, first mask lower + # versions that conflict with higher versions. Note that + # this behavior makes SlotConflictMaskUpdateTestCase + # fail. + ResolverPlaygroundTestCase( + world, + all_permutations = True, + options = {"--update": True, "--deep": True}, + success = True, + mergelist = ['dev-util/boost-build-1.53.0', 'dev-libs/boost-1.53.0', 'dev-cpp/libcmis-0.3.1']), + + ) + + 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()