forked from git-workflow/autogits
Also address potential race condition between requested reviews and sending approvals in TC-MERGE-002
327 lines
14 KiB
Python
Executable File
327 lines
14 KiB
Python
Executable File
import pytest
|
|
import re
|
|
import time
|
|
import subprocess
|
|
import requests
|
|
from pathlib import Path
|
|
from tests.lib.common_test_utils import (
|
|
GiteaAPIClient,
|
|
)
|
|
|
|
# =============================================================================
|
|
# TEST CASES
|
|
# =============================================================================
|
|
|
|
pytest.pr = None
|
|
pytest.pr_details = None
|
|
pytest.initial_pr_number = None
|
|
pytest.forwarded_pr_number = None
|
|
|
|
|
|
@pytest.mark.t001
|
|
@pytest.mark.dependency()
|
|
def test_001_project_pr(gitea_env):
|
|
"""Forwarded PR correct title"""
|
|
diff = "diff --git a/another_test.txt b/another_test.txt\nnew file mode 100644\nindex 0000000..e69de29\n"
|
|
pytest.pr = gitea_env.create_gitea_pr("mypool/pkgA", diff, "Test PR", False)
|
|
pytest.initial_pr_number = pytest.pr["number"]
|
|
time.sleep(5) # Give Gitea some time to process the PR and make the timeline available
|
|
|
|
compose_dir = Path(__file__).parent.parent
|
|
|
|
pytest.forwarded_pr_number = None
|
|
print(
|
|
f"Polling mypool/pkgA PR #{pytest.initial_pr_number} timeline for forwarded PR event..."
|
|
)
|
|
# Instead of polling timeline, check if forwarded PR exists directly
|
|
for _ in range(20):
|
|
time.sleep(1)
|
|
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", pytest.initial_pr_number)
|
|
for event in timeline_events:
|
|
if event.get("type") == "pull_ref":
|
|
if not (ref_issue := event.get("ref_issue")):
|
|
continue
|
|
url_to_check = ref_issue.get("html_url", "")
|
|
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
|
if match:
|
|
pytest.forwarded_pr_number = match.group(1)
|
|
break
|
|
if pytest.forwarded_pr_number:
|
|
break
|
|
assert (
|
|
pytest.forwarded_pr_number is not None
|
|
), "Workflow bot did not create a forwarded PR."
|
|
pytest.pr_details = gitea_env.get_pr_details("myproducts/mySLFO", pytest.forwarded_pr_number)
|
|
assert (
|
|
pytest.pr_details["title"] == "Forwarded PRs: pkgA"
|
|
), "Forwarded PR correct title"
|
|
|
|
|
|
@pytest.mark.t002
|
|
@pytest.mark.dependency(depends=["test_001_project_pr"])
|
|
def test_002_updated_project_pr(gitea_env):
|
|
"""Forwarded PR head is updated"""
|
|
diff = "diff --git a/another_test.txt b/another_test.txt\nnew file mode 100444\nindex 0000000..e69de21\n"
|
|
gitea_env.modify_gitea_pr("mypool/pkgA", pytest.initial_pr_number, diff, "Tweaks")
|
|
sha_old = pytest.pr_details["head"]["sha"]
|
|
|
|
sha_changed = False
|
|
for _ in range(20):
|
|
time.sleep(1)
|
|
new_pr_details = gitea_env.get_pr_details("myproducts/mySLFO", pytest.forwarded_pr_number)
|
|
sha_new = new_pr_details["head"]["sha"]
|
|
if sha_new != sha_old:
|
|
print(f"Sha changed from {sha_old} to {sha_new}")
|
|
sha_changed = True
|
|
break
|
|
|
|
assert sha_changed, "Forwarded PR has sha updated"
|
|
|
|
|
|
@pytest.mark.t003
|
|
@pytest.mark.dependency(depends=["test_001_project_pr"])
|
|
def test_003_wip(gitea_env):
|
|
"""WIP flag set for PR"""
|
|
# 1. set WIP flag in PR f"mypool/pkgA#{pytest.initial_pr_number}"
|
|
initial_pr_details = gitea_env.get_pr_details("mypool/pkgA", pytest.initial_pr_number)
|
|
wip_title = "WIP: " + initial_pr_details["title"]
|
|
|
|
gitea_env.update_gitea_pr_properties("mypool/pkgA", pytest.initial_pr_number, title=wip_title)
|
|
# 2. in loop check whether WIP flag is set for PR f"myproducts/mySLFO #{pytest.forwarded_pr_number}"
|
|
wip_flag_set = False
|
|
for _ in range(20):
|
|
time.sleep(1)
|
|
forwarded_pr_details = gitea_env.get_pr_details(
|
|
"myproducts/mySLFO", pytest.forwarded_pr_number
|
|
)
|
|
if "WIP: " in forwarded_pr_details["title"]:
|
|
wip_flag_set = True
|
|
break
|
|
|
|
assert wip_flag_set, "WIP flag was not set in the forwarded PR."
|
|
|
|
# Remove WIP flag from PR f"mypool/pkgA#{pytest.initial_pr_number}"
|
|
initial_pr_details = gitea_env.get_pr_details("mypool/pkgA", pytest.initial_pr_number)
|
|
non_wip_title = initial_pr_details["title"].replace("WIP: ", "")
|
|
gitea_env.update_gitea_pr_properties(
|
|
"mypool/pkgA", pytest.initial_pr_number, title=non_wip_title
|
|
)
|
|
|
|
# In loop check whether WIP flag is removed for PR f"myproducts/mySLFO #{pytest.forwarded_pr_number}"
|
|
wip_flag_removed = False
|
|
for _ in range(20):
|
|
time.sleep(1)
|
|
forwarded_pr_details = gitea_env.get_pr_details(
|
|
"myproducts/mySLFO", pytest.forwarded_pr_number
|
|
)
|
|
if "WIP: " not in forwarded_pr_details["title"]:
|
|
wip_flag_removed = True
|
|
break
|
|
assert wip_flag_removed, "WIP flag was not removed from the forwarded PR."
|
|
|
|
|
|
@pytest.mark.t005
|
|
@pytest.mark.skip(reason="works only in ibs_state branch?")
|
|
@pytest.mark.dependency()
|
|
def test_005_NoProjectGitPR_edits_disabled(no_project_git_pr_env, test_user_client):
|
|
"""
|
|
Reworked test: Sets workflow.config with NoProjectGitPR: true and creates a Package PR.
|
|
Verifies that no Project PR is created, then manually creates one and checks for bot warning.
|
|
"""
|
|
gitea_env, test_full_repo_name, dev_branch_name = no_project_git_pr_env
|
|
|
|
# 1. Create a Package PR (without "Allow edits from maintainers" enabled)
|
|
initial_diff = """diff --git a/first_file.txt b/first_file.txt
|
|
new file mode 100644
|
|
index 0000000..e69de29
|
|
--- /dev/null
|
|
+++ b/first_file.txt
|
|
@@ -0,0 +1 @@
|
|
+Initial content
|
|
"""
|
|
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", initial_diff, "Test PR for No Project PR, No Edits", False, base_branch=dev_branch_name)
|
|
package_pr_number = package_pr["number"]
|
|
print(f"Created Package PR #{package_pr_number}")
|
|
|
|
# 2. Verify that the workflow-pr bot did not create a Project PR
|
|
project_pr_created = False
|
|
for i in range(10): # Poll for some time
|
|
time.sleep(2)
|
|
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
|
for event in timeline_events:
|
|
if event.get("type") == "pull_ref":
|
|
if not (ref_issue := event.get("ref_issue")):
|
|
continue
|
|
url_to_check = ref_issue.get("html_url", "")
|
|
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
|
if match:
|
|
project_pr_created = True
|
|
break
|
|
if project_pr_created:
|
|
break
|
|
|
|
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in myproducts/mySLFO."
|
|
print("Verification complete: No Project PR was created by the bot.")
|
|
|
|
# 3. Manually create the Project PR
|
|
pkgA_main_sha = gitea_env._request("GET", f"repos/mypool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
|
package_pr_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
|
pkgA_pr_head_sha = package_pr_details["head"]["sha"]
|
|
|
|
project_pr_title = "Forwarded PRs: pkgA (Manual)"
|
|
project_pr_body = f"Manual Project PR for NoProjectGitPR. \nPR: mypool/pkgA!{package_pr_number}"
|
|
project_pr_diff = f"""diff --git a/pkgA b/pkgA
|
|
index {pkgA_main_sha[:7]}..{pkgA_pr_head_sha[:7]} 160000
|
|
--- a/pkgA
|
|
+++ b/pkgA
|
|
@@ -1 +1 @@
|
|
-Subproject commit {pkgA_main_sha}
|
|
+Subproject commit {pkgA_pr_head_sha}
|
|
"""
|
|
manual_project_pr = test_user_client.create_gitea_pr(test_full_repo_name, project_pr_diff, project_pr_title, True, base_branch=dev_branch_name, body=project_pr_body)
|
|
manual_project_pr_number = manual_project_pr["number"]
|
|
|
|
# Verify and set allow_maintainer_edit to False
|
|
test_user_client.update_gitea_pr_properties(test_full_repo_name, manual_project_pr_number, allow_maintainer_edit=False)
|
|
|
|
# Verify that allow_maintainer_edit is now disabled
|
|
updated_pr = gitea_env.get_pr_details(test_full_repo_name, manual_project_pr_number)
|
|
assert updated_pr.get("allow_maintainer_edit") is False, "Expected allow_maintainer_edit to be False after update"
|
|
|
|
print(f"Manually created Project PR #{manual_project_pr_number} in {test_full_repo_name}")
|
|
|
|
# 4. Trigger an update on the Package PR to prompt the bot to react to the manual Project PR
|
|
new_diff_content = """diff --git a/trigger_bot.txt b/trigger_bot.txt
|
|
new file mode 100644
|
|
index 0000000..e69de29
|
|
--- /dev/null
|
|
+++ b/trigger_bot.txt
|
|
@@ -0,0 +1 @@
|
|
+Trigger content
|
|
"""
|
|
test_user_client.modify_gitea_pr("mypool/pkgA", package_pr_number, new_diff_content, "Trigger bot update")
|
|
|
|
# 5. Verify that the bot adds a warning comment because it cannot update the manual PR (edits disabled)
|
|
warning_found = False
|
|
print(f"Polling Package PR #{package_pr_number} for warning comment...")
|
|
for _ in range(20):
|
|
time.sleep(3)
|
|
comments = gitea_env.get_comments("mypool/pkgA", package_pr_number)
|
|
for comment in comments:
|
|
# According to test-plan.md, the warning explains that it cannot update the PR.
|
|
if "cannot update" in comment.get("body", "").lower():
|
|
warning_found = True
|
|
print(f"Warning comment found: {comment.get('body')}")
|
|
break
|
|
if warning_found:
|
|
break
|
|
|
|
# assert warning_found, "Bot did not post the expected warning comment on the Package PR."
|
|
# print("Verification complete: Bot posted a warning comment as expected.")
|
|
|
|
|
|
@pytest.mark.t006
|
|
@pytest.mark.skip(reason="works only in ibs_state branch?")
|
|
@pytest.mark.dependency()
|
|
def test_006_NoProjectGitPR_edits_enabled(no_project_git_pr_env, test_user_client):
|
|
"""
|
|
Verify that no project PR is created when "NoProjectGitPR" is true
|
|
and "Allow edits from maintainers" is enabled, using a dev branch.
|
|
"""
|
|
gitea_env, test_full_repo_name, dev_branch_name = no_project_git_pr_env
|
|
|
|
# 2. Create a Package PR with "Allow edits from maintainers" enabled
|
|
diff = """diff --git a/new_feature.txt b/new_feature.txt
|
|
new file mode 100644
|
|
index 0000000..e69de29
|
|
--- /dev/null
|
|
+++ b/new_feature.txt
|
|
@@ -0,0 +1 @@
|
|
+New feature content
|
|
"""
|
|
package_pr = test_user_client.create_gitea_pr("mypool/pkgA", diff, "Test PR for NoProjectGitPR", False, base_branch=dev_branch_name)
|
|
package_pr_number = package_pr["number"]
|
|
|
|
# Enable "Allow edits from maintainers"
|
|
test_user_client.update_gitea_pr_properties("mypool/pkgA", package_pr_number, allow_maintainer_edit=True)
|
|
print(f"Created Package PR #{package_pr_number} and enabled 'Allow edits from maintainers'.")
|
|
|
|
# Get SHAs needed for the manual Project PR diff
|
|
pkgA_main_sha = gitea_env._request("GET", f"repos/mypool/pkgA/branches/{dev_branch_name}").json()["commit"]["id"]
|
|
package_pr_details = gitea_env.get_pr_details("mypool/pkgA", package_pr_number)
|
|
pkgA_pr_head_sha = package_pr_details["head"]["sha"]
|
|
|
|
# 3. Assert that the workflow-pr bot did not create a Project PR in the myproducts/mySLFO repository
|
|
project_pr_created = False
|
|
for i in range(20): # Poll for a reasonable time
|
|
time.sleep(2) # Wait a bit longer to be sure
|
|
timeline_events = gitea_env.get_timeline_events("mypool/pkgA", package_pr_number)
|
|
for event in timeline_events:
|
|
if event.get("type") == "pull_ref":
|
|
if not (ref_issue := event.get("ref_issue")):
|
|
continue
|
|
url_to_check = ref_issue.get("html_url", "")
|
|
# Regex now searches for myproducts/mySLFO/pulls/(\d+)
|
|
match = re.search(r"myproducts/mySLFO/pulls/(\d+)", url_to_check)
|
|
if match:
|
|
project_pr_created = True
|
|
break
|
|
if project_pr_created:
|
|
break
|
|
|
|
assert not project_pr_created, "Workflow bot unexpectedly created a Project PR in myproducts/mySLFO."
|
|
print("Verification complete: No Project PR was created in myproducts/mySLFO as expected.")
|
|
|
|
# 1. Create that Project PR from the test code.
|
|
project_pr_title = "Forwarded PRs: pkgA"
|
|
project_pr_body = f"Test Project PR for NoProjectGitPR. \nPR: mypool/pkgA!{package_pr_number}"
|
|
project_pr_diff = f"""diff --git a/pkgA b/pkgA
|
|
index {pkgA_main_sha[:7]}..{pkgA_pr_head_sha[:7]} 160000
|
|
--- a/pkgA
|
|
+++ b/pkgA
|
|
@@ -1 +1 @@
|
|
-Subproject commit {pkgA_main_sha}
|
|
+Subproject commit {pkgA_pr_head_sha}
|
|
"""
|
|
manual_project_pr = test_user_client.create_gitea_pr(test_full_repo_name, project_pr_diff, project_pr_title, True, base_branch=dev_branch_name, body=project_pr_body)
|
|
manual_project_pr_number = manual_project_pr["number"]
|
|
# Explicitly ensure allow_maintainer_edit is True (it should be by default now, but just in case)
|
|
test_user_client.update_gitea_pr_properties(test_full_repo_name, manual_project_pr_number, allow_maintainer_edit=True)
|
|
print(f"Manually created Project PR #{manual_project_pr_number} in {test_full_repo_name}")
|
|
time.sleep(5) # Give the bot time to potentially react or for the PR to settle
|
|
|
|
# Get initial SHA of the manually created Project PR
|
|
initial_project_pr_details = gitea_env.get_pr_details(test_full_repo_name, manual_project_pr_number)
|
|
initial_head_sha = initial_project_pr_details["head"]["sha"]
|
|
print(f"Manually created Project PR initial head SHA: {initial_head_sha}")
|
|
|
|
# 2. Add new commit to the package PR.
|
|
new_diff_content = """diff --git a/another_file.txt b/another_file.txt
|
|
new file mode 100644
|
|
index 0000000..f587a12
|
|
--- /dev/null
|
|
+++ b/another_file.txt
|
|
@@ -0,0 +1 @@
|
|
+Another file content
|
|
"""
|
|
test_user_client.modify_gitea_pr("mypool/pkgA", package_pr_number, new_diff_content, "Add another file to Package PR")
|
|
print(f"Added new commit to Package PR #{package_pr_number}.")
|
|
time.sleep(5) # Give the bot time to react
|
|
|
|
# 3. Make sure the project PR is properly updated by the bot
|
|
project_pr_updated = False
|
|
print(f"Polling manually created Project PR #{manual_project_pr_number} for update...")
|
|
for _ in range(20): # Poll for a reasonable time
|
|
time.sleep(2) # Wait a bit longer to be sure
|
|
current_project_pr_details = gitea_env.get_pr_details(test_full_repo_name, manual_project_pr_number)
|
|
current_head_sha = current_project_pr_details["head"]["sha"]
|
|
if current_head_sha != initial_head_sha:
|
|
project_pr_updated = True
|
|
print(f"Manually created Project PR updated. New head SHA: {current_head_sha}")
|
|
break
|
|
|
|
assert project_pr_updated, "Manually created Project PR was not updated by the bot."
|
|
print("Verification complete: Manually created Project PR was updated by the bot as expected.")
|
|
|
|
|