コード例 #1
0
    def test_default_collection(self):
        # Make it easy to filter out sample data
        store = IStore(Processor)
        store.execute("UPDATE Processor SET name = 'sample_data_' || name")
        self.factory.makeProcessor(name='q1')
        self.factory.makeProcessor(name='i686')
        self.factory.makeProcessor(name='g4')

        logout()

        collection = self.webservice.get(
            '/+processors?ws.size=10', api_version='devel').jsonBody()
        self.assertEquals(
            ['g4', 'i686', 'q1'],
            sorted(
            processor['name'] for processor in collection['entries']
            if not processor['name'].startswith('sample_data_')))
コード例 #2
0
 def _set_collection(self, cls, enum, attribute, current_set, desired_set):
     desired_set = frozenset(desired_set)
     if desired_set == frozenset(enum.items):
         # Setting all is the same as setting none, and setting none is
         # cheaper for reading and storage.
         desired_set = frozenset()
     # Add missing.
     store = IStore(cls)
     for kind in desired_set.difference(current_set):
         bsf = cls()
         bsf.filter = self
         setattr(bsf, attribute, kind)
         store.add(bsf)
     # Remove unused.
     kind = getattr(cls, attribute)
     store.find(cls, cls.filter == self,
                kind.is_in(current_set.difference(desired_set))).remove()
コード例 #3
0
    def current_published(self):
        """See IDistroArchSeriesBinaryPackage."""
        current = IStore(BinaryPackagePublishingHistory).find(
            BinaryPackagePublishingHistory,
            BinaryPackagePublishingHistory.status
                == PackagePublishingStatus.PUBLISHED,
            *self._getPublicationJoins()
            ).order_by(Desc(BinaryPackagePublishingHistory.datecreated)
            ).first()

        if current is None:
            raise NotFoundError("Binary package %s not published in %s/%s"
                                % (self.binarypackagename.name,
                                   self.distroarchseries.distroseries.name,
                                   self.distroarchseries.architecturetag))

        return current
コード例 #4
0
    def create(cls, blob):
        """See `IProcessApportBlobJobSource`."""
        # If there's already a job for the BLOB, don't create a new one.
        # We also include jobs which have been completed when checking
        # for exisiting jobs, since a BLOB should only be processed
        # once.
        job_for_blob = IStore(ApportJob).find(
            ApportJob,
            ApportJob.blob == blob,
            ApportJob.job_type == cls.class_job_type,
            ApportJob.job == Job.id,
        ).any()

        if job_for_blob is not None:
            return cls(job_for_blob)
        else:
            return super(ProcessApportBlobJob, cls).create(blob)
コード例 #5
0
 def releases(self):
     """See IDistroArchSeriesBinaryPackage."""
     ret = IStore(BinaryPackageRelease).find(
         BinaryPackageRelease,
         *self._getPublicationJoins()
         ).order_by(Desc(BinaryPackageRelease.datecreated)
         ).config(distinct=True)
     result = []
     versions = set()
     for bpr in ret:
         if bpr.version not in versions:
             versions.add(bpr.version)
             darbpr = DistroArchSeriesBinaryPackageRelease(
                 distroarchseries=self.distroarchseries,
                 binarypackagerelease=bpr)
             result.append(darbpr)
     return result
コード例 #6
0
    def __init__(self, *args, **kwargs):
        """Construct a collection, possibly based on another one.

        :param base: Optional collection that this collection is based
            on.  The new collection will inherit its configuration.
        :param conditions: Optional Storm select conditions, e.g.
            `MyClass.attribute > 2`.
        :param classes: A class, or tuple or list of classes, that
            should go into the "FROM" clause of the new collection.
            This need not include classes that are already in the
            base collection, or that are included as outer joins.
        :param store: Optional: Storm `Store` to use.
        """
        starting_tables = []

        if len(args) >= 1 and isinstance(args[0], Collection):
            # There's a base collection.
            base = args[0]
            conditions = args[1:]
        else:
            # We're starting a fresh collection.
            base = None
            conditions = args
            if self.starting_table is not None:
                starting_tables = [self.starting_table]

        self.base = base

        if base is None:
            base_conditions = (True, )
            base_tables = []
        else:
            self.store = base.store
            base_conditions = base.conditions
            base_tables = list(base.tables)

        self.store = kwargs.get('store')
        if self.store is None:
            from lp.services.librarian.model import LibraryFileAlias
            self.store = IStore(LibraryFileAlias)

        self.tables = (starting_tables + base_tables +
                       self._parseTablesArg(kwargs.get('tables', [])))

        self.conditions = base_conditions + conditions
