def test_checkwatches_error_recovery(self): firefox = getUtility(IProductSet).get(4) foobar = getUtility(IPersonSet).get(16) params = CreateBugParams(title="test bug one", comment="test bug one", owner=foobar, target=firefox) test_bug_one = getUtility(IBugSet).createBug(params) params = CreateBugParams(title="test bug two", comment="test bug two", owner=foobar, target=firefox) test_bug_two = getUtility(IBugSet).createBug(params) self.layer.txn.commit() # We use a test bug tracker, which is guaranteed to # try and update two bug watches - the first will # trigger a DB error, the second updates successfully. bug_tracker = TestBugTracker(test_bug_one, test_bug_two) bug_watch_updater = TestCheckwatchesMaster(self.layer.txn) self.layer.txn.commit() bug_watch_updater._updateBugTracker(bug_tracker) # We verify that the first bug watch didn't update the status, # and the second did. for bugtask in test_bug_one.bugtasks: self.assertNotEqual(bugtask.status, BugTaskStatus.FIXRELEASED) for bugtask in test_bug_two.bugtasks: self.assertEqual(bugtask.status, BugTaskStatus.FIXRELEASED)
def bugtarget_filebug(bugtarget, summary, status=None): """File a bug as the current user on the bug target and return it.""" return bugtarget.createBug( CreateBugParams(getUtility(ILaunchBag).user, summary, comment=summary, status=status))
def createBug(self, owner=None, title="A bug", comment="Nothing important.", **kwargs): with person_logged_in(owner): params = CreateBugParams( owner=owner, title=title, comment=comment, **kwargs) bug = getUtility(IBugSet).createBug(params) return bug
def _createUbuntuBugTaskLinkedToQuestion(): """Get the id of an Ubuntu bugtask linked to a question. The Ubuntu team is set as the answer contact for Ubuntu, and no-priv is used as the submitter.. """ login('*****@*****.**') sample_person = getUtility(IPersonSet).getByEmail('*****@*****.**') ubuntu_team = getUtility(IPersonSet).getByName('ubuntu-team') ubuntu_team.addLanguage(getUtility(ILanguageSet)['en']) ubuntu = getUtility(IDistributionSet).getByName('ubuntu') ubuntu.addAnswerContact(ubuntu_team, ubuntu_team.teamowner) ubuntu_question = ubuntu.newQuestion( sample_person, "Can't install Ubuntu", "I insert the install CD in the CD-ROM drive, but it won't boot.") no_priv = getUtility(IPersonSet).getByEmail('*****@*****.**') params = CreateBugParams(owner=no_priv, title="Installer fails on a Mac PPC", comment=ubuntu_question.description) bug = ubuntu.createBug(params) ubuntu_question.linkBug(bug) [ubuntu_bugtask] = bug.bugtasks login(ANONYMOUS) # Remove the notifcations for the newly created question. pop_notifications() return ubuntu_bugtask.id
def test_execute_bug_params_with_rubbish(self): user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = InformationTypeEmailCommand('informationtype', ['rubbish']) dummy_event = object() self.assertRaises(EmailProcessingError, command.execute, bug_params, dummy_event)
def test_filters_match_when_bug_is_created(self): message = u"this is an unfiltered comment" params = CreateBugParams( title=u"crashes all the time", comment=message, owner=self.submitter, status=BugTaskStatus.NEW) bug = self.product.createBug(params) notification = fetch_notifications(self.subscriber, bug).one() self.assertEqual(notification.message.text_contents, message)
def execute(self, parsed_msg, filealias): """See IBugEmailCommand.""" self._ensureNumberOfArguments() bugid = self.string_args[0] if bugid == 'new': message = getUtility(IMessageSet).fromEmail( parsed_msg.as_string(), owner=getUtility(ILaunchBag).user, filealias=filealias, parsed_message=parsed_msg) description = message.text_contents if description.strip() == '': # The report for a new bug must contain an affects command, # since the bug must have at least one task raise EmailProcessingError(get_error_message( 'no-affects-target-on-submit.txt', error_templates=error_templates), stop_processing=True) # Check the message validator. validator = IBugAddForm['comment'].validate try: validator(description) except TooLong: raise EmailProcessingError( 'The description is too long. If you have lots of ' 'text to add, use an attachment instead.', stop_processing=True) except ValidationError as e: # More a just in case than any real expectation of getting # something. raise EmailProcessingError(str(e), stop_processing=True) params = CreateBugParams(msg=message, title=message.title, owner=getUtility(ILaunchBag).user) return params, None else: try: bugid = int(bugid) except ValueError: raise EmailProcessingError( get_error_message('bug-argument-mismatch.txt', error_templates=error_templates)) try: bug = getUtility(IBugSet).get(bugid) except NotFoundError: bug = None if bug is None or not check_permission('launchpad.View', bug): raise EmailProcessingError( get_error_message('no-such-bug.txt', error_templates=error_templates, bug_id=bugid)) return bug, None
def test_filters_do_not_match_when_bug_is_created(self): message = u"this is a filtered comment" params = CreateBugParams( title=u"crashes all the time", comment=message, owner=self.submitter, status=BugTaskStatus.TRIAGED, importance=BugTaskImportance.HIGH) bug = self.product.createBug(params) notifications = fetch_notifications(self.subscriber, bug) self.assertTrue(notifications.is_empty())
def test_execute_bug_params(self): user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = TagEmailCommand('tag', ['ui', 'trivial']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertContentEqual(['ui', 'trivial'], bug_params.tags) self.assertEqual(dummy_event, event)
def test_execute_bug_params(self): user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = SummaryEmailCommand('summary', ['new title']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual('new title', bug_params.title) self.assertEqual(dummy_event, event)
def test_execute_bug_params(self): user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = PrivateEmailCommand('private', ['yes']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual(InformationType.USERDATA, bug_params.information_type) self.assertEqual(dummy_event, event)
def test_execute_bug_params_one_subscriber(self): user = self.factory.makePerson() login_person(user) subscriber = self.factory.makePerson() bug_params = CreateBugParams(title='bug title', owner=user) command = SubscribeEmailCommand('subscribe', [subscriber.name]) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertContentEqual([subscriber], bug_params.subscribers) self.assertEqual(dummy_event, event)
def test_execute_bug_params(self): # duplicate does nothing because the is not yet a bug. # Any value can be used for the bug is. user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = DuplicateEmailCommand('duplicate', ['non-existent']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual(dummy_event, event)
def test_execute_bug_params(self): user = self.factory.makePerson() login_person(user) cve = self.factory.makeCVE('1999-1717') bug_params = CreateBugParams(title='bug title', owner=user) command = CVEEmailCommand('cve', ['1999-1717']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual(cve, params.cve) self.assertEqual(dummy_event, event)
def test_execute_bug_params(self): user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams(title='bug title', owner=user) command = InformationTypeEmailCommand('informationtype', ['publicsecurity']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual(InformationType.PUBLICSECURITY, bug_params.information_type) self.assertTrue(IObjectModifiedEvent.providedBy(event))
def distroseries_sourcepackage_filebug(distroseries, summary, status=None): params = CreateBugParams( getUtility(ILaunchBag).user, summary, comment=summary, status=status, target=distroseries.distribution.getSourcePackage('alsa-utils')) bug = distroseries.distribution.createBug(params) nomination = bug.addNomination(distroseries.distribution.owner, distroseries) nomination.approve(distroseries.distribution.owner) return bug
def createBug(self, owner, title, description, target, information_type=None, tags=None, security_related=None, private=None): """See `IMaloneApplication`.""" if (information_type is None and (security_related is not None or private is not None)): # Adapt the deprecated args to information_type. information_type = convert_to_information_type( private, security_related) params = CreateBugParams( title=title, comment=description, owner=owner, information_type=information_type, tags=tags, target=target) return getUtility(IBugSet).createBug(params)
def create_action(self, action, data): """Create a Bug from a Question.""" question = self.context with notify_modified(question, ['bugs']): params = CreateBugParams(owner=self.user, title=data['title'], comment=data['description']) bug = question.target.createBug(params) question.linkBug(bug, user=self.user) bug.subscribe(question.owner, self.user) self.request.response.addNotification( _('Thank you! Bug #$bugid created.', mapping={'bugid': bug.id})) self.next_url = canonical_url(bug)
def _createProductBugtask(self, product_name, milestone_name): """Create a bugtask for a product, assign the task to a milestone.""" personset = getUtility(IPersonSet) sample_person = personset.getByEmail('*****@*****.**') product = getUtility(IProductSet)[product_name] milestone = product.getMilestone(milestone_name) params = CreateBugParams(title='Milestone test bug for %s' % product_name, comment='comment', owner=sample_person, status=BugTaskStatus.CONFIRMED) bug = product.createBug(params) [bugtask] = bug.bugtasks bugtask.milestone = milestone
def importBug(self, external_bugtracker, bugtracker, bug_target, remote_bug): """Import a remote bug into Launchpad. :param external_bugtracker: An ISupportsBugImport, which talks to the external bug tracker. :param bugtracker: An IBugTracker, to which the created bug watch will be linked. :param bug_target: An IBugTarget, to which the created bug will be linked. :param remote_bug: The remote bug id as a string. :return: The created Launchpad bug. """ assert IDistribution.providedBy(bug_target), ( 'Only imports of bugs for a distribution is implemented.') reporter_name, reporter_email = ( external_bugtracker.getBugReporter(remote_bug)) reporter = getUtility(IPersonSet).ensurePerson( reporter_email, reporter_name, PersonCreationRationale.BUGIMPORT, comment='when importing bug #%s from %s' % ( remote_bug, external_bugtracker.baseurl)) package_name = external_bugtracker.getBugTargetName(remote_bug) package = bug_target.getSourcePackage(package_name) if package is not None: bug_target = package else: self.warning( 'Unknown %s package (#%s at %s): %s' % ( bug_target.name, remote_bug, external_bugtracker.baseurl, package_name)) summary, description = ( external_bugtracker.getBugSummaryAndDescription(remote_bug)) bug = bug_target.createBug( CreateBugParams( reporter, summary, description, subscribe_owner=False, filed_by=getUtility(ILaunchpadCelebrities).bug_watch_updater)) [added_task] = bug.bugtasks bug_watch = getUtility(IBugWatchSet).createBugWatch( bug=bug, owner=getUtility(ILaunchpadCelebrities).bug_watch_updater, bugtracker=bugtracker, remotebug=remote_bug) added_task.bugwatch = bug_watch # Need to flush databse updates, so that the bug watch knows it # is linked from a bug task. flush_database_updates() return bug
def test_execute_bug_params_distribution(self): user = self.factory.makePerson() login_person(user) distribution = self.factory.makeDistribution(name='fnord') message = self.factory.makeMessage(subject='bug title', content='borked\n affects fnord') command = AffectsEmailCommand('affects', ['fnord']) bug_params = CreateBugParams(title='bug title', msg=message, owner=user) bugtask, bugtask_event, bug_event = command.execute(bug_params, None) self.assertEqual(distribution, bugtask.target) self.assertEqual('bug title', bugtask.bug.title) self.assertTrue(IObjectCreatedEvent.providedBy(bugtask_event)) self.assertTrue(IObjectCreatedEvent.providedBy(bug_event))
def create_bug_from_strings( distribution, sourcepackagename, owner, summary, description, status=None): """Create and return a bug.""" distroset = getUtility(IDistributionSet) distribution = distroset.getByName(distribution) personset = getUtility(IPersonSet) owner = personset.getByName(owner) bugset = getUtility(IBugSet) params = CreateBugParams( owner, summary, description, status=status, target=distribution.getSourcePackage(sourcepackagename)) return bugset.createBug(params)
def test_execute_bug_params_with_security(self): # BugSet.createBug() requires new security bugs to be private. user = self.factory.makePerson() login_person(user) bug_params = CreateBugParams( title='bug title', owner=user, information_type=InformationType.PRIVATESECURITY) command = PrivateEmailCommand('private', ['no']) dummy_event = object() params, event = command.execute(bug_params, dummy_event) self.assertEqual(bug_params, params) self.assertEqual(InformationType.PRIVATESECURITY, bug_params.information_type) self.assertEqual(dummy_event, event)
def test_execute_bug_params_productseries(self): product = self.factory.makeProduct(name='fnord') login_person(product.owner) series = self.factory.makeProductSeries(name='pting', product=product) message = self.factory.makeMessage( subject='bug title', content='borked\n affects fnord/pting') command = AffectsEmailCommand('affects', ['fnord/pting']) bug_params = CreateBugParams(title='bug title', msg=message, owner=product.owner) bugtask, bugtask_event, bug_event = command.execute(bug_params, None) self.assertEqual(series, bugtask.target) self.assertEqual('bug title', bugtask.bug.title) self.assertEqual(2, len(bugtask.bug.bugtasks)) self.assertTrue(IObjectCreatedEvent.providedBy(bugtask_event)) self.assertTrue(IObjectCreatedEvent.providedBy(bug_event))
def create_action(self, action, data): """Create a Bug from a Question.""" question = self.context unmodifed_question = Snapshot(question, providing=providedBy(question)) params = CreateBugParams(owner=self.user, title=data['title'], comment=data['description']) bug = question.target.createBug(params) question.linkBug(bug) bug.subscribe(question.owner, self.user) bug_added_event = ObjectModifiedEvent(question, unmodifed_question, ['bugs']) notify(bug_added_event) self.request.response.addNotification( _('Thank you! Bug #$bugid created.', mapping={'bugid': bug.id})) self.next_url = canonical_url(bug)
def test_manage_notifications_message_is_included(self): # Set up a subscription to a product. subscriber = self.factory.makePerson() submitter = self.factory.makePerson() product = self.factory.makeProduct( bug_supervisor=submitter) product.addSubscription(subscriber, subscriber) # Create a bug that will match the subscription. bug = product.createBug(CreateBugParams( title=self.factory.getUniqueString(), comment=self.factory.getUniqueString(), owner=submitter)) notification = fetch_notifications(subscriber, bug).one() _, _, (message,) = construct_email_notifications([notification]) payload = message.get_payload() self.assertThat(payload, Contains( 'To manage notifications about this bug go to:\nhttp://'))
def _createProductSeriesBugtask(self, product_name, product_series_name, milestone_name): """Create a bugtask for a productseries, assign it to a milestone.""" personset = getUtility(IPersonSet) sample_person = personset.getByEmail('*****@*****.**') product = getUtility(IProductSet)[product_name] series = product.getSeries(product_series_name) milestone = product.getMilestone(milestone_name) params = CreateBugParams(title='Milestone test bug for %s series' % product_name, comment='comment', owner=sample_person, status=BugTaskStatus.CONFIRMED) bug = product.createBug(params) getUtility(IBugTaskSet).createTask(bug, sample_person, series) for bugtask in bug.bugtasks: if bugtask.productseries is not None: bugtask.milestone = milestone
def test_execute_bug_params_distroseries_sourcepackage(self): distribution = self.factory.makeDistribution(name='fnord') login_person(distribution.owner) series = self.factory.makeDistroSeries(name='pting', distribution=distribution) package = self.factory.makeSourcePackage(sourcepackagename='snarf', distroseries=series, publish=True) message = self.factory.makeMessage( subject='bug title', content='borked\n affects fnord/pting/snarf') command = AffectsEmailCommand('affects', ['fnord/pting/snarf']) bug_params = CreateBugParams(title='bug title', msg=message, owner=distribution.owner) bugtask, bugtask_event, bug_event = command.execute(bug_params, None) self.assertEqual(package, bugtask.target) self.assertEqual('bug title', bugtask.bug.title) self.assertEqual(2, len(bugtask.bug.bugtasks)) self.assertTrue(IObjectCreatedEvent.providedBy(bugtask_event)) self.assertTrue(IObjectCreatedEvent.providedBy(bug_event))
def create_old_bug( title, days_old, target, status=BugTaskStatus.INCOMPLETE, with_message=True, external_bugtracker=None, assignee=None, milestone=None, duplicateof=None): """Create an aged bug. :title: A string. The bug title for testing. :days_old: An int. The bug's age in days. :target: A BugTarget. The bug's target. :status: A BugTaskStatus. The status of the bug's single bugtask. :with_message: A Bool. Whether to create a reply message. :external_bugtracker: An external bug tracker which is watched for this bug. """ no_priv = getUtility(IPersonSet).getByEmail('*****@*****.**') params = CreateBugParams( owner=no_priv, title=title, comment='Something is broken.') bug = target.createBug(params) if duplicateof is not None: bug.markAsDuplicate(duplicateof) sample_person = getUtility(IPersonSet).getByEmail('*****@*****.**') if with_message is True: bug.newMessage( owner=sample_person, subject='Something is broken.', content='Can you provide more information?') bugtask = bug.bugtasks[0] bugtask.transitionToStatus( status, sample_person) if assignee is not None: bugtask.transitionToAssignee(assignee) bugtask.milestone = milestone if external_bugtracker is not None: getUtility(IBugWatchSet).createBugWatch(bug=bug, owner=sample_person, bugtracker=external_bugtracker, remotebug='1234') date = datetime.now(UTC) - timedelta(days=days_old) removeSecurityProxy(bug).date_last_updated = date return bugtask
def importBug(self, bugnode): assert not self.haveImportedBug(bugnode), ( 'the bug has already been imported') bug_id = int(bugnode.get('id')) self.logger.info('Handling bug %d', bug_id) comments = get_all(bugnode, 'comment') owner = self.getPerson(get_element(bugnode, 'reporter')) datecreated = parse_date(get_value(bugnode, 'datecreated')) title = get_value(bugnode, 'title') private = get_value(bugnode, 'private') == 'True' security_related = get_value(bugnode, 'security_related') == 'True' information_type = convert_to_information_type(private, security_related) if owner is None: owner = self.bug_importer commentnode = comments.pop(0) msg = self.createMessage(commentnode, defaulttitle=title) bug = self.product.createBug( CreateBugParams(msg=msg, datecreated=datecreated, title=title, information_type=information_type, owner=owner)) bugtask = bug.bugtasks[0] self.logger.info('Creating Launchpad bug #%d', bug.id) # Remaining setup for first comment self.createAttachments(bug, msg, commentnode) bug.findCvesInText(msg.text_contents, bug.owner) # Process remaining comments for commentnode in comments: msg = self.createMessage(commentnode, defaulttitle=bug.followup_subject()) bug.linkMessage(msg) self.createAttachments(bug, msg, commentnode) bug.name = get_value(bugnode, 'nickname') description = get_value(bugnode, 'description') if description: bug.description = description for cvenode in get_all(bugnode, 'cves/cve'): cve = getUtility(ICveSet)[get_text(cvenode)] if cve is None: raise BugXMLSyntaxError('Unknown CVE: %s' % get_text(cvenode)) bug.linkCVE(cve, self.bug_importer, check_permissions=False) tags = [] for tagnode in get_all(bugnode, 'tags/tag'): tags.append(get_text(tagnode)) bug.tags = tags # Create bugwatches bugwatchset = getUtility(IBugWatchSet) for watchnode in get_all(bugnode, 'bugwatches/bugwatch'): try: bugtracker, remotebug = bugwatchset.extractBugTrackerAndBug( watchnode.get('href')) except NoBugTrackerFound as exc: self.logger.debug('Registering bug tracker for %s', exc.base_url) bugtracker = getUtility(IBugTrackerSet).ensureBugTracker( exc.base_url, self.bug_importer, exc.bugtracker_type) remotebug = exc.remote_bug bugwatchset.createBugWatch(bug, self.bug_importer, bugtracker, remotebug) for subscribernode in get_all(bugnode, 'subscriptions/subscriber'): person = self.getPerson(subscribernode) if person is not None: bug.subscribe(person, owner) # set up bug task bugtask.datecreated = datecreated bugtask.transitionToImportance( get_enum_value(BugTaskImportance, get_value(bugnode, 'importance')), self.bug_importer) bugtask.transitionToStatus( get_enum_value(BugTaskStatus, get_value(bugnode, 'status')), self.bug_importer) bugtask.transitionToAssignee( self.getPerson(get_element(bugnode, 'assignee'))) bugtask.milestone = self.getMilestone(get_value(bugnode, 'milestone')) # Make a note of the import in the activity log: getUtility(IBugActivitySet).new(bug=bug.id, datechanged=UTC_NOW, person=self.bug_importer, whatchanged='bug', message='Imported external bug #%s' % bug_id) self.handleDuplicate(bug, bug_id, get_value(bugnode, 'duplicateof')) self.bug_id_map[bug_id] = bug.id # clear any pending bug notifications bug.expireNotifications() return bug