Beispiel #1
0
    def put(self, job: Job):
        """
        Update a job.
        """
        result = self.schema_from_request(job_schema, partial=True)
        if result.errors:
            return self.respond(result.errors, 403)

        was_unfinished = job.status != Status.finished

        for key, value in result.data.items():
            if getattr(job, key) != value:
                setattr(job, key, value)

        if db.session.is_modified(job):
            db.session.add(job)
            if job.status == Status.finished and was_unfinished and not job.date_finished:
                job.date_finished = timezone.now()
            if job.status == Status.finished and has_unprocessed_artifacts(job.id):
                job.status = Status.collecting_results
            db.session.commit()

        aggregate_build_stats_for_job.delay(job_id=job.id)

        return self.respond_with_schema(job_schema, job)
def record_failure_reasons(job: Job):
    has_failures = db.session.query(
        TestCase.query.filter(
            TestCase.job_id == job.id,
            TestCase.result == Result.failed).exists()).scalar()
    any_failures = False

    if has_failures:
        any_failures = True
        try:
            with db.session.begin_nested():
                db.session.add(
                    FailureReason(
                        job_id=job.id,
                        repository_id=job.repository_id,
                        reason=FailureReason.Reason.failing_tests,
                    ))
        except IntegrityError:
            pass

    if any_failures and job.result == Result.passed:
        job.result = Result.failed
        db.session.add(job)

    db.session.flush()
Beispiel #3
0
def test_result_generation(sample_gotest):
    job = Job()

    fp = BytesIO(sample_gotest.encode("utf8"))

    handler = GoTestHandler(job)
    results = handler.get_tests(fp)

    assert len(results) == 3

    r1 = results[0]
    assert type(r1) == ZeusTestResult
    assert r1.job == job
    assert r1.name == "golang.org/x/sync/syncmap/TestMapMatchesRWMutex"
    assert r1.duration == 10.0
    assert r1.result == Result.passed
    assert r1.message is None
    r2 = results[1]
    assert type(r2) == ZeusTestResult
    assert r2.job == job
    assert r2.name == "golang.org/x/sync/syncmap/TestMapMatchesDeepCopy"
    assert r2.duration == 10.0
    assert r2.result == Result.passed
    assert r2.message is None
    r3 = results[2]
    assert type(r3) == ZeusTestResult
    assert r3.job == job
    assert r3.name == "golang.org/x/sync/syncmap/TestConcurrentRange"
    assert r3.duration == 0.0
    assert r3.result == Result.failed
    assert (
        r3.message ==
        "\tmap_test.go:169: Range visited 1024 elements of 1024-element Map\n")
Beispiel #4
0
def test_result_generation(sample_xunit):
    job = Job()

    fp = BytesIO(sample_xunit.encode("utf8"))

    handler = XunitHandler(job)
    results = handler.get_tests(fp)

    assert len(results) == 2

    r1 = results[0]
    assert type(r1) == ZeusTestResult
    assert r1.job == job
    assert r1.name == "tests.test_report"
    assert r1.duration == 0.0
    assert r1.result == Result.failed
    assert (r1.message == """tests/test_report.py:1: in <module>
>   import mock
E   ImportError: No module named mock""")
    r2 = results[1]
    assert type(r2) == ZeusTestResult
    assert r2.job == job
    assert r2.name == "tests.test_report.ParseTestResultsTest.test_simple"
    assert r2.duration == 1.65796279907
    assert r2.result == Result.passed
    assert r2.message == ""
Beispiel #5
0
    def post(self, build: Build):
        """
        Create a new job.
        """
        result = self.schema_from_request(job_schema, partial=True)
        if result.errors:
            return self.respond(result.errors, 403)
        data = result.data
        job = Job(build=build, repository_id=build.repository_id, **data)
        if not job.date_started:
            job.date_started = timezone.now()
        db.session.add(job)
        db.session.commit()

        aggregate_build_stats_for_job.delay(job_id=job.id)

        return self.respond_with_schema(job_schema, job)
Beispiel #6
0
    def post(self, build: Build):
        """
        Create a new job.
        """
        data = self.schema_from_request(job_schema, partial=True)
        job = Job(build=build, repository_id=build.repository_id, **data)
        if job.status != Status.queued and not job.date_started:
            job.date_started = timezone.now()

        db.session.add(job)

        try:
            db.session.commit()
        except IntegrityError:
            db.session.rollback()
            return self.respond(status=422)

        aggregate_build_stats_for_job.delay(job_id=job.id)

        return self.respond_with_schema(job_schema, job)
Beispiel #7
0
    def put(self, job: Job):
        """
        Update a job.
        """
        result = self.schema_from_request(job_schema, partial=True)
        if result.errors:
            return self.respond(result.errors, 403)

        prev_status = job.status

        for key, value in result.data.items():
            if getattr(job, key) != value:
                setattr(job, key, value)

        if db.session.is_modified(job):
            if job.status == Status.queued:
                job.date_started = None
                job.result = Result.unknown
            elif job.status == Status.in_progress and prev_status != Status.in_progress:
                # TODO(dcramer): this is effectively 'restart' on a job, and we need to
                # decide how Zeus should deal with it. We either could orphan/hide/remove the
                # current job, or alternatively we would want to truncate all of its children
                # which is fairly complex.
                if not result.data.get("date_started"):
                    job.date_started = timezone.now()
                if "result" not in result.data:
                    job.result = Result.unknown
            if (
                job.status == Status.finished
                and prev_status != job.status
                and not result.data.get("date_finished")
            ):
                job.date_finished = timezone.now()
                if not job.date_started:
                    job.date_started = job.date_created
            elif job.status != Status.finished:
                job.date_finished = None
            if job.status == Status.finished and has_unprocessed_artifacts(job.id):
                job.status = Status.collecting_results
            db.session.add(job)
            db.session.commit()

        aggregate_build_stats_for_job.delay(job_id=job.id)

        return self.respond_with_schema(job_schema, job)
Beispiel #8
0
    def post(self, build: Build):
        """
        Create a new job.
        """
        result = self.schema_from_request(job_schema, partial=True)
        if result.errors:
            return self.respond(result.errors, 403)
        data = result.data
        job = Job(build=build,
                  project_id=build.project_id,
                  organization_id=build.organization_id,
                  **data)
        db.session.add(job)
        db.session.commit()

        aggregate_build_stats_for_job.delay(job_id=job.id)

        return self.respond_with_schema(job_schema, job)
Beispiel #9
0
def record_failure_reasons(job: Job):
    has_failures = db.session.query(
        TestCase.query.filter(
            TestCase.job_id == job.id,
            TestCase.result == Result.failed,
        ).exists()).scalar()
    any_failures = False

    if has_failures:
        any_failures = True
        db.session.add(
            FailureReason(
                job_id=job.id,
                repository_id=job.repository_id,
                reason=FailureReason.Code.failing_tests,
            ))

    if any_failures and job.result == Result.passed:
        job.result = Result.failed
        db.session.add(job)

    db.session.flush()