コード例 #7
0
    def storeRemoteProductsAndComponents(self, bz_bugtracker, lp_bugtracker):
        """Stores parsed product/component data from bz_bugtracker"""
        components_to_add = []
        for product in bz_bugtracker.products.itervalues():
            # Look up the component group id from Launchpad for the product
            # if it already exists.  Otherwise, add it.
            lp_component_group = lp_bugtracker.getRemoteComponentGroup(
                product['name'])
            if lp_component_group is None:
                lp_component_group = lp_bugtracker.addRemoteComponentGroup(
                    product['name'])
                if lp_component_group is None:
                    self.logger.warning("Failed to add new component group")
                    continue
            else:
                for component in lp_component_group.components:
                    if (component.name in product['components']
                            or component.is_visible == False
                            or component.is_custom == True):
                        # We already know something about this component,
                        # or a user has configured it, so ignore it
                        del product['components'][component.name]
                    else:
                        # Component is now missing from Bugzilla,
                        # so drop it here too
                        store = IStore(BugTrackerComponent)
                        store.find(
                            BugTrackerComponent,
                            BugTrackerComponent.id == component.id,
                        ).remove()

            # The remaining components in the collection will need to be
            # added to launchpad.  Record them for now.
            for component in product['components'].values():
                components_to_add.append(
                    (component['name'], lp_component_group, True, False))

        if len(components_to_add) > 0:
            self.logger.debug("...Inserting components into database")
            bulk.create(
                (BugTrackerComponent.name, BugTrackerComponent.component_group,
                 BugTrackerComponent.is_visible,
                 BugTrackerComponent.is_custom), components_to_add)
            transaction.commit()
            self.logger.debug("...Done")
コード例 #8
0
ファイル: ftparchive.py プロジェクト: pombredanne/launchpad-3
    def getBinaryFiles(self, distroseries, pocket):
        """Fetch publishing information about all published binary files.

        The publishing information consists of tuples with 'sourcename',
        'filename', 'component' and 'architecture' strings, in this order.

        :param distroseries: target `IDistroSeries`
        :param pocket: target `PackagePublishingPocket`

        :return: a `ResultSet` with the binary files information tuples.
        """
        columns = (
            SourcePackageName.name,
            LibraryFileAlias.filename,
            Component.name,
            Concatenate(u"binary-", DistroArchSeries.architecturetag),
        )
        join_conditions = [
            BinaryPackageRelease.id ==
            BinaryPackagePublishingHistory.binarypackagereleaseID,
            BinaryPackageFile.binarypackagereleaseID ==
            BinaryPackagePublishingHistory.binarypackagereleaseID,
            BinaryPackageBuild.id == BinaryPackageRelease.buildID,
            SourcePackageName.id == BinaryPackageBuild.source_package_name_id,
            LibraryFileAlias.id == BinaryPackageFile.libraryfileID,
            DistroArchSeries.id ==
            BinaryPackagePublishingHistory.distroarchseriesID,
            Component.id == BinaryPackagePublishingHistory.componentID,
        ]
        select_conditions = [
            DistroArchSeries.distroseriesID == distroseries.id,
            BinaryPackagePublishingHistory.archive == self.publisher.archive,
            BinaryPackagePublishingHistory.pocket == pocket,
            BinaryPackagePublishingHistory.status ==
            PackagePublishingStatus.PUBLISHED,
        ]

        if not self.publisher.archive.publish_debug_symbols:
            select_conditions.append(BinaryPackageRelease.binpackageformat !=
                                     BinaryPackageFormat.DDEB)

        result_set = IStore(BinaryPackageRelease).find(
            columns, *(join_conditions + select_conditions))
        return result_set.order_by(LibraryFileAlias.filename,
                                   BinaryPackageFile.id)
