Ejemplo n.º 1
0
    def get(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        args = self.get_parser.parse_args()

        queryset = Plan.query.filter(
            Plan.project_id == project.id,
        )

        if args.query:
            queryset = queryset.filter(
                func.lower(Plan.label).contains(args.query.lower()),
            )

        if args.status:
            queryset = queryset.filter(
                Plan.status == PlanStatus[args.status],
            )

        if args.sort == 'name':
            queryset = queryset.order_by(Plan.label.asc())
        elif args.sort == 'date':
            queryset = queryset.order_by(Plan.date_created.asc())

        return self.paginate(queryset)
Ejemplo n.º 2
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).join(Revision.author).first()
        if not revision:
            return '', 404

        build_list = list(Build.query.options(
            joinedload('author'),
            contains_eager('source'),
        ).join(
            Source, Build.source_id == Source.id,
        ).filter(
            Build.project_id == project.id,
            Source.revision_sha == revision.sha,
            Source.patch == None,  # NOQA
        ).order_by(Build.date_created.desc()))[:100]

        context = self.serialize(revision)

        context.update({
            'repository': repo,
            'builds': build_list,
        })

        return self.respond(context)
Ejemplo n.º 3
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        query = request.args.get('q', request.args.get('query'))
        source = request.args.get('source')

        filters = []

        if source:
            filters.append(Build.target.startswith(source))

        if query:
            filters.append(or_(
                Build.label.contains(query),
                Build.target.startswith(query),
            ))

        queryset = Build.query.options(
            joinedload('project', innerjoin=True),
            joinedload('author'),
            joinedload('source'),
        ).filter(
            Build.project_id == project.id,
            *filters
        ).order_by(Build.date_created.desc())

        return self.paginate(queryset)
Ejemplo n.º 4
0
    def get(self, project_id, source_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        source = Source.query.filter(
            Source.id == source_id,
            Source.repository_id == repo.id,
        ).first()
        if source is None:
            return '', 404

        context = self.serialize(source)

        if source.patch:
            context['diff'] = source.patch.diff
        else:
            vcs = repo.get_vcs()
            if vcs:
                try:
                    context['diff'] = vcs.export(source.revision_sha)
                except Exception:
                    context['diff'] = None
            else:
                context['diff'] = None

        return self.respond(context)
Ejemplo n.º 5
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.get_parser.parse_args()

        filters = []

        if args.source:
            filters.append(Build.target.startswith(args.source))

        if args.query:
            filters.append(or_(
                Build.label.contains(args.query),
                Build.target.startswith(args.query),
            ))

        if args.result:
            filters.append(Build.result == Result[args.result])

        queryset = Build.query.options(
            joinedload('project', innerjoin=True),
            joinedload('author'),
            joinedload('source').joinedload('revision'),
        ).filter(
            Build.project_id == project.id,
            *filters
        ).order_by(Build.date_created.desc())

        return self.paginate(queryset)
Ejemplo n.º 6
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()
        if args.date:
            try:
                query_date = datetime.strptime(args.date, '%Y-%m-%d').date()
            except:
                return 'Can\'t parse date "%s"' % (args.date), 500
        else:
            # This `7` is hard-coded to match the code in config.py which kicks
            # off the cron job 7 hours past midnight GMT (which corresponds to
            # midnight PST)
            delta = timedelta(days=2 if datetime.utcnow().hour < 7 else 1)
            query_date = datetime.utcnow().date() - delta

        data = {
            'date': str(query_date),
            'chartData': self.get_chart_data(project_id, query_date),
            'flakyTests': self.get_flaky_tests(project_id, query_date)
        }

        return self.respond(data, serialize=False)
Ejemplo n.º 7
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).join(Revision.author).first()
        if not revision:
            return '', 404

        build_query = Build.query.options(
            joinedload('author'),
            contains_eager('source').joinedload('revision'),
        ).join(
            Source, Build.source_id == Source.id,
        ).filter(
            Build.project_id == project.id,
            Source.revision_sha == revision.sha,
            Source.patch == None,  # NOQA
        ).order_by(Build.date_created.desc())

        return self.paginate(build_query)
Ejemplo n.º 8
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        try:
            revision = Revision.get_by_sha_prefix_query(
                repo.id,
                commit_id,
            ).options(
                joinedload('author')
            ).scalar()
        except MultipleResultsFound:
            return '', 404
        else:
            if not revision:
                return '', 404

            context = self.serialize(revision)

            context.update({
                'repository': repo,
            })

            return self.respond(context)
Ejemplo n.º 9
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        first_test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.asc()).limit(1).first()
        first_build = Build.query.options(
            joinedload('author'),
            joinedload('source').joinedload('revision'),
        ).filter(
            Build.id == first_test.job.build_id,
        ).first()

        context = self.serialize(test, {
            TestCase: GeneralizedTestCase(),
        })
        context.update({
            'firstBuild': first_build,
        })

        return self.respond(context, serialize=False)
