Merge lp:~robru/cupstream2distro/faster-content-mismatch-detection into lp:cupstream2distro

Proposed by Robert Bruce Park
Status: Merged
Approved by: Robert Bruce Park
Approved revision: 1243
Merged at revision: 1239
Proposed branch: lp:~robru/cupstream2distro/faster-content-mismatch-detection
Merge into: lp:cupstream2distro
Diff against target: 279 lines (+62/-60)
5 files modified
citrain/recipes/base.py (+15/-23)
citrain/recipes/merge.py (+1/-1)
cupstream2distro/archive.py (+27/-21)
tests/unit/test_archive.py (+1/-11)
tests/unit/test_recipe_base.py (+18/-4)
To merge this branch: bzr merge lp:~robru/cupstream2distro/faster-content-mismatch-detection
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Robert Bruce Park (community) Approve
Review via email: mp+278237@code.launchpad.net

Commit message

Be faster about detecting versions with content mismatches.

To post a comment you must log in.
Revision history for this message
Robert Bruce Park (robru) wrote :

Looks excellent in staging.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1242
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/918/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/918/rebuild

review: Approve (continuous-integration)
1243. By Robert Bruce Park

Log when a status is found.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'citrain/recipes/base.py'
2--- citrain/recipes/base.py 2015-11-21 04:41:12 +0000
3+++ citrain/recipes/base.py 2015-11-21 06:36:05 +0000
4@@ -187,15 +187,10 @@
5 self.target = None
6 self.dest = dest
7
8- def get_version(self):
9- """Identify what version this package is."""
10- for get_ver in (self.get_package_version, self.get_archive_version):
11- version = get_ver()
12- if version:
13- return version
14-
15 def check_status(self):
16 """Identify this package's progress through the train."""
17+ version = self.get_package_version()
18+ source = self.get_source_from_archive(version=version)
19 checks = (
20 self.check_silo_version,
21 self.check_new_commits,
22@@ -206,35 +201,34 @@
23 self.check_diff_exists,
24 self.check_destination_version,
25 )
26- version = self.get_version()
27 for check in checks:
28 logging.info('%s: %s', self.name, check.__doc__.split('\n')[0])
29- message = check(version)
30+ message = check(source=source)
31 if message:
32+ logging.info('%s: %s', self.name, message)
33 return message
34 return 'Successfully built'
35
36- def check_silo_version(self, version):
37+ def check_silo_version(self, source=None):
38 """Check that local version matches silo version."""
39 version = self.get_package_version()
40- silo_version = self.get_archive_version()
41- if not silo_version:
42+ if version and not source:
43+ return '{} not in PPA'.format(version)
44+ if not source:
45 return 'Ready to build'
46- if version and version != silo_version:
47- return '{} not in PPA'.format(version)
48
49- def check_new_commits(self, version):
50+ def check_new_commits(self, source=None):
51 """Not built from merges, skipping new commit check."""
52 pass
53
54- def check_destination_version(self, version=None):
55+ def check_destination_version(self, source=None):
56 """Check that destination version is listed in our changelog."""
57 dest_version = self.get_archive_version(self.dest)
58 log_value_of.dest_version('Dest archive')
59 if dest_version and self.package_changelog_has(dest_version) is False:
60 return DEST_MISSING.format(dest_version)
61
62- def check_autopkgtest_status(self, version=None):
63+ def check_autopkgtest_status(self, source=None):
64 """Check current status of autopkgtests, if any."""
65 found = set()
66 for arch in AUTOPKGTEST_ARCHES:
67@@ -267,11 +261,9 @@
68 else:
69 return self.inspect_tar_files()
70
71- def _check_build_status(self, version=None):
72+ def _check_build_status(self, source=None):
73 """Report the build pass/fail status in the PPA."""
74 watcher = ArchWatcher(self.arches)
75- source = self.get_source_from_archive(
76- version=version or self.get_version())
77 states = defaultdict(list)
78 if source:
79 for build in source.getBuilds():
80@@ -282,13 +274,13 @@
81 states[state].append(build.arch_tag)
82 return states
83
84- def check_build_status(self, version):
85+ def check_build_status(self, source=None):
86 """Report any build failures from the PPA."""
87- states = self._check_build_status(version)
88+ states = self._check_build_status(source)
89 if states.keys() - {'Successfully built'}:
90 return pretty_print_states(states, fmt=ARCH_FMT)
91
92- def check_diff_exists(self, version=None):
93+ def check_diff_exists(self, source=None):
94 """Complain if the full diff is missing."""
95 if not exists(self.full_diff):
96 return 'Diff missing'
97
98=== modified file 'citrain/recipes/merge.py'
99--- citrain/recipes/merge.py 2015-11-18 23:05:03 +0000
100+++ citrain/recipes/merge.py 2015-11-21 06:36:05 +0000
101@@ -276,7 +276,7 @@
102 if env.ALLOW_UNAPPROVED != 'true':
103 self.enforce_merge_states(PUBLISHABLE_STATES)
104
105- def check_new_commits(self, version=None):
106+ def check_new_commits(self, source=None):
107 """Report if this package needs a rebuild, or not."""
108 if check_for_unbuilt_revids(self.name, self.merges):
109 return 'Needs rebuild due to new commits'
110
111=== modified file 'cupstream2distro/archive.py'
112--- cupstream2distro/archive.py 2015-11-20 23:42:57 +0000
113+++ cupstream2distro/archive.py 2015-11-21 06:36:05 +0000
114@@ -23,7 +23,7 @@
115 from os.path import join
116 from operator import attrgetter
117 from six.moves.urllib.parse import unquote
118-from six.moves.urllib.request import urlretrieve
119+from six.moves.urllib.request import urlretrieve, urlopen
120
121 from cupstream2distro.version import V
122 from cupstream2distro.errors import ArchiveError
123@@ -93,10 +93,9 @@
124 if binary.architecture_specific}
125 return set()
126
127- def archive_hashes(self, sourcepub):
128- """Return the binary file sha1 hashes for comparison."""
129- return {binary.binaryFileUrls(include_meta=True)[0]['sha1']
130- for binary in sourcepub.getPublishedBinaries()}
131+ def archive_id(self, sourcepub):
132+ """Return some data that uniquely identifies a package's contents."""
133+ return urlopen(sourcepub.changelogUrl()).read(4096)
134
135 def get_archive_version(self, archive=None, series=None):
136 """Get current version for a package name in that series.
137@@ -121,7 +120,9 @@
138 kwargs = dict(distro_series=self.series, source_name=self.name)
139 if version:
140 kwargs['version'] = version
141- return newest(archive or self.silo_ppa, **kwargs)
142+ source = newest(archive or self.silo_ppa, **kwargs)
143+ if getattr(source, 'status', None) in ('Pending', 'Published'):
144+ return source
145
146 def copy_to_archive(self, source, archive=None):
147 """Copy this source package to a given archive.
148@@ -203,31 +204,36 @@
149 log_value_of.shortname()
150 return shortname
151
152- def archive_pocket(self, version):
153+ def archive_pocket(self, source=None):
154 """Ask the archive what pocket this version is in.
155
156- :param version: The version you want to check for.
157+ :param source: The source package publishing history you want to check.
158 :returns: The name of the pocket it's in, or None.
159 """
160- kwargs = dict(
161- distro_series=self.series, source_name=self.name, version=version)
162- dest = newest(self.dest, **kwargs)
163- if dest:
164- ours = newest(self.silo_ppa, **kwargs)
165- if self.archive_hashes(ours) == self.archive_hashes(dest):
166- return dest.pocket + ' pocket'
167- logging.info('%s at dest has different contents.', version)
168+ if source:
169+ dest = newest(
170+ self.dest,
171+ distro_series=self.series,
172+ source_name=self.name,
173+ version=source.source_package_version)
174+ if dest:
175+ if self.archive_id(source) == self.archive_id(dest):
176+ return dest.pocket + ' pocket'
177+ return 'Needs rebuild due to burned version number'
178
179- def archive_queue(self, version):
180+ def archive_queue(self, source=None):
181 """Check what queue this version of the package is in.
182
183 :param version: The version you want to check for.
184 :returns: The name of the queue it's in, or None.
185 """
186- uploads = self.series.getPackageUploads(
187- exact_match=True, name=self.name, version=version)
188- if uploads.total_size > 0:
189- return uploads[0].status.upper() + ' queue'
190+ if source:
191+ uploads = self.series.getPackageUploads(
192+ version=source.source_package_version,
193+ exact_match=True,
194+ name=self.name)
195+ if uploads.total_size > 0:
196+ return uploads[0].status.upper() + ' queue'
197
198
199 class ArchWatcher(object):
200
201=== modified file 'tests/unit/test_archive.py'
202--- tests/unit/test_archive.py 2015-11-20 23:42:57 +0000
203+++ tests/unit/test_archive.py 2015-11-21 06:36:05 +0000
204@@ -182,6 +182,7 @@
205 def test_get_source_from_archive(self):
206 """Return LPlib source package object."""
207 source = Mock()
208+ source.status = 'Pending'
209 self.archive.silo_ppa.getPublishedSources.return_value = [source]
210 self.assertEqual(self.archive.get_source_from_archive(), source)
211 self.archive.silo_ppa.getPublishedSources.assert_called_once_with(
212@@ -347,17 +348,6 @@
213 with self.assertRaisesRegexp(ArchiveError, 'Download failed'):
214 self.archive.unpack_archive_dsc(path, '1.0-0ubuntu1')
215
216- @patch('cupstream2distro.archive.newest')
217- def test_archive_pocket_mismatch(self, new):
218- """Correctly identify when dest has same version with diff contents."""
219- results = [{'hash'}, {'mismatch'}]
220- new.return_value.source_package_version = '42-0ubuntu1'
221- new.return_value.pocket = 'Proposed'
222- new.return_value.status = 'Pending'
223- self.archive.archive_hashes = Mock(
224- side_effect=lambda src: results.pop())
225- self.assertIsNone(self.archive.archive_pocket('42-0ubuntu1'))
226-
227 def test_watch_arch(self):
228 """Ignore the correct arches."""
229 watcher = ArchWatcher(['foo', 'i386', 'amd64'])
230
231=== modified file 'tests/unit/test_recipe_base.py'
232--- tests/unit/test_recipe_base.py 2015-11-21 00:12:26 +0000
233+++ tests/unit/test_recipe_base.py 2015-11-21 06:36:05 +0000
234@@ -95,20 +95,20 @@
235 """Correctly identify when package missing from PPA."""
236 new.return_value = None
237 build = BuildBase('state', self.series, self.dest, self.ppa)
238- build.get_package_version = Mock(return_value='42-0ubuntu1')
239+ build.get_package_version = Mock(return_value=None)
240 self.assertEqual(build.check_status(), 'Ready to build')
241
242 @patch('cupstream2distro.archive.newest')
243 def test_check_status_mismatch(self, new):
244 """Correctly identify when PPA has wrong version."""
245- new.return_value.source_package_version = '41-0ubuntu1'
246- new.return_value.status = 'Published'
247+ new.return_value = None
248 build = BuildBase('state', self.series, self.dest, self.ppa)
249 build.get_package_version = Mock(return_value='42-0ubuntu1')
250 self.assertEqual(build.check_status(), '42-0ubuntu1 not in PPA')
251
252 @patch('cupstream2distro.archive.newest')
253- def test_check_status_pocket(self, new):
254+ @patch('cupstream2distro.archive.urlopen')
255+ def test_check_status_pocket(self, urlopen, new):
256 """Correctly identify when PPA has wrong version."""
257 new.return_value.source_package_version = '42-0ubuntu1'
258 new.return_value.pocket = 'Proposed'
259@@ -118,6 +118,20 @@
260 self.assertEqual(build.check_status(), 'Proposed pocket')
261
262 @patch('cupstream2distro.archive.newest')
263+ def test_archive_pocket_mismatch(self, new):
264+ """Correctly identify when dest has same version with diff contents."""
265+ results = [{'hash'}, {'mismatch'}]
266+ new.return_value.source_package_version = '42-0ubuntu1'
267+ new.return_value.pocket = 'Proposed'
268+ new.return_value.status = 'Pending'
269+ build = BuildBase('state', self.series, self.dest, self.ppa)
270+ build.get_package_version = Mock(return_value='42-0ubuntu1')
271+ build.archive_id = Mock(
272+ side_effect=lambda src: results.pop())
273+ self.assertEqual(
274+ build.check_status(), 'Needs rebuild due to burned version number')
275+
276+ @patch('cupstream2distro.archive.newest')
277 def test_check_status_queue(self, new):
278 """Correctly identify when PPA has wrong version."""
279 sources = {

Subscribers

People subscribed via source and target branches