コード例 #9
0
    def _getSharedPillars(self, person, user, pillar_class, extra_filter=None):
        """Helper method for getSharedProjects and getSharedDistributions.

        pillar_class is either Product or Distribution. Products define the
        owner foreign key attribute as _owner so we need to account for that,
        but otherwise the logic is the same for both pillar types.
        """
        if user is None:
            return []
        store = IStore(AccessPolicyGrantFlat)
        roles = IPersonRoles(user)
        if roles.in_admin:
            filter = True
        else:
            with_statement = With("teams",
                Select(TeamParticipation.teamID,
                    tables=TeamParticipation,
                    where=TeamParticipation.person == user.id))
            teams_sql = SQL("SELECT team from teams")
            store = store.with_(with_statement)
            if IProduct.implementedBy(pillar_class):
                ownerID = pillar_class._ownerID
            else:
                ownerID = pillar_class.ownerID
            filter = Or(
                extra_filter or False,
                ownerID.is_in(teams_sql),
                pillar_class.driverID.is_in(teams_sql))
        tables = [
            AccessPolicyGrantFlat,
            Join(
                AccessPolicy,
                AccessPolicyGrantFlat.policy_id == AccessPolicy.id)]
        if IProduct.implementedBy(pillar_class):
            access_policy_column = AccessPolicy.product_id
        else:
            access_policy_column = AccessPolicy.distribution_id
        result_set = store.find(
            pillar_class,
            pillar_class.id.is_in(
                Select(
                    columns=access_policy_column, tables=tables,
                    where=(AccessPolicyGrantFlat.grantee_id == person.id))
            ), filter)
        return result_set
コード例 #10
0
    def _set_tags(self, tags):
        """Update the tags to filter on.

        The tags can be qualified with a leading hyphen, and can be bundled in
        any iterable.

        If they are passed within a `searchbuilder.any` or `searchbuilder.all`
        object, the `find_all_tags` attribute will be updated to match.

        Wildcard tags - `*` and `-*` - can be given too, and will update
        `include_any_tags` and `exclude_any_tags`.
        """
        # Deal with searchbuilder terms.
        if isinstance(tags, searchbuilder.all):
            self.find_all_tags = True
            tags = frozenset(tags.query_values)
        elif isinstance(tags, searchbuilder.any):
            self.find_all_tags = False
            tags = frozenset(tags.query_values)
        else:
            # Leave find_all_tags unchanged.
            tags = frozenset(tags)
        wildcards = frozenset((u"*", u"-*")).intersection(tags)
        # Set wildcards.
        self.include_any_tags = "*" in wildcards
        self.exclude_any_tags = "-*" in wildcards
        # Deal with other tags.
        tags = tags - wildcards
        store = IStore(BugSubscriptionFilterTag)
        current_tag_filters = dict(
            (tag_filter.qualified_tag, tag_filter)
            for tag_filter in store.find(
                BugSubscriptionFilterTag, BugSubscriptionFilterTag.filter ==
                self))
        # Remove unused tags.
        for tag in set(current_tag_filters).difference(tags):
            tag_filter = current_tag_filters.pop(tag)
            store.remove(tag_filter)
        # Add additional tags.
        for tag in tags.difference(current_tag_filters):
            tag_filter = BugSubscriptionFilterTag()
            tag_filter.filter = self
            tag_filter.include = not tag.startswith("-")
            tag_filter.tag = tag.lstrip("-")
            store.add(tag_filter)
コード例 #11
0
 def getSubscriptionsForTeams(self, person, teams):
     """See `IMailingListSet`."""
     store = IStore(MailingList)
     team_ids = set(map(operator.attrgetter("id"), teams))
     lists = dict(
         store.find((MailingList.teamID, MailingList.id),
                    MailingList.teamID.is_in(team_ids),
                    MailingList.status.is_in(USABLE_STATUSES)))
     subscriptions = dict(
         store.find(
             (MailingListSubscription.mailing_listID,
              MailingListSubscription.id),
             MailingListSubscription.person == person,
             MailingListSubscription.mailing_listID.is_in(lists.values())))
     by_team = {}
     for team, mailing_list in lists.items():
         by_team[team] = (mailing_list, subscriptions.get(mailing_list))
     return by_team
コード例 #12
0
 def checkPillarAccess(self, pillars, information_type, person):
     """See `ISharingService`."""
     policies = getUtility(IAccessPolicySource).find([
         (pillar, information_type) for pillar in pillars
     ])
     policy_ids = [policy.id for policy in policies]
     if not policy_ids:
         return False
     store = IStore(AccessPolicyGrant)
     tables = [
         AccessPolicyGrant,
         Join(TeamParticipation,
              TeamParticipation.teamID == AccessPolicyGrant.grantee_id),
     ]
     result = store.using(*tables).find(
         AccessPolicyGrant, AccessPolicyGrant.policy_id.is_in(policy_ids),
         TeamParticipation.personID == person.id)
     return not result.is_empty()
コード例 #13
0
    def iterReady(cls):
        """Iterate through all ready PackageCopyJobs.

        Even though it's slower, we repeat the query each time in order that
        very long queues of mass syncs can be pre-empted by other jobs.
        """
        seen = set()
        while True:
            jobs = IStore(PackageCopyJob).find(
                PackageCopyJob, PackageCopyJob.job_type == cls.class_job_type,
                PackageCopyJob.job == Job.id, Job.id.is_in(Job.ready_jobs),
                Not(Job.id.is_in(seen)))
            jobs.order_by(PackageCopyJob.copy_policy)
            job = jobs.first()
            if job is None:
                break
            seen.add(job.job_id)
            yield cls(job)
コード例 #14
0
ファイル: buildqueue.py プロジェクト: pombredanne/launchpad-3
 def preloadForBuildFarmJobs(self, builds):
     """See `IBuildQueueSet`."""
     from lp.buildmaster.model.builder import Builder
     bqs = list(
         IStore(BuildQueue).find(
             BuildQueue,
             BuildQueue._build_farm_job_id.is_in([
                 removeSecurityProxy(b).build_farm_job_id for b in builds
             ])))
     load_related(Builder, bqs, ['builderID'])
     prefetched_data = dict(
         (removeSecurityProxy(buildqueue)._build_farm_job_id, buildqueue)
         for buildqueue in bqs)
     for build in builds:
         bq = prefetched_data.get(
             removeSecurityProxy(build).build_farm_job_id)
         get_property_cache(build).buildqueue_record = bq
     return bqs
コード例 #15
0
 def test_manifest(self):
     """Manifest should start empty, but accept SourcePackageRecipeData."""
     recipe = self.factory.makeSourcePackageRecipe()
     build = recipe.requestBuild(
         recipe.daily_build_archive, recipe.owner,
         list(recipe.distroseries)[0], PackagePublishingPocket.RELEASE)
     self.assertIs(None, build.manifest)
     self.assertIs(None, build.getManifestText())
     manifest_text = self.factory.makeRecipeText()
     removeSecurityProxy(build).setManifestText(manifest_text)
     self.assertEqual(manifest_text, build.getManifestText())
     self.assertIsNot(None, build.manifest)
     IStore(build).flush()
     manifest_text = self.factory.makeRecipeText()
     removeSecurityProxy(build).setManifestText(manifest_text)
     self.assertEqual(manifest_text, build.getManifestText())
     removeSecurityProxy(build).setManifestText(None)
     self.assertIs(None, build.manifest)
