← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
Run branch/repository notification tests in Zopeless layers.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

Run branch/repository notification tests in Zopeless layers.

This more closely matches the environment in which this code is actually run following async-branch-notifications, and it's part of the cleanup required in order to be able to change BaseMailer to assert that it is running with a permissive security policy.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/zopeless-branch-notification-tests into lp:launchpad.
=== modified file 'lib/lp/code/doc/branch-merge-proposal-notifications.txt'
--- lib/lp/code/doc/branch-merge-proposal-notifications.txt	2015-07-21 09:04:01 +0000
+++ lib/lp/code/doc/branch-merge-proposal-notifications.txt	2015-09-02 17:01:27 +0000
@@ -11,15 +11,14 @@
 When subscribers subscribe to branches, they can specify what level of
 notification they would like to receive.
 
-    >>> from zope.security.proxy import removeSecurityProxy
-    >>> from difflib import unified_diff
     >>> from lp.code.enums import (
     ...     BranchSubscriptionDiffSize, BranchSubscriptionNotificationLevel,
     ...     CodeReviewNotificationLevel)
     >>> from lp.code.interfaces.branchmergeproposal import (
     ...     IBranchMergeProposalJobSource)
-    >>> from lp.code.model.diff import PreviewDiff
     >>> from lp.code.tests.helpers import make_merge_proposal_without_reviewers
+    >>> from lp.services.config import config
+    >>> from lp.testing.dbuser import dbuser
     >>> from lp.testing.mail_helpers import pop_notifications
     >>> import transaction
     >>> login('test@xxxxxxxxxxxxx')
@@ -113,7 +112,8 @@
     >>> bmp.next_preview_diff_job.start()
     >>> bmp.next_preview_diff_job.complete()
     >>> [job] = list(getUtility(IBranchMergeProposalJobSource).iterReady())
-    >>> job.run()
+    >>> with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+    ...     job.run()
     >>> notifications = pop_notifications(
     ...     sort_key=lambda n: n.get('X-Envelope-To'))
 
@@ -169,7 +169,8 @@
     >>> bmp.next_preview_diff_job.start()
     >>> bmp.next_preview_diff_job.complete()
     >>> [job] = list(getUtility(IBranchMergeProposalJobSource).iterReady())
-    >>> job.run()
+    >>> with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+    ...     job.run()
     >>> notifications = pop_notifications(
     ...     sort_key=lambda n: n.get('X-Envelope-To'))
     >>> for notification in notifications:

=== modified file 'lib/lp/code/doc/branch-notifications.txt'
--- lib/lp/code/doc/branch-notifications.txt	2015-09-02 17:01:27 +0000
+++ lib/lp/code/doc/branch-notifications.txt	2015-09-02 17:01:27 +0000
@@ -95,7 +95,7 @@
   * Send the entire diff
 
     >>> from lp.registry.interfaces.person import IPersonSet
-    >>> from lp.code.interfaces.branch import IBranch, IBranchSet
+    >>> from lp.code.interfaces.branch import IBranch
     >>> personset = getUtility(IPersonSet)
 
     >>> def subscribe_user_by_email(branch, email, level, size, level2):
@@ -424,12 +424,14 @@
     >>> from lp.code.interfaces.branchjob import IBranchModifiedMailJobSource
     >>> from lp.services.config import config
     >>> from lp.services.job.runner import JobRunner
+    >>> from lp.services.log.logger import DevNullLogger
     >>> from lp.testing.dbuser import dbuser
 
     >>> def run_modified_mail_jobs():
     ...     job_source = getUtility(IBranchModifiedMailJobSource)
+    ...     logger = DevNullLogger()
     ...     with dbuser(config.IBranchModifiedMailJobSource.dbuser):
-    ...         JobRunner.fromReady(job_source).runAll()
+    ...         JobRunner.fromReady(job_source, logger=logger).runAll()
 
     >>> login('test@xxxxxxxxxxxxx')
     >>> before_modification = Snapshot(branch, providing=IBranch)

