toddlers/tests/plugins/test_scm_request_processor.py
Michal Konečný cc26011ee2 Add unit tests for smc_request_processsor
Finish creating tests for create_new_repo method and continue with
create_new_branch method.

Signed-off-by: Michal Konečný <mkonecny@redhat.com>
2022-03-17 16:44:11 +01:00

1441 lines
44 KiB
Python

"""
Unit tests for `toddlers.plugins.scm_request_processor`
"""
import json
from unittest.mock import call, patch, Mock
import logging
from pagure_messages.issue_schema import IssueNewV1
import pytest
import toddlers.plugins.scm_request_processor as scm_request_processor
from toddlers.exceptions import ValidationError
class TestAcceptsTopic:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.accepts_topic` method.
"""
toddler_cls = scm_request_processor.SCMRequestProcessor
def test_accetps_topic_invalid(self, toddler):
"""
Assert that invalid topic is not accepted.
"""
assert toddler.accepts_topic("foo.bar") is False
@pytest.mark.parametrize(
"topic",
[
"org.fedoraproject.*.pagure.issue.new",
"org.fedoraproject.*.pagure.issue.edit",
"org.fedoraproject.stg.pagure.issue.new",
"org.fedoraproject.stg.pagure.issue.edit",
"org.fedoraproject.prod.pagure.issue.new",
"org.fedoraproject.prod.pagure.issue.edit",
]
)
def test_accetps_topic_valid(self, topic, toddler):
"""
Assert that valid topics are accepted.
"""
assert toddler.accepts_topic(topic)
class TestProcess:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.process` method.
"""
toddler_cls = scm_request_processor.SCMRequestProcessor
def test_process_invalid_project(self, caplog, toddler):
"""
Assert that messages from other projects than fedora_scm_requests will be skipped.
"""
caplog.set_level(logging.INFO)
msg = IssueNewV1()
msg.body = {
"project": {
"fullname": "foo/bar"
}
}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.process_ticket"
) as mock_process_ticket:
toddler.process({}, msg)
mock_process_ticket.assert_not_called()
assert (
caplog.records[-1].message ==
"The message doesn't belong to project releng/fedora-scm-requests. Skipping message."
)
def test_process_issue_not_open(self, caplog, toddler):
"""
Assert that messages with closed issues will be skipped.
"""
caplog.set_level(logging.INFO)
msg = IssueNewV1()
msg.body = {
"project": {
"fullname": scm_request_processor.PROJECT_NAMESPACE
},
"issue": {
"id": 100,
"close_status": "Closed"
}
}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.process_ticket"
) as mock_process_ticket:
toddler.process({}, msg)
mock_process_ticket.assert_not_called()
assert (
caplog.records[-1].message ==
"The issue 100 is not open. Skipping message."
)
@patch("toddlers.utils.pdc.set_pdc")
@patch("toddlers.utils.pagure.set_pagure")
@patch("toddlers.utils.fedora_account.set_fasjson")
@patch("toddlers.utils.bugzilla_system.set_bz")
def test_process(self, mock_bugzilla, mock_fasjson, mock_pagure, mock_pdc, toddler):
"""
Assert that message toddler will be initialized correctly, if message passes
initial processing.
"""
msg = IssueNewV1()
issue = {
"id": 100,
"close_status": "Open"
}
msg.body = {
"project": {
"fullname": scm_request_processor.PROJECT_NAMESPACE
},
"issue": issue
}
config = {
"branch_slas": {},
"monitoring_choices": [],
"pagure_namespace_to_component": {},
"pagure_namespace_to_product": {},
"temp_dir": "",
"dist_git_url": "https://src.fedoraproject.org",
"dist_git_token": "Private API Key"
}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.process_ticket"
) as mock_process_ticket:
toddler.process(config, msg)
mock_process_ticket.assert_called_with(issue)
mock_pdc.assert_called_with(config)
mock_pagure.assert_has_calls([
call(config),
call({
"pagure_url": "https://src.fedoraproject.org",
"pagure_api_key": "Private API Key"
})
])
mock_fasjson.assert_called_with(config)
mock_bugzilla.assert_called_with(config)
class TestProcessTicket:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.process_ticket` method.
"""
def setup(self):
"""
Initialize toddler.
"""
self.toddler = scm_request_processor.SCMRequestProcessor()
self.toddler.pagure_io = Mock()
self.toddler.dist_git = Mock()
def test_process_ticket_invalid_json(self):
"""
Assert that invalid json in issue will end the processing.
"""
issue = {
"id": 100,
"content": "invalid JSON",
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.process_ticket(issue)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Invalid JSON provided",
reason="Invalid"
)
def test_process_ticket_invalid_slas(self):
"""
Assert that invalid SLAs in issue will end the processing.
"""
content = {
"sls": {},
"branch": "branch",
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.verify_slas"
) as mock_verify_slas:
mock_verify_slas.side_effect = ValidationError("error")
self.toddler.process_ticket(issue)
mock_verify_slas.assert_called_with("branch", {})
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="error",
reason="Invalid"
)
def test_process_ticket_missing_action(self):
"""
Assert that missing action in issue will end the processing.
"""
content = {
"sls": {},
"branch": "branch",
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.process_ticket(issue)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Invalid or missing action field",
reason="Invalid"
)
def test_process_ticket_missing_sla(self):
"""
Assert that missing SLA for branch will end the processing.
"""
content = {
"branch": "branch",
"action": "new_repo"
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.process_ticket(issue)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Couldn't find standard SLA for branch 'branch'",
reason="Invalid"
)
def test_process_ticket_invalid_branch_name(self):
"""
Assert that invalid name for branch in specific namespace will end the processing.
"""
content = {
"branch": "branch/",
"action": "new_repo",
"namespace": "flatpaks"
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.branch_slas = {"branch/": "SLA"}
self.toddler.process_ticket(issue)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=("Only characters, numbers, periods, dashes, underscores, "
"and pluses are allowed in flatpak branch names"),
reason="Invalid"
)
def test_process_ticket_invalid_monitoring_setting(self):
"""
Assert that invalid monitoring setting for repo will end the processing.
"""
content = {
"branch": "branch",
"action": "new_repo",
"namespace": "flatpaks",
"monitor": "monitor"
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.branch_slas = {"branch": "SLA"}
self.toddler.process_ticket(issue)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message='The monitor choice of "monitor" is invalid',
reason="Invalid"
)
def test_process_ticket_action_new_repo(self):
"""
Assert that action new_repo is correctly processed.
"""
content = {
"branch": "branch",
"action": "new_repo",
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.branch_slas = {"branch": "SLA"}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.create_new_repo"
) as mock_new_repo:
self.toddler.process_ticket(issue)
content["sls"] = "SLA"
mock_new_repo.assert_called_with(
issue, content, initial_commit=True,
)
def test_process_ticket_action_new_branch(self):
"""
Assert that action new_branch is correctly processed.
"""
content = {
"branch": "branch",
"action": "new_branch",
}
issue = {
"id": 100,
"content": json.dumps(content),
"full_url": "https://blacklibrary.wh40k"
}
self.toddler.branch_slas = {"branch": "SLA"}
with patch(
"toddlers.plugins.scm_request_processor.SCMRequestProcessor.create_new_branch"
) as mock_new_branch:
self.toddler.process_ticket(issue)
content["sls"] = "SLA"
mock_new_branch.assert_called_with(
issue, content,
)
class TestVerifySLAs:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.verify_slas` method.
"""
def setup(self):
"""
Initialize toddler.
"""
self.toddler = scm_request_processor.SCMRequestProcessor()
self.toddler.pagure_io = Mock()
self.toddler.dist_git = Mock()
def test_verify_slas_not_dict(self):
"""
Assert that SLA verification will fail if SLA isn't dict.
"""
sla = []
with pytest.raises(ValueError, match="The object provided is not a dict"):
self.toddler.verify_slas("", sla)
def test_verify_slas_no_branch(self):
"""
Assert that the validation will not fail if no branch is provided.
This will fail later in create method, but the verification passes.
"""
sla = {}
branch = None
self.toddler.verify_slas(branch, sla)
def test_verify_slas_branch_sla_correct(self):
"""
Assert that the validation will not fail if provided branch SLAs are
correct.
"""
branch = "branch"
sla = { "rawhide": "2022-06-01"}
self.toddler.branch_slas = {
branch: {
"rawhide": "2022-06-01"
}
}
self.toddler.verify_slas(branch, sla)
def test_verify_slas_branch_sla_incorrect(self):
"""
Assert that the validation will fail if provided branch SLAs are
incorrect.
"""
branch = "branch"
sla = { "rawhide": "2022-01-01"}
self.toddler.branch_slas = {
branch: {
"rawhide": "2022-06-01"
}
}
error = 'The SLAs for the branch "{0}" are incorrect'.format(branch)
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas(branch, sla)
def test_verify_slas_eol_not_string(self):
"""
Assert that the validation will fail if provided SLA EOL is
not string.
"""
sla = { "rawhide": 100 }
error = 'The SL\'s EOL is not a string. It was type "{0}"'.format(type(100).__name__)
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas("", sla)
def test_verify_slas_eol_invalid_format(self):
"""
Assert that the validation will fail if provided SLA EOL date is in invalid format.
"""
sla = { "rawhide": "01-01-2022" }
error = 'The EOL date "{0}" is in an invalid format'.format("01-01-2022")
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas("", sla)
def test_verify_slas_eol_expired(self):
"""
Assert that the validation will fail if provided SLA EOL date is already expired.
"""
sla = { "rawhide": "2022-01-01" }
error = 'The SL "{0}" is already expired'.format("2022-01-01")
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas("", sla)
def test_verify_slas_eol_date_invalid(self):
"""
Assert that the validation will fail if provided SLA EOL date is invalid.
"""
sla = { "rawhide": "2050-01-01" }
error = 'The SL "{0}" must expire on June 1st or December 1st'.format("2050-01-01")
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas("", sla)
@patch('toddlers.utils.pdc.get_sla')
def test_verify_slas_not_in_pdc(self, mock_pdc):
"""
Assert that the validation will fail if SLA is not in PDC.
"""
sla = { "rawhide": "2050-06-01" }
error = 'The SL "{0}" is not in PDC'.format("rawhide")
mock_pdc.return_value = None
with pytest.raises(ValidationError, match=error):
self.toddler.verify_slas("", sla)
mock_pdc.assert_called_with("rawhide")
@patch('toddlers.utils.pdc.get_sla')
def test_verify_slas_in_pdc(self, mock_pdc):
"""
Assert that the validation will pass if SLA is in PDC.
"""
sla = { "rawhide": "2050-06-01" }
mock_pdc.return_value = sla
self.toddler.verify_slas("", sla)
mock_pdc.assert_called_with("rawhide")
class TestCreateNewRepo:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.create_new_repo` method.
"""
def setup(self):
"""
Initialize toddler.
"""
self.toddler = scm_request_processor.SCMRequestProcessor()
self.toddler.pagure_io = Mock()
self.toddler.dist_git = Mock()
def test_create_new_repo_missing_required_key(self):
"""
Assert that ticket will be closed if required key is missing in request.
"""
issue = {
"id": 100,
}
self.toddler.create_new_repo(issue, {})
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Invalid body, missing required field: repo",
reason="Invalid"
)
def test_create_new_repo_invalid_repo_name(self):
"""
Assert that ticket will be closed if provided repository name is invalid.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
json = {
"repo": "+a",
"branch": "rawhide",
"namespace": "namespace",
"bug_id": "123",
"action": "new_repo",
"sls": {
"rawhide": "2050-06-01"
},
"monitor": "monitor"
}
self.toddler.create_new_repo(issue, json)
error = ('The repository name is invalid. It must be at least two '
'characters long with only letters, numbers, hyphens, '
'underscores, plus signs, and/or periods. Please note that '
'the project cannot start with a period or a plus sign.')
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=error,
reason="Invalid"
)
def test_create_new_repo_missing_bug_id(self):
"""
Assert that ticket will be closed if Bugzilla bug id is not provided.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
json = {
"repo": "repo",
"branch": "rawhide",
"namespace": "namespace",
"bug_id": "",
"action": "new_repo",
"sls": {
"rawhide": "2050-06-01"
},
"monitor": "monitor"
}
self.toddler.create_new_repo(issue, json)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="An invalid Bugzilla bug was provided",
reason="Invalid"
)
@patch("toddlers.plugins.scm_request_processor.SCMRequestProcessor.validate_review_bug")
def test_create_new_repo_invalid_review_bug(self, mock_validate_review_bug):
"""
Assert that ticket will be closed if Bugzilla bug is not valid.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
json = {
"repo": "repo",
"branch": "rawhide",
"namespace": "namespace",
"bug_id": "123",
"action": "new_repo",
"sls": {
"rawhide": "2050-06-01"
},
"monitor": "monitor"
}
mock_validate_review_bug.side_effect = ValidationError("error")
self.toddler.create_new_repo(issue, json)
mock_validate_review_bug.assert_called_with(
"123", "repo", "rawhide",
namespace="namespace", pagure_user="zlopez"
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="error",
reason="Invalid"
)
@patch("toddlers.plugins.scm_request_processor.SCMRequestProcessor.valid_epel_package")
def test_create_new_repo_invalid_epel(self, mock_valid_epel_package):
"""
Assert that ticket will be closed if repo is invalid EPEL repo.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "epel8"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
mock_valid_epel_package.return_value = False
self.toddler.create_new_repo(issue, json)
mock_valid_epel_package.assert_called_with(
repo, branch
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=scm_request_processor.INVALID_EPEL_ERROR,
reason="Invalid"
)
def test_create_new_repo_requester_not_in_dist_git(self):
"""
Assert that ticket will be commented on when requester doesn't have a valid dist git account.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.dist_git.user_exists.return_value = False
self.toddler.dist_git._pagure_url = "https://src.fedoraproject.org"
self.toddler.create_new_repo(issue, json)
self.toddler.dist_git.user_exists.assert_called_with(
"zlopez"
)
message = "@zlopez needs to login to {0} to sync accounts before we can proceed.".format(self.toddler.dist_git._pagure_url)
self.toddler.pagure_io.add_comment_to_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
comment=message,
)
def test_create_new_repo_project_exists(self):
"""
Assert that ticket will be closed when repo already exists in dist git.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.dist_git.get_project.return_value = "project"
self.toddler.create_new_repo(issue, json)
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="The Pagure project already exists",
reason="Invalid"
)
def test_create_new_repo_master_branch(self):
"""
Assert that ticket will be closed when branch is set to master branch.
Master branch is no longer allowed.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "master"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.dist_git.get_project.return_value = None
self.toddler.create_new_repo(issue, json)
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Branch `master` cannot be created, please request the right branch.",
reason="Invalid"
)
def test_create_new_repo_unsupported_namespace(self):
"""
Assert that ticket will be closed when requested namespace is not recognized.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "invalid"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.dist_git.get_project.return_value = None
self.toddler.create_new_repo(issue, json)
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
error = ("The requested namespace '{0}' is not recognized. "
"Currently supported namespaces are: "
"rpms, container, flatpaks, modules, tests.".format(namespace))
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=error,
reason="Invalid"
)
@patch('toddlers.utils.pdc.get_branch')
def test_create_new_repo_branch_exist(self, mock_pdc_get_branch):
"""
Assert that ticket will be closed when branch already exist in PDC.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
"rawhide": "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.dist_git.get_project.return_value = None
mock_pdc_get_branch.return_value = branch
self.toddler.create_new_repo(issue, json)
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
mock_pdc_get_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="The PDC branch already exists",
reason="Invalid"
)
@pytest.mark.parametrize(
"namespace, branch",
[
("rpms", "rawhide"),
("container", "rawhide"),
("flatpaks", "stable"),
("modules", "rawhide"),
]
)
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_repo_namespaces(self, mock_pdc, namespace, branch):
"""
Assert that ticket will be processed when everything is in order and namespace is correct.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
bug_id = ""
action = "new_repo"
sls = {
branch: "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
dist_git_url = "https://src.fp.o"
self.toddler.dist_git.get_project.return_value = None
self.toddler.dist_git._pagure_url = dist_git_url
mock_pdc.get_branch.return_value = None
self.toddler.create_new_repo(issue, json)
# asserts
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.dist_git.new_project.assert_called_with(
namespace, repo, '', '', branch, initial_commit=True, alias=True
)
self.toddler.dist_git.set_monitoring_status.assert_called_with(
namespace, repo, monitor
)
self.toddler.dist_git.change_project_main_admin.assert_called_with(
namespace, repo, "zlopez"
)
mock_pdc.get_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
mock_pdc.new_global_component.assert_called_with(
repo, "{0}/{1}/{2}".format(dist_git_url, namespace, repo)
)
mock_pdc.new_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
mock_pdc.new_sla_to_branch.assert_called_with(
branch, sls[branch], repo, branch, namespace.rstrip('s')
)
message = "The Pagure repository was created at {0}/{1}/{2}".format(
dist_git_url, namespace, repo)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=message,
reason="Processed"
)
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_repo_tests_namespace(self, mock_pdc):
"""
Assert that ticket will be processed when everything is in order and namespace is set to tests.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "main"
namespace = "tests"
bug_id = ""
action = "new_repo"
sls = {
branch: "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
dist_git_url = "https://src.fp.o"
self.toddler.dist_git.get_project.return_value = None
self.toddler.dist_git._pagure_url = dist_git_url
mock_pdc.get_branch.return_value = None
self.toddler.create_new_repo(issue, json)
# asserts
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.dist_git.new_project.assert_called_with(
namespace, repo, '', '', branch, initial_commit=True, alias=True
)
self.toddler.dist_git.set_monitoring_status.assert_called_with(
namespace, repo, monitor
)
self.toddler.dist_git.change_project_main_admin.assert_called_with(
namespace, repo, "zlopez"
)
mock_pdc.get_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
message = "The Pagure repository was created at {0}/{1}/{2}".format(
dist_git_url, namespace, repo)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=message,
reason="Processed"
)
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_repo_non_default_branch(self, mock_pdc):
"""
Assert that ticket will be processed when everything is in order and requested branch is not default.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "f35"
namespace = "rpms"
bug_id = ""
action = "new_repo"
sls = {
branch: "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
self.toddler.branch_slas = {
"rawhide": {
"rawhide": "2050-06-01"
}
}
dist_git_url = "https://src.fp.o"
self.toddler.dist_git.get_project.return_value = None
self.toddler.dist_git._pagure_url = dist_git_url
mock_pdc.get_branch.return_value = None
self.toddler.create_new_repo(issue, json)
# asserts
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.dist_git.new_project.assert_called_with(
namespace, repo, '', '', "rawhide", initial_commit=True, alias=True
)
self.toddler.dist_git.set_monitoring_status.assert_called_with(
namespace, repo, monitor
)
self.toddler.dist_git.change_project_main_admin.assert_called_with(
namespace, repo, "zlopez"
)
mock_pdc.get_branch.assert_has_calls(
[
call(repo, "rawhide", namespace.rstrip('s')),
call(repo, branch, namespace.rstrip('s')),
]
)
mock_pdc.new_global_component.assert_called_with(
repo, "{0}/{1}/{2}".format(dist_git_url, namespace, repo)
)
mock_pdc.new_branch.assert_has_calls(
[
call(repo, "rawhide", namespace.rstrip('s')),
call(repo, branch, namespace.rstrip('s')),
]
)
mock_pdc.new_sla_to_branch.assert_has_calls(
[
call("rawhide", "2050-06-01", repo, "rawhide", namespace.rstrip('s')),
call(branch, sls[branch], repo, branch, namespace.rstrip('s')),
]
)
message = ('The Pagure repository was created at {0}/{1}/{2}. '
'You may commit to the branch "{3}" in about '
'10 minutes.'.format(dist_git_url, namespace, repo, branch)
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=message,
reason="Processed"
)
@patch("toddlers.plugins.scm_request_processor.bugzilla_system")
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_repo_update_bug(self, mock_pdc, mock_bz):
"""
Assert that bug will be updated if the bug_id is provided.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
bug_id = "123"
action = "new_repo"
sls = {
branch: "2050-06-01"
}
monitor = "monitor"
exception = True
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"bug_id": bug_id,
"action": action,
"sls": sls,
"monitor": monitor,
"exception": exception
}
dist_git_url = "https://src.fp.o"
self.toddler.dist_git.get_project.return_value = None
self.toddler.dist_git._pagure_url = dist_git_url
mock_pdc.get_branch.return_value = None
self.toddler.create_new_repo(issue, json)
# asserts
self.toddler.dist_git.get_project.assert_called_with(
namespace, repo
)
self.toddler.dist_git.new_project.assert_called_with(
namespace, repo, '', '', branch, initial_commit=True, alias=True
)
self.toddler.dist_git.set_monitoring_status.assert_called_with(
namespace, repo, monitor
)
self.toddler.dist_git.change_project_main_admin.assert_called_with(
namespace, repo, "zlopez"
)
mock_pdc.get_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
mock_pdc.new_global_component.assert_called_with(
repo, "{0}/{1}/{2}".format(dist_git_url, namespace, repo)
)
mock_pdc.new_branch.assert_called_with(repo, branch, namespace.rstrip('s'))
mock_pdc.new_sla_to_branch.assert_called_with(
branch, sls[branch], repo, branch, namespace.rstrip('s')
)
message = "The Pagure repository was created at {0}/{1}/{2}".format(
dist_git_url, namespace, repo)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=message,
reason="Processed"
)
mock_bz.comment_on_bug.assert_called_with(bug_id, message)
class TestCreateNewBranch:
"""
Test class for `toddlers.plugins.scm_request_processor.SCMRequestProcessor.create_new_branch` method.
"""
def setup(self):
"""
Initialize toddler.
"""
self.toddler = scm_request_processor.SCMRequestProcessor()
self.toddler.pagure_io = Mock()
self.toddler.dist_git = Mock()
def test_create_new_branch_missing_required_key(self):
"""
Assert that ticket will be closed if required key is missing in request.
"""
issue = {
"id": 100,
}
self.toddler.create_new_branch(issue, {})
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="Invalid body, missing required field: action",
reason="Invalid"
)
def test_create_new_branch_no_contributors(self):
"""
Assert that ticket will be closed if contributors are not retrieved.
"""
issue = {
"id": 100,
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
action = "new_branch"
sls = {
branch: "2050-06-01"
}
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"action": action,
"sls": sls,
}
self.toddler.dist_git.get_project_contributors.return_value = None
self.toddler.create_new_branch(issue, json)
# Asserts
self.toddler.dist_git.get_project_contributors.assert_called_with(namespace, repo)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="The dist git repository doesn't exist",
reason="Invalid"
)
@patch("toddlers.plugins.scm_request_processor.SCMRequestProcessor.valid_epel_package")
def test_create_new_branch_invalid_epel(self, mock_valid_epel_package):
"""
Assert that ticket will be closed if repo is invalid EPEL repo.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "epel8"
namespace = "rpms"
action = "new_branch"
sls = {
"rawhide": "2050-06-01"
}
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"action": action,
"sls": sls,
}
mock_valid_epel_package.return_value = False
self.toddler.create_new_branch(issue, json)
# Asserts
self.toddler.dist_git.get_project_contributors.assert_called_with(namespace, repo)
mock_valid_epel_package.assert_called_with(
repo, branch
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=scm_request_processor.INVALID_EPEL_ERROR,
reason="Invalid"
)
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_branch_branch_exists(self, mock_pdc):
"""
Assert that ticket will be closed if branch already exists in PDC.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
action = "new_branch"
sls = {
"rawhide": "2050-06-01"
}
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"action": action,
"sls": sls,
}
self.toddler.create_new_branch(issue, json)
# Asserts
self.toddler.dist_git.get_project_contributors.assert_called_with(namespace, repo)
mock_pdc.get_branch.assert_called_with(repo, branch, namespace.strip().rstrip('s'))
message = \
"The branch in PDC already exists, you can now create it yourself as follows:\n" \
"Check in the project's settings if you have activated the git hook preventing" \
"new git branches from being created and if you did, de-activate it.\n" \
"Then simply run in cloned repository: " \
"``git checkout -b <branch_name> && git push -u origin <branch_name>``.\n" \
"``<branch_name>`` is the name of the branch you requested. \n" \
"You only need to do this once and you can then use fedpkg as you normally do."
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message=message,
reason="Invalid"
)
@patch("toddlers.plugins.scm_request_processor.fedora_account")
@patch("toddlers.plugins.scm_request_processor.pdc")
def test_create_new_branch_requester_is_not_maintainer(self, mock_pdc, mock_fedora_account):
"""
Assert that ticket will be closed if requester is not a maintainer of package.
"""
issue = {
"id": 100,
"user": {
"name": "zlopez"
}
}
repo = "repo"
branch = "rawhide"
namespace = "rpms"
action = "new_branch"
sls = {
"rawhide": "2050-06-01"
}
json = {
"repo": repo,
"branch": branch,
"namespace": namespace,
"action": action,
"sls": sls,
}
self.toddler.dist_git.get_project_contributors.return_value = {
"users": {
"admin": [],
"commit": [],
"collaborators": [{
"user": "",
"branches": "rawhide"
}]
},
"groups": {
"admin": ["group"],
"commit": [],
"collaborators": [{
"user": "",
"branches": "rawhide"
}]
}
}
mock_pdc.get_branch.return_value = None
mock_fedora_account.user_member_of.return_value = False
self.toddler.create_new_branch(issue, json)
# Asserts
self.toddler.dist_git.get_project_contributors.assert_called_with(namespace, repo)
mock_pdc.get_branch.assert_called_with(repo, branch, namespace.strip().rstrip('s'))
mock_fedora_account.user_member_of.assert_called_with(
mock_fedora_account.get_user_by_username(), "group"
)
self.toddler.pagure_io.close_issue.assert_called_with(
100, namespace=scm_request_processor.PROJECT_NAMESPACE,
message="zlopez is not a maintainer of the {0} package".format(repo),
reason="Invalid"
)