コード例 #16
0
 def sourcesIncluded(self, direct_inclusion=False):
     """See `IPackageset`."""
     if direct_inclusion == False:
         source_name_query = '''
             SELECT pss.sourcepackagename
             FROM packagesetsources pss, flatpackagesetinclusion fpsi
             WHERE pss.packageset = fpsi.child AND fpsi.parent = ?
         '''
     else:
         source_name_query = '''
             SELECT pss.sourcepackagename FROM packagesetsources pss
             WHERE pss.packageset = ?
         '''
     store = IStore(Packageset)
     source_names = SQL(source_name_query, (self.id,))
     result_set = store.find(
         SourcePackageName, SourcePackageName.id.is_in(source_names))
     return _order_result_set(result_set)
コード例 #17
0
ファイル: karma.py プロジェクト: pombreda/UnnaturalCodeFork
    def _getEntry(self,
                  person_id,
                  category_id,
                  product_id=None,
                  distribution_id=None,
                  sourcepackagename_id=None,
                  project_id=None):
        """Return the KarmaCache entry with the given arguments.

        Return None if it's not found.
        """
        return IStore(KarmaCache).find(
            KarmaCache, KarmaCache.personID == person_id,
            KarmaCache.categoryID == category_id,
            KarmaCache.productID == product_id,
            KarmaCache.projectID == project_id,
            KarmaCache.distributionID == distribution_id,
            KarmaCache.sourcepackagenameID == sourcepackagename_id).one()
コード例 #18
0
    def getOnePOFile(self):
        """See `ITranslationMessage`."""
        from lp.translations.model.pofile import POFile

        # Get any POFile where this translation exists.
        # Because we can't create a subselect with "LIMIT" using Storm,
        # we directly embed a subselect using raw SQL instead.
        # We can do this because our message sharing code ensures a POFile
        # exists for any of the sharing templates.
        # This approach gives us roughly a 100x performance improvement
        # compared to straightforward join as of 2010-11-11. - danilo
        pofile = IStore(self).find(
            POFile, POFile.potemplateID == SQL("""(SELECT potemplate
                    FROM TranslationTemplateItem
                    WHERE potmsgset = %s AND sequence > 0
                    LIMIT 1)""" % sqlvalues(self.potmsgsetID)),
            POFile.language == self.language).one()
        return pofile
コード例 #19
0
 def _getFreeBuildersCount(self, processor, virtualized):
     """How many builders capable of running jobs for the given processor
     and virtualization combination are idle/free at present?"""
     query = """
         SELECT COUNT(id) FROM builder
         WHERE
             builderok = TRUE AND manual = FALSE
             AND id NOT IN (
                 SELECT builder FROM BuildQueue WHERE builder IS NOT NULL)
             AND virtualized = %s
         """ % sqlvalues(normalize_virtualization(virtualized))
     if processor is not None:
         query += """
             AND processor = %s
         """ % sqlvalues(processor)
     result_set = IStore(BuildQueue).execute(query)
     free_builders = result_set.get_one()[0]
     return free_builders
コード例 #20
0
 def getNextJobStatus(cls, packaging):
     """Return the status of the next job to run."""
     store = IStore(TranslationSharingJob)
     result = store.find(
         Job, Job.id == TranslationSharingJob.job_id,
         (TranslationSharingJob.distroseries_id
          == packaging.distroseries.id),
         TranslationSharingJob.sourcepackagename_id ==
         packaging.sourcepackagename.id,
         (TranslationSharingJob.productseries_id
          == packaging.productseries.id),
         TranslationSharingJob.job_type == cls.class_job_type,
         Job._status.is_in([JobStatus.WAITING, JobStatus.RUNNING]))
     result.order_by(TranslationSharingJob.id)
     job = result.first()
     if job is None:
         return None
     return job.status
