Пример #1
0
    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)
Пример #2
0
 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
Пример #3
0
 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
Пример #4
0
 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
Пример #5
0
 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)
Пример #6
0
    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
Пример #9
0
 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
Пример #10
0
 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
Пример #11
0
    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
Пример #12
0
 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
Пример #14
0
    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
Пример #15
0
    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
Пример #16
0
    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
Пример #18
0
    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))
Пример #19
0
    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
Пример #20
0
 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
Пример #21
0
    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')
Пример #22
0
 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
Пример #23
0
    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
Пример #25
0
    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
Пример #29
0
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
Пример #31
0
 def new(cls, build, job):
     """See `ISourcePackageRecipeBuildJobSource`."""
     specific_job = cls(build, job)
     store = IMasterStore(cls)
     store.add(specific_job)
     return specific_job
Пример #32
0
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)
Пример #33
0
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)
Пример #34
0
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