Skip to content

Commit ea4c50d

Browse files
wip: make reset_gitlab() better
1 parent f26bf7d commit ea4c50d

File tree

1 file changed

+80
-11
lines changed

1 file changed

+80
-11
lines changed

tests/functional/conftest.py

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import tempfile
23
import time
34
import uuid
@@ -10,54 +11,119 @@
1011
import gitlab.base
1112

1213
SLEEP_INTERVAL = 0.1
13-
TIMEOUT = 60 # seconds before timeout will occur
14+
TIMEOUT = 3 * 60 # seconds before timeout will occur
1415

1516

1617
@pytest.fixture(scope="session")
1718
def fixture_dir(test_dir):
1819
return test_dir / "functional" / "fixtures"
1920

2021

21-
def reset_gitlab(gl):
22-
# previously tools/reset_gitlab.py
22+
def reset_gitlab(gl: gitlab.Gitlab) -> None:
23+
# Mark our resources for deletion. It takes time for them to actually be deleted
24+
# though.
25+
_reset_gitlab_delete_resources(gl=gl)
26+
27+
# Wait for all resources to be deleted
28+
_reset_gitlab_wait_deletion_finish(gl=gl)
29+
30+
31+
def _reset_gitlab_delete_resources(gl: gitlab.Gitlab) -> None:
32+
"""Mark for deletion, resources (such as projects, groups, users) that shouldn't
33+
exist. Once marked they will still take time to be deleted."""
2334
for project in gl.projects.list():
35+
logging.info(f"Mark for deletion project: {project.name!r}")
2436
for deploy_token in project.deploytokens.list():
37+
logging.info(
38+
f"Mark for deletion token: {deploy_token.name!r} in "
39+
f"project: {project.name!r}"
40+
)
2541
deploy_token.delete()
2642
project.delete()
2743
for group in gl.groups.list():
44+
logging.info(f"Mark for deletion group: {group.name!r}")
2845
for deploy_token in group.deploytokens.list():
46+
logging.info(
47+
f"Mark for deletion token: {deploy_token.name!r} in "
48+
f"group: {group.name!r}"
49+
)
2950
deploy_token.delete()
3051
group.delete()
3152
for variable in gl.variables.list():
53+
logging.info(f"Mark for deletion variable: {variable.name!r}")
3254
variable.delete()
3355
for user in gl.users.list():
3456
if user.username != "root":
57+
logging.info(f"Mark for deletion user: {user.username!r}")
3558
user.delete(hard_delete=True)
3659

60+
61+
def _reset_gitlab_wait_deletion_finish(gl: gitlab.Gitlab) -> None:
62+
"""Wait for all of our resources to be deleted.
63+
64+
If anything exists then mark it again for deletion in case initial call to delete
65+
didn't work, which has been seen :("""
66+
3767
max_iterations = int(TIMEOUT / SLEEP_INTERVAL)
3868

3969
# Ensure everything has been reset
4070
start_time = time.perf_counter()
4171

4272
def wait_for_maximum_list_length(
43-
rest_manager: gitlab.base.RESTManager, description: str, max_length: int = 0
73+
rest_manager: gitlab.base.RESTManager,
74+
description: str,
75+
max_length: int = 0,
76+
should_delete_func=lambda x: True,
77+
delete_kwargs={},
4478
) -> None:
4579
"""Wait for the list() length to be no greater than expected maximum or fail
4680
test if timeout is exceeded"""
47-
for _ in range(max_iterations):
48-
if len(rest_manager.list()) <= max_length:
81+
for count in range(max_iterations):
82+
items = rest_manager.list()
83+
logging.info(
84+
f"Iteration: {count}: items in {description}: {[x.name for x in items]}"
85+
)
86+
for item in items:
87+
if should_delete_func(item):
88+
logging.info(
89+
f"Marking again for deletion {description}: {item.name!r}"
90+
)
91+
try:
92+
item.delete(**delete_kwargs)
93+
except gitlab.exceptions.GitlabDeleteError as exc:
94+
logging.info(
95+
f"Already marked for deletion: {item.name!r} {exc}"
96+
)
97+
if len(items) <= max_length:
4998
break
5099
time.sleep(SLEEP_INTERVAL)
51-
assert len(rest_manager.list()) <= max_length, (
100+
items = rest_manager.list()
101+
elapsed_time = time.perf_counter() - start_time
102+
if len(items) > max_length:
103+
logging.error(
104+
f"Too many items still remaining and timeout exceeded: {elapsed_time}"
105+
)
106+
assert len(items) <= max_length, (
52107
f"Did not delete required items for {description}. "
53-
f"Elapsed_time: {time.perf_counter() - start_time}"
108+
f"Elapsed_time: {time.perf_counter() - start_time}\n"
109+
f"items: {[str(x) for x in items]!r}"
54110
)
55111

56112
wait_for_maximum_list_length(rest_manager=gl.projects, description="projects")
57113
wait_for_maximum_list_length(rest_manager=gl.groups, description="groups")
58114
wait_for_maximum_list_length(rest_manager=gl.variables, description="variables")
115+
116+
def should_delete_user(user):
117+
if user.username == "root":
118+
return False
119+
return True
120+
59121
wait_for_maximum_list_length(
60-
rest_manager=gl.users, description="users", max_length=1
122+
rest_manager=gl.users,
123+
description="users",
124+
max_length=1,
125+
should_delete_func=should_delete_user,
126+
delete_kwargs={"hard_delete": True},
61127
)
62128

63129

@@ -144,7 +210,7 @@ def wait_for_sidekiq(gl):
144210
"""
145211

146212
def _wait(timeout=30, step=0.5):
147-
for _ in range(timeout):
213+
for count in range(timeout):
148214
time.sleep(step)
149215
busy = False
150216
processes = gl.sidekiq.process_metrics()["processes"]
@@ -153,6 +219,7 @@ def _wait(timeout=30, step=0.5):
153219
busy = True
154220
if not busy:
155221
return True
222+
logging.info(f"sidekiq busy {count} of {timeout}")
156223
return False
157224

158225
return _wait
@@ -188,8 +255,10 @@ def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, fixture_
188255
def gl(gitlab_config):
189256
"""Helper instance to make fixtures and asserts directly via the API."""
190257

258+
logging.info("Create python-gitlab gitlab.Gitlab object")
191259
instance = gitlab.Gitlab.from_config("local", [gitlab_config])
192-
reset_gitlab(instance)
260+
261+
reset_gitlab(gl=instance)
193262

194263
return instance
195264

0 commit comments

Comments
 (0)