* [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/tests/util/, pym/portage/util/, ...
@ 2017-03-17 16:03 Zac Medico
0 siblings, 0 replies; only message in thread
From: Zac Medico @ 2017-03-17 16:03 UTC (permalink / raw
To: gentoo-commits
commit: 35208d80a55228a50ea4ac64904465ce4651e381
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 17 06:14:12 2017 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Fri Mar 17 16:01:58 2017 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=35208d80
depgraph: avoid missed update with slot operator and circ dep (bug 612874)
Fix check_reverse_dependencies to ignore direct circular dependencies,
since these dependencies tend to prevent updates of packages. This
solves a missed update from llvm:0 to llvm:4 when clang is not in the
world file, as demonstrated by the included test case.
X-Gentoo-bug: 612874
X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612874
Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>
pym/_emerge/depgraph.py | 31 ++++++++++++-----
.../resolver/test_slot_operator_exclusive_slots.py | 39 ++++++++++++++++++++++
pym/portage/tests/util/test_digraph.py | 2 ++
pym/portage/util/digraph.py | 9 +++++
4 files changed, 73 insertions(+), 8 deletions(-)
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
index f4145d05f..e94b96ce8 100644
--- a/pym/_emerge/depgraph.py
+++ b/pym/_emerge/depgraph.py
@@ -1844,14 +1844,29 @@ class depgraph(object):
if (not self._too_deep(parent.depth) and
not self._frozen_config.excluded_pkgs.
findAtomForPackage(parent,
- modified_use=self._pkg_use_enabled(parent)) and
- (self._upgrade_available(parent) or
- (parent.installed and self._in_blocker_conflict(parent)))):
- # This parent may be irrelevant, since an
- # update is available (see bug 584626), or
- # it could be uninstalled in order to solve
- # a blocker conflict (bug 612772).
- continue
+ modified_use=self._pkg_use_enabled(parent))):
+ # Check for common reasons that the parent's
+ # dependency might be irrelevant.
+ if self._upgrade_available(parent):
+ # This parent could be replaced by
+ # an upgrade (bug 584626).
+ continue
+ if parent.installed and self._in_blocker_conflict(parent):
+ # This parent could be uninstalled in order
+ # to solve a blocker conflict (bug 612772).
+ continue
+ if self._dynamic_config.digraph.has_edge(parent,
+ existing_pkg):
+ # There is a direct circular dependency between
+ # parent and existing_pkg. This type of
+ # relationship tends to prevent updates
+ # of packages (bug 612874). Since candidate_pkg
+ # is available, we risk a missed update if we
+ # don't try to eliminate this parent from the
+ # graph. Therefore, we give candidate_pkg a
+ # chance, and assume that it will be masked
+ # by backtracking if necessary.
+ continue
atom_set = InternalPackageSet(initial_atoms=(atom,),
allow_repo=True)
diff --git a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
index 2ab379cce..689ed31d0 100644
--- a/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
+++ b/pym/portage/tests/resolver/test_slot_operator_exclusive_slots.py
@@ -107,3 +107,42 @@ class SlotOperatorExclusiveSlotsTestCase(TestCase):
test_case.fail_msg)
finally:
playground.cleanup()
+
+
+ world = ["media-libs/mesa"]
+
+ test_cases = (
+
+ # Test bug #612874, where a direct circular dependency
+ # between llvm-3.9.1 and clang-3.9.1-r100 causes a
+ # missed update from llvm:0 to llvm:4. Since llvm:4 does
+ # not have a dependency on clang, the upgrade from llvm:0
+ # to llvm:4 makes the installed sys-devel/clang-3.9.1-r100
+ # instance eligible for removal by emerge --depclean, which
+ # explains why clang does not appear in the mergelist.
+ ResolverPlaygroundTestCase(
+ ["@world"],
+ options = {"--update": True, "--deep": True},
+ success = True,
+ ambiguous_merge_order = True,
+ mergelist = [
+ 'sys-devel/llvm-4.0.0',
+ (
+ 'media-libs/mesa-17.0.1',
+ '[uninstall]sys-devel/llvm-3.9.1',
+ '!sys-devel/llvm:0',
+ )
+ ],
+ ),
+
+ )
+
+ playground = ResolverPlayground(ebuilds=ebuilds,
+ installed=installed, world=world)
+ 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/util/test_digraph.py b/pym/portage/tests/util/test_digraph.py
index 4e858cf88..f519536d3 100644
--- a/pym/portage/tests/util/test_digraph.py
+++ b/pym/portage/tests/util/test_digraph.py
@@ -133,6 +133,8 @@ class DigraphTest(TestCase):
for x in g, f:
self.assertEqual(bool(x), True)
self.assertEqual(x.contains("A"), True)
+ self.assertEqual(x.has_edge("B", "A"), True)
+ self.assertEqual(x.has_edge("A", "B"), False)
self.assertEqual(x.firstzero(), "B")
self.assertRaises(KeyError, x.remove, "Z")
x.delnode("Z")
diff --git a/pym/portage/util/digraph.py b/pym/portage/util/digraph.py
index 4a9cb43b6..99b24fa1d 100644
--- a/pym/portage/util/digraph.py
+++ b/pym/portage/util/digraph.py
@@ -93,6 +93,15 @@ class digraph(object):
del self.nodes[node]
self.order = order
+ def has_edge(self, child, parent):
+ """
+ Return True if the given edge exists.
+ """
+ try:
+ return child in self.nodes[parent][0]
+ except KeyError:
+ return False
+
def remove_edge(self, child, parent):
"""
Remove edge in the direction from child to parent. Note that it is
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2017-03-17 16:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-03-17 16:03 [gentoo-commits] proj/portage:master commit in: pym/_emerge/, pym/portage/tests/util/, pym/portage/util/, Zac Medico
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox