Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] depgraph: fix runtime package mask interaction with slot operator rebuilds (bug 612094)
Date: Thu, 09 Mar 2017 06:12:09
Message-Id: 20170309061145.23038-1-zmedico@gentoo.org
1 In some cases the backtracking runtime package mask can interact badly
2 with slot operator rebuilds, preventing a solution from being found.
3 This patch fixes the problem, which is demonstrated by the included
4 unit test.
5
6 X-Gentoo-bug: 612094
7 X-Gentoo-bug-url: https://bugs.gentoo.org/show_bug.cgi?id=612094
8 ---
9 pym/_emerge/depgraph.py | 28 +++--
10 .../test_slot_operator_runtime_pkg_mask.py | 136 +++++++++++++++++++++
11 2 files changed, 152 insertions(+), 12 deletions(-)
12 create mode 100644 pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py
13
14 diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py
15 index bb3e307..1379b05 100644
16 --- a/pym/_emerge/depgraph.py
17 +++ b/pym/_emerge/depgraph.py
18 @@ -1597,9 +1597,6 @@ class depgraph(object):
19 atom.package and atom.slot_operator_built):
20 continue
21
22 - if pkg not in conflict_pkgs:
23 - continue
24 -
25 for other_pkg in slot_nodes:
26 if other_pkg in conflict_pkgs:
27 continue
28 @@ -2569,18 +2566,25 @@ class depgraph(object):
29 # runtime_pkg_mask, since that would trigger an
30 # infinite backtracking loop.
31 if self._dynamic_config._allow_backtracking:
32 - if dep.parent in self._dynamic_config._runtime_pkg_mask:
33 - if debug:
34 - writemsg(
35 - "!!! backtracking loop detected: %s %s\n" % \
36 - (dep.parent,
37 - self._dynamic_config._runtime_pkg_mask[
38 - dep.parent]), noiselevel=-1)
39 - elif dep.atom.package and dep.atom.slot_operator_built and \
40 - self._slot_operator_unsatisfied_probe(dep):
41 + if (dep.parent not in self._dynamic_config._runtime_pkg_mask and
42 + dep.atom.package and dep.atom.slot_operator_built and
43 + self._slot_operator_unsatisfied_probe(dep)):
44 self._slot_operator_unsatisfied_backtrack(dep)
45 return 1
46 else:
47 + # This is for backward-compatibility with previous
48 + # behavior, so that installed packages with unsatisfied
49 + # dependencies trigger an error message but do not
50 + # cause the dependency calculation to fail. Only do
51 + # this if the parent is already in the runtime package
52 + # mask, since otherwise we need to backtrack.
53 + if (dep.parent.installed and
54 + dep.parent in self._dynamic_config._runtime_pkg_mask and
55 + not any(self._iter_match_pkgs_any(
56 + dep.parent.root_config, dep.atom))):
57 + self._dynamic_config._initially_unsatisfied_deps.append(dep)
58 + return 1
59 +
60 # Do not backtrack if only USE have to be changed in
61 # order to satisfy the dependency. Note that when
62 # want_restart_for_use_change sets the need_restart
63 diff --git a/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py b/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py
64 new file mode 100644
65 index 0000000..0a5a7fa
66 --- /dev/null
67 +++ b/pym/portage/tests/resolver/test_slot_operator_runtime_pkg_mask.py
68 @@ -0,0 +1,136 @@
69 +# Copyright 2017 Gentoo Foundation
70 +# Distributed under the terms of the GNU General Public License v2
71 +
72 +from portage.tests import TestCase
73 +from portage.tests.resolver.ResolverPlayground import (
74 + ResolverPlayground,
75 + ResolverPlaygroundTestCase,
76 +)
77 +
78 +class SlotOperatorRuntimePkgMaskTestCase(TestCase):
79 +
80 + def testSlotOperatorRuntimePkgMask(self):
81 +
82 + ebuilds = {
83 + "app-misc/meta-pkg-2" : {
84 + "EAPI": "6",
85 + "DEPEND": "=app-misc/B-2 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-2",
86 + "RDEPEND": "=app-misc/B-2 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-2",
87 + },
88 +
89 + "app-misc/meta-pkg-1" : {
90 + "EAPI": "6",
91 + "DEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1",
92 + "RDEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1",
93 + },
94 +
95 + "app-misc/B-1" : {
96 + "EAPI": "6",
97 + "DEPEND": "dev-libs/foo:=",
98 + "RDEPEND": "dev-libs/foo:=",
99 + },
100 +
101 + "app-misc/B-2" : {
102 + "EAPI": "6",
103 + "DEPEND": "dev-libs/foo:=",
104 + "RDEPEND": "dev-libs/foo:=",
105 + },
106 +
107 + "app-misc/C-1" : {
108 + "EAPI": "6",
109 + "DEPEND": "dev-libs/foo:=",
110 + "RDEPEND": "dev-libs/foo:=",
111 + },
112 +
113 + "app-misc/C-2" : {
114 + "EAPI": "6",
115 + "DEPEND": "dev-libs/foo:=",
116 + "RDEPEND": "dev-libs/foo:=",
117 + },
118 +
119 + "app-misc/D-1" : {
120 + "EAPI": "6",
121 + "DEPEND": "dev-libs/foo:=",
122 + "RDEPEND": "dev-libs/foo:=",
123 + },
124 +
125 + "app-misc/D-2" : {
126 + "EAPI": "6",
127 + "DEPEND": "dev-libs/foo:=",
128 + "RDEPEND": "dev-libs/foo:=",
129 + },
130 +
131 + "dev-libs/foo-1" : {
132 + "EAPI": "6",
133 + "SLOT": "0/1",
134 + },
135 +
136 + "dev-libs/foo-2" : {
137 + "EAPI": "6",
138 + "SLOT": "0/2",
139 + },
140 + }
141 +
142 + installed = {
143 + "app-misc/meta-pkg-1" : {
144 + "EAPI": "6",
145 + "DEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1",
146 + "RDEPEND": "=app-misc/B-1 =app-misc/C-1 =app-misc/D-1 =dev-libs/foo-1",
147 + },
148 +
149 + "app-misc/B-1" : {
150 + "EAPI": "6",
151 + "DEPEND": "dev-libs/foo:0/1=",
152 + "RDEPEND": "dev-libs/foo:0/1=",
153 + },
154 +
155 + "app-misc/C-1" : {
156 + "EAPI": "6",
157 + "DEPEND": "dev-libs/foo:0/1=",
158 + "RDEPEND": "dev-libs/foo:0/1=",
159 + },
160 +
161 + "app-misc/D-1" : {
162 + "EAPI": "6",
163 + "DEPEND": "dev-libs/foo:0/1=",
164 + "RDEPEND": "dev-libs/foo:0/1=",
165 + },
166 +
167 + "dev-libs/foo-1" : {
168 + "EAPI": "6",
169 + "SLOT": "0/1",
170 + },
171 + }
172 +
173 + world = (
174 + "app-misc/meta-pkg",
175 + )
176 +
177 + test_cases = (
178 + ResolverPlaygroundTestCase(
179 + ["=app-misc/meta-pkg-2"],
180 + options = {
181 + "--backtrack": 5,
182 + },
183 + success = True,
184 + ambiguous_merge_order = True,
185 + mergelist = [
186 + 'dev-libs/foo-2',
187 + ('app-misc/D-1', 'app-misc/C-1', 'app-misc/B-2'),
188 + 'app-misc/meta-pkg-2',
189 + ]
190 + ),
191 + )
192 +
193 + playground = ResolverPlayground(debug=False,
194 + ebuilds=ebuilds, installed=installed,
195 + world=world)
196 + try:
197 + for test_case in test_cases:
198 + playground.run_TestCase(test_case)
199 + self.assertEqual(test_case.test_success, True,
200 + test_case.fail_msg)
201 + finally:
202 + # Disable debug so that cleanup works.
203 + playground.debug = False
204 + playground.cleanup()
205 --
206 2.10.2

Replies