aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2013-08-02 01:24:32 -0700
committerZac Medico <zmedico@gentoo.org>2013-08-02 01:24:32 -0700
commit9b6f69e2a66c0f1d1d6545208edb3c45eacfd845 (patch)
treef6dbb9bc36c248c30c2e914ec084c5daaba25e4d
parentFix imprecise paragraph, bug #339446 (diff)
downloadportage-9b6f69e2a66c0f1d1d6545208edb3c45eacfd845.tar.gz
portage-9b6f69e2a66c0f1d1d6545208edb3c45eacfd845.tar.bz2
portage-9b6f69e2a66c0f1d1d6545208edb3c45eacfd845.zip
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
-rw-r--r--pym/_emerge/depgraph.py15
-rw-r--r--pym/portage/tests/resolver/test_backtracking.py31
-rw-r--r--pym/portage/tests/resolver/test_slot_conflict_mask_update.py41
-rw-r--r--pym/portage/tests/resolver/test_slot_conflict_update.py98
4 files changed, 143 insertions, 42 deletions
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()