def test_smoke_admining_team(self): # Smoke test, primarily for DB permissions needed by queries to work # with admining users and teams # Check the oopses in /var/tmp/lperr.test if the assertions fail. self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'MembershipNotificationJob' })) team = self.factory.makeTeam(name='a-team') with person_logged_in(team.teamowner): # This implicitly creates a job, but it is not the job under test. admining_team = self.factory.makeTeam() team.addMember( admining_team, team.teamowner, force_team_add=True) membership = getUtility(ITeamMembershipSet).getByPersonAndTeam( admining_team, team) membership.setStatus( TeamMembershipStatus.ADMIN, team.teamowner) person = self.factory.makePerson(name='murdock') with block_on_job(self): transaction.commit() pop_remote_notifications() job = getUtility(IMembershipNotificationJobSource).create( person, team, team.teamowner, TeamMembershipStatus.APPROVED, TeamMembershipStatus.ADMIN) with block_on_job(self): transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status) (notification,) = pop_remote_notifications() self.assertIn('murdock made admin by', notification['Subject'])
def test_uncommit_branch(self): """RevisionMailJob for removed revisions runs via Celery.""" db_branch, tree = self.prepare('RevisionMailJob') tree.commit('message') bzr_sync = BzrSync(db_branch) with block_on_job(): bzr_sync.syncBranchAndClose(tree.branch) pop_remote_notifications() uncommit(tree.branch) with block_on_job(): bzr_sync.syncBranchAndClose(tree.branch) self.assertEqual(1, len(pop_remote_notifications()))
def test_revisions_added(self): """RevisionsAddedJob for added revisions runs via Celery.""" # Enable RevisionMailJob to let celery activate a new connection # before trying to flush sent emails calling pop_remote_notifications. db_branch, tree = self.prepare('RevisionMailJob RevisionsAddedJob') tree.commit('message') bzr_sync = BzrSync(db_branch) with block_on_job(): bzr_sync.syncBranchAndClose(tree.branch) pop_remote_notifications() tree.commit('message2') with block_on_job(): bzr_sync.syncBranchAndClose(tree.branch) self.assertEqual(1, len(pop_remote_notifications()))
def test_jobs_with_retry_exceptions_are_queued_again(self): # A job that raises a retry error is automatically queued # and executed again. self.useFixture( FeatureFixture( {'jobs.celery.enabled_classes': 'TestJobWithRetryError'})) with block_on_job(self): job = TestJobWithRetryError() job.celeryRunOnCommit() job_id = job.job_id transaction.commit() store = IStore(Job) # block_on_job() is not aware of the Celery request # issued when the retry exception occurs, but we can # check the status of the job in the database. def job_finished(): transaction.abort() dbjob = store.find(Job, id=job_id)[0] return (dbjob.status == JobStatus.COMPLETED and dbjob.attempt_count == 2) count = 0 while count < 300 and not job_finished(): # We have a maximum wait of one minute. We should not get # anywhere close to that on developer machines (10 seconds was # working fine), but when the test suite is run in parallel we # can need a lot more time (see bug 1007576). sleep(0.2) count += 1 dbjob = store.find(Job, id=job_id)[0] self.assertEqual(2, dbjob.attempt_count) self.assertEqual(JobStatus.COMPLETED, dbjob.status)
def test_run(self): # A proper test run closes bugs. self.useFixture(FeatureFixture({ "jobs.celery.enabled_classes": "ProcessAcceptedBugsJob", })) distroseries = self.factory.makeDistroSeries() spr = self.factory.makeSourcePackageRelease( distroseries=distroseries, changelog_entry="changelog") bug = self.factory.makeBug() bugtask = self.factory.makeBugTask( target=distroseries.getSourcePackage(spr.sourcepackagename), bug=bug) self.assertEqual(BugTaskStatus.NEW, bugtask.status) job = getUtility(IProcessAcceptedBugsJobSource).create( distroseries, spr, [bug.id]) self.assertEqual(distroseries, job.distroseries) self.assertEqual(spr, job.sourcepackagerelease) self.assertEqual([bug.id], job.bug_ids) with block_on_job(self): transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status) self.assertEqual(BugTaskStatus.FIXRELEASED, bugtask.status)
def test_unsubscribe_pillar_artifacts_specific_info_types(self): # Only remove subscriptions for bugs of the specified info type. person_grantee = self.factory.makePerson(name='grantee') owner = self.factory.makePerson(name='pillarowner') pillar = self.factory.makeProduct(owner=owner) # Make bugs the person_grantee is subscribed to. bug1, ignored = self._make_subscribed_bug( person_grantee, pillar, information_type=InformationType.USERDATA) bug2, ignored = self._make_subscribed_bug( person_grantee, pillar, information_type=InformationType.PRIVATESECURITY) # Now run the job, removing access to userdata artifacts. getUtility(IRemoveArtifactSubscriptionsJobSource).create( pillar.owner, pillar=pillar, information_types=[InformationType.USERDATA]) with block_on_job(self): transaction.commit() self.assertNotIn(person_grantee, removeSecurityProxy(bug1).getDirectSubscribers()) self.assertIn(person_grantee, removeSecurityProxy(bug2).getDirectSubscribers())
def test_unsubscribe_pillar_artifacts_specific_info_types(self): # Only remove subscriptions for bugs of the specified info type. person_grantee = self.factory.makePerson(name='grantee') owner = self.factory.makePerson(name='pillarowner') pillar = self.factory.makeProduct(owner=owner) # Make bugs the person_grantee is subscribed to. bug1, ignored = self._make_subscribed_bug( person_grantee, pillar, information_type=InformationType.USERDATA) bug2, ignored = self._make_subscribed_bug( person_grantee, pillar, information_type=InformationType.PRIVATESECURITY) # Now run the job, removing access to userdata artifacts. getUtility(IRemoveArtifactSubscriptionsJobSource).create( pillar.owner, pillar=pillar, information_types=[InformationType.USERDATA]) with block_on_job(self): transaction.commit() self.assertNotIn( person_grantee, removeSecurityProxy(bug1).getDirectSubscribers()) self.assertIn( person_grantee, removeSecurityProxy(bug2).getDirectSubscribers())
def test_jobs_with_retry_exceptions_are_queued_again(self): # A job that raises a retry error is automatically queued # and executed again. self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'TestJobWithRetryError' })) with block_on_job(self): job = TestJobWithRetryError() job.celeryRunOnCommit() job_id = job.job_id transaction.commit() store = IStore(Job) # block_on_job() is not aware of the Celery request # issued when the retry exception occurs, but we can # check the status of the job in the database. def job_finished(): transaction.abort() dbjob = store.find(Job, id=job_id)[0] return ( dbjob.status == JobStatus.COMPLETED and dbjob.attempt_count == 2) count = 0 while count < 300 and not job_finished(): # We have a maximum wait of one minute. We should not get # anywhere close to that on developer machines (10 seconds was # working fine), but when the test suite is run in parallel we # can need a lot more time (see bug 1007576). sleep(0.2) count += 1 dbjob = store.find(Job, id=job_id)[0] self.assertEqual(2, dbjob.attempt_count) self.assertEqual(JobStatus.COMPLETED, dbjob.status)
def test_GenerateIncrementalDiffJob(self): """GenerateIncrementalDiffJob runs under Celery.""" self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'GenerateIncrementalDiffJob'})) with block_on_job(): job = make_runnable_incremental_diff_job(self) transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status)
def test_run(self): self.useFixture(FeatureFixture({"jobs.celery.enabled_classes": "PackageDiffJob"})) diff = create_proper_job(self.factory) with block_on_job(self): transaction.commit() self.assertEqual(PackageDiffStatus.COMPLETED, diff.status) self.assertIsNot(None, diff.diff_content)
def test_CodeReviewCommentEmailJob(self): """CodeReviewCommentEmailJob runs under Celery.""" comment = self.factory.makeCodeReviewComment() self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'CodeReviewCommentEmailJob'})) with block_on_job(): CodeReviewCommentEmailJob.create(comment) transaction.commit() self.assertEqual(2, len(pop_remote_notifications()))
def test_ReviewRequestedEmailJob(self): """ReviewRequestedEmailJob runs under Celery.""" request = self.factory.makeCodeReviewVoteReference() self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'ReviewRequestedEmailJob'})) with block_on_job(): ReviewRequestedEmailJob.create(request) transaction.commit() self.assertEqual(1, len(pop_remote_notifications()))
def test_MergeProposalUpdatedEmailJob(self): """MergeProposalUpdatedEmailJob runs under Celery.""" bmp = self.factory.makeBranchMergeProposal() self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'MergeProposalUpdatedEmailJob'})) with block_on_job(): MergeProposalUpdatedEmailJob.create( bmp, 'change', bmp.registrant) transaction.commit() self.assertEqual(2, len(pop_remote_notifications()))
def test_DerivedDistroseriesDifferenceJob(self): self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'DistroSeriesDifferenceJob', })) dsp = self.factory.makeDistroSeriesParent() package = self.factory.makeSourcePackageName() with block_on_job(): job = create_job(dsp.derived_series, package, dsp.parent_series) transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status)
def test_run(self): self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'PackageDiffJob', })) diff = create_proper_job(self.factory) with block_on_job(self): transaction.commit() self.assertEqual(PackageDiffStatus.COMPLETED, diff.status) self.assertIsNot(None, diff.diff_content)
def test_run(self): # When run it merges from_person into to_person. self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'PersonMergeJob', })) job = create_job(self.factory) transfer_email(job) from_person = job.from_person with block_on_job(self): transaction.commit() self.assertEqual(job.to_person, from_person.merged)
def test_UpdatePreviewDiffJob(self): """UpdatePreviewDiffJob runs under Celery.""" self.useBzrBranches(direct_database=True) bmp = create_example_merge(self)[0] self.factory.makeRevisionsForBranch(bmp.source_branch, count=1) self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'UpdatePreviewDiffJob'})) with block_on_job(): UpdatePreviewDiffJob.create(bmp) transaction.commit() self.assertIsNot(None, bmp.preview_diff)
def test_run(self): self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'PackageTranslationsUploadJob', })) spr, sp, job = self.makeJob() with block_on_job(self): transaction.commit() translation_import_queue = getUtility(ITranslationImportQueue) entries_in_queue = translation_import_queue.getAllEntries( target=sp).count() self.assertEqual(2, entries_in_queue)
def test_job(self): """Job runs successfully via Celery.""" fixture = FeatureFixture({"jobs.celery.enabled_classes": "InitializeDistroSeriesJob"}) self.useFixture(fixture) parent, child, test1 = create_child(self.factory) job_source = getUtility(IInitializeDistroSeriesJobSource) with block_on_job(): job_source.create(child, [parent.id]) transaction.commit() child.updatePackageCount() self.assertEqual(parent.sourcecount, child.sourcecount) self.assertEqual(parent.binarycount, child.binarycount)
def test_run(self): self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'PackageTranslationsUploadJob', })) spr, job = self.makeJob() with block_on_job(self): transaction.commit() translation_import_queue = getUtility(ITranslationImportQueue) entries_in_queue = translation_import_queue.getAllEntries( target=spr.sourcepackage).count() self.assertEqual(2, entries_in_queue)
def test_DerivedDistroseriesDifferenceJob(self): self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'DistroSeriesDifferenceJob', })) dsp = self.factory.makeDistroSeriesParent() package = self.factory.makeSourcePackageName() with block_on_job(): job = create_job(dsp.derived_series, package, dsp.parent_series) transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status)
def test_run(self): # When run it merges from_person into to_person. self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'PersonMergeJob', })) job = create_job(self.factory) transfer_email(job) from_person = job.from_person with block_on_job(self): transaction.commit() self.assertEqual(job.to_person, from_person.merged)
def test_TestJob(self): # TestJob can be run via Celery. self.useFixture( FeatureFixture({'jobs.celery.enabled_classes': 'TestJob'})) with block_on_job(self): job = TestJob() job.celeryRunOnCommit() job_id = job.job_id transaction.commit() store = IStore(Job) dbjob = store.find(Job, id=job_id)[0] self.assertEqual(JobStatus.COMPLETED, dbjob.status)
def test_TestJob(self): # TestJob can be run via Celery. self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'TestJob' })) with block_on_job(self): job = TestJob() job.celeryRunOnCommit() job_id = job.job_id transaction.commit() store = IStore(Job) dbjob = store.find(Job, id=job_id)[0] self.assertEqual(JobStatus.COMPLETED, dbjob.status)
def test_job(self): """Job runs successfully via Celery.""" fixture = FeatureFixture({ 'jobs.celery.enabled_classes': 'InitializeDistroSeriesJob', }) self.useFixture(fixture) parent, child, test1 = create_child(self.factory) job_source = getUtility(IInitializeDistroSeriesJobSource) with block_on_job(): job_source.create(child, [parent.id]) transaction.commit() child.updatePackageCount() self.assertEqual(parent.sourcecount, child.sourcecount) self.assertEqual(parent.binarycount, child.binarycount)
def test_TranslationSplitJob(self): """Ensure TranslationSplitJob runs under Celery.""" self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationSplitJob', })) upstream_item, ubuntu_item = make_shared_potmsgset(self.factory) TranslationSplitJob.create( upstream_item.potemplate.productseries, ubuntu_item.potemplate.distroseries, ubuntu_item.potemplate.sourcepackagename, ) self.assertEqual(upstream_item.potmsgset, ubuntu_item.potmsgset) with block_on_job(self): transaction.commit() self.assertNotEqual(upstream_item.potmsgset, ubuntu_item.potmsgset)
def test_WebhookDeliveryJob(self): """WebhookDeliveryJob runs under Celery.""" hook = self.factory.makeWebhook(delivery_url=u'http://example.com/ep') self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'WebhookDeliveryJob'})) with block_on_job(): job = WebhookDeliveryJob.create( hook, 'test', payload={'foo': 'bar'}) transaction.commit() self.assertEqual(JobStatus.WAITING, job.status) self.assertIn( 'Cannot connect to proxy', job.json_data['result']['connection_error'])
def test_TranslationTemplateChangeJob(self): """Ensure TranslationTemplateChangeJob runs under Celery.""" self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationTemplateChangeJob', })) potemplate = self.factory.makePOTemplate(name='template') other_ps = self.factory.makeProductSeries( product=potemplate.productseries.product) old_shared = self.factory.makePOTemplate(name='template', productseries=other_ps) new_shared = self.factory.makePOTemplate(name='renamed', productseries=other_ps) # Set up shared POTMsgSets and translations. potmsgset = self.factory.makePOTMsgSet(potemplate, sequence=1) potmsgset.setSequence(old_shared, 1) self.factory.makeCurrentTranslationMessage(potmsgset=potmsgset) # This is the identical English message in the new_shared template. target_potmsgset = self.factory.makePOTMsgSet( new_shared, sequence=1, singular=potmsgset.singular_text) # Rename the template and confirm that messages are now shared # with new_shared instead of old_shared. with celebrity_logged_in('admin'): potemplate.name = 'renamed' TranslationTemplateChangeJob.create(potemplate=potemplate) with block_on_job(self): transaction.commit() # New POTMsgSet is now different from the old one (it's been split), # but matches the target potmsgset (it's been merged into it). new_potmsgset = potemplate.getPOTMsgSets()[0] old_potmsgset = old_shared.getPOTMsgSets()[0] target_potmsgset = new_shared.getPOTMsgSets()[0] self.assertNotEqual(old_potmsgset, new_potmsgset) self.assertEqual(target_potmsgset, new_potmsgset) # Translations have been merged as well. self.assertContentEqual( [tm.translations for tm in potmsgset.getAllTranslationMessages()], [ tm.translations for tm in new_potmsgset.getAllTranslationMessages() ])
def test_run(self): # POFileJob can run via Celery. self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'POFileStatsJob'})) # Running a job causes the POFile statistics to be updated. singular = self.factory.getUniqueString() pofile = self.factory.makePOFile(side=TranslationSide.UPSTREAM) # Create a message so we have something to have statistics about. self.factory.makePOTMsgSet(pofile.potemplate, singular) # The statistics start at 0. self.assertEqual(pofile.potemplate.messageCount(), 0) pofilestatsjob.schedule(pofile.id) with block_on_job(): transaction.commit() # Now that the job ran, the statistics have been updated. self.assertEqual(pofile.potemplate.messageCount(), 1)
def test_ProcessApportBlobJob(self): # ProcessApportBlobJob runs under Celery. blob = self.factory.makeBlob(blob_file='extra_filebug_data.msg') self.useFixture(FeatureFixture( {'jobs.celery.enabled_classes': 'ProcessApportBlobJob'})) with block_on_job(self): job = getUtility(IProcessApportBlobJobSource).create(blob) transaction.commit() # Once the job has been run, its metadata will contain a dict # called processed_data, which will contain the data parsed from # the BLOB. processed_data = job.metadata.get('processed_data', None) self.assertIsNot( None, processed_data, "processed_data should not be None after the job has run.")
def test_run(self): # POFileJob can run via Celery. self.useFixture( FeatureFixture({'jobs.celery.enabled_classes': 'POFileStatsJob'})) # Running a job causes the POFile statistics to be updated. singular = self.factory.getUniqueString() pofile = self.factory.makePOFile(side=TranslationSide.UPSTREAM) # Create a message so we have something to have statistics about. self.factory.makePOTMsgSet(pofile.potemplate, singular) # The statistics start at 0. self.assertEqual(pofile.potemplate.messageCount(), 0) pofilestatsjob.schedule(pofile.id) with block_on_job(): transaction.commit() # Now that the job ran, the statistics have been updated. self.assertEqual(pofile.potemplate.messageCount(), 1)
def test_ProcessApportBlobJob(self): # ProcessApportBlobJob runs under Celery. blob = self.factory.makeBlob(blob_file='extra_filebug_data.msg') self.useFixture( FeatureFixture( {'jobs.celery.enabled_classes': 'ProcessApportBlobJob'})) with block_on_job(self): job = getUtility(IProcessApportBlobJobSource).create(blob) transaction.commit() # Once the job has been run, its metadata will contain a dict # called processed_data, which will contain the data parsed from # the BLOB. processed_data = job.metadata.get('processed_data', None) self.assertIsNot( None, processed_data, "processed_data should not be None after the job has run.")
def test_TranslationMergeJob(self): """TranslationMergeJob runs under Celery.""" self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationMergeJob', })) job = make_translation_merge_job(self.factory) product_msg = get_msg_sets(productseries=job.productseries) package_msg = get_msg_sets( sourcepackagename=job.sourcepackagename, distroseries=job.distroseries) with block_on_job(self): transaction.commit() product_msg = get_msg_sets(productseries=job.productseries) package_msg = get_msg_sets( sourcepackagename=job.sourcepackagename, distroseries=job.distroseries) self.assertEqual(package_msg, product_msg)
def test_TranslationSplitJob(self): """Ensure TranslationSplitJob runs under Celery.""" self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationSplitJob', })) upstream_item, ubuntu_item = make_shared_potmsgset(self.factory) TranslationSplitJob.create( upstream_item.potemplate.productseries, ubuntu_item.potemplate.distroseries, ubuntu_item.potemplate.sourcepackagename, ) self.assertEqual(upstream_item.potmsgset, ubuntu_item.potmsgset) with block_on_job(self): transaction.commit() self.assertNotEqual(upstream_item.potmsgset, ubuntu_item.potmsgset)
def test_TranslationMergeJob(self): """TranslationMergeJob runs under Celery.""" self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationMergeJob', })) job = make_translation_merge_job(self.factory) product_msg = get_msg_sets(productseries=job.productseries) package_msg = get_msg_sets(sourcepackagename=job.sourcepackagename, distroseries=job.distroseries) with block_on_job(self): transaction.commit() product_msg = get_msg_sets(productseries=job.productseries) package_msg = get_msg_sets(sourcepackagename=job.sourcepackagename, distroseries=job.distroseries) self.assertEqual(package_msg, product_msg)
def test_TranslationTemplateChangeJob(self): """Ensure TranslationTemplateChangeJob runs under Celery.""" self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'TranslationTemplateChangeJob', })) potemplate = self.factory.makePOTemplate(name='template') other_ps = self.factory.makeProductSeries( product=potemplate.productseries.product) old_shared = self.factory.makePOTemplate(name='template', productseries=other_ps) new_shared = self.factory.makePOTemplate(name='renamed', productseries=other_ps) # Set up shared POTMsgSets and translations. potmsgset = self.factory.makePOTMsgSet(potemplate, sequence=1) potmsgset.setSequence(old_shared, 1) self.factory.makeCurrentTranslationMessage(potmsgset=potmsgset) # This is the identical English message in the new_shared template. target_potmsgset = self.factory.makePOTMsgSet( new_shared, sequence=1, singular=potmsgset.singular_text) # Rename the template and confirm that messages are now shared # with new_shared instead of old_shared. with celebrity_logged_in('admin'): potemplate.name = 'renamed' TranslationTemplateChangeJob.create(potemplate=potemplate) with block_on_job(self): transaction.commit() # New POTMsgSet is now different from the old one (it's been split), # but matches the target potmsgset (it's been merged into it). new_potmsgset = potemplate.getPOTMsgSets()[0] old_potmsgset = old_shared.getPOTMsgSets()[0] target_potmsgset = new_shared.getPOTMsgSets()[0] self.assertNotEqual(old_potmsgset, new_potmsgset) self.assertEqual(target_potmsgset, new_potmsgset) # Translations have been merged as well. self.assertContentEqual( [tm.translations for tm in potmsgset.getAllTranslationMessages()], [tm.translations for tm in new_potmsgset.getAllTranslationMessages()])
def test_run(self): # The email is sent to all the recipients. # Create the question before turning on the feature flag to avoid # running two jobs via Celery. question = self.factory.makeQuestion() self.useFixture(FeatureFixture({ 'jobs.celery.enabled_classes': 'QuestionEmailJob', })) body = self.factory.getUniqueString('body') make_question_job( self.factory, QuestionRecipientSet.ASKER_SUBSCRIBER, question=question, body=body) with block_on_job(self): transaction.commit() transaction.commit() mail = pop_remote_notifications() self.assertEqual(2, len(mail)) for message in mail: self.assertIn(body, message.get_payload())
def test_admins_retain_subscriptions(self): # Admins subscriptions are retained even if they don't have explicit # access. product = self.factory.makeProduct() owner = self.factory.makePerson() admin = getUtility(ILaunchpadCelebrities).admin.teamowner login_person(owner) bug = self.factory.makeBug(owner=owner, target=product, information_type=InformationType.USERDATA) bug.subscribe(admin, owner) getUtility(IRemoveArtifactSubscriptionsJobSource).create( owner, [bug], pillar=product) with block_on_job(self): transaction.commit() # Check the result. admin should still be subscribed. subscribers = removeSecurityProxy(bug).getDirectSubscribers() self.assertIn(admin, subscribers)
def test_admins_retain_subscriptions(self): # Admins subscriptions are retained even if they don't have explicit # access. product = self.factory.makeProduct() owner = self.factory.makePerson() admin = getUtility(ILaunchpadCelebrities).admin.teamowner login_person(owner) bug = self.factory.makeBug( owner=owner, target=product, information_type=InformationType.USERDATA) bug.subscribe(admin, owner) getUtility(IRemoveArtifactSubscriptionsJobSource).create( owner, [bug], pillar=product) with block_on_job(self): transaction.commit() # Check the result. admin should still be subscribed. subscribers = removeSecurityProxy(bug).getDirectSubscribers() self.assertIn(admin, subscribers)
def test_run(self): # The email is sent to all the recipients. # Create the question before turning on the feature flag to avoid # running two jobs via Celery. question = self.factory.makeQuestion() self.useFixture( FeatureFixture({ 'jobs.celery.enabled_classes': 'QuestionEmailJob', })) body = self.factory.getUniqueString('body') make_question_job(self.factory, QuestionRecipientSet.ASKER_SUBSCRIBER, question=question, body=body) with block_on_job(self): transaction.commit() transaction.commit() mail = pop_remote_notifications() self.assertEqual(2, len(mail)) for message in mail: self.assertIn(body, message.get_payload())
def test_run(self): # A proper test run closes bugs. self.useFixture(FeatureFixture({ "jobs.celery.enabled_classes": "ProcessAcceptedBugsJob", })) distroseries = self.factory.makeDistroSeries() spr = self.factory.makeSourcePackageRelease( distroseries=distroseries, changelog_entry="changelog") bug = self.factory.makeBug() bugtask = self.factory.makeBugTask(target=spr.sourcepackage, bug=bug) self.assertEqual(BugTaskStatus.NEW, bugtask.status) job = getUtility(IProcessAcceptedBugsJobSource).create( distroseries, spr, [bug.id]) self.assertEqual(distroseries, job.distroseries) self.assertEqual(spr, job.sourcepackagerelease) self.assertEqual([bug.id], job.bug_ids) with block_on_job(self): transaction.commit() self.assertEqual(JobStatus.COMPLETED, job.status) self.assertEqual(BugTaskStatus.FIXRELEASED, bugtask.status)
def _assert_artifact_change_unsubscribes(self, change_callback, configure_test): # Subscribers are unsubscribed if the artifact becomes invisible # due to a change in information_type. product = self.factory.makeProduct(specification_sharing_policy=( SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY)) owner = self.factory.makePerson() [policy] = getUtility(IAccessPolicySource).find([ (product, InformationType.USERDATA) ]) # The policy grantees will lose access. policy_indirect_grantee = self.factory.makePerson() policy_team_grantee = self.factory.makeTeam( membership_policy=TeamMembershipPolicy.RESTRICTED, members=[policy_indirect_grantee]) self.factory.makeAccessPolicyGrant(policy, policy_team_grantee, owner) login_person(owner) bug = self.factory.makeBug(owner=owner, target=product, information_type=InformationType.USERDATA) branch = self.factory.makeBranch( owner=owner, product=product, information_type=InformationType.USERDATA) specification = self.factory.makeSpecification( owner=owner, product=product, information_type=InformationType.PROPRIETARY) # The artifact grantees will not lose access when the job is run. artifact_indirect_grantee = self.factory.makePerson() artifact_team_grantee = self.factory.makeTeam( membership_policy=TeamMembershipPolicy.RESTRICTED, members=[artifact_indirect_grantee]) bug.subscribe(artifact_indirect_grantee, owner) branch.subscribe(artifact_indirect_grantee, BranchSubscriptionNotificationLevel.NOEMAIL, None, CodeReviewNotificationLevel.NOEMAIL, owner) # Subscribing somebody to a specification does not automatically # create an artifact grant. spec_artifact = self.factory.makeAccessArtifact(specification) self.factory.makeAccessArtifactGrant(spec_artifact, artifact_indirect_grantee) specification.subscribe(artifact_indirect_grantee, owner) # pick one of the concrete artifacts (bug, branch or spec) # and subscribe the teams and persons. concrete_artifact, get_pillars, get_subscribers = configure_test( bug, branch, specification, policy_team_grantee, policy_indirect_grantee, artifact_team_grantee, owner) # Subscribing policy_team_grantee has created an artifact grant so we # need to revoke that to test the job. artifact = self.factory.makeAccessArtifact(concrete=concrete_artifact) getUtility(IAccessArtifactGrantSource).revokeByArtifact( [artifact], [policy_team_grantee]) # policy grantees are subscribed because the job has not been run yet. subscribers = get_subscribers(concrete_artifact) self.assertIn(policy_team_grantee, subscribers) self.assertIn(policy_indirect_grantee, subscribers) # Change artifact attributes so that it can become inaccessible for # some users. change_callback(concrete_artifact) reconcile_access_for_artifact(concrete_artifact, concrete_artifact.information_type, get_pillars(concrete_artifact)) getUtility(IRemoveArtifactSubscriptionsJobSource).create( owner, [concrete_artifact]) with block_on_job(self): transaction.commit() # Check the result. Policy grantees will be unsubscribed. subscribers = get_subscribers(concrete_artifact) self.assertNotIn(policy_team_grantee, subscribers) self.assertNotIn(policy_indirect_grantee, subscribers) self.assertIn(artifact_team_grantee, subscribers) self.assertIn(artifact_indirect_grantee, bug.getDirectSubscribers()) self.assertIn(artifact_indirect_grantee, branch.subscribers) self.assertIn(artifact_indirect_grantee, specification.subscribers)
def test_empty_branch(self): """RevisionMailJob for empty branches runs via Celery.""" db_branch, tree = self.prepare('RevisionMailJob') with block_on_job(): BzrSync(db_branch).syncBranchAndClose(tree.branch) self.assertEqual(1, len(pop_remote_notifications()))
def _assert_artifact_change_unsubscribes(self, change_callback, configure_test): # Subscribers are unsubscribed if the artifact becomes invisible # due to a change in information_type. product = self.factory.makeProduct( specification_sharing_policy=( SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY)) owner = self.factory.makePerson() [policy] = getUtility(IAccessPolicySource).find( [(product, InformationType.USERDATA)]) # The policy grantees will lose access. policy_indirect_grantee = self.factory.makePerson() policy_team_grantee = self.factory.makeTeam( membership_policy=TeamMembershipPolicy.RESTRICTED, members=[policy_indirect_grantee]) self.factory.makeAccessPolicyGrant(policy, policy_team_grantee, owner) login_person(owner) bug = self.factory.makeBug( owner=owner, target=product, information_type=InformationType.USERDATA) branch = self.factory.makeBranch( owner=owner, product=product, information_type=InformationType.USERDATA) specification = self.factory.makeSpecification( owner=owner, product=product, information_type=InformationType.PROPRIETARY) # The artifact grantees will not lose access when the job is run. artifact_indirect_grantee = self.factory.makePerson() artifact_team_grantee = self.factory.makeTeam( membership_policy=TeamMembershipPolicy.RESTRICTED, members=[artifact_indirect_grantee]) bug.subscribe(artifact_indirect_grantee, owner) branch.subscribe(artifact_indirect_grantee, BranchSubscriptionNotificationLevel.NOEMAIL, None, CodeReviewNotificationLevel.NOEMAIL, owner) # Subscribing somebody to a specification does not automatically # create an artifact grant. spec_artifact = self.factory.makeAccessArtifact(specification) self.factory.makeAccessArtifactGrant( spec_artifact, artifact_indirect_grantee) specification.subscribe(artifact_indirect_grantee, owner) # pick one of the concrete artifacts (bug, branch or spec) # and subscribe the teams and persons. concrete_artifact, get_pillars, get_subscribers = configure_test( bug, branch, specification, policy_team_grantee, policy_indirect_grantee, artifact_team_grantee, owner) # Subscribing policy_team_grantee has created an artifact grant so we # need to revoke that to test the job. artifact = self.factory.makeAccessArtifact(concrete=concrete_artifact) getUtility(IAccessArtifactGrantSource).revokeByArtifact( [artifact], [policy_team_grantee]) # policy grantees are subscribed because the job has not been run yet. subscribers = get_subscribers(concrete_artifact) self.assertIn(policy_team_grantee, subscribers) self.assertIn(policy_indirect_grantee, subscribers) # Change artifact attributes so that it can become inaccessible for # some users. change_callback(concrete_artifact) reconcile_access_for_artifact( concrete_artifact, concrete_artifact.information_type, get_pillars(concrete_artifact)) getUtility(IRemoveArtifactSubscriptionsJobSource).create( owner, [concrete_artifact]) with block_on_job(self): transaction.commit() # Check the result. Policy grantees will be unsubscribed. subscribers = get_subscribers(concrete_artifact) self.assertNotIn(policy_team_grantee, subscribers) self.assertNotIn(policy_indirect_grantee, subscribers) self.assertIn(artifact_team_grantee, subscribers) self.assertIn(artifact_indirect_grantee, bug.getDirectSubscribers()) self.assertIn(artifact_indirect_grantee, branch.subscribers) self.assertIn(artifact_indirect_grantee, specification.subscribers)