Merge lp:~wgrant/launchpad/replace-archiveuploader-doctests-0 into lp:launchpad

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
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.
Revision history for this message
Robert Collins (lifeless) wrote :

Thanks. You might like to start using testscenarios for the permutations rather than looping - its easier to debug failures that way.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/archiveuploader/nascentupload.py'
--- lib/lp/archiveuploader/nascentupload.py 2010-07-15 09:42:28 +0000
+++ lib/lp/archiveuploader/nascentupload.py 2010-07-24 09:41:13 +0000
@@ -82,10 +82,6 @@
82 archindep = False82 archindep = False
83 archdep = False83 archdep = False
8484
85 # Defined in check_sourceful_consistency()
86 native = False
87 hasorig = False
88
89 # Defined if we successfully do_accept() and storeObjectsInDatabase()85 # Defined if we successfully do_accept() and storeObjectsInDatabase()
90 queue_root = None86 queue_root = None
9187
@@ -308,31 +304,17 @@
308 assert self.sourceful, (304 assert self.sourceful, (
309 "Source consistency check called for a non-source upload")305 "Source consistency check called for a non-source upload")
310306
311 dsc = 0307 dsc = len([
312 native_tarball = 0308 file for file in self.changes.files
313 orig_tarball = 0309 if determine_source_file_type(file.filename) ==
314310 SourcePackageFileType.DSC])
315 for uploaded_file in self.changes.files:
316 filetype = determine_source_file_type(uploaded_file.filename)
317 if filetype == SourcePackageFileType.DSC:
318 dsc += 1
319 elif (filetype == SourcePackageFileType.NATIVE_TARBALL
320 and not isinstance(uploaded_file, CustomUploadFile)):
321 native_tarball += 1
322 elif filetype == SourcePackageFileType.ORIG_TARBALL:
323 orig_tarball += 1
324
325311
326 # It is never sane to upload more than one source at a time.312 # It is never sane to upload more than one source at a time.
327 if dsc > 1:313 if dsc > 1:
328 self.reject("Changes file lists more than one .dsc")314 self.reject("Changes file lists more than one .dsc")
329
330 if dsc == 0:315 if dsc == 0:
331 self.reject("Sourceful upload without a .dsc")316 self.reject("Sourceful upload without a .dsc")
332317
333 self.native = bool(native_tarball)
334 self.hasorig = bool(orig_tarball)
335
336 def _check_binaryful_consistency(self):318 def _check_binaryful_consistency(self):
337 """Heuristic checks on a binaryful upload.319 """Heuristic checks on a binaryful upload.
338320
339321
=== renamed file 'lib/lp/soyuz/doc/nascentupload-announcements.txt' => 'lib/lp/archiveuploader/tests/nascentupload-announcements.txt'
--- lib/lp/soyuz/doc/nascentupload-announcements.txt 2010-05-27 09:08:10 +0000
+++ lib/lp/archiveuploader/tests/nascentupload-announcements.txt 2010-07-24 09:41:13 +0000
@@ -39,6 +39,8 @@
3939
40We need to be logged into the security model in order to get any further40We need to be logged into the security model in order to get any further
4141
42 >>> from canonical.testing.layers import LaunchpadZopelessLayer
43 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
42 >>> login('foo.bar@canonical.com')44 >>> login('foo.bar@canonical.com')
4345
44Helper functions to examine emails that were sent:46Helper functions to examine emails that were sent:
@@ -58,17 +60,12 @@
58address and allow uploads to universe:60address and allow uploads to universe:
5961
60 >>> from canonical.launchpad.interfaces import (62 >>> from canonical.launchpad.interfaces import (
61 ... SeriesStatus, IComponentSet, IDistributionSet,63 ... SeriesStatus, IDistributionSet, ILibraryFileAliasSet)
62 ... ILibraryFileAliasSet)
63 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']64 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
64 >>> hoary = ubuntu['hoary']65 >>> hoary = ubuntu['hoary']
65 >>> hoary.status = SeriesStatus.DEVELOPMENT66 >>> hoary.status = SeriesStatus.DEVELOPMENT
66 >>> hoary.changeslist = "hoary-announce@lists.ubuntu.com"67 >>> hoary.changeslist = "hoary-announce@lists.ubuntu.com"
67 >>> from canonical.launchpad.database import ComponentSelection
68 >>> universe = getUtility(IComponentSet)['universe']
69 >>> trash = ComponentSelection(distroseries=hoary, component=universe)
70 >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1]68 >>> fake_chroot = getUtility(ILibraryFileAliasSet)[1]
71 >>> trash = hoary['i386'].addOrUpdateChroot(fake_chroot)
72 >>> trash = hoary['hppa'].addOrUpdateChroot(fake_chroot)69 >>> trash = hoary['hppa'].addOrUpdateChroot(fake_chroot)
7370
74NEW source upload to RELEASE pocket via 'sync' policy (it presents71NEW source upload to RELEASE pocket via 'sync' policy (it presents
7572
=== renamed file 'lib/lp/soyuz/doc/nascentupload-security-uploads.txt' => 'lib/lp/archiveuploader/tests/nascentupload-security-uploads.txt'
--- lib/lp/soyuz/doc/nascentupload-security-uploads.txt 2009-05-13 14:05:27 +0000
+++ lib/lp/archiveuploader/tests/nascentupload-security-uploads.txt 2010-07-24 09:41:13 +0000
@@ -31,6 +31,8 @@
31respective processorfamily and processor. Let's create them31respective processorfamily and processor. Let's create them
32on-the-fly:32on-the-fly:
3333
34 >>> from canonical.testing.layers import LaunchpadZopelessLayer
35 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
34 >>> from canonical.launchpad.interfaces import IDistributionSet36 >>> from canonical.launchpad.interfaces import IDistributionSet
35 >>> from canonical.launchpad.database import (37 >>> from canonical.launchpad.database import (
36 ... Processor, ProcessorFamily)38 ... Processor, ProcessorFamily)
@@ -45,6 +47,7 @@
4547
46 >>> import transaction48 >>> import transaction
47 >>> transaction.commit()49 >>> transaction.commit()
50 >>> LaunchpadZopelessLayer.switchDbUser('uploader')
4851
4952
50== Mixed Security Upload ==53== Mixed Security Upload ==
5154
=== renamed file 'lib/lp/soyuz/doc/nascentupload.txt' => 'lib/lp/archiveuploader/tests/nascentupload.txt'
--- lib/lp/soyuz/doc/nascentupload.txt 2010-05-21 12:12:58 +0000
+++ lib/lp/archiveuploader/tests/nascentupload.txt 2010-07-24 09:41:13 +0000
@@ -10,27 +10,13 @@
10 >>> login('foo.bar@canonical.com')10 >>> login('foo.bar@canonical.com')
1111
12For the purpose of this test, hoary needs to be an open (development)12For the purpose of this test, hoary needs to be an open (development)
13distroseries so that we can upload to it. It also needs to allow uploads13distroseries so that we can upload to it.
14to the universe component.
15
16This test normally runs as the "uploader" db user but it does not have
17permission to add a new ComponentSelection, so we temporarily switch to
18"launchpad" to handle this.
1914
20 >>> from canonical.launchpad.interfaces import (15 >>> from canonical.launchpad.interfaces import (
21 ... SeriesStatus, IComponentSet, IDistributionSet)16 ... SeriesStatus, IDistributionSet)
22 >>> from canonical.launchpad.database import ComponentSelection
23 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']17 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
24 >>> hoary = ubuntu['hoary']18 >>> hoary = ubuntu['hoary']
25 >>> hoary.status = SeriesStatus.DEVELOPMENT19 >>> hoary.status = SeriesStatus.DEVELOPMENT
26 >>> universe = getUtility(IComponentSet)['universe']
27 >>> from canonical.testing import LaunchpadZopelessLayer
28 >>> from canonical.database.sqlbase import commit
29 >>> commit()
30 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
31 >>> trash = ComponentSelection(distroseries=hoary, component=universe)
32 >>> commit()
33 >>> LaunchpadZopelessLayer.switchDbUser('uploader')
3420
35A NascentUpload is a collection of files in a directory. They21A NascentUpload is a collection of files in a directory. They
36represent what may turn out to be an acceptable upload to a launchpad22represent what may turn out to be an acceptable upload to a launchpad
@@ -152,9 +138,21 @@
152138
153ed_source is uses ORIG + DIFF form:139ed_source is uses ORIG + DIFF form:
154140
155 >>> ed_source_upload.native141 >>> from lp.archiveuploader.utils import determine_source_file_type
142 >>> from lp.registry.interfaces.sourcepackage import SourcePackageFileType
143 >>> def determine_file_types(upload):
144 ... return [determine_source_file_type(uf.filename)
145 ... for uf in upload.changes.files]
146 >>> def has_orig(upload):
147 ... return (SourcePackageFileType.ORIG_TARBALL
148 ... in determine_file_types(upload))
149 >>> def has_native(upload):
150 ... return (SourcePackageFileType.NATIVE_TARBALL
151 ... in determine_file_types(upload))
152
153 >>> has_native(ed_source_upload)
156 False154 False
157 >>> ed_source_upload.hasorig155 >>> has_orig(ed_source_upload)
158 True156 True
159157
160For *sourceful* uploads 'archdep' and 'archindep' are always False:158For *sourceful* uploads 'archdep' and 'archindep' are always False:
@@ -197,9 +195,9 @@
197As expected 'native' and 'hasorig' doesn't make any sense for binary195As expected 'native' and 'hasorig' doesn't make any sense for binary
198uploads, so they are alway False:196uploads, so they are alway False:
199197
200 >>> ed_binary_upload.native198 >>> has_native(ed_binary_upload)
201 False199 False
202 >>> ed_binary_upload.hasorig200 >>> has_orig(ed_binary_upload)
203 False201 False
204202
205Since the binary policy lets things through unsigned, we don't try and203Since the binary policy lets things through unsigned, we don't try and
@@ -287,9 +285,9 @@
287ancestries (it saves a lot of bandwidth). So, the upload is not285ancestries (it saves a lot of bandwidth). So, the upload is not
288'native', neither 'hasorig':286'native', neither 'hasorig':
289287
290 >>> ed_mixed_upload.native288 >>> has_native(ed_mixed_upload)
291 False289 False
292 >>> ed_mixed_upload.hasorig290 >>> has_orig(ed_mixed_upload)
293 False291 False
294292
295But if we check the DSC we will find the reference to the already293But if we check the DSC we will find the reference to the already
@@ -716,7 +714,9 @@
716to set hoary to CURRENT in order to do this because we're not allowed714to set hoary to CURRENT in order to do this because we're not allowed
717to upload to -UPDATES in a DEVELOPMENT series.715to upload to -UPDATES in a DEVELOPMENT series.
718716
717 >>> from canonical.testing import LaunchpadZopelessLayer
719 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')718 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
719 >>> from canonical.database.sqlbase import commit
720 >>> hoary.status = SeriesStatus.CURRENT720 >>> hoary.status = SeriesStatus.CURRENT
721 >>> commit()721 >>> commit()
722 >>> LaunchpadZopelessLayer.switchDbUser('uploader')722 >>> LaunchpadZopelessLayer.switchDbUser('uploader')
723723
=== modified file 'lib/lp/archiveuploader/tests/nascentuploadfile.txt'
--- lib/lp/archiveuploader/tests/nascentuploadfile.txt 2010-06-16 09:08:16 +0000
+++ lib/lp/archiveuploader/tests/nascentuploadfile.txt 2010-07-24 09:41:13 +0000
@@ -155,161 +155,10 @@
155155
156=== CustomUploadFile identification ===156=== CustomUploadFile identification ===
157157
158Source and Binary files are easily recognized by a regexp on the158A custom upload is essentially a tarball, so it matches the is_source
159filenames:159regexp, even though it isn't actually a source file:
160160
161 >>> from lp.archiveuploader.utils import (161 >>> from lp.archiveuploader.utils import re_issource
162 ... re_isadeb, re_issource)
163
164The binary regexp matches 'deb', 'ddeb' and 'udeb' filenames.
165
166 >>> deb_match = re_isadeb.match('foo-bar_1.0_i386.deb')
167 >>> deb_match.group(0)
168 'foo-bar_1.0_i386.deb'
169 >>> deb_match.group(1)
170 'foo-bar'
171 >>> deb_match.group(2)
172 '1.0'
173 >>> deb_match.group(3)
174 'i386'
175
176 >>> ddeb_match = re_isadeb.match('foo-bar_1.0_i386.ddeb')
177 >>> ddeb_match.group(0)
178 'foo-bar_1.0_i386.ddeb'
179 >>> ddeb_match.group(1)
180 'foo-bar'
181 >>> ddeb_match.group(2)
182 '1.0'
183 >>> ddeb_match.group(3)
184 'i386'
185
186 >>> udeb_match = re_isadeb.match('foo-bar_1.0_i386.udeb')
187 >>> udeb_match.group(0)
188 'foo-bar_1.0_i386.udeb'
189 >>> udeb_match.group(1)
190 'foo-bar'
191 >>> udeb_match.group(2)
192 '1.0'
193 >>> udeb_match.group(3)
194 'i386'
195
196The source regexp matches 'orig.tar.gz', 'tar.gz', 'diff.gz' and 'dsc'
197filenames.
198
199 >>> src_match = re_issource.match('foo_1.0.orig.tar.gz')
200 >>> src_match.group(0)
201 'foo_1.0.orig.tar.gz'
202 >>> src_match.group(1)
203 'foo'
204 >>> src_match.group(2)
205 '1.0'
206 >>> src_match.group(3)
207 'orig.tar.gz'
208
209 >>> src_match = re_issource.match('foo_1.0.tar.gz')
210 >>> src_match.group(0)
211 'foo_1.0.tar.gz'
212 >>> src_match.group(1)
213 'foo'
214 >>> src_match.group(2)
215 '1.0'
216 >>> src_match.group(3)
217 'tar.gz'
218
219 >>> src_match = re_issource.match('foo_1.0.tar.bz2')
220 >>> src_match.group(0)
221 'foo_1.0.tar.bz2'
222 >>> src_match.group(1)
223 'foo'
224 >>> src_match.group(2)
225 '1.0'
226 >>> src_match.group(3)
227 'tar.bz2'
228
229 >>> src_match = re_issource.match('foo_1.0.diff.gz')
230 >>> src_match.group(0)
231 'foo_1.0.diff.gz'
232 >>> src_match.group(1)
233 'foo'
234 >>> src_match.group(2)
235 '1.0'
236 >>> src_match.group(3)
237 'diff.gz'
238
239 >>> src_match = re_issource.match('foo_1.0.dsc')
240 >>> src_match.group(0)
241 'foo_1.0.dsc'
242 >>> src_match.group(1)
243 'foo'
244 >>> src_match.group(2)
245 '1.0'
246 >>> src_match.group(3)
247 'dsc'
248
249 >>> src_match = re_issource.match('foo_1.0.debian.tar.gz')
250 >>> src_match.group(0)
251 'foo_1.0.debian.tar.gz'
252 >>> src_match.group(1)
253 'foo'
254 >>> src_match.group(2)
255 '1.0'
256 >>> src_match.group(3)
257 'debian.tar.gz'
258
259 >>> src_match = re_issource.match('foo_1.0.debian.tar.bz2')
260 >>> src_match.group(0)
261 'foo_1.0.debian.tar.bz2'
262 >>> src_match.group(1)
263 'foo'
264 >>> src_match.group(2)
265 '1.0'
266 >>> src_match.group(3)
267 'debian.tar.bz2'
268
269 >>> src_match = re_issource.match('foo_1.0.orig-foo.tar.gz')
270 >>> src_match.group(0)
271 'foo_1.0.orig-foo.tar.gz'
272 >>> src_match.group(1)
273 'foo'
274 >>> src_match.group(2)
275 '1.0'
276 >>> src_match.group(3)
277 'orig-foo.tar.gz'
278
279 >>> src_match = re_issource.match('foo_1.0.orig-bar.tar.bz2')
280 >>> src_match.group(0)
281 'foo_1.0.orig-bar.tar.bz2'
282 >>> src_match.group(1)
283 'foo'
284 >>> src_match.group(2)
285 '1.0'
286 >>> src_match.group(3)
287 'orig-bar.tar.bz2'
288
289 >>> src_match = re_issource.match('foo_1.0.porig-bar.tar.bz2')
290 >>> src_match.group(0)
291 'foo_1.0.porig-bar.tar.bz2'
292 >>> src_match.group(1)
293 'foo'
294 >>> src_match.group(2)
295 '1.0.porig-bar'
296 >>> src_match.group(3)
297 'tar.bz2'
298
299And finally some failures:
300
301 >>> re_isadeb.match('foo-bar_1.0_i386.bed') is None
302 True
303
304 >>> re_issource.match('foo_1.0.c') is None
305 True
306
307 >>> re_issource.match('foo_1.0.diff.bz2') is None
308 True
309
310However a custom upload is essencially a tarball, so it also matches
311the is_source regexp:
312
313 >>> src_match = re_issource.match('dist-upgrader_1.0.tar.gz')162 >>> src_match = re_issource.match('dist-upgrader_1.0.tar.gz')
314 >>> src_match.group(0)163 >>> src_match.group(0)
315 'dist-upgrader_1.0.tar.gz'164 'dist-upgrader_1.0.tar.gz'
@@ -600,115 +449,6 @@
600 ['File ed_0.2-20.dsc mentioned in the changes has a size mismatch. 578 != 500']449 ['File ed_0.2-20.dsc mentioned in the changes has a size mismatch. 578 != 500']
601450
602451
603=== Format file type verification ===
604
605DSCFile performs additional verification on the types of the referenced
606files, confirming that they are suitable for the source package's
607format. There is an error generator to verify each format.
608
609 >>> from lp.archiveuploader.dscfile import (check_format_1_0_files,
610 ... check_format_3_0_native_files, check_format_3_0_quilt_files)
611 >>> from lp.registry.interfaces.sourcepackage import SourcePackageFileType
612
613==== 1.0 ====
614
615A 1.0 source can contain either a tar.gz or an orig.tar.gz and diff.gz.
616
617 >>> list(check_format_1_0_files('foo_1.dsc', {
618 ... SourcePackageFileType.ORIG_TARBALL: 1,
619 ... SourcePackageFileType.DIFF: 1,
620 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
621 ... SourcePackageFileType.NATIVE_TARBALL: 0,
622 ... }, {}, 0))
623 []
624
625 >>> list(check_format_1_0_files('foo_1.dsc', {
626 ... SourcePackageFileType.NATIVE_TARBALL: 1,
627 ... SourcePackageFileType.ORIG_TARBALL: 0,
628 ... SourcePackageFileType.DIFF: 0,
629 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
630 ... }, {}, 0))
631 []
632
633But if we have some other combination, or bzip2 compression, errors
634will be generated.
635
636 >>> list(check_format_1_0_files('foo_1.dsc', {
637 ... SourcePackageFileType.NATIVE_TARBALL: 1,
638 ... SourcePackageFileType.ORIG_TARBALL: 1,
639 ... SourcePackageFileType.DIFF: 1,
640 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
641 ... }, {}, 1))
642 [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',)]
643
644The files are also bad if there are any components:
645
646 >>> list(check_format_1_0_files('foo_1.dsc', {
647 ... SourcePackageFileType.ORIG_TARBALL: 1,
648 ... SourcePackageFileType.DIFF: 1,
649 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
650 ... SourcePackageFileType.NATIVE_TARBALL: 0,
651 ... }, {'foo': 1}, 0))
652 [UploadError('foo_1.dsc: must have exactly one tar.gz, or an orig.tar.gz and diff.gz',)]
653
654==== 3.0 (native) ====
655
656A 3.0 (native) source must contain just a tar.(gz|bz2).
657
658 >>> list(check_format_3_0_native_files('foo_1.dsc', {
659 ... SourcePackageFileType.NATIVE_TARBALL: 1,
660 ... SourcePackageFileType.ORIG_TARBALL: 0,
661 ... SourcePackageFileType.DIFF: 0,
662 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
663 ... }, {}, 1))
664 []
665
666 >>> list(check_format_3_0_native_files('foo_1.dsc', {
667 ... SourcePackageFileType.NATIVE_TARBALL: 1,
668 ... SourcePackageFileType.ORIG_TARBALL: 1,
669 ... SourcePackageFileType.DIFF: 0,
670 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
671 ... }, {}, 1))
672 [UploadError('foo_1.dsc: must have only a tar.*.',)]
673
674 >>> list(check_format_3_0_native_files('foo_1.dsc', {
675 ... SourcePackageFileType.NATIVE_TARBALL: 1,
676 ... SourcePackageFileType.ORIG_TARBALL: 0,
677 ... SourcePackageFileType.DIFF: 0,
678 ... SourcePackageFileType.DEBIAN_TARBALL: 0,
679 ... }, {'foo': 1}, 0))
680 [UploadError('foo_1.dsc: must have only a tar.*.',)]
681
682==== 3.0 (quilt) ====
683
684A 3.0 (quilt) source must have an orig.tar.*, a debian.tar.*, and at
685most one orig-COMPONENT.tar.* for each COMPONENT.
686
687 >>> list(check_format_3_0_quilt_files('foo_1.dsc', {
688 ... SourcePackageFileType.ORIG_TARBALL: 1,
689 ... SourcePackageFileType.DEBIAN_TARBALL: 1,
690 ... SourcePackageFileType.NATIVE_TARBALL: 0,
691 ... SourcePackageFileType.DIFF: 0,
692 ... }, {'foo': 1}, 1))
693 []
694
695 >>> list(check_format_3_0_quilt_files('foo_1.dsc', {
696 ... SourcePackageFileType.NATIVE_TARBALL: 1,
697 ... SourcePackageFileType.ORIG_TARBALL: 1,
698 ... SourcePackageFileType.DIFF: 0,
699 ... SourcePackageFileType.DEBIAN_TARBALL: 1,
700 ... }, {}, 1))
701 [UploadError('foo_1.dsc: must have only an orig.tar.*, a debian.tar.*, and optionally orig-*.tar.*',)]
702
703 >>> list(check_format_3_0_quilt_files('foo_1.dsc', {
704 ... SourcePackageFileType.ORIG_TARBALL: 1,
705 ... SourcePackageFileType.DEBIAN_TARBALL: 1,
706 ... SourcePackageFileType.NATIVE_TARBALL: 0,
707 ... SourcePackageFileType.DIFF: 0,
708 ... }, {'foo': 2}, 0))
709 [UploadError('foo_1.dsc: has more than one orig-foo.tar.*.',)]
710
711
712=== Sub-DSC files or DSCUploadedFiles ===452=== Sub-DSC files or DSCUploadedFiles ===
713453
714Sub-DSCFiles are DSCUploadedFile objects.454Sub-DSCFiles are DSCUploadedFile objects.
715455
=== renamed file 'lib/lp/soyuz/doc/safe_fix_maintainer.txt' => 'lib/lp/archiveuploader/tests/safe_fix_maintainer.txt'
=== modified file 'lib/lp/archiveuploader/tests/test_dscfile.py'
--- lib/lp/archiveuploader/tests/test_dscfile.py 2010-07-20 15:25:30 +0000
+++ lib/lp/archiveuploader/tests/test_dscfile.py 2010-07-24 09:41:13 +0000
@@ -7,16 +7,22 @@
77
8import os8import os
99
10from canonical.config import config
11from canonical.launchpad.scripts.logger import QuietFakeLogger10from canonical.launchpad.scripts.logger import QuietFakeLogger
12from canonical.testing.layers import LaunchpadZopelessLayer11from canonical.testing.layers import LaunchpadZopelessLayer
13from lp.archiveuploader.dscfile import (12from lp.archiveuploader.dscfile import (
14 DSCFile, findChangelog, findCopyright)13 DSCFile, findChangelog, findCopyright, format_to_file_checker_map)
15from lp.archiveuploader.nascentuploadfile import UploadError14from lp.archiveuploader.nascentuploadfile import UploadError
16from lp.archiveuploader.tests import datadir, mock_logger_quiet15from lp.archiveuploader.tests import datadir, mock_logger_quiet
17from lp.archiveuploader.uploadpolicy import BuildDaemonUploadPolicy16from lp.archiveuploader.uploadpolicy import BuildDaemonUploadPolicy
17from lp.registry.interfaces.sourcepackage import SourcePackageFileType
18from lp.soyuz.interfaces.sourcepackageformat import SourcePackageFormat
18from lp.testing import TestCase, TestCaseWithFactory19from lp.testing import TestCase, TestCaseWithFactory
1920
21ORIG_TARBALL = SourcePackageFileType.ORIG_TARBALL
22DEBIAN_TARBALL = SourcePackageFileType.DEBIAN_TARBALL
23NATIVE_TARBALL = SourcePackageFileType.NATIVE_TARBALL
24DIFF = SourcePackageFileType.DIFF
25
2026
21class TestDscFile(TestCase):27class TestDscFile(TestCase):
2228
@@ -146,3 +152,132 @@
146 dsc_file.cleanUp()152 dsc_file.cleanUp()
147 finally:153 finally:
148 os.chmod(tempdir, 0755)154 os.chmod(tempdir, 0755)
155
156
157class BaseTestSourceFileVerification(TestCase):
158
159 def assertErrorsForFiles(self, expected, files, components={},
160 bzip2_count=0):
161 """Check problems with the given set of files for the given format.
162
163 :param expected: a list of expected errors, as strings.
164 :param format: the `SourcePackageFormat` to check against.
165 :param files: a dict mapping `SourcePackageFileType`s to counts.
166 :param components: a dict mapping orig component tarball components
167 to counts.
168 :param bzip2_count: number of files using bzip2 compression.
169 """
170 full_files = {
171 NATIVE_TARBALL: 0,
172 ORIG_TARBALL: 0,
173 DIFF: 0,
174 DEBIAN_TARBALL: 0,
175 }
176 full_files.update(files)
177 self.assertEquals(
178 expected,
179 [str(e) for e in format_to_file_checker_map[self.format](
180 'foo_1.dsc', full_files, components, bzip2_count)])
181
182 def assertFilesOK(self, files, components={}, bzip2_count=0):
183 """Check that the given set of files is OK for the given format.
184
185 :param format: the `SourcePackageFormat` to check against.
186 :param files: a dict mapping `SourcePackageFileType`s to counts.
187 :param components: a dict mapping orig component tarball components
188 to counts.
189 :param bzip2_count: number of files using bzip2 compression.
190 """
191 self.assertErrorsForFiles([], files, components, bzip2_count)
192
193
194class Test10SourceFormatVerification(BaseTestSourceFileVerification):
195
196 format = SourcePackageFormat.FORMAT_1_0
197
198 wrong_files_error = ('foo_1.dsc: must have exactly one tar.gz, or an '
199 'orig.tar.gz and diff.gz')
200 bzip2_error = 'foo_1.dsc: is format 1.0 but uses bzip2 compression.'
201
202 def testFormat10Debian(self):
203 # A 1.0 source can contain an original tarball and a Debian diff
204 self.assertFilesOK({ORIG_TARBALL: 1, DIFF: 1})
205
206 def testFormat10Native(self):
207 # A 1.0 source can contain a native tarball.
208 self.assertFilesOK({NATIVE_TARBALL: 1})
209
210 def testFormat10CannotHaveWrongFiles(self):
211 # A 1.0 source cannot have a combination of native and
212 # non-native files, and cannot have just one of the non-native
213 # files.
214 for combination in (
215 {DIFF: 1}, {ORIG_TARBALL: 1}, {ORIG_TARBALL: 1, DIFF: 1,
216 NATIVE_TARBALL: 1}):
217 self.assertErrorsForFiles([self.wrong_files_error], combination)
218
219 # A 1.0 source with component tarballs is invalid.
220 self.assertErrorsForFiles(
221 [self.wrong_files_error], {ORIG_TARBALL: 1, DIFF: 1}, {'foo': 1})
222
223 def testFormat10CannotUseBzip2(self):
224 # 1.0 sources cannot use bzip2 compression.
225 self.assertErrorsForFiles(
226 [self.bzip2_error], {NATIVE_TARBALL: 1}, {}, 1)
227
228
229class Test30QuiltSourceFormatVerification(BaseTestSourceFileVerification):
230
231 format = SourcePackageFormat.FORMAT_3_0_QUILT
232
233 wrong_files_error = ('foo_1.dsc: must have only an orig.tar.*, a '
234 'debian.tar.* and optionally orig-*.tar.*')
235 comp_conflict_error = 'foo_1.dsc: has more than one orig-bar.tar.*.'
236
237 def testFormat30Quilt(self):
238 # A 3.0 (quilt) source must contain an orig tarball and a debian
239 # tarball. It may also contain at most one component tarball for
240 # each component, and can use gzip or bzip2 compression.
241 for components in ({}, {'foo': 1}, {'foo': 1, 'bar': 1}):
242 for bzip2_count in (0, 1):
243 self.assertFilesOK(
244 {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1}, components,
245 bzip2_count)
246
247 def testFormat30QuiltCannotHaveConflictingComponentTarballs(self):
248 # Multiple conflicting tarballs for a single component are
249 # invalid.
250 self.assertErrorsForFiles(
251 [self.comp_conflict_error],
252 {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1}, {'foo': 1, 'bar': 2})
253
254 def testFormat30QuiltCannotHaveWrongFiles(self):
255 # 3.0 (quilt) sources may not have a diff or native tarball.
256 for filetype in (DIFF, NATIVE_TARBALL):
257 self.assertErrorsForFiles(
258 [self.wrong_files_error],
259 {ORIG_TARBALL: 1, DEBIAN_TARBALL: 1, filetype: 1})
260
261
262class Test30QuiltSourceFormatVerification(BaseTestSourceFileVerification):
263
264 format = SourcePackageFormat.FORMAT_3_0_NATIVE
265
266 wrong_files_error = 'foo_1.dsc: must have only a tar.*.'
267
268 def testFormat30Native(self):
269 # 3.0 (native) sources must contain just a native tarball. They
270 # may use gzip or bzip2 compression.
271 for bzip2_count in (0, 1):
272 self.assertFilesOK({NATIVE_TARBALL: 1}, {},
273 bzip2_count)
274
275 def testFormat30NativeCannotHaveWrongFiles(self):
276 # 3.0 (quilt) sources may not have a diff, Debian tarball, orig
277 # tarball, or any component tarballs.
278 for filetype in (DIFF, DEBIAN_TARBALL, ORIG_TARBALL):
279 self.assertErrorsForFiles(
280 [self.wrong_files_error], {NATIVE_TARBALL: 1, filetype: 1})
281 # A 3.0 (native) source with component tarballs is invalid.
282 self.assertErrorsForFiles(
283 [self.wrong_files_error], {NATIVE_TARBALL: 1}, {'foo': 1})
149284
=== modified file 'lib/lp/archiveuploader/tests/test_utils.py'
--- lib/lp/archiveuploader/tests/test_utils.py 2010-07-18 00:26:33 +0000
+++ lib/lp/archiveuploader/tests/test_utils.py 2010-07-24 09:41:13 +0000
@@ -5,23 +5,19 @@
55
6# arch-tag: 90e6eb79-83a2-47e8-9f8b-3c687079c9236# arch-tag: 90e6eb79-83a2-47e8-9f8b-3c687079c923
77
8import unittest8from testtools import TestCase
9import sys
109
11from lp.registry.interfaces.sourcepackage import SourcePackageFileType10from lp.registry.interfaces.sourcepackage import SourcePackageFileType
12from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFileType11from lp.soyuz.interfaces.binarypackagerelease import BinaryPackageFileType
13from lp.archiveuploader.tests import datadir12from lp.archiveuploader.tests import datadir
1413from lp.archiveuploader.utils import (determine_binary_file_type,
1514 determine_source_file_type, re_isadeb, re_issource)
16class TestUtilities(unittest.TestCase):15
1716
18 def testImport(self):17class TestUtilities(TestCase):
19 """lp.archiveuploader.utils should be importable"""
20 import lp.archiveuploader.utils
2118
22 def test_determine_source_file_type(self):19 def test_determine_source_file_type(self):
23 """lp.archiveuploader.utils.determine_source_file_type should work."""20 """lp.archiveuploader.utils.determine_source_file_type should work."""
24 from lp.archiveuploader.utils import determine_source_file_type
2521
26 # .dsc -> DSC22 # .dsc -> DSC
27 self.assertEquals(23 self.assertEquals(
@@ -74,8 +70,6 @@
7470
75 def test_determine_binary_file_type(self):71 def test_determine_binary_file_type(self):
76 """lp.archiveuploader.utils.determine_binary_file_type should work."""72 """lp.archiveuploader.utils.determine_binary_file_type should work."""
77 from lp.archiveuploader.utils import determine_binary_file_type
78
79 # .deb -> DEB73 # .deb -> DEB
80 self.assertEquals(74 self.assertEquals(
81 determine_binary_file_type('foo_1.0-1_all.deb'),75 determine_binary_file_type('foo_1.0-1_all.deb'),
@@ -222,20 +216,43 @@
222 pass216 pass
223217
224218
225def test_suite():219class TestFilenameRegularExpressions(TestCase):
226 suite = unittest.TestSuite()220
227 loader = unittest.TestLoader()221 def test_re_isadeb(self):
228 suite.addTest(loader.loadTestsFromTestCase(TestUtilities))222 # Verify that the three binary extensions match the regexp.
229 return suite223 for extension in ('deb', 'ddeb', 'udeb'):
230224 self.assertEquals(
231225 ('foo-bar', '1.0', 'i386', extension),
232def main(argv):226 re_isadeb.match('foo-bar_1.0_i386.%s' % extension).groups())
233 suite = test_suite()227
234 runner = unittest.TextTestRunner(verbosity = 2)228 # Some other extension doesn't match.
235 if not runner.run(suite).wasSuccessful():229 self.assertIs(None, re_isadeb.match('foo-bar_1.0_i386.notdeb'))
236 return 1230
237 return 0231 # A missing architecture also doesn't match.
238232 self.assertIs(None, re_isadeb.match('foo-bar_1.0.deb'))
239233
240if __name__ == '__main__':234 def test_re_issource(self):
241 sys.exit(main(sys.argv))235 # Verify that various source extensions match the regexp.
236 extensions = (
237 'dsc', 'tar.gz', 'tar.bz2', 'diff.gz', 'orig.tar.gz',
238 'orig.tar.bz2', 'orig-bar.tar.gz', 'orig-bar.tar.bz2',
239 'debian.tar.gz', 'debian.tar.bz2')
240 for extension in extensions:
241 self.assertEquals(
242 ('foo-bar', '1.0', extension),
243 re_issource.match('foo-bar_1.0.%s' % extension).groups())
244
245 # While orig-*.tar.gz is all interpreted as extension, *orig-*.tar.gz
246 # is taken to have an extension of just 'tar.gz'.
247 self.assertEquals(
248 ('foo-bar', '1.0.porig-bar', 'tar.gz'),
249 re_issource.match('foo-bar_1.0.porig-bar.tar.gz').groups())
250
251 # Some other extension doesn't match.
252 self.assertIs(None, re_issource.match('foo-bar_1.0.notdsc'))
253
254 # A badly formatted name also doesn't match.
255 self.assertIs(None, re_issource.match('foo-bar.dsc'))
256
257 # bzip2 compression for files which must be gzipped is invalid.
258 self.assertIs(None, re_issource.match('foo-bar_1.0.diff.bz2'))
242259
=== renamed file 'lib/lp/soyuz/doc/uploadpolicy.txt' => 'lib/lp/archiveuploader/tests/uploadpolicy.txt'
=== modified file 'lib/lp/soyuz/tests/test_doc.py'
--- lib/lp/soyuz/tests/test_doc.py 2010-04-30 09:49:59 +0000
+++ lib/lp/soyuz/tests/test_doc.py 2010-07-24 09:41:13 +0000
@@ -123,11 +123,6 @@
123123
124124
125special = {125special = {
126 'nascentupload.txt': LayeredDocFileSuite(
127 '../doc/nascentupload.txt',
128 setUp=uploaderSetUp, tearDown=uploaderTearDown,
129 layer=LaunchpadZopelessLayer,
130 ),
131 'build-notification.txt': LayeredDocFileSuite(126 'build-notification.txt': LayeredDocFileSuite(
132 '../doc/build-notification.txt',127 '../doc/build-notification.txt',
133 setUp=builddmasterSetUp,128 setUp=builddmasterSetUp,