Ejemplo n.º 10
0
    def post(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        args = self.post_parser.parse_args()

        if args.name:
            project.name = args.name

        if args.slug:
            match = Project.query.filter(
                Project.slug == args.slug,
                Project.id != project.id,
            ).first()
            if match:
                return '{"error": "Project with slug %r already exists"}' % (args.slug,), 400

            project.slug = args.slug

        if args.repository:
            repository = Repository.get(args.repository)
            if repository is None:
                return '{"error": "Repository with url %r does not exist"}' % (args.repository,), 400
            project.repository = repository

        db.session.add(project)

        data = self.serialize(project)
        data['repository'] = self.serialize(project.repository)

        return self.respond(data, serialize=False)
Ejemplo n.º 11
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        first_test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.asc()).limit(1).first()
        first_build = Build.query.options(
            joinedload('author'),
            joinedload('source').joinedload('revision'),
        ).filter(Build.id == first_test.job.build_id, ).first()

        context = self.serialize(test, {
            TestCase: GeneralizedTestCase(),
        })
        context.update({
            'firstBuild': first_build,
        })

        return self.respond(context, serialize=False)
Ejemplo n.º 12
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.options(joinedload('author'), ).filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).first()
        if not revision:
            return '', 404

        build_query = Build.query.options(
            joinedload('author'),
            contains_eager('source').joinedload('revision'),
        ).join(
            Source,
            Build.source_id == Source.id,
        ).filter(
            Build.project_id == project.id,
            Source.revision_sha == revision.sha,
            Source.patch == None,  # NOQA
        ).order_by(Build.date_created.desc())

        return self.paginate(build_query)
Ejemplo n.º 13
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        args = self.get_parser.parse_args()

        num_results = args.per_page

        # restrict the join to the last N jobs otherwise this can get
        # significantly expensive as we have to seek quite a ways
        job_sq = Job.query.filter(
            Job.status == Status.finished,
            Job.project_id == project_id,
        ).order_by(Job.date_created.desc()).limit(num_results * 10).subquery()

        recent_runs = list(
            TestCase.query.options(
                contains_eager('job', alias=job_sq),
                contains_eager('job.source'),
                joinedload('job.build'),
                joinedload('job.build.author'),
                joinedload('job.build.source'),
                joinedload('job.build.source.revision'),
            ).join(
                job_sq,
                TestCase.job_id == job_sq.c.id,
            ).join(
                Source,
                job_sq.c.source_id == Source.id,
            ).filter(
                Source.repository_id == project.repository_id,
                Source.patch_id == None,  # NOQA
                Source.revision_sha != None,  # NOQA
                TestCase.name_sha == test.name_sha,
            ).order_by(job_sq.c.date_created.desc()))

        jobs = set(r.job for r in recent_runs)
        builds = set(j.build for j in jobs)

        serialized_jobs = dict(zip(jobs, self.serialize(jobs)))
        serialized_builds = dict(zip(builds, self.serialize(builds)))

        results = []
        for recent_run, s_recent_run in zip(recent_runs,
                                            self.serialize(recent_runs)):
            s_recent_run['job'] = serialized_jobs[recent_run.job]
            s_recent_run['job']['build'] = serialized_builds[
                recent_run.job.build]
            results.append(s_recent_run)

        return self.paginate(results, serialize=False)
Ejemplo n.º 14
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.get_parser.parse_args()

        filters = []

        if args.source:
            filters.append(Build.target.startswith(args.source))

        if args.query:
            filters.append(
                or_(
                    Build.label.contains(args.query),
                    Build.target.startswith(args.query),
                ))

        if args.result:
            filters.append(Build.result == Result[args.result])

        queryset = Build.query.options(
            joinedload('project', innerjoin=True),
            joinedload('author'),
            joinedload('source'),
        ).filter(Build.project_id == project.id,
                 *filters).order_by(Build.date_created.desc())

        return self.paginate(queryset)
Ejemplo n.º 15
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).join(Revision.author).first()
        if not revision:
            return '', 404

        build_list = list(
            Build.query.options(
                joinedload('author'),
                contains_eager('source'),
            ).join(
                Source,
                Build.source_id == Source.id,
            ).filter(
                Build.project_id == project.id,
                Source.revision_sha == revision.sha,
                Source.patch == None,  # NOQA
            ).order_by(Build.date_created.desc()))[:100]

        context = self.serialize(revision)

        context.update({
            'repository': repo,
            'builds': build_list,
        })

        return self.respond(context)
Ejemplo n.º 16
0
def test_simple():
    build = Build(
        id=UUID(hex='33846695b2774b29a71795a009e8168a'),
        label='Hello world',
        target='D1234',
        message='Foo bar',
        project=Project(
            slug='test', name='test', id=UUID('1e7958a368f44b0eb5a57372a9910d50'),
        ),
        project_id=UUID('1e7958a368f44b0eb5a57372a9910d50'),
        source=Source(
            revision_sha='1e7958a368f44b0eb5a57372a9910d50',
        ),
        date_created=datetime(2013, 9, 19, 22, 15, 22),
        date_started=datetime(2013, 9, 19, 22, 15, 23),
        date_finished=datetime(2013, 9, 19, 22, 15, 33),
    )
    result = serialize(build)
    assert result['name'] == 'Hello world'
    assert result['id'] == '33846695b2774b29a71795a009e8168a'
    assert result['source']['id'] == build.source.id.hex
    assert result['target'] == 'D1234'
    assert result['message'] == 'Foo bar'
    assert result['dateCreated'] == '2013-09-19T22:15:22'
    assert result['dateStarted'] == '2013-09-19T22:15:23'
    assert result['dateFinished'] == '2013-09-19T22:15:33'
    assert result['duration'] == 10000
    assert result['link'] == 'http://example.com/projects/test/builds/{0}/'.format(build.id.hex)
