Read about our upcoming Code of Conduct on this issue

Commit 76089291 authored by Georges Racinet's avatar Georges Racinet 🦑
Browse files

Expanded on functional test for protected branch checks

See heptapod#368

Now with two sets of scenarios with various refusals, and
the check that accepting Merge Requests is recognized to
go through another set of permissions (very important to
avoid locking situations)

--HG--
branch : stable
parent 6511b461008e
Pipeline #13276 waiting for manual action with stages
in 24 seconds
import json
from urllib.parse import parse_qs
import pytest
import re
import requests
from .utils import needs
from .utils.reverse_calls import HttpListener
......@@ -238,24 +240,145 @@ def test_protected_branch_refusal(test_project, tmpdir):
print(repo.graphlog())
repo.hg('push', '--new-branch', url)
# now let's protect the branch and close it (it's forbidden to remove
# protected GitLab branches)
# now let's protect the branch
resp = test_project.owner_api_post(subpath='protected_branches',
data=dict(name='branch/a_branch'))
assert resp.status_code in (200, 201, 202)
# Later on, we'll have a 'publisher' role. Meanwhile, let's
# avoid the check_publish hook to prevent developer pushing.
test_project.owner_api_hgrc_set(inherit=True, auto_publish='nothing')
test_project.grant_member_access(user_name='test_basic',
level=ProjectAccess.DEVELOPER)
# Later on, we'll have a 'publisher' role. In the meanwhile let's
# avoid the check_publish hook to prevent developer pushing.
repo.hg('commit', '--close-branch', '-m', "closing")
basic_user_url = test_project.basic_auth_url(user_name='test_basic')
basic_user_ssh_params = test_project.ssh_params('test_basic')
repo_path.join('foo').write('still in branch')
repo.hg('commit', '-m', 'New commit that only maintainer can push')
code, out, err = repo.hg_unchecked('push', '--ssh', *basic_user_ssh_params)
assert code != 0
assert re.search("push.*protected branches", out)
code, out, err = repo.hg_unchecked('push', basic_user_url)
assert code != 0
assert re.search("push.*protected branches", out)
# it is also forbidden to remove protected branches
repo.hg('commit', '--close-branch', '-m', "closing")
code, out, err = repo.hg_unchecked('push', basic_user_url)
assert code != 0
# let's not depend too much on exact message wording
assert "delete protected branches" in out
# the failed pushes had indeed no effect on the hg repo
clone = LocalRepo.clone(url, tmpdir.join('repo2'))
log = clone.hg('log', '-T', '{desc}:{branch}\n').splitlines()
assert set(l.strip() for l in log) == {
'Commit 0:default',
'Commit 1:default',
'Commit in branch:a_branch',
}
def test_protected_branch_ultimate(test_project, tmpdir):
"""Mode in which even maintainers can't push."""
repo_path = tmpdir.join('repo1')
url = test_project.owner_basic_auth_url
repo = LocalRepo.init(repo_path)
# let's have two branches
repo_path.join('foo').write('foo0')
repo.hg('commit', '-Am', "Commit 0")
repo_path.join('foo').write('foo1')
repo.hg('commit', '-Am', "Commit 1")
repo.hg('push', url) # make sure 'default' is the GitLab default branch
repo.hg('up', '0')
repo.hg('branch', 'a_branch')
repo_path.join('foo').write('in branch')
repo.hg('commit', '-Am', "Commit in branch")
repo.hg('phase', '-pr', "default+a_branch")
print(repo.graphlog())
repo.hg('push', '--new-branch', url)
resp = test_project.owner_api_post(subpath='protected_branches',
data=dict(name='branch/a_branch',
push_access_level=0))
assert resp.status_code in (200, 201, 202)
repo_path.join('foo').write('still in branch')
repo.hg('commit', '-m', 'New commit that even Owner cannot push')
ssh_params = test_project.owner_ssh_params
code, out, err = repo.hg_unchecked('push', '--ssh', *ssh_params)
assert code != 0
assert re.search("push.*protected branches", out)
code, out, err = repo.hg_unchecked('push', url)
assert code != 0
assert re.search("push.*protected branches", out)
# regular owner is also instance-wide administrator, and should
# arguably still be allowed to remove the branch, let's make a Maintainer
test_project.grant_member_access(user_name='test_basic',
level=ProjectAccess.MAINTAINER)
maintainer_url = test_project.basic_auth_url(user_name='test_basic')
repo.hg('commit', '--close-branch', '-m', "closing")
code, out, err = repo.hg_unchecked('push', maintainer_url)
assert code != 0
# let's not depend too much on exact message wording
assert "delete protected branches" in out
# the failed pushes had indeed no effect on the hg repo
clone = LocalRepo.clone(url, tmpdir.join('repo2'))
log = clone.hg('log', '-T', '{desc}:{branch}\n').splitlines()
assert set(l.strip() for l in log) == {
'Commit 0:default',
'Commit 1:default',
'Commit in branch:a_branch',
}
# far from being completely blocked the newly appointed Maintainer
# can still accept MRs
repo.hg('topic', '-r', '.~1', 'zetop')
repo.hg('push', '-r', 'zetop', maintainer_url)
mr_id = test_project.api_create_merge_request(
source='topic/a_branch/zetop',
target='branch/a_branch',
)
# TODO looks like it's really time to put this kind of MR handling
# down to the project level or on a separate MergeRequest object
test_project.wait_assert_merge_request(
mr_id, lambda mr: mr.get('merge_status') == 'can_be_merged',
msg="Mergeability wrong or still unknown")
# we have nicer helpers for API requests from other users than owner
# in the default branch but can't use them right away (stable branch)
headers = {
'Private-Token': test_project.heptapod.get_user('test_basic').token,
}
resp = requests.put('%s/merge_requests/%d/merge' % (test_project.api_url,
mr_id),
headers=headers,
data=dict(merge_request_iid=mr_id,
id=test_project.id))
assert resp.status_code < 300
assert resp.json()['state'] == 'merged'
clone.hg('pull')
log = clone.hg('log', '-T', '{desc}:{branch}:{phase}\n').splitlines()
assert set(l.strip() for l in log) == {
'Commit 0:default:public',
'Commit 1:default:public',
'Commit in branch:a_branch:public',
'New commit that even Owner cannot push:a_branch:public',
}
@needs.docker
def test_push_corrupted_2(test_project, tmpdir):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment