FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

refactor: use python-gitlab in acceptance tests · gitlabform/gitlabform@0b6fb94 · GitHub

Repository navigation

Commit 0b6fb94

Browse files
committed
refactor: use python-gitlab in acceptance tests
1 parent 1118b9e commit 0b6fb94

42 files changed

Lines changed: 1111 additions & 1202 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎dev/run_gitlab_in_docker.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ fi
7878
cecho b "Starting GitLab..."
7979
# run GitLab with root password pre-set and as many unnecessary features disabled to speed up the startup
8080
docker run --detach \
81-
--hostname gitlab.foobar.com \
81+
--hostname localhost \
8282
--env GITLAB_OMNIBUS_CONFIG="$gitlab_omnibus_config" \
8383
--publish 443:443 --publish 80:80 --publish 2022:22 \
8484
--name gitlab \

‎gitlabform/gitlab/branches.py‎

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -67,50 +67,6 @@ def get_branch_access_levels(self, project_and_group_name, branch):
6767
"projects/%s/protected_branches/%s", (project_and_group_name, branch)
6868
)
6969

70-
def get_only_branch_access_levels(self, project_and_group_name, branch):
71-
try:
72-
result = self._make_requests_to_api(
73-
"projects/%s/protected_branches/%s", (project_and_group_name, branch)
74-
)
75-
76-
push_access_levels = set()
77-
merge_access_levels = set()
78-
push_access_user_ids = set()
79-
merge_access_user_ids = set()
80-
unprotect_access_level = None
81-
82-
if "push_access_levels" in result:
83-
for push_access in result["push_access_levels"]:
84-
if not push_access["user_id"]:
85-
push_access_levels.add(push_access["access_level"])
86-
else:
87-
push_access_user_ids.add(push_access["user_id"])
88-
89-
if "merge_access_levels" in result:
90-
for merge_access in result["merge_access_levels"]:
91-
if not merge_access["user_id"]:
92-
merge_access_levels.add(merge_access["access_level"])
93-
else:
94-
merge_access_user_ids.add(merge_access["user_id"])
95-
96-
if (
97-
"unprotect_access_levels" in result
98-
and len(result["unprotect_access_levels"]) == 1
99-
):
100-
unprotect_access_level = result["unprotect_access_levels"][0][
101-
"access_level"
102-
]
103-
104-
return (
105-
sorted(push_access_levels),
106-
sorted(merge_access_levels),
107-
sorted(push_access_user_ids),
108-
sorted(merge_access_user_ids),
109-
unprotect_access_level,
110-
)
111-
except NotFoundException:
112-
return None, None, None, None, None
113-
11470
def create_branch(
11571
self, project_and_group_name, new_branch_name, create_branch_from_ref
11672
):

‎gitlabform/gitlab/core.py‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,6 @@ def _get_project_id(self, project_and_group):
9898
result = self.get_project(project_and_group)
9999
return str(result["id"])
100100

101-
def has_no_license(self):
102-
license = self._make_requests_to_api("license")
103-
return not license or license["expired"]
104-
105101
def _make_requests_to_api(
106102
self,
107103
path_as_format_string,

‎gitlabform/gitlab/groups.py‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,6 @@ def put_group_settings(self, project_and_group_name, group_settings):
122122
"groups/%s", project_and_group_name, "PUT", group_settings
123123
)
124124

125-
def get_group_shared_with(self, group):
126-
group = self.get_group_case_insensitive(group)
127-
128-
return group["shared_with_groups"]
129-
130125
def add_share_to_group(
131126
self, group, share_with_group_name, group_access, expires_at=None
132127
):

‎gitlabform/gitlab/members.py‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@ def get_project_members(self, project_and_group_name, all=False):
99

1010
return self._make_requests_to_api(url_template, project_and_group_name)
1111

12-
def get_shared_with_groups(self, project_and_group_name):
13-
# a dict with groups that this project has been shared with
14-
return self._make_requests_to_api("projects/%s", project_and_group_name)[
15-
"shared_with_groups"
16-
]
17-
1812
def add_member_to_project(
1913
self,
2014
project_and_group_name,

‎gitlabform/gitlab/tags.py‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,6 @@ def get_tags(self, project_and_group_name):
77
"projects/%s/repository/tags", project_and_group_name
88
)
99

