Example #1
0
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)
Example #2
0
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'])
Example #3
0
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'])
Example #4
0
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)
Example #5
0
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'])
Example #6
0
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'])