1+ import logging
12import tempfile
23import time
34import uuid
1011import gitlab .base
1112
1213SLEEP_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" )
1718def 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: { elapsed_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
@@ -163,9 +230,11 @@ def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, fixture_
163230 config_file = temp_dir / "python-gitlab.cfg"
164231 port = docker_services .port_for ("gitlab" , 80 )
165232
233+ logging .info ("Waiting for GitLab container to become ready." )
166234 docker_services .wait_until_responsive (
167235 timeout = 200 , pause = 5 , check = lambda : check_is_alive ("gitlab-test" )
168236 )
237+ logging .info ("GitLab container is now ready." )
169238
170239 token = set_token ("gitlab-test" , fixture_dir = fixture_dir )
171240
@@ -188,8 +257,10 @@ def gitlab_config(check_is_alive, docker_ip, docker_services, temp_dir, fixture_
188257def gl (gitlab_config ):
189258 """Helper instance to make fixtures and asserts directly via the API."""
190259
260+ logging .info ("Create python-gitlab gitlab.Gitlab object" )
191261 instance = gitlab .Gitlab .from_config ("local" , [gitlab_config ])
192- reset_gitlab (instance )
262+
263+ reset_gitlab (gl = instance )
193264
194265 return instance
195266
0 commit comments