Ejemplo n.º 17
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.get_parser.parse_args()

        filters = []

        if args.authors:
            filters.append(Build.author_id.in_([a.id for a in args.authors]))
        elif args.authors is not None:
            return []

        if args.source:
            filters.append(Build.target.startswith(args.source))

        # is this from the search bar
        if args.query:
            clauses = []
            # search by revision title
            clauses.append(Build.label.contains(args.query))
            # search by prefix
            clauses.append(Build.target.startswith(args.query))
            # allows users to paste a full commit hash and still
            # find the relevant build(s). Should be fine for mercurial/git,
            # and svn will never have long enough strings
            if len(args.query) > 12:
                clauses.append(Build.target.startswith(args.query[0:12]))
            # if they searched for something that looks like a phabricator
            # identifier, try to find it
            if might_be_diffusion_iden(args.query):
                possible_hash = get_hash_from_diffusion_iden(args.query)
                if possible_hash:
                    # the query should always be at least as long or longer than
                    # our commit identifiers
                    clauses.append(
                        Build.target.startswith(possible_hash[0:12]))
            filters.append(or_(*clauses))

        if args.result:
            filters.append(Build.result == Result[args.result])

        if args.patches_only:
            filters.append(Source.patch_id != None)  # NOQA
        elif not args.include_patches:
            filters.append(Source.patch_id == None)  # NOQA

        queryset = Build.query.options(
            joinedload('project', innerjoin=True),
            joinedload('author'),
            contains_eager('source').joinedload('revision'),
        ).join(
            Source, Source.id == Build.source_id,
        ).filter(
            Build.project_id == project.id,
            *filters
        ).order_by(Build.date_created.desc())

        return self.paginate(queryset)
Ejemplo n.º 18
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()
        if args.date:
            try:
                query_date = datetime.strptime(args.date, '%Y-%m-%d').date()
            except:
                return 'Can\'t parse date "%s"' % (args.date), 500
        else:
            # This `7` is hard-coded to match the code in config.py which kicks
            # off the cron job 7 hours past midnight GMT (which corresponds to
            # midnight PST)
            delta = timedelta(days=2 if datetime.utcnow().hour < 7 else 1)
            query_date = datetime.utcnow().date() - delta

        data = {
            'date': str(query_date),
            'chartData': self.get_chart_data(project_id, query_date),
            'flakyTests': self.get_flaky_tests(project_id, query_date)
        }

        return self.respond(data, serialize=False)
Ejemplo n.º 19
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return error('project not found', http_code=404)

        args = self.get_parser.parse_args()

        # we want to only return commits in the repo that are within the
        # project's whitelist
        paths = None
        if not args.every_commit:
            paths = self.get_whitelisted_paths(project)

        repo = project.repository
        offset = (args.page - 1) * args.per_page
        limit = args.per_page + 1  # +1 to tell if there are more revs to get

        vcs = repo.get_vcs()
        if vcs:
            try:
                commits = self.get_commits_from_vcs(repo, vcs, offset, limit,
                                                    paths, args.parent,
                                                    args.branch)
            except ValueError as err:
                return error(err.message)
        else:
            if args.parent or args.branch:
                param = 'Branches' if args.branch else 'Parents'
                return error(
                    '{0} not supported for projects with no repository.'.
                    format(param),
                    http_code=422)
            # TODO: right now this fallback returns every commit for projects
            # with whitelisted paths.  At the very least, we need to tell the
            # frontend about this (perhaps using a response header)
            commits = self.get_commits_from_db(repo, offset, limit)

        page_links = self.make_links(
            current_page=args.page,
            has_next_page=len(commits) > args.per_page,
        )
        # we fetched one extra commit so that we'd know whether to create a
        # next link. Delete it
        commits = commits[:args.per_page]

        builds_map = {}
        if commits:
            builds_map = self.get_builds_for_commits(commits, project,
                                                     args.all_builds)

        results = []
        for result in commits:
            if args.all_builds:
                result['builds'] = builds_map.get(result['id'], [])
            else:
                result['build'] = builds_map.get(result['id'])
            results.append(result)

        return self.respond(results, serialize=False, links=page_links)
Ejemplo n.º 20
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        queryset = Snapshot.query.filter(Snapshot.project_id == project.id, )

        return self.paginate(queryset)
