Merge lp:~cjwatson/launchpad/refactor-customupload-tests into lp:launchpad

Proposed by Colin Watson on 2012-05-25
Status: Merged
Approved by: Brad Crittenden on 2012-05-25
Approved revision: no longer in the source branch.
Merged at revision: 15312
Proposed branch: lp:~cjwatson/launchpad/refactor-customupload-tests
Merge into: lp:launchpad
Diff against target: 1812 lines (+722/-921)
14 files modified
lib/lp/archivepublisher/tests/test_ddtp_tarball.py (+102/-0)
lib/lp/archivepublisher/tests/test_debian_installer.py (+147/-0)
lib/lp/archivepublisher/tests/test_dist_upgrader.py (+86/-0)
lib/lp/archiveuploader/tests/data/ddtp-tarball/translations-main_20060817_all.changes (+0/-27)
lib/lp/services/doc/tarfile_helpers.txt (+35/-19)
lib/lp/services/tarfile_helpers.py (+39/-16)
lib/lp/services/tests/test_helpers.py (+2/-2)
lib/lp/soyuz/doc/distroseriesqueue-ddtp-tarball.txt (+0/-308)
lib/lp/soyuz/doc/distroseriesqueue-debian-installer.txt (+0/-187)
lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt (+0/-339)
lib/lp/soyuz/tests/test_distroseriesqueue_ddtp_tarball.py (+104/-0)
lib/lp/soyuz/tests/test_distroseriesqueue_debian_installer.py (+74/-0)
lib/lp/soyuz/tests/test_distroseriesqueue_dist_upgrader.py (+133/-0)
lib/lp/soyuz/tests/test_doc.py (+0/-23)
To merge this branch: bzr merge lp:~cjwatson/launchpad/refactor-customupload-tests
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code 2012-05-25 Approve on 2012-05-25
Review via email: mp+107381@code.launchpad.net

Commit Message

Convert custom upload doctests to unit tests.

Description of the Change

== Summary ==

I've been working on a branch which adds another custom upload format (not included here), and I really couldn't face writing doctests for it just so that they'd be similar to the existing custom upload tests. Therefore I cracked and decided to rewrite the custom upload doctests as unit tests. It won't do my LoC credit any harm either, which I may need.

The doctests were a mixture of fine-grained testing of the behaviour of the custom upload processors, albeit at one remove via queue processing, and high-level testing of upload and queue manipulation. The latter can be done in much the same way the doctests were doing it (although the doctest-style matching of debug output really doesn't add much of any interest), but the former is much better handled by unit tests that generate tarballs on the fly to exercise specific features. I put the former in archivepublisher near to the custom upload processors, and the latter in soyuz near to the queue processing.

== Tests ==

bin/test -vvct test_ddtp_tarball -t test_debian_installer -t test_dist_upgrader -t tarfile_helpers.txt -t test_distroseriesqueue

To post a comment you must log in.
Brad Crittenden (bac) wrote :

Colin these conversions to unit test are excellent. Thanks for taking the time to DTRT!

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'lib/lp/archivepublisher/tests/test_ddtp_tarball.py'
2--- lib/lp/archivepublisher/tests/test_ddtp_tarball.py 1970-01-01 00:00:00 +0000
3+++ lib/lp/archivepublisher/tests/test_ddtp_tarball.py 2012-05-25 13:49:22 +0000
4@@ -0,0 +1,102 @@
5+# Copyright 2012 Canonical Ltd. This software is licensed under the
6+# GNU Affero General Public License version 3 (see the file LICENSE).
7+
8+"""Test ddtp-tarball custom uploads.
9+
10+See also lp.soyuz.tests.test_distroseriesqueue_ddtp_tarball for high-level
11+tests of ddtp-tarball upload and queue manipulation.
12+"""
13+
14+import os
15+
16+from lp.archivepublisher.ddtp_tarball import process_ddtp_tarball
17+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
18+from lp.testing import TestCase
19+
20+
21+class TestDdtpTarball(TestCase):
22+
23+ def setUp(self):
24+ super(TestDdtpTarball, self).setUp()
25+ self.temp_dir = self.makeTemporaryDirectory()
26+ self.suite = "distroseries"
27+ # CustomUpload.installFiles requires a umask of 022.
28+ old_umask = os.umask(022)
29+ self.addCleanup(os.umask, old_umask)
30+
31+ def openArchive(self, version):
32+ self.path = os.path.join(
33+ self.temp_dir, "translations_main_%s.tar.gz" % version)
34+ self.buffer = open(self.path, "wb")
35+ self.archive = LaunchpadWriteTarFile(self.buffer)
36+
37+ def process(self):
38+ self.archive.close()
39+ self.buffer.close()
40+ process_ddtp_tarball(self.temp_dir, self.path, self.suite)
41+
42+ def getTranslationsPath(self, filename):
43+ return os.path.join(
44+ self.temp_dir, "dists", self.suite, "main", "i18n", filename)
45+
46+ def test_basic(self):
47+ # Processing a simple correct tar file works.
48+ self.openArchive("20060728")
49+ self.archive.add_file("i18n/Translation-de", "")
50+ self.process()
51+ self.assertTrue(os.path.exists(
52+ self.getTranslationsPath("Translation-de")))
53+
54+ def test_ignores_empty_directories(self):
55+ # Empty directories in the tarball are not extracted.
56+ self.openArchive("20060728")
57+ self.archive.add_file("i18n/Translation-de", "")
58+ self.archive.add_directory("i18n/foo")
59+ self.process()
60+ self.assertTrue(os.path.exists(
61+ self.getTranslationsPath("Translation-de")))
62+ self.assertFalse(os.path.exists(self.getTranslationsPath("foo")))
63+
64+ def test_partial_update(self):
65+ # If a DDTP tarball only contains a subset of published translation
66+ # files, these are updated and the rest are left untouched.
67+ self.openArchive("20060728")
68+ self.archive.add_file("i18n/Translation-bn", "bn")
69+ self.archive.add_file("i18n/Translation-ca", "ca")
70+ self.process()
71+ with open(self.getTranslationsPath("Translation-bn")) as bn_file:
72+ self.assertEqual("bn", bn_file.read())
73+ with open(self.getTranslationsPath("Translation-ca")) as ca_file:
74+ self.assertEqual("ca", ca_file.read())
75+ self.openArchive("20060817")
76+ self.archive.add_file("i18n/Translation-bn", "new bn")
77+ self.process()
78+ with open(self.getTranslationsPath("Translation-bn")) as bn_file:
79+ self.assertEqual("new bn", bn_file.read())
80+ with open(self.getTranslationsPath("Translation-ca")) as ca_file:
81+ self.assertEqual("ca", ca_file.read())
82+
83+ def test_breaks_hard_links(self):
84+ # Our archive uses dsync to replace identical files with hard links
85+ # in order to save some space. tarfile.extract overwrites
86+ # pre-existing files rather than creating new files and moving them
87+ # into place, so making this work requires special care. Test that
88+ # that care has been taken.
89+ self.openArchive("20060728")
90+ self.archive.add_file("i18n/Translation-ca", "")
91+ self.process()
92+ ca = self.getTranslationsPath("Translation-ca")
93+ bn = self.getTranslationsPath("Translation-bn")
94+ os.link(ca, bn)
95+ self.assertTrue(os.path.exists(bn))
96+ self.assertEqual(2, os.stat(bn).st_nlink)
97+ self.assertEqual(2, os.stat(ca).st_nlink)
98+ self.openArchive("20060817")
99+ self.archive.add_file("i18n/Translation-bn", "break hard link")
100+ self.process()
101+ with open(bn) as bn_file:
102+ self.assertEqual("break hard link", bn_file.read())
103+ with open(ca) as ca_file:
104+ self.assertEqual("", ca_file.read())
105+ self.assertEqual(1, os.stat(bn).st_nlink)
106+ self.assertEqual(1, os.stat(ca).st_nlink)
107
108=== added file 'lib/lp/archivepublisher/tests/test_debian_installer.py'
109--- lib/lp/archivepublisher/tests/test_debian_installer.py 1970-01-01 00:00:00 +0000
110+++ lib/lp/archivepublisher/tests/test_debian_installer.py 2012-05-25 13:49:22 +0000
111@@ -0,0 +1,147 @@
112+# Copyright 2012 Canonical Ltd. This software is licensed under the
113+# GNU Affero General Public License version 3 (see the file LICENSE).
114+
115+"""Test debian-installer custom uploads.
116+
117+See also lp.soyuz.tests.test_distroseriesqueue_debian_installer for
118+high-level tests of debian-installer upload and queue manipulation.
119+"""
120+
121+import os
122+
123+from lp.archivepublisher.customupload import CustomUploadBadUmask
124+from lp.archivepublisher.debian_installer import (
125+ DebianInstallerAlreadyExists,
126+ process_debian_installer,
127+ )
128+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
129+from lp.testing import TestCase
130+
131+
132+class TestDebianInstaller(TestCase):
133+
134+ def setUp(self):
135+ super(TestDebianInstaller, self).setUp()
136+ self.temp_dir = self.makeTemporaryDirectory()
137+ self.suite = "distroseries"
138+ # CustomUpload.installFiles requires a umask of 022.
139+ old_umask = os.umask(022)
140+ self.addCleanup(os.umask, old_umask)
141+
142+ def openArchive(self):
143+ self.version = "20070214ubuntu1"
144+ self.arch = "i386"
145+ self.path = os.path.join(
146+ self.temp_dir,
147+ "debian-installer-images_%s_%s.tar.gz" % (self.version, self.arch))
148+ self.buffer = open(self.path, "wb")
149+ self.archive = LaunchpadWriteTarFile(self.buffer)
150+
151+ def addFile(self, path, contents):
152+ self.archive.add_file(
153+ "installer-%s/%s/%s" % (self.arch, self.version, path), contents)
154+
155+ def addSymlink(self, path, target):
156+ self.archive.add_symlink(
157+ "installer-%s/%s/%s" % (self.arch, self.version, path), target)
158+
159+ def process(self):
160+ self.archive.close()
161+ self.buffer.close()
162+ process_debian_installer(self.temp_dir, self.path, self.suite)
163+
164+ def getInstallerPath(self, versioned_filename=None):
165+ installer_path = os.path.join(
166+ self.temp_dir, "dists", self.suite, "main",
167+ "installer-%s" % self.arch)
168+ if versioned_filename is not None:
169+ installer_path = os.path.join(
170+ installer_path, self.version, versioned_filename)
171+ return installer_path
172+
173+ def test_basic(self):
174+ # Processing a simple correct tar file succeeds.
175+ self.openArchive()
176+ self.addFile("hello", "world")
177+ self.process()
178+
179+ def test_already_exists(self):
180+ # If the target directory already exists, processing fails.
181+ self.openArchive()
182+ os.makedirs(self.getInstallerPath("."))
183+ self.assertRaises(DebianInstallerAlreadyExists, self.process)
184+
185+ def test_bad_umask(self):
186+ # The umask must be 022 to avoid incorrect permissions.
187+ self.openArchive()
188+ self.addFile("dir/file", "foo")
189+ os.umask(002) # cleanup already handled by setUp
190+ self.assertRaises(CustomUploadBadUmask, self.process)
191+
192+ def test_current_symlink(self):
193+ # A "current" symlink is created to the last version.
194+ self.openArchive()
195+ self.addFile("hello", "world")
196+ self.process()
197+ installer_path = self.getInstallerPath()
198+ self.assertContentEqual(
199+ [self.version, "current"], os.listdir(installer_path))
200+ self.assertEqual(
201+ self.version, os.readlink(os.path.join(installer_path, "current")))
202+
203+ def test_correct_file(self):
204+ # Files in the tarball are extracted correctly.
205+ self.openArchive()
206+ directory = ("images/netboot/ubuntu-installer/i386/"
207+ "pxelinux.cfg.serial-9600")
208+ filename = os.path.join(directory, "default")
209+ long_filename = os.path.join(
210+ directory, "very_very_very_very_very_very_long_filename")
211+ self.addFile(filename, "hey")
212+ self.addFile(long_filename, "long")
213+ self.process()
214+ with open(self.getInstallerPath(filename)) as f:
215+ self.assertEqual("hey", f.read())
216+ with open(self.getInstallerPath(long_filename)) as f:
217+ self.assertEqual("long", f.read())
218+
219+ def test_correct_symlink(self):
220+ # Symbolic links in the tarball are extracted correctly.
221+ self.openArchive()
222+ foo_path = "images/netboot/foo"
223+ foo_target = "ubuntu-installer/i386/pxelinux.cfg.serial-9600/default"
224+ link_to_dir_path = "images/netboot/link_to_dir"
225+ link_to_dir_target = "ubuntu-installer/i386/pxelinux.cfg.serial-9600"
226+ self.addSymlink(foo_path, foo_target)
227+ self.addSymlink(link_to_dir_path, link_to_dir_target)
228+ self.process()
229+ self.assertEqual(
230+ foo_target, os.readlink(self.getInstallerPath(foo_path)))
231+ self.assertEqual(
232+ link_to_dir_target,
233+ os.path.normpath(os.readlink(
234+ self.getInstallerPath(link_to_dir_path))))
235+
236+ def test_top_level_permissions(self):
237+ # Top-level directories are set to mode 0755 (see bug 107068).
238+ self.openArchive()
239+ self.addFile("hello", "world")
240+ self.process()
241+ installer_path = self.getInstallerPath()
242+ self.assertEqual(0755, os.stat(installer_path).st_mode & 0777)
243+ self.assertEqual(
244+ 0755,
245+ os.stat(os.path.join(installer_path, os.pardir)).st_mode & 0777)
246+
247+ def test_extracted_permissions(self):
248+ # Extracted files and directories are set to 0644/0755.
249+ self.openArchive()
250+ directory = ("images/netboot/ubuntu-installer/i386/"
251+ "pxelinux.cfg.serial-9600")
252+ filename = os.path.join(directory, "default")
253+ self.addFile(filename, "hey")
254+ self.process()
255+ self.assertEqual(
256+ 0644, os.stat(self.getInstallerPath(filename)).st_mode & 0777)
257+ self.assertEqual(
258+ 0755, os.stat(self.getInstallerPath(directory)).st_mode & 0777)
259
260=== added file 'lib/lp/archivepublisher/tests/test_dist_upgrader.py'
261--- lib/lp/archivepublisher/tests/test_dist_upgrader.py 1970-01-01 00:00:00 +0000
262+++ lib/lp/archivepublisher/tests/test_dist_upgrader.py 2012-05-25 13:49:22 +0000
263@@ -0,0 +1,86 @@
264+# Copyright 2012 Canonical Ltd. This software is licensed under the
265+# GNU Affero General Public License version 3 (see the file LICENSE).
266+
267+"""Test dist-upgrader custom uploads.
268+
269+See also lp.soyuz.tests.test_distroseriesqueue_dist_upgrader for high-level
270+tests of dist-upgrader upload and queue manipulation.
271+"""
272+
273+import os
274+
275+from lp.archivepublisher.customupload import CustomUploadBadUmask
276+from lp.archivepublisher.dist_upgrader import (
277+ DistUpgraderAlreadyExists,
278+ DistUpgraderBadVersion,
279+ process_dist_upgrader,
280+ )
281+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
282+from lp.testing import TestCase
283+
284+
285+class TestDistUpgrader(TestCase):
286+
287+ def setUp(self):
288+ super(TestDistUpgrader, self).setUp()
289+ self.temp_dir = self.makeTemporaryDirectory()
290+ self.suite = "distroseries"
291+ # CustomUpload.installFiles requires a umask of 022.
292+ old_umask = os.umask(022)
293+ self.addCleanup(os.umask, old_umask)
294+
295+ def openArchive(self, version):
296+ self.path = os.path.join(
297+ self.temp_dir, "dist-upgrader_%s_all.tar.gz" % version)
298+ self.buffer = open(self.path, "wb")
299+ self.archive = LaunchpadWriteTarFile(self.buffer)
300+
301+ def process(self):
302+ self.archive.close()
303+ self.buffer.close()
304+ process_dist_upgrader(self.temp_dir, self.path, self.suite)
305+
306+ def getUpgraderPath(self):
307+ return os.path.join(
308+ self.temp_dir, "dists", self.suite, "main", "dist-upgrader-all")
309+
310+ def test_basic(self):
311+ # Processing a simple correct tar file works.
312+ self.openArchive("20060302.0120")
313+ self.archive.add_file("20060302.0120/hello", "world")
314+ self.process()
315+
316+ def test_already_exists(self):
317+ # If the target directory already exists, processing fails.
318+ self.openArchive("20060302.0120")
319+ self.archive.add_file("20060302.0120/hello", "world")
320+ os.makedirs(os.path.join(self.getUpgraderPath(), "20060302.0120"))
321+ self.assertRaises(DistUpgraderAlreadyExists, self.process)
322+
323+ def test_bad_umask(self):
324+ # The umask must be 022 to avoid incorrect permissions.
325+ self.openArchive("20060302.0120")
326+ self.archive.add_file("20060302.0120/file", "foo")
327+ os.umask(002) # cleanup already handled by setUp
328+ self.assertRaises(CustomUploadBadUmask, self.process)
329+
330+ def test_current_symlink(self):
331+ # A "current" symlink is created to the last version.
332+ self.openArchive("20060302.0120")
333+ self.archive.add_file("20060302.0120/hello", "world")
334+ self.process()
335+ upgrader_path = self.getUpgraderPath()
336+ self.assertContentEqual(
337+ ["20060302.0120", "current"], os.listdir(upgrader_path))
338+ self.assertEqual(
339+ "20060302.0120",
340+ os.readlink(os.path.join(upgrader_path, "current")))
341+ self.assertContentEqual(
342+ ["hello"],
343+ os.listdir(os.path.join(upgrader_path, "20060302.0120")))
344+
345+ def test_bad_version(self):
346+ # Bad versions in the tarball are refused.
347+ self.openArchive("20070219.1234")
348+ self.archive.add_file("foobar/foobar/dapper.tar.gz", "")
349+ self.assertRaises(DistUpgraderBadVersion, self.process)
350
351=== removed file 'lib/lp/archiveuploader/tests/data/ddtp-tarball/translations-main_20060817_all.changes'
352--- lib/lp/archiveuploader/tests/data/ddtp-tarball/translations-main_20060817_all.changes 2011-05-20 13:48:46 +0000
353+++ lib/lp/archiveuploader/tests/data/ddtp-tarball/translations-main_20060817_all.changes 1970-01-01 00:00:00 +0000
354@@ -1,27 +0,0 @@
355------BEGIN PGP SIGNED MESSAGE-----
356-Hash: SHA1
357-
358-Origin: Ubuntu/warty
359-Format: 1.7
360-Date: Thu, 17 Aug 2006 14:20:25 +0300
361-Architecture: all
362-Version: 20060817
363-Distribution: breezy-autotest
364-Source: ddtp-tarball
365-Binary: ddtp-tarball
366-Urgency: low
367-Maintainer: Foo Bar <foo.bar@canonical.com>
368-Changed-By: Foo Bar <foo.bar@canonical.com>
369-Changes:
370- .
371- * Partial update, new language index
372- .
373-Files:
374- a774352e50a4b4606a85d53b1cf1b49e 181 raw-ddtp-tarball - translations_main_20060817.tar.gz
375------BEGIN PGP SIGNATURE-----
376-Version: GnuPG v1.4.11 (GNU/Linux)
377-
378-iEYEARECAAYFAk3WbpIACgkQjn63CGxkqMVACgCfc3GXQwcDuSs8C+lopI+Igw2c
379-w0cAn1YBCAxqTvipznXueOOWsphAMLCP
380-=803N
381------END PGP SIGNATURE-----
382
383=== removed file 'lib/lp/archiveuploader/tests/data/ddtp-tarball/translations_main_20060817.tar.gz'
384Binary files lib/lp/archiveuploader/tests/data/ddtp-tarball/translations_main_20060817.tar.gz 2007-03-27 21:01:50 +0000 and lib/lp/archiveuploader/tests/data/ddtp-tarball/translations_main_20060817.tar.gz 1970-01-01 00:00:00 +0000 differ
385=== modified file 'lib/lp/services/doc/tarfile_helpers.txt'
386--- lib/lp/services/doc/tarfile_helpers.txt 2010-12-17 14:06:07 +0000
387+++ lib/lp/services/doc/tarfile_helpers.txt 2012-05-25 13:49:22 +0000
388@@ -5,28 +5,35 @@
389 easy.
390
391 >>> from StringIO import StringIO
392+ >>> import tarfile
393 >>> from lp.services.tarfile_helpers import LaunchpadWriteTarFile
394
395 First, we are going to define a function we are going to use to validate the
396 output we will get.
397
398- >>> def examine_tarfile(tarfile):
399- ... names = tarfile.getnames()
400+ >>> def examine_tarfile(tar):
401+ ... members = tar.getmembers()
402 ... # Calculate the length of the longest name.
403- ... max_length = max(len(name) for name in names)
404+ ... max_length = max(len(member.name) for member in members)
405 ... # Use this length to generate an appropriate format string.
406 ... format = '%%-%ds | %%s' % max_length
407 ...
408- ... for name in names:
409- ... file = tarfile.extractfile(name)
410+ ... for member in members:
411+ ... if member.type == tarfile.REGTYPE:
412+ ... file = tar.extractfile(member)
413 ...
414- ... # XXX: 2010-04-26, Salgado, bug=570244: This is to make the
415- ... # test pass on python2.5 and 2.6.
416- ... name = name.rstrip('/')
417- ... if file is not None:
418- ... print format % (name, file.read())
419- ... else:
420- ... print format % (name, '')
421+ ... # XXX: 2010-04-26, Salgado, bug=570244: This is to make
422+ ... # the test pass on python2.5 and 2.6.
423+ ... name = member.name.rstrip('/')
424+ ... if file is not None:
425+ ... print format % (name, file.read())
426+ ... else:
427+ ... print format % (name, '')
428+ ... elif member.type == tarfile.SYMTYPE:
429+ ... print format % (
430+ ... member.name, "<link to %s>" % member.linkname)
431+ ... elif member.type == tarfile.DIRTYPE:
432+ ... print format % (member.name, "<directory>")
433
434 # Start off by creating a blank archive.
435 # We'll need a filehandle to store it in.
436@@ -43,19 +50,28 @@
437
438 >>> archive.add_files({'bar': '2', 'baz': '3'})
439
440+We can add symbolic links.
441+
442+ >>> archive.add_symlink('link', 'foo')
443+
444+We can add directories.
445+
446+ >>> archive.add_directory('dir')
447+
448 Once we are done adding files, the archive needs to be closed.
449
450 >>> archive.close()
451
452 And now we can inspect the produced file.
453
454- >>> import tarfile
455 >>> buffer.seek(0)
456 >>> archive = tarfile.open('', 'r', buffer)
457 >>> examine_tarfile(archive)
458- foo | 1
459- bar | 2
460- baz | 3
461+ foo | 1
462+ bar | 2
463+ baz | 3
464+ link | <link to foo>
465+ dir | <directory>
466
467 There are also some convenience methods for getting directly from several
468 files, represented with a dictionary, which have the file name as key and
469@@ -99,9 +115,9 @@
470 ... 'uno/dos/tres/cuatro': 'blah'
471 ... })
472 >>> examine_tarfile(archive)
473- uno |
474- uno/dos |
475- uno/dos/tres |
476+ uno | <directory>
477+ uno/dos | <directory>
478+ uno/dos/tres | <directory>
479 uno/dos/tres/cuatro | blah
480
481 Also, if there is a duplicated file, last one is the one that remains there.
482
483=== modified file 'lib/lp/services/tarfile_helpers.py'
484--- lib/lp/services/tarfile_helpers.py 2010-12-17 14:06:07 +0000
485+++ lib/lp/services/tarfile_helpers.py 2012-05-25 13:49:22 +0000
486@@ -1,4 +1,4 @@
487-# Copyright 2010 Canonical Ltd. This software is licensed under the
488+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
489 # GNU Affero General Public License version 3 (see the file LICENSE).
490
491 """Helpers to work with tar files more easily."""
492@@ -25,6 +25,7 @@
493 # any longer.
494 # -- Dafydd Harries, 2005-04-07.
495
496+
497 class LaunchpadWriteTarFile:
498 """Convenience wrapper around the tarfile module.
499
500@@ -66,36 +67,46 @@
501 self.tarfile.close()
502 self.closed = True
503
504- def add_file(self, path, contents):
505- """Add a file to the archive."""
506- assert not self.closed, "Can't add a file to a closed archive"
507+ def _make_skeleton_tarinfo(self, path, now):
508+ """Make a basic TarInfo object to be fleshed out by the caller."""
509+ tarinfo = tarfile.TarInfo(path)
510+ tarinfo.mtime = now
511+ tarinfo.uname = 'launchpad'
512+ tarinfo.gname = 'launchpad'
513+ return tarinfo
514
515- now = int(time.time())
516+ def _ensure_directories(self, path, now):
517+ """Ensure that all the directories in the path are present."""
518 path_bits = path.split(os.path.sep)
519
520- # Ensure that all the directories in the path are present in the
521- # archive.
522 for i in range(1, len(path_bits)):
523 joined_path = os.path.join(*path_bits[:i])
524
525 try:
526 self.tarfile.getmember(joined_path)
527 except KeyError:
528- tarinfo = tarfile.TarInfo(joined_path)
529+ tarinfo = self._make_skeleton_tarinfo(joined_path, now)
530 tarinfo.type = tarfile.DIRTYPE
531- tarinfo.mtime = now
532 tarinfo.mode = 0755
533- tarinfo.uname = 'launchpad'
534- tarinfo.gname = 'launchpad'
535 self.tarfile.addfile(tarinfo)
536
537- tarinfo = tarfile.TarInfo(path)
538- tarinfo.time = now
539- tarinfo.mtime = now
540+ def add_directory(self, path):
541+ """Add a directory to the archive."""
542+ assert not self.closed, "Can't add a directory to a closed archive"
543+
544+ now = int(time.time())
545+ self._ensure_directories(os.path.join(path, "."), now)
546+
547+ def add_file(self, path, contents):
548+ """Add a file to the archive."""
549+ assert not self.closed, "Can't add a file to a closed archive"
550+
551+ now = int(time.time())
552+ self._ensure_directories(path, now)
553+
554+ tarinfo = self._make_skeleton_tarinfo(path, now)
555 tarinfo.mode = 0644
556 tarinfo.size = len(contents)
557- tarinfo.uname = 'launchpad'
558- tarinfo.gname = 'launchpad'
559 self.tarfile.addfile(tarinfo, StringIO(contents))
560
561 def add_files(self, files):
562@@ -106,3 +117,15 @@
563
564 for filename in sorted(files.keys()):
565 self.add_file(filename, files[filename])
566+
567+ def add_symlink(self, path, target):
568+ """Add a symbolic link to the archive."""
569+ assert not self.closed, "Can't add a symlink to a closed archive"
570+
571+ now = int(time.time())
572+ self._ensure_directories(path, now)
573+
574+ tarinfo = self._make_skeleton_tarinfo(path, now)
575+ tarinfo.type = tarfile.SYMTYPE
576+ tarinfo.linkname = target
577+ self.tarfile.addfile(tarinfo)
578
579=== modified file 'lib/lp/services/tests/test_helpers.py'
580--- lib/lp/services/tests/test_helpers.py 2011-12-23 23:44:59 +0000
581+++ lib/lp/services/tests/test_helpers.py 2012-05-25 13:49:22 +0000
582@@ -1,4 +1,4 @@
583-# Copyright 2009 Canonical Ltd. This software is licensed under the
584+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
585 # GNU Affero General Public License version 3 (see the file LICENSE).
586
587 from doctest import DocTestSuite
588@@ -6,7 +6,7 @@
589 import unittest
590
591 from lp.services import helpers
592-from lp.translations.utilities.translation_export import LaunchpadWriteTarFile
593+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
594
595
596 def make_test_tarball_1():
597
598=== removed file 'lib/lp/soyuz/doc/distroseriesqueue-ddtp-tarball.txt'
599--- lib/lp/soyuz/doc/distroseriesqueue-ddtp-tarball.txt 2012-01-06 11:08:30 +0000
600+++ lib/lp/soyuz/doc/distroseriesqueue-ddtp-tarball.txt 1970-01-01 00:00:00 +0000
601@@ -1,308 +0,0 @@
602-DDTP-TARBALL upload
603--------------------
604-
605-This test will describe how launchpad treats an upload of DDTP
606-tarball.
607-
608-DDTP (Debian Description Translation Project) tarball upload is
609-consisted of a tarball (specified in the changesfile as a
610-DDTP-TARBALL) containing all the supported index files for the DDTP
611-contents driven by component.
612-
613-The index-files needs to be published in the ubuntu archive, according
614-its target suite and component, under the 'i18n' (see
615-http://en.wikipedia.org/wiki/Internationalization_and_localization)
616-directory.
617-
618-Soonish APT will be able to download and follow the indexes files,
619-then present the appropriated translated package description the users
620-in ubuntu.
621-
622-For further info about DDTP see:
623- https://wiki.ubuntu.com/TranslatedPackageDescriptionsSpec
624-
625- >>> from lp.registry.interfaces.distribution import IDistributionSet
626-
627- >>> ubuntutest = getUtility(IDistributionSet)['ubuntutest']
628- >>> breezy_autotest = ubuntutest['breezy-autotest']
629-
630- >>> from lp.archiveuploader.nascentupload import NascentUpload
631- >>> from lp.archiveuploader.tests import datadir, getPolicy
632-
633- >>> from lp.testing.gpgkeys import import_public_test_keys
634- >>> import_public_test_keys()
635-
636-Login as an admin (or ubuntutest.archive_admin if we have one), since
637-we need to access and modify PackageUpload records and other tables.
638-
639- >>> login('foo.bar@canonical.com')
640-
641-Set the email address for announcements:
642-
643- >>> breezy_autotest.changeslist = 'test@example.com'
644-
645-First, test the rejection of a misapplied changesfile name, which
646-doesn't follow the accepted format, "<pkg>_<version>_<arch>.changes"
647-
648- >>> sync_policy = getPolicy(
649- ... name='sync', distro='ubuntutest', distroseries=None)
650-
651- >>> from lp.services.log.logger import DevNullLogger
652- >>> upload = NascentUpload.from_changesfile_path(
653- ... datadir('ddtp-tarball/translations-main_20060728.changes'),
654- ... sync_policy, DevNullLogger())
655- >>> upload.process()
656- Traceback (most recent call last):
657- ...
658- EarlyReturnUploadError: An error occurred that prevented further
659- processing.
660-
661-Now do a proper upload into the system.
662-
663- >>> insecure_policy = getPolicy(
664- ... name='insecure', distro='ubuntutest', distroseries=None)
665-
666- >>> from lp.services.log.logger import FakeLogger
667- >>> upload = NascentUpload.from_changesfile_path(
668- ... datadir('ddtp-tarball/translations-main_20060728_all.changes'),
669- ... insecure_policy, FakeLogger())
670- DEBUG Verifying signature on translations-main_20060728_all.changes
671-
672- >>> upload.process()
673- DEBUG Beginning processing.
674- DEBUG Verifying the changes file.
675- DEBUG Verifying files in upload.
676- DEBUG Single Custom Upload detected.
677- DEBUG Finished checking upload.
678-
679-It was not rejected.
680-
681- >>> upload.is_rejected
682- False
683-
684- >>> success = upload.do_accept()
685- DEBUG Creating queue entry
686- ...
687- DEBUG Sent a mail:
688- DEBUG Subject: [ubuntutest/breezy-autotest]
689- translations_main_20060728.tar.gz - (Accepted)
690- DEBUG Sender: Root <root@localhost>
691- DEBUG Recipients: Foo Bar <foo.bar@canonical.com>
692- DEBUG Bcc: Root <root@localhost>
693- DEBUG Body:
694- DEBUG .
695- DEBUG * Duhh
696- DEBUG
697- DEBUG
698- DEBUG Date: Thu, 01 Aug 2006 14:20:25 +0300
699- DEBUG Changed-By: Foo Bar <foo.bar@canonical.com>
700- DEBUG Origin: Ubuntu/warty
701- DEBUG
702- DEBUG
703- DEBUG ==
704- DEBUG
705- DEBUG Announcing to test@example.com
706- DEBUG
707- DEBUG Thank you for your contribution to Ubuntu Test.
708- DEBUG
709- DEBUG --
710- DEBUG You are receiving this email because you are the uploader,
711- maintainer or
712- DEBUG signer of the above package.
713- DEBUG Sent a mail:
714- DEBUG Subject: [ubuntutest/breezy-autotest]
715- translations_main_20060728.tar.gz - (Accepted)
716- DEBUG Sender: Foo Bar <foo.bar@canonical.com>
717- DEBUG Recipients: test@example.com
718- DEBUG Bcc: Root <root@localhost>
719- DEBUG Body:
720- DEBUG .
721- DEBUG * Duhh
722- DEBUG
723- DEBUG
724- DEBUG Date: Thu, 01 Aug 2006 14:20:25 +0300
725- DEBUG Changed-By: Foo Bar <foo.bar@canonical.com>
726- DEBUG Origin: Ubuntu/warty
727- DEBUG
728-
729-And all things worked.
730-
731- >>> success
732- True
733-
734- >>> not upload.rejection_message
735- True
736-
737-We need to commit the transaction to be able to use the librarian files.
738-
739- >>> flush_database_updates()
740- >>> transaction.commit()
741-
742-Let's use the script to fetch the ddtp-tarball upload:
743-
744- >>> import subprocess
745- >>> import os
746- >>> import sys
747- >>> from lp.services.config import config
748-
749- >>> script = os.path.join(
750- ... config.root, "scripts", "ftpmaster-tools", "queue")
751-
752- >>> process = subprocess.Popen([sys.executable, script, "-Q", "accepted",
753- ... "-s", "breezy-autotest", "fetch", "trans",
754- ... "-d", "ubuntutest"],
755- ... stdout=subprocess.PIPE)
756- >>> stdout, stderr = process.communicate()
757- >>> process.returncode
758- 0
759- >>> print stdout
760- Initializing connection to queue accepted
761- Running: "fetch trans"
762- Fetching ubuntutest/breezy-autotest (ACCEPTED) 1/1
763- ---------------------------------------------------------------------------
764- Constructing translations-main_20060728_all.changes
765- Constructing translations_main_20060728.tar.gz
766- ---------------------------------------------------------------------------
767- 1/1 total
768- <BLANKLINE>
769-
770-Check if the files were written:
771-
772- >>> os.path.exists('translations-main_20060728_all.changes')
773- True
774- >>> os.path.exists('translations_main_20060728.tar.gz')
775- True
776-
777-Cleanup the mess:
778-
779- >>> os.remove('translations-main_20060728_all.changes')
780- >>> os.remove('translations_main_20060728.tar.gz')
781-
782-
783-Inspect the QUEUE looking for an ACCEPTED entry corresponding to the
784-previous upload:
785-
786- >>> from lp.soyuz.enums import PackageUploadStatus
787- >>> queue_item = breezy_autotest.getPackageUploads(
788- ... status=PackageUploadStatus.ACCEPTED)[0]
789- >>> queue_item.customfiles[0].libraryfilealias.filename
790- u'translations_main_20060728.tar.gz'
791-
792-Do the publish, i.e process the CustomUpload decompressing and writing
793-the tarball contents in the archive, collect and check debug message:
794-
795-The umask must be 022 in order to perform the upload.
796-
797- >>> old_mask = os.umask(022)
798- >>> pub_records = queue_item.realiseUpload(FakeLogger())
799- DEBUG Publishing custom translations_main_20060728.tar.gz to
800- ubuntutest/breezy-autotest
801- >>> print '%03o' % os.umask(old_mask)
802- 022
803-
804-Check what was published in the target directory:
805-
806- >>> import os
807- >>> archive_dir = '/var/tmp/archive/'
808-
809-DDTP indexes are published in the "i18n" directory inside archive dists:
810-
811- >>> upgrade_dir = 'ubuntutest/dists/breezy-autotest/main/i18n'
812- >>> target_dir = os.path.join(archive_dir, upgrade_dir)
813-
814-We simply decompress the contents of the tarball, the files follow
815-the format:
816-
817- Translation-<lang-code>{'', '.gz', '.bz2'}
818-
819-We have only used uncompressed files for tests:
820-
821- >>> dir_list = os.listdir(target_dir)
822- >>> for filename in sorted(dir_list):
823- ... content = open(os.path.join(target_dir, filename), 'rb').read()
824- ... print filename, len(content)
825- Translation-bn 0
826- Translation-ca 0
827- Translation-en 16
828- Translation-pt_BR 15
829-
830-** Note that a incomming directory inside the tarball "i18n" directory
831-was skipped by the DDTP processor
832-
833-Upload a new DDTP tarball which is supposed to only add a new language
834-index , the "bn" one, and left the rest untouched, this feature is
835-know as "partial update" and will save some storage when fixing specific
836-language indexes or adding new ones:
837-
838- >>> insecure_policy = getPolicy(
839- ... name='insecure', distro='ubuntutest', distroseries=None)
840-
841- >>> upload = NascentUpload.from_changesfile_path(
842- ... datadir('ddtp-tarball/translations-main_20060817_all.changes'),
843- ... insecure_policy, DevNullLogger())
844- >>> upload.process()
845- >>> upload.is_rejected
846- False
847- >>> success = upload.do_accept()
848- >>> success
849- True
850-
851-
852-We need to commit the transaction to be able to use the librarian files.
853-
854- >>> flush_database_updates()
855- >>> transaction.commit()
856-
857-
858-Our archive uses `dsync` to replace identical files by hard link in
859-order to save some space. This feature breaks the tarfile.extract method,
860-because it doesn't remove pre-existing files, it simply overwrite them.
861-
862-Create a hard link to "bn" package file.
863-
864- >>> src = os.path.join(target_dir, 'Translation-ca')
865- >>> dest = os.path.join(target_dir, 'Translation-bn')
866- >>> os.remove(dest)
867- >>> os.link(src, dest)
868-
869- >>> os.path.exists(dest)
870- True
871- >>> os.stat(dest).st_nlink
872- 2
873- >>> os.stat(src).st_nlink
874- 2
875-
876-
877-Retrieve and publish new custom upload:
878-
879- >>> queue_item = breezy_autotest.getPackageUploads(
880- ... status=PackageUploadStatus.ACCEPTED)[0]
881-
882- >>> pub_records = queue_item.realiseUpload()
883-
884-
885-Check if there is new content for "bn" index:
886-
887- >>> dir_list = os.listdir(target_dir)
888- >>> for filename in sorted(dir_list):
889- ... content = open(os.path.join(target_dir, filename), 'rb').read()
890- ... print filename, len(content)
891- Translation-bn 22
892- Translation-ca 0
893- Translation-en 16
894- Translation-pt_BR 15
895-
896-
897-Check if the contents of "ca" were not affected by the "bn" contents
898-(this would happen if "bn" was not removed, left as hard link):
899-
900- >>> open(os.path.join(target_dir, 'Translation-bn')).read()
901- 'hardlinks are bad !!!\n'
902-
903- >>> open(os.path.join(target_dir, 'Translation-ca')).read()
904- ''
905-
906-Remove the directory to keep the test working.
907-
908- >>> import shutil
909- >>> shutil.rmtree(target_dir)
910
911=== removed file 'lib/lp/soyuz/doc/distroseriesqueue-debian-installer.txt'
912--- lib/lp/soyuz/doc/distroseriesqueue-debian-installer.txt 2012-05-23 23:02:08 +0000
913+++ lib/lp/soyuz/doc/distroseriesqueue-debian-installer.txt 1970-01-01 00:00:00 +0000
914@@ -1,187 +0,0 @@
915-= Debian Installer Custom Uploads =
916-
917-Debian Installer uploads are treated as one of the Soyuz "custom"
918-types.
919-
920-They come from buildd as result of the 'debian-installer' source
921-build. This binary upload usually contains:
922-
923- * The debian-installer binaries (DEB)
924- * The debian-installer translation (TAR.GZ, custom ROSETTA_TRANSLATIONS)
925- * The debian-installer special archive files (TAR.GZ, custom DEBIAN_INSTALLER)
926-
927-We have a special processor to publish debian-installer special archive
928-file contents.
929-
930-The debian-installer filename should be something like:
931-
932-<BASE>_<VERSION>_<ARCH>.tar.gz
933-
934-Where:
935-
936- * BASE: base name (usually 'debian-installer-images')
937-
938- * VERSION: encoded version (something like '20061102ubuntu14')
939-
940- * ARCH: targeted architecture tag ('i386', 'amd64', etc)
941-
942-The contents are extracted in the archive in the following path:
943-
944- * <ARCHIVE>/dists/<SUITE>/main/installer-<ARCH>/
945-
946-
947-Let's try one test upload and verify the results of its publication.
948-In order to keep the tests simple we will upload only the
949-debian-installer tarball, despite the fact that it's very unlikely to
950-happen in production:
951-
952- >>> from lp.testing.gpgkeys import import_public_test_keys
953- >>> import_public_test_keys()
954- >>> login('foo.bar@canonical.com')
955-
956- >>> from lp.registry.interfaces.distribution import IDistributionSet
957- >>> ubuntutest = getUtility(IDistributionSet)['ubuntutest']
958-
959- >>> from lp.archiveuploader.nascentupload import NascentUpload
960- >>> from lp.archiveuploader.tests import datadir, getPolicy
961-
962- >>> anything_policy = getPolicy(
963- ... name='anything', distro='ubuntutest', distroseries=None)
964- >>> anything_policy.setDistroSeriesAndPocket('hoary-test')
965-
966-Set the email address for annoucements emails:
967-
968- >>> anything_policy.distroseries.changeslist = 'announce@example.com'
969-
970- >>> from lp.services.log.logger import DevNullLogger
971- >>> upload = NascentUpload.from_changesfile_path(
972- ... datadir(
973- ... 'debian-installer/debian-installer_20070214ubuntu1_i386.changes'),
974- ... anything_policy, DevNullLogger())
975- >>> upload.process()
976- >>> success = upload.do_accept()
977- >>> success
978- True
979-
980-Upload was successfully 'processed' and 'accepted'. Two email messages
981-were generated (acceptance and announcement). Inspect the queue (IDRQ)
982-information we find out that it contains one custom upload.
983-
984- >>> upload.queue_root.status.name
985- 'ACCEPTED'
986-
987-Make librarian files available for publication:
988-
989- >>> import transaction
990- >>> transaction.commit()
991-
992- >>> from lp.services.mail import stub
993- >>> len(stub.test_emails)
994- 2
995- >>> upload.queue_root.customfiles.count()
996- 1
997-
998-Let's force an error simulating a conflict in archive:
999-
1000- >>> import os
1001- >>> archive_path = "/var/tmp/archive/"
1002- >>> installer_path = os.path.join(
1003- ... archive_path, "ubuntutest/dists/hoary-test/main/installer-i386")
1004-
1005- >>> os.makedirs(os.path.join(installer_path, '20070214ubuntu1'))
1006-
1007-Try to publish the custom upload, but it will be skipped due the disk
1008-conflict and the queue item will remain in ACCEPTED
1009-
1010- >>> from lp.services.log.logger import FakeLogger
1011- >>> pub_records = upload.queue_root.realiseUpload(FakeLogger())
1012- DEBUG Publishing custom debian-installer-images_20070214ubuntu1_i386.tar.gz to ubuntutest/hoary-test
1013- ERROR Queue item ignored: installer build i386 for architecture 20070214ubuntu1 already exists
1014- >>> upload.queue_root.status.name
1015- 'ACCEPTED'
1016-
1017-Let's remove the conflicted directory from disk and expect it to work
1018-next time:
1019-
1020- >>> os.rmdir(os.path.join(installer_path, '20070214ubuntu1'))
1021-
1022-The upload task requires that the umask be 022, otherwise things will end up
1023-with the wrong permission.
1024-
1025- >>> old_mask = os.umask(002)
1026- >>> pub_records = upload.queue_root.realiseUpload(FakeLogger())
1027- DEBUG ...
1028- ERROR Queue item ignored: Bad umask; expected 022, got 002
1029-
1030-Reset the umask, remove any residual directories, and try again.
1031-
1032- >>> os.rmdir(os.path.join(installer_path, '20070214ubuntu1'))
1033- >>> print '%03o' % os.umask(old_mask)
1034- 002
1035-
1036-Process (publish) the custom upload:
1037-
1038- >>> pub_records = upload.queue_root.realiseUpload(DevNullLogger())
1039- >>> upload.queue_root.status.name
1040- 'DONE'
1041-
1042-The current debian-installer directory (20070214ubuntu1) and a link to
1043-the last version (we only have the one we uploaded) should be
1044-presented:
1045-
1046- >>> sorted(os.listdir(installer_path))
1047- ['20070214ubuntu1', 'current']
1048-
1049-As a consistency check, let's verify one of the files inside the
1050-tarball:
1051-
1052- >>> the_file = ("current/images/netboot/ubuntu-installer/i386/"
1053- ... "pxelinux.cfg.serial-9600/default")
1054- >>> the_file_path = os.path.join(installer_path, the_file)
1055- >>> print open(the_file_path).read()
1056- hey
1057-
1058-Also check if the symbolic link included in the installer tarball
1059-looks sane:
1060-
1061- >>> the_link = "current/images/netboot/foo"
1062- >>> the_link_path = os.path.join(installer_path, the_link)
1063- >>> os.readlink(the_link_path)
1064- 'ubuntu-installer/i386/pxelinux.cfg.serial-9600/default'
1065-
1066- >>> the_dir_link = "current/images/netboot/link_to_dir"
1067- >>> the_dir_link_path = os.path.join(installer_path, the_dir_link)
1068- >>> os.readlink(the_dir_link_path)
1069- 'ubuntu-installer/i386/pxelinux.cfg.serial-9600/'
1070-
1071-Check permissions on the created directories to satisfy the
1072-publication path. They are created with os.makedirs() and forced to
1073-set permission '0755' instead of the default '0777' (see further
1074-details in bug #107068):
1075-
1076- >>> oct(os.stat(installer_path).st_mode & 0777)
1077- '0755'
1078-
1079- >>> the_path = os.path.join(installer_path, os.pardir)
1080- >>> oct(os.stat(the_path).st_mode & 0777)
1081- '0755'
1082-
1083-Check permissions of created files and directories:
1084-
1085- >>> the_file = ("current/images/netboot/ubuntu-installer/i386/"
1086- ... "pxelinux.cfg.serial-9600/default")
1087- >>> the_file_path = os.path.join(installer_path, the_file)
1088- >>> oct(os.stat(the_file_path).st_mode & 0777)
1089- '0644'
1090-
1091- >>> the_dir = ("current/images/netboot/ubuntu-installer/i386/"
1092- ... "pxelinux.cfg.serial-9600/")
1093- >>> the_dir_path = os.path.join(installer_path, the_dir)
1094- >>> oct(os.stat(the_dir_path).st_mode & 0777)
1095- '0755'
1096-
1097-
1098-Remove local archive contents:
1099-
1100- >>> import shutil
1101- >>> shutil.rmtree(archive_path)
1102
1103=== removed file 'lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt'
1104--- lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 2012-01-06 11:08:30 +0000
1105+++ lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt 1970-01-01 00:00:00 +0000
1106@@ -1,339 +0,0 @@
1107-DIST-UPGRADE upload
1108-===================
1109-
1110-This test will check the upload of dist-upgrade tarballs
1111-
1112- >>> from lp.registry.interfaces.distribution import IDistributionSet
1113-
1114- >>> from lp.archiveuploader.nascentupload import NascentUpload
1115- >>> from lp.archiveuploader.tests import datadir, getPolicy
1116-
1117- >>> ubuntutest = getUtility(IDistributionSet)['ubuntutest']
1118- >>> breezy_autotest = ubuntutest['breezy-autotest']
1119-
1120- >>> from lp.testing.gpgkeys import import_public_test_keys
1121- >>> import_public_test_keys()
1122-
1123-Login as an admin.
1124-
1125- >>> login('foo.bar@canonical.com')
1126-
1127-First, test the rejection of a misapplied changesfile name:
1128-
1129- >>> sync_policy = getPolicy(
1130- ... name='sync', distro='ubuntutest', distroseries=None)
1131-
1132- >>> from lp.services.log.logger import FakeLogger
1133- >>> upload = NascentUpload.from_changesfile_path(
1134- ... datadir('dist-upgrader/dist-upgrader_20060302.0120.changes'),
1135- ... sync_policy, FakeLogger())
1136- DEBUG dist-upgrader_20060302.0120.changes can be unsigned.
1137- >>> upload.process()
1138- Traceback (most recent call last):
1139- ...
1140- EarlyReturnUploadError: An error occurred that prevented further
1141- processing.
1142-
1143-Now do a proper upload into the system.
1144-
1145- >>> insecure_policy = getPolicy(
1146- ... name='insecure', distro='ubuntutest', distroseries=None)
1147-
1148- >>> upload = NascentUpload.from_changesfile_path(
1149- ... datadir('dist-upgrader/dist-upgrader_20060302.0120_all.changes'),
1150- ... insecure_policy, FakeLogger())
1151- DEBUG Verifying signature on dist-upgrader_20060302.0120_all.changes
1152-
1153- >>> upload.process()
1154- DEBUG Beginning processing.
1155- DEBUG Verifying the changes file.
1156- DEBUG Verifying files in upload.
1157- DEBUG Single Custom Upload detected.
1158- DEBUG Finished checking upload.
1159-
1160-It was not rejected.
1161-
1162- >>> upload.is_rejected
1163- False
1164-
1165- >>> success = upload.do_accept()
1166- DEBUG Creating queue entry
1167- DEBUG Setting it to ACCEPTED
1168- DEBUG Building recipients list.
1169- ...
1170- DEBUG Adding recipient: 'Foo Bar <foo.bar@canonical.com>'
1171- DEBUG Sent a mail:
1172- ...
1173- DEBUG signer of the above package.
1174-
1175-And all things worked.
1176-
1177- >>> success
1178- True
1179-
1180- >>> print upload.rejection_message
1181-
1182-We need to commit the transaction to be able to use the librarian files.
1183-XXX: flush_database_updates() shouldn't be needed. This seems to be
1184-Bug 3989 -- StuartBishop 20060713
1185-
1186- >>> flush_database_updates()
1187- >>> transaction.commit()
1188-
1189-Let's check how queue tool handles dist_upgrader uploads:
1190-
1191- >>> import subprocess
1192- >>> import os
1193- >>> import sys
1194- >>> from lp.services.config import config
1195-
1196- >>> script = os.path.join(
1197- ... config.root, "scripts", "ftpmaster-tools", "queue")
1198-
1199-
1200-Rejecting item from accepted queue (very unlikely, normally it would
1201-be rejecting from unapproved or new, fix bug #54649):
1202-
1203- >>> process = subprocess.Popen([
1204- ... sys.executable, script,
1205- ... "-Q", "accepted",
1206- ... "-s", "breezy-autotest", "reject", "dist",
1207- ... "-d", "ubuntutest", "-M"],
1208- ... stderr=subprocess.PIPE,
1209- ... stdout=subprocess.PIPE)
1210- >>> stdout, stderr = process.communicate()
1211- >>> process.returncode
1212- 0
1213- >>> print stdout
1214- Initializing connection to queue accepted
1215- ...
1216- Rejecting dist-upgrader_20060302.0120_all.tar.gz
1217- ...
1218-
1219-
1220-Accepting from rejected queue (resurrecting an reject upload is also
1221-very unlikely, however it's only for testing purposes, fix #54649):
1222-
1223- >>> process = subprocess.Popen([sys.executable, script, "-Q", "rejected",
1224- ... "-s", "breezy-autotest", "accept", "dist",
1225- ... "-d", "ubuntutest", "-M"],
1226- ... stderr=subprocess.PIPE,
1227- ... stdout=subprocess.PIPE)
1228- >>> stdout, stderr = process.communicate()
1229- >>> process.returncode
1230- 0
1231- >>> print stdout
1232- Initializing connection to queue rejected
1233- ...
1234- Accepting dist-upgrader_20060302.0120_all.tar.gz
1235- ...
1236-
1237-
1238-Let's use the script to fetch the dist-upgrader upload:
1239-
1240- >>> process = subprocess.Popen([sys.executable, script, "-Q", "accepted",
1241- ... "-s", "breezy-autotest", "fetch", "dist",
1242- ... "-d", "ubuntutest"],
1243- ... stdout=subprocess.PIPE)
1244- >>> stdout, stderr = process.communicate()
1245- >>> process.returncode
1246- 0
1247- >>> print stdout
1248- Initializing connection to queue accepted
1249- Running: "fetch dist"
1250- Fetching ubuntutest/breezy-autotest (ACCEPTED) 1/1
1251- ---------------------------------------------------------------------------
1252- Constructing dist-upgrader_20060302.0120_all.changes
1253- Constructing dist-upgrader_20060302.0120_all.tar.gz
1254- ---------------------------------------------------------------------------
1255- 1/1 total
1256- <BLANKLINE>
1257-
1258-
1259-Check if the files were written:
1260-
1261- >>> os.path.exists('dist-upgrader_20060302.0120_all.changes')
1262- True
1263- >>> os.path.exists('dist-upgrader_20060302.0120_all.tar.gz')
1264- True
1265-
1266-Cleanup the mess:
1267-
1268- >>> os.remove('dist-upgrader_20060302.0120_all.changes')
1269- >>> os.remove('dist-upgrader_20060302.0120_all.tar.gz')
1270-
1271-
1272-Inspect the QUEUE looking for an ACCEPTED entry corresponding to the
1273-previous upload:
1274-
1275- >>> from lp.soyuz.enums import PackageUploadStatus
1276- >>> queue_item = breezy_autotest.getPackageUploads(
1277- ... status=PackageUploadStatus.ACCEPTED)[0]
1278- >>> queue_item.customfiles[0].libraryfilealias.filename
1279- u'dist-upgrader_20060302.0120_all.tar.gz'
1280-
1281-Do the publish, i.e process the CustomUpload writing the tarball in
1282-the archive. The umask must be 022 in order to perform the upload.
1283-
1284- >>> old_mask = os.umask(022)
1285- >>> pub_records = queue_item.realiseUpload()
1286- >>> print '%03o' % os.umask(old_mask)
1287- 022
1288-
1289-Check what was published in the target directory:
1290-
1291- >>> import os
1292- >>> archive_dir = '/var/tmp/archive/'
1293- >>> upgrade_dir = (
1294- ... 'ubuntutest/dists/breezy-autotest/main/dist-upgrader-all')
1295- >>> target_dir = os.path.join(archive_dir, upgrade_dir)
1296- >>> content = sorted(os.listdir(target_dir))
1297- >>> content
1298- ['20060302.0120', 'current']
1299-
1300-Check the content of the directories published and the integrity of
1301-the 'current' symbolic link.
1302-
1303- >>> real_path = os.path.join(target_dir, '20060302.0120')
1304- >>> current_path = os.path.join(target_dir, 'current')
1305-
1306- >>> os.path.islink(current_path)
1307- True
1308-
1309- >>> os.path.join(target_dir, os.readlink(current_path)) == real_path
1310- True
1311-
1312- >>> sorted(os.listdir(real_path))
1313- ['ReleaseAnouncement', 'dapper.tar.gz']
1314-
1315-
1316-Pre-publication version checks
1317-------------------------------
1318-
1319-Dist-Upgrader version is checked before installing any files in the
1320-archive.
1321-
1322-If any problem happen during the custom publication, the error will be
1323-printed and the queue item will remain in ACCEPTED queue waiting for
1324-manual intervention.
1325-
1326- >>> insecure_policy = getPolicy(
1327- ... name='insecure', distro='ubuntutest', distroseries=None)
1328-
1329- >>> upload = NascentUpload.from_changesfile_path(
1330- ... datadir('dist-upgrader/dist-upgrader_20070219.1234_all.changes'),
1331- ... insecure_policy, FakeLogger())
1332- DEBUG Verifying signature on dist-upgrader_20070219.1234_all.changes
1333-
1334- >>> upload.process()
1335- DEBUG Beginning processing.
1336- DEBUG Verifying the changes file.
1337- DEBUG Verifying files in upload.
1338- DEBUG Single Custom Upload detected.
1339- DEBUG Finished checking upload.
1340-
1341- >>> success = upload.do_accept()
1342- DEBUG Creating queue entry
1343- DEBUG Setting it to ACCEPTED
1344- DEBUG Building recipients list.
1345- ...
1346- DEBUG Adding recipient: 'Foo Bar <foo.bar@canonical.com>'
1347- DEBUG Sent a mail:
1348- ...
1349- DEBUG signer of the above package.
1350-
1351-Make the just-uploaded librarian file visible:
1352-
1353- >>> transaction.commit()
1354-
1355-Check current archive status:
1356-
1357- >>> previous_content = sorted(os.listdir(target_dir))
1358- >>> previous_content
1359- ['20060302.0120', 'current']
1360-
1361-Publish the custom upload:
1362-
1363- >>> pub_records = upload.queue_root.realiseUpload(FakeLogger())
1364- DEBUG Publishing custom dist-upgrader_20070219.1234_all.tar.gz to
1365- ubuntutest/breezy-autotest
1366- ERROR Queue item ignored: bad version found in
1367- '.../dist-upgrader_20070219.1234_all.tar.gz': Could not parse version: Bad
1368- upstream version format foobar
1369-
1370-Check if the queue item remained in ACCEPTED and not cruft was
1371-inserted in the archive:
1372-
1373- >>> upload.queue_root.status.name
1374- 'ACCEPTED'
1375-
1376- >>> content = sorted(os.listdir(target_dir))
1377- >>> content == previous_content
1378- True
1379-
1380-Remove the directory to keep the test working.
1381-
1382- >>> import shutil
1383- >>> shutil.rmtree(target_dir)
1384-
1385-
1386-Dist Upgrader to PPA
1387---------------------
1388-
1389-Custom uploads for PPAs should work as expected, i.e, publish its
1390-files in the respective PPA location.
1391-
1392- >>> from lp.registry.interfaces.person import IPersonSet
1393- >>> from lp.soyuz.enums import ArchivePurpose
1394- >>> from lp.soyuz.interfaces.archive import IArchiveSet
1395-
1396- >>> name16 = getUtility(IPersonSet).getByName("name16")
1397- >>> foobar_archive = getUtility(IArchiveSet).new(
1398- ... distribution=ubuntutest, purpose=ArchivePurpose.PPA,
1399- ... owner=name16)
1400-
1401- >>> insecure_policy.archive = foobar_archive
1402-
1403- >>> ppa_upload = NascentUpload.from_changesfile_path(
1404- ... datadir('dist-upgrader/dist-upgrader_20060302.0120_all.changes'),
1405- ... insecure_policy, FakeLogger())
1406- DEBUG Verifying signature on dist-upgrader_20060302.0120_all.changes
1407-
1408- >>> ppa_upload.process()
1409- DEBUG Beginning processing.
1410- DEBUG Verifying the changes file.
1411- DEBUG Verifying files in upload.
1412- DEBUG Single Custom Upload detected.
1413- DEBUG Finished checking upload.
1414-
1415- >>> success = ppa_upload.do_accept()
1416- DEBUG Creating queue entry
1417- DEBUG Setting it to ACCEPTED
1418- DEBUG Building recipients list.
1419- DEBUG Adding recipient: 'Foo Bar <foo.bar@canonical.com>'
1420- DEBUG Sent a mail:
1421- ...
1422- DEBUG PPA package.
1423-
1424- >>> transaction.commit()
1425-
1426-The upload task requires that the umask be 022, otherwise things will end up
1427-with the wrong permission.
1428-
1429- >>> old_mask = os.umask(022)
1430- >>> pub_records = ppa_upload.queue_root.realiseUpload(FakeLogger())
1431- DEBUG Publishing custom dist-upgrader_20060302.0120_all.tar.gz to
1432- ubuntutest/breezy-autotest
1433- >>> ignore = os.umask(old_mask)
1434-
1435- >>> ppa_root = config.personalpackagearchive.root
1436- >>> ppa_dir = os.path.join(ppa_root, 'name16', 'ppa')
1437- >>> target_dir = os.path.join(ppa_dir, upgrade_dir)
1438- >>> content = sorted(os.listdir(target_dir))
1439- >>> content
1440- ['20060302.0120', 'current']
1441-
1442-Remove the directory to keep the test working.
1443-
1444- >>> import shutil
1445- >>> shutil.rmtree(target_dir)
1446
1447=== added file 'lib/lp/soyuz/tests/test_distroseriesqueue_ddtp_tarball.py'
1448--- lib/lp/soyuz/tests/test_distroseriesqueue_ddtp_tarball.py 1970-01-01 00:00:00 +0000
1449+++ lib/lp/soyuz/tests/test_distroseriesqueue_ddtp_tarball.py 2012-05-25 13:49:22 +0000
1450@@ -0,0 +1,104 @@
1451+# Copyright 2012 Canonical Ltd. This software is licensed under the
1452+# GNU Affero General Public License version 3 (see the file LICENSE).
1453+
1454+"""Test upload and queue manipulation of DDTP tarballs.
1455+
1456+DDTP (Debian Description Translation Project) uploads consist of a tarball
1457+containing translations of package descriptions for a component. These
1458+translations should be published in the Ubuntu archive under the
1459+dists/SUITE/COMPONENT/i18n/ directory.
1460+
1461+ https://wiki.ubuntu.com/TranslatedPackageDescriptionsSpec
1462+
1463+See also lp.archivepublisher.tests.test_ddtp_tarball for detailed tests of
1464+ddtp-tarball extraction.
1465+"""
1466+
1467+import os
1468+
1469+import transaction
1470+
1471+from lp.archiveuploader.nascentupload import (
1472+ EarlyReturnUploadError,
1473+ NascentUpload,
1474+ )
1475+from lp.archiveuploader.tests import (
1476+ datadir,
1477+ getPolicy,
1478+ )
1479+from lp.services.log.logger import DevNullLogger
1480+from lp.soyuz.scripts.queue import (
1481+ CommandRunner,
1482+ name_queue_map,
1483+ )
1484+from lp.soyuz.tests.test_publishing import TestNativePublishingBase
1485+from lp.testing.gpgkeys import import_public_test_keys
1486+
1487+
1488+class TestDistroSeriesQueueDdtpTarball(TestNativePublishingBase):
1489+
1490+ def setUp(self):
1491+ super(TestDistroSeriesQueueDdtpTarball, self).setUp()
1492+ import_public_test_keys()
1493+ # CustomUpload.installFiles requires a umask of 022.
1494+ old_umask = os.umask(022)
1495+ self.addCleanup(os.umask, old_umask)
1496+ self.anything_policy = getPolicy(
1497+ name="anything", distro="ubuntutest", distroseries=None)
1498+ self.absolutely_anything_policy = getPolicy(
1499+ name="absolutely-anything", distro="ubuntutest", distroseries=None)
1500+ self.logger = DevNullLogger()
1501+
1502+ def test_rejects_misspelled_changesfile_name(self):
1503+ upload = NascentUpload.from_changesfile_path(
1504+ datadir("ddtp-tarball/translations-main_20060728.changes"),
1505+ self.absolutely_anything_policy, self.logger)
1506+ self.assertRaises(EarlyReturnUploadError, upload.process)
1507+
1508+ def uploadTestData(self, version):
1509+ upload = NascentUpload.from_changesfile_path(
1510+ datadir("ddtp-tarball/translations-main_%s_all.changes" % version),
1511+ self.anything_policy, self.logger)
1512+ upload.process()
1513+ self.assertFalse(upload.is_rejected)
1514+ self.assertTrue(upload.do_accept())
1515+ self.assertFalse(upload.rejection_message)
1516+ return upload
1517+
1518+ def test_accepts_correct_upload(self):
1519+ self.uploadTestData("20060728")
1520+
1521+ def runQueueCommand(self, queue_name, args):
1522+ def null_display(text):
1523+ pass
1524+
1525+ queue = name_queue_map[queue_name]
1526+ runner = CommandRunner(
1527+ queue, "ubuntutest", "breezy-autotest", True, None, None, None,
1528+ display=null_display)
1529+ runner.execute(args)
1530+
1531+ def test_queue_tool_behaviour(self):
1532+ # The queue tool can fetch ddtp-tarball uploads.
1533+ self.uploadTestData("20060728")
1534+ # Make sure that we can use the librarian files.
1535+ transaction.commit()
1536+ # Fetch upload into a temporary directory.
1537+ self.useTempDir()
1538+ self.runQueueCommand("accepted", ["fetch", "trans"])
1539+ expected_entries = [
1540+ "translations-main_20060728_all.changes",
1541+ "translations_main_20060728.tar.gz",
1542+ ]
1543+ self.assertContentEqual(expected_entries, os.listdir("."))
1544+
1545+ def test_publish(self):
1546+ upload = self.uploadTestData("20060728")
1547+ transaction.commit()
1548+ upload.queue_root.realiseUpload(self.logger)
1549+ target_dir = os.path.join(
1550+ self.config.distroroot, "ubuntutest", "dists", "breezy-autotest",
1551+ "main", "i18n")
1552+ # In this high-level test, we only care that something was unpacked.
1553+ self.assertTrue([name for name in os.listdir(target_dir)
1554+ if name.startswith("Translation-")])
1555
1556=== added file 'lib/lp/soyuz/tests/test_distroseriesqueue_debian_installer.py'
1557--- lib/lp/soyuz/tests/test_distroseriesqueue_debian_installer.py 1970-01-01 00:00:00 +0000
1558+++ lib/lp/soyuz/tests/test_distroseriesqueue_debian_installer.py 2012-05-25 13:49:22 +0000
1559@@ -0,0 +1,74 @@
1560+# Copyright 2012 Canonical Ltd. This software is licensed under the
1561+# GNU Affero General Public License version 3 (see the file LICENSE).
1562+
1563+"""Test upload and queue manipulation of debian-installer custom uploads.
1564+
1565+See also lp.archivepublisher.tests.test_debian_installer for detailed tests
1566+of debian-installer custom upload extraction.
1567+"""
1568+
1569+import os
1570+
1571+import transaction
1572+
1573+from lp.archivepublisher.debian_installer import DebianInstallerAlreadyExists
1574+from lp.archiveuploader.nascentupload import NascentUpload
1575+from lp.archiveuploader.tests import (
1576+ datadir,
1577+ getPolicy,
1578+ )
1579+from lp.services.log.logger import DevNullLogger
1580+from lp.services.mail import stub
1581+from lp.soyuz.tests.test_publishing import TestNativePublishingBase
1582+from lp.testing.gpgkeys import import_public_test_keys
1583+
1584+
1585+class TestDistroSeriesQueueDebianInstaller(TestNativePublishingBase):
1586+
1587+ def setUp(self):
1588+ super(TestDistroSeriesQueueDebianInstaller, self).setUp()
1589+ import_public_test_keys()
1590+ # CustomUpload.installFiles requires a umask of 022.
1591+ old_umask = os.umask(022)
1592+ self.addCleanup(os.umask, old_umask)
1593+ self.anything_policy = getPolicy(
1594+ name="anything", distro="ubuntutest", distroseries=None)
1595+ self.logger = DevNullLogger()
1596+
1597+ def uploadTestData(self):
1598+ upload = NascentUpload.from_changesfile_path(
1599+ datadir(
1600+ "debian-installer/"
1601+ "debian-installer_20070214ubuntu1_i386.changes"),
1602+ self.anything_policy, self.logger)
1603+ upload.process()
1604+ self.assertFalse(upload.is_rejected)
1605+ self.assertTrue(upload.do_accept())
1606+ self.assertFalse(upload.rejection_message)
1607+ return upload
1608+
1609+ def test_accepts_correct_upload(self):
1610+ upload = self.uploadTestData()
1611+ self.assertEqual(1, upload.queue_root.customfiles.count())
1612+
1613+ def test_generates_mail(self):
1614+ # Two e-mail messages were generated (acceptance and announcement).
1615+ self.anything_policy.setDistroSeriesAndPocket("hoary-test")
1616+ self.anything_policy.distroseries.changeslist = "announce@example.com"
1617+ self.uploadTestData()
1618+ self.assertEqual(2, len(stub.test_emails))
1619+
1620+ def test_bad_upload_remains_in_accepted(self):
1621+ # Bad debian-installer uploads remain in accepted. Simulate an
1622+ # on-disk conflict to force an error.
1623+ upload = self.uploadTestData()
1624+ # Make sure that we can use the librarian files.
1625+ transaction.commit()
1626+ os.makedirs(os.path.join(
1627+ self.config.distroroot, "ubuntutest", "dists", "hoary-test",
1628+ "main", "installer-i386", "20070214ubuntu1"))
1629+ self.assertFalse(upload.queue_root.realiseUpload(self.logger))
1630+ self.assertRaises(
1631+ DebianInstallerAlreadyExists,
1632+ upload.queue_root.customfiles[0].publish, self.logger)
1633+ self.assertEqual("ACCEPTED", upload.queue_root.status.name)
1634
1635=== added file 'lib/lp/soyuz/tests/test_distroseriesqueue_dist_upgrader.py'
1636--- lib/lp/soyuz/tests/test_distroseriesqueue_dist_upgrader.py 1970-01-01 00:00:00 +0000
1637+++ lib/lp/soyuz/tests/test_distroseriesqueue_dist_upgrader.py 2012-05-25 13:49:22 +0000
1638@@ -0,0 +1,133 @@
1639+# Copyright 2012 Canonical Ltd. This software is licensed under the
1640+# GNU Affero General Public License version 3 (see the file LICENSE).
1641+
1642+"""Test upload and queue manipulation of dist-upgrader tarballs.
1643+
1644+See also lp.archivepublisher.tests.test_dist_upgrader for detailed tests of
1645+dist-upgrader tarball extraction.
1646+"""
1647+
1648+import os
1649+import shutil
1650+
1651+import transaction
1652+
1653+from lp.archivepublisher.dist_upgrader import DistUpgraderBadVersion
1654+from lp.archiveuploader.nascentupload import (
1655+ EarlyReturnUploadError,
1656+ NascentUpload,
1657+ )
1658+from lp.archiveuploader.tests import (
1659+ datadir,
1660+ getPolicy,
1661+ )
1662+from lp.services.config import config
1663+from lp.services.log.logger import DevNullLogger
1664+from lp.soyuz.scripts.queue import (
1665+ CommandRunner,
1666+ name_queue_map,
1667+ )
1668+from lp.soyuz.tests.test_publishing import TestNativePublishingBase
1669+from lp.testing.gpgkeys import import_public_test_keys
1670+
1671+
1672+class TestDistroSeriesQueueDistUpgrader(TestNativePublishingBase):
1673+
1674+ def setUp(self):
1675+ super(TestDistroSeriesQueueDistUpgrader, self).setUp()
1676+ import_public_test_keys()
1677+ # CustomUpload.installFiles requires a umask of 022.
1678+ old_umask = os.umask(022)
1679+ self.addCleanup(os.umask, old_umask)
1680+ self.anything_policy = getPolicy(
1681+ name="anything", distro="ubuntutest", distroseries=None)
1682+ self.absolutely_anything_policy = getPolicy(
1683+ name="absolutely-anything", distro="ubuntutest", distroseries=None)
1684+ self.logger = DevNullLogger()
1685+
1686+ def tearDown(self):
1687+ super(TestDistroSeriesQueueDistUpgrader, self).tearDown()
1688+ if os.path.exists(config.personalpackagearchive.root):
1689+ shutil.rmtree(config.personalpackagearchive.root)
1690+
1691+ def test_rejects_misspelled_changesfile_name(self):
1692+ upload = NascentUpload.from_changesfile_path(
1693+ datadir("dist-upgrader/dist-upgrader_20060302.0120.changes"),
1694+ self.absolutely_anything_policy, self.logger)
1695+ self.assertRaises(EarlyReturnUploadError, upload.process)
1696+
1697+ def uploadTestData(self, version):
1698+ upload = NascentUpload.from_changesfile_path(
1699+ datadir("dist-upgrader/dist-upgrader_%s_all.changes" % version),
1700+ self.anything_policy, self.logger)
1701+ upload.process()
1702+ self.assertFalse(upload.is_rejected)
1703+ self.assertTrue(upload.do_accept())
1704+ self.assertFalse(upload.rejection_message)
1705+ return upload
1706+
1707+ def test_accepts_correct_upload(self):
1708+ self.uploadTestData("20060302.0120")
1709+
1710+ def runQueueCommand(self, queue_name, args):
1711+ def null_display(text):
1712+ pass
1713+
1714+ queue = name_queue_map[queue_name]
1715+ runner = CommandRunner(
1716+ queue, "ubuntutest", "breezy-autotest", True, None, None, None,
1717+ display=null_display)
1718+ runner.execute(args)
1719+
1720+ def test_queue_tool_behaviour(self):
1721+ # The queue tool can accept, reject, and fetch dist-upgrader
1722+ # uploads. See bug #54649.
1723+ upload = self.uploadTestData("20060302.0120")
1724+ # Make sure that we can use the librarian files.
1725+ transaction.commit()
1726+ # Reject from accepted queue (unlikely, would normally be from
1727+ # unapproved or new).
1728+ self.runQueueCommand("accepted", ["reject", "dist"])
1729+ self.assertEqual("REJECTED", upload.queue_root.status.name)
1730+ # Accept from rejected queue (also unlikely, but only for testing).
1731+ self.runQueueCommand("rejected", ["accept", "dist"])
1732+ self.assertEqual("ACCEPTED", upload.queue_root.status.name)
1733+ # Fetch upload into a temporary directory.
1734+ self.useTempDir()
1735+ self.runQueueCommand("accepted", ["fetch", "dist"])
1736+ expected_entries = [
1737+ "dist-upgrader_20060302.0120_all.changes",
1738+ "dist-upgrader_20060302.0120_all.tar.gz",
1739+ ]
1740+ self.assertContentEqual(expected_entries, os.listdir("."))
1741+
1742+ def test_bad_upload_remains_in_accepted(self):
1743+ # Bad dist-upgrader uploads remain in ACCEPTED.
1744+ upload = self.uploadTestData("20070219.1234")
1745+ # Make sure that we can use the librarian files.
1746+ transaction.commit()
1747+ self.assertFalse(upload.queue_root.realiseUpload(self.logger))
1748+ self.assertEqual(1, upload.queue_root.customfiles.count())
1749+ self.assertRaises(
1750+ DistUpgraderBadVersion, upload.queue_root.customfiles[0].publish,
1751+ self.logger)
1752+ self.assertEqual("ACCEPTED", upload.queue_root.status.name)
1753+
1754+ def test_ppa_publishing_location(self):
1755+ # A PPA dist-upgrader upload is published to the right place.
1756+ archive = self.factory.makeArchive(distribution=self.ubuntutest)
1757+ self.anything_policy.archive = archive
1758+ ppa_upload = self.uploadTestData("20060302.0120")
1759+ ppa_upload = NascentUpload.from_changesfile_path(
1760+ datadir("dist-upgrader/dist-upgrader_20060302.0120_all.changes"),
1761+ self.anything_policy, self.logger)
1762+ ppa_upload.process()
1763+ self.assertTrue(ppa_upload.do_accept())
1764+ transaction.commit()
1765+ ppa_upload.queue_root.realiseUpload(self.logger)
1766+ ppa_root = config.personalpackagearchive.root
1767+ ppa_dir = os.path.join(ppa_root, archive.owner.name, archive.name)
1768+ target_dir = os.path.join(
1769+ ppa_dir, "ubuntutest/dists/breezy-autotest/main/dist-upgrader-all")
1770+ self.assertContentEqual(
1771+ ["20060302.0120", "current"], os.listdir(target_dir))
1772
1773=== modified file 'lib/lp/soyuz/tests/test_doc.py'
1774--- lib/lp/soyuz/tests/test_doc.py 2012-05-16 01:09:00 +0000
1775+++ lib/lp/soyuz/tests/test_doc.py 2012-05-25 13:49:22 +0000
1776@@ -77,24 +77,6 @@
1777 tearDown(test)
1778
1779
1780-def distroseriesqueueSetUp(test):
1781- setUp(test)
1782- # The test requires that the umask be set to 022, and in fact this comment
1783- # was made in irc on 13-Apr-2007:
1784- #
1785- # (04:29:18 PM) kiko: barry, cprov says that the local umask is controlled
1786- # enough for us to rely on it
1787- #
1788- # Setting it here reproduces the environment that the doctest expects.
1789- # Save the old umask so we can reset it in the tearDown().
1790- test.old_umask = os.umask(022)
1791-
1792-
1793-def distroseriesqueueTearDown(test):
1794- os.umask(test.old_umask)
1795- tearDown(test)
1796-
1797-
1798 def uploadQueueSetUp(test):
1799 lobotomize_stevea()
1800 test_dbuser = config.uploadqueue.dbuser
1801@@ -142,11 +124,6 @@
1802 setUp=setUp, tearDown=tearDown,
1803 layer=LaunchpadZopelessLayer
1804 ),
1805- 'distroseriesqueue-debian-installer.txt': LayeredDocFileSuite(
1806- '../doc/distroseriesqueue-debian-installer.txt',
1807- setUp=distroseriesqueueSetUp, tearDown=distroseriesqueueTearDown,
1808- layer=LaunchpadFunctionalLayer
1809- ),
1810 'closing-bugs-from-changelogs.txt': LayeredDocFileSuite(
1811 '../doc/closing-bugs-from-changelogs.txt',
1812 setUp=uploadQueueSetUp,