def test_merges_approved_pr(tmpdir): BRANCH_NAME = 'test_merges_approved_pr' pr_number = None try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test' }, 'name': 'master' }, True]] os.chdir(tmpdir) call( [ 'git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git' ], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call([ 'git', 'config', 'user.email', '*****@*****.**' ]) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) call(['git', 'checkout', '-b', BRANCH_NAME]) call(['git', 'commit', '--allow-empty', '-m', 'foo']) call(['git', 'push', 'origin', BRANCH_NAME]) source_sha = rev_parse(BRANCH_NAME) gh_pr = post_repo(FQ_REPO, 'pulls', json={ "title": "foo", "head": BRANCH_NAME, "base": "master" }, status_code=201) pr_number = str(gh_pr['number']) post_repo(FQ_REPO, f'pulls/{pr_number}/reviews', json={ "commit_id": source_sha, "event": "APPROVE" }, status_code=200, token=oauth_tokens['user2']) get_repo(FQ_REPO, f'pulls/{pr_number}/reviews', status_code=200, token=oauth_tokens['user1']) time.sleep(7) poll_github_until_merged(pr_number) call(['git', 'fetch', 'origin']) merged_sha = rev_parse('origin/master') # deploy job takes some time time.sleep(7) deploy_artifact = run( ['gsutil', 'cat', f'gs://hail-ci-test/{merged_sha}'], stdout=subprocess.PIPE, check=True) deploy_artifact = deploy_artifact.stdout.decode('utf-8').strip() assert f'commit {merged_sha}' in deploy_artifact finally: call(['git', 'push', 'origin', ':' + BRANCH_NAME]) if pr_number is not None: patch_repo(FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200)
def test_push_while_building(tmpdir): BRANCH_NAME = 'test_push_while_building' SLOW_BRANCH_NAME = 'test_push_while_building_slow' pr_number = {} source_sha = {} gh_pr = {} pr = {} try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test' }, 'name': 'master' }, True]] os.chdir(tmpdir) call( [ 'git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git' ], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call([ 'git', 'config', 'user.email', '*****@*****.**' ]) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) # start slow branch call(['git', 'checkout', 'master']) first_target_sha = rev_parse('master') call(['git', 'checkout', '-b', SLOW_BRANCH_NAME]) with open('hail-ci-build.sh', 'w') as f: f.write('sleep 45') call(['git', 'add', 'hail-ci-build.sh']) call(['git', 'commit', '-m', 'foo']) source_sha[SLOW_BRANCH_NAME] = push(SLOW_BRANCH_NAME) gh_pr[SLOW_BRANCH_NAME] = create_pull_request('foo', SLOW_BRANCH_NAME) pr_number[SLOW_BRANCH_NAME] = gh_pr[SLOW_BRANCH_NAME]['number'] # get details on first job of slow branch pr[SLOW_BRANCH_NAME] = poll_until_pr_exists_and( SLOW_BRANCH_NAME, lambda x: x.is_building()) assertDictHasKVs( pr[SLOW_BRANCH_NAME].to_json(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": first_target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": SLOW_BRANCH_NAME }, "sha": source_sha[SLOW_BRANCH_NAME] }, "review": "pending", "build": { "type": "Building", "target_sha": first_target_sha }, "number": str(pr_number[SLOW_BRANCH_NAME]) }) first_slow_job_id = pr[SLOW_BRANCH_NAME].build.job.id assert first_slow_job_id is not None # start fast branch source_sha[BRANCH_NAME] = create_and_push_empty_commit(BRANCH_NAME) gh_pr[BRANCH_NAME] = create_pull_request('foo', BRANCH_NAME) pr_number[BRANCH_NAME] = gh_pr[BRANCH_NAME]['number'] approve(pr_number[BRANCH_NAME], source_sha[BRANCH_NAME]) poll_github_until_merged(pr_number[BRANCH_NAME]) call(['git', 'fetch', 'origin']) second_target_sha = rev_parse('origin/master') time.sleep(10) # allow deploy job to run deploy_artifact = run( ['gsutil', 'cat', f'gs://hail-ci-test/{second_target_sha}'], stdout=subprocess.PIPE) deploy_artifact = deploy_artifact.stdout.decode('utf-8').strip() assert f'commit {second_target_sha}' in deploy_artifact time.sleep(5) # allow github push notification to be sent pr[SLOW_BRANCH_NAME] = poll_until_finished_pr(SLOW_BRANCH_NAME) assertDictHasKVs( pr[SLOW_BRANCH_NAME].to_json(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": second_target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": SLOW_BRANCH_NAME }, "sha": source_sha[SLOW_BRANCH_NAME] }, "review": "pending", "build": { "type": "Mergeable", "target_sha": second_target_sha }, "number": str(pr_number[SLOW_BRANCH_NAME]) }) finally: call(['git', 'push', 'origin', ':' + SLOW_BRANCH_NAME]) call(['git', 'push', 'origin', ':' + BRANCH_NAME]) for pr_number in pr_number.values(): patch_repo(FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200, token=oauth_tokens['user1'])
def test_pull_request_trigger(tmpdir): BRANCH_NAME = 'test_pull_request_trigger' pr_number = None try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test' }, 'name': 'master' }, True]] os.chdir(tmpdir) call( [ 'git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git' ], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call([ 'git', 'config', 'user.email', '*****@*****.**' ]) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) call(['git', 'checkout', '-b', BRANCH_NAME]) call(['git', 'commit', '--allow-empty', '-m', 'foo']) call(['git', 'push', 'origin', BRANCH_NAME]) source_sha = rev_parse(BRANCH_NAME) target_sha = rev_parse('master') data = post_repo(FQ_REPO, 'pulls', json={ "title": "foo", "head": BRANCH_NAME, "base": "master" }, status_code=201, token=oauth_tokens['user1']) pr_number = str(data['number']) time.sleep(7) pr = poll_until_finished_pr(BRANCH_NAME) assertDictHasKVs( pr.to_json(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": BRANCH_NAME }, "sha": source_sha }, "review": "pending", "build": { "type": "Mergeable", "target_sha": target_sha }, "number": pr_number }) finally: call(['git', 'push', 'origin', ':' + BRANCH_NAME]) if pr_number is not None: patch_repo(FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200, token=oauth_tokens['user1'])
def test_merges_approved_pr(tmpdir): BRANCH_NAME = 'test_merges_approved_pr' pr_number = None try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test'}, 'name': 'master'}, True]] os.chdir(tmpdir) call(['git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git'], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call(['git', 'config', 'user.email', '*****@*****.**']) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) call(['git', 'checkout', '-b', BRANCH_NAME]) call(['git', 'commit', '--allow-empty', '-m', 'foo']) call(['git', 'push', 'origin', BRANCH_NAME]) source_sha = rev_parse(BRANCH_NAME) gh_pr = post_repo( FQ_REPO, 'pulls', json={ "title": "foo", "head": BRANCH_NAME, "base": "master" }, status_code=201) pr_number = str(gh_pr['number']) post_repo( FQ_REPO, f'pulls/{pr_number}/reviews', json={ "commit_id": source_sha, "event": "APPROVE" }, status_code=200, token=oauth_tokens['user2']) get_repo( FQ_REPO, f'pulls/{pr_number}/reviews', status_code=200, token=oauth_tokens['user1']) time.sleep(7) poll_github_until_merged(pr_number) call(['git', 'fetch', 'origin']) merged_sha = rev_parse('origin/master') poll_until_deployed_sha_is(FQRef.from_short_str(FQ_REPO+':master'), merged_sha) deploy_artifact = run(['gsutil', 'cat', f'gs://hail-ci-test/{merged_sha}'], stdout=subprocess.PIPE, check=True) deploy_artifact = deploy_artifact.stdout.decode('utf-8').strip() assert f'commit {merged_sha}' in deploy_artifact finally: call(['git', 'push', 'origin', ':' + BRANCH_NAME]) if pr_number is not None: patch_repo( FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200)
def test_push_while_building(tmpdir): BRANCH_NAME = 'test_push_while_building' SLOW_BRANCH_NAME = 'test_push_while_building_slow' pr_number = {} source_sha = {} gh_pr = {} pr = {} try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test'}, 'name': 'master'}, True]] os.chdir(tmpdir) call(['git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git'], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call(['git', 'config', 'user.email', '*****@*****.**']) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) # start slow branch call(['git', 'checkout', 'master']) first_target_sha = rev_parse('master') call(['git', 'checkout', '-b', SLOW_BRANCH_NAME]) with open('hail-ci-build.sh', 'w') as f: f.write('sleep 45') call(['git', 'add', 'hail-ci-build.sh']) call(['git', 'commit', '-m', 'foo']) source_sha[SLOW_BRANCH_NAME] = push(SLOW_BRANCH_NAME) gh_pr[SLOW_BRANCH_NAME] = create_pull_request( 'foo', SLOW_BRANCH_NAME) pr_number[SLOW_BRANCH_NAME] = gh_pr[SLOW_BRANCH_NAME]['number'] # get details on first job of slow branch pr[SLOW_BRANCH_NAME] = poll_until_pr_exists_and( SLOW_BRANCH_NAME, lambda x: x.is_building()) assertDictHasKVs( pr[SLOW_BRANCH_NAME].to_dict(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": first_target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": SLOW_BRANCH_NAME }, "sha": source_sha[SLOW_BRANCH_NAME] }, "review": "pending", "build": { "type": "Building", "target_sha": first_target_sha }, "number": str(pr_number[SLOW_BRANCH_NAME]) }) first_slow_job_id = pr[SLOW_BRANCH_NAME].build.job.id assert first_slow_job_id is not None # start fast branch source_sha[BRANCH_NAME] = create_and_push_empty_commit( BRANCH_NAME) gh_pr[BRANCH_NAME] = create_pull_request( 'foo', BRANCH_NAME) pr_number[BRANCH_NAME] = gh_pr[BRANCH_NAME]['number'] approve(pr_number[BRANCH_NAME], source_sha[BRANCH_NAME]) poll_github_until_merged(pr_number[BRANCH_NAME]) call(['git', 'fetch', 'origin']) second_target_sha = rev_parse('origin/master') i = 0 while True: time.sleep(0.100 * (2 ** i)) deploy_artifact = run( ['gsutil', 'cat', f'gs://hail-ci-test/{second_target_sha}'], stdout=subprocess.PIPE) if deploy_artifact.returncode == 0: deploy_artifact = deploy_artifact.stdout.decode('utf-8').strip() assert f'commit {second_target_sha}' in deploy_artifact break elif i > 14: assert False, (f'tried {i} times to get deployed artifact, ' f'but never found it {deploy_artifact}') else: i = i + 1 time.sleep(5) # allow github push notification to be sent pr[SLOW_BRANCH_NAME] = poll_until_finished_pr( SLOW_BRANCH_NAME) assertDictHasKVs( pr[SLOW_BRANCH_NAME].to_dict(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": second_target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": SLOW_BRANCH_NAME }, "sha": source_sha[SLOW_BRANCH_NAME] }, "review": "pending", "build": { "type": "Mergeable", "target_sha": second_target_sha }, "number": str(pr_number[SLOW_BRANCH_NAME]) }) finally: call(['git', 'push', 'origin', ':' + SLOW_BRANCH_NAME]) call(['git', 'push', 'origin', ':' + BRANCH_NAME]) for pr_number in pr_number.values(): patch_repo( FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200, token=oauth_tokens['user1'])
def test_pull_request_trigger(tmpdir): BRANCH_NAME = 'test_pull_request_trigger' pr_number = None try: status = ci_get('/status', status_code=200) assert '_watched_targets' in status assert status['_watched_targets'] == [[{ 'repo': { 'name': REPO_NAME, 'owner': 'hail-ci-test'}, 'name': 'master'}, True]] os.chdir(tmpdir) call(['git', 'clone', f'https://{oauth_tokens["user1"]}@github.com/hail-ci-test/{REPO_NAME}.git'], # do not leak the token stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chdir(REPO_NAME) call(['git', 'config', 'user.email', '*****@*****.**']) call(['git', 'config', 'user.name', 'ci-automated-tests']) call(['git', 'remote', '-v']) call(['git', 'checkout', '-b', BRANCH_NAME]) call(['git', 'commit', '--allow-empty', '-m', 'foo']) call(['git', 'push', 'origin', BRANCH_NAME]) source_sha = rev_parse(BRANCH_NAME) target_sha = rev_parse('master') data = post_repo( FQ_REPO, 'pulls', json={ "title": "foo", "head": BRANCH_NAME, "base": "master" }, status_code=201, token=oauth_tokens['user1']) pr_number = str(data['number']) time.sleep(7) pr = poll_until_finished_pr(BRANCH_NAME) assertDictHasKVs( pr.to_dict(), { "target": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": "master" }, "sha": target_sha }, "source": { "ref": { "repo": { "owner": "hail-ci-test", "name": REPO_NAME }, "name": BRANCH_NAME }, "sha": source_sha }, "review": "pending", "build": { "type": "Mergeable", "target_sha": target_sha }, "number": pr_number }) finally: call(['git', 'push', 'origin', ':' + BRANCH_NAME]) if pr_number is not None: patch_repo( FQ_REPO, f'pulls/{pr_number}', json={"state": "closed"}, status_code=200, token=oauth_tokens['user1'])