← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/zopeless-upload-notification-tests into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/zopeless-upload-notification-tests into lp:launchpad with lp:~cjwatson/launchpad/async-upload-notifications as a prerequisite.

Commit message:
Run package upload notification tests in Zopeless layers.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/zopeless-upload-notification-tests/+merge/270170

Run package upload notification tests in Zopeless layers.

Like https://code.launchpad.net/~cjwatson/launchpad/zopeless-branch-notification-tests/+merge/269950, but for uploads.  I moved a couple of security adapter tests from distroseriesqueue.txt into unit tests so that I could run the rest of that doctest in LaunchpadZopelessLayer.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/zopeless-upload-notification-tests into lp:launchpad.
=== modified file 'lib/lp/soyuz/browser/tests/distroseriesqueue-views.txt'
--- lib/lp/soyuz/browser/tests/distroseriesqueue-views.txt	2013-05-28 08:49:38 +0000
+++ lib/lp/soyuz/browser/tests/distroseriesqueue-views.txt	2015-09-04 12:46:52 +0000
@@ -260,6 +260,7 @@
     >>> from lp.soyuz.interfaces.component import IComponentSet
     >>> from lp.soyuz.model.component import ComponentSelection
     >>> from lp.testing.gpgkeys import import_public_test_keys
+    >>> from lp.testing.pages import permissive_security_policy
     >>> import_public_test_keys()
     >>> universe = getUtility(IComponentSet)['universe']
     >>> trash = ComponentSelection(distroseries=hoary, component=universe)
@@ -271,7 +272,8 @@
     ...    datadir('suite/foo_1.0-2_multi_binary/foo_1.0-2_i386.changes'),
     ...    sync_policy, DevNullLogger())
     >>> foo_upload.process()
-    >>> foo_upload.do_accept()
+    >>> with permissive_security_policy("uploader"):
+    ...     foo_upload.do_accept()
     True
 
 Now we can examine the view, which provides an is_new method:

=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-notify.txt'
--- lib/lp/soyuz/doc/distroseriesqueue-notify.txt	2015-08-25 14:05:24 +0000
+++ lib/lp/soyuz/doc/distroseriesqueue-notify.txt	2015-09-04 12:46:52 +0000
@@ -1,10 +1,7 @@
 Queue Notify
 ============
 
-PackageUpload has a notify() method to send emails. We need to be logged
-into the security model in order to get any further.
-
-    >>> login('foo.bar@xxxxxxxxxxxxx')
+PackageUpload has a notify() method to send emails.
 
 Get a packageupload object for netapplet, which has a relatively intact
 set of supporting sample data.  It has rows in distribution,

=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-translations.txt'
--- lib/lp/soyuz/doc/distroseriesqueue-translations.txt	2015-07-06 16:57:27 +0000
+++ lib/lp/soyuz/doc/distroseriesqueue-translations.txt	2015-09-04 12:46:52 +0000
@@ -33,9 +33,6 @@
     >>> from lp.soyuz.model.packagetranslationsuploadjob import (
     ...     PackageTranslationsUploadJob)
 
-# Login as an admin.
-    >>> login('foo.bar@xxxxxxxxxxxxx')
-
     # We need to setup our test environment and create the needed objects.
     >>> distro_series_set = getUtility(IDistroSeriesSet)
     >>> ubuntu = getUtility(IDistributionSet)['ubuntu']

=== modified file 'lib/lp/soyuz/doc/distroseriesqueue.txt'
--- lib/lp/soyuz/doc/distroseriesqueue.txt	2015-09-04 12:46:52 +0000
+++ lib/lp/soyuz/doc/distroseriesqueue.txt	2015-09-04 12:46:52 +0000
@@ -46,14 +46,6 @@
 
     >>> from lp.archiveuploader.nascentupload import NascentUpload
     >>> from lp.archiveuploader.tests import datadir, getPolicy
-
-Since we landed correct security adapters for PackageUpload,
-we need to perform further actions logged in as an admins, which have
-launchpad.Edit on the records:
-
-    >>> from lp.testing import login
-    >>> login("foo.bar@xxxxxxxxxxxxx")
-
     >>> from lp.registry.interfaces.distribution import IDistributionSet
     >>> from lp.soyuz.interfaces.component import IComponentSet
     >>> from lp.soyuz.model.component import ComponentSelection
@@ -317,12 +309,11 @@
 
 Move the ACCEPTED items back to NEW.
 
-    >>> from zope.security.proxy import removeSecurityProxy
     >>> from lp.soyuz.model.queue import PassthroughStatusValue
-    >>> items = breezy_autotest.getPackageUploads(PackageUploadStatus.ACCEPTED)
+    >>> items = breezy_autotest.getPackageUploads(
+    ...     PackageUploadStatus.ACCEPTED)
     >>> for item in items:
-    ...     removeSecurityProxy(item).status = PassthroughStatusValue(
-    ...         PackageUploadStatus.NEW)
+    ...     item.status = PassthroughStatusValue(PackageUploadStatus.NEW)
     ...     print item.displayname, item.status.name
     netapplet-1.0.0.tar.gz NEW
     netapplet-1.0.0.tar.gz NEW
@@ -339,8 +330,7 @@
     >>> test_qitem.setUnapproved()
     >>> test_qitem.setRejected()
     >>> test_qitem.setDone()
-    >>> removeSecurityProxy(test_qitem).status = PassthroughStatusValue(
-    ...     PackageUploadStatus.NEW)
+    >>> test_qitem.status = PassthroughStatusValue(PackageUploadStatus.NEW)
 
 Check forbidden approval of not selected Section:
 
@@ -356,6 +346,7 @@
 
 XXX cprov 20060118: remove proxy magic is required for BPR instances.
 
+    >>> from zope.security.proxy import removeSecurityProxy
     >>> naked_bin = removeSecurityProxy(
     ...       item.builds[0].build.binarypackages[0])
     >>> naked_bin.component = getUtility(IComponentSet).new('hell')
@@ -416,7 +407,7 @@
 Move the second item back to its original queue to perform the same
 test after the former accepted item was published (DONE queue)
 
-    >>> removeSecurityProxy(dup_two).status = PassthroughStatusValue(
+    >>> dup_two.status = PassthroughStatusValue(
     ...     PackageUploadStatus.UNAPPROVED)
     >>> dup_two.syncUpdate()
     >>> dup_two.status.name
@@ -459,58 +450,6 @@
     >>> print item.status.name
     ACCEPTED
 
-We will reject the just-accepted entry so it does not mess with the
-other tests.
-
-    >>> item.setRejected()
-
-Check how the security adapters work for PackageUpload:
-
-    >>> pub_qitem = getUtility(IPackageUploadSet)[1]
-
-UNAPPROVED queue items are expected to be private:
-
-    >>> priv_qitem = getUtility(IPackageUploadSet)[5]
-
-Anonymous can view all queue items, public and private ones.
-
-    >>> login(ANONYMOUS)
-
-    >>> pub_qitem.displayname
-    u'mozilla-firefox'
-
-    >>> priv_qitem.displayname
-    u'netapplet-1.0.0.tar.gz'
-
-A normal user can't act on both of them:
-
-    >>> login('no-priv@xxxxxxxxxxxxx')
-
-    >>> pub_qitem.setDone()
-    Traceback (most recent call last):
-    ...
-    Unauthorized: (<PackageUpload ..., 'setDone', 'launchpad.Edit')
-
-    >>> priv_qitem.setDone()
-    Traceback (most recent call last):
-    ...
-    Unauthorized: (<PackageUpload ..., 'setDone', 'launchpad.Edit')
-
-Only the members of distroseries drivers in question have
-launchpad.Edit on a packageupload record.
-
-    >>> login('foo.bar@xxxxxxxxxxxxx')
-
-    >>> pub_qitem.displayname
-    u'mozilla-firefox'
-
-    >>> priv_qitem.displayname
-    u'netapplet-1.0.0.tar.gz'
-
-    >>> pub_qitem.setDone()
-
-    >>> priv_qitem.setDone()
-
 Roll back modified data:
 
     >>> transaction.abort()

=== modified file 'lib/lp/soyuz/tests/test_build_notify.py'
--- lib/lp/soyuz/tests/test_build_notify.py	2015-07-14 10:57:46 +0000
+++ lib/lp/soyuz/tests/test_build_notify.py	2015-09-04 12:46:52 +0000
@@ -23,7 +23,8 @@
     person_logged_in,
     TestCaseWithFactory,
     )
-from lp.testing.layers import LaunchpadFunctionalLayer
+from lp.testing.dbuser import dbuser
+from lp.testing.layers import LaunchpadZopelessLayer
 from lp.testing.mail_helpers import pop_notifications
 from lp.testing.sampledata import ADMIN_EMAIL
 
@@ -44,7 +45,7 @@
 
 class TestBuildNotify(TestCaseWithFactory):
 
-    layer = LaunchpadFunctionalLayer
+    layer = LaunchpadZopelessLayer
 
     def setUp(self):
         super(TestBuildNotify, self).setUp()
@@ -188,7 +189,8 @@
         # admins and the source package creator.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.FAILEDTOBUILD.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -199,7 +201,8 @@
         # and the archive owner, but not the buildd admins.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.FAILEDTOBUILD.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -211,7 +214,8 @@
         # be built.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.NEEDSBUILD.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -222,7 +226,8 @@
         # to be built.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.NEEDSBUILD.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -233,7 +238,8 @@
         # Successful builds don't notify anyone.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.FULLYBUILT.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         self.assertEqual([], pop_notifications())
 
     def test_notify_dependency_wait(self):
@@ -241,7 +247,8 @@
         # find a dependency.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.MANUALDEPWAIT.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -252,7 +259,8 @@
         # can't find a dependency.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.MANUALDEPWAIT.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -264,7 +272,8 @@
         # build attempted to be built on has an internal problem.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.CHROOTWAIT.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -275,7 +284,8 @@
         # build attempted to be built on has an internal problem.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.CHROOTWAIT.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -288,7 +298,8 @@
         # chance to be dispatched.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.SUPERSEDED.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -300,7 +311,8 @@
         # chance to be dispatched.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.SUPERSEDED.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -312,7 +324,8 @@
         # currently building.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.BUILDING.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -323,7 +336,8 @@
         # currently building.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.BUILDING.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -335,7 +349,8 @@
         # completed, and binary packages are being uploaded by the builder.
         self.create_builds(self.archive)
         build = self.builds[BuildStatus.UPLOADING.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))
@@ -346,7 +361,8 @@
         # completed, and binary packages are being uploaded by the builder.
         self.create_builds(self.ppa)
         build = self.builds[BuildStatus.UPLOADING.value]
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (self.creator, "signer"),
             (self.ppa.owner, "owner"),
@@ -362,7 +378,8 @@
         ppa_spph = spph.copyTo(
             self.distroseries, PackagePublishingPocket.RELEASE, self.ppa)
         [ppa_build] = ppa_spph.createMissingBuilds()
-        ppa_build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            ppa_build.notify()
         self._assert_mails_are_correct(
             ppa_build, [(self.ppa.owner, "owner")], ppa=True)
 
@@ -377,7 +394,8 @@
             notify_owner: False
             """)
         config.push('notify_owner', notify_owner)
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         self._assert_mails_are_correct(
             build,
             [(person, "buildd-admin")
@@ -395,7 +413,8 @@
             send_build_notification: False
             """)
         config.push('send_build_notification', send_build_notification)
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         notifications = pop_notifications()
         self.assertEqual(0, len(notifications))
         # And undo what we just did.
@@ -411,7 +430,8 @@
         spr = build.current_source_publication.sourcepackagerelease
         # Push past the security proxy
         removeSecurityProxy(spr).dscsigningkey = key
-        build.notify()
+        with dbuser(config.builddmaster.dbuser):
+            build.notify()
         expected_reasons = [
             (person, "buildd-admin") for person in self.buildd_admins_members]
         expected_reasons.append((self.creator, "creator"))

=== modified file 'lib/lp/soyuz/tests/test_doc.py'
--- lib/lp/soyuz/tests/test_doc.py	2014-11-06 02:11:23 +0000
+++ lib/lp/soyuz/tests/test_doc.py	2015-09-04 12:46:52 +0000
@@ -134,6 +134,26 @@
         setUp=setUp,
         layer=LaunchpadZopelessLayer,
         ),
+    'build-failedtoupload-workflow.txt': LayeredDocFileSuite(
+        '../doc/build-failedtoupload-workflow.txt',
+        setUp=setUp, tearDown=tearDown,
+        layer=LaunchpadZopelessLayer,
+        ),
+    'distroseriesqueue.txt': LayeredDocFileSuite(
+        '../doc/distroseriesqueue.txt',
+        setUp=setUp, tearDown=tearDown,
+        layer=LaunchpadZopelessLayer,
+        ),
+    'distroseriesqueue-notify.txt': LayeredDocFileSuite(
+        '../doc/distroseriesqueue-notify.txt',
+        setUp=setUp, tearDown=tearDown,
+        layer=LaunchpadZopelessLayer,
+        ),
+    'distroseriesqueue-translations.txt': LayeredDocFileSuite(
+        '../doc/distroseriesqueue-translations.txt',
+        setUp=setUp, tearDown=tearDown,
+        layer=LaunchpadZopelessLayer,
+        ),
     }
 
 

=== modified file 'lib/lp/soyuz/tests/test_packageupload.py'
--- lib/lp/soyuz/tests/test_packageupload.py	2015-09-04 12:46:52 +0000
+++ lib/lp/soyuz/tests/test_packageupload.py	2015-09-04 12:46:52 +0000
@@ -366,7 +366,7 @@
             stub.test_emails[0][-1])
 
 
-class TestPackageUploadPrivacy(TestCaseWithFactory):
+class TestPackageUploadSecurity(TestCaseWithFactory):
     """Test PackageUpload security."""
 
     layer = LaunchpadFunctionalLayer
@@ -384,6 +384,25 @@
             self.assertRaises(
                 ZopeUnauthorized, getattr, upload, "contains_source")
 
+    def test_non_queue_admin_cannot_edit_upload(self):
+        upload = self.factory.makePackageUpload()
+        with admin_logged_in():
+            upload.addSource(
+                self.factory.makeSourcePackageRelease(component="main"))
+        with person_logged_in(self.factory.makePerson()):
+            self.assertRaises(ZopeUnauthorized, getattr, upload, "setDone")
+
+    def test_queue_admin_can_edit_upload(self):
+        archive = self.factory.makeArchive()
+        queue_admin = self.factory.makePerson()
+        with admin_logged_in():
+            archive.newQueueAdmin(queue_admin, "main")
+            upload = self.factory.makePackageUpload(archive=archive)
+            upload.addSource(
+                self.factory.makeSourcePackageRelease(component="main"))
+        with person_logged_in(queue_admin):
+            upload.setDone()
+
 
 class TestPackageUploadWithPackageCopyJob(TestCaseWithFactory):
 


Follow ups