def test_LoginTokenPruner(self): store = IMasterStore(LoginToken) now = datetime.now(UTC) switch_dbuser('testadmin') # It is configured as a daily task. self.assertTrue( LoginTokenPruner in DailyDatabaseGarbageCollector.tunable_loops) # Create a token that will be pruned. old_token = LoginToken( email='whatever', tokentype=LoginTokenType.NEWACCOUNT) old_token.date_created = now - timedelta(days=666) old_token_id = old_token.id store.add(old_token) # Create a token that will not be pruned. current_token = LoginToken( email='whatever', tokentype=LoginTokenType.NEWACCOUNT) current_token_id = current_token.id store.add(current_token) # Run the pruner. Batching is tested by the BulkPruner tests so # no need to repeat here. switch_dbuser('garbo_daily') pruner = LoginTokenPruner(logging.getLogger('garbo')) while not pruner.isDone(): pruner(10) pruner.cleanUp() # Only the old LoginToken is gone. self.assertEqual( store.find(LoginToken, id=old_token_id).count(), 0) self.assertEqual( store.find(LoginToken, id=current_token_id).count(), 1)
def new(cls, job_type, status=BuildStatus.NEEDSBUILD, date_created=None, builder=None, archive=None): """See `IBuildFarmJobSource`.""" build_farm_job = BuildFarmJob( job_type, status, date_created, builder, archive) store = IMasterStore(BuildFarmJob) store.add(build_farm_job) return build_farm_job
def new(self, registrant, name, display_name, distro_series, build_channels, date_created=DEFAULT): """See `ISnapBaseSet`.""" store = IMasterStore(SnapBase) snap_base = SnapBase( registrant, name, display_name, distro_series, build_channels, date_created=date_created) store.add(snap_base) return snap_base
def new(self, distribution, root_dir, base_url, copy_base_url): """Make and return a new `PublisherConfig`.""" store = IMasterStore(PublisherConfig) pubconf = PublisherConfig() pubconf.distribution = distribution pubconf.root_dir = root_dir pubconf.base_url = base_url pubconf.copy_base_url = copy_base_url store.add(pubconf) return pubconf
def storeAssociation(self, server_url, association): """See `OpenIDStore`.""" store = IMasterStore(self.Association) db_assoc = store.get( self.Association, (server_url.decode('UTF-8'), association.handle.decode('ASCII'))) if db_assoc is None: db_assoc = self.Association(server_url, association) store.add(db_assoc) else: db_assoc.update(association)
def newPackagesetUploader( self, archive, person, packageset, explicit=False): """See `IArchivePermissionSet`.""" packageset = self._nameToPackageset(packageset) store = IMasterStore(ArchivePermission) # First see whether we have a matching permission in the database # already. query = ''' SELECT ap.id FROM archivepermission ap, teamparticipation tp WHERE ap.person = tp.team AND tp.person = ? AND ap.packageset = ? AND ap.archive = ? ''' query = SQL(query, (person.id, packageset.id, archive.id)) permissions = list( store.find( ArchivePermission, ArchivePermission.id.is_in(query))) if len(permissions) > 0: # Found permissions in the database, does the 'explicit' flag # have the requested value? conflicting = [permission for permission in permissions if permission.explicit != explicit] if len(conflicting) > 0: # At least one permission with conflicting 'explicit' flag # value exists already. cperm = conflicting[0] raise ValueError( "Permission for package set '%s' already exists for %s " "but with a different 'explicit' flag value (%s)." % (packageset.name, cperm.person.name, cperm.explicit)) else: # No conflicts, does the requested permission exist already? existing = [permission for permission in permissions if (permission.explicit == explicit and permission.person == person and permission.packageset == packageset)] assert len(existing) <= 1, ( "Too many permissions for %s and %s" % (person.name, packageset.name)) if len(existing) == 1: # The existing permission matches, just return it. return existing[0] # The requested permission does not exist yet. Insert it into the # database. permission = ArchivePermission( archive=archive, person=person, packageset=packageset, permission=ArchivePermissionType.UPLOAD, explicit=explicit) store.add(permission) return permission
def new(self, derived_series, parent_series, initialized, is_overlay=False, pocket=None, component=None, ordering=1): """Make and return a new `DistroSeriesParent`.""" store = IMasterStore(DistroSeriesParent) dsp = DistroSeriesParent() dsp.derived_series = derived_series dsp.parent_series = parent_series dsp.initialized = initialized dsp.is_overlay = is_overlay dsp.pocket = pocket dsp.component = component dsp.ordering = ordering store.add(dsp) return dsp
def new(cls, distroseries, recipe, requester, archive, pocket=None, date_created=None, duration=None): """See `ISourcePackageRecipeBuildSource`.""" store = IMasterStore(SourcePackageRecipeBuild) if pocket is None: pocket = PackagePublishingPocket.RELEASE if date_created is None: date_created = UTC_NOW build_farm_job = getUtility(IBuildFarmJobSource).new( cls.job_type, BuildStatus.NEEDSBUILD, date_created, None, archive) spbuild = cls( build_farm_job, distroseries, recipe, requester, archive, pocket, date_created) store.add(spbuild) return spbuild
def new(self, derived_series, parent_series, initialized, is_overlay=False, inherit_overrides=False, pocket=None, component=None, ordering=1): """Make and return a new `DistroSeriesParent`.""" store = IMasterStore(DistroSeriesParent) dsp = DistroSeriesParent() dsp.derived_series = derived_series dsp.parent_series = parent_series dsp.initialized = initialized dsp.is_overlay = is_overlay dsp.inherit_overrides = inherit_overrides dsp.pocket = pocket dsp.component = component dsp.ordering = ordering store.add(dsp) return dsp
def new(self, requester, snap, archive, distro_arch_series, pocket, channels=None, date_created=DEFAULT, store_upload_metadata=None, build_request=None): """See `ISnapBuildSet`.""" store = IMasterStore(SnapBuild) build_farm_job = getUtility(IBuildFarmJobSource).new( SnapBuild.job_type, BuildStatus.NEEDSBUILD, date_created, None, archive) snapbuild = SnapBuild( build_farm_job, requester, snap, archive, distro_arch_series, pocket, channels, distro_arch_series.processor, not distro_arch_series.processor.supports_nonvirtualized or snap.require_virtualized or archive.require_virtualized, date_created, store_upload_metadata=store_upload_metadata, build_request=build_request) store.add(snapbuild) return snapbuild
def useNonce(self, server_url, timestamp, salt): """See `OpenIDStore`.""" # If the nonce is too far from the present time, it is not valid. if abs(timestamp - time.time()) > nonce.SKEW: return False server_url = server_url.decode('UTF-8') salt = salt.decode('ASCII') store = IMasterStore(self.Nonce) old_nonce = store.get(self.Nonce, (server_url, timestamp, salt)) if old_nonce is not None: # The nonce has already been seen, so reject it. return False # Record the nonce so it can't be used again. store.add(self.Nonce(server_url, timestamp, salt)) return True
def new(self, registrant, name, display_name, status, preferred_distro_series=None, date_created=DEFAULT): """See `ISnappySeriesSet`.""" store = IMasterStore(SnappySeries) snappy_series = SnappySeries( registrant, name, display_name, status, preferred_distro_series=preferred_distro_series, date_created=date_created) store.add(snappy_series) return snappy_series
def new(cls, distroseries, recipe, requester, archive, pocket=None, date_created=None, duration=None): """See `ISourcePackageRecipeBuildSource`.""" store = IMasterStore(SourcePackageRecipeBuild) if pocket is None: pocket = PackagePublishingPocket.RELEASE if date_created is None: date_created = UTC_NOW build_farm_job = getUtility(IBuildFarmJobSource).new( cls.job_type, BuildStatus.NEEDSBUILD, date_created, None, archive) spbuild = cls(build_farm_job, distroseries, recipe, requester, archive, pocket, date_created) store.add(spbuild) return spbuild
def new(cls, name, owner, registrant, description=None, configuration=None, branches=None): """See `IBranchMergeQueueSource`.""" store = IMasterStore(BranchMergeQueue) if configuration is None: configuration = unicode(simplejson.dumps({})) queue = cls() queue.name = name queue.owner = owner queue.registrant = registrant queue.description = description queue.configuration = configuration if branches is not None: for branch in branches: branch.addToQueue(queue) store.add(queue) return queue
def __init__(self, *args, **kwargs): """Extended version of the SQLObjectBase constructor. We force use of the master Store. We refetch any parameters from different stores from the correct master Store. """ # Make it simple to write dumb-invalidators - initialized # _cached_properties to a valid list rather than just-in-time # creation. self._cached_properties = [] store = IMasterStore(self.__class__) # The constructor will fail if objects from a different Store # are passed in. We need to refetch these objects from the correct # master Store if necessary so the foreign key references can be # constructed. # XXX StuartBishop 2009-03-02 bug=336867: We probably want to remove # this code - there are enough other places developers have to be # aware of the replication # set boundaries. Why should # Person(..., account=an_account) work but # some_person.account = an_account fail? for key, argument in kwargs.items(): argument = removeSecurityProxy(argument) if not isinstance(argument, Storm): continue argument_store = Store.of(argument) if argument_store is not store: new_argument = store.find(argument.__class__, id=argument.id).one() assert new_argument is not None, ( '%s not yet synced to this store' % repr(argument)) kwargs[key] = new_argument store.add(self) try: self._create(None, **kwargs) except: store.remove(self) raise
def __init__(self, *args, **kwargs): """Extended version of the SQLObjectBase constructor. We force use of the master Store. We refetch any parameters from different stores from the correct master Store. """ # Make it simple to write dumb-invalidators - initialized # _cached_properties to a valid list rather than just-in-time # creation. self._cached_properties = [] store = IMasterStore(self.__class__) # The constructor will fail if objects from a different Store # are passed in. We need to refetch these objects from the correct # master Store if necessary so the foreign key references can be # constructed. # XXX StuartBishop 2009-03-02 bug=336867: We probably want to remove # this code - there are enough other places developers have to be # aware of the replication # set boundaries. Why should # Person(..., account=an_account) work but # some_person.account = an_account fail? for key, argument in kwargs.items(): argument = removeSecurityProxy(argument) if not isinstance(argument, Storm): continue argument_store = Store.of(argument) if argument_store is not store: new_argument = store.find( argument.__class__, id=argument.id).one() assert new_argument is not None, ( '%s not yet synced to this store' % repr(argument)) kwargs[key] = new_argument store.add(self) try: self._create(None, **kwargs) except: store.remove(self) raise
def new(registrant, owner, name, recipe, description, distroseries=None, daily_build_archive=None, build_daily=False, date_created=DEFAULT): """See `ISourcePackageRecipeSource.new`.""" store = IMasterStore(SourcePackageRecipe) sprecipe = SourcePackageRecipe() builder_recipe = SourcePackageRecipeData.getParsedRecipe(recipe) SourcePackageRecipeData(builder_recipe, sprecipe) sprecipe.registrant = registrant sprecipe.owner = owner sprecipe.name = name if distroseries is not None: for distroseries_item in distroseries: sprecipe.distroseries.add(distroseries_item) sprecipe.description = description sprecipe.daily_build_archive = daily_build_archive sprecipe.build_daily = build_daily sprecipe.date_created = date_created sprecipe.date_last_modified = date_created store.add(sprecipe) return sprecipe
def test_OAuthNoncePruner(self): now = datetime.now(UTC) timestamps = [ now - timedelta(days=2), # Garbage now - timedelta(days=1) - timedelta(seconds=60), # Garbage now - timedelta(days=1) + timedelta(seconds=60), # Not garbage now, # Not garbage ] switch_dbuser('testadmin') store = IMasterStore(OAuthNonce) # Make sure we start with 0 nonces. self.failUnlessEqual(store.find(OAuthNonce).count(), 0) for timestamp in timestamps: store.add(OAuthNonce( access_token=OAuthAccessToken.get(1), request_timestamp=timestamp, nonce=str(timestamp))) transaction.commit() # Make sure we have 4 nonces now. self.failUnlessEqual(store.find(OAuthNonce).count(), 4) self.runFrequently( maximum_chunk_size=60) # 1 minute maximum chunk size store = IMasterStore(OAuthNonce) # Now back to two, having removed the two garbage entries. self.failUnlessEqual(store.find(OAuthNonce).count(), 2) # And none of them are older than a day. # Hmm... why is it I'm putting tz aware datetimes in and getting # naive datetimes back? Bug in the SQLObject compatibility layer? # Test is still fine as we know the timezone. self.failUnless( store.find( Min(OAuthNonce.request_timestamp)).one().replace(tzinfo=UTC) >= now - timedelta(days=1))
def new( self, name, description, owner, distroseries=None, related_set=None): """See `IPackagesetSet`.""" store = IMasterStore(Packageset) packagesetgroup = None if related_set is not None: # Use the packagesetgroup of the `related_set`. packagesetgroup = related_set.packagesetgroup else: # We create the related internal PackagesetGroup for this # packageset so that we can later see related package sets across # distroseries. packagesetgroup = PackagesetGroup() packagesetgroup.owner = owner store.add(packagesetgroup) if distroseries is None: ubuntu = getUtility(IDistributionSet).getByName('ubuntu') distroseries = ubuntu.currentseries packageset = Packageset() packageset.packagesetgroup = packagesetgroup packageset.name = name packageset.description = description packageset.owner = owner packageset.distroseries = distroseries store.add(packageset) # We need to ensure that the cached statements are flushed so that # the duplicate name constraint gets triggered here. try: store.flush() except IntegrityError: raise DuplicatePackagesetName() return packageset
def new(registrant, owner, name, recipe, description, distroseries=None, daily_build_archive=None, build_daily=False, date_created=DEFAULT): """See `ISourcePackageRecipeSource.new`.""" store = IMasterStore(SourcePackageRecipe) sprecipe = SourcePackageRecipe() builder_recipe, recipe_branch_type = ( getUtility(IRecipeBranchSource).getParsedRecipe(recipe)) SourcePackageRecipeData(builder_recipe, recipe_branch_type, sprecipe) sprecipe.registrant = registrant sprecipe.owner = owner sprecipe.name = name if distroseries is not None: for distroseries_item in distroseries: sprecipe.distroseries.add(distroseries_item) sprecipe.description = description sprecipe.daily_build_archive = daily_build_archive sprecipe.build_daily = build_daily sprecipe.date_created = date_created sprecipe.date_last_modified = date_created store.add(sprecipe) return sprecipe
def test_OpenIDConsumerNoncePruner(self): now = int(time.mktime(time.gmtime())) MINUTES = 60 HOURS = 60 * 60 DAYS = 24 * HOURS timestamps = [ now - 2 * DAYS, # Garbage now - 1 * DAYS - 1 * MINUTES, # Garbage now - 1 * DAYS + 1 * MINUTES, # Not garbage now, # Not garbage ] switch_dbuser('testadmin') store = IMasterStore(OpenIDConsumerNonce) # Make sure we start with 0 nonces. self.failUnlessEqual(store.find(OpenIDConsumerNonce).count(), 0) for timestamp in timestamps: store.add(OpenIDConsumerNonce( u'http://server/', timestamp, u'aa')) transaction.commit() # Make sure we have 4 nonces now. self.failUnlessEqual(store.find(OpenIDConsumerNonce).count(), 4) # Run the garbage collector. self.runFrequently(maximum_chunk_size=60) # 1 minute maximum chunks. store = IMasterStore(OpenIDConsumerNonce) # We should now have 2 nonces. self.failUnlessEqual(store.find(OpenIDConsumerNonce).count(), 2) # And none of them are older than 1 day earliest = store.find(Min(OpenIDConsumerNonce.timestamp)).one() self.failUnless( earliest >= now - 24 * 60 * 60, 'Still have old nonces')
def new(self, requester, livefs, archive, distro_arch_series, pocket, unique_key=None, metadata_override=None, version=None, date_created=DEFAULT): """See `ILiveFSBuildSet`.""" store = IMasterStore(LiveFSBuild) build_farm_job = getUtility(IBuildFarmJobSource).new( LiveFSBuild.job_type, BuildStatus.NEEDSBUILD, date_created, None, archive) livefsbuild = LiveFSBuild( build_farm_job, requester, livefs, archive, distro_arch_series, pocket, distro_arch_series.processor, not distro_arch_series.processor.supports_nonvirtualized or livefs.require_virtualized or archive.require_virtualized, unique_key, metadata_override, version, date_created) store.add(livefsbuild) return livefsbuild
def new(self, name, description, owner, distroseries, related_set=None): """See `IPackagesetSet`.""" store = IMasterStore(Packageset) try: self.getByName(distroseries, name) raise DuplicatePackagesetName except NoSuchPackageSet: pass packagesetgroup = None if related_set is not None: # Use the packagesetgroup of the `related_set`. packagesetgroup = related_set.packagesetgroup else: # We create the related internal PackagesetGroup for this # packageset so that we can later see related package sets across # distroseries. packagesetgroup = PackagesetGroup() packagesetgroup.owner = owner store.add(packagesetgroup) packageset = Packageset() packageset.packagesetgroup = packagesetgroup packageset.name = name packageset.description = description packageset.owner = owner packageset.distroseries = distroseries store.add(packageset) # Explicit flush since it's common to use Packageset.id immediately # after creation. store.flush() return packageset
def new(distro_series_difference, owner, comment): """See `IDistroSeriesDifferenceCommentSource`.""" msgid = make_msgid('distroseriesdifference') message = Message( parent=None, owner=owner, rfc822msgid=msgid, subject=distro_series_difference.title) MessageChunk(message=message, content=comment, sequence=1) store = IMasterStore(DistroSeriesDifferenceComment) dsd_comment = DistroSeriesDifferenceComment() dsd_comment.distro_series_difference = distro_series_difference dsd_comment.message = message comment = store.add(dsd_comment) store.flush() return comment
def new(distro_series_difference, owner, comment): """See `IDistroSeriesDifferenceCommentSource`.""" msgid = make_msgid('distroseriesdifference') message = Message(parent=None, owner=owner, rfc822msgid=msgid, subject=distro_series_difference.title) MessageChunk(message=message, content=comment, sequence=1) store = IMasterStore(DistroSeriesDifferenceComment) dsd_comment = DistroSeriesDifferenceComment() dsd_comment.distro_series_difference = distro_series_difference dsd_comment.message = message comment = store.add(dsd_comment) store.flush() return comment
def new(derived_series, source_package_name, parent_series): """See `IDistroSeriesDifferenceSource`.""" dsps = getUtility(IDistroSeriesParentSet) dsp = dsps.getByDerivedAndParentSeries(derived_series, parent_series) if dsp is None: raise NotADerivedSeriesError() store = IMasterStore(DistroSeriesDifference) diff = DistroSeriesDifference() diff.derived_series = derived_series diff.parent_series = parent_series diff.source_package_name = source_package_name # The status and type is set to default values - they will be # updated appropriately during the update() call. diff.status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION diff.difference_type = DistroSeriesDifferenceType.DIFFERENT_VERSIONS diff.update() return store.add(diff)
def new(derived_series, source_package_name, parent_series): """See `IDistroSeriesDifferenceSource`.""" dsps = getUtility(IDistroSeriesParentSet) dsp = dsps.getByDerivedAndParentSeries( derived_series, parent_series) if dsp is None: raise NotADerivedSeriesError() store = IMasterStore(DistroSeriesDifference) diff = DistroSeriesDifference() diff.derived_series = derived_series diff.parent_series = parent_series diff.source_package_name = source_package_name # The status and type is set to default values - they will be # updated appropriately during the update() call. diff.status = DistroSeriesDifferenceStatus.NEEDS_ATTENTION diff.difference_type = DistroSeriesDifferenceType.DIFFERENT_VERSIONS diff.update() return store.add(diff)
def create(cls, child, parents, arches=(), archindep_archtag=None, packagesets=(), rebuild=False, overlays=(), overlay_pockets=(), overlay_components=()): """Create a new `InitializeDistroSeriesJob`. :param child: The child `IDistroSeries` to initialize :param parents: An iterable of `IDistroSeries` of parents to initialize from. :param arches: An iterable of architecture tags which lists the architectures to enable in the child. :param packagesets: An iterable of `PackageSet` IDs from which to copy packages in parents. :param rebuild: A boolean to say whether the child should rebuild all the copied sources (if True), or to copy the parents' binaries (if False). :param overlays: An iterable of booleans corresponding exactly to each parent in the "parents" parameter. Each boolean says whether this corresponding parent is an overlay for the child or not. An overlay allows the child to use the parent's packages for build dependencies, and the overlay_pockets and overlay_components parameters dictate from where the dependencies may be used in the parent. :param overlay_pockets: An iterable of textual pocket names corresponding exactly to each parent. The name *must* be set if the corresponding overlays boolean is True. :param overlay_components: An iterable of textual component names corresponding exactly to each parent. The name *must* be set if the corresponding overlays boolean is True. """ store = IMasterStore(DistributionJob) # Only one InitializeDistroSeriesJob can be present at a time. distribution_job = store.find( DistributionJob, DistributionJob.job_id == Job.id, DistributionJob.job_type == cls.class_job_type, DistributionJob.distroseries_id == child.id).one() if distribution_job is not None: if distribution_job.job.status == JobStatus.FAILED: # Delete the failed job to allow initialization of the series # to be rescheduled. store.remove(distribution_job) store.remove(distribution_job.job) elif distribution_job.job.status == JobStatus.COMPLETED: raise InitializationCompleted(cls(distribution_job)) else: raise InitializationPending(cls(distribution_job)) # Schedule the initialization. metadata = { 'parents': parents, 'arches': arches, 'archindep_archtag': archindep_archtag, 'packagesets': packagesets, 'rebuild': rebuild, 'overlays': overlays, 'overlay_pockets': overlay_pockets, 'overlay_components': overlay_components, } distribution_job = DistributionJob( child.distribution, child, cls.class_job_type, metadata) store.add(distribution_job) derived_job = cls(distribution_job) derived_job.celeryRunOnCommit() return derived_job
class TestBugSummary(TestCaseWithFactory): layer = LaunchpadZopelessLayer def setUp(self): super(TestBugSummary, self).setUp() # Some things we are testing are impossible as mere mortals, # but might happen from the SQL command line. switch_dbuser('testadmin') self.store = IMasterStore(BugSummary) def getCount(self, person, **kw_find_expr): self._maybe_rollup() store = self.store user_with, user_where = get_bugsummary_filter_for_user(person) if user_with: store = store.with_(user_with) summaries = store.find(BugSummary, *user_where, **kw_find_expr) # Note that if there a 0 records found, sum() returns None, but # we prefer to return 0 here. return summaries.sum(BugSummary.count) or 0 def assertCount(self, count, user=None, **kw_find_expr): self.assertEqual(count, self.getCount(user, **kw_find_expr)) def _maybe_rollup(self): """Rollup the journal if the class is testing the rollup case.""" # The base class does not rollup the journal, see # TestBugSummaryRolledUp which does. pass def test_providesInterface(self): bug_summary = self.store.find(BugSummary)[0] self.assertTrue(IBugSummary.providedBy(bug_summary)) def test_addTag(self): tag = u'pustular' # Ensure nothing using our tag yet. self.assertCount(0, tag=tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=tag) # There should be no other BugSummary rows. self.assertCount(3, tag=tag) def test_changeTag(self): old_tag = u'pustular' new_tag = u'flatulent' # Ensure nothing using our tags yet. self.assertCount(0, tag=old_tag) self.assertCount(0, tag=new_tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=old_tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=old_tag) for count in reversed(range(3)): bug_tag = self.store.find(BugTag, tag=old_tag).any() bug_tag.tag = new_tag self.assertCount(count, product=product, tag=old_tag) self.assertCount(3 - count, product=product, tag=new_tag) # There should be no other BugSummary rows. self.assertCount(0, tag=old_tag) self.assertCount(3, tag=new_tag) def test_removeTag(self): tag = u'pustular' # Ensure nothing using our tags yet. self.assertCount(0, tag=tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=tag) for count in reversed(range(3)): bug_tag = self.store.find(BugTag, tag=tag).any() self.store.remove(bug_tag) self.assertCount(count, product=product, tag=tag) # There should be no other BugSummary rows. self.assertCount(0, tag=tag) def test_changeStatus(self): org_status = BugTaskStatus.NEW new_status = BugTaskStatus.INVALID product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_task = self.store.find(BugTask, bug=bug).one() bug_task._status = org_status self.assertCount(count + 1, product=product, status=org_status) for count in reversed(range(3)): bug_task = self.store.find( BugTask, product=product, _status=org_status).any() bug_task._status = new_status self.assertCount(count, product=product, status=org_status) self.assertCount(3 - count, product=product, status=new_status) def test_changeImportance(self): org_importance = BugTaskImportance.UNDECIDED new_importance = BugTaskImportance.CRITICAL product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_task = self.store.find(BugTask, bug=bug).one() bug_task.importance = org_importance self.assertCount( count + 1, product=product, importance=org_importance) for count in reversed(range(3)): bug_task = self.store.find( BugTask, product=product, importance=org_importance).any() bug_task.importance = new_importance self.assertCount( count, product=product, importance=org_importance) self.assertCount( 3 - count, product=product, importance=new_importance) def test_makePrivate(self): # The bug owner and two other people are subscribed directly to # the bug, and another has a grant for the whole project. All of # them see the bug once. person_a = self.factory.makePerson() person_b = self.factory.makePerson() person_c = self.factory.makePerson() product = self.factory.makeProduct() getUtility(IService, 'sharing').sharePillarInformation( product, person_c, product.owner, {InformationType.USERDATA: SharingPermission.ALL}) bug = self.factory.makeBug(target=product, owner=person_b) bug.subscribe(person=person_a, subscribed_by=person_a) # Make the bug private. We have to use the Python API to ensure # BugSubscription records get created for implicit # subscriptions. bug.transitionToInformationType(InformationType.USERDATA, bug.owner) # Confirm counts; the two other people shouldn't have access. self.assertCount(0, product=product) self.assertCount(0, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) self.assertCount(1, user=person_c, product=product) self.assertCount(1, user=bug.owner, product=product) def test_makePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug( target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) # Make the bug public. We have to use the Python API to ensure # BugSubscription records get created for implicit # subscriptions. bug.setPrivate(False, bug.owner) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_subscribePrivate(self): product = self.factory.makeProduct() bug = self.factory.makeBug( target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) self.assertCount(0, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(0, user=person_b, product=product) def test_unsubscribePrivate(self): product = self.factory.makeProduct() bug = self.factory.makeBug( target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) bug.subscribe(person=person_b, subscribed_by=person_b) bug.unsubscribe(person=person_b, unsubscribed_by=person_b) self.assertCount(0, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(0, user=person_b, product=product) def test_subscribePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_unsubscribePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) bug.subscribe(person=person_b, subscribed_by=person_b) bug.unsubscribe(person=person_b, unsubscribed_by=person_b) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_addProduct(self): distribution = self.factory.makeDistribution() product = self.factory.makeProduct() bug = self.factory.makeBug(target=distribution) self.assertCount(1, distribution=distribution) self.assertCount(0, product=product) self.factory.makeBugTask(bug=bug, target=product) self.assertCount(1, distribution=distribution) self.assertCount(1, product=product) def test_changeProduct(self): product_a = self.factory.makeProduct() product_b = self.factory.makeProduct() bug_task = self.factory.makeBugTask(target=product_a) self.assertCount(1, product=product_a) self.assertCount(0, product=product_b) removeSecurityProxy(bug_task).product = product_b self.assertCount(0, product=product_a) self.assertCount(1, product=product_b) def test_removeProduct(self): distribution = self.factory.makeDistribution() product = self.factory.makeProduct() product_bug_task = self.factory.makeBugTask(target=product) self.factory.makeBugTask( bug=product_bug_task.bug, target=distribution) self.assertCount(1, distribution=distribution) self.assertCount(1, product=product) self.store.remove(product_bug_task) self.assertCount(1, distribution=distribution) self.assertCount(0, product=product) def test_addProductSeries(self): bug = self.factory.makeBug() productseries = self.factory.makeProductSeries() product = productseries.product bug_task = self.factory.makeBugTask(bug=bug, target=productseries) self.assertTrue(bug_task.product is None) self.assertCount(1, product=product) self.assertCount(1, productseries=productseries) def test_changeProductSeries(self): product = self.factory.makeProduct() productseries_a = self.factory.makeProductSeries(product=product) productseries_b = self.factory.makeProductSeries(product=product) # You can't have a BugTask targetted to a productseries without # already having a BugTask targetted to the product. Create # this task explicitly. product_task = self.factory.makeBugTask(target=product) series_task = self.factory.makeBugTask( bug=product_task.bug, target=productseries_a) self.assertCount(1, product=product) self.assertCount(1, productseries=productseries_a) removeSecurityProxy(series_task).productseries = productseries_b self.assertCount(1, product=product) self.assertCount(0, productseries=productseries_a) self.assertCount(1, productseries=productseries_b) def test_removeProductSeries(self): series = self.factory.makeProductSeries() product = series.product bug_task = self.factory.makeBugTask(target=series) self.assertCount(1, product=product) self.assertCount(1, productseries=series) self.store.remove(bug_task) self.assertCount(1, product=product) self.assertCount(0, productseries=series) def test_addDistribution(self): distribution = self.factory.makeDistribution() self.factory.makeBugTask(target=distribution) self.assertCount(1, distribution=distribution) def test_changeDistribution(self): distribution_a = self.factory.makeDistribution() distribution_b = self.factory.makeDistribution() bug_task = self.factory.makeBugTask(target=distribution_a) self.assertCount(1, distribution=distribution_a) removeSecurityProxy(bug_task).distribution = distribution_b self.assertCount(0, distribution=distribution_a) self.assertCount(1, distribution=distribution_b) def test_removeDistribution(self): distribution_a = self.factory.makeDistribution() distribution_b = self.factory.makeDistribution() bug_task_a = self.factory.makeBugTask(target=distribution_a) bug = bug_task_a.bug bug_task_b = self.factory.makeBugTask(bug=bug, target=distribution_b) self.assertCount(1, distribution=distribution_a) self.assertCount(1, distribution=distribution_b) self.store.remove(bug_task_b) self.assertCount(1, distribution=distribution_a) self.assertCount(0, distribution=distribution_b) def test_addDistroSeries(self): series = self.factory.makeDistroSeries() distribution = series.distribution # This first creates a BugTask on the distribution. We can't # have a distroseries BugTask without a distribution BugTask. self.factory.makeBugTask(target=series) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series) def test_changeDistroSeries(self): distribution = self.factory.makeDistribution() series_a = self.factory.makeDistroSeries(distribution=distribution) series_b = self.factory.makeDistroSeries(distribution=distribution) bug_task = self.factory.makeBugTask(target=series_a) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series_a) self.assertCount(0, distroseries=series_b) removeSecurityProxy(bug_task).distroseries = series_b self.assertCount(1, distribution=distribution) self.assertCount(0, distroseries=series_a) self.assertCount(1, distroseries=series_b) def test_removeDistroSeries(self): series = self.factory.makeDistroSeries() distribution = series.distribution bug_task = self.factory.makeBugTask(target=series) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series) self.store.remove(bug_task) self.assertCount(1, distribution=distribution) self.assertCount(0, distroseries=series) def test_addDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage = self.factory.makeDistributionSourcePackage( distribution=distribution) bug = self.factory.makeBug() self.factory.makeBugTask(bug=bug, target=sourcepackage) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount( 1, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) def test_changeDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage_a = self.factory.makeDistributionSourcePackage( distribution=distribution) sourcepackage_b = self.factory.makeDistributionSourcePackage( distribution=distribution) bug_task = self.factory.makeBugTask(target=sourcepackage_a) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount( 1, distribution=distribution, sourcepackagename=sourcepackage_a.sourcepackagename) self.assertCount( 0, distribution=distribution, sourcepackagename=sourcepackage_b.sourcepackagename) removeSecurityProxy(bug_task).sourcepackagename = ( sourcepackage_b.sourcepackagename) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount( 0, distribution=distribution, sourcepackagename=sourcepackage_a.sourcepackagename) self.assertCount( 1, distribution=distribution, sourcepackagename=sourcepackage_b.sourcepackagename) def test_removeDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage = self.factory.makeDistributionSourcePackage( distribution=distribution) bug_task = self.factory.makeBugTask(target=sourcepackage) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount( 1, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) removeSecurityProxy(bug_task).sourcepackagename = None self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount( 0, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) def test_addDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package = self.factory.makeSourcePackage(distroseries=series) spn = package.sourcepackagename self.factory.makeBugTask(target=package) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn) def test_changeDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package_a = self.factory.makeSourcePackage( distroseries=series, publish=True) package_b = self.factory.makeSourcePackage( distroseries=series, publish=True) spn_a = package_a.sourcepackagename spn_b = package_b.sourcepackagename bug_task = self.factory.makeBugTask(target=package_a) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn_a) self.assertCount(0, distribution=distribution, sourcepackagename=spn_b) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn_a) self.assertCount(0, distroseries=series, sourcepackagename=spn_b) bug_task.transitionToTarget( series.getSourcePackage(spn_b), bug_task.owner) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=spn_a) self.assertCount(1, distribution=distribution, sourcepackagename=spn_b) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(0, distroseries=series, sourcepackagename=spn_a) self.assertCount(1, distroseries=series, sourcepackagename=spn_b) def test_removeDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package = self.factory.makeSourcePackage(distroseries=series) spn = package.sourcepackagename bug_task = self.factory.makeBugTask(target=package) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn) bug_task.transitionToTarget(series, bug_task.owner) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(0, distroseries=series, sourcepackagename=spn) def test_addMilestone(self): distribution = self.factory.makeDistribution() milestone = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) self.assertCount(1, distribution=distribution, milestone=None) bug_task.milestone = milestone self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone) def test_changeMilestone(self): distribution = self.factory.makeDistribution() milestone_a = self.factory.makeMilestone(distribution=distribution) milestone_b = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) bug_task.milestone = milestone_a self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone_a) self.assertCount(0, distribution=distribution, milestone=milestone_b) bug_task.milestone = milestone_b self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(0, distribution=distribution, milestone=milestone_a) self.assertCount(1, distribution=distribution, milestone=milestone_b) def test_removeMilestone(self): distribution = self.factory.makeDistribution() milestone = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) bug_task.milestone = milestone self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone) bug_task.milestone = None self.assertCount(1, distribution=distribution, milestone=None) self.assertCount(0, distribution=distribution, milestone=milestone) def test_addPatch(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) self.assertCount(0, product=product, has_patch=True) removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc) self.assertCount(1, product=product, has_patch=True) def test_removePatch(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc) self.assertCount(1, product=product, has_patch=True) self.assertCount(0, product=product, has_patch=False) removeSecurityProxy(bug).latest_patch_uploaded = None self.assertCount(0, product=product, has_patch=True) self.assertCount(1, product=product, has_patch=False) def test_duplicate(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) self.assertCount(1, product=product) bug.markAsDuplicate(self.factory.makeBug()) self.assertCount(0, product=product)
def create(cls, child, parents, arches=(), archindep_archtag=None, packagesets=None, rebuild=False, overlays=(), overlay_pockets=(), overlay_components=()): """Create a new `InitializeDistroSeriesJob`. :param child: The child `IDistroSeries` to initialize :param parents: An iterable of `IDistroSeries` of parents to initialize from. :param arches: An iterable of architecture tags which lists the architectures to enable in the child. :param packagesets: An iterable of `PackageSet` IDs from which to copy packages in parents. :param rebuild: A boolean to say whether the child should rebuild all the copied sources (if True), or to copy the parents' binaries (if False). :param overlays: An iterable of booleans corresponding exactly to each parent in the "parents" parameter. Each boolean says whether this corresponding parent is an overlay for the child or not. An overlay allows the child to use the parent's packages for build dependencies, and the overlay_pockets and overlay_components parameters dictate from where the dependencies may be used in the parent. :param overlay_pockets: An iterable of textual pocket names corresponding exactly to each parent. The name *must* be set if the corresponding overlays boolean is True. :param overlay_components: An iterable of textual component names corresponding exactly to each parent. The name *must* be set if the corresponding overlays boolean is True. """ store = IMasterStore(DistributionJob) # Only one InitializeDistroSeriesJob can be present at a time. distribution_job = store.find( DistributionJob, DistributionJob.job_id == Job.id, DistributionJob.job_type == cls.class_job_type, DistributionJob.distroseries_id == child.id).one() if distribution_job is not None: if distribution_job.job.status == JobStatus.FAILED: # Delete the failed job to allow initialization of the series # to be rescheduled. store.remove(distribution_job) store.remove(distribution_job.job) elif distribution_job.job.status == JobStatus.COMPLETED: raise InitializationCompleted(cls(distribution_job)) else: raise InitializationPending(cls(distribution_job)) # Schedule the initialization. metadata = { 'parents': parents, 'arches': arches, 'archindep_archtag': archindep_archtag, 'packagesets': packagesets, 'rebuild': rebuild, 'overlays': overlays, 'overlay_pockets': overlay_pockets, 'overlay_components': overlay_components, } distribution_job = DistributionJob(child.distribution, child, cls.class_job_type, metadata) store.add(distribution_job) derived_job = cls(distribution_job) derived_job.celeryRunOnCommit() return derived_job
def new(cls, build, job): """See `ISourcePackageRecipeBuildJobSource`.""" specific_job = cls(build, job) store = IMasterStore(cls) store.add(specific_job) return specific_job
class TestBugSummary(TestCaseWithFactory): layer = LaunchpadZopelessLayer def setUp(self): super(TestBugSummary, self).setUp() # Some things we are testing are impossible as mere mortals, # but might happen from the SQL command line. switch_dbuser('testadmin') self.store = IMasterStore(BugSummary) def getCount(self, person, **kw_find_expr): self._maybe_rollup() store = self.store user_with, user_where = get_bugsummary_filter_for_user(person) if user_with: store = store.with_(user_with) summaries = store.find(BugSummary, *user_where, **kw_find_expr) # Note that if there a 0 records found, sum() returns None, but # we prefer to return 0 here. return summaries.sum(BugSummary.count) or 0 def assertCount(self, count, user=None, **kw_find_expr): self.assertEqual(count, self.getCount(user, **kw_find_expr)) def _maybe_rollup(self): """Rollup the journal if the class is testing the rollup case.""" # The base class does not rollup the journal, see # TestBugSummaryRolledUp which does. pass def test_providesInterface(self): bug_summary = self.store.find(BugSummary)[0] self.assertTrue(IBugSummary.providedBy(bug_summary)) def test_addTag(self): tag = u'pustular' # Ensure nothing using our tag yet. self.assertCount(0, tag=tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=tag) # There should be no other BugSummary rows. self.assertCount(3, tag=tag) def test_changeTag(self): old_tag = u'pustular' new_tag = u'flatulent' # Ensure nothing using our tags yet. self.assertCount(0, tag=old_tag) self.assertCount(0, tag=new_tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=old_tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=old_tag) for count in reversed(range(3)): bug_tag = self.store.find(BugTag, tag=old_tag).any() bug_tag.tag = new_tag self.assertCount(count, product=product, tag=old_tag) self.assertCount(3 - count, product=product, tag=new_tag) # There should be no other BugSummary rows. self.assertCount(0, tag=old_tag) self.assertCount(3, tag=new_tag) def test_removeTag(self): tag = u'pustular' # Ensure nothing using our tags yet. self.assertCount(0, tag=tag) product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_tag = BugTag(bug=bug, tag=tag) self.store.add(bug_tag) # Number of tagged tasks for a particular product self.assertCount(3, product=product, tag=tag) for count in reversed(range(3)): bug_tag = self.store.find(BugTag, tag=tag).any() self.store.remove(bug_tag) self.assertCount(count, product=product, tag=tag) # There should be no other BugSummary rows. self.assertCount(0, tag=tag) def test_changeStatus(self): org_status = BugTaskStatus.NEW new_status = BugTaskStatus.INVALID product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_task = self.store.find(BugTask, bug=bug).one() bug_task._status = org_status self.assertCount(count + 1, product=product, status=org_status) for count in reversed(range(3)): bug_task = self.store.find(BugTask, product=product, _status=org_status).any() bug_task._status = new_status self.assertCount(count, product=product, status=org_status) self.assertCount(3 - count, product=product, status=new_status) def test_changeImportance(self): org_importance = BugTaskImportance.UNDECIDED new_importance = BugTaskImportance.CRITICAL product = self.factory.makeProduct() for count in range(3): bug = self.factory.makeBug(target=product) bug_task = self.store.find(BugTask, bug=bug).one() bug_task.importance = org_importance self.assertCount(count + 1, product=product, importance=org_importance) for count in reversed(range(3)): bug_task = self.store.find(BugTask, product=product, importance=org_importance).any() bug_task.importance = new_importance self.assertCount(count, product=product, importance=org_importance) self.assertCount(3 - count, product=product, importance=new_importance) def test_makePrivate(self): # The bug owner and two other people are subscribed directly to # the bug, and another has a grant for the whole project. All of # them see the bug once. person_a = self.factory.makePerson() person_b = self.factory.makePerson() person_c = self.factory.makePerson() product = self.factory.makeProduct() getUtility(IService, 'sharing').sharePillarInformation( product, person_c, product.owner, {InformationType.USERDATA: SharingPermission.ALL}) bug = self.factory.makeBug(target=product, owner=person_b) bug.subscribe(person=person_a, subscribed_by=person_a) # Make the bug private. We have to use the Python API to ensure # BugSubscription records get created for implicit # subscriptions. bug.transitionToInformationType(InformationType.USERDATA, bug.owner) # Confirm counts; the two other people shouldn't have access. self.assertCount(0, product=product) self.assertCount(0, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) self.assertCount(1, user=person_c, product=product) self.assertCount(1, user=bug.owner, product=product) def test_makePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) # Make the bug public. We have to use the Python API to ensure # BugSubscription records get created for implicit # subscriptions. bug.setPrivate(False, bug.owner) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_subscribePrivate(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) self.assertCount(0, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(0, user=person_b, product=product) def test_unsubscribePrivate(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product, information_type=InformationType.USERDATA) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) bug.subscribe(person=person_b, subscribed_by=person_b) bug.unsubscribe(person=person_b, unsubscribed_by=person_b) self.assertCount(0, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(0, user=person_b, product=product) def test_subscribePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_unsubscribePublic(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) person_a = self.factory.makePerson() person_b = self.factory.makePerson() bug.subscribe(person=person_a, subscribed_by=person_a) bug.subscribe(person=person_b, subscribed_by=person_b) bug.unsubscribe(person=person_b, unsubscribed_by=person_b) self.assertCount(1, product=product) self.assertCount(1, user=person_a, product=product) self.assertCount(1, user=person_b, product=product) def test_addProduct(self): distribution = self.factory.makeDistribution() product = self.factory.makeProduct() bug = self.factory.makeBug(target=distribution) self.assertCount(1, distribution=distribution) self.assertCount(0, product=product) self.factory.makeBugTask(bug=bug, target=product) self.assertCount(1, distribution=distribution) self.assertCount(1, product=product) def test_changeProduct(self): product_a = self.factory.makeProduct() product_b = self.factory.makeProduct() bug_task = self.factory.makeBugTask(target=product_a) self.assertCount(1, product=product_a) self.assertCount(0, product=product_b) removeSecurityProxy(bug_task).product = product_b self.assertCount(0, product=product_a) self.assertCount(1, product=product_b) def test_removeProduct(self): distribution = self.factory.makeDistribution() product = self.factory.makeProduct() product_bug_task = self.factory.makeBugTask(target=product) self.factory.makeBugTask(bug=product_bug_task.bug, target=distribution) self.assertCount(1, distribution=distribution) self.assertCount(1, product=product) self.store.remove(product_bug_task) self.assertCount(1, distribution=distribution) self.assertCount(0, product=product) def test_addProductSeries(self): bug = self.factory.makeBug() productseries = self.factory.makeProductSeries() product = productseries.product bug_task = self.factory.makeBugTask(bug=bug, target=productseries) self.assertTrue(bug_task.product is None) self.assertCount(1, product=product) self.assertCount(1, productseries=productseries) def test_changeProductSeries(self): product = self.factory.makeProduct() productseries_a = self.factory.makeProductSeries(product=product) productseries_b = self.factory.makeProductSeries(product=product) # You can't have a BugTask targetted to a productseries without # already having a BugTask targetted to the product. Create # this task explicitly. product_task = self.factory.makeBugTask(target=product) series_task = self.factory.makeBugTask(bug=product_task.bug, target=productseries_a) self.assertCount(1, product=product) self.assertCount(1, productseries=productseries_a) removeSecurityProxy(series_task).productseries = productseries_b self.assertCount(1, product=product) self.assertCount(0, productseries=productseries_a) self.assertCount(1, productseries=productseries_b) def test_removeProductSeries(self): series = self.factory.makeProductSeries() product = series.product bug_task = self.factory.makeBugTask(target=series) self.assertCount(1, product=product) self.assertCount(1, productseries=series) self.store.remove(bug_task) self.assertCount(1, product=product) self.assertCount(0, productseries=series) def test_addDistribution(self): distribution = self.factory.makeDistribution() self.factory.makeBugTask(target=distribution) self.assertCount(1, distribution=distribution) def test_changeDistribution(self): distribution_a = self.factory.makeDistribution() distribution_b = self.factory.makeDistribution() bug_task = self.factory.makeBugTask(target=distribution_a) self.assertCount(1, distribution=distribution_a) removeSecurityProxy(bug_task).distribution = distribution_b self.assertCount(0, distribution=distribution_a) self.assertCount(1, distribution=distribution_b) def test_removeDistribution(self): distribution_a = self.factory.makeDistribution() distribution_b = self.factory.makeDistribution() bug_task_a = self.factory.makeBugTask(target=distribution_a) bug = bug_task_a.bug bug_task_b = self.factory.makeBugTask(bug=bug, target=distribution_b) self.assertCount(1, distribution=distribution_a) self.assertCount(1, distribution=distribution_b) self.store.remove(bug_task_b) self.assertCount(1, distribution=distribution_a) self.assertCount(0, distribution=distribution_b) def test_addDistroSeries(self): series = self.factory.makeDistroSeries() distribution = series.distribution # This first creates a BugTask on the distribution. We can't # have a distroseries BugTask without a distribution BugTask. self.factory.makeBugTask(target=series) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series) def test_changeDistroSeries(self): distribution = self.factory.makeDistribution() series_a = self.factory.makeDistroSeries(distribution=distribution) series_b = self.factory.makeDistroSeries(distribution=distribution) bug_task = self.factory.makeBugTask(target=series_a) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series_a) self.assertCount(0, distroseries=series_b) removeSecurityProxy(bug_task).distroseries = series_b self.assertCount(1, distribution=distribution) self.assertCount(0, distroseries=series_a) self.assertCount(1, distroseries=series_b) def test_removeDistroSeries(self): series = self.factory.makeDistroSeries() distribution = series.distribution bug_task = self.factory.makeBugTask(target=series) self.assertCount(1, distribution=distribution) self.assertCount(1, distroseries=series) self.store.remove(bug_task) self.assertCount(1, distribution=distribution) self.assertCount(0, distroseries=series) def test_addDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage = self.factory.makeDistributionSourcePackage( distribution=distribution) bug = self.factory.makeBug() self.factory.makeBugTask(bug=bug, target=sourcepackage) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) def test_changeDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage_a = self.factory.makeDistributionSourcePackage( distribution=distribution) sourcepackage_b = self.factory.makeDistributionSourcePackage( distribution=distribution) bug_task = self.factory.makeBugTask(target=sourcepackage_a) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=sourcepackage_a.sourcepackagename) self.assertCount(0, distribution=distribution, sourcepackagename=sourcepackage_b.sourcepackagename) removeSecurityProxy(bug_task).sourcepackagename = ( sourcepackage_b.sourcepackagename) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=sourcepackage_a.sourcepackagename) self.assertCount(1, distribution=distribution, sourcepackagename=sourcepackage_b.sourcepackagename) def test_removeDistributionSourcePackage(self): distribution = self.factory.makeDistribution() sourcepackage = self.factory.makeDistributionSourcePackage( distribution=distribution) bug_task = self.factory.makeBugTask(target=sourcepackage) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) removeSecurityProxy(bug_task).sourcepackagename = None self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=sourcepackage.sourcepackagename) def test_addDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package = self.factory.makeSourcePackage(distroseries=series) spn = package.sourcepackagename self.factory.makeBugTask(target=package) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn) def test_changeDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package_a = self.factory.makeSourcePackage(distroseries=series, publish=True) package_b = self.factory.makeSourcePackage(distroseries=series, publish=True) spn_a = package_a.sourcepackagename spn_b = package_b.sourcepackagename bug_task = self.factory.makeBugTask(target=package_a) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn_a) self.assertCount(0, distribution=distribution, sourcepackagename=spn_b) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn_a) self.assertCount(0, distroseries=series, sourcepackagename=spn_b) bug_task.transitionToTarget(series.getSourcePackage(spn_b), bug_task.owner) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=spn_a) self.assertCount(1, distribution=distribution, sourcepackagename=spn_b) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(0, distroseries=series, sourcepackagename=spn_a) self.assertCount(1, distroseries=series, sourcepackagename=spn_b) def test_removeDistroSeriesSourcePackage(self): distribution = self.factory.makeDistribution() series = self.factory.makeDistroSeries(distribution=distribution) package = self.factory.makeSourcePackage(distroseries=series) spn = package.sourcepackagename bug_task = self.factory.makeBugTask(target=package) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(1, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(1, distroseries=series, sourcepackagename=spn) bug_task.transitionToTarget(series, bug_task.owner) self.assertCount(1, distribution=distribution, sourcepackagename=None) self.assertCount(0, distribution=distribution, sourcepackagename=spn) self.assertCount(1, distroseries=series, sourcepackagename=None) self.assertCount(0, distroseries=series, sourcepackagename=spn) def test_addMilestone(self): distribution = self.factory.makeDistribution() milestone = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) self.assertCount(1, distribution=distribution, milestone=None) bug_task.milestone = milestone self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone) def test_changeMilestone(self): distribution = self.factory.makeDistribution() milestone_a = self.factory.makeMilestone(distribution=distribution) milestone_b = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) bug_task.milestone = milestone_a self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone_a) self.assertCount(0, distribution=distribution, milestone=milestone_b) bug_task.milestone = milestone_b self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(0, distribution=distribution, milestone=milestone_a) self.assertCount(1, distribution=distribution, milestone=milestone_b) def test_removeMilestone(self): distribution = self.factory.makeDistribution() milestone = self.factory.makeMilestone(distribution=distribution) bug_task = self.factory.makeBugTask(target=distribution) bug_task.milestone = milestone self.assertCount(0, distribution=distribution, milestone=None) self.assertCount(1, distribution=distribution, milestone=milestone) bug_task.milestone = None self.assertCount(1, distribution=distribution, milestone=None) self.assertCount(0, distribution=distribution, milestone=milestone) def test_addPatch(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) self.assertCount(0, product=product, has_patch=True) removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc) self.assertCount(1, product=product, has_patch=True) def test_removePatch(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc) self.assertCount(1, product=product, has_patch=True) self.assertCount(0, product=product, has_patch=False) removeSecurityProxy(bug).latest_patch_uploaded = None self.assertCount(0, product=product, has_patch=True) self.assertCount(1, product=product, has_patch=False) def test_duplicate(self): product = self.factory.makeProduct() bug = self.factory.makeBug(target=product) self.assertCount(1, product=product) bug.markAsDuplicate(self.factory.makeBug()) self.assertCount(0, product=product)
class TestPersonSetCreateByOpenId(TestCaseWithFactory): layer = DatabaseFunctionalLayer def setUp(self): super(TestPersonSetCreateByOpenId, self).setUp() self.person_set = getUtility(IPersonSet) self.store = IMasterStore(Account) # Generate some valid test data. self.account = self.makeAccount() self.identifier = self.makeOpenIdIdentifier(self.account, u'whatever') self.person = self.makePerson(self.account) self.email = self.makeEmailAddress(email='*****@*****.**', person=self.person) def makeAccount(self): return self.store.add( Account(displayname='Displayname', creation_rationale=AccountCreationRationale.UNKNOWN, status=AccountStatus.ACTIVE)) def makeOpenIdIdentifier(self, account, identifier): openid_identifier = OpenIdIdentifier() openid_identifier.identifier = identifier openid_identifier.account = account return self.store.add(openid_identifier) def makePerson(self, account): return self.store.add( Person(name='acc%d' % account.id, account=account, displayname='Displayname', creation_rationale=PersonCreationRationale.UNKNOWN)) def makeEmailAddress(self, email, person): return self.store.add( EmailAddress(email=email, account=person.account, person=person, status=EmailAddressStatus.PREFERRED)) def testAllValid(self): found, updated = self.person_set.getOrCreateByOpenIDIdentifier( self.identifier.identifier, self.email.email, 'Ignored Name', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) self.assertIs(False, updated) self.assertIs(self.person, found) self.assertIs(self.account, found.account) self.assertIs(self.email, found.preferredemail) self.assertIs(self.email.account, self.account) self.assertIs(self.email.person, self.person) self.assertEqual([self.identifier], list(self.account.openid_identifiers)) def testEmailAddressCaseInsensitive(self): # As per testAllValid, but the email address used for the lookup # is all upper case. found, updated = self.person_set.getOrCreateByOpenIDIdentifier( self.identifier.identifier, self.email.email.upper(), 'Ignored Name', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) self.assertIs(False, updated) self.assertIs(self.person, found) self.assertIs(self.account, found.account) self.assertIs(self.email, found.preferredemail) self.assertIs(self.email.account, self.account) self.assertIs(self.email.person, self.person) self.assertEqual([self.identifier], list(self.account.openid_identifiers)) def testNewOpenId(self): # Account looked up by email and the new OpenId identifier # attached. We can do this because we trust our OpenId Provider. new_identifier = u'newident' found, updated = self.person_set.getOrCreateByOpenIDIdentifier( new_identifier, self.email.email, 'Ignored Name', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) self.assertIs(True, updated) self.assertIs(self.person, found) self.assertIs(self.account, found.account) self.assertIs(self.email, found.preferredemail) self.assertIs(self.email.account, self.account) self.assertIs(self.email.person, self.person) # Old OpenId Identifier still attached. self.assertIn(self.identifier, list(self.account.openid_identifiers)) # So is our new one. identifiers = [ identifier.identifier for identifier in self.account.openid_identifiers ] self.assertIn(new_identifier, identifiers) def testNewAccountAndIdentifier(self): # If neither the OpenId Identifier nor the email address are # found, we create everything. new_email = u'*****@*****.**' new_identifier = u'new_identifier' found, updated = self.person_set.getOrCreateByOpenIDIdentifier( new_identifier, new_email, 'New Name', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) # We have a new Person self.assertIs(True, updated) self.assertIsNot(None, found) # It is correctly linked to an account, emailaddress and # identifier. self.assertIs(found, found.preferredemail.person) self.assertEqual(new_identifier, found.account.openid_identifiers.any().identifier) def testNoAccount(self): # EmailAddress is linked to a Person, but there is no Account. # Convert this stub into something valid. self.email.account = None self.email.status = EmailAddressStatus.NEW self.person.account = None new_identifier = u'new_identifier' found, updated = self.person_set.getOrCreateByOpenIDIdentifier( new_identifier, self.email.email, 'Ignored', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) self.assertTrue(updated) self.assertIsNot(None, found.account) self.assertEqual(new_identifier, found.account.openid_identifiers.any().identifier) self.assertIs(self.email.person, found) self.assertEqual(EmailAddressStatus.PREFERRED, self.email.status) def testEmailAddressAccountAndOpenIDAccountAreDifferent(self): # The EmailAddress and OpenId Identifier are both in the database, # but they are not linked to the same account. In this case, the # OpenId Identifier trumps the EmailAddress's account. self.identifier.account = self.store.find(Account, displayname='Foo Bar').one() email_account = self.email.account found, updated = self.person_set.getOrCreateByOpenIDIdentifier( self.identifier.identifier, self.email.email, 'New Name', PersonCreationRationale.UNKNOWN, 'No Comment') found = removeSecurityProxy(found) self.assertFalse(updated) self.assertIs(IPerson(self.identifier.account), found) self.assertIs(found.account, self.identifier.account) self.assertIn(self.identifier, list(found.account.openid_identifiers)) self.assertIs(email_account, self.email.account) def testEmptyOpenIDIdentifier(self): self.assertRaises(AssertionError, self.person_set.getOrCreateByOpenIDIdentifier, u'', '*****@*****.**', 'New Name', PersonCreationRationale.UNKNOWN, 'No Comment') def testTeamEmailAddress(self): # If the EmailAddress is linked to a team, login fails. There is # no way to automatically recover -- someone must manually fix # the email address of the team or the SSO account. self.factory.makeTeam(email="*****@*****.**") self.assertRaises(TeamEmailAddressError, self.person_set.getOrCreateByOpenIDIdentifier, u'other-openid-identifier', '*****@*****.**', 'New Name', PersonCreationRationale.UNKNOWN, 'No Comment') def testDeactivatedAccount(self): # Logging into a deactivated account with a new email address # reactivates the account, adds that email address, and sets it # as preferred. addr = '*****@*****.**' self.person.preDeactivate('I hate life.') self.assertEqual(AccountStatus.DEACTIVATED, self.person.account_status) self.assertIs(None, self.person.preferredemail) found, updated = self.person_set.getOrCreateByOpenIDIdentifier( self.identifier.identifier, addr, 'New Name', PersonCreationRationale.UNKNOWN, 'No Comment') self.assertEqual(AccountStatus.ACTIVE, self.person.account_status) self.assertEqual(addr, self.person.preferredemail.email)
class TestBulkPruner(TestCase): layer = ZopelessDatabaseLayer def setUp(self): super(TestBulkPruner, self).setUp() self.store = IMasterStore(CommercialSubscription) self.store.execute("CREATE TABLE BulkFoo (id serial PRIMARY KEY)") for i in range(10): self.store.add(BulkFoo()) self.log = logging.getLogger('garbo') def test_bulkpruner(self): pruner = BulkFooPruner(self.log) # The loop thinks there is stuff to do. Confirm the initial # state is sane. self.assertFalse(pruner.isDone()) # An arbitrary chunk size. chunk_size = 2 # Determine how many items to prune and to leave rather than # hardcode these numbers. num_to_prune = self.store.find( BulkFoo, BulkFoo.id < 5).count() num_to_leave = self.store.find( BulkFoo, BulkFoo.id >= 5).count() self.assertTrue(num_to_prune > chunk_size) self.assertTrue(num_to_leave > 0) # Run one loop. Make sure it committed by throwing away # uncommitted changes. pruner(chunk_size) transaction.abort() # Confirm 'chunk_size' items where removed; no more, no less. num_remaining = self.store.find(BulkFoo).count() expected_num_remaining = num_to_leave + num_to_prune - chunk_size self.assertEqual(num_remaining, expected_num_remaining) # The loop thinks there is more stuff to do. self.assertFalse(pruner.isDone()) # Run the loop to completion, removing the remaining targetted # rows. while not pruner.isDone(): pruner(1000000) transaction.abort() # Confirm we have removed all targetted rows. self.assertEqual(self.store.find(BulkFoo, BulkFoo.id < 5).count(), 0) # Confirm we have the expected number of remaining rows. # With the previous check, this means no untargetted rows # where removed. self.assertEqual( self.store.find(BulkFoo, BulkFoo.id >= 5).count(), num_to_leave) # Cleanup clears up our resources. pruner.cleanUp() # We can run it again - temporary objects cleaned up. pruner = BulkFooPruner(self.log) while not pruner.isDone(): pruner(chunk_size)
def new(cls, build, job): """See `ISourcePackageRecipeBuildJobSource`.""" specific_job = cls(build, job) store = IMasterStore(cls) store.add(specific_job) return specific_job