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