Skip to content

Commit 43e8bff

Browse files
committed
fix: update cli tests for gitlab 16.8 functionality
1 parent 5b539b4 commit 43e8bff

File tree

8 files changed

+133
-67
lines changed

8 files changed

+133
-67
lines changed

docs/cli-examples.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ CLI examples
99
CI Lint
1010
-------
1111

12+
**ci-lint has been Removed in Gitlab 16, use project-ci-lint instead**
13+
1214
Lint a CI YAML configuration from a string:
1315

14-
.. note::
16+
.. note::
1517

1618
To see output, you will need to use the ``-v``/``--verbose`` flag.
1719

@@ -39,6 +41,9 @@ Validate a CI YAML configuration from a file (lints and exits with non-zero on f
3941
4042
$ gitlab ci-lint validate --content @.gitlab-ci.yml
4143
44+
Project CI Lint
45+
---------------
46+
4247
Lint a project's CI YAML configuration:
4348

4449
.. code-block:: console

tests/functional/api/test_merge_requests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def test_merge_requests(project):
1616
}
1717
)
1818

19-
source_branch = "branch1"
19+
source_branch = "branch-merge-request-api"
2020
project.branches.create({"branch": source_branch, "ref": "main"})
2121

2222
project.files.create(
@@ -28,7 +28,7 @@ def test_merge_requests(project):
2828
}
2929
)
3030
project.mergerequests.create(
31-
{"source_branch": "branch1", "target_branch": "main", "title": "MR readme2"}
31+
{"source_branch": source_branch, "target_branch": "main", "title": "MR readme2"}
3232
)
3333

3434

tests/functional/cli/test_cli_repository.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import logging
23
import time
34

45

@@ -31,9 +32,13 @@ def test_list_all_commits(gitlab_cli, project):
3132
data = {
3233
"branch": "new-branch",
3334
"start_branch": "main",
34-
"commit_message": "New commit on new branch",
35+
"commit_message": "chore: test commit on new branch",
3536
"actions": [
36-
{"action": "create", "file_path": "new-file", "content": "new content"}
37+
{
38+
"action": "create",
39+
"file_path": "test-cli-repo.md",
40+
"content": "new content",
41+
}
3742
],
3843
}
3944
commit = project.commits.create(data)
@@ -76,6 +81,19 @@ def test_commit_merge_requests(gitlab_cli, project, merge_request, wait_for_side
7681
"""This tests the `project-commit merge-requests` command and also tests
7782
that we can print the result using the `json` formatter"""
7883
# Merge the MR first
84+
wait_for_sidekiq(timeout=60)
85+
86+
logging.info(f"MR status: {merge_request.state}")
87+
logging.info(f"MR merge status: {merge_request.detailed_merge_status}")
88+
89+
if merge_request.detailed_merge_status == "not_approved":
90+
logging.info("Approving Merge Request")
91+
92+
merge_request.approve()
93+
94+
logging.info(f"MR merge status: {merge_request.detailed_merge_status}")
95+
time.sleep(5)
96+
7997
merge_result = merge_request.merge(should_remove_source_branch=True)
8098
wait_for_sidekiq(timeout=60)
8199

tests/functional/cli/test_cli_resource_access_tokens.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import pytest
1+
from datetime import date
22

33

44
def test_list_project_access_tokens(gitlab_cli, project):
@@ -18,13 +18,14 @@ def test_create_project_access_token_with_scopes(gitlab_cli, project):
1818
"test-token",
1919
"--scopes",
2020
"api,read_repository",
21+
"--expires-at",
22+
date.today().isoformat(),
2123
]
2224
ret = gitlab_cli(cmd)
2325

2426
assert ret.success
2527

2628

27-
@pytest.mark.skip(reason="Requires GitLab 14.7")
2829
def test_list_group_access_tokens(gitlab_cli, group):
2930
cmd = ["group-access-token", "list", "--group-id", group.id]
3031
ret = gitlab_cli(cmd)
@@ -42,6 +43,8 @@ def test_create_group_access_token_with_scopes(gitlab_cli, group):
4243
"test-token",
4344
"--scopes",
4445
"api,read_repository",
46+
"--expires-at",
47+
date.today().isoformat(),
4548
]
4649
ret = gitlab_cli(cmd)
4750

tests/functional/cli/test_cli_users.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from datetime import date
2+
3+
14
def test_create_user_impersonation_token_with_scopes(gitlab_cli, user):
25
cmd = [
36
"user-impersonation-token",
@@ -8,6 +11,8 @@ def test_create_user_impersonation_token_with_scopes(gitlab_cli, user):
811
"test-token",
912
"--scopes",
1013
"api,read_user",
14+
"--expires-at",
15+
date.today().isoformat(),
1116
]
1217
ret = gitlab_cli(cmd)
1318

tests/functional/cli/test_cli_v4.py

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import logging
12
import os
23
import time
34
from datetime import date
45

6+
branch = "branch-cli-v4"
7+
58

69
def test_create_project(gitlab_cli):
710
name = "test-project1"
@@ -23,28 +26,6 @@ def test_update_project(gitlab_cli, project):
2326
assert description in ret.stdout
2427

2528

26-
def test_create_ci_lint(gitlab_cli, valid_gitlab_ci_yml):
27-
cmd = ["ci-lint", "create", "--content", valid_gitlab_ci_yml]
28-
ret = gitlab_cli(cmd)
29-
30-
assert ret.success
31-
32-
33-
def test_validate_ci_lint(gitlab_cli, valid_gitlab_ci_yml):
34-
cmd = ["ci-lint", "validate", "--content", valid_gitlab_ci_yml]
35-
ret = gitlab_cli(cmd)
36-
37-
assert ret.success
38-
39-
40-
def test_validate_ci_lint_invalid_exits_non_zero(gitlab_cli, invalid_gitlab_ci_yml):
41-
cmd = ["ci-lint", "validate", "--content", invalid_gitlab_ci_yml]
42-
ret = gitlab_cli(cmd)
43-
44-
assert not ret.success
45-
assert "CI YAML Lint failed (Invalid configuration format)" in ret.stderr
46-
47-
4829
def test_validate_project_ci_lint(gitlab_cli, project, valid_gitlab_ci_yml):
4930
cmd = [
5031
"project-ci-lint",
@@ -216,8 +197,6 @@ def test_create_issue_note(gitlab_cli, issue):
216197

217198

218199
def test_create_branch(gitlab_cli, project):
219-
branch = "branch1"
220-
221200
cmd = [
222201
"project-branch",
223202
"create",
@@ -234,7 +213,6 @@ def test_create_branch(gitlab_cli, project):
234213

235214

236215
def test_create_merge_request(gitlab_cli, project):
237-
branch = "branch1"
238216

239217
cmd = [
240218
"project-merge-request",
@@ -258,23 +236,43 @@ def test_accept_request_merge(gitlab_cli, project, wait_for_sidekiq):
258236
mr = project.mergerequests.list()[0]
259237
file_data = {
260238
"branch": mr.source_branch,
261-
"file_path": "README2",
239+
"file_path": "test-cli-v4.md",
262240
"content": "Content",
263-
"commit_message": "Pre-merge commit",
241+
"commit_message": "chore: test-cli-v4 change",
264242
}
265243
project.files.create(file_data)
266-
time.sleep(2)
244+
time.sleep(30)
267245
wait_for_sidekiq(timeout=60)
268246

269-
cmd = [
247+
logging.info(f"MR status: {mr.state}")
248+
logging.info(f"MR merge status: {mr.detailed_merge_status}")
249+
250+
if mr.detailed_merge_status == "not_approved":
251+
logging.info("Approving Merge Request")
252+
253+
approve_cmd = [
254+
"project-merge-request",
255+
"approve",
256+
"--project-id",
257+
project.id,
258+
"--iid",
259+
mr.iid,
260+
]
261+
gitlab_cli(approve_cmd)
262+
263+
time.sleep(5)
264+
logging.info(f"MR merge status: {mr.detailed_merge_status}")
265+
266+
time.sleep(0.5)
267+
approve_cmd = [
270268
"project-merge-request",
271269
"merge",
272270
"--project-id",
273271
project.id,
274272
"--iid",
275273
mr.iid,
276274
]
277-
ret = gitlab_cli(cmd)
275+
ret = gitlab_cli(approve_cmd)
278276

279277
assert ret.success
280278

@@ -502,9 +500,6 @@ def test_delete_project_variable(gitlab_cli, variable):
502500

503501

504502
def test_delete_branch(gitlab_cli, project):
505-
# TODO: branch fixture
506-
branch = "branch1"
507-
508503
cmd = ["project-branch", "delete", "--project-id", project.id, "--name", branch]
509504
ret = gitlab_cli(cmd)
510505

@@ -591,7 +586,7 @@ def test_create_project_with_values_at_prefixed(gitlab_cli, tmpdir):
591586
def test_create_project_deploy_token(gitlab_cli, project):
592587
name = "project-token"
593588
username = "root"
594-
expires_at = (date.today().isoformat(),)
589+
expires_at = date.today().isoformat()
595590
scopes = "read_registry"
596591

597592
cmd = [
@@ -667,7 +662,7 @@ def test_delete_project_deploy_token(gitlab_cli, deploy_token):
667662
def test_create_group_deploy_token(gitlab_cli, group):
668663
name = "group-token"
669664
username = "root"
670-
expires_at = (date.today().isoformat(),)
665+
expires_at = date.today().isoformat()
671666
scopes = "read_registry"
672667

673668
cmd = [

tests/functional/conftest.py

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,13 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
7272
if helpers.get_gitlab_plan(gl):
7373
logging.info("GitLab EE detected")
7474
# 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)
7978
settings = gl.settings.get()
8079
modified_settings = False
8180
if settings.deletion_adjourned_period != 1:
8281
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-
)
8682
settings.deletion_adjourned_period = 1
8783
modified_settings = True
8884
if modified_settings:
@@ -125,7 +121,7 @@ def reset_gitlab(gl: gitlab.Gitlab) -> None:
125121
for user in gl.users.list():
126122
if user.username not in ["root", "ghost"]:
127123
logging.info(f"Deleting user: {user.username!r}")
128-
helpers.safe_delete(user, hard_delete=True)
124+
helpers.safe_delete(user)
129125

130126

131127
def set_token(container: str, fixture_dir: pathlib.Path) -> str:
@@ -215,21 +211,32 @@ def _check(
215211
@pytest.fixture
216212
def wait_for_sidekiq(gl):
217213
"""
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.
219218
220219
Use this with asserts for slow tasks (group/project/user creation/deletion).
220+
221+
{ ..., 'labels': [], 'concurrency': 20, 'busy': 3}
221222
"""
222223

223224
def _wait(timeout: int = 30, step: float = 0.5, allow_fail: bool = False) -> bool:
224225
for count in range(timeout):
225226
time.sleep(step)
226-
busy = False
227227
processes = gl.sidekiq.process_metrics()["processes"]
228+
busy_processes = 0
229+
total_concurrency = 0
228230
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")
232238
return True
239+
233240
logging.info(f"sidekiq busy {count} of {timeout}")
234241
assert allow_fail, "sidekiq process should have terminated but did not."
235242
return False
@@ -403,6 +410,7 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
403410
assert result is True, "sidekiq process should have terminated but did not"
404411

405412
project.refresh() # Gets us the current default branch
413+
logging.info(f"Creating branch {source_branch}")
406414
mr_branch = project.branches.create(
407415
{"branch": source_branch, "ref": project.default_branch}
408416
)
@@ -416,6 +424,11 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
416424
"commit_message": "New commit in new branch",
417425
}
418426
)
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+
419432
if create_pipeline:
420433
project.files.create(
421434
{
@@ -431,6 +444,7 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
431444
"commit_message": "Add a simple pipeline",
432445
}
433446
)
447+
logging.info(f"Creating merge request for {source_branch}")
434448
mr = project.mergerequests.create(
435449
{
436450
"source_branch": source_branch,
@@ -445,10 +459,19 @@ def _make_merge_request(*, source_branch: str, create_pipeline: bool = False):
445459
mr_iid = mr.iid
446460
for _ in range(60):
447461
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:
449471
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"
452475

453476
to_delete.extend([mr, mr_branch])
454477
return mr
@@ -532,8 +555,7 @@ def user(gl):
532555

533556
yield user
534557

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)
537559

538560

539561
@pytest.fixture(scope="module")

0 commit comments

Comments
 (0)