<commit_before>from flask import current_app, request
from marshmallow import Schema, fields, pre_dump

from zeus.config import db
from zeus.constants import Result, Status
from zeus.models import Build, Repository, TestCase, Job, Source

from .base_repository import BaseRepositoryResource
from ..schemas import ResultField, BuildSchema


class TestCaseHistorySchema(Schema):
    results = fields.Dict(keys=fields.Str(), values=fields.List(ResultField))
    builds = fields.List(
        fields.Nested(BuildSchema(exclude=["stats", "source", "repository"]))
    )

    @pre_dump(pass_many=False)
    def process_results(self, data, **kwargs):
        results_by_test = {}
        for (name, result, build_id) in data:
            test_name = results_by_test.get(name, {})
            test_name[str(build_id)] = result
            results_by_test[name] = test_name

        results = {}
        for test_name, result_by_test in results_by_test.items():
            results[test_name] = []
            for build in self.context["builds"]:
                # XXX(dcramer): insert is not optimal
                results[test_name].insert(0, result_by_test.get(str(build.id), None))

        output = {"results": results, "builds": self.context["builds"]}
        return output


class RepositoryTestsHistoryByBuildResource(BaseRepositoryResource):
    def get(self, repo: Repository):
        """
        Return a list of testcases for the given repository.
        """
        results = min(int(request.args.get("results", 20)), 100)
        query = request.args.get("query")

        # use the most recent successful build to fetch test results
        builds = (
            Build.query.join(Source, Source.id == Build.source_id)
            .filter(
                Source.patch_id == None,  # NOQA
                Build.repository_id == repo.id,
                Build.result == Result.passed,
                Build.status == Status.finished,
            )
            .order_by(Build.number.desc())
            .limit(results)
        )

        if not builds:
            current_app.logger.info("no successful builds found for repository")
            return self.respond([])

        # TODO(dcramer): this will likely need paginated as tests can be in the thousands
        testcase_query = (
            db.session.query(TestCase.name, TestCase.result, Job.build_id)
            .join(Job, TestCase.job_id == Job.id)
            .filter(Job.build_id.in_(b.id for b in builds))
        )
        if query:
            testcase_query = testcase_query.filter(TestCase.name.contains(query))

        schema = TestCaseHistorySchema(context={"builds": builds})

        return self.paginate_with_schema(schema, testcase_query)<commit_msg>fix: use all builds for test history<commit_after>from flask import current_app, request
from marshmallow import Schema, fields, pre_dump

from zeus.config import db
from zeus.constants import Status
from zeus.models import Build, Repository, TestCase, Job, Source

from .base_repository import BaseRepositoryResource
from ..schemas import ResultField, BuildSchema


class TestCaseHistorySchema(Schema):
    results = fields.Dict(keys=fields.Str(), values=fields.List(ResultField))
    builds = fields.List(
        fields.Nested(BuildSchema(exclude=["stats", "source", "repository"]))
    )

    @pre_dump(pass_many=False)
    def process_results(self, data, **kwargs):
        results_by_test = {}
        for (name, result, build_id) in data:
            test_name = results_by_test.get(name, {})
            test_name[str(build_id)] = result
            results_by_test[name] = test_name

        results = {}
        for test_name, result_by_test in results_by_test.items():
            results[test_name] = []
            for build in self.context["builds"]:
                # XXX(dcramer): insert is not optimal
                results[test_name].insert(0, result_by_test.get(str(build.id), None))

        output = {"results": results, "builds": self.context["builds"]}
        return output


class RepositoryTestsHistoryByBuildResource(BaseRepositoryResource):
    def get(self, repo: Repository):
        """
        Return a list of testcases for the given repository.
        """
        results = min(int(request.args.get("results", 20)), 100)
        query = request.args.get("query")

        builds = (
            Build.query.join(Source, Source.id == Build.source_id)
            .filter(
                Source.patch_id == None,  # NOQA
                Build.repository_id == repo.id,
                Build.status == Status.finished,
            )
            .order_by(Build.number.desc())
            .limit(results)
        )

        if not builds:
            current_app.logger.info("no successful builds found for repository")
            return self.respond([])

        testcase_query = (
            db.session.query(TestCase.name, TestCase.result, Job.build_id)
            .join(Job, TestCase.job_id == Job.id)
            .filter(Job.build_id.in_(b.id for b in builds))
        )
        if query:
            testcase_query = testcase_query.filter(TestCase.name.contains(query))

        schema = TestCaseHistorySchema(context={"builds": builds})

        return self.paginate_with_schema(schema, testcase_query)
{'fraction_non_alphanumeric': 0.10637895135339769, 'fraction_numerical': 0.002271436683702442, 'mean_word_length': 2.50863213811421, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6076530', 'n_tokens_mistral': 1505, 'n_tokens_neox': 1456, 'n_words': 347}