=== modified file 'lib/lp/code/mail/tests/test_branch.py'
--- lib/lp/code/mail/tests/test_branch.py	2015-06-01 17:09:56 +0000
+++ lib/lp/code/mail/tests/test_branch.py	2015-09-02 17:01:27 +0000
@@ -1,10 +1,8 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for Branch-related mailings"""
 
-from zope.security.proxy import removeSecurityProxy
-
 from lp.code.enums import (
     BranchSubscriptionDiffSize,
     BranchSubscriptionNotificationLevel,
@@ -16,17 +14,19 @@
     )
 from lp.code.model.branch import Branch
 from lp.code.model.gitref import GitRef
+from lp.services.config import config
 from lp.testing import (
     login_person,
     TestCaseWithFactory,
     )
-from lp.testing.layers import DatabaseFunctionalLayer
+from lp.testing.dbuser import switch_dbuser
+from lp.testing.layers import ZopelessDatabaseLayer
 
 
 class TestRecipientReasonMixin:
     """Test the RecipientReason class."""
 
-    layer = DatabaseFunctionalLayer
+    layer = ZopelessDatabaseLayer
 
     def setUp(self):
         # Need to set merge_target.date_last_modified.
@@ -36,6 +36,7 @@
         """Test values when created from a branch subscription."""
         merge_proposal, subscription = self.makeProposalWithSubscription()
         subscriber = subscription.person
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forBranchSubscriber(
             subscription, merge_proposal.merge_source, subscriber, '',
             merge_proposal)
@@ -57,6 +58,7 @@
         merge_proposal, vote_reference, subscriber = (
             self.makeReviewerAndSubscriber())
         pending_review = vote_reference.comment is None
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forReviewer(
             merge_proposal, pending_review, subscriber)
         self.assertEqual(subscriber, reason.subscriber)
@@ -67,6 +69,7 @@
     def test_forReview_individual_pending(self):
         bmp = self.factory.makeBranchMergeProposal()
         reviewer = self.factory.makePerson(name='eric')
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forReviewer(bmp, True, reviewer)
         self.assertEqual('Reviewer', reason.mail_header)
         self.assertEqual(
@@ -77,6 +80,7 @@
     def test_forReview_individual_in_progress(self):
         bmp = self.factory.makeBranchMergeProposal()
         reviewer = self.factory.makePerson(name='eric')
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forReviewer(bmp, False, reviewer)
         self.assertEqual('Reviewer', reason.mail_header)
         self.assertEqual(
@@ -87,6 +91,7 @@
     def test_forReview_team_pending(self):
         bmp = self.factory.makeBranchMergeProposal()
         reviewer = self.factory.makeTeam(name='vikings')
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forReviewer(bmp, True, reviewer)
         self.assertEqual('Reviewer @vikings', reason.mail_header)
         self.assertEqual(
@@ -98,6 +103,7 @@
     def test_getReasonPerson(self):
         """Ensure the correct reason is generated for individuals."""
         merge_proposal, subscription = self.makeProposalWithSubscription()
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forBranchSubscriber(
             subscription, merge_proposal.merge_source, subscription.person, '',
             merge_proposal)
@@ -111,6 +117,7 @@
             displayname='Foo Bar', email='foo@xxxxxxx')
         team = self.factory.makeTeam(team_member, displayname='Qux')
         bmp, subscription = self.makeProposalWithSubscription(team)
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forBranchSubscriber(
             subscription, bmp.merge_source, team_member, '', bmp)
         self.assertEqual(
@@ -150,6 +157,7 @@
             Branch.identity = patched
         self.addCleanup(cleanup)
         self.assertRaises(AssertionError, getattr, branch, 'identity')
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forBranchSubscriber(
             subscription, branch, subscription.person, '',
             branch_identity_cache=branch_cache)
@@ -192,6 +200,7 @@
             GitRef.identity = patched
         self.addCleanup(cleanup)
         self.assertRaises(AssertionError, getattr, ref, 'identity')
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         reason = RecipientReason.forBranchSubscriber(
             subscription, ref, subscription.person, '',
             branch_identity_cache=branch_cache)
@@ -203,7 +212,7 @@
 class TestBranchMailerHeadersMixin:
     """Check the headers are correct."""
 
-    layer = DatabaseFunctionalLayer
+    layer = ZopelessDatabaseLayer
 
     def test_branch_modified(self):
         # Test the email headers for a branch modified email.
@@ -211,6 +220,7 @@
         branch = self.makeBranch(owner=bob)
         branch.getSubscription(bob).notification_level = (
             BranchSubscriptionNotificationLevel.FULL)
+        switch_dbuser(config.IBranchModifiedMailJobSource.dbuser)
         mailer = BranchMailer.forBranchModified(branch, branch.owner, None)
         mailer.message_id = '<foobar-example-com>'
         ctrl = mailer.generateEmail('bob@xxxxxxxxxxx', branch.owner)
@@ -228,6 +238,7 @@
         branch = self.makeBranch(owner=bob)
         branch.getSubscription(bob).notification_level = (
             BranchSubscriptionNotificationLevel.FULL)
+        switch_dbuser(config.IRevisionsAddedJobSource.dbuser)
         mailer = BranchMailer.forRevision(
             branch, 'from@xxxxxxxxxxx', contents='', diff=None, subject='',
             revno=1)
@@ -269,7 +280,7 @@
 class TestBranchMailerDiffMixin:
     """Check the diff is an attachment."""
 
-    layer = DatabaseFunctionalLayer
+    layer = ZopelessDatabaseLayer
 
     def makeBobMailController(self, diff=None,
                               max_lines=BranchSubscriptionDiffSize.WHOLEDIFF):
@@ -279,6 +290,7 @@
         subscription.max_diff_lines = max_lines
         subscription.notification_level = (
             BranchSubscriptionNotificationLevel.FULL)
+        switch_dbuser(config.IRevisionsAddedJobSource.dbuser)
         mailer = BranchMailer.forRevision(
             branch, 'from@xxxxxxxxxxx', contents='', diff=diff, subject='',
             revno=1)
@@ -336,7 +348,7 @@
 class TestBranchMailerSubjectMixin:
     """The subject for a BranchMailer is returned verbatim."""
 
-    layer = DatabaseFunctionalLayer
+    layer = ZopelessDatabaseLayer
 
     def test_subject(self):
         # No string interpolation should occur on the subject.
@@ -344,13 +356,14 @@
         # Subscribe the owner to get revision email.
         branch.getSubscription(branch.owner).notification_level = (
             BranchSubscriptionNotificationLevel.FULL)
+        switch_dbuser(config.IRevisionsAddedJobSource.dbuser)
         mailer = BranchMailer.forRevision(
             branch, 'test@xxxxxxxxxxx', 'content', 'diff', 'Testing %j foo',
             revno=1)
-        branch_owner_email = removeSecurityProxy(
-            branch.owner).preferredemail.email
-        self.assertEqual('Testing %j foo', mailer._getSubject(
-                branch_owner_email, branch.owner))
+        owner = branch.owner
+        self.assertEqual(
+            'Testing %j foo',
+            mailer._getSubject(owner.preferredemail.email, owner))
 
 
 class TestBranchMailerSubjectBzr(

=== modified file 'lib/lp/code/mail/tests/test_branchmergeproposal.py'
--- lib/lp/code/mail/tests/test_branchmergeproposal.py	2015-09-02 17:01:27 +0000
+++ lib/lp/code/mail/tests/test_branchmergeproposal.py	2015-09-02 17:01:27 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2014 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for BranchMergeProposal mailings"""
@@ -11,7 +11,6 @@
 from lazr.lifecycle.snapshot import Snapshot
 import transaction
 from zope.interface import providedBy
-from zope.security.proxy import removeSecurityProxy
 
 from lp.app.enums import InformationType
 from lp.code.enums import (
@@ -31,6 +30,7 @@
 from lp.code.model.codereviewvote import CodeReviewVoteReference
 from lp.code.model.diff import PreviewDiff
 from lp.code.subscribers.branchmergeproposal import merge_proposal_modified
+from lp.services.config import config
 from lp.services.database.interfaces import IStore
 from lp.services.mail.sendmail import format_address_for_person
 from lp.services.webapp import canonical_url
@@ -38,9 +38,13 @@
     person_logged_in,
     TestCaseWithFactory,
     )
+from lp.testing.dbuser import (
+    dbuser,
+    switch_dbuser,
+    )
 from lp.testing.layers import (
-    DatabaseFunctionalLayer,
-    LaunchpadFunctionalLayer,
+    LaunchpadZopelessLayer,
+    ZopelessDatabaseLayer,
     )
 from lp.testing.mail_helpers import pop_notifications
 
@@ -48,7 +52,7 @@
 class TestMergeProposalMailing(TestCaseWithFactory):
     """Test that reasonable mailings are generated"""
 
-    layer = LaunchpadFunctionalLayer
+    layer = LaunchpadZopelessLayer
 
     def setUp(self):
         super(TestMergeProposalMailing, self).setUp('admin@xxxxxxxxxxxxx')
