def test_build_tests_list( client, db_session, default_login, default_repo, default_revision, default_build, default_repo_access, ): job1 = factories.JobFactory(build=default_build) job2 = factories.JobFactory(build=default_build) db_session.add(job1) db_session.add(job2) testcase1 = factories.TestCaseFactory(job=job1, name="bar", passed=True) testcase2 = factories.TestCaseFactory(job=job2, name="foo", passed=True) testcase3 = factories.TestCaseFactory(job=job2, name="bar", failed=True) db_session.add(testcase1) db_session.add(testcase2) db_session.add(testcase3) resp = client.get("/api/repos/{}/revisions/{}/tests".format( default_repo.get_full_name(), default_revision.sha)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2
def test_build_tests_list(client, db_session, default_login, default_repo, default_build, default_repo_access): job1 = factories.JobFactory(build=default_build, ) job2 = factories.JobFactory(build=default_build, ) db_session.add(job1) db_session.add(job2) testcase1 = factories.TestCaseFactory( job=job1, name='bar', ) testcase2 = factories.TestCaseFactory( job=job2, name='foo', ) db_session.add(testcase1) db_session.add(testcase2) resp = client.get('/api/repos/{}/builds/{}/tests'.format( default_repo.get_full_name(), default_build.number)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]['id'] == str(testcase1.id) assert data[1]['id'] == str(testcase2.id)
def test_build_styleviolations_list(client, db_session, default_login, default_repo, default_build, default_repo_access): job1 = factories.JobFactory(build=default_build, ) job2 = factories.JobFactory(build=default_build, ) db_session.add(job1) db_session.add(job2) violation1 = factories.StyleViolationFactory( job=job1, filename='bar', ) violation2 = factories.StyleViolationFactory( job=job2, filename='foo', ) db_session.add(violation1) db_session.add(violation2) resp = client.get('/api/repos/{}/builds/{}/style-violations'.format( default_repo.get_full_name(), default_build.number)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]['id'] == str(violation1.id) assert data[1]['id'] == str(violation2.id)
def test_test_stats(mocker, db_session, default_source): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) job2 = factories.JobFactory(build=build, passed=True) db_session.add(job2) db_session.add( factories.TestCaseFactory( job=job, name='foo', failed=True, duration=8, )) db_session.add( factories.TestCaseFactory( job=job, name='bar', passed=True, duration=2, )) db_session.add( factories.TestCaseFactory( job=job2, name='bar', failed=True, duration=2, )) aggregate_build_stats_for_job(job.id) aggregate_build_stats_for_job(job2.id) aggregate_build_stats(build.id) build_stats = { i.name: i.value for i in ItemStat.query.filter(ItemStat.item_id == build.id, ) } assert build_stats['tests.count'] == 3 assert build_stats['tests.count_unique'] == 2 assert build_stats['tests.failures'] == 2 assert build_stats['tests.failures_unique'] == 2 assert build_stats['tests.duration'] == 12 job_stats = { i.name: i.value for i in ItemStat.query.filter(ItemStat.item_id == job.id, ) } assert job_stats['tests.count'] == 2 assert job_stats['tests.failures'] == 1 assert job_stats['tests.duration'] == 10
def test_build_tests_list(client, db_session, default_login, default_repo, default_build, default_repo_access): job1 = factories.JobFactory(build=default_build, ) job2 = factories.JobFactory(build=default_build, ) db_session.add(job1) db_session.add(job2) testcase1 = factories.TestCaseFactory( job=job1, name='bar', passed=True, ) testcase2 = factories.TestCaseFactory( job=job2, name='foo', passed=True, ) testcase3 = factories.TestCaseFactory( job=job2, name='bar', failed=True, ) db_session.add(testcase1) db_session.add(testcase2) db_session.add(testcase3) resp = client.get('/api/repos/{}/builds/{}/tests'.format( default_repo.get_full_name(), default_build.number)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]['name'] == 'bar' assert data[0]['result'] == 'failed' assert data[0]['runs'] == [{ 'id': str(testcase3.id), 'job_id': str(job2.id), 'result': 'failed', 'duration': testcase3.duration, }, { 'id': str(testcase1.id), 'job_id': str(job1.id), 'result': 'passed', 'duration': testcase1.duration, }] assert data[1]['name'] == 'foo' assert data[1]['result'] == 'passed' assert data[1]['runs'] == [{ 'id': str(testcase2.id), 'job_id': str(job2.id), 'result': 'passed', 'duration': testcase2.duration, }]
def test_build_tests_list( client, db_session, default_login, default_repo, default_build, default_repo_access, mock_vcs_server, ): job1 = factories.JobFactory(build=default_build) job2 = factories.JobFactory(build=default_build) db_session.add(job1) db_session.add(job2) testcase1 = factories.TestCaseFactory(job=job1, name="bar", passed=True) testcase2 = factories.TestCaseFactory(job=job2, name="foo", passed=True) testcase3 = factories.TestCaseFactory(job=job2, name="bar", failed=True) db_session.add(testcase1) db_session.add(testcase2) db_session.add(testcase3) resp = client.get("/api/repos/{}/builds/{}/tests".format( default_repo.get_full_name(), default_build.number)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]["name"] == "bar" assert data[0]["result"] == "failed" assert data[0]["runs"] == [ { "id": str(testcase3.id), "job_id": str(job2.id), "result": "failed", "duration": testcase3.duration, }, { "id": str(testcase1.id), "job_id": str(job1.id), "result": "passed", "duration": testcase1.duration, }, ] assert data[1]["name"] == "foo" assert data[1]["result"] == "passed" assert data[1]["runs"] == [{ "id": str(testcase2.id), "job_id": str(job2.id), "result": "passed", "duration": testcase2.duration, }]
def test_build_failures_list( client, sqla_assertions, db_session, default_login, default_repo, default_build, default_repo_access, ): job1 = factories.JobFactory(build=default_build) job2 = factories.JobFactory(build=default_build) db_session.add(job1) db_session.add(job2) failure1 = factories.FailureReasonFactory(job=job1, failing_tests=True) failure2 = factories.FailureReasonFactory(job=job2, missing_tests=True) failure3 = factories.FailureReasonFactory(job=job2, failing_tests=True) db_session.add(failure1) db_session.add(failure2) db_session.add(failure3) # Queries: # - Tenant # - Build # - Failures # - Failure Count (paginator) with sqla_assertions.assert_statement_count(5): resp = client.get("/api/repos/{}/builds/{}/failures".format( default_repo.get_full_name(), default_build.number)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]["reason"] == "failing_tests" assert data[0]["runs"] == [ { "id": str(failure3.id), "job_id": str(job2.id) }, { "id": str(failure1.id), "job_id": str(job1.id) }, ] assert data[1]["reason"] == "missing_tests" assert data[1]["runs"] == [{ "id": str(failure2.id), "job_id": str(job2.id) }]
def test_new_artifact(client, default_source, default_repo, default_hook, sample_xunit): build = factories.BuildFactory(source=default_source, provider=default_hook.provider, external_id="3") job = factories.JobFactory(build=build, provider=default_hook.provider, external_id="2", in_progress=True) path = "/hooks/{}/{}/builds/{}/jobs/{}/artifacts".format( default_hook.id, default_hook.get_signature(), build.external_id, job.external_id, ) resp = client.post( path, data={ "name": "junit.xml", "file": (BytesIO(sample_xunit.encode("utf-8")), "junit.xml"), "type": "xunit", }, ) assert resp.status_code == 201, repr(resp.data) data = resp.json() artifact = Artifact.query.get(data["id"]) assert artifact.file.filename.endswith("junit.xml") assert artifact.type == "xunit"
def test_failing_tests_duplicate_reason(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) factories.TestCaseFactory(job=job, failed=True) db_session.add( FailureReason( build_id=build.id, reason=FailureReason.Reason.failing_tests, job_id=job.id, repository_id=job.repository_id, )) aggregate_build_stats_for_job(job.id) assert job.result == Result.failed reasons = list(FailureReason.query.filter(FailureReason.job_id == job.id)) assert len(reasons) == 1 assert reasons[0].reason == FailureReason.Reason.failing_tests
def test_existing_job(client, default_revision, default_repo, default_hook): build = factories.BuildFactory( revision=default_revision, provider=default_hook.get_provider().get_name(default_hook.config), external_id="3", ) job = factories.JobFactory( build=build, provider=default_hook.get_provider().get_name(default_hook.config), external_id="2", in_progress=True, ) path = "/hooks/{}/{}/builds/{}/jobs/{}".format( default_hook.id, default_hook.get_signature(), build.external_id, job.external_id, ) payload = {"result": "passed", "status": "finished"} resp = client.post(path, json=payload) assert resp.status_code == 200, repr(resp.data) data = resp.json() assert data["result"] == "passed" assert data["status"] == "finished" job = Job.query.unrestricted_unsafe().get(job.id) assert job.result == Result.passed assert job.status == Status.finished
def default_job(default_build): return factories.JobFactory( build=default_build, date_started=datetime.now(timezone.utc) - timedelta(minutes=6), date_finished=datetime.now(timezone.utc), passed=True, )
def test_existing_job(client, default_project, default_source, default_repo, default_hook): build = factories.BuildFactory( source=default_source, project=default_project, provider=default_hook.provider, external_id='3', ) job = factories.JobFactory( build=build, provider=default_hook.provider, external_id='2', in_progress=True, ) path = '/hooks/{}/{}/builds/{}/jobs/{}'.format( default_hook.id, default_hook.get_signature(), build.external_id, job.external_id ) payload = { 'result': 'passed', 'status': 'finished', } resp = client.post( path, json=payload, ) assert resp.status_code == 200, repr(resp.data) job = Job.query.unrestricted_unsafe().get(job.id) assert job.result == Result.passed assert job.status == Status.finished
def test_new_artifact(client, default_source, default_repo, default_hook, sample_xunit): build = factories.BuildFactory( source=default_source, provider=default_hook.provider, external_id='3', ) job = factories.JobFactory( build=build, provider=default_hook.provider, external_id='2', in_progress=True, ) path = '/hooks/{}/{}/builds/{}/jobs/{}/artifacts'.format( default_hook.id, default_hook.get_signature(), build.external_id, job.external_id) resp = client.post( path, data={ 'name': 'junit.xml', 'file': (BytesIO(sample_xunit.encode('utf-8')), 'junit.xml'), 'type': 'xunit', }, ) assert resp.status_code == 201, repr(resp.data) data = resp.json() artifact = Artifact.query.get(data['id']) assert artifact.file.filename.endswith('junit.xml') assert artifact.type == 'xunit'
def test_repository_tests_history_by_build( client, default_login, default_build, default_testcase, default_repo, default_repo_access, default_revision, ): build2 = factories.BuildFactory(revision=default_revision, finished=True) job2 = factories.JobFactory(build=build2) factories.TestCaseFactory(job=job2, name=default_testcase.name, failed=True) build3 = factories.BuildFactory(revision=default_revision, finished=True) job3 = factories.JobFactory(build=build3) testcase2 = factories.TestCaseFactory(job=job3, passed=True, name=default_testcase.name + "2") build4 = factories.BuildFactory(revision=default_revision, finished=True) job4 = factories.JobFactory(build=build4) factories.TestCaseFactory(job=job4, name=default_testcase.name, passed=True) resp = client.get("/api/repos/{}/tests-by-build?results=3".format( default_repo.get_full_name())) assert resp.status_code == 200 data = resp.json() assert data["tests"] == [ { "name": default_testcase.name, "hash": default_testcase.hash, "results": ["passed", None, "failed"], }, { "name": testcase2.name, "hash": testcase2.hash, "results": [None, "passed", None], }, ] assert len(data["builds"]) == 3 assert data["builds"][0]["id"] == str(build4.id) assert data["builds"][1]["id"] == str(build3.id) assert data["builds"][2]["id"] == str(build2.id)
def test_revision_failures_list( client, sqla_assertions, db_session, default_login, default_repo, default_build, default_revision, default_repo_access, ): job1 = factories.JobFactory(build=default_build) job2 = factories.JobFactory(build=default_build) db_session.add(job1) db_session.add(job2) failure1 = factories.FailureReasonFactory(job=job1, failing_tests=True) failure2 = factories.FailureReasonFactory(job=job2, missing_tests=True) failure3 = factories.FailureReasonFactory(job=job2, failing_tests=True) db_session.add(failure1) db_session.add(failure2) db_session.add(failure3) resp = client.get("/api/repos/{}/revisions/{}/failures".format( default_repo.get_full_name(), default_revision.sha)) assert resp.status_code == 200 data = resp.json() assert len(data) == 2 assert data[0]["reason"] == "failing_tests" assert data[0]["runs"] == [ { "id": str(failure3.id), "job_id": str(job2.id) }, { "id": str(failure1.id), "job_id": str(job1.id) }, ] assert data[1]["reason"] == "missing_tests" assert data[1]["runs"] == [{ "id": str(failure2.id), "job_id": str(job2.id) }]
def test_test_stats(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) job2 = factories.JobFactory(build=build, passed=True) db_session.add(job2) db_session.add( factories.TestCaseFactory(job=job, name="foo", failed=True, duration=8)) db_session.add( factories.TestCaseFactory(job=job, name="bar", passed=True, duration=2)) db_session.add( factories.TestCaseFactory(job=job2, name="bar", failed=True, duration=2)) aggregate_build_stats_for_job(job.id) aggregate_build_stats_for_job(job2.id) aggregate_build_stats(build.id) build_stats = { i.name: i.value for i in ItemStat.query.filter(ItemStat.item_id == build.id) } assert build_stats["tests.count"] == 3 assert build_stats["tests.count_unique"] == 2 assert build_stats["tests.failures"] == 2 assert build_stats["tests.failures_unique"] == 2 assert build_stats["tests.duration"] == 12 job_stats = { i.name: i.value for i in ItemStat.query.filter(ItemStat.item_id == job.id) } assert job_stats["tests.count"] == 2 assert job_stats["tests.failures"] == 1 assert job_stats["tests.duration"] == 10
def test_build_job_create_existing_entity(client, default_login, default_repo, default_build, default_repo_access): existing_job = factories.JobFactory(build=default_build, travis=True) resp = client.post('/api/repos/{}/builds/{}/jobs'.format( default_repo.get_full_name(), default_build.number), json={ 'provider': existing_job.provider, 'external_id': existing_job.external_id, }) assert resp.status_code == 422
def test_unfinished_job(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, queued=True) db_session.add(build) job = factories.JobFactory(build=build, in_progress=True) db_session.add(job) aggregate_build_stats(build.id) assert build.status == Status.in_progress assert build.result == Result.unknown
def test_failure_with_allow_failure(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, failed=True, allow_failure=True) db_session.add(job) aggregate_build_stats(build.id) assert build.status == Status.finished assert build.result == Result.passed
def test_failure_with_allow_failure(mocker, db_session, default_source): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, failed=True, allow_failure=True) db_session.add(job) aggregate_build_stats(build.id) assert build.status == Status.finished assert build.result == Result.passed
def test_unfinished_job(mocker, db_session, default_source): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, queued=True) db_session.add(build) job = factories.JobFactory(build=build, in_progress=True) db_session.add(job) aggregate_build_stats_for_job(job.id) assert build.status == Status.in_progress assert build.result == Result.unknown
def test_finished_job(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, failed=True) db_session.add(job) mock_send_build_notifications = mocker.patch( "zeus.tasks.send_build_notifications.delay") aggregate_build_stats(build.id) assert build.status == Status.finished assert build.result == Result.failed mock_send_build_notifications.assert_called_once_with(build_id=build.id)
def test_coverage_stats(mocker, db_session, default_source): auth.set_current_tenant( auth.RepositoryTenant(repository_id=default_source.repository_id)) build = factories.BuildFactory(source=default_source) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) db_session.add( factories.FileCoverageFactory( build=build, lines_covered=20, lines_uncovered=50, diff_lines_covered=5, diff_lines_uncovered=2, )) db_session.add( factories.FileCoverageFactory( build=build, lines_covered=10, lines_uncovered=10, diff_lines_covered=5, diff_lines_uncovered=0, )) aggregate_build_stats(build.id) stats = { i.name: i.value for i in ItemStat.query.filter( ItemStat.item_id == build.id, ItemStat.name.in_([ "coverage.lines_covered", "coverage.lines_uncovered", "coverage.diff_lines_covered", "coverage.diff_lines_uncovered", ]), ) } assert stats["coverage.lines_covered"] == 30 assert stats["coverage.lines_uncovered"] == 60 assert stats["coverage.diff_lines_covered"] == 10 assert stats["coverage.diff_lines_uncovered"] == 2
def test_finished_job(mocker, db_session, default_project, default_source): auth.set_current_tenant( auth.Tenant(organization_ids=[default_project.organization_id], project_ids=[default_project.id], repository_ids=[default_source.repository_id])) build = factories.BuildFactory(project=default_project, source=default_source, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, failed=True) db_session.add(job) aggregate_build_stats_for_job(job.id) assert build.status == Status.finished assert build.result == Result.failed
def test_failing_tests(mocker, db_session, default_source): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) factories.TestCaseFactory(job=job, failed=True) aggregate_build_stats_for_job(job.id) assert job.result == Result.failed reasons = list(FailureReason.query.filter(FailureReason.job_id == job.id)) assert len(reasons) == 1 assert reasons[0].reason == FailureReason.Code.failing_tests
def test_finished_job(mocker, db_session, default_source): auth.set_current_tenant( auth.Tenant(repository_ids=[default_source.repository_id])) build = factories.BuildFactory(source=default_source, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, failed=True) db_session.add(job) mock_send_build_notifications = mocker.patch( 'zeus.tasks.send_build_notifications.delay') aggregate_build_stats(build.id) assert build.status == Status.finished assert build.result == Result.failed mock_send_build_notifications.assert_called_once_with(build_id=build.id)
def test_record_bundle_stats(mocker, db_session, default_revision, default_tenant): build = factories.BuildFactory(revision=default_revision, in_progress=True) db_session.add(build) job = factories.JobFactory(build=build, passed=True) db_session.add(job) bundle = factories.BundleFactory(job=job) db_session.add(factories.BundleFactory(job=job)) db_session.add(factories.BundleAssetFactory(bundle=bundle, size=1000)) db_session.add(factories.BundleAssetFactory(bundle=bundle, size=1500)) record_bundle_stats(job.id) job_stats = { i.name: i.value for i in ItemStat.query.filter(ItemStat.item_id == job.id) } assert job_stats["bundle.total_asset_size"] == 2500
def test_update_job_to_in_progress(client, mocker, default_login, default_repo, default_build, default_repo_access): job = factories.JobFactory(build=default_build, queued=True) mock_delay = mocker.patch('zeus.tasks.aggregate_build_stats_for_job.delay') resp = client.put('/api/repos/{}/builds/{}/jobs/{}'.format( default_repo.get_full_name(), default_build.number, job.number), json={ 'status': 'in_progress', }) assert resp.status_code == 200 data = resp.json() assert data['id'] == str(job.id) assert job.status == Status.in_progress assert job.date_started assert not job.date_finished mock_delay.assert_called_once_with(job_id=job.id)
def test_aggregates_upon_completion(mocker, default_hook): build = factories.BuildFactory(travis=True, repository=default_hook.repository) job = factories.JobFactory(travis=True, build=build) pending_artifact = factories.PendingArtifactFactory( external_build_id=build.external_id, external_job_id=job.external_id, hook=default_hook, ) process_pending_artifact(pending_artifact_id=pending_artifact.id) artifact = (Artifact.query.unrestricted_unsafe().filter( Artifact.job_id == job.id).first()) assert artifact.name == pending_artifact.name assert artifact.file.path == pending_artifact.file.path assert artifact.file.size == pending_artifact.file.size assert artifact.file.filename == pending_artifact.file.filename
def test_update_job_to_finished(client, mocker, default_login, default_repo, default_build, default_repo_access): job = factories.JobFactory(build=default_build, in_progress=True) mock_delay = mocker.patch("zeus.tasks.aggregate_build_stats_for_job.delay") resp = client.put( "/api/repos/{}/builds/{}/jobs/{}".format(default_repo.get_full_name(), default_build.number, job.number), json={ "result": "failed", "status": "finished", "started_at": "2017-01-01T01:02:30Z", "finished_at": "2017-01-01T01:22:30Z", }, ) assert resp.status_code == 200 data = resp.json() assert data["id"] == str(job.id) assert job.status == Status.finished assert job.result == Result.failed assert job.date_started == datetime(2017, 1, 1, 1, 2, 30, tzinfo=timezone.utc) assert job.date_finished == datetime(2017, 1, 1, 1, 22, 30, tzinfo=timezone.utc) mock_delay.assert_called_once_with(job_id=job.id)