コード例 #21
0
 def fetchProjectsForDisplay(self, user):
     """See `ITranslationGroup`."""
     # Avoid circular imports.
     from lp.registry.model.product import (
         get_precached_products,
         Product,
         ProductSet,
         )
     products = list(IStore(Product).find(
         Product,
         Product.translationgroupID == self.id,
         Product.active == True,
         ProductSet.getProductPrivacyFilter(user),
         ).order_by(Product.display_name))
     get_precached_products(products, need_licences=True)
     icons = bulk.load_related(LibraryFileAlias, products, ['iconID'])
     bulk.load_related(LibraryFileContent, icons, ['contentID'])
     return products
コード例 #22
0
    def getSimpleUpgrades(distro_series):
        """See `IDistroSeriesDifferenceSource`.

        Eager-load related `ISourcePackageName` records.
        """
        differences = IStore(DistroSeriesDifference).find(
            (DistroSeriesDifference, SourcePackageName),
            DistroSeriesDifference.derived_series == distro_series,
            DistroSeriesDifference.difference_type ==
            DistroSeriesDifferenceType.DIFFERENT_VERSIONS,
            DistroSeriesDifference.status ==
            DistroSeriesDifferenceStatus.NEEDS_ATTENTION,
            DistroSeriesDifference.parent_source_version !=
            DistroSeriesDifference.base_version,
            DistroSeriesDifference.source_version ==
            DistroSeriesDifference.base_version, SourcePackageName.id ==
            DistroSeriesDifference.source_package_name_id)
        return DecoratedResultSet(differences, itemgetter(0))
コード例 #23
0
ファイル: productjob.py プロジェクト: pombredanne/launchpad-3
 def getExpiringProducts(cls):
     """See `ExpirationSourceMixin`."""
     earliest_date, latest_date, past_date = cls._get_expiration_dates()
     recent_jobs = And(
         ProductJob.job_type == cls.class_job_type,
         ProductJob.job_id == Job.id,
         Job.date_created > past_date,
         )
     conditions = [
         Product.active == True,
         CommercialSubscription.productID == Product.id,
         CommercialSubscription.date_expires >= earliest_date,
         CommercialSubscription.date_expires < latest_date,
         Not(Product.id.is_in(Select(
             ProductJob.product_id,
             tables=[ProductJob, Job], where=recent_jobs))),
         ]
     return IStore(Product).find(Product, *conditions)
コード例 #24
0
 def test_revokeByArtifact_specified_grantees(self):
     # revokeByArtifact() removes the relevant grants for the specified
     # grantees.
     artifact = self.factory.makeAccessArtifact()
     grantee = self.factory.makePerson()
     someone_else = self.factory.makePerson()
     grant = self.factory.makeAccessArtifactGrant(artifact=artifact,
                                                  grantee=grantee)
     someone_else_grant = self.factory.makeAccessArtifactGrant(
         artifact=artifact, grantee=someone_else)
     other_grant = self.factory.makeAccessArtifactGrant()
     aags = getUtility(IAccessArtifactGrantSource)
     aags.revokeByArtifact([artifact], [grantee])
     IStore(grant).invalidate()
     self.assertRaises(LostObjectError, getattr, grant, 'grantor')
     self.assertEqual(someone_else_grant,
                      aags.findByArtifact([artifact])[0])
     self.assertIsNot(None, other_grant.grantor)
コード例 #25
0
 def findStaleDailyBuilds():
     one_day_ago = datetime.now(utc) - timedelta(hours=23, minutes=50)
     joins = (
         SourcePackageRecipe,
         LeftJoin(
             SourcePackageRecipeBuild,
             And(
                 SourcePackageRecipeBuild.recipe_id ==
                 SourcePackageRecipe.id, SourcePackageRecipeBuild.archive_id
                 == SourcePackageRecipe.daily_build_archive_id,
                 SourcePackageRecipeBuild.date_created > one_day_ago)),
     )
     return IStore(SourcePackageRecipe).using(*joins).find(
         SourcePackageRecipe,
         SourcePackageRecipe.is_stale == True,
         SourcePackageRecipe.build_daily == True,
         SourcePackageRecipeBuild.date_created == None,
     ).config(distinct=True)