@@ -95,6 +99,7 @@
     def test_generateCreationEmail(self):
         """Ensure that the contents of the mail are as expected"""
         bmp, subscriber = self.makeProposalWithSubscriber()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         assert mailer.message_id is not None, 'Message-id should be set'
         mailer.message_id = '<foobar-example-com>'
@@ -144,6 +149,7 @@
         """If there is no commit message, email should say 'None Specified.'"""
         bmp, subscriber = self.makeProposalWithSubscriber()
         bmp.commit_message = None
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         self.assertNotIn('Commit message:', ctrl.body)
@@ -154,6 +160,7 @@
         bug = self.factory.makeBug(title='I am a bug')
         bugtask = bug.default_bugtask
         bmp.source_branch.linkBug(bug, bmp.registrant)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         expected = (
@@ -165,6 +172,7 @@
     def test_forCreation_without_bugs(self):
         """If there are no related bugs, omit 'Related bugs'."""
         bmp, subscriber = self.makeProposalWithSubscriber()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         self.assertNotIn('Related bugs:\n', ctrl.body)
@@ -174,6 +182,7 @@
         reviewer = self.factory.makePerson(name='review-person')
         bmp, subscriber = self.makeProposalWithSubscriber(reviewer=reviewer)
         bmp.nominateReviewer(reviewer, bmp.registrant, None)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         self.assertIn(
@@ -192,6 +201,7 @@
         bugtask = bug.default_bugtask
         bmp.source_branch.linkBug(bug, bmp.registrant)
         bmp.nominateReviewer(reviewer, bmp.registrant, None)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         expected = (
@@ -233,6 +243,7 @@
 
         # Set up the mailer
         bmp.nominateReviewer(reviewer, bmp.registrant, None)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
 
         # A non authorised email recipient doesn't see the private bug.
@@ -269,6 +280,7 @@
     def test_forCreation_with_prerequisite_branch(self):
         """Correctly format list of reviewers."""
         bmp, subscriber = self.makeProposalWithSubscriber(prerequisite=True)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         prereq = bmp.prerequisite_branch.bzr_identity
@@ -281,6 +293,7 @@
         bmp.source_branch.subscribe(
             bmp.registrant, BranchSubscriptionNotificationLevel.NOEMAIL, None,
             CodeReviewNotificationLevel.FULL, bmp.registrant)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail(bmp.registrant.preferredemail.email,
                                     bmp.registrant)
@@ -294,6 +307,7 @@
         team = self.factory.makeTeam(email='group@xxxxxxxx')
         CodeReviewVoteReference(
             branch_merge_proposal=bmp, reviewer=team, registrant=subscriber)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail(subscriber.preferredemail.email,
                                     subscriber)
@@ -306,6 +320,7 @@
         request, requester = self.makeReviewRequest()
         request.recipient.hide_email_addresses = True
         bmp = request.merge_proposal
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail(request.recipient.preferredemail.email,
                                     request.recipient)
@@ -314,6 +329,7 @@
     def test_RecordMessageId(self):
         """Ensure that the contents of the mail are as expected"""
         bmp, subscriber = self.makeProposalWithSubscriber()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         mailer.message_id = '<foobar-example-com>'
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
@@ -334,6 +350,7 @@
         """Ensure that messages are in reply to the root"""
         bmp, subscriber = self.makeProposalWithSubscriber()
         bmp.root_message_id = '<root-message-id>'
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         self.assertEqual('<root-message-id>', ctrl.headers['In-Reply-To'])
@@ -349,6 +366,7 @@
         diff_text = ''.join(unified_diff('', 'Fake diff'))
         bmp, subscriber = self.makeProposalWithSubscriber(
             diff_text=diff_text)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         (attachment,) = ctrl.attachments
@@ -366,6 +384,7 @@
         bmp.source_branch.subscribe(subscriber,
             BranchSubscriptionNotificationLevel.NOEMAIL, None,
             CodeReviewNotificationLevel.STATUS, subscriber)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         self.assertEqual(0, len(ctrl.attachments))
@@ -376,6 +395,7 @@
         diff_text = ''.join(unified_diff('', "1234567890" * 10))
         bmp, subscriber = self.makeProposalWithSubscriber(
             diff_text=diff_text)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forCreation(bmp, bmp.registrant)
         ctrl = mailer.generateEmail('baz.quxx@xxxxxxxxxxx', subscriber)
         (attachment,) = ctrl.attachments
@@ -472,6 +492,7 @@
     def test_forModificationHasMsgId(self):
         """Ensure the right delta is filled out if there is a change."""
         merge_proposal = self.factory.makeBranchMergeProposal()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forModification(
             merge_proposal, 'the diff', merge_proposal.registrant)
         self.assertIsNot(None, mailer.message_id, 'message_id not set')
@@ -488,7 +509,8 @@
         """Should send emails when invoked with correct parameters."""
         job, subscriber = self.makeProposalUpdatedEmailJob()
         pop_notifications()
-        job.run()
+        with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+            job.run()
         emails = pop_notifications(
             sort_key=operator.itemgetter('x-launchpad-message-rationale'))
         self.assertEqual(3, len(emails),
@@ -543,6 +565,7 @@
     def test_forReviewRequest(self):
         """Test creating a mailer for a review request."""
         request, requester = self.makeReviewRequest()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forReviewRequest(
             request, request.merge_proposal, requester)
         self.assertEqual(
@@ -554,6 +577,7 @@
 
     def test_to_addrs_for_review_request(self):
         request, requester = self.makeReviewRequest()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forReviewRequest(
             request, request.merge_proposal, requester)
         ctrl = mailer.generateEmail(request.recipient.preferredemail.email,
@@ -564,6 +588,7 @@
     def test_forReviewRequestMessageId(self):
         """Test creating a mailer for a review request."""
         request, requester = self.makeReviewRequest()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = BMPMailer.forReviewRequest(
             request, request.merge_proposal, requester)
         assert mailer.message_id is not None, 'message_id not set'
@@ -572,7 +597,7 @@
 class TestBranchMergeProposalRequestReview(TestCaseWithFactory):
     """Tests for `BranchMergeProposalRequestReviewView`."""
 
-    layer = DatabaseFunctionalLayer
+    layer = ZopelessDatabaseLayer
 
     def getReviewEmailJobs(self, bmp):
         """Return the result set for the merge proposals review email jobs."""
@@ -631,7 +656,8 @@
             bmp.description = 'This branch is awesome.'
             bmp.nominateReviewer(reviewer, bmp.registrant, None)
         review_request_job = self.getReviewNotificationEmail(bmp)
-        review_request_job.run()
+        with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+            review_request_job.run()
         [sent_mail] = pop_notifications()
         expected = dedent("""\
             You have been requested to review the proposed merge of"""
@@ -665,7 +691,8 @@
         with person_logged_in(bmp.registrant):
             bmp.nominateReviewer(review_team, bmp.registrant, None)
         review_request_job = self.getReviewNotificationEmail(bmp)
-        review_request_job.run()
+        with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+            review_request_job.run()
         sent_mail = pop_notifications()
         self.assertEqual(
             ['Black Beard <black@xxxxxxxxxxxxxxxxxxx>',
@@ -683,10 +710,10 @@
             bmp.nominateReviewer(candidate, bmp.registrant, None)
         # Send the mail.
         review_request_job = self.getReviewNotificationEmail(bmp)
-        review_request_job.run()
+        with dbuser(config.IBranchMergeProposalJobSource.dbuser):
+            review_request_job.run()
         mails = pop_notifications()
         self.assertEqual(1, len(mails))
-        candidate = removeSecurityProxy(candidate)
         expected_email = '%s <%s>' % (
             candidate.displayname, candidate.preferredemail.email)
         self.assertEmailHeadersEqual(expected_email, mails[0]['To'])

=== modified file 'lib/lp/code/mail/tests/test_codereviewcomment.py'
--- lib/lp/code/mail/tests/test_codereviewcomment.py	2015-08-23 22:53:55 +0000
+++ lib/lp/code/mail/tests/test_codereviewcomment.py	2015-09-02 17:01:27 +0000
@@ -6,7 +6,6 @@
 import testtools
 import transaction
 from zope.component import getUtility
-from zope.security.proxy import removeSecurityProxy
 
 from lp.code.enums import (
     BranchSubscriptionNotificationLevel,
@@ -17,6 +16,7 @@
     build_inline_comments_section,
     CodeReviewCommentMailer,
     )
+from lp.services.config import config
 from lp.services.mail.sendmail import format_address
 from lp.services.messages.interfaces.message import IMessageSet
 from lp.services.webapp import canonical_url
@@ -26,13 +26,17 @@
     person_logged_in,
     TestCaseWithFactory,
     )
-from lp.testing.layers import LaunchpadFunctionalLayer
+from lp.testing.dbuser import (
+    lp_dbuser,
+    switch_dbuser,
+    )
+from lp.testing.layers import LaunchpadZopelessLayer
 
 
 class TestCodeReviewComment(TestCaseWithFactory):
     """Test that comments are generated as expected."""
 
-    layer = LaunchpadFunctionalLayer
+    layer = LaunchpadZopelessLayer
 
     def setUp(self):
         """Prepare test fixtures."""
@@ -68,6 +72,7 @@
         """Return a CodeReviewCommentMailer and the sole subscriber."""
         comment, subscriber = self.makeCommentAndSubscriber(
             body=body, as_reply=as_reply, vote=vote, vote_tag=vote_tag)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         return CodeReviewCommentMailer.forCreation(comment), subscriber
 
     def assertRecipientsMatches(self, recipients, mailer):
@@ -78,6 +83,7 @@
     def test_forCreation(self):
         """Ensure that forCreation produces a mailer with expected values."""
         comment, subscriber = self.makeCommentAndSubscriber()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         self.assertEqual(comment.message.subject,
                          mailer._subject_template)
@@ -99,6 +105,7 @@
         """Ensure that subscriptions with STATUS aren't used."""
         comment, subscriber = self.makeCommentAndSubscriber(
             CodeReviewNotificationLevel.STATUS)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         bmp = comment.branch_merge_proposal
         # The branch owners are implicitly subscribed to their branches
@@ -110,6 +117,7 @@
         """Ensure that subscriptions with NOEMAIL aren't used."""
         comment, subscriber = self.makeCommentAndSubscriber(
             CodeReviewNotificationLevel.NOEMAIL)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         bmp = comment.branch_merge_proposal
         # The branch owners are implicitly subscribed to their branches
@@ -121,6 +129,7 @@
         # The mailer should not attempt to expand templates in the subject.
         comment, subscriber = self.makeCommentAndSubscriber(
             subject='A %(carefully)s constructed subject')
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         self.assertEqual(
             'A %(carefully)s constructed subject',
@@ -174,6 +183,7 @@
         comment, subscriber = self.makeCommentAndSubscriber()
         second_comment = self.factory.makeCodeReviewComment(
             merge_proposal=comment.branch_merge_proposal)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(second_comment)
         ctrl = mailer.generateEmail(
             subscriber.preferredemail.email, subscriber)
@@ -196,7 +206,7 @@
     def test_appendExpandedFooter(self):
         """Check that expanded notification footers are sensible."""
         mailer, subscriber = self.makeMailer(as_reply=True)
-        with person_logged_in(subscriber):
+        with lp_dbuser(), person_logged_in(subscriber):
             subscriber.expanded_notification_footers = True
         ctrl = mailer.generateEmail(
             subscriber.preferredemail.email, subscriber)
@@ -263,6 +273,7 @@
         """
         comment = self.makeCommentWithInlineComments(
             inline_comments={'3': 'Is this from Pl\u0060net Earth ?'})
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         commenter = comment.branch_merge_proposal.registrant
         ctrl = mailer.generateEmail(
@@ -302,6 +313,7 @@
                 ('inc.diff', 'text/x-diff', 'This is a diff.'),
                 ('pic.jpg', 'image/jpeg', 'Binary data')])
         comment = self.makeComment(msg)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         # The attachments of the mailer should have only the diff.
         [outgoing_attachment] = mailer.attachments
@@ -322,6 +334,7 @@
             attachments=[('inc.diff', 'text/x-diff', 'This is a diff.')],
             encode_attachments=True)
         comment = self.makeComment(msg)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         person = comment.branch_merge_proposal.target_branch.owner
         message = mailer.generateEmail(
@@ -350,6 +363,7 @@
     def test_getToAddresses_no_parent(self):
         """To address for a comment with no parent should be the proposer."""
         comment = self.makeCommentAndParticipants()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         to = mailer._getToAddresses('comment@xxxxxxxxx', comment.message.owner)
         self.assertEqual(['Proposer <proposer@xxxxxxxxx>'], to)
@@ -364,6 +378,7 @@
         should not affect the actual recipient list.
         """
         comment = self.makeCommentAndParticipants()
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(comment)
         ctrl = mailer.generateEmail('commenter@xxxxxxxxx',
                                     comment.message.owner)
@@ -377,6 +392,7 @@
             email='commenter2@xxxxxxxxx', displayname='Commenter2')
         reply = comment.branch_merge_proposal.createComment(
             second_commenter, 'hello2', parent=comment)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(reply)
         to = mailer._getToAddresses('comment2@xxxxxxxxx', second_commenter)
         self.assertEqual(['Commenter <commenter@xxxxxxxxx>'], to)
@@ -386,11 +402,12 @@
     def test_getToAddresses_with_hidden_address(self):
         """Don't show address if Person.hide_email_addresses."""
         comment = self.makeCommentAndParticipants()
-        removeSecurityProxy(comment.message.owner).hide_email_addresses = True
+        comment.message.owner.hide_email_addresses = True
         second_commenter = self.factory.makePerson(
             email='commenter2@xxxxxxxxx', displayname='Commenter2')
         reply = comment.branch_merge_proposal.createComment(
             second_commenter, 'hello2', parent=comment)
+        switch_dbuser(config.IBranchMergeProposalJobSource.dbuser)
         mailer = CodeReviewCommentMailer.forCreation(reply)
         to = mailer._getToAddresses('comment2@xxxxxxxxx', second_commenter)
         self.assertEqual([mailer.merge_proposal.address], to)

=== modified file 'lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py'
--- lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py	2015-08-25 14:13:03 +0000
+++ lib/lp/code/mail/tests/test_sourcepackagerecipebuild.py	2015-09-02 17:01:27 +0000
@@ -1,4 +1,4 @@
-# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# Copyright 2010-2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 
@@ -8,7 +8,6 @@
 from datetime import timedelta
 
 from storm.locals import Store
-from zope.security.proxy import removeSecurityProxy
 
 from lp.buildmaster.enums import BuildStatus
 from lp.code.mail.sourcepackagerecipebuild import (
@@ -17,7 +16,8 @@
 from lp.services.config import config
 from lp.services.webapp import canonical_url
 from lp.testing import TestCaseWithFactory
-from lp.testing.layers import LaunchpadFunctionalLayer
+from lp.testing.dbuser import switch_dbuser
+from lp.testing.layers import LaunchpadZopelessLayer
 
 
 expected_body = u"""\
@@ -45,11 +45,12 @@
 
 class TestSourcePackageRecipeBuildMailer(TestCaseWithFactory):
 
-    layer = LaunchpadFunctionalLayer
+    layer = LaunchpadZopelessLayer
 
     def makeStatusEmail(self, build):
+        switch_dbuser(config.builddmaster.dbuser)
         mailer = SourcePackageRecipeBuildMailer.forStatus(build)
-        email = removeSecurityProxy(build.requester).preferredemail.email
+        email = build.requester.preferredemail.email
         return mailer.generateEmail(email, build.requester)
 
     def test_generateEmail(self):
@@ -60,7 +61,7 @@
         pantry_owner = self.factory.makePerson(name='archiveowner')
         pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
         secret = self.factory.makeDistroSeries(name=u'distroseries')
-        removeSecurityProxy(secret).nominatedarchindep = (
+        secret.nominatedarchindep = (
             self.factory.makeDistroArchSeries(distroseries=secret))
         build = self.factory.makeSourcePackageRecipeBuild(
             recipe=cake, distroseries=secret, archive=pantry,
@@ -98,7 +99,7 @@
         pantry_owner = self.factory.makePerson(name='archiveowner')
         pantry = self.factory.makeArchive(name='ppa', owner=pantry_owner)
         secret = self.factory.makeDistroSeries(name=u'distroseries')
-        removeSecurityProxy(secret).nominatedarchindep = (
+        secret.nominatedarchindep = (
             self.factory.makeDistroArchSeries(distroseries=secret))
         build = self.factory.makeSourcePackageRecipeBuild(
             recipe=cake, distroseries=secret, archive=pantry,

=== modified file 'lib/lp/code/model/tests/test_branchjob.py'
--- lib/lp/code/model/tests/test_branchjob.py	2013-07-04 08:32:03 +0000
+++ lib/lp/code/model/tests/test_branchjob.py	2015-09-02 17:01:27 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Tests for BranchJobs."""
@@ -827,6 +827,7 @@
             "added:" '\n'
             "  hello.txt" '\n' % tree.branch.nick)
         job = RevisionsAddedJob.create(db_branch, '', '', '')
+        switch_dbuser(config.IRevisionsAddedJobSource.dbuser)
         self.assertEqual(
             job.getRevisionMessage(first_revision, 1), expected)
 
@@ -861,6 +862,7 @@
         self.updateDBRevisions(db_branch, tree.branch,
             branch_revision_history(tree.branch))
         job = RevisionsAddedJob.create(db_branch, '', '', '')
+        switch_dbuser(config.IRevisionsAddedJobSource.dbuser)
         message = job.getRevisionMessage(rev_id, 1)
         # The revision message must be a unicode object.
         expected = (

=== modified file 'lib/lp/code/model/tests/test_gitrepository.py'
--- lib/lp/code/model/tests/test_gitrepository.py	2015-09-02 17:01:27 +0000
+++ lib/lp/code/model/tests/test_gitrepository.py	2015-09-02 17:01:27 +0000
@@ -132,6 +132,7 @@
     DatabaseFunctionalLayer,
     LaunchpadFunctionalLayer,
     LaunchpadZopelessLayer,
+    ZopelessDatabaseLayer,
     )
 from lp.testing.mail_helpers import pop_notifications
 from lp.testing.pages import webservice_for_person
@@ -675,7 +676,7 @@
 
 
 class TestGitRepositoryModifications(TestCaseWithFactory):
-    """Tests for Git repository modification notifications."""
+    """Tests for Git repository modifications."""
 
     layer = DatabaseFunctionalLayer
 
@@ -732,6 +733,12 @@
         self.assertSqlAttributeEqualsDate(
             repository, "date_last_modified", UTC_NOW)
 
+
+class TestGitRepositoryModificationNotifications(TestCaseWithFactory):
+    """Tests for Git repository modification notifications."""
+
+    layer = ZopelessDatabaseLayer
+
     def test_sends_notifications(self):
         # Attribute modifications send mail to subscribers.
         self.assertEqual(0, len(stub.test_emails))

=== modified file 'lib/lp/code/tests/test_doc.py'
--- lib/lp/code/tests/test_doc.py	2013-07-04 07:58:00 +0000
+++ lib/lp/code/tests/test_doc.py	2015-09-02 17:01:27 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """
@@ -68,7 +68,15 @@
         ),
     'branch-merge-proposal-notifications.txt': LayeredDocFileSuite(
         '../doc/branch-merge-proposal-notifications.txt',
-        setUp=setUp, tearDown=tearDown, layer=LaunchpadFunctionalLayer,
+        setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer,
+        ),
+    'branch-notifications.txt': LayeredDocFileSuite(
+        '../doc/branch-notifications.txt',
+        setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer,
+        ),
+    'codereviewcomment.txt': LayeredDocFileSuite(
+        '../doc/codereviewcomment.txt',
+        setUp=setUp, tearDown=tearDown, layer=LaunchpadZopelessLayer,
         ),
     }
 


Follow ups