1 |
commit: 9b6f69e2a66c0f1d1d6545208edb3c45eacfd845 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Aug 2 08:24:32 2013 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri Aug 2 08:24:32 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=9b6f69e2 |
7 |
|
8 |
Avoid some missed updates when backtracking. |
9 |
|
10 |
This avoids unnecessarily missed updates like the following: |
11 |
|
12 |
WARNING: One or more updates have been skipped due to a dependency conflict: |
13 |
|
14 |
dev-util/boost-build:0 |
15 |
|
16 |
(dev-util/boost-build-1.53.0::gentoo, ebuild scheduled for merge) conflicts with |
17 |
=dev-util/boost-build-1.52.0-r1 required by (dev-libs/boost-1.52.0-r6::gentoo, installed) |
18 |
|
19 |
!!! The following update(s) have been skipped due to unsatisfied dependencies |
20 |
!!! triggered by backtracking: |
21 |
|
22 |
dev-libs/boost:0 |
23 |
|
24 |
--- |
25 |
pym/_emerge/depgraph.py | 15 +--- |
26 |
pym/portage/tests/resolver/test_backtracking.py | 31 ------- |
27 |
.../resolver/test_slot_conflict_mask_update.py | 41 +++++++++ |
28 |
.../tests/resolver/test_slot_conflict_update.py | 98 ++++++++++++++++++++++ |
29 |
4 files changed, 143 insertions(+), 42 deletions(-) |
30 |
|
31 |
diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py |
32 |
index 76fda2c..39ae3ea 100644 |
33 |
--- a/pym/_emerge/depgraph.py |
34 |
+++ b/pym/_emerge/depgraph.py |
35 |
@@ -6,6 +6,7 @@ from __future__ import print_function, unicode_literals |
36 |
import errno |
37 |
import io |
38 |
import logging |
39 |
+import operator |
40 |
import stat |
41 |
import sys |
42 |
import textwrap |
43 |
@@ -983,17 +984,9 @@ class depgraph(object): |
44 |
backtrack_data.append((to_be_masked, conflict_atoms)) |
45 |
|
46 |
if len(backtrack_data) > 1: |
47 |
- # NOTE: Generally, we prefer to mask the higher |
48 |
- # version since this solves common cases in which a |
49 |
- # lower version is needed so that all dependencies |
50 |
- # will be satisfied (bug #337178). However, if |
51 |
- # existing_node happens to be installed then we |
52 |
- # mask that since this is a common case that is |
53 |
- # triggered when --update is not enabled. |
54 |
- if existing_node.installed: |
55 |
- pass |
56 |
- elif any(pkg > existing_node for pkg in conflict_pkgs): |
57 |
- backtrack_data.reverse() |
58 |
+ # In order to avoid a missed update, first mask lower |
59 |
+ # versions that conflict with higher versions. |
60 |
+ backtrack_data.sort(key=operator.itemgetter(0), reverse=True) |
61 |
|
62 |
to_be_masked = backtrack_data[-1][0] |
63 |
|
64 |
|
65 |
diff --git a/pym/portage/tests/resolver/test_backtracking.py b/pym/portage/tests/resolver/test_backtracking.py |
66 |
index 53899eb..9dc37ac 100644 |
67 |
--- a/pym/portage/tests/resolver/test_backtracking.py |
68 |
+++ b/pym/portage/tests/resolver/test_backtracking.py |
69 |
@@ -67,37 +67,6 @@ class BacktrackingTestCase(TestCase): |
70 |
finally: |
71 |
playground.cleanup() |
72 |
|
73 |
- |
74 |
- def testBacktrackingGoodVersionFirst(self): |
75 |
- """ |
76 |
- When backtracking due to slot conflicts, we masked the version that has been pulled |
77 |
- in first. This is not always a good idea. Mask the highest version instead. |
78 |
- """ |
79 |
- |
80 |
- ebuilds = { |
81 |
- "dev-libs/A-1": { "DEPEND": "=dev-libs/C-1 dev-libs/B" }, |
82 |
- "dev-libs/B-1": { "DEPEND": "=dev-libs/C-1" }, |
83 |
- "dev-libs/B-2": { "DEPEND": "=dev-libs/C-2" }, |
84 |
- "dev-libs/C-1": { }, |
85 |
- "dev-libs/C-2": { }, |
86 |
- } |
87 |
- |
88 |
- test_cases = ( |
89 |
- ResolverPlaygroundTestCase( |
90 |
- ["dev-libs/A"], |
91 |
- mergelist = ["dev-libs/C-1", "dev-libs/B-1", "dev-libs/A-1",], |
92 |
- success = True), |
93 |
- ) |
94 |
- |
95 |
- playground = ResolverPlayground(ebuilds=ebuilds) |
96 |
- |
97 |
- try: |
98 |
- for test_case in test_cases: |
99 |
- playground.run_TestCase(test_case) |
100 |
- self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
101 |
- finally: |
102 |
- playground.cleanup() |
103 |
- |
104 |
def testBacktrackWithoutUpdates(self): |
105 |
""" |
106 |
If --update is not given we might have to mask the old installed version later. |
107 |
|
108 |
diff --git a/pym/portage/tests/resolver/test_slot_conflict_mask_update.py b/pym/portage/tests/resolver/test_slot_conflict_mask_update.py |
109 |
new file mode 100644 |
110 |
index 0000000..a90eeac |
111 |
--- /dev/null |
112 |
+++ b/pym/portage/tests/resolver/test_slot_conflict_mask_update.py |
113 |
@@ -0,0 +1,41 @@ |
114 |
+# Copyright 2013 Gentoo Foundation |
115 |
+# Distributed under the terms of the GNU General Public License v2 |
116 |
+ |
117 |
+from portage.tests import TestCase |
118 |
+from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, |
119 |
+ ResolverPlaygroundTestCase) |
120 |
+ |
121 |
+class SlotConflictMaskUpdateTestCase(TestCase): |
122 |
+ |
123 |
+ def testBacktrackingGoodVersionFirst(self): |
124 |
+ """ |
125 |
+ When backtracking due to slot conflicts, we masked the version that has been pulled |
126 |
+ in first. This is not always a good idea. Mask the highest version instead. |
127 |
+ """ |
128 |
+ |
129 |
+ |
130 |
+ self.todo = True |
131 |
+ |
132 |
+ ebuilds = { |
133 |
+ "dev-libs/A-1": { "DEPEND": "=dev-libs/C-1 dev-libs/B" }, |
134 |
+ "dev-libs/B-1": { "DEPEND": "=dev-libs/C-1" }, |
135 |
+ "dev-libs/B-2": { "DEPEND": "=dev-libs/C-2" }, |
136 |
+ "dev-libs/C-1": { }, |
137 |
+ "dev-libs/C-2": { }, |
138 |
+ } |
139 |
+ |
140 |
+ test_cases = ( |
141 |
+ ResolverPlaygroundTestCase( |
142 |
+ ["dev-libs/A"], |
143 |
+ mergelist = ["dev-libs/C-1", "dev-libs/B-1", "dev-libs/A-1",], |
144 |
+ success = True), |
145 |
+ ) |
146 |
+ |
147 |
+ playground = ResolverPlayground(ebuilds=ebuilds) |
148 |
+ |
149 |
+ try: |
150 |
+ for test_case in test_cases: |
151 |
+ playground.run_TestCase(test_case) |
152 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
153 |
+ finally: |
154 |
+ playground.cleanup() |
155 |
|
156 |
diff --git a/pym/portage/tests/resolver/test_slot_conflict_update.py b/pym/portage/tests/resolver/test_slot_conflict_update.py |
157 |
new file mode 100644 |
158 |
index 0000000..331e578 |
159 |
--- /dev/null |
160 |
+++ b/pym/portage/tests/resolver/test_slot_conflict_update.py |
161 |
@@ -0,0 +1,98 @@ |
162 |
+# Copyright 2013 Gentoo Foundation |
163 |
+# Distributed under the terms of the GNU General Public License v2 |
164 |
+ |
165 |
+from portage.tests import TestCase |
166 |
+from portage.tests.resolver.ResolverPlayground import (ResolverPlayground, |
167 |
+ ResolverPlaygroundTestCase) |
168 |
+ |
169 |
+class SlotConflictUpdateTestCase(TestCase): |
170 |
+ |
171 |
+ def testSlotConflictUpdate(self): |
172 |
+ |
173 |
+ ebuilds = { |
174 |
+ |
175 |
+ "app-text/podofo-0.9.2" : { |
176 |
+ "EAPI": "5", |
177 |
+ "RDEPEND" : "dev-util/boost-build" |
178 |
+ }, |
179 |
+ |
180 |
+ "dev-cpp/libcmis-0.3.1" : { |
181 |
+ "EAPI": "5", |
182 |
+ "RDEPEND" : "dev-libs/boost:=" |
183 |
+ }, |
184 |
+ |
185 |
+ "dev-libs/boost-1.53.0" : { |
186 |
+ "EAPI": "5", |
187 |
+ "SLOT": "0/1.53", |
188 |
+ "RDEPEND" : "=dev-util/boost-build-1.53.0" |
189 |
+ }, |
190 |
+ |
191 |
+ "dev-libs/boost-1.52.0" : { |
192 |
+ "EAPI": "5", |
193 |
+ "SLOT": "0/1.52", |
194 |
+ "RDEPEND" : "=dev-util/boost-build-1.52.0" |
195 |
+ }, |
196 |
+ |
197 |
+ "dev-util/boost-build-1.53.0" : { |
198 |
+ "EAPI": "5", |
199 |
+ "SLOT": "0" |
200 |
+ }, |
201 |
+ |
202 |
+ "dev-util/boost-build-1.52.0" : { |
203 |
+ "EAPI": "5", |
204 |
+ "SLOT": "0" |
205 |
+ }, |
206 |
+ |
207 |
+ |
208 |
+ } |
209 |
+ |
210 |
+ installed = { |
211 |
+ |
212 |
+ "app-text/podofo-0.9.2" : { |
213 |
+ "EAPI": "5", |
214 |
+ "RDEPEND" : "dev-util/boost-build" |
215 |
+ }, |
216 |
+ |
217 |
+ "dev-cpp/libcmis-0.3.1" : { |
218 |
+ "EAPI": "5", |
219 |
+ "RDEPEND" : "dev-libs/boost:0/1.52=" |
220 |
+ }, |
221 |
+ |
222 |
+ "dev-util/boost-build-1.52.0" : { |
223 |
+ "EAPI": "5", |
224 |
+ "SLOT": "0" |
225 |
+ }, |
226 |
+ |
227 |
+ "dev-libs/boost-1.52.0" : { |
228 |
+ "EAPI": "5", |
229 |
+ "SLOT": "0/1.52", |
230 |
+ "RDEPEND" : "=dev-util/boost-build-1.52.0" |
231 |
+ } |
232 |
+ |
233 |
+ } |
234 |
+ |
235 |
+ world = ["dev-cpp/libcmis", "dev-libs/boost", "app-text/podofo"] |
236 |
+ |
237 |
+ test_cases = ( |
238 |
+ |
239 |
+ # In order to avoid a missed update, first mask lower |
240 |
+ # versions that conflict with higher versions. Note that |
241 |
+ # this behavior makes SlotConflictMaskUpdateTestCase |
242 |
+ # fail. |
243 |
+ ResolverPlaygroundTestCase( |
244 |
+ world, |
245 |
+ all_permutations = True, |
246 |
+ options = {"--update": True, "--deep": True}, |
247 |
+ success = True, |
248 |
+ mergelist = ['dev-util/boost-build-1.53.0', 'dev-libs/boost-1.53.0', 'dev-cpp/libcmis-0.3.1']), |
249 |
+ |
250 |
+ ) |
251 |
+ |
252 |
+ playground = ResolverPlayground(ebuilds=ebuilds, |
253 |
+ installed=installed, world=world, debug=False) |
254 |
+ try: |
255 |
+ for test_case in test_cases: |
256 |
+ playground.run_TestCase(test_case) |
257 |
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg) |
258 |
+ finally: |
259 |
+ playground.cleanup() |