コード例 #26
0
 def packagesetsForSourceUploader(self, archive, sourcepackagename, person):
     """See `IArchivePermissionSet`."""
     sourcepackagename = self._nameToSourcePackageName(sourcepackagename)
     store = IStore(ArchivePermission)
     query = '''
         SELECT ap.id
         FROM
             archivepermission ap, teamparticipation tp,
             packagesetsources pss, flatpackagesetinclusion fpsi
         WHERE
             ap.person = tp.team AND tp.person = ?
             AND ap.packageset = fpsi.parent
             AND pss.packageset = fpsi.child
             AND pss.sourcepackagename = ?
             AND ap.archive = ?
     '''
     query = SQL(query, (person.id, sourcepackagename.id, archive.id))
     return store.find(ArchivePermission, ArchivePermission.id.is_in(query))
コード例 #27
0
 def test_reclaimbranchspace_script(self):
     # When the reclaimbranchspace script is run, it removes from the file
     # system any branches that were deleted from the database more than a
     # week ago.
     db_branch = self.factory.makeAnyBranch()
     mirrored_path = self.getBranchPath(
         db_branch, config.codehosting.mirrored_branches_root)
     if os.path.exists(mirrored_path):
         shutil.rmtree(mirrored_path)
     os.makedirs(mirrored_path)
     db_branch.destroySelf()
     transaction.commit()
     # The first run doesn't remove anything yet.
     retcode, stdout, stderr = run_script(
         'cronscripts/process-job-source.py',
         ['IReclaimBranchSpaceJobSource'])
     self.assertEqual('', stdout)
     self.assertEqual(
         'INFO    Creating lockfile: /var/lock/'
         'launchpad-process-job-source-IReclaimBranchSpaceJobSource.lock\n'
         'INFO    Running synchronously.\n', stderr)
     self.assertEqual(0, retcode)
     self.assertTrue(os.path.exists(mirrored_path))
     # Now pretend that the branch was deleted 8 days ago.
     reclaim_job = IStore(BranchJob).find(
         BranchJob,
         BranchJob.job_type == BranchJobType.RECLAIM_BRANCH_SPACE).one()
     reclaim_job.job.scheduled_start -= datetime.timedelta(days=8)
     transaction.commit()
     # The script will now remove the branch from disk.
     retcode, stdout, stderr = run_script(
         'cronscripts/process-job-source.py',
         ['IReclaimBranchSpaceJobSource'])
     self.assertEqual('', stdout)
     self.assertTextMatchesExpressionIgnoreWhitespace(
         'INFO    Creating lockfile: /var/lock/'
         'launchpad-process-job-source-IReclaimBranchSpaceJobSource.lock\n'
         'INFO    Running synchronously.\n'
         'INFO    Running <RECLAIM_BRANCH_SPACE branch job \(\d+\) for '
         '\d+> \(ID %s\) in status Waiting\n'
         'INFO    Ran 1 ReclaimBranchSpaceJob jobs.\n' % reclaim_job.job.id,
         stderr)
     self.assertEqual(0, retcode)
     self.assertFalse(os.path.exists(mirrored_path))
コード例 #28
0
        def load_teams_and_permissions(grantees):
            # We now have the grantees we want in the result so load any
            # associated team memberships and permissions and cache them.
            if permissions_cache:
                return
            store = IStore(cls)
            for grantee in grantees:
                grantees_by_id[grantee[0].id] = grantee[0]
            # Find any teams associated with the grantees. If grantees is a
            # sliced list (for batching), it may contain indirect grantees but
            # not the team they belong to so that needs to be fixed below.
            with_expr = With(
                "grantees",
                store.find(cls.grantee_id,
                           cls.policy_id.is_in(policies_by_id.keys())).config(
                               distinct=True)._get_select())
            result_set = store.with_(with_expr).find(
                (TeamParticipation.teamID, TeamParticipation.personID),
                TeamParticipation.personID.is_in(grantees_by_id.keys()),
                TeamParticipation.teamID.is_in(
                    Select((SQL("grantees.grantee"), ),
                           tables="grantees",
                           distinct=True)))
            team_ids = set()
            direct_grantee_ids = set()
            for team_id, team_member_id in result_set:
                if team_member_id == team_id:
                    direct_grantee_ids.add(team_member_id)
                else:
                    via_teams_cache[team_member_id].append(team_id)
                    team_ids.add(team_id)
            # Remove from the via_teams cache all the direct grantees.
            for direct_grantee_id in direct_grantee_ids:
                if direct_grantee_id in via_teams_cache:
                    del via_teams_cache[direct_grantee_id]
            # Load and cache the additional required teams.
            persons = store.find(Person, Person.id.is_in(team_ids))
            for person in persons:
                grantees_by_id[person.id] = person

            cls._populatePermissionsCache(permissions_cache,
                                          shared_artifact_info_types,
                                          grantees_by_id.keys(),
                                          policies_by_id, grantees_by_id)
コード例 #29
0
    def test_run_cronscript(self):
        # Everything is configured: ZCML, schema-lazr.conf, and security.cfg.
        product, reviewer = self.make_notification_data()
        private_branch = self.factory.makeBranch(
            owner=product.owner, product=product,
            information_type=InformationType.USERDATA)
        with person_logged_in(product.owner):
            product.development_focus.branch = private_branch
        self.expire_commercial_subscription(product)
        job = self.JOB_CLASS.create(product, reviewer)
        # Create a proprietary project owned by a team which will have
        # different DB relations.
        team = self.factory.makeTeam(
            membership_policy=TeamMembershipPolicy.RESTRICTED)
        proprietary_product = self.factory.makeProduct(
            owner=team, licenses=[License.OTHER_PROPRIETARY])
        self.expire_commercial_subscription(proprietary_product)
        proprietary_job = self.JOB_CLASS.create(proprietary_product, reviewer)
        transaction.commit()

        out, err, exit_code = run_script(
            "LP_DEBUG_SQL=1 cronscripts/process-job-source.py -vv %s" %
             self.JOB_SOURCE_INTERFACE.getName())
        self.addDetail("stdout", Content(UTF8_TEXT, lambda: out))
        self.addDetail("stderr", Content(UTF8_TEXT, lambda: err))
        self.assertEqual(0, exit_code)
        self.assertTrue(
            'Traceback (most recent call last)' not in err)
        message = (
            '%s has sent email to the maintainer of %s.' % (
                self.JOB_CLASS.__name__, product.name))
        self.assertTrue(
            message in err,
            'Cound not find "%s" in err log:\n%s.' % (message, err))
        message = (
            '%s has sent email to the maintainer of %s.' % (
                self.JOB_CLASS.__name__, proprietary_product.name))
        self.assertTrue(
            message in err,
            'Cound not find "%s" in err log:\n%s.' % (message, err))
        IStore(job.job).invalidate()
        self.assertEqual(JobStatus.COMPLETED, job.job.status)
        self.assertEqual(JobStatus.COMPLETED, proprietary_job.job.status)
コード例 #30
0
 def _nameToPackageset(self, packageset):
     """Helper to convert a possible string name to IPackageset."""
     if isinstance(packageset, basestring):
         # A package set name was passed, assume the current distro series.
         ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
         name = packageset
         store = IStore(Packageset)
         packageset = store.find(Packageset,
                                 name=name,
                                 distroseries=ubuntu.currentseries).one()
         if packageset is not None:
             return packageset
         else:
             raise NotFoundError("No such package set '%s'" % name)
     elif IPackageset.providedBy(packageset):
         return packageset
     else:
         raise ValueError('Not a package set: %s' %
                          _extract_type_name(packageset))