Merge lp:~xnox/britney/deps-components into lp:~ubuntu-release/britney/britney2-ubuntu

Proposed by Dimitri John Ledkov on 2016-02-18
Status: Merged
Merged at revision: 583
Proposed branch: lp:~xnox/britney/deps-components
Merge into: lp:~ubuntu-release/britney/britney2-ubuntu
Diff against target: 203 lines (+109/-8)
4 files modified
britney.py (+18/-7)
britney_util.py (+32/-1)
consts.py (+7/-0)
tests/test_util.py (+52/-0)
To merge this branch: bzr merge lp:~xnox/britney/deps-components
Reviewer Review Type Date Requested Status
Martin Pitt (community) 2016-02-18 Approve on 2016-03-01
Colin Watson 2016-02-18 Pending
Ubuntu Release Team 2016-02-18 Pending
Review via email: mp+286511@code.launchpad.net

Description of the Change

Teach excuse_unsat_deps() about components ogre model.

This does not change other instalability tests, to hopefully, avoid britney trading all components mismatches around.

With this, components-mismatched things should stop migrating.

To post a comment you must log in.
Dimitri John Ledkov (xnox) wrote :

I did not run britney with this change in, not sure how to.

All tests do pass, but they are limited in coverage.

Dimitri John Ledkov (xnox) wrote :

Run it, britney did not crash and found a buggy package already:

maas (1.9.0+bzr4533-0ubuntu1 to 1.10.0+bzr4578-0ubuntu2)
Maintainer: Ubuntu Developers
0 days old
python3-maas-provisioningserver/amd64 unsatisfiable Depends: python3-distro-info
Not considered

vs

maas (1.9.0+bzr4533-0ubuntu1 to 1.10.0+bzr4578-0ubuntu2)
Maintainer: Ubuntu Developers
7 days old
Valid candidate

Martin Pitt (pitti) wrote :