Ejemplo n.º 21
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        # restrict the join to the last 1000 jobs otherwise this can get
        # significantly expensive as we have to seek quite a ways
        job_sq = Job.query.filter(
            Job.status == Status.finished,
            Job.project_id == project_id,
        ).order_by(Job.date_created.desc()).limit(1000).subquery()

        recent_runs = list(TestCase.query.options(
            contains_eager('job', alias=job_sq),
            contains_eager('job.source'),
            joinedload('job', 'build'),
        ).join(
            job_sq, TestCase.job_id == job_sq.c.id,
        ).join(
            Source, job_sq.c.source_id == Source.id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Source.revision_sha != None,  # NOQA
            TestCase.name_sha == test.name_sha,
        ).order_by(job_sq.c.date_created.desc())[:25])

        first_build = Build.query.join(
            Job, Job.build_id == Build.id,
        ).join(
            TestCase, TestCase.job_id == Job.id,
        ).filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.asc()).limit(1).first()

        extended_serializers = {
            TestCase: TestCaseWithJobSerializer(),
            Job: JobWithBuildSerializer(),
        }

        context = self.serialize(test, {
            TestCase: GeneralizedTestCase(),
        })
        context.update({
            'results': self.serialize(recent_runs, extended_serializers),
            'firstBuild': first_build,
        })

        return self.respond(context, serialize=False)
Ejemplo n.º 22
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return error('project not found', http_code=404)

        args = self.get_parser.parse_args()

        # we want to only return commits in the repo that are within the
        # project's whitelist
        paths = None
        if not args.every_commit:
            paths = self.get_whitelisted_paths(project)

        repo = project.repository
        offset = (args.page - 1) * args.per_page
        limit = args.per_page + 1  # +1 to tell if there are more revs to get

        vcs = repo.get_vcs()
        if vcs:
            try:
                commits = self.get_commits_from_vcs(
                    repo, vcs, offset, limit, paths, args.parent, args.branch)
            except ValueError as err:
                return error(err.message)
        else:
            if args.parent or args.branch:
                param = 'Branches' if args.branch else 'Parents'
                return error(
                    '{0} not supported for projects with no repository.'.format(param),
                    http_code=422)
            # TODO: right now this fallback returns every commit for projects
            # with whitelisted paths.  At the very least, we need to tell the
            # frontend about this (perhaps using a response header)
            commits = self.get_commits_from_db(repo, offset, limit)

        page_links = self.make_links(
            current_page=args.page,
            has_next_page=len(commits) > args.per_page,
        )
        # we fetched one extra commit so that we'd know whether to create a
        # next link. Delete it
        commits = commits[:args.per_page]

        builds_map = {}
        if commits:
            builds_map = self.get_builds_for_commits(
                commits, project, args.all_builds)

        results = []
        for result in commits:
            if args.all_builds:
                result['builds'] = builds_map.get(result['id'], [])
            else:
                result['build'] = builds_map.get(result['id'])
            results.append(result)

        return self.respond(results, serialize=False, links=page_links)
