Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] _solve_..slot_conflicts: fix bug #522084
Date: Thu, 18 Sep 2014 23:29:18
Message-Id: 541B6AC9.20703@gentoo.org
1 From 963efa6fcf1e61d836d5292c88500a7c032cf46e Mon Sep 17 00:00:00 2001
2 From: Zac Medico <zmedico@g.o>
3 Date: Thu, 18 Sep 2014 16:16:13 -0700
4 Subject: [PATCH] _solve_..slot_conflicts: fix bug #522084
5
6 Fix _solve_non_slot_operator_slot_conflicts to add all parents to the
7 conflict_graph, even for parents where the atom matches all relevant
8 nodes. Otherwise, we risk removing all of the matched nodes from the
9 graph, which would cause a missed update.
10
11 X-Gentoo-Bug: 522084
12 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=522084
13 ---
14 pym/_emerge/depgraph.py | 14 ++--
15 .../test_solve_non_slot_operator_slot_conflicts.py | 74 ++++++++++++++++++++++
16 2 files changed, 81 insertions(+), 7 deletions(-)
17 create mode 100644 pym/portage/tests/resolver/test_solve_non_slot_operator_slot_conflicts.py
18
19 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
20 index 6332733..7bb5252 100644
21 --- a/pym/_emerge/depgraph.py
22 +++ b/pym/_emerge/depgraph.py
23 @@ -1171,12 +1171,15 @@ class depgraph(object):
24 for match in matched:
25 writemsg_level(" match: %s\n" % match, level=logging.DEBUG, noiselevel=-1)
26
27 - if len(matched) == len(conflict):
28 - # All packages match.
29 - continue
30 + if len(matched) > 1:
31 + # Even if all packages match, This parent must still
32 + # be added to the conflict_graph. Otherwise, we risk
33 + # removing all of these packages from the depgraph,
34 + # which could cause a missed update (bug #522084).
35 + conflict_graph.add(or_tuple(matched), parent)
36 elif len(matched) == 1:
37 conflict_graph.add(matched[0], parent)
38 - elif len(matched) == 0:
39 + else:
40 # This typically means that autounmask broke a
41 # USE-dep, but it could also be due to the slot
42 # not matching due to multislot (bug #220341).
43 @@ -1188,9 +1191,6 @@ class depgraph(object):
44 for pkg in conflict:
45 writemsg_level(" non-match: %s\n" % pkg,
46 level=logging.DEBUG, noiselevel=-1)
47 - else:
48 - # More than one packages matched, but not all.
49 - conflict_graph.add(or_tuple(matched), parent)
50
51 for pkg in indirect_conflict_pkgs:
52 for parent, atom in self._dynamic_config._parent_atoms.get(pkg, []):
53 diff --git a/pym/portage/tests/resolver/test_solve_non_slot_operator_slot_conflicts.py b/pym/portage/tests/resolver/test_solve_non_slot_operator_slot_conflicts.py
54 new file mode 100644
55 index 0000000..ecda28e
56 --- /dev/null
57 +++ b/pym/portage/tests/resolver/test_solve_non_slot_operator_slot_conflicts.py
58 @@ -0,0 +1,74 @@
59 +# Copyright 2014 Gentoo Foundation
60 +# Distributed under the terms of the GNU General Public License v2
61 +
62 +from portage.tests import TestCase
63 +from portage.tests.resolver.ResolverPlayground import (ResolverPlayground,
64 + ResolverPlaygroundTestCase)
65 +
66 +class SolveNonSlotOperatorSlotConflictsTestCase(TestCase):
67 +
68 + def testSolveNonSlotOperatorSlotConflicts(self):
69 +
70 + ebuilds = {
71 +
72 + "app-misc/A-1" : {
73 + "EAPI": "5",
74 + "SLOT": "0/1",
75 + "PDEPEND": "app-misc/B"
76 + },
77 +
78 + "app-misc/A-2" : {
79 + "EAPI": "5",
80 + "SLOT": "0/2",
81 + "PDEPEND": "app-misc/B"
82 + },
83 +
84 + "app-misc/B-0" : {
85 + "EAPI": "5",
86 + "RDEPEND": "app-misc/A:="
87 + },
88 +
89 + }
90 +
91 + installed = {
92 +
93 + "app-misc/A-1" : {
94 + "EAPI": "5",
95 + "SLOT": "0/1",
96 + "PDEPEND": "app-misc/B"
97 + },
98 +
99 + "app-misc/B-0" : {
100 + "EAPI": "5",
101 + "RDEPEND": "app-misc/A:0/1="
102 + },
103 +
104 + }
105 +
106 + world = ["app-misc/A"]
107 +
108 + test_cases = (
109 +
110 + # bug 522084
111 + # In this case, _solve_non_slot_operator_slot_conflicts
112 + # removed both versions of app-misc/A from the graph, since
113 + # they didn't have any non-conflict parents (except for
114 + # @selected which matched both instances). The result was
115 + # a missed update.
116 + ResolverPlaygroundTestCase(
117 + ["@world"],
118 + options = {"--update": True, "--deep": True},
119 + success = True,
120 + mergelist = ['app-misc/A-2', 'app-misc/B-0']
121 + ),
122 +
123 + )
124 +
125 + playground = ResolverPlayground(ebuilds=ebuilds,
126 + installed=installed, world=world, debug=False)
127 + try:
128 + for test_case in test_cases:
129 + playground.run_TestCase(test_case)
130 + self.assertEqual(test_case.test_success, True, test_case.fail_msg)
131 + finally:
132 + playground.cleanup()
133 --
134 1.8.5.5