It's quite important to add some integration tests for this, but this doesn't need to block the initial rollout. LGTM otherwise, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'britney.py'
2--- britney.py 2016-02-16 09:18:43 +0000
3+++ britney.py 2016-02-18 14:08:15 +0000
4@@ -208,10 +208,11 @@
5 eval_uninst, newly_uninst, make_migrationitem,
6 write_excuses, write_heidi_delta, write_controlfiles,
7 old_libraries, is_nuninst_asgood_generous, ensuredir,
8- clone_nuninst)
9+ clone_nuninst, get_component, allowed_component)
10 from consts import (VERSION, SECTION, BINARIES, MAINTAINER, FAKESRC,
11- SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS,
12- PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL)
13+ SOURCE, SOURCEVER, ARCHITECTURE, DEPENDS, CONFLICTS,
14+ PROVIDES, RDEPENDS, RCONFLICTS, MULTIARCH, ESSENTIAL,
15+ COMPONENT, MULTIVERSE)
16 from autopkgtest import AutoPackageTest, srchash
17
18
19@@ -710,6 +711,7 @@
20 [],
21 [],
22 ess,
23+ get_component(get_field('Section'))
24 ]
25
26 # retrieve the name and the version of the source package
27@@ -1105,7 +1107,7 @@
28 # Utility methods for package analysis
29 # ------------------------------------
30
31- def get_dependency_solvers(self, block, arch, distribution):
32+ def get_dependency_solvers(self, block, arch, distribution, component=MULTIVERSE):
33 """Find the packages which satisfy a dependency block
34
35 This method returns the list of packages which satisfy a dependency
36@@ -1115,6 +1117,12 @@
37 It returns a tuple with two items: the first is a boolean which is
38 True if the dependency is satisfied, the second is the list of the
39 solving packages.
40+
41+ If component was not specified, use all availalbe
42+ (multiverse). This is to avoid britney pretending that a bunch
43+ of things are non-installable in release pocket, and start
44+ trading components-missmatches things.
45+
46 """
47
48 packages = []
49@@ -1136,7 +1144,8 @@
50 # (if present)
51 if (op == '' and version == '') or apt_pkg.check_dep(package[VERSION], op, version):
52 if archqual is None or (archqual == 'any' and package[MULTIARCH] == 'allowed'):
53- packages.append(name)
54+ if allowed_component(component, package[COMPONENT]):
55+ packages.append(name)
56
57 # look for the package in the virtual packages list and loop on them
58 for prov in binaries[1].get(name, []):
59@@ -1193,12 +1202,14 @@
60 return True
61 deps = binary_u[DEPENDS]
62
63+ component = binary_u[COMPONENT]
64+
65 all_satisfiable = True
66
67 # for every dependency block (formed as conjunction of disjunction)
68 for block, block_txt in zip(parse_depends(deps, False), deps.split(',')):
69 # if the block is satisfied in testing, then skip the block
70- packages = get_dependency_solvers(block, arch, 'testing')
71+ packages = get_dependency_solvers(block, arch, 'testing', component)
72 if packages:
73 for p in packages:
74 if p not in self.binaries[suite][arch][0]: continue
75@@ -1206,7 +1217,7 @@
76 continue
77
78 # check if the block can be satisfied in unstable, and list the solving packages
79- packages = get_dependency_solvers(block, arch, suite)
80+ packages = get_dependency_solvers(block, arch, suite, component)
81 packages = [self.binaries[suite][arch][0][p][SOURCE] for p in packages]
82
83 # if the dependency can be satisfied by the same source package, skip the block:
84
85=== modified file 'britney_util.py'
86--- britney_util.py 2015-08-24 18:46:42 +0000
87+++ britney_util.py 2016-02-18 14:08:15 +0000
88@@ -35,7 +35,7 @@
89 from consts import (VERSION, BINARIES, PROVIDES, DEPENDS, CONFLICTS,
90 RDEPENDS, RCONFLICTS, ARCHITECTURE, SECTION,
91 SOURCE, SOURCEVER, MAINTAINER, MULTIARCH,
92- ESSENTIAL)
93+ ESSENTIAL, MAIN, RESTRICTED, UNIVERSE, MULTIVERSE)
94
95 binnmu_re = re.compile(r'^(.*)\+b\d+$')
96
97@@ -620,3 +620,34 @@
98 clone[arch] = set(x for x in nuninst[arch] if x in packages_s[arch][0])
99 clone[arch + "+all"] = set(x for x in nuninst[arch + "+all"] if x in packages_s[arch][0])
100 return clone
101+
102+
103+def get_component(section):
104+ """Parse section and return component
105+
106+ Given a section, return component. Packages in MAIN have no
107+ prefix, all others have <component>/ prefix.
108+ """
109+ name2component = {
110+ "restricted": RESTRICTED,
111+ "universe": UNIVERSE,
112+ "multiverse": MULTIVERSE
113+ }
114+
115+ if '/' in section:
116+ return name2component[section.split('/', 1)[0]]
117+
118+ return MAIN
119+
120+
121+def allowed_component(me, dep):
122+ """Check if I can depend on the other component"""
123+
124+ component_dependencies = {
125+ MAIN: [MAIN],
126+ RESTRICTED: [MAIN, RESTRICTED],
127+ UNIVERSE: [MAIN, UNIVERSE],
128+ MULTIVERSE: [MAIN, RESTRICTED, UNIVERSE, MULTIVERSE],
129+ }
130+
131+ return dep in component_dependencies[me]
132
133=== modified file 'consts.py'
134--- consts.py 2015-07-01 13:49:06 +0000
135+++ consts.py 2016-02-18 14:08:15 +0000
136@@ -37,3 +37,10 @@
137 RDEPENDS = 9
138 RCONFLICTS = 10
139 ESSENTIAL = 11
140+COMPONENT = 12
141+
142+# components
143+MAIN = 0
144+RESTRICTED = 1
145+UNIVERSE = 2
146+MULTIVERSE = 3
147
148=== added file 'tests/test_util.py'
149--- tests/test_util.py 1970-01-01 00:00:00 +0000
150+++ tests/test_util.py 2016-02-18 14:08:15 +0000
151@@ -0,0 +1,52 @@
152+#!/usr/bin/python3
153+# (C) 2014 - 2016 Canonical Ltd.
154+#
155+# This program is free software; you can redistribute it and/or modify
156+# it under the terms of the GNU General Public License as published by
157+# the Free Software Foundation; either version 2 of the License, or
158+# (at your option) any later version.
159+
160+import os
161+import sys
162+import unittest
163+
164+PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
165+sys.path.insert(0, PROJECT_DIR)
166+
167+from britney_util import get_component, allowed_component
168+from consts import MAIN, RESTRICTED, UNIVERSE, MULTIVERSE
169+
170+
171+class UtilTests(unittest.TestCase):
172+
173+ def test_get_component(self):
174+ self.assertEqual(get_component('utils'), MAIN)
175+ self.assertEqual(get_component('utils'), MAIN)
176+ self.assertEqual(get_component('restricted/admin'), RESTRICTED)
177+ self.assertEqual(get_component('universe/web'), UNIVERSE)
178+ self.assertEqual(get_component('multiverse/libs'), MULTIVERSE)
179+
180+ def test_allowed_component(self):
181+ self.assertTrue(allowed_component(MAIN, MAIN))
182+ self.assertFalse(allowed_component(MAIN, UNIVERSE))
183+ self.assertFalse(allowed_component(MAIN, MULTIVERSE))
184+ self.assertFalse(allowed_component(MAIN, RESTRICTED))
185+
186+ self.assertTrue(allowed_component(RESTRICTED, MAIN))
187+ self.assertFalse(allowed_component(RESTRICTED, UNIVERSE))
188+ self.assertFalse(allowed_component(RESTRICTED, MULTIVERSE))
189+ self.assertTrue(allowed_component(RESTRICTED, RESTRICTED))
190+
191+ self.assertTrue(allowed_component(UNIVERSE, MAIN))
192+ self.assertTrue(allowed_component(UNIVERSE, UNIVERSE))
193+ self.assertFalse(allowed_component(UNIVERSE, MULTIVERSE))
194+ self.assertFalse(allowed_component(UNIVERSE, RESTRICTED))
195+
196+ self.assertTrue(allowed_component(MULTIVERSE, MAIN))
197+ self.assertTrue(allowed_component(MULTIVERSE, UNIVERSE))
198+ self.assertTrue(allowed_component(MULTIVERSE, MULTIVERSE))
199+ self.assertTrue(allowed_component(MULTIVERSE, RESTRICTED))
200+
201+
202+if __name__ == '__main__':
203+ unittest.main()

Subscribers

People subscribed via source and target branches