from test.fixtures import * import pytest from mock import patch from data import model from data.database import BUILD_PHASE, RepositoryBuild, RepositoryBuildTrigger from data.model.build import ( create_repository_build, get_repository_build, update_phase_then_close, update_trigger_disable_status, ) TEST_FAIL_THRESHOLD = 5 TEST_INTERNAL_ERROR_THRESHOLD = 2 @pytest.mark.parametrize( "starting_failure_count, starting_error_count, status, expected_reason", [ (0, 0, BUILD_PHASE.COMPLETE, None), (10, 10, BUILD_PHASE.COMPLETE, None), (TEST_FAIL_THRESHOLD - 1, TEST_INTERNAL_ERROR_THRESHOLD - 1, BUILD_PHASE.COMPLETE, None), (TEST_FAIL_THRESHOLD - 1, 0, BUILD_PHASE.ERROR, "successive_build_failures"), ( 0, TEST_INTERNAL_ERROR_THRESHOLD - 1, BUILD_PHASE.INTERNAL_ERROR, "successive_build_internal_errors", ), ], ) def test_update_trigger_disable_status( starting_failure_count, starting_error_count, status, expected_reason, initialized_db ): test_config = { "SUCCESSIVE_TRIGGER_FAILURE_DISABLE_THRESHOLD": TEST_FAIL_THRESHOLD, "SUCCESSIVE_TRIGGER_INTERNAL_ERROR_DISABLE_THRESHOLD": TEST_INTERNAL_ERROR_THRESHOLD, } trigger = model.build.list_build_triggers("devtable", "building")[0] trigger.successive_failure_count = starting_failure_count trigger.successive_internal_error_count = starting_error_count trigger.enabled = True trigger.save() with patch("data.model.config.app_config", test_config): update_trigger_disable_status(trigger, status) updated_trigger = RepositoryBuildTrigger.get(uuid=trigger.uuid) assert updated_trigger.enabled == (expected_reason is None) if expected_reason is not None: assert updated_trigger.disabled_reason.name == expected_reason else: assert updated_trigger.disabled_reason is None assert updated_trigger.successive_failure_count == 0 assert updated_trigger.successive_internal_error_count == 0 def test_archivable_build_logs(initialized_db): # Make sure there are no archivable logs. result = model.build.get_archivable_build() assert result is None # Add a build that cannot (yet) be archived. repo = model.repository.get_repository("devtable", "simple") token = model.token.create_access_token(repo, "write") created = RepositoryBuild.create( repository=repo, access_token=token, phase=model.build.BUILD_PHASE.WAITING, logs_archived=False, job_config="{}", display_name="", ) # Make sure there are no archivable logs. result = model.build.get_archivable_build() assert result is None # Change the build to being complete. created.phase = model.build.BUILD_PHASE.COMPLETE created.save() # Make sure we now find an archivable build. result = model.build.get_archivable_build() assert result.id == created.id def test_update_build_phase(initialized_db): build = create_build(model.repository.get_repository("devtable", "building")) repo_build = get_repository_build(build.uuid) assert repo_build.phase == BUILD_PHASE.WAITING assert update_phase_then_close(build.uuid, BUILD_PHASE.COMPLETE) repo_build = get_repository_build(build.uuid) assert repo_build.phase == BUILD_PHASE.COMPLETE repo_build.delete_instance() assert not update_phase_then_close(repo_build.uuid, BUILD_PHASE.PULLING) def create_build(repository): new_token = model.token.create_access_token(repository, "write", "build-worker") repo = "ci.devtable.com:5000/%s/%s" % (repository.namespace_user.username, repository.name) job_config = { "repository": repo, "docker_tags": ["latest"], "build_subdir": "", "trigger_metadata": { "commit": "3482adc5822c498e8f7db2e361e8d57b3d77ddd9", "ref": "refs/heads/master", "default_branch": "master", }, } build = create_repository_build( repository, new_token, job_config, "68daeebd-a5b9-457f-80a0-4363b882f8ea", "build_name" ) build.save() return build