Ejemplo n.º 23
0
    def get(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        plans = Plan.query.options(
            subqueryload_all(Plan.steps),
        ).filter(
            Plan.projects.contains(project),
        )

        last_build = Build.query.options(
            joinedload('author'),
            contains_eager('source')
        ).join(
            Source, Build.source_id == Source.id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project == project,
            Build.status == Status.finished,
        ).order_by(
            Build.date_created.desc(),
        ).first()
        if not last_build or last_build.result == Result.passed:
            last_passing_build = last_build
        else:
            last_passing_build = Build.query.options(
                joinedload('author'),
                contains_eager('source')
            ).join(
                Source, Build.source_id == Source.id,
            ).filter(
                Source.patch_id == None,  # NOQA
                Build.project == project,
                Build.result == Result.passed,
                Build.status == Status.finished,
            ).order_by(
                Build.date_created.desc(),
            ).first()

        options = dict(
            (o.name, o.value) for o in ProjectOption.query.filter(
                ProjectOption.project_id == project.id,
            )
        )
        for key, value in OPTION_DEFAULTS.iteritems():
            options.setdefault(key, value)

        data = self.serialize(project)
        data['lastBuild'] = last_build
        data['lastPassingBuild'] = last_passing_build
        data['repository'] = project.repository
        data['plans'] = list(plans)
        data['options'] = options
        data['stats'] = self._get_stats(project)

        return self.respond(data)
Ejemplo n.º 24
0
    def get(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        plans = Plan.query.options(
            subqueryload_all(Plan.steps),
        ).filter(
            Plan.projects.contains(project),
        )

        last_build = Build.query.options(
            joinedload('author'),
            contains_eager('source')
        ).join(
            Source, Build.source_id == Source.id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project == project,
            Build.status == Status.finished,
        ).order_by(
            Build.date_created.desc(),
        ).first()
        if not last_build or last_build.result == Result.passed:
            last_passing_build = last_build
        else:
            last_passing_build = Build.query.options(
                joinedload('author'),
                contains_eager('source')
            ).join(
                Source, Build.source_id == Source.id,
            ).filter(
                Source.patch_id == None,  # NOQA
                Build.project == project,
                Build.result == Result.passed,
                Build.status == Status.finished,
            ).order_by(
                Build.date_created.desc(),
            ).first()

        options = dict(
            (o.name, o.value) for o in ProjectOption.query.filter(
                ProjectOption.project_id == project.id,
            )
        )
        for key, value in OPTION_DEFAULTS.iteritems():
            options.setdefault(key, value)

        data = self.serialize(project)
        data['lastBuild'] = last_build
        data['lastPassingBuild'] = last_passing_build
        data['repository'] = project.repository
        data['plans'] = list(plans)
        data['options'] = options
        data['stats'] = self._get_stats(project)

        return self.respond(data)
Ejemplo n.º 25
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        queryset = Snapshot.query.filter(
            Snapshot.project_id == project.id,
        )

        return self.paginate(queryset)
Ejemplo n.º 26
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        args = self.get_parser.parse_args()

        num_results = args.per_page

        # restrict the join to the last N jobs otherwise this can get
        # significantly expensive as we have to seek quite a ways
        job_sq = Job.query.filter(
            Job.status == Status.finished,
            Job.project_id == project_id,
        ).order_by(Job.date_created.desc()).limit(num_results * 10).subquery()

        recent_runs = list(TestCase.query.options(
            contains_eager('job', alias=job_sq),
            contains_eager('job.source'),
            joinedload('job.build'),
            joinedload('job.build.author'),
            joinedload('job.build.source'),
            joinedload('job.build.source.revision'),
        ).join(
            job_sq, TestCase.job_id == job_sq.c.id,
        ).join(
            Source, job_sq.c.source_id == Source.id,
        ).filter(
            Source.repository_id == project.repository_id,
            Source.patch_id == None,  # NOQA
            Source.revision_sha != None,  # NOQA
            TestCase.name_sha == test.name_sha,
        ).order_by(job_sq.c.date_created.desc())[:num_results])

        jobs = set(r.job for r in recent_runs)
        builds = set(j.build for j in jobs)

        serialized_jobs = dict(zip(jobs, self.serialize(jobs)))
        serialized_builds = dict(zip(builds, self.serialize(builds)))

        results = []
        for recent_run, s_recent_run in zip(recent_runs, self.serialize(recent_runs)):
            s_recent_run['job'] = serialized_jobs[recent_run.job]
            s_recent_run['job']['build'] = serialized_builds[recent_run.job.build]
            results.append(s_recent_run)

        return self.respond(results, serialize=False)
Ejemplo n.º 27
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()

        latest_build = Build.query.join(
            Source, Source.id == Build.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project_id == project.id,
            Build.result == Result.passed,
            Build.status == Status.finished,
        ).order_by(
            Build.date_created.desc(),
        ).limit(1).first()

        if not latest_build:
            return self.respond([])

        job_list = db.session.query(Job.id).filter(
            Job.build_id == latest_build.id,
        )

        if not job_list:
            return self.respond([])

        # use the most recent test
        test_list = TestCase.query.filter(
            TestCase.project_id == project.id,
            TestCase.job_id.in_(job_list),
        )

        if args.min_duration:
            test_list = test_list.filter(
                TestCase.duration >= args.min_duration,
            )

        if args.query:
            test_list = test_list.filter(
                TestCase.name.contains(args.query),
            )

        if args.sort == 'duration':
            sort_by = TestCase.duration.desc()
        elif args.sort == 'name':
            sort_by = TestCase.name.asc()

        test_list = test_list.order_by(sort_by)

        return self.paginate(test_list, serializers={
            TestCase: GeneralizedTestCase(),
        })
Ejemplo n.º 28
0
def project(repository, **kwargs):
    if 'name' not in kwargs:
        kwargs['name'] = PROJECT_NAMES.next()

    project = Project.query.filter(Project.name == kwargs['name'], ).first()
    if project:
        return project

    result = Project(repository=repository, **kwargs)
    db.session.add(result)
    return result
Ejemplo n.º 29
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        queryset = Snapshot.query.options(
            joinedload('source').joinedload('revision'), ).filter(
                Snapshot.project_id == project.id, ).order_by(
                    Snapshot.date_created.desc(), )

        return self.paginate(queryset)
Ejemplo n.º 30
0
    def post(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        args = self.post_parser.parse_args()

        plan = Plan(label=args.name, project_id=project.id,)
        db.session.add(plan)

        return self.respond(plan)
Ejemplo n.º 31
0
    def create_project(self, **kwargs):
        if not kwargs.get('repository'):
            kwargs['repository'] = self.create_repo()
        kwargs['repository_id'] = kwargs['repository'].id
        kwargs.setdefault('name', uuid4().hex)
        kwargs.setdefault('slug', kwargs['name'])

        project = Project(**kwargs)
        db.session.add(project)
        db.session.commit()

        return project
Ejemplo n.º 32
0
def test_simple():
    project = Project(
        id=UUID(hex='33846695b2774b29a71795a009e8168a'),
        slug='hello-world',
        name='Hello world',
        date_created=datetime(2013, 9, 19, 22, 15, 22),
    )
    result = serialize(project)
    assert result['name'] == 'Hello world'
    assert result['id'] == '33846695b2774b29a71795a009e8168a'
    assert result['slug'] == 'hello-world'
    assert result['dateCreated'] == '2013-09-19T22:15:22'
Ejemplo n.º 33
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()

        latest_build = Build.query.join(
            Source, Source.id == Build.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project_id == project.id,
            Build.result == Result.passed,
            Build.status == Status.finished,
        ).order_by(
            Build.date_created.desc(),
        ).limit(1).first()

        if not latest_build:
            return self.respond([])

        job_list = db.session.query(Job.id).filter(
            Job.build_id == latest_build.id,
        )

        # use the most recent test
        test_list = TestCase.query.filter(
            TestCase.project_id == project.id,
            TestCase.job_id.in_(job_list),
        )

        if args.min_duration:
            test_list = test_list.filter(
                TestCase.duration >= args.min_duration,
            )

        if args.query:
            test_list = test_list.filter(
                TestCase.name.contains(args.query),
            )

        if args.sort == 'duration':
            sort_by = TestCase.duration.desc()
        elif args.sort == 'name':
            sort_by = TestCase.name.asc()

        test_list = test_list.order_by(sort_by)

        return self.paginate(test_list, serializers={
            TestCase: GeneralizedTestCase(),
        })
Ejemplo n.º 34
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        queryset = Plan.query.options(
            subqueryload_all(Plan.steps),
        ).filter(
            Plan.projects.contains(project),
        ).order_by(
            Plan.label.asc(),
        )

        return self.paginate(queryset)
Ejemplo n.º 35
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        queryset = Snapshot.query.options(
            joinedload('source').joinedload('revision'),
        ).filter(
            Snapshot.project_id == project.id,
        ).order_by(
            Snapshot.date_created.desc(),
        )

        return self.paginate(queryset)
Ejemplo n.º 36
0
def test_simple():
    change = Change(
        id=UUID(hex='33846695b2774b29a71795a009e8168a'),
        label='Hello world',
        project=Project(slug='test', name='test'),
        date_created=datetime(2013, 9, 19, 22, 15, 22),
        date_modified=datetime(2013, 9, 19, 22, 15, 23),
    )
    result = serialize(change)
    assert result['name'] == 'Hello world'
    assert result[
        'link'] == 'http://example.com/changes/33846695b2774b29a71795a009e8168a/'
    assert result['id'] == '33846695b2774b29a71795a009e8168a'
    assert result['dateCreated'] == '2013-09-19T22:15:22'
    assert result['dateModified'] == '2013-09-19T22:15:23'
Ejemplo n.º 37
0
    def post(self, project_id):
        """Initiates a new snapshot for this project."""
        project = Project.get(project_id)
        if not project:
            return '', 404

        # TODO(adegtiar): initialize a snapshot build.
        snapshot = Snapshot(project_id=project.id, )

        db.session.add(snapshot)
        db.session.commit()

        # TODO(adegtiar): execute the build.

        return self.respond(snapshot)
Ejemplo n.º 38
0
    def post(self, project_id):
        """Initiates a new snapshot for this project."""
        project = Project.get(project_id)
        if not project:
            return '', 404

        # TODO(adegtiar): initialize a snapshot build.
        snapshot = Snapshot(
            project_id=project.id,
        )

        db.session.add(snapshot)
        db.session.commit()

        # TODO(adegtiar): execute the build.

        return self.respond(snapshot)
Ejemplo n.º 39
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        latest_job = Job.query.options(
            subqueryload(Job.project),
        ).join(
            Source, Source.id == Job.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Job.project == project,
            Job.result == Result.passed,
            Job.status == Status.finished,
        ).order_by(
            Job.date_created.desc(),
        ).limit(1).first()

        if latest_job:
            test_list = db.session.query(AggregateTestGroup, TestGroup).options(
                subqueryload(AggregateTestGroup.first_job),
                subqueryload(AggregateTestGroup.parent),
                subqueryload(TestGroup.parent),
            ).join(
                TestGroup, and_(
                    TestGroup.job_id == latest_job.id,
                    TestGroup.name_sha == AggregateTestGroup.name_sha,
                )
            ).filter(
                AggregateTestGroup.parent_id == None,  # NOQA: we have to use == here
                AggregateTestGroup.project_id == project.id,
            ).order_by(TestGroup.duration.desc())

            results = []
            for agg, group in test_list:
                agg.last_testgroup = group
                results.append(agg)
        else:
            results = []

        context = {
            'tests': results,
        }

        return self.respond(context)
Ejemplo n.º 40
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()

        latest_build = Build.query.join(
            Source, Source.id == Build.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project_id == project.id,
            Build.result == Result.passed,
            Build.status == Status.finished,
        ).order_by(
            Build.date_created.desc(),
        ).limit(1).first()

        if not latest_build:
            return self.respond([])

        # use the most recent coverage
        cover_list = FileCoverage.query.filter(
            FileCoverage.job_id.in_(
                db.session.query(Job.id).filter(Job.build_id == latest_build.id)
            )
        )

        if args.query:
            cover_list = cover_list.filter(
                FileCoverage.filename.startswith(args.query),
            )

        if args.sort == 'lines_covered':
            sort_by = FileCoverage.lines_covered.desc()
        elif args.sort == 'lines_covered':
            sort_by = FileCoverage.lines_uncovered.desc()
        elif args.sort == 'name':
            sort_by = FileCoverage.filename.asc()

        cover_list = cover_list.order_by(sort_by)

        return self.paginate(cover_list, serializers={
            FileCoverage: GeneralizedFileCoverage(),
        })
Ejemplo n.º 41
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.get_parser.parse_args()

        filters = []

        if args.authors:
            filters.append(Build.author_id.in_([a.id for a in args.authors]))
        elif args.authors is not None:
            return []

        if args.source:
            filters.append(Build.target.startswith(args.source))

        if args.query:
            filters.append(or_(
                Build.label.contains(args.query),
                Build.target.startswith(args.query),
            ))

        if args.result:
            filters.append(Build.result == Result[args.result])

        if args.patches_only:
            filters.append(Source.patch_id != None)  # NOQA
        elif not args.include_patches:
            filters.append(Source.patch_id == None)  # NOQA

        queryset = Build.query.options(
            joinedload('project', innerjoin=True),
            joinedload('author'),
            contains_eager('source').joinedload('revision'),
        ).join(
            Source, Source.id == Build.source_id,
        ).filter(
            Build.project_id == project.id,
            *filters
        ).order_by(Build.date_created.desc())

        return self.paginate(queryset)
Ejemplo n.º 42
0
    def get(self, project_id, source_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        source = Source.query.filter(
            Source.id == source_id,
            Source.repository_id == repo.id,
        ).first()
        if source is None:
            return '', 404

        build_query = Build.query.options(joinedload('author'), ).filter(
            Build.project_id == project.id,
            Build.source_id == source.id,
        ).order_by(Build.date_created.desc())

        return self.paginate(build_query)
Ejemplo n.º 43
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()

        latest_build = Build.query.join(
            Source,
            Source.id == Build.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Build.project_id == project.id,
            Build.result == Result.passed,
            Build.status == Status.finished,
        ).order_by(Build.date_created.desc(), ).limit(1).first()

        if not latest_build:
            return self.respond([])

        # use the most recent coverage
        cover_list = FileCoverage.query.filter(
            FileCoverage.job_id.in_(
                db.session.query(
                    Job.id).filter(Job.build_id == latest_build.id)))

        if args.query:
            cover_list = cover_list.filter(
                FileCoverage.filename.startswith(args.query), )

        if args.sort == 'lines_covered':
            sort_by = FileCoverage.lines_covered.desc()
        elif args.sort == 'lines_covered':
            sort_by = FileCoverage.lines_uncovered.desc()
        elif args.sort == 'name':
            sort_by = FileCoverage.filename.asc()

        cover_list = cover_list.order_by(sort_by)

        return self.paginate(cover_list,
                             serializers={
                                 FileCoverage: GeneralizedFileCoverage(),
                             })
Ejemplo n.º 44
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        args = self.get_parser.parse_args()

        return self.paginate(
            HistorySliceable(project_id, args.branch, test, project.repository_id, self.serialize),
            serialize=False
        )
Ejemplo n.º 45
0
    def get(self, project_id, test_hash):
        project = Project.get(project_id)
        if not project:
            return '', 404

        # use the most recent test run to find basic details
        test = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.name_sha == test_hash,
        ).order_by(TestCase.date_created.desc()).limit(1).first()
        if not test:
            return '', 404

        args = self.get_parser.parse_args()

        return self.paginate(HistorySliceable(project_id, args.branch, test,
                                              project.repository_id,
                                              self.serialize),
                             serialize=False)
Ejemplo n.º 46
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()

        latest_job = Job.query.join(
            Source, Source.id == Job.source_id,
        ).filter(
            Source.patch_id == None,  # NOQA
            Job.project_id == project.id,
            Job.result == Result.passed,
            Job.status == Status.finished,
        ).order_by(
            Job.date_created.desc(),
        ).limit(1).first()

        if not latest_job:
            return self.respond([])

        # use the most recent test
        test_list = TestCase.query.filter(
            TestCase.project_id == project_id,
            TestCase.job_id == latest_job.id,
        )

        if args.query:
            test_list = test_list.filter(
                TestCase.name.startswith(args.query),
            )

        if args.sort == 'duration':
            sort_by = TestCase.duration.desc()
        elif args.sort == 'name':
            sort_by = TestCase.name.asc()

        test_list = test_list.order_by(sort_by)

        return self.paginate(test_list, serializers={
            TestCase: GeneralizedTestCase(),
        })
Ejemplo n.º 47
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).join(Revision.author).first()
        if not revision:
            return '', 404

        context = self.serialize(revision)

        context.update({
            'repository': repo,
        })

        return self.respond(context)
Ejemplo n.º 48
0
    def get(self, project_id, source_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        source = Source.query.filter(
            Source.id == source_id,
            Source.repository_id == repo.id,
        ).first()
        if source is None:
            return '', 404

        build_list = list(Build.query.options(
            joinedload('author'),
        ).filter(
            Build.source_id == source.id,
        ).order_by(Build.date_created.desc()))[:100]

        return self.respond(build_list)
Ejemplo n.º 49
0
def test_simple():
    patch = Patch(
        id=UUID(hex='33846695b2774b29a71795a009e8168a'),
        label='Hello world',
        message='Foo bar',
        diff=SAMPLE_DIFF,
        project=Project(slug='test', name='test'),
        parent_revision_sha='1e7958a368f44b0eb5a57372a9910d50',
        date_created=datetime(2013, 9, 19, 22, 15, 22),
    )
    result = serialize(patch)
    assert result['name'] == 'Hello world'
    assert result['link'] == 'http://example.com/patches/33846695b2774b29a71795a009e8168a/'
    assert result['id'] == '33846695b2774b29a71795a009e8168a'
    assert result['parentRevision'] == {
        'sha': '1e7958a368f44b0eb5a57372a9910d50',
    }
    assert result['message'] == 'Foo bar'
    assert result['dateCreated'] == '2013-09-19T22:15:22'
    assert result['diff'] == SAMPLE_DIFF
Ejemplo n.º 50
0
    def get(self, project_id, commit_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        revision = Revision.query.options(joinedload('author'), ).filter(
            Revision.repository_id == repo.id,
            Revision.sha == commit_id,
        ).first()
        if not revision:
            return '', 404

        context = self.serialize(revision)

        context.update({
            'repository': repo,
        })

        return self.respond(context)
Ejemplo n.º 51
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        include_patches = request.args.get('include_patches') or '1'

        queryset = Build.query.options(
            joinedload('project'),
            joinedload('author'),
            joinedload('source').joinedload('revision'),
        ).filter(Build.project_id == project.id, ).order_by(
            Build.date_created.desc())

        if include_patches == '0':
            queryset = queryset.filter(
                Build.patch == None,  # NOQA
            )

        return self.paginate(queryset)
Ejemplo n.º 52
0
    def get(self, project_id, source_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        repo = project.repository
        source = Source.query.filter(
            Source.id == source_id,
            Source.repository_id == repo.id,
        ).first()
        if source is None:
            return '', 404

        context = self.serialize(source)

        diff = source.generate_diff()

        if diff:
            files = self._get_files_from_raw_diff(diff)

            coverage = {
                c.filename: c.data
                for c in get_coverage_by_source_id(source_id)
                if c.filename in files
            }

            coverage_for_added_lines = self._filter_coverage_for_added_lines(
                diff, coverage)

            tails_info = dict(source.data)
        else:
            coverage = None
            coverage_for_added_lines = None
            tails_info = None

        context['diff'] = diff
        context['coverage'] = coverage
        context['coverageForAddedLines'] = coverage_for_added_lines
        context['tailsInfo'] = tails_info

        return self.respond(context)
Ejemplo n.º 53
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        include_patches = request.args.get('include_patches') or '1'

        queryset = Build.query.options(
            joinedload('project'),
            joinedload('author'),
            joinedload('source').joinedload('revision'),
        ).filter(
            Build.project_id == project.id,
        ).order_by(Build.date_created.desc())

        if include_patches == '0':
            queryset = queryset.filter(
                Build.patch == None,  # NOQA
            )

        return self.paginate(queryset)
Ejemplo n.º 54
0
    def get(self, project_id):
        project = Project.get(project_id)
        if not project:
            return '', 404

        args = self.parser.parse_args()
        if args.date:
            try:
                query_date = datetime.strptime(args.date, '%Y-%m-%d').date()
            except:
                return 'Can\'t parse date "%s"' % (args.date), 500
        else:
            query_date = date.today() - timedelta(days=1)

        data = {
            'date': str(query_date),
            'chartData': self.get_chart_data(project_id, query_date),
            'flakyTests': self.get_flaky_tests(project_id, query_date)
        }

        return self.respond(data, serialize=False)
Ejemplo n.º 55
0
    def post(self, project_id):
        project = Project.get(project_id)
        if project is None:
            return '', 404

        args = self.post_parser.parse_args()

        if args.name:
            project.name = args.name

        if args.slug:
            match = Project.query.filter(
                Project.slug == args.slug,
                Project.id != project.id,
            ).first()
            if match:
                return '{"error": "Project with slug %r already exists"}' % (
                    args.slug, ), 400

            project.slug = args.slug

        if args.repository:
            repository = Repository.get(args.repository)
            if repository is None:
                return '{"error": "Repository with url %r does not exist"}' % (
                    args.repository, ), 400
            project.repository = repository

        if args.status == 'inactive':
            project.status = ProjectStatus.inactive
        elif args.status == 'active':
            project.status = ProjectStatus.active

        db.session.add(project)

        data = self.serialize(project)
        data['repository'] = self.serialize(project.repository)

        return self.respond(data, serialize=False)
Ejemplo n.º 56
0
def test_simple():
    job = Job(
        id=UUID(hex='33846695b2774b29a71795a009e8168a'),
        label='Hello world',
        project=Project(slug='test', name='test'),
        date_created=datetime(2013, 9, 19, 22, 15, 22),
        date_started=datetime(2013, 9, 19, 22, 15, 23),
        date_finished=datetime(2013, 9, 19, 22, 15, 33),
        build=Build(id=UUID('1e7958a368f44b0eb5a57372a9910d50'), ),
        build_id=UUID('1e7958a368f44b0eb5a57372a9910d50'),
        change=Change(
            id=UUID(hex='2e18a7cbc0c24316b2ef9d41fea191d6'),
            label='Hello world',
        ),
    )
    result = serialize(job)
    assert result['name'] == 'Hello world'
    assert result['id'] == '33846695b2774b29a71795a009e8168a'
    assert result['dateCreated'] == '2013-09-19T22:15:22'
    assert result['dateStarted'] == '2013-09-19T22:15:23'
    assert result['dateFinished'] == '2013-09-19T22:15:33'
    assert result['duration'] == 10000