def test_updater_main(tmpdir, upstream_repo, midstream_repo, git_at,
                      monkeypatch, gerrit_push_map, run_click_command,
                      call_with_env):
    monkeypatch.chdir(tmpdir)
    # we need to mock this because the tool is actually designed to work with
    # Gerrit but in the test we don't have an actual Gerrit server
    mock_check_if_similar_patch_pushed = MagicMock(return_value=False)
    monkeypatch.setattr('stdci_tools.pusher.check_if_similar_patch_pushed',
                        mock_check_if_similar_patch_pushed)
    midstream_git = git_at(midstream_repo)

    if call_with_env:
        monkeypatch.setenv('REPO_URL', str(midstream_repo))
        monkeypatch.setenv('REPO_REF', 'refs/heads/master')
        monkeypatch.setenv('REPO_PUSH_BRANCH', 'other_branch')
        monkeypatch.setenv('PUSHER_PUSH_MAP', str(gerrit_push_map))
        run_click_command(updater_main_cli, '-d', '-v')
    else:
        run_click_command(updater_main_cli, '-d', '-v', str(midstream_repo),
                          'refs/heads/master', 'other_branch',
                          str(gerrit_push_map))

    assert mock_check_if_similar_patch_pushed.called, \
        'expected check if similar patch pushed to be called'
    other_branch_sha = git_rev_parse('refs/for/other_branch', midstream_git)
    head_sha = git_rev_parse('HEAD', midstream_git)
    assert head_sha == other_branch_sha, \
        'expected push to occur to other_branch and sha to be the same as HEAD'
Beispiel #2
0
def test_git_rev_parse(repo_with_patches, git_repo_log, monkeypatch, ref,
                       exp_idx):
    monkeypatch.chdir(repo_with_patches)
    if isinstance(exp_idx, type) and issubclass(exp_idx, Exception):
        with pytest.raises(exp_idx) as e:
            git_rev_parse(ref)
        assert e.value.ref == ref
    else:
        out = git_rev_parse(ref)
        assert out == git_repo_log()[exp_idx]
def test_run_upstream_source_updater(midstream_repo, upstream_repo, git_at):
    upstream_git = git_at(upstream_repo)
    upstream_head_sha = git_rev_parse('HEAD', upstream_git)
    midstream_git = git_at(midstream_repo)
    midstream_head_sha = git_rev_parse('HEAD', midstream_git)
    midstream_usrc_config = midstream_repo / 'upstream_sources.yaml'
    run_upstream_source_updater(str(midstream_repo))
    with midstream_usrc_config.open() as usrc_config_file:
        usrc_yaml = yaml.safe_load(usrc_config_file)
    assert usrc_yaml == {
        'git': [{
            'commit': upstream_head_sha,
            'branch': 'master',
            'url': str(upstream_repo),
        }]
    }
    assert git_rev_parse('HEAD', midstream_git) != midstream_head_sha, \
        'expected a new commit sha on the midstream repository'
Beispiel #4
0
def get_patch_owner(push_details, commit='HEAD'):
    """Get the Gerrit username for the owner of the given commit

    :param PushDetails push_details: Details about where we're pushing the
                                     patch to
    :param str commit:               (Optional) A commit ref for a commit in
                                     $PWD, Defaults to HEAD.
    :rtype: str
    :returns: The Gerrit username for the owner of the patchset that includes
              the given commit
    """
    git_hash = git_rev_parse(commit)
    change_json_lines = gerrit_cli(push_details, 'query', '--format=json',
                                   'commit:' + git_hash).splitlines()
    if len(change_json_lines) <= 1:
        return None
    change = json.loads(change_json_lines[0])
    return change['owner']['username']
Beispiel #5
0
def test_prep_git_repo(
        monkeypatch, tmpdir, git_at, repo_with_patches, git_last_sha):
    # we need this nested tmpdir because `repo_with_patches` exists in the
    # default tmpdir and the new git repo we initialize will have the same name
    tmpdir = tmpdir / 'tmpdir'
    tmpdir.mkdir()
    monkeypatch.chdir(tmpdir)
    repo_url = str(repo_with_patches)
    refspec = 'master'
    git_func, last_sha = prep_git_repo(
        tmpdir, repo_url, refspec, checkout=True)
    # we can't use get-url because on centos7 the git version is too old
    remote_url = git_func('remote', '-v').split()[1]
    assert remote_url == repo_url, \
        'expected git func to return the URL for repo_with_patches'
    assert last_sha == git_rev_parse('HEAD', git_func), (
        'expected to find the fetched sha at the HEAD'
        ' of the checked out branch'
    )
Beispiel #6
0
def merge_to_scm(push_map, commit='HEAD', check_header='automerge'):
    """Make a remote SCM merge a given commit

    :param str push_map:     The path to a file containing information about
                             remote SCM servers that is needed to push changes
                             to them.
    :param str commit:       (Optional) A ref to the commit to merge. The
                             default is HEAD
    :param str check_header: (Optional) The name of a commit header that should
                             be set to 'true' or 'yes' in order for the merge
                             to be attempted. Set to 'automerge' be default,
                             cat be set to None to skip header check.
    """
    if not can_merge_to_scm(push_map, commit, check_header):
        return
    commit_hash = git_rev_parse(commit)
    logger.info("Will merge commit: %s", commit_hash)
    push_details = read_push_details(push_map)
    logger.info("Would merge to: '%s'", push_details.push_url)
    gerrit_cli(push_details, 'review', commit_hash, '--submit',
               *push_details.merge_flags)
Beispiel #7
0
def push_to_scm(dst_branch,
                push_map,
                direct=False,
                if_not_exists=True,
                unless_hash=None):
    """Push commits to the specified remote branch

    :param str dst_branch:    The target remote branch to push changes into.
                              What this means in practice depends on the type
                              of remote SCM server being pushed to.
    :param str push_map:      The path to a file containing information about
                              remote SCM servers that is needed to push changes
                              to them.
    :param bool direct:       If set to True, bypass review and directly merge
                              the patch.
    :param bool if_not_exists: If set to 'True' (the default), check remote for
                              a similar patch before pushing, and don't push if
                              it exists.
    :param str unless_hash:   Given a Git hash value, or a commit ref, if HEAD
                              is equal to this commit, don't try to push it.
    """
    if unless_hash is not None:
        if get_patch_sha() == git_rev_parse(unless_hash):
            logger.info("HEAD commit is '%s', skipping push", unless_hash)
            return
    push_details = read_push_details(push_map)
    logger.info("Would push to: '%s'", push_details.push_url)
    if push_details.host_key:
        add_key_to_known_hosts(push_details.host_key)
    if if_not_exists and check_if_similar_patch_pushed(push_details,
                                                       dst_branch):
        logger.info('Found similar patch in SCM server, not pushing')
        return
    if direct:
        dest_to_push_to = 'HEAD:refs/heads/{0}'.format(dst_branch)
    else:
        dest_to_push_to = 'HEAD:refs/for/{0}'.format(dst_branch)
    logger.info("Push to: '%s' at '%s'", push_details.push_url,
                dest_to_push_to)
    git('push', push_details.push_url, dest_to_push_to)