def test_exportToBranches_handles_unpushed_branches(self):
        # bzrlib raises NotBranchError when accessing a nonexistent
        # branch.  The exporter deals with that by calling
        # _handleUnpushedBranch.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        productseries.translations_branch = self.factory.makeBranch()

        self.becomeDbUser('translationstobranch')

        # _handleUnpushedBranch is called if _exportToBranch raises
        # NotBranchError.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("No!"))
        exporter._exportToBranches([productseries])
        self.assertEqual(1, exporter._handleUnpushedBranch.call_count)

        # This does not happen if the export succeeds.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod()
        exporter._exportToBranches([productseries])
        self.assertEqual(0, exporter._handleUnpushedBranch.call_count)

        # Nor does it happen if the export fails in some other way.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod(failure=IndexError("Ayyeee!"))
        exporter._exportToBranches([productseries])
        self.assertEqual(0, exporter._handleUnpushedBranch.call_count)
    def test_exportToBranches_handles_unpushed_branches(self):
        # bzrlib raises NotBranchError when accessing a nonexistent
        # branch.  The exporter deals with that by calling
        # _handleUnpushedBranch.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        productseries.translations_branch = self.factory.makeBranch()

        self.becomeDbUser('translationstobranch')

        # _handleUnpushedBranch is called if _exportToBranch raises
        # NotBranchError.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("No!"))
        exporter._exportToBranches([productseries])
        self.assertEqual(1, exporter._handleUnpushedBranch.call_count)

        # This does not happen if the export succeeds.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod()
        exporter._exportToBranches([productseries])
        self.assertEqual(0, exporter._handleUnpushedBranch.call_count)

        # Nor does it happen if the export fails in some other way.
        exporter._handleUnpushedBranch = FakeMethod()
        exporter._exportToBranch = FakeMethod(failure=IndexError("Ayyeee!"))
        exporter._exportToBranches([productseries])
        self.assertEqual(0, exporter._handleUnpushedBranch.call_count)
 def test_exportToStaleBranch(self):
     # Attempting to export to a stale branch marks it for scanning.
     self.useBzrBranches(direct_database=False)
     exporter = ExportTranslationsToBranch(test_args=[])
     exporter.logger = BufferLogger()
     productseries = self.factory.makeProductSeries()
     db_branch, tree = self.create_branch_and_tree(
         product=productseries.product)
     removeSecurityProxy(productseries).translations_branch = db_branch
     db_branch.last_mirrored_id = 'stale-id'
     db_branch.last_scanned_id = db_branch.last_mirrored_id
     self.becomeDbUser('translationstobranch')
     self.assertFalse(db_branch.pending_writes)
     self.assertNotEqual(db_branch.last_mirrored_id,
                         tree.branch.last_revision())
     # The export code works on a Branch from the slave store.  It
     # shouldn't stop the scan request.
     slave_series = ISlaveStore(productseries).get(ProductSeries,
                                                   productseries.id)
     exporter._exportToBranch(slave_series)
     self.assertEqual(db_branch.last_mirrored_id,
                      tree.branch.last_revision())
     self.assertTrue(db_branch.pending_writes)
     matches = MatchesRegex(
         "(.|\n)*WARNING Skipped .* due to stale DB info, and scheduled a "
         "new scan.")
     self.assertThat(exporter.logger.getLogBuffer(), matches)
 def test_exportToStaleBranch(self):
     # Attempting to export to a stale branch marks it for scanning.
     self.useBzrBranches(direct_database=False)
     exporter = ExportTranslationsToBranch(test_args=[])
     exporter.logger = BufferLogger()
     productseries = self.factory.makeProductSeries()
     db_branch, tree = self.create_branch_and_tree(
         product=productseries.product)
     removeSecurityProxy(productseries).translations_branch = db_branch
     db_branch.last_mirrored_id = 'stale-id'
     db_branch.last_scanned_id = db_branch.last_mirrored_id
     self.becomeDbUser('translationstobranch')
     self.assertFalse(db_branch.pending_writes)
     self.assertNotEqual(
         db_branch.last_mirrored_id, tree.branch.last_revision())
     # The export code works on a Branch from the slave store.  It
     # shouldn't stop the scan request.
     slave_series = ISlaveStore(productseries).get(
         ProductSeries, productseries.id)
     exporter._exportToBranch(slave_series)
     self.assertEqual(
         db_branch.last_mirrored_id, tree.branch.last_revision())
     self.assertTrue(db_branch.pending_writes)
     matches = MatchesRegex(
         "(.|\n)*WARNING Skipped .* due to stale DB info, and scheduled a "
         "new scan.")
     self.assertThat(exporter.logger.getLogBuffer(), matches)
    def test_handleUnpushedBranch_mails_branch_owner(self):
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        branch_owner = self.factory.makePerson(email=email)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))
        exporter._sendMail = FakeMethod()

        self.becomeDbUser('translationstobranch')

        exporter._exportToBranches([productseries])

        self.assertEqual(1, exporter._sendMail.call_count)
        (sender, recipients, subject,
         text), kwargs = (exporter._sendMail.calls[-1])
        self.assertIn(config.canonical.noreply_from_address, sender)
        self.assertIn(email, recipients)
        self.assertEqual("Launchpad: translations branch has not been set up.",
                         subject)

        self.assertIn("problem with translations branch synchronization", text)
        self.assertIn(productseries.title, text)
        self.assertIn(productseries.translations_branch.bzr_identity, text)
        self.assertIn('bzr push lp://', text)
    def test_handleUnpushedBranch_mails_branch_owner(self):
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        branch_owner = self.factory.makePerson(email=email)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))
        exporter._sendMail = FakeMethod()

        self.becomeDbUser('translationstobranch')

        exporter._exportToBranches([productseries])

        self.assertEqual(1, exporter._sendMail.call_count)
        (sender, recipients, subject, text), kwargs = (
            exporter._sendMail.calls[-1])
        self.assertIn(config.canonical.noreply_from_address, sender)
        self.assertIn(email, recipients)
        self.assertEqual(
            "Launchpad: translations branch has not been set up.", subject)

        self.assertIn(
            "problem with translations branch synchronization", text)
        self.assertIn(productseries.title, text)
        self.assertIn(productseries.translations_branch.bzr_identity, text)
        self.assertIn('bzr push lp://', text)
    def test_exportToBranches_handles_nonascii_exceptions(self):
        # There's an exception handler in _exportToBranches that must
        # cope well with non-ASCII exception strings.
        productseries = self.factory.makeProductSeries()
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        boom = u'\u2639'
        exporter._exportToBranch = FakeMethod(failure=GruesomeException(boom))

        self.becomeDbUser('translationstobranch')

        exporter._exportToBranches([productseries])

        self.assertEqual(1, exporter._exportToBranch.call_count)

        message = exporter.logger.getLogBuffer()
        self.assertTrue(message.startswith("ERROR"))
        self.assertTrue("GruesomeException" in message)
    def test_exportToBranches_handles_nonascii_exceptions(self):
        # There's an exception handler in _exportToBranches that must
        # cope well with non-ASCII exception strings.
        productseries = self.factory.makeProductSeries()
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        boom = u'\u2639'
        exporter._exportToBranch = FakeMethod(failure=GruesomeException(boom))

        self.becomeDbUser('translationstobranch')

        exporter._exportToBranches([productseries])

        self.assertEqual(1, exporter._exportToBranch.call_count)

        message = exporter.logger.getLogBuffer()
        self.assertTrue(message.startswith("ERROR"))
        self.assertTrue("GruesomeException" in message)
    def test_handleUnpushedBranch_has_required_privileges(self):
        # Dealing with an unpushed branch is a special code path that
        # was not exercised by the full-script test.  Ensure that it has
        # the database privileges that it requires.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        branch_owner = self.factory.makePerson(email=email)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))

        self.becomeDbUser('translationstobranch')

        exporter._handleUnpushedBranch(productseries)

        # _handleUnpushedBranch completes successfully.  There are no
        # database changes still pending in the ORM that are going to
        # fail either.
        transaction.commit()
    def test_handleUnpushedBranch_has_required_privileges(self):
        # Dealing with an unpushed branch is a special code path that
        # was not exercised by the full-script test.  Ensure that it has
        # the database privileges that it requires.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        branch_owner = self.factory.makePerson(email=email)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))

        self.becomeDbUser('translationstobranch')

        exporter._handleUnpushedBranch(productseries)

        # _handleUnpushedBranch completes successfully.  There are no
        # database changes still pending in the ORM that are going to
        # fail either.
        transaction.commit()
    def test_handleUnpushedBranch_is_privileged_to_contact_team(self):
        # Notifying a branch owner that is a team can require other
        # database privileges.  The script also has these privileges.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        team_member = self.factory.makePerson(email=email)
        branch_owner = self.factory.makeTeam()
        getUtility(ITeamMembershipSet).new(team_member, branch_owner,
                                           TeamMembershipStatus.APPROVED,
                                           branch_owner.teamowner)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))

        self.becomeDbUser('translationstobranch')

        exporter._handleUnpushedBranch(productseries)

        # _handleUnpushedBranch completes successfully.  There are no
        # database changes still pending in the ORM that are going to
        # fail either.
        transaction.commit()
    def test_handleUnpushedBranch_is_privileged_to_contact_team(self):
        # Notifying a branch owner that is a team can require other
        # database privileges.  The script also has these privileges.
        exporter = ExportTranslationsToBranch(test_args=[])
        exporter.logger = BufferLogger()
        productseries = self.factory.makeProductSeries()
        email = self.factory.getUniqueEmailAddress()
        team_member = self.factory.makePerson(email=email)
        branch_owner = self.factory.makeTeam()
        getUtility(ITeamMembershipSet).new(
            team_member, branch_owner, TeamMembershipStatus.APPROVED,
            branch_owner.teamowner)
        productseries.translations_branch = self.factory.makeBranch(
            owner=branch_owner)
        exporter._exportToBranch = FakeMethod(failure=NotBranchError("Ow"))

        self.becomeDbUser('translationstobranch')

        exporter._handleUnpushedBranch(productseries)

        # _handleUnpushedBranch completes successfully.  There are no
        # database changes still pending in the ORM that are going to
        # fail either.
        transaction.commit()