10-
def create_tag(self, project_and_group_name, tag_name, ref, message=None):
11-
data = {
12-
"tag_name": tag_name,
13-
"ref": ref,
14-
"message": message,
15-
}
16-
return self._make_requests_to_api(
17-
"projects/%s/repository/tags",
18-
project_and_group_name,
19-
method="POST",
20-
data=data,
21-
expected_codes=201,
22-
)
23-
2410
def delete_tag(self, project_and_group_name, tag_name):
2511
self._make_requests_to_api(
2612
"projects/%s/repository/tags/%s",

‎gitlabform/gitlab/users.py‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,3 @@ def get_user_by_name(self, username, user_id=None):
1717
if not user_id:
1818
user_id = self._get_user_id(username)
1919
return self._make_requests_to_api("users/%s", str(user_id), "GET")
20-
21-
def delete_user(self, username, user_id=None):
22-
if not user_id:
23-
user_id = self._get_user_id(username)
24-
# 404 means that the user does not exist anymore, so let's accept it for idempotency
25-
return self._make_requests_to_api(
26-
"users/%s", str(user_id), method="DELETE", expected_codes=[204, 404]
27-
)

‎setup.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def get_version_file_path():
6060
extras_require={
6161
"test": [
6262
"pytest==7.2.0",
63+
"python-gitlab==3.11.0",
6364
"xkcdpass==1.19.3",
6465
"pre-commit==2.20.0", # not really for tests, but for development
6566
"coverage==6.5.0",

‎tests/acceptance/__init__.py‎

Lines changed: 118 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import os
22
import textwrap
3+
from contextlib import contextmanager
4+
from typing import Union, TYPE_CHECKING
35

6+
import gitlab
7+
from gitlab.v4.objects import Group, Project
48
from xkcdpass import xkcd_password as xp
59

610
from gitlabform import GitLabForm
7-
from gitlabform.gitlab import GitLab, AccessLevel
8-
from gitlabform.gitlab.core import NotFoundException, UnexpectedResponseException
911

1012
CONFIG = """
1113
config_version: 3
@@ -38,7 +40,25 @@
3840
else:
3941
print(f"{file_path} doesn't exist.")
4042

41-
gl = GitLab(config_string=CONFIG)
43+
gl = gitlab.Gitlab(
44+
os.getenv("GITLAB_URL"), private_token=os.getenv("GITLAB_TOKEN"), per_page=100
45+
)
46+
47+
48+
@contextmanager
49+
def allowed_codes(codes: Union[int, list[int]]):
50+
"""
51+
A context manager that allows failures on specific response status codes
52+
when gitlab.Gitlab objects.
53+
"""
54+
if isinstance(codes, int):
55+
codes = [codes]
56+
57+
try:
58+
yield
59+
except gitlab.GitlabOperationError as e:
60+
if e.response_code not in codes:
61+
raise e
4262

4363

4464
def get_random_name(entity: str) -> str:
@@ -54,108 +74,127 @@ def get_random_suffix():
5474
return xp.generate_xkcdpassword(wordlist=my_words, numwords=1, delimiter="_")
5575

5676

57-
def get_gitlab():
58-
return gl
59-
60-
61-
def create_group(group_name, parent_id=None):
62-
gl.create_group(group_name, group_name, parent_id=parent_id, visibility="internal")
77+
def create_group(group_name, parent_id=None) -> Group:
78+
with allowed_codes(404):
79+
group = gl.groups.create(
80+
{
81+
"name": group_name,
82+
"path": group_name,
83+
"parent_id": parent_id,
84+
"visibility": "internal",
85+
}
86+
)
87+
if TYPE_CHECKING:
88+
assert isinstance(group, Group)
89+
return group
6390

6491

6592
def create_groups(group_base_name, no_of_groups):
6693
groups = []
6794
for group_no in range(1, no_of_groups + 1):
6895
group_name = group_base_name + str(group_no)
6996
try:
70-
gl.get_group_case_insensitive(group_name)
71-
except NotFoundException:
72-
gl.create_group(group_name, group_name)
73-
groups.append(group_name)
97+
group = gl.groups.get(group_name)
98+
except gitlab.GitlabGetError:
99+
group = create_group(group_name)
100+
groups.append(group)
74101
return groups
75102

76103

77104
def delete_groups(group_base_name, no_of_groups):
78105
for group_no in range(1, no_of_groups + 1):
79106
group_name = group_base_name + str(group_no)
80-
gl.delete_group(group_name)
81-
82-
83-
def create_project(group_name, project_name):
84-
group = gl.get_group(group_name)
85-
gl.create_project(
86-
project_name,
87-
project_name,
88-
group["id"],
89-
default_branch="main",
90-
wait_if_still_being_deleted=True,
107+
with allowed_codes(404):
108+
gl.groups.delete(group_name)
109+
110+
111+
def create_project(group: Group, project_name) -> Project:
112+
project = gl.projects.create(
113+
{
114+
"name": project_name,
115+
"path": project_name,
116+
"namespace_id": group.id,
117+
"default_branch": "main",
118+
}
91119
)
92120

93-
gl.add_file(
94-
f"{group_name}/{project_name}",
95-
"main",
96-
"README.md",
97-
DEFAULT_README,
98-
"Create README",
121+
project.files.create(
122+
{
123+
"branch": "main",
124+
"file_path": "README.md",
125+
"content": DEFAULT_README,
126+
"commit_message": "Create README",
127+
}
99128
)
129+
if TYPE_CHECKING:
130+
assert isinstance(project, Project)
131+
return project
100132

101133

102134
def create_users(user_base_name, no_of_users):
103135
users = []
104136
for user_no in range(1, no_of_users + 1):
105137
username = user_base_name + str(user_no)
138+
existing = gl.users.list(username=username)
106139
try:
107-
gl.get_user_by_name(username)
108-
except NotFoundException:
109-
gl.create_user(
110-
username + "@example.com", username + " Example", username, "password"
140+
user = existing[0]
141+
except IndexError:
142+
user = gl.users.create(
143+
{
144+
"username": username,
145+
"email": username + "@example.com",
146+
"name": username + " Example",
147+
"password": username + "password",
148+
}
111149
)
112-
users.append(username)
150+
users.append(user)
113151
return users
114152

115153

116-
def delete_users(user_base_name, no_of_users):
117-
for user_no in range(1, no_of_users + 1):
118-
username = user_base_name + str(user_no)
119-
gl.delete_user(username)
154+
def get_only_branch_access_levels(project: Project, branch):
155+
protected_branch = None
120156

157+
with allowed_codes(404):
158+
protected_branch = project.protectedbranches.get(branch)
121159

122-
def remove_users_from_project(user_base_name, no_of_users, project_and_group):
123-
for user_no in range(1, no_of_users + 1):
124-
username = user_base_name + str(user_no)
125-
gl.remove_member_from_project(project_and_group, username)
160+
if not protected_branch:
161+
return None, None, None, None, None
126162

163+
push_access_levels = set()
164+
merge_access_levels = set()
165+
push_access_user_ids = set()
166+
merge_access_user_ids = set()
167+
unprotect_access_level = None
127168

128-
def add_users_to_group(group_name, usernames, access_level=AccessLevel.DEVELOPER.value):
129-
for username in usernames:
130-
try:
131-
gl.add_member_to_group(group_name, username, access_level)
132-
except UnexpectedResponseException:
133-
# this is fine - user is already in the group
134-
pass
135-
136-
137-
def remove_users_from_group(group_name, usernames):
138-
for username in usernames:
139-
try:
140-
gl.remove_member_from_group(group_name, username)
141-
except NotFoundException:
142-
# this is fine - user is removed from group
143-
pass
144-
145-
146-
def delete_variables_from_group(group_name, variables):
147-
for variable in variables:
148-
try:
149-
gl.delete_group_variable(group_name, variable)
150-
except NotFoundException:
151-
# this is fine - variable is removed from group
152-
pass
153-
169+
if "push_access_levels" in protected_branch.attributes:
170+
for push_access in protected_branch.push_access_levels:
171+
if not push_access["user_id"]:
172+
push_access_levels.add(push_access["access_level"])
173+
else:
174+
push_access_user_ids.add(push_access["user_id"])
154175

155-
def delete_pipeline_schedules_from_project(project_and_group):
156-
schedules = gl.get_all_pipeline_schedules(project_and_group)
157-
for schedule in schedules:
158-
gl.delete_pipeline_schedule(project_and_group, schedule["id"])
176+
if "merge_access_levels" in protected_branch.attributes:
177+
for merge_access in protected_branch.merge_access_levels:
178+
if not merge_access["user_id"]:
179+
merge_access_levels.add(merge_access["access_level"])
180+
else:
181+
merge_access_user_ids.add(merge_access["user_id"])
182+
183+
if (
184+
"unprotect_access_levels" in protected_branch.attributes
185+
and len(protected_branch.unprotect_access_levels) == 1
186+
):
187+
unprotect_access_level = protected_branch.unprotect_access_levels[0][
188+
"access_level"
189+
]
190+
191+
return (
192+
sorted(push_access_levels),
193+
sorted(merge_access_levels),
194+
sorted(push_access_user_ids),
195+
sorted(merge_access_user_ids),
196+
unprotect_access_level,
197+
)
159198

160199

161200
def run_gitlabform(config, target, include_archived_projects=True):
@@ -165,6 +204,12 @@ def run_gitlabform(config, target, include_archived_projects=True):
165204
# we don't want to repeat ourselves in the tests, so prefix the configs with this mandatory part here
166205
config = CONFIG + config
167206

207+
# allow passing in gitlab RESTObjects. assume full path string otherwise
208+
if isinstance(target, Group):
209+
target = target.full_path
210+
elif isinstance(target, Project):
211+
target = target.path_with_namespace
212+
168213
gf = GitLabForm(
169214
include_archived_projects=include_archived_projects,
170215
config_string=config,

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL