Merge lp:~brian-murray/update-manager/phased-update-source-packages into lp:update-manager

Proposed by Brian Murray
Status: Merged
Merged at revision: 2623
Proposed branch: lp:~brian-murray/update-manager/phased-update-source-packages
Merge into: lp:update-manager
Diff against target: 157 lines (+69/-7) (has conflicts)
5 files modified
UpdateManager/Core/UpdateList.py (+9/-4)
debian/changelog (+7/-0)
tests/aptroot-update-list-test/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_main_binary-amd64_Packages (+30/-0)
tests/aptroot-update-list-test/var/lib/dpkg/status (+11/-0)
tests/test_update_list.py (+12/-3)
Text conflict in debian/changelog
To merge this branch: bzr merge lp:~brian-murray/update-manager/phased-update-source-packages
Reviewer Review Type Date Requested Status
Steve Langasek Pending
Review via email: mp+163360@code.launchpad.net

Description of the change

As discussed we should be handling the phased update percentage for binary packages in their source package groups so that we don't end up in a situations where binary dependent packages are not installed or uninstallable due to the clients phasing luck.

To post a comment you must log in.
Revision history for this message
Steve Langasek (vorlon) wrote :

> self.random.seed("%s-%s-%s" % (
> pkg.candidate.source_name, pkg.candidate.version,
> self.machine_uniq_id))

There's a buglet here; in some cases the binary package versions for packages from the same source package may not be the same, causing the binaries to be phased differently still. (Example: util-linux vs. bsdutils). I think this is probably ignorable for now, though.

+ if not is_security_update:
+ if src_name not in ignored_phased_updates:
+ if self._is_ignored_phased_update(pkg):
+ ignored_phased_updates.append(src_name)
+ continue
+ elif src_name in ignored_phased_updates:
+ continue

So if the source package has already been marked as to-be-ignored, we don't check again; but if a previous binary from the source package has been seen and is *not* to be ignored, we do check again. Fortunately we'll get the same result either way, so checking again doesn't hurt us, but it seems inconsistent. We could simply do this as:

+ if not is_security_update:
+ if self._is_ignored_phased_update(pkg):
+ continue

and that should have the same effect.

It would, however, cause your test case to fail since your test case returns '50' as the random value for all inputs, and your test data has two different phased values for zsh vs. zsh-dev. I guess a more 'realistic' reproducible test case would check that the same random value is returned for both binary packages.

2623. By Brian Murray

modifications based upon reviewer feedback

Revision history for this message
Brian Murray (brian-murray) wrote :

I've updated my branch based upon your feedback and created a new test case.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UpdateManager/Core/UpdateList.py'
2--- UpdateManager/Core/UpdateList.py 2013-05-01 05:35:33 +0000
3+++ UpdateManager/Core/UpdateList.py 2013-05-17 23:20:31 +0000
4@@ -205,6 +205,7 @@
5 self.security_groups = []
6 self.num_updates = 0
7 self.random = random.Random()
8+ self.ignored_phased_updates = []
9 # a stable machine uniq id
10 with open(self.UNIQ_MACHINE_ID_FILE) as f:
11 self.machine_uniq_id = f.read()
12@@ -357,7 +358,7 @@
13 # multiple runs of the update-manager, so we need to
14 # feed a seed that is a combination of the pkg/ver/machine
15 self.random.seed("%s-%s-%s" % (
16- pkg.name, pkg.candidate.version,
17+ pkg.candidate.source_name, pkg.candidate.version,
18 self.machine_uniq_id))
19 threshold = pkg.candidate.record[self.PHASED_UPDATES_KEY]
20 percentage = self.random.randint(0, 100)
21@@ -456,10 +457,14 @@
22 continue
23
24 # see if its a phased update and *not* a security update
25+ # keep track of packages for which the update percentage was
26+ # not met for testing
27 is_security_update = self._is_security_update(pkg)
28- if (not is_security_update and
29- self._is_ignored_phased_update(pkg)):
30- continue
31+ src_name = pkg.candidate.source_name
32+ if not is_security_update:
33+ if self._is_ignored_phased_update(pkg):
34+ self.ignored_phased_updates.append(pkg)
35+ continue
36
37 if is_security_update:
38 security_pkgs.append(pkg)
39
40=== modified file 'debian/changelog'
41--- debian/changelog 2013-05-13 10:04:53 +0000
42+++ debian/changelog 2013-05-17 23:20:31 +0000
43@@ -3,10 +3,17 @@
44 [ Sami Jaktholm ]
45 * Greatly speed up update calculation (LP: #1167277)
46
47+<<<<<<< TREE
48 [ Martin Pitt ]
49 * Drop unnecessary ubuntu-drivers-common build dependency, to ease
50 backporting.
51
52+=======
53+ [ Brian Murray ]
54+ * Modify phased update percentage to use source packages and not binary
55+ packages, additionally add a test for this.
56+
57+>>>>>>> MERGE-SOURCE
58 -- Michael Terry <mterry@ubuntu.com> Wed, 01 May 2013 14:32:43 -0700
59
60 update-manager (1:0.186) raring; urgency=low
61
62=== modified file 'tests/aptroot-update-list-test/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_main_binary-amd64_Packages'
63--- tests/aptroot-update-list-test/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_main_binary-amd64_Packages 2012-08-20 15:42:16 +0000
64+++ tests/aptroot-update-list-test/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_lucid_main_binary-amd64_Packages 2013-05-17 23:20:31 +0000
65@@ -60,3 +60,33 @@
66 Supported: 5y
67 Phased-Update-Percentage: 10
68
69+Package: zsh-dev
70+Priority: optional
71+Section: libdevel
72+Installed-Size: 348
73+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
74+Original-Maintainer: Clint Adams <schizo@debian.org>
75+Architecture: amd64
76+Source: zsh
77+Version: 4.3.10-5ubuntu3
78+Filename: pool/main/z/zsh/zsh-dev_4.3.10-5ubuntu3_amd64.deb
79+Size: 79682
80+MD5sum: 307bcd1994a2eb0d01cc06856a75fb52
81+SHA1: 9e8d41855b62ba018341882099e3849e550aa55c
82+SHA256: 5c615269c6a41ed44923edc696ab77c5c4e4b9c0ece17c0e3d767db80bfb65cc
83+Description: A shell with lots of features (development files)
84+ Zsh is a UNIX command interpreter (shell) usable as an
85+ interactive login shell and as a shell script command
86+ processor. Of the standard shells, zsh most closely resembles
87+ ksh but includes many enhancements. Zsh has command-line editing,
88+ built-in spelling correction, programmable command completion,
89+ shell functions (with autoloading), a history mechanism, and a
90+ host of other features.
91+ .
92+ This package contains headers and scripts necessary to compile
93+ third-party modules.
94+Homepage: http://www.zsh.org/
95+Bugs: https://bugs.launchpad.net/ubuntu/+filebug
96+Origin: Ubuntu
97+Supported: 18m
98+Phased-Update-Percentage: 10
99
100=== modified file 'tests/aptroot-update-list-test/var/lib/dpkg/status'
101--- tests/aptroot-update-list-test/var/lib/dpkg/status 2013-01-16 12:35:39 +0000
102+++ tests/aptroot-update-list-test/var/lib/dpkg/status 2013-05-17 23:20:31 +0000
103@@ -19,3 +19,14 @@
104 Phased-Update-Percentage: 10
105 Description: a example package with a phased updates percentage of 10%
106
107+Package: zsh-dev
108+Status: install ok installed
109+Priority: important
110+Section: admin
111+Installed-Size: 3005
112+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
113+Architecture: all
114+Version: 0.1
115+Phased-Update-Percentage: 10
116+Description: a second binary example package with a phased updates percentage of 10%
117+
118
119=== modified file 'tests/test_update_list.py'
120--- tests/test_update_list.py 2013-02-22 05:47:27 +0000
121+++ tests/test_update_list.py 2013-05-17 23:20:31 +0000
122@@ -46,7 +46,16 @@
123 with patch.object(self.updates_list.random, "randint") as mock_randint:
124 mock_randint.return_value = 1
125 self.updates_list.update(self.cache)
126- self.assertUpdatesListLen(2)
127+ self.assertUpdatesListLen(3)
128+
129+ def test_second_phased_binary_not_included(self):
130+ """ Test that there is no overlap between the source packages of the
131+ packages being ignored and installed """
132+ self.updates_list.update(self.cache)
133+ ignored_srcs = set([pkg.candidate.source_name for pkg in self.updates_list.ignored_phased_updates])
134+ group = self.updates_list.update_groups[0]
135+ install_srcs = set([x.pkg.candidate.source_name for x in group.items])
136+ self.assertTrue(len(ignored_srcs & install_srcs) == 0)
137
138 def test_phased_percentage_included_via_force(self):
139 """ Test that the "always" override config works """
140@@ -59,7 +68,7 @@
141 with patch.object(self.updates_list.random, "randint") as mock_randint:
142 mock_randint.return_value = 100
143 self.updates_list.update(self.cache)
144- self.assertUpdatesListLen(2)
145+ self.assertUpdatesListLen(3)
146
147 def test_phased_percentage_excluded_via_force(self):
148 """ Test that the "never" override config works """
149@@ -82,7 +91,7 @@
150 with patch.object(self.updates_list.random, "randint") as mock_randint:
151 mock_randint.return_value = 100
152 self.updates_list.update(self.cache)
153- self.assertUpdatesListLen(2)
154+ self.assertUpdatesListLen(3)
155
156
157 class GroupingTestCase(unittest.TestCase):

Subscribers

People subscribed via source and target branches

to status/vote changes: