launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02504
[Merge] lp:~gary/launchpad/bug548-db-2-tests into lp:launchpad/db-devel
Gary Poster has proposed merging lp:~gary/launchpad/bug548-db-2-tests into lp:launchpad/db-devel with lp:~gary/launchpad/bug548-db-2 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~gary/launchpad/bug548-db-2-tests/+merge/48570
This branch fixes tests that failed on ~gary/launchpad/bug548-db-2
I added a test tool because I was doing the same thing over and over again, and other tests I was touch were too.
I'm not entirely satisfied with the test helper--tests for it would be nice, for instance, and I wonder if it should hang off the Layer, and so on--but this is an improvement at least.
I would love to get this landed before pqm early my tomorrow morning, and would be happy to promise to make a branch to fix review comments afterwards (that is, first thing tomorrow morning) if that is acceptable.
Thank you
--
https://code.launchpad.net/~gary/launchpad/bug548-db-2-tests/+merge/48570
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gary/launchpad/bug548-db-2-tests into lp:launchpad/db-devel.
=== removed directory 'lib/canonical/widgets'
=== removed file 'lib/canonical/widgets/__init__.py'
--- lib/canonical/widgets/__init__.py 2011-02-02 21:39:04 +0000
+++ lib/canonical/widgets/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
-
-# This is a stub to keep canonical.shipit operational. this module
-# can delete when shipit is independent.
-
-from lp.app.widgets.itemswidgets import (
- CheckBoxMatrixWidget,
- LabeledMultiCheckBoxWidget,
- )
-
-
=== modified file 'lib/lp/archivepublisher/tests/publishing-meta-data-files.txt'
--- lib/lp/archivepublisher/tests/publishing-meta-data-files.txt 2010-12-22 20:46:21 +0000
+++ lib/lp/archivepublisher/tests/publishing-meta-data-files.txt 2011-02-04 02:39:17 +0000
@@ -17,9 +17,11 @@
>>> from lp.soyuz.enums import PackageUploadCustomFormat
>>> from lp.soyuz.interfaces.publishing import PackagePublishingPocket
>>> from lp.soyuz.model.queue import PackageUploadCustom
+ >>> from lp.testing.dbuser import lp_dbuser
>>> bat = getUtility(IDistributionSet)['ubuntutest']['breezy-autotest']
- >>> ppa = factory.makeArchive(distribution=bat.distribution)
+ >>> with lp_dbuser():
+ ... ppa = factory.makeArchive(distribution=bat.distribution)
>>> package_upload = bat.createQueueEntry(
... pocket=PackagePublishingPocket.RELEASE, changesfilename="test",
... changesfilecontent="test",
=== modified file 'lib/lp/archivepublisher/tests/test_dominator.py'
--- lib/lp/archivepublisher/tests/test_dominator.py 2010-10-17 13:35:20 +0000
+++ lib/lp/archivepublisher/tests/test_dominator.py 2011-02-04 02:39:17 +0000
@@ -13,6 +13,7 @@
from lp.registry.interfaces.series import SeriesStatus
from lp.soyuz.enums import PackagePublishingStatus
from lp.soyuz.tests.test_publishing import TestNativePublishingBase
+from lp.testing.dbuser import lp_dbuser
class TestDominator(TestNativePublishingBase):
@@ -116,7 +117,8 @@
in an AssertionError), and shouldn't be directly considered for
superseding either.
"""
- ppa = self.factory.makeArchive()
+ with lp_dbuser():
+ ppa = self.factory.makeArchive()
foo_10_source, foo_10_binaries = self.createSourceAndBinaries(
'1.0', with_debug=True, archive=ppa)
foo_11_source, foo_11_binaries = self.createSourceAndBinaries(
=== modified file 'lib/lp/archivepublisher/tests/test_publisher.py'
--- lib/lp/archivepublisher/tests/test_publisher.py 2010-12-19 22:47:25 +0000
+++ lib/lp/archivepublisher/tests/test_publisher.py 2011-02-04 02:39:17 +0000
@@ -50,6 +50,7 @@
IArchiveSet,
)
from lp.soyuz.tests.test_publishing import TestNativePublishingBase
+from lp.testing.dbuser import lp_dbuser
class TestPublisherBase(TestNativePublishingBase):
@@ -475,7 +476,8 @@
# status of DELETING.
ubuntu = getUtility(IDistributionSet)['ubuntu']
- archive = self.factory.makeArchive()
+ with lp_dbuser():
+ archive = self.factory.makeArchive()
old_num_pending_archives = ubuntu.getPendingPublicationPPAs().count()
archive.status = ArchiveStatus.DELETING
new_num_pending_archives = ubuntu.getPendingPublicationPPAs().count()
@@ -1039,9 +1041,10 @@
def testHtaccessForPrivatePPA(self):
# A htaccess file is created for new private PPA's.
- ppa = self.factory.makeArchive(
- distribution=self.ubuntutest, private=True)
- ppa.buildd_secret = "geheim"
+ with lp_dbuser():
+ ppa = self.factory.makeArchive(
+ distribution=self.ubuntutest, private=True)
+ ppa.buildd_secret = "geheim"
# Setup the publisher for it and publish its repository.
archive_publisher = getPublisher(ppa, [], self.logger)
=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
--- lib/lp/bugs/doc/bugnotification-sending.txt 2011-02-04 02:39:16 +0000
+++ lib/lp/bugs/doc/bugnotification-sending.txt 2011-02-04 02:39:17 +0000
@@ -30,20 +30,9 @@
... print email_notification.get_payload(decode=True)
... print "-" * 70
-We'll also define some helper functions to help us with database users.
-
- >>> from canonical.config import config
- >>> from canonical.database.sqlbase import commit
- >>> from canonical.testing.layers import LaunchpadZopelessLayer
-
- >>> def switch_db_to_launchpad():
- ... commit()
- ... LaunchpadZopelessLayer.switchDbUser('launchpad')
-
- >>> def switch_db_to_bugnotification():
- ... commit()
- ... LaunchpadZopelessLayer.switchDbUser(
- ... config.malone.bugnotification_dbuser)
+We'll also import a helper function to help us with database users.
+
+ >>> from lp.testing.dbuser import lp_dbuser
You'll note that we are printing out an X-Launchpad-Message-Rationale
header. This header is a simple string that allows people to filter
@@ -356,16 +345,13 @@
... print member.preferredemail.email
marilize@xxxxxxx
- >>> switch_db_to_launchpad()
- >>> bug_one.subscribe(shipit_admins, shipit_admins)
- <...>
-
- >>> comment = getUtility(IMessageSet).fromText(
- ... 'subject', 'a comment.', sample_person,
- ... datecreated=ten_minutes_ago)
- >>> bug_one.addCommentNotification(comment)
-
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... ignored = bug_one.subscribe(shipit_admins, shipit_admins)
+ ... comment = getUtility(IMessageSet).fromText(
+ ... 'subject', 'a comment.', sample_person,
+ ... datecreated=ten_minutes_ago)
+ ... bug_one.addCommentNotification(comment)
+
>>> pending_notifications = getUtility(
... IBugNotificationSet).getNotificationsToSend()
>>> len(pending_notifications)
@@ -398,17 +384,15 @@
>>> params = CreateBugParams(
... msg=description, owner=sample_person, title='new bug')
- >>> switch_db_to_launchpad()
- >>> new_bug = ubuntu.createBug(params)
- >>> switch_db_to_bugnotification()
- >>> flush_notifications()
+ >>> with lp_dbuser():
+ ... new_bug = ubuntu.createBug(params)
If a bug is a duplicate of another bug, a marker gets inserted at the
top of the email:
- >>> switch_db_to_launchpad()
- >>> new_bug.markAsDuplicate(bug_one)
- >>> switch_db_to_bugnotification()
+ >>> flush_notifications()
+ >>> with lp_dbuser():
+ ... new_bug.markAsDuplicate(bug_one)
>>> comment = getUtility(IMessageSet).fromText(
... 'subject', 'a comment.', sample_person,
... datecreated=ten_minutes_ago)
@@ -474,12 +458,11 @@
... 'Zero-day on Frobulator', 'Woah.', sample_person,
... datecreated=ten_minutes_ago)
- >>> switch_db_to_launchpad()
- >>> sec_vuln_bug = ubuntu.createBug(CreateBugParams(
+ >>> with lp_dbuser():
+ ... sec_vuln_bug = ubuntu.createBug(CreateBugParams(
... msg=sec_vuln_description, owner=sample_person,
... title='Zero-day on Frobulator',
... security_related=True, private=True))
- >>> switch_db_to_bugnotification()
>>> sec_vuln_bug.security_related
True
@@ -730,10 +713,8 @@
The tags will be space-separated to allow the list to be wrapped if it
gets over-long.
- >>> switch_db_to_launchpad()
- >>> bug_three.tags = [u'layout-test', u'another-tag', u'yet-another']
-
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... bug_three.tags = [u'layout-test', u'another-tag', u'yet-another']
>>> bug_three = getUtility(IBugSet).get(3)
>>> for message in trigger_and_get_email_messages(bug_three):
@@ -743,15 +724,13 @@
If we remove the tags from the bug, the X-Launchpad-Bug-Tags header
won't be included.
- >>> switch_db_to_launchpad()
- >>> bug_three.tags = []
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... bug_three.tags = []
>>> bug_three = getUtility(IBugSet).get(3)
>>> for message in trigger_and_get_email_messages(bug_three):
... message.get_all('X-Launchpad-Bug-Tags')
- >>> switch_db_to_launchpad()
>>> #bug_three.unsubscribe(sample_person, sample_person)
@@ -771,7 +750,8 @@
Predictably, private bugs are sent with a slightly different header:
- >>> bug_three.setPrivate(True, sample_person)
+ >>> with lp_dbuser():
+ ... bug_three.setPrivate(True, sample_person)
True
>>> bug_three.private
True
@@ -799,7 +779,8 @@
The presence of the security flag on a bug is, surprise, denoted by a
simple "yes":
- >>> bug_three.setSecurityRelated(True)
+ >>> with lp_dbuser():
+ ... bug_three.setSecurityRelated(True)
True
>>> bug_three.security_related
True
@@ -824,9 +805,9 @@
>>> foo_bar = getUtility(IPersonSet).getByEmail('foo.bar@xxxxxxxxxxxxx')
>>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
- >>> getUtility(IBugMessageSet).createMessage(
- ... 'Hungry', bug_three, foo_bar, "Make me a sandwich.")
- <BugMessage ...>
+ >>> with lp_dbuser():
+ ... ignored = getUtility(IBugMessageSet).createMessage(
+ ... 'Hungry', bug_three, foo_bar, "Make me a sandwich.")
>>> for message in trigger_and_get_email_messages(bug_three):
... print message.get('X-Launchpad-Bug-Commenters')
@@ -835,9 +816,9 @@
It only lists each user once, no matter how many comments they've
made.
- >>> getUtility(IBugMessageSet).createMessage(
- ... 'Hungry', bug_three, foo_bar, "Make me a sandwich.")
- <BugMessage ...>
+ >>> with lp_dbuser():
+ ... ignored = getUtility(IBugMessageSet).createMessage(
+ ... 'Hungry', bug_three, foo_bar, "Make me a sandwich.")
>>> for message in trigger_and_get_email_messages(bug_three):
... print message.get('X-Launchpad-Bug-Commenters')
@@ -868,63 +849,58 @@
Concise Person does not. We'll also create teams and give them members
with different verbose_bugnotifications settings.
- >>> switch_db_to_launchpad()
- >>> bug = factory.makeBug(
- ... product=factory.makeProduct(title='Foo'),
- ... title='In the beginning, the universe was created. This '
- ... 'has made a lot of people very angry and has been '
- ... 'widely regarded as a bad move',
- ... description="This is a long description of the bug, which "
- ... "will be automatically wrapped by the BugNotification "
- ... "machinery. Ain't technology great?")
-
- >>> verbose_person = factory.makePerson(
- ... displayname='Verbose Person', email='verbose@xxxxxxxxxxx')
- >>> verbose_person.verbose_bugnotifications = True
- >>> bug.subscribe(verbose_person, verbose_person)
- <lp.bugs.model.bugsubscription.BugSubscription ...>
-
- >>> concise_person = factory.makePerson(
- ... displayname='Concise Person', email='concise@xxxxxxxxxxx')
- >>> concise_person.verbose_bugnotifications = False
- >>> bug.subscribe(concise_person, concise_person)
- <lp.bugs.model.bugsubscription.BugSubscription ...>
+ >>> with lp_dbuser():
+ ... bug = factory.makeBug(
+ ... product=factory.makeProduct(title='Foo'),
+ ... title='In the beginning, the universe was created. This '
+ ... 'has made a lot of people very angry and has been '
+ ... 'widely regarded as a bad move',
+ ... description="This is a long description of the bug, which "
+ ... "will be automatically wrapped by the BugNotification "
+ ... "machinery. Ain't technology great?")
+ ... verbose_person = factory.makePerson(
+ ... displayname='Verbose Person', email='verbose@xxxxxxxxxxx')
+ ... verbose_person.verbose_bugnotifications = True
+ ... ignored = bug.subscribe(verbose_person, verbose_person)
+ ... concise_person = factory.makePerson(
+ ... displayname='Concise Person', email='concise@xxxxxxxxxxx')
+ ... concise_person.verbose_bugnotifications = False
+ ... ignored = bug.subscribe(concise_person, concise_person)
Concise Team doesn't want verbose notifications, while Concise Team
Person, a member, does.
- >>> concise_team = factory.makeTeam(
- ... name='conciseteam', displayname='Concise Team')
- >>> concise_team.verbose_bugnotifications = False
- >>> concise_team_person = factory.makePerson(
- ... displayname='Concise Team Person',
- ... email='conciseteam@xxxxxxxxxxx')
- >>> concise_team_person.verbose_bugnotifications = True
- >>> ignored = concise_team.addMember(
- ... concise_team_person, concise_team_person)
- >>> bug.subscribe(concise_team, concise_team_person)
- <lp.bugs.model.bugsubscription.BugSubscription ...>
+ >>> with lp_dbuser():
+ ... concise_team = factory.makeTeam(
+ ... name='conciseteam', displayname='Concise Team')
+ ... concise_team.verbose_bugnotifications = False
+ ... concise_team_person = factory.makePerson(
+ ... displayname='Concise Team Person',
+ ... email='conciseteam@xxxxxxxxxxx')
+ ... concise_team_person.verbose_bugnotifications = True
+ ... ignored = concise_team.addMember(
+ ... concise_team_person, concise_team_person)
+ ... ignored = bug.subscribe(concise_team, concise_team_person)
Verbose Team wants verbose notifications, while Verbose Team Person, a
member, does not.
- >>> verbose_team = factory.makeTeam(
- ... name='verboseteam', displayname='Verbose Team')
- >>> verbose_team.verbose_bugnotifications = True
- >>> verbose_team_person = factory.makePerson(
- ... displayname='Verbose Team Person',
- ... email='verboseteam@xxxxxxxxxxx')
- >>> verbose_team_person.verbose_bugnotifications = False
- >>> ignored = verbose_team.addMember(
- ... verbose_team_person, verbose_team_person)
- >>> bug.subscribe(verbose_team, verbose_team_person)
- <lp.bugs.model.bugsubscription.BugSubscription ...>
+ >>> with lp_dbuser():
+ ... verbose_team = factory.makeTeam(
+ ... name='verboseteam', displayname='Verbose Team')
+ ... verbose_team.verbose_bugnotifications = True
+ ... verbose_team_person = factory.makePerson(
+ ... displayname='Verbose Team Person',
+ ... email='verboseteam@xxxxxxxxxxx')
+ ... verbose_team_person.verbose_bugnotifications = False
+ ... ignored = verbose_team.addMember(
+ ... verbose_team_person, verbose_team_person)
+ ... ignored = bug.subscribe(verbose_team, verbose_team_person)
We'll expire all existing notifications since we're not interested in
them:
- >>> switch_db_to_bugnotification()
>>> notifications = getUtility(
... IBugNotificationSet).getNotificationsToSend()
>>> len(notifications)
@@ -1105,8 +1081,6 @@
they generated. For now, everyone receives these notifications whether they
want them or not. However, we can show that the attribute exists for now.
- >>> flush_notifications()
- >>> switch_db_to_launchpad()
>>> verbose_person.selfgenerated_bugnotifications
True
@@ -1125,16 +1099,14 @@
notification level of the subscription.
>>> flush_notifications()
- >>> switch_db_to_launchpad()
>>> from lp.bugs.enum import BugNotificationLevel
>>> from lp.registry.interfaces.product import IProductSet
>>> firefox = getUtility(IProductSet).getByName('firefox')
>>> mr_no_privs = getUtility(IPersonSet).getByName('no-priv')
- >>> subscription_no_priv = firefox.addBugSubscription(
- ... mr_no_privs, mr_no_privs)
-
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... subscription_no_priv = firefox.addBugSubscription(
+ ... mr_no_privs, mr_no_privs)
The notifications generated by addCommentNotification() are sent only to
structural subscribers with no filters, or with the notification level
@@ -1200,10 +1172,9 @@
>>> flush_notifications()
- >>> switch_db_to_launchpad()
- >>> filter = subscription_no_priv.newBugFilter()
- >>> filter.bug_notification_level = BugNotificationLevel.COMMENTS
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... filter = subscription_no_priv.newBugFilter()
+ ... filter.bug_notification_level = BugNotificationLevel.COMMENTS
>>> comment = getUtility(IMessageSet).fromText(
... 'subject', 'another comment.', sample_person,
@@ -1261,9 +1232,8 @@
no comment notifications.
>>> flush_notifications()
- >>> switch_db_to_launchpad()
- >>> filter.bug_notification_level = BugNotificationLevel.METADATA
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... filter.bug_notification_level = BugNotificationLevel.METADATA
>>> comment = getUtility(IMessageSet).fromText(
... 'subject', 'no comment for no-priv.', sample_person,
@@ -1373,9 +1343,8 @@
no notifications created by addChangeNotification().
>>> flush_notifications()
- >>> switch_db_to_launchpad()
- >>> filter.bug_notification_level = BugNotificationLevel.LIFECYCLE
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... filter.bug_notification_level = BugNotificationLevel.LIFECYCLE
>>> bug_one.addChangeNotification('** Summary changed to: something.',
... sample_person, when=ten_minutes_ago)
@@ -1433,10 +1402,9 @@
after all.
>>> flush_notifications()
- >>> switch_db_to_launchpad()
- >>> filter2 = subscription_no_priv.newBugFilter()
- >>> filter2.bug_notification_level = BugNotificationLevel.METADATA
- >>> switch_db_to_bugnotification()
+ >>> with lp_dbuser():
+ ... filter2 = subscription_no_priv.newBugFilter()
+ ... filter2.bug_notification_level = BugNotificationLevel.METADATA
>>> bug_one.addChangeNotification('** Summary changed to: whatever.',
... sample_person, when=ten_minutes_ago)
=== added file 'lib/lp/testing/dbuser.py'
--- lib/lp/testing/dbuser.py 1970-01-01 00:00:00 +0000
+++ lib/lp/testing/dbuser.py 2011-02-04 02:39:17 +0000
@@ -0,0 +1,47 @@
+# Copyright 2011 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Provides a context manager to run parts of a test as a different dbuser."""
+
+__metaclass__ = type
+__all__ = [
+ 'dbuser',
+ 'lp_dbuser',
+ ]
+
+from contextlib import contextmanager
+
+from canonical.database.sqlbase import commit
+from canonical.testing.layers import LaunchpadZopelessLayer
+
+@contextmanager
+def dbuser(temporary_name, restore_name=None):
+ """A context manager that temporarily changes the dbuser.
+
+ Use with the LaunchpadZopelessLayer layer and subclasses.
+
+ temporary_name is the name of the dbuser that should be in place for the
+ code in the "with" block. restore_name is the name of the dbuser that
+ should be restored after the with block. If it is not supplied, the
+ dbuser currently set (as far as LaunchpadZopelessLayer knows) is used.
+ """
+ if restore_name is None:
+ restore_name = LaunchpadZopelessLayer.txn._dbuser
+ commit()
+ # Note that this will raise an assertion error if the
+ # LaunchpadZopelessLayer is not already set up.
+ LaunchpadZopelessLayer.switchDbUser(temporary_name)
+ yield
+ commit()
+ LaunchpadZopelessLayer.switchDbUser(restore_name)
+
+def lp_dbuser(restore_name=None):
+ """A context manager that temporarily changes to the launchpad dbuser.
+
+ Use with the LaunchpadZopelessLayer layer and subclasses.
+
+ restore_name is the name of the dbuser that should be restored after
+ the with block. If it is not supplied, the dbuser currently set (as
+ far as LaunchpadZopelessLayer knows) is used.
+ """
+ return dbuser('launchpad', restore_name=restore_name)
Follow ups