def test_queue_tip_changed_email_jobs_subscribed(self): """A queue_tip_changed_email_jobs is run when TipChanged emitted.""" self.useBzrBranches(direct_database=True) db_branch, tree = self.create_branch_and_tree() db_branch.subscribe(db_branch.registrant, BranchSubscriptionNotificationLevel.FULL, BranchSubscriptionDiffSize.WHOLEDIFF, CodeReviewNotificationLevel.FULL, db_branch.registrant) self.assertEqual(0, len(list(RevisionMailJob.iterReady()))) notify(events.TipChanged(db_branch, tree.branch, True)) self.assertEqual(1, len(list(RevisionMailJob.iterReady())))
def test_scheduleTranslationTemplatesBuild_subscribed(self): # If the feature is enabled, a TipChanged event for a branch that # generates templates will schedule a templates build. branch = self._makeTranslationBranch() removeSecurityProxy(branch).last_scanned_id = 'null:' commit = DirectBranchCommit(branch) commit.writeFile('POTFILES.in', 'foo') commit.commit('message') notify(events.TipChanged(branch, None, False)) branchjobs = list(TranslationTemplatesBuildJob.iterReady()) self.assertEqual(1, len(branchjobs)) self.assertEqual(branch, branchjobs[0].branch)
def test_scheduleTranslationTemplatesBuild_subscribed(self): # If the feature is enabled, a TipChanged event for a branch that # generates templates will schedule a templates build. branch = self._makeTranslationBranch() removeSecurityProxy(branch).last_scanned_id = 'null:' commit = DirectBranchCommit(branch) commit.writeFile('POTFILES.in', 'foo') commit.commit('message') notify(events.TipChanged(branch, commit.bzrbranch, False)) self.assertEqual( 1, TranslationTemplatesBuild.findByBranch(branch).count())
def syncBranch(self, bzr_branch): """Synchronize the database view of a branch with Bazaar data. `bzr_branch` must be read locked. Several tables must be updated: * Revision: there must be one Revision row for each revision in the branch ancestry. If the row for a revision that has just been added to the branch is already present, it must be checked for consistency. * BranchRevision: there must be one BrancheRevision row for each revision in the branch ancestry. If history revisions became merged revisions, the corresponding rows must be changed. * Branch: the branch-scanner status information must be updated when the sync is complete. """ self.logger.info("Scanning branch: %s", self.db_branch.unique_name) self.logger.info(" from %s", bzr_branch.base) # Get the history and ancestry from the branch first, to fail early # if something is wrong with the branch. self.logger.info("Retrieving history from bzrlib.") bzr_history = branch_revision_history(bzr_branch) # The BranchRevision, Revision and RevisionParent tables are only # written to by the branch-scanner, so they are not subject to # write-lock contention. Update them all in a single transaction to # improve the performance and allow garbage collection in the future. db_ancestry, db_history = self.retrieveDatabaseAncestry() (new_ancestry, branchrevisions_to_delete, revids_to_insert) = self.planDatabaseChanges(bzr_branch, bzr_history, db_ancestry, db_history) new_db_revs = (new_ancestry - getUtility(IRevisionSet).onlyPresent(new_ancestry)) self.logger.info("Adding %s new revisions.", len(new_db_revs)) for revids in iter_list_chunks(list(new_db_revs), 10000): revisions = self.getBazaarRevisions(bzr_branch, revids) self.syncRevisions(bzr_branch, revisions, revids_to_insert) self.deleteBranchRevisions(branchrevisions_to_delete) self.insertBranchRevisions(bzr_branch, revids_to_insert) transaction.commit() # Synchronize the RevisionCache for this branch. getUtility(IRevisionSet).updateRevisionCacheForBranch(self.db_branch) transaction.commit() # Notify any listeners that the tip of the branch has changed, but # before we've actually updated the database branch. initial_scan = (len(db_history) == 0) notify(events.TipChanged(self.db_branch, bzr_branch, initial_scan)) # The Branch table is modified by other systems, including the web UI, # so we need to update it in a short transaction to avoid causing # timeouts in the webapp. This opens a small race window where the # revision data is updated in the database, but the Branch table has # not been updated. Since this has no ill-effect, and can only err on # the pessimistic side (tell the user the data has not yet been # updated although it has), the race is acceptable. self.updateBranchStatus(bzr_history) notify( events.ScanCompleted(self.db_branch, bzr_branch, self.logger, new_ancestry)) transaction.commit()