@@ -72,17 +72,13 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
72
72
if helpers .get_gitlab_plan (gl ):
73
73
logging .info ("GitLab EE detected" )
74
74
# NOTE(jlvillal, timknight): By default in GitLab EE it will wait 7 days before
75
- # deleting a group.
76
- # In GL 16.0 we need to call delete twice to immediately delete rather than toggle
77
- # a setting for it.
78
- # https://docs.gitlab.com/ee/user/project/working_with_projects.html#delete-a-project-immediately
75
+ # deleting a group or project.
76
+ # In GL 16.0 we need to call delete with `permanently_remove=True` for projects and sub groups
77
+ # (handled in helpers.py safe_delete)
79
78
settings = gl .settings .get ()
80
79
modified_settings = False
81
80
if settings .deletion_adjourned_period != 1 :
82
81
logging .info ("Setting `deletion_adjourned_period` to 1 Day" )
83
- logging .info (
84
- "To perform immediate deletion in GL 16+, call delete again on the project or group"
85
- )
86
82
settings .deletion_adjourned_period = 1
87
83
modified_settings = True
88
84
if modified_settings :
@@ -125,7 +121,7 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
125
121
for user in gl .users .list ():
126
122
if user .username not in ["root" , "ghost" ]:
127
123
logging .info (f"Deleting user: { user .username !r} " )
128
- helpers .safe_delete (user , hard_delete = True )
124
+ helpers .safe_delete (user )
129
125
130
126
131
127
def set_token (container : str , fixture_dir : pathlib .Path ) -> str :
@@ -215,21 +211,32 @@ def _check(
215
211
@pytest .fixture
216
212
def wait_for_sidekiq (gl ):
217
213
"""
218
- Return a helper function to wait until there are no busy sidekiq processes.
214
+ Return a helper function to wait until there are spare sidekiq processes.
215
+
216
+ Because not all Groups can be deleted immediately in GL 16, we will likely have busy Sidekiq jobs
217
+ set aside for their deletion in 1 days time.
219
218
220
219
Use this with asserts for slow tasks (group/project/user creation/deletion).
220
+
221
+ { ..., 'labels': [], 'concurrency': 20, 'busy': 3}
221
222
"""
222
223
223
224
def _wait (timeout : int = 30 , step : float = 0.5 , allow_fail : bool = False ) -> bool :
224
225
for count in range (timeout ):
225
226
time .sleep (step )
226
- busy = False
227
227
processes = gl .sidekiq .process_metrics ()["processes" ]
228
+ busy_processes = 0
229
+ total_concurrency = 0
228
230
for process in processes :
229
- if process ["busy" ]:
230
- busy = True
231
- if not busy :
231
+ busy_processes += process ["busy" ]
232
+ total_concurrency += process ["concurrency" ]
233
+
234
+ logging .info (f"Busy processes { busy_processes } " )
235
+ # If we have space concurrency in the process, continue
236
+ if busy_processes < total_concurrency :
237
+ logging .info ("Spare sidekiq process found" )
232
238
return True
239
+
233
240
logging .info (f"sidekiq busy { count } of { timeout } " )
234
241
assert allow_fail , "sidekiq process should have terminated but did not."
235
242
return False
@@ -403,6 +410,7 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
403
410
assert result is True , "sidekiq process should have terminated but did not"
404
411
405
412
project .refresh () # Gets us the current default branch
413
+ logging .info (f"Creating branch { source_branch } " )
406
414
mr_branch = project .branches .create (
407
415
{"branch" : source_branch , "ref" : project .default_branch }
408
416
)
@@ -416,6 +424,11 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
416
424
"commit_message" : "New commit in new branch" ,
417
425
}
418
426
)
427
+
428
+ # Helps with Debugging why MRs fail to merge resulting in 405 from downstream tests
429
+ approval_rules = project .approvalrules .list ()
430
+ logging .info (f"Project MR Approval Rules { approval_rules } " )
431
+
419
432
if create_pipeline :
420
433
project .files .create (
421
434
{
@@ -431,6 +444,7 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
431
444
"commit_message" : "Add a simple pipeline" ,
432
445
}
433
446
)
447
+ logging .info (f"Creating merge request for { source_branch } " )
434
448
mr = project .mergerequests .create (
435
449
{
436
450
"source_branch" : source_branch ,
@@ -445,10 +459,19 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
445
459
mr_iid = mr .iid
446
460
for _ in range (60 ):
447
461
mr = project .mergerequests .get (mr_iid )
448
- if mr .merge_status != "checking" :
462
+ logging .info (
463
+ f"Waiting for Gitlab to update MR status: { mr .detailed_merge_status } "
464
+ )
465
+ if (
466
+ mr .detailed_merge_status == "checking"
467
+ or mr .detailed_merge_status == "unchecked"
468
+ ):
469
+ time .sleep (0.5 )
470
+ else :
449
471
break
450
- time .sleep (0.5 )
451
- assert mr .merge_status != "checking"
472
+
473
+ assert mr .detailed_merge_status != "checking"
474
+ assert mr .detailed_merge_status != "unchecked"
452
475
453
476
to_delete .extend ([mr , mr_branch ])
454
477
return mr
@@ -532,8 +555,7 @@ def user(gl):
532
555
533
556
yield user
534
557
535
- # Use `hard_delete=True` or a 'Ghost User' may be created.
536
- helpers .safe_delete (user , hard_delete = True )
558
+ helpers .safe_delete (user )
537
559
538
560
539
561
@pytest .fixture (scope = "module" )
0 commit comments