Merge lp:~wgrant/launchpad/replace-archiveuploader-doctests-0 into lp:launchpad
- replace-archiveuploader-doctests-0
- Merge into devel
Proposed by
William Grant
Status: | Merged |
---|---|
Approved by: | Robert Collins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 11269 |
Proposed branch: | lp:~wgrant/launchpad/replace-archiveuploader-doctests-0 |
Merge into: | lp:launchpad |
Diff against target: |
765 lines (+219/-350) 8 files modified
lib/lp/archiveuploader/nascentupload.py (+4/-22) lib/lp/archiveuploader/tests/nascentupload-announcements.txt (+3/-6) lib/lp/archiveuploader/tests/nascentupload-security-uploads.txt (+3/-0) lib/lp/archiveuploader/tests/nascentupload.txt (+22/-22) lib/lp/archiveuploader/tests/nascentuploadfile.txt (+4/-264) lib/lp/archiveuploader/tests/test_dscfile.py (+137/-2) lib/lp/archiveuploader/tests/test_utils.py (+46/-29) lib/lp/soyuz/tests/test_doc.py (+0/-5) |
To merge this branch: | bzr merge lp:~wgrant/launchpad/replace-archiveuploader-doctests-0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Collins (community) | Approve | ||
Review via email: mp+30850@code.launchpad.net |
Commit message
Replaced some archiveuploader doctests with unit tests, and moved some remaining archiveuploader doctests from Soyuz to archiveuploader.
Description of the change
Three things:
- Replaces some archiveuploader doctest sections with unit tests.
- Removes a couple of attributes from NascentUpload that were used by only one test -- that test now calculates them itself.
- Moves some missed archiveuploader doctests from lp.soyuz to lp.archiveuploader.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/archiveuploader/nascentupload.py' |
2 | --- lib/lp/archiveuploader/nascentupload.py 2010-07-15 09:42:28 +0000 |
3 | +++ lib/lp/archiveuploader/nascentupload.py 2010-07-24 09:41:13 +0000 |
4 | @@ -82,10 +82,6 @@ |
5 | archindep = False |
6 | archdep = False |
7 | |
8 | - # Defined in check_sourceful_consistency() |
9 | - native = False |
10 | - hasorig = False |
11 | - |
12 | # Defined if we successfully do_accept() and storeObjectsInDatabase() |
13 | queue_root = None |
14 | |
15 | @@ -308,31 +304,17 @@ |
16 | assert self.sourceful, ( |
17 | "Source consistency check called for a non-source upload") |
18 | |
19 | - dsc = 0 |
20 | - native_tarball = 0 |
21 | - orig_tarball = 0 |
22 | - |
23 | - for uploaded_file in self.changes.files: |
24 | - filetype = determine_source_file_type(uploaded_file.filename) |
25 | - if filetype == SourcePackageFileType.DSC: |
26 | - dsc += 1 |
27 | - elif (filetype == SourcePackageFileType.NATIVE_TARBALL |
28 | - and not isinstance(uploaded_file, CustomUploadFile)): |
29 | - native_tarball += 1 |
30 | - elif filetype == SourcePackageFileType.ORIG_TARBALL: |
31 | - orig_tarball += 1 |
32 | - |
33 | + dsc = len([ |
34 | + file for file in self.changes.files |
35 | + if determine_source_file_type(file.filename) == |
36 | + SourcePackageFileType.DSC]) |
37 | |
38 | # It is never sane to upload more than one source at a time. |
39 | if dsc > 1: |
40 | self.reject("Changes file lists more than one .dsc") |
41 | - |
42 | if dsc == 0: |
43 | self.reject("Sourceful upload without a .dsc") |
44 | |
45 | - self.native = bool(native_tarball) |
46 | - self.hasorig = bool(orig_tarball) |
47 | - |
48 | def _check_binaryful_consistency(self): |
49 | """Heuristic checks on a binaryful upload. |
50 | |
51 | |
52 | === renamed file 'lib/lp/soyuz/doc/nascentupload-announcements.txt' => 'lib/lp/archiveuploader/tests/nascentupload-announcements.txt' |
53 | --- lib/lp/soyuz/doc/nascentupload-announcements.txt 2010-05-27 09:08:10 +0000 |
54 | +++ lib/lp/archiveuploader/tests/nascentupload-announcements.txt 2010-07-24 09:41:13 +0000 |
55 | @@ -39,6 +39,8 @@ |
56 | |
57 | We need to be logged into the security model in order to get any further |
58 | |
59 | + >>> from canonical.testing.layers import LaunchpadZopelessLayer |
60 | + >>> LaunchpadZopelessLayer.switchDbUser('launchpad') |
61 | >>> login('foo.bar@canonical.com') |
62 | |
63 | Helper functions to examine emails that were sent: |
64 | @@ -58,17 +60,12 @@ |
65 | address and allow uploads to universe: |
66 | |
67 | >>> from canonical.launchpad.interfaces import ( |
68 | - ... SeriesStatus, IComponentSet, IDistributionSet, |
69 | - ... ILibraryFileAliasSet) |
70 | + ... SeriesStatus, IDistributionSet, ILibraryFileAliasSet) |
71 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] |
72 | >>> hoary = ubuntu['hoary'] |
73 | >>> hoary.status = SeriesStatus.DEVELOPMENT |
74 | >>> hoary.changeslist = "hoary-announce@lists.ubuntu.com" |
75 | - >>> from canonical.launchpad.database import ComponentSelection |
76 | - >>> universe = getUtility(IComponentSet)['universe'] |
77 | - >>> trash = ComponentSelection(distroseries=hoary, component=universe) |
78 | >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1] |
79 | - >>> trash = hoary['i386'].addOrUpdateChroot(fake_chroot) |
80 | >>> trash = hoary['hppa'].addOrUpdateChroot(fake_chroot) |
81 | |
82 | NEW source upload to RELEASE pocket via 'sync' policy (it presents |
83 | |
84 | === renamed file 'lib/lp/soyuz/doc/nascentupload-security-uploads.txt' => 'lib/lp/archiveuploader/tests/nascentupload-security-uploads.txt' |
85 | --- lib/lp/soyuz/doc/nascentupload-security-uploads.txt 2009-05-13 14:05:27 +0000 |
86 | +++ lib/lp/archiveuploader/tests/nascentupload-security-uploads.txt 2010-07-24 09:41:13 +0000 |
87 | @@ -31,6 +31,8 @@ |
88 | respective processorfamily and processor. Let's create them |
89 | on-the-fly: |
90 | |
91 | + >>> from canonical.testing.layers import LaunchpadZopelessLayer |
92 | + >>> LaunchpadZopelessLayer.switchDbUser('launchpad') |
93 | >>> from canonical.launchpad.interfaces import IDistributionSet |
94 | >>> from canonical.launchpad.database import ( |
95 | ... Processor, ProcessorFamily) |
96 | @@ -45,6 +47,7 @@ |
97 | |
98 | >>> import transaction |
99 | >>> transaction.commit() |
100 | + >>> LaunchpadZopelessLayer.switchDbUser('uploader') |
101 | |
102 | |
103 | == Mixed Security Upload == |
104 | |
105 | === renamed file 'lib/lp/soyuz/doc/nascentupload.txt' => 'lib/lp/archiveuploader/tests/nascentupload.txt' |
106 | --- lib/lp/soyuz/doc/nascentupload.txt 2010-05-21 12:12:58 +0000 |
107 | +++ lib/lp/archiveuploader/tests/nascentupload.txt 2010-07-24 09:41:13 +0000 |
108 | @@ -10,27 +10,13 @@ |
109 | >>> login('foo.bar@canonical.com') |
110 | |
111 | For the purpose of this test, hoary needs to be an open (development) |
112 | -distroseries so that we can upload to it. It also needs to allow uploads |
113 | -to the universe component. |
114 | - |
115 | -This test normally runs as the "uploader" db user but it does not have |
116 | -permission to add a new ComponentSelection, so we temporarily switch to |
117 | -"launchpad" to handle this. |
118 | +distroseries so that we can upload to it. |
119 | |
120 | >>> from canonical.launchpad.interfaces import ( |
121 | - ... SeriesStatus, IComponentSet, IDistributionSet) |
122 | - >>> from canonical.launchpad.database import ComponentSelection |
123 | + ... SeriesStatus, IDistributionSet) |
124 | >>> ubuntu = getUtility(IDistributionSet)['ubuntu'] |
125 | >>> hoary = ubuntu['hoary'] |
126 | >>> hoary.status = SeriesStatus.DEVELOPMENT |
127 | - >>> universe = getUtility(IComponentSet)['universe'] |
128 | - >>> from canonical.testing import LaunchpadZopelessLayer |
129 | - >>> from canonical.database.sqlbase import commit |
130 | - >>> commit() |
131 | - >>> LaunchpadZopelessLayer.switchDbUser('launchpad') |
132 | - >>> trash = ComponentSelection(distroseries=hoary, component=universe) |
133 | - >>> commit() |
134 | - >>> LaunchpadZopelessLayer.switchDbUser('uploader') |
135 | |
136 | A NascentUpload is a collection of files in a directory. They |
137 | represent what may turn out to be an acceptable upload to a launchpad |
138 | @@ -152,9 +138,21 @@ |
139 | |
140 | ed_source is uses ORIG + DIFF form: |
141 | |
142 | - >>> ed_source_upload.native |
143 | + >>> from lp.archiveuploader.utils import determine_source_file_type |
144 | + >>> from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
145 | + >>> def determine_file_types(upload): |
146 | + ... return [determine_source_file_type(uf.filename) |
147 | + ... for uf in upload.changes.files] |
148 | + >>> def has_orig(upload): |
149 | + ... return (SourcePackageFileType.ORIG_TARBALL |
150 | + ... in determine_file_types(upload)) |
151 | + >>> def has_native(upload): |
152 | + ... return (SourcePackageFileType.NATIVE_TARBALL |
153 | + ... in determine_file_types(upload)) |
154 | + |
155 | + >>> has_native(ed_source_upload) |
156 | False |
157 | - >>> ed_source_upload.hasorig |
158 | + >>> has_orig(ed_source_upload) |
159 | True |
160 | |
161 | For *sourceful* uploads 'archdep' and 'archindep' are always False: |
162 | @@ -197,9 +195,9 @@ |
163 | As expected 'native' and 'hasorig' doesn't make any sense for binary |
164 | uploads, so they are alway False: |
165 | |
166 | - >>> ed_binary_upload.native |
167 | + >>> has_native(ed_binary_upload) |
168 | False |
169 | - >>> ed_binary_upload.hasorig |
170 | + >>> has_orig(ed_binary_upload) |
171 | False |
172 | |
173 | Since the binary policy lets things through unsigned, we don't try and |
174 | @@ -287,9 +285,9 @@ |
175 | ancestries (it saves a lot of bandwidth). So, the upload is not |
176 | 'native', neither 'hasorig': |
177 | |
178 | - >>> ed_mixed_upload.native |
179 | + >>> has_native(ed_mixed_upload) |
180 | False |
181 | - >>> ed_mixed_upload.hasorig |
182 | + >>> has_orig(ed_mixed_upload) |
183 | False |
184 | |
185 | But if we check the DSC we will find the reference to the already |
186 | @@ -716,7 +714,9 @@ |
187 | to set hoary to CURRENT in order to do this because we're not allowed |
188 | to upload to -UPDATES in a DEVELOPMENT series. |
189 | |
190 | + >>> from canonical.testing import LaunchpadZopelessLayer |
191 | >>> LaunchpadZopelessLayer.switchDbUser('launchpad') |
192 | + >>> from canonical.database.sqlbase import commit |
193 | >>> hoary.status = SeriesStatus.CURRENT |
194 | >>> commit() |
195 | >>> LaunchpadZopelessLayer.switchDbUser('uploader') |
196 | |
197 | === modified file 'lib/lp/archiveuploader/tests/nascentuploadfile.txt' |
198 | --- lib/lp/archiveuploader/tests/nascentuploadfile.txt 2010-06-16 09:08:16 +0000 |
199 | +++ lib/lp/archiveuploader/tests/nascentuploadfile.txt 2010-07-24 09:41:13 +0000 |
200 | @@ -155,161 +155,10 @@ |
201 | |
202 | === CustomUploadFile identification === |
203 | |
204 | -Source and Binary files are easily recognized by a regexp on the |
205 | -filenames: |
206 | - |
207 | - >>> from lp.archiveuploader.utils import ( |
208 | - ... re_isadeb, re_issource) |
209 | - |
210 | -The binary regexp matches 'deb', 'ddeb' and 'udeb' filenames. |
211 | - |
212 | - >>> deb_match = re_isadeb.match('foo-bar_1.0_i386.deb') |
213 | - >>> deb_match.group(0) |
214 | - 'foo-bar_1.0_i386.deb' |
215 | - >>> deb_match.group(1) |
216 | - 'foo-bar' |
217 | - >>> deb_match.group(2) |
218 | - '1.0' |
219 | - >>> deb_match.group(3) |
220 | - 'i386' |
221 | - |
222 | - >>> ddeb_match = re_isadeb.match('foo-bar_1.0_i386.ddeb') |
223 | - >>> ddeb_match.group(0) |
224 | - 'foo-bar_1.0_i386.ddeb' |
225 | - >>> ddeb_match.group(1) |
226 | - 'foo-bar' |
227 | - >>> ddeb_match.group(2) |
228 | - '1.0' |
229 | - >>> ddeb_match.group(3) |
230 | - 'i386' |
231 | - |
232 | - >>> udeb_match = re_isadeb.match('foo-bar_1.0_i386.udeb') |
233 | - >>> udeb_match.group(0) |
234 | - 'foo-bar_1.0_i386.udeb' |
235 | - >>> udeb_match.group(1) |
236 | - 'foo-bar' |
237 | - >>> udeb_match.group(2) |
238 | - '1.0' |
239 | - >>> udeb_match.group(3) |
240 | - 'i386' |
241 | - |
242 | -The source regexp matches 'orig.tar.gz', 'tar.gz', 'diff.gz' and 'dsc' |
243 | -filenames. |
244 | - |
245 | - >>> src_match = re_issource.match('foo_1.0.orig.tar.gz') |
246 | - >>> src_match.group(0) |
247 | - 'foo_1.0.orig.tar.gz' |
248 | - >>> src_match.group(1) |
249 | - 'foo' |
250 | - >>> src_match.group(2) |
251 | - '1.0' |
252 | - >>> src_match.group(3) |
253 | - 'orig.tar.gz' |
254 | - |
255 | - >>> src_match = re_issource.match('foo_1.0.tar.gz') |
256 | - >>> src_match.group(0) |
257 | - 'foo_1.0.tar.gz' |
258 | - >>> src_match.group(1) |
259 | - 'foo' |
260 | - >>> src_match.group(2) |
261 | - '1.0' |
262 | - >>> src_match.group(3) |
263 | - 'tar.gz' |
264 | - |
265 | - >>> src_match = re_issource.match('foo_1.0.tar.bz2') |
266 | - >>> src_match.group(0) |
267 | - 'foo_1.0.tar.bz2' |
268 | - >>> src_match.group(1) |
269 | - 'foo' |
270 | - >>> src_match.group(2) |
271 | - '1.0' |
272 | - >>> src_match.group(3) |
273 | - 'tar.bz2' |
274 | - |
275 | - >>> src_match = re_issource.match('foo_1.0.diff.gz') |
276 | - >>> src_match.group(0) |
277 | - 'foo_1.0.diff.gz' |
278 | - >>> src_match.group(1) |
279 | - 'foo' |
280 | - >>> src_match.group(2) |
281 | - '1.0' |
282 | - >>> src_match.group(3) |
283 | - 'diff.gz' |
284 | - |
285 | - >>> src_match = re_issource.match('foo_1.0.dsc') |
286 | - >>> src_match.group(0) |
287 | - 'foo_1.0.dsc' |
288 | - >>> src_match.group(1) |
289 | - 'foo' |
290 | - >>> src_match.group(2) |
291 | - '1.0' |
292 | - >>> src_match.group(3) |
293 | - 'dsc' |
294 | - |
295 | - >>> src_match = re_issource.match('foo_1.0.debian.tar.gz') |
296 | - >>> src_match.group(0) |
297 | - 'foo_1.0.debian.tar.gz' |
298 | - >>> src_match.group(1) |
299 | - 'foo' |
300 | - >>> src_match.group(2) |
301 | - '1.0' |
302 | - >>> src_match.group(3) |
303 | - 'debian.tar.gz' |
304 | - |
305 | - >>> src_match = re_issource.match('foo_1.0.debian.tar.bz2') |
306 | - >>> src_match.group(0) |
307 | - 'foo_1.0.debian.tar.bz2' |
308 | - >>> src_match.group(1) |
309 | - 'foo' |
310 | - >>> src_match.group(2) |
311 | - '1.0' |
312 | - >>> src_match.group(3) |
313 | - 'debian.tar.bz2' |
314 | - |
315 | - >>> src_match = re_issource.match('foo_1.0.orig-foo.tar.gz') |
316 | - >>> src_match.group(0) |
317 | - 'foo_1.0.orig-foo.tar.gz' |
318 | - >>> src_match.group(1) |
319 | - 'foo' |
320 | - >>> src_match.group(2) |
321 | - '1.0' |
322 | - >>> src_match.group(3) |
323 | - 'orig-foo.tar.gz' |
324 | - |
325 | - >>> src_match = re_issource.match('foo_1.0.orig-bar.tar.bz2') |
326 | - >>> src_match.group(0) |
327 | - 'foo_1.0.orig-bar.tar.bz2' |
328 | - >>> src_match.group(1) |
329 | - 'foo' |
330 | - >>> src_match.group(2) |
331 | - '1.0' |
332 | - >>> src_match.group(3) |
333 | - 'orig-bar.tar.bz2' |
334 | - |
335 | - >>> src_match = re_issource.match('foo_1.0.porig-bar.tar.bz2') |
336 | - >>> src_match.group(0) |
337 | - 'foo_1.0.porig-bar.tar.bz2' |
338 | - >>> src_match.group(1) |
339 | - 'foo' |
340 | - >>> src_match.group(2) |
341 | - '1.0.porig-bar' |
342 | - >>> src_match.group(3) |
343 | - 'tar.bz2' |
344 | - |
345 | -And finally some failures: |
346 | - |
347 | - >>> re_isadeb.match('foo-bar_1.0_i386.bed') is None |
348 | - True |
349 | - |
350 | - >>> re_issource.match('foo_1.0.c') is None |
351 | - True |
352 | - |
353 | - >>> re_issource.match('foo_1.0.diff.bz2') is None |
354 | - True |
355 | - |
356 | -However a custom upload is essencially a tarball, so it also matches |
357 | -the is_source regexp: |
358 | - |
359 | +A custom upload is essentially a tarball, so it matches the is_source |
360 | +regexp, even though it isn't actually a source file: |
361 | + |
362 | + >>> from lp.archiveuploader.utils import re_issource |
363 | >>> src_match = re_issource.match('dist-upgrader_1.0.tar.gz') |
364 | >>> src_match.group(0) |
365 | 'dist-upgrader_1.0.tar.gz' |
366 | @@ -600,115 +449,6 @@ |
367 | ['File ed_0.2-20.dsc mentioned in the changes has a size mismatch. 578 != 500'] |
368 | |
369 | |
370 | -=== Format file type verification === |
371 | - |
372 | -DSCFile performs additional verification on the types of the referenced |
373 | -files, confirming that they are suitable for the source package's |
374 | -format. There is an error generator to verify each format. |
375 | - |
376 | - >>> from lp.archiveuploader.dscfile import (check_format_1_0_files, |
377 | - ... check_format_3_0_native_files, check_format_3_0_quilt_files) |
378 | - >>> from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
379 | - |
380 | -==== 1.0 ==== |
381 | - |
382 | -A 1.0 source can contain either a tar.gz or an orig.tar.gz and diff.gz. |
383 | - |
384 | - >>> list(check_format_1_0_files('foo_1.dsc', { |
385 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
386 | - ... SourcePackageFileType.DIFF: 1, |
387 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
388 | - ... SourcePackageFileType.NATIVE_TARBALL: 0, |
389 | - ... }, {}, 0)) |
390 | - [] |
391 | - |
392 | - >>> list(check_format_1_0_files('foo_1.dsc', { |
393 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
394 | - ... SourcePackageFileType.ORIG_TARBALL: 0, |
395 | - ... SourcePackageFileType.DIFF: 0, |
396 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
397 | - ... }, {}, 0)) |
398 | - [] |
399 | - |
400 | -But if we have some other combination, or bzip2 compression, errors |
401 | -will be generated. |
402 | - |
403 | - >>> list(check_format_1_0_files('foo_1.dsc', { |
404 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
405 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
406 | - ... SourcePackageFileType.DIFF: 1, |
407 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
408 | - ... }, {}, 1)) |
409 | - [UploadError('foo_1.dsc: is format 1.0 but uses bzip2 compression.',), UploadError('foo_1.dsc: must have exactly one tar.gz, or an orig.tar.gz and diff.gz',)] |
410 | - |
411 | -The files are also bad if there are any components: |
412 | - |
413 | - >>> list(check_format_1_0_files('foo_1.dsc', { |
414 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
415 | - ... SourcePackageFileType.DIFF: 1, |
416 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
417 | - ... SourcePackageFileType.NATIVE_TARBALL: 0, |
418 | - ... }, {'foo': 1}, 0)) |
419 | - [UploadError('foo_1.dsc: must have exactly one tar.gz, or an orig.tar.gz and diff.gz',)] |
420 | - |
421 | -==== 3.0 (native) ==== |
422 | - |
423 | -A 3.0 (native) source must contain just a tar.(gz|bz2). |
424 | - |
425 | - >>> list(check_format_3_0_native_files('foo_1.dsc', { |
426 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
427 | - ... SourcePackageFileType.ORIG_TARBALL: 0, |
428 | - ... SourcePackageFileType.DIFF: 0, |
429 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
430 | - ... }, {}, 1)) |
431 | - [] |
432 | - |
433 | - >>> list(check_format_3_0_native_files('foo_1.dsc', { |
434 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
435 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
436 | - ... SourcePackageFileType.DIFF: 0, |
437 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
438 | - ... }, {}, 1)) |
439 | - [UploadError('foo_1.dsc: must have only a tar.*.',)] |
440 | - |
441 | - >>> list(check_format_3_0_native_files('foo_1.dsc', { |
442 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
443 | - ... SourcePackageFileType.ORIG_TARBALL: 0, |
444 | - ... SourcePackageFileType.DIFF: 0, |
445 | - ... SourcePackageFileType.DEBIAN_TARBALL: 0, |
446 | - ... }, {'foo': 1}, 0)) |
447 | - [UploadError('foo_1.dsc: must have only a tar.*.',)] |
448 | - |
449 | -==== 3.0 (quilt) ==== |
450 | - |
451 | -A 3.0 (quilt) source must have an orig.tar.*, a debian.tar.*, and at |
452 | -most one orig-COMPONENT.tar.* for each COMPONENT. |
453 | - |
454 | - >>> list(check_format_3_0_quilt_files('foo_1.dsc', { |
455 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
456 | - ... SourcePackageFileType.DEBIAN_TARBALL: 1, |
457 | - ... SourcePackageFileType.NATIVE_TARBALL: 0, |
458 | - ... SourcePackageFileType.DIFF: 0, |
459 | - ... }, {'foo': 1}, 1)) |
460 | - [] |
461 | - |
462 | - >>> list(check_format_3_0_quilt_files('foo_1.dsc', { |
463 | - ... SourcePackageFileType.NATIVE_TARBALL: 1, |
464 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
465 | - ... SourcePackageFileType.DIFF: 0, |
466 | - ... SourcePackageFileType.DEBIAN_TARBALL: 1, |
467 | - ... }, {}, 1)) |
468 | - [UploadError('foo_1.dsc: must have only an orig.tar.*, a debian.tar.*, and optionally orig-*.tar.*',)] |
469 | - |
470 | - >>> list(check_format_3_0_quilt_files('foo_1.dsc', { |
471 | - ... SourcePackageFileType.ORIG_TARBALL: 1, |
472 | - ... SourcePackageFileType.DEBIAN_TARBALL: 1, |
473 | - ... SourcePackageFileType.NATIVE_TARBALL: 0, |
474 | - ... SourcePackageFileType.DIFF: 0, |
475 | - ... }, {'foo': 2}, 0)) |
476 | - [UploadError('foo_1.dsc: has more than one orig-foo.tar.*.',)] |
477 | - |
478 | - |
479 | === Sub-DSC files or DSCUploadedFiles === |
480 | |
481 | Sub-DSCFiles are DSCUploadedFile objects. |
482 | |
483 | === renamed file 'lib/lp/soyuz/doc/safe_fix_maintainer.txt' => 'lib/lp/archiveuploader/tests/safe_fix_maintainer.txt' |
484 | === modified file 'lib/lp/archiveuploader/tests/test_dscfile.py' |
485 | --- lib/lp/archiveuploader/tests/test_dscfile.py 2010-07-20 15:25:30 +0000 |
486 | +++ lib/lp/archiveuploader/tests/test_dscfile.py 2010-07-24 09:41:13 +0000 |
487 | @@ -7,16 +7,22 @@ |
488 | |
489 | import os |
490 | |
491 | -from canonical.config import config |
492 | from canonical.launchpad.scripts.logger import QuietFakeLogger |
493 | from canonical.testing.layers import LaunchpadZopelessLayer |
494 | from lp.archiveuploader.dscfile import ( |
495 | - DSCFile, findChangelog, findCopyright) |
496 | + DSCFile, findChangelog, findCopyright, format_to_file_checker_map) |
497 | from lp.archiveuploader.nascentuploadfile import UploadError |
498 | from lp.archiveuploader.tests import datadir, mock_logger_quiet |
499 | from lp.archiveuploader.uploadpolicy import BuildDaemonUploadPolicy |
500 | +from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
501 | +from lp.soyuz.interfaces.sourcepackageformat import SourcePackageFormat |
502 | from lp.testing import TestCase, TestCaseWithFactory |
503 | |
504 | +ORIG_TARBALL = SourcePackageFileType.ORIG_TARBALL |
505 | +DEBIAN_TARBALL = SourcePackageFileType.DEBIAN_TARBALL |
506 | +NATIVE_TARBALL = SourcePackageFileType.NATIVE_TARBALL |
507 | +DIFF = SourcePackageFileType.DIFF |
508 | + |
509 | |
510 | class TestDscFile(TestCase): |
511 | |
512 | @@ -146,3 +152,132 @@ |
513 | dsc_file.cleanUp() |
514 | finally: |
515 | os.chmod(tempdir, 0755) |
516 | + |
517 | + |
518 | +class BaseTestSourceFileVerification(TestCase): |
519 | + |
520 | + def assertErrorsForFiles(self, expected, files, components={}, |
521 | + bzip2_count=0): |
522 | + """Check problems with the given set of files for the given format. |
523 | + |
524 | + :param expected: a list of expected errors, as strings. |
525 | + :param format: the `SourcePackageFormat` to check against. |
526 | + :param files: a dict mapping `SourcePackageFileType`s to counts. |
527 | + :param components: a dict mapping orig component tarball components |
528 | + to counts. |
529 | + :param bzip2_count: number of files using bzip2 compression. |
530 | + """ |
531 | + full_files = { |
532 | + NATIVE_TARBALL: 0, |
533 | + ORIG_TARBALL: 0, |
534 | + DIFF: 0, |
535 | + DEBIAN_TARBALL: 0, |
536 | + } |
537 | + full_files.update(files) |
538 | + self.assertEquals( |
539 | + expected, |
540 | + [str(e) for e in format_to_file_checker_map[self.format]( |
541 | + 'foo_1.dsc', full_files, components, bzip2_count)]) |
542 | + |
543 | + def assertFilesOK(self, files, components={}, bzip2_count=0): |
544 | + """Check that the given set of files is OK for the given format. |
545 | + |
546 | + :param format: the `SourcePackageFormat` to check against. |
547 | + :param files: a dict mapping `SourcePackageFileType`s to counts. |
548 | + :param components: a dict mapping orig component tarball components |
549 | + to counts. |
550 | + :param bzip2_count: number of files using bzip2 compression. |
551 | + """ |
552 | + self.assertErrorsForFiles([], files, components, bzip2_count) |
553 | + |
554 | + |
555 | +class Test10SourceFormatVerification(BaseTestSourceFileVerification): |
556 | + |
557 | + format = SourcePackageFormat.FORMAT_1_0 |
558 | + |
559 | + wrong_files_error = ('foo_1.dsc: must have exactly one tar.gz, or an ' |
560 | + 'orig.tar.gz and diff.gz') |
561 | + bzip2_error = 'foo_1.dsc: is format 1.0 but uses bzip2 compression.' |
562 | + |
563 | + def testFormat10Debian(self): |
564 | + # A 1.0 source can contain an original tarball and a Debian diff |
565 | + self.assertFilesOK({ORIG_TARBALL: 1, DIFF: 1}) |
566 | + |
567 | + def testFormat10Native(self): |
568 | + # A 1.0 source can contain a native tarball. |
569 | + self.assertFilesOK({NATIVE_TARBALL: 1}) |
570 | + |
571 | + def testFormat10CannotHaveWrongFiles(self): |
572 | + # A 1.0 source cannot have a combination of native and |
573 | + # non-native files, and cannot have just one of the non-native |
574 | + # files. |
575 | + for combination in ( |
576 | + {DIFF: 1}, {ORIG_TARBALL: 1}, {ORIG_TARBALL: 1, DIFF: 1, |
577 | + NATIVE_TARBALL: 1}): |
578 | + self.assertErrorsForFiles([self.wrong_files_error], combination) |
579 | + |
580 | + # A 1.0 source with component tarballs is invalid. |
581 | + self.assertErrorsForFiles( |
582 | + [self.wrong_files_error], {ORIG_TARBALL: 1, DIFF: 1}, {'foo': 1}) |
583 | + |
584 | + def testFormat10CannotUseBzip2(self): |
585 | + # 1.0 sources cannot use bzip2 compression. |
586 | + self.assertErrorsForFiles( |
587 | + [self.bzip2_error], {NATIVE_TARBALL: 1}, {}, 1) |
588 | + |
589 | + |
590 | +class Test30QuiltSourceFormatVerification(BaseTestSourceFileVerification): |
591 | + |
592 | + format = SourcePackageFormat.FORMAT_3_0_QUILT |
593 | + |
594 | + wrong_files_error = ('foo_1.dsc: must have only an orig.tar.*, a ' |
595 | + 'debian.tar.* and optionally orig-*.tar.*') |
596 | + comp_conflict_error = 'foo_1.dsc: has more than one orig-bar.tar.*.' |
597 | + |
598 | + def testFormat30Quilt(self): |
599 | + # A 3.0 (quilt) source must contain an orig tarball and a debian |
600 | + # tarball. It may also contain at most one component tarball for |
601 | + # each component, and can use gzip or bzip2 compression. |
602 | + for components in ({}, {'foo': 1}, {'foo': 1, 'bar': 1}): |
603 | + for bzip2_count in (0, 1): |
604 | + self.assertFilesOK( |
605 | + {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1}, components, |
606 | + bzip2_count) |
607 | + |
608 | + def testFormat30QuiltCannotHaveConflictingComponentTarballs(self): |
609 | + # Multiple conflicting tarballs for a single component are |
610 | + # invalid. |
611 | + self.assertErrorsForFiles( |
612 | + [self.comp_conflict_error], |
613 | + {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1}, {'foo': 1, 'bar': 2}) |
614 | + |
615 | + def testFormat30QuiltCannotHaveWrongFiles(self): |
616 | + # 3.0 (quilt) sources may not have a diff or native tarball. |
617 | + for filetype in (DIFF, NATIVE_TARBALL): |
618 | + self.assertErrorsForFiles( |
619 | + [self.wrong_files_error], |
620 | + {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1, filetype: 1}) |
621 | + |
622 | + |
623 | +class Test30QuiltSourceFormatVerification(BaseTestSourceFileVerification): |
624 | + |
625 | + format = SourcePackageFormat.FORMAT_3_0_NATIVE |
626 | + |
627 | + wrong_files_error = 'foo_1.dsc: must have only a tar.*.' |
628 | + |
629 | + def testFormat30Native(self): |
630 | + # 3.0 (native) sources must contain just a native tarball. They |
631 | + # may use gzip or bzip2 compression. |
632 | + for bzip2_count in (0, 1): |
633 | + self.assertFilesOK({NATIVE_TARBALL: 1}, {}, |
634 | + bzip2_count) |
635 | + |
636 | + def testFormat30NativeCannotHaveWrongFiles(self): |
637 | + # 3.0 (quilt) sources may not have a diff, Debian tarball, orig |
638 | + # tarball, or any component tarballs. |
639 | + for filetype in (DIFF, DEBIAN_TARBALL, ORIG_TARBALL): |
640 | + self.assertErrorsForFiles( |
641 | + [self.wrong_files_error], {NATIVE_TARBALL: 1, filetype: 1}) |
642 | + # A 3.0 (native) source with component tarballs is invalid. |
643 | + self.assertErrorsForFiles( |
644 | + [self.wrong_files_error], {NATIVE_TARBALL: 1}, {'foo': 1}) |
645 | |
646 | === modified file 'lib/lp/archiveuploader/tests/test_utils.py' |
647 | --- lib/lp/archiveuploader/tests/test_utils.py 2010-07-18 00:26:33 +0000 |
648 | +++ lib/lp/archiveuploader/tests/test_utils.py 2010-07-24 09:41:13 +0000 |
649 | @@ -5,23 +5,19 @@ |
650 | |
651 | # arch-tag: 90e6eb79-83a2-47e8-9f8b-3c687079c923 |
652 | |
653 | -import unittest |
654 | -import sys |
655 | +from testtools import TestCase |
656 | |
657 | from lp.registry.interfaces.sourcepackage import SourcePackageFileType |
658 | from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFileType |
659 | from lp.archiveuploader.tests import datadir |
660 | - |
661 | - |
662 | -class TestUtilities(unittest.TestCase): |
663 | - |
664 | - def testImport(self): |
665 | - """lp.archiveuploader.utils should be importable""" |
666 | - import lp.archiveuploader.utils |
667 | +from lp.archiveuploader.utils import (determine_binary_file_type, |
668 | + determine_source_file_type, re_isadeb, re_issource) |
669 | + |
670 | + |
671 | +class TestUtilities(TestCase): |
672 | |
673 | def test_determine_source_file_type(self): |
674 | """lp.archiveuploader.utils.determine_source_file_type should work.""" |
675 | - from lp.archiveuploader.utils import determine_source_file_type |
676 | |
677 | # .dsc -> DSC |
678 | self.assertEquals( |
679 | @@ -74,8 +70,6 @@ |
680 | |
681 | def test_determine_binary_file_type(self): |
682 | """lp.archiveuploader.utils.determine_binary_file_type should work.""" |
683 | - from lp.archiveuploader.utils import determine_binary_file_type |
684 | - |
685 | # .deb -> DEB |
686 | self.assertEquals( |
687 | determine_binary_file_type('foo_1.0-1_all.deb'), |
688 | @@ -222,20 +216,43 @@ |
689 | pass |
690 | |
691 | |
692 | -def test_suite(): |
693 | - suite = unittest.TestSuite() |
694 | - loader = unittest.TestLoader() |
695 | - suite.addTest(loader.loadTestsFromTestCase(TestUtilities)) |
696 | - return suite |
697 | - |
698 | - |
699 | -def main(argv): |
700 | - suite = test_suite() |
701 | - runner = unittest.TextTestRunner(verbosity = 2) |
702 | - if not runner.run(suite).wasSuccessful(): |
703 | - return 1 |
704 | - return 0 |
705 | - |
706 | - |
707 | -if __name__ == '__main__': |
708 | - sys.exit(main(sys.argv)) |
709 | +class TestFilenameRegularExpressions(TestCase): |
710 | + |
711 | + def test_re_isadeb(self): |
712 | + # Verify that the three binary extensions match the regexp. |
713 | + for extension in ('deb', 'ddeb', 'udeb'): |
714 | + self.assertEquals( |
715 | + ('foo-bar', '1.0', 'i386', extension), |
716 | + re_isadeb.match('foo-bar_1.0_i386.%s' % extension).groups()) |
717 | + |
718 | + # Some other extension doesn't match. |
719 | + self.assertIs(None, re_isadeb.match('foo-bar_1.0_i386.notdeb')) |
720 | + |
721 | + # A missing architecture also doesn't match. |
722 | + self.assertIs(None, re_isadeb.match('foo-bar_1.0.deb')) |
723 | + |
724 | + def test_re_issource(self): |
725 | + # Verify that various source extensions match the regexp. |
726 | + extensions = ( |
727 | + 'dsc', 'tar.gz', 'tar.bz2', 'diff.gz', 'orig.tar.gz', |
728 | + 'orig.tar.bz2', 'orig-bar.tar.gz', 'orig-bar.tar.bz2', |
729 | + 'debian.tar.gz', 'debian.tar.bz2') |
730 | + for extension in extensions: |
731 | + self.assertEquals( |
732 | + ('foo-bar', '1.0', extension), |
733 | + re_issource.match('foo-bar_1.0.%s' % extension).groups()) |
734 | + |
735 | + # While orig-*.tar.gz is all interpreted as extension, *orig-*.tar.gz |
736 | + # is taken to have an extension of just 'tar.gz'. |
737 | + self.assertEquals( |
738 | + ('foo-bar', '1.0.porig-bar', 'tar.gz'), |
739 | + re_issource.match('foo-bar_1.0.porig-bar.tar.gz').groups()) |
740 | + |
741 | + # Some other extension doesn't match. |
742 | + self.assertIs(None, re_issource.match('foo-bar_1.0.notdsc')) |
743 | + |
744 | + # A badly formatted name also doesn't match. |
745 | + self.assertIs(None, re_issource.match('foo-bar.dsc')) |
746 | + |
747 | + # bzip2 compression for files which must be gzipped is invalid. |
748 | + self.assertIs(None, re_issource.match('foo-bar_1.0.diff.bz2')) |
749 | |
750 | === renamed file 'lib/lp/soyuz/doc/uploadpolicy.txt' => 'lib/lp/archiveuploader/tests/uploadpolicy.txt' |
751 | === modified file 'lib/lp/soyuz/tests/test_doc.py' |
752 | --- lib/lp/soyuz/tests/test_doc.py 2010-04-30 09:49:59 +0000 |
753 | +++ lib/lp/soyuz/tests/test_doc.py 2010-07-24 09:41:13 +0000 |
754 | @@ -123,11 +123,6 @@ |
755 | |
756 | |
757 | special = { |
758 | - 'nascentupload.txt': LayeredDocFileSuite( |
759 | - '../doc/nascentupload.txt', |
760 | - setUp=uploaderSetUp, tearDown=uploaderTearDown, |
761 | - layer=LaunchpadZopelessLayer, |
762 | - ), |
763 | 'build-notification.txt': LayeredDocFileSuite( |
764 | '../doc/build-notification.txt', |
765 | setUp=builddmasterSetUp, |
Thanks. You might like to start using testscenarios for the permutations rather than looping - its easier to debug failures that way.