Using real objects is considered polite

Previously, ToddlerBase and derived classes were used directly, but none
of the methods is marked as a class or static method. Amazingly enough,
it worked regardless. It's useful to have a constructor, though, so do
things conventionally.

As we can't just monkey-patch the classes then, use the shared `toddler`
fixture which creates the object for the test methods that need it.

Signed-off-by: Nils Philippsen <nils@redhat.com>
This commit is contained in:
Nils Philippsen 2020-07-16 13:16:38 +02:00
parent 3f081a66ac
commit 7fe0937190
14 changed files with 167 additions and 225 deletions

17
tests/conftest.py Normal file
View file

@ -0,0 +1,17 @@
import pytest
@pytest.fixture
def toddler(request, monkeypatch):
"""Fixture creating a toddler for a class testing it
The test class must set the toddler class in its `toddler_cls` attribute.
"""
test_cls = request.cls
if not hasattr(test_cls, "toddler_cls"):
raise RuntimeError(f"{test_cls} needs to set `toddler_cls`")
toddler_cls = test_cls.toddler_cls
toddler_obj = toddler_cls()
return toddler_obj

View file

@ -1,16 +1,17 @@
import fedora_messaging.api import fedora_messaging.api
import toddlers.plugins.debug from toddlers.plugins.debug import DebugToddler
class TestDebugToddler: class TestDebugToddler:
def test_accepts_topic(self):
assert toddlers.plugins.debug.DebugToddler.accepts_topic("foo.bar")
def test_process(self): toddler_cls = DebugToddler
def test_accepts_topic(self, toddler):
assert toddler.accepts_topic("foo.bar")
def test_process(self, toddler):
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "toddlers.test.topic" msg.topic = "toddlers.test.topic"
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.debug.DebugToddler.process(config={}, message=msg) is None
)

View file

@ -4,12 +4,15 @@ from unittest.mock import MagicMock, patch
import fedora_messaging.api import fedora_messaging.api
import pytest import pytest
import toddlers.plugins.flag_ci_pr from toddlers.plugins.flag_ci_pr import FlagCIPR
class TestFlagCIPRToddler: class TestFlagCIPRToddler:
def test_accepts_topic_invalid(self):
assert toddlers.plugins.flag_ci_pr.FlagCIPR.accepts_topic("foo.bar") is False toddler_cls = FlagCIPR
def test_accepts_topic_invalid(self, toddler):
assert toddler.accepts_topic("foo.bar") is False
@pytest.mark.parametrize( @pytest.mark.parametrize(
"topic", "topic",
@ -25,55 +28,47 @@ class TestFlagCIPRToddler:
"org.centos.stg.ci.dist-git-pr.test.running", "org.centos.stg.ci.dist-git-pr.test.running",
], ],
) )
def test_accepts_topic_valid(self, topic): def test_accepts_topic_valid(self, toddler, topic):
assert toddlers.plugins.flag_ci_pr.FlagCIPR.accepts_topic(topic) assert toddler.accepts_topic(topic)
def test_process_invalid(self): def test_process_invalid(self, toddler):
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "toddlers.test.topic" msg.topic = "toddlers.test.topic"
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) is None
)
def test_process_invalid_status(self, caplog): def test_process_invalid_status(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.invalid" msg.topic = "org.centos.stg.ci.dist-git-pr.test.invalid"
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Pipeline state is not 'complete' or 'running' or 'error'." == "Pipeline state is not 'complete' or 'running' or 'error'."
) )
def test_process_no_version(self, caplog): def test_process_no_version(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete" msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete"
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) is None
)
assert caplog.records[-1].message == "Unsupported msg version, ignoring" assert caplog.records[-1].message == "Unsupported msg version, ignoring"
def test_process_invalid_complete_status(self, caplog): def test_process_invalid_complete_status(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete" msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete"
msg.body = {"version": "0.2.1", "test": {"result": "invalid"}} msg.body = {"version": "0.2.1", "test": {"result": "invalid"}}
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Build is not in one of the expected status, ignoring" == "Build is not in one of the expected status, ignoring"
) )
def test_process_no_artifact(self, caplog): def test_process_no_artifact(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
@ -83,9 +78,7 @@ class TestFlagCIPRToddler:
"test": {"result": "passed"}, "test": {"result": "passed"},
"artifact": {"commit_hash": "abcdefghijklmnopqrst"}, "artifact": {"commit_hash": "abcdefghijklmnopqrst"},
} }
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Invalid message: {'commit_hash': 'abcdefghijklmnopqrst'}, could not extract " == "Invalid message: {'commit_hash': 'abcdefghijklmnopqrst'}, could not extract "
@ -93,7 +86,7 @@ class TestFlagCIPRToddler:
) )
@patch("toddlers.plugins.flag_ci_pr.requests_session") @patch("toddlers.plugins.flag_ci_pr.requests_session")
def test_process_request_failed(self, mock_requests, caplog): def test_process_request_failed(self, mock_requests, toddler, caplog):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid" ok=False, status_code=401, text="invalid"
) )
@ -117,16 +110,13 @@ class TestFlagCIPRToddler:
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) == 1
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config=config, message=msg)
== 1
)
assert ( assert (
caplog.records[-1].message == "Request to https://pagure.io returned: 401" caplog.records[-1].message == "Request to https://pagure.io returned: 401"
) )
@patch("toddlers.plugins.flag_ci_pr.requests_session") @patch("toddlers.plugins.flag_ci_pr.requests_session")
def test_process_valid(self, mock_requests, caplog): def test_process_valid(self, mock_requests, toddler, caplog):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=True, status_code=200, text="invalid" ok=True, status_code=200, text="invalid"
) )
@ -150,10 +140,7 @@ class TestFlagCIPRToddler:
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config=config, message=msg)
is None
)
assert ( assert (
caplog.records[-3].message == "Request to https://pagure.io returned: 200" caplog.records[-3].message == "Request to https://pagure.io returned: 200"
) )

View file

@ -4,15 +4,15 @@ from unittest.mock import MagicMock, Mock, patch
import fedora_messaging.api import fedora_messaging.api
import pytest import pytest
import toddlers.plugins.flag_commit_build from toddlers.plugins.flag_commit_build import FlagCommitBuild
class TestFlagCommitBuildToddler: class TestFlagCommitBuildToddler:
def test_accepts_topic_invalid(self):
assert ( toddler_cls = FlagCommitBuild
toddlers.plugins.flag_commit_build.FlagCommitBuild.accepts_topic("foo.bar")
is False def test_accepts_topic_invalid(self, toddler):
) assert toddler.accepts_topic("foo.bar") is False
@pytest.mark.parametrize( @pytest.mark.parametrize(
"topic", "topic",
@ -22,38 +22,28 @@ class TestFlagCommitBuildToddler:
"org.fedoraproject.prod.buildsys.build.state.change", "org.fedoraproject.prod.buildsys.build.state.change",
], ],
) )
def test_accepts_topic_valid(self, topic): def test_accepts_topic_valid(self, toddler, topic):
assert toddlers.plugins.flag_commit_build.FlagCommitBuild.accepts_topic(topic) assert toddler.accepts_topic(topic)
def test_process_containerbuild(self, caplog): def test_process_containerbuild(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change" msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {"owner": "containerbuild"} msg.body = {"owner": "containerbuild"}
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
is None
)
assert caplog.records[-1].message == "Skipping container build" assert caplog.records[-1].message == "Skipping container build"
def test_process_mbs_build(self, caplog): def test_process_mbs_build(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change" msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {"owner": "mbs/mbs.fedoraproject.org"} msg.body = {"owner": "mbs/mbs.fedoraproject.org"}
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
is None
)
assert caplog.records[-1].message == "Skipping MBS builds" assert caplog.records[-1].message == "Skipping MBS builds"
def test_process_secondary_instance(self, caplog): def test_process_secondary_instance(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
@ -62,15 +52,10 @@ class TestFlagCommitBuildToddler:
"owner": "username", "owner": "username",
"instance": "secondary", "instance": "secondary",
} }
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
is None
)
assert caplog.records[-1].message == "Ignoring secondary arch task..." assert caplog.records[-1].message == "Ignoring secondary arch task..."
def test_process_uninteresting_status(self, caplog): def test_process_uninteresting_status(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message() msg = fedora_messaging.api.Message()
msg.id = 123 msg.id = 123
@ -80,19 +65,14 @@ class TestFlagCommitBuildToddler:
"instance": "primary", "instance": "primary",
"new": 2, "new": 2,
} }
assert ( assert toddler.process(config={}, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Build is not in a state we care about, skipping" == "Build is not in a state we care about, skipping"
) )
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_no_git_url(self, mock_koji, caplog): def test_process_no_git_url(self, mock_koji, toddler, caplog):
client = Mock() client = Mock()
client.getBuild = Mock(return_value={}) client.getBuild = Mock(return_value={})
mock_koji.ClientSession = Mock(return_value=client) mock_koji.ClientSession = Mock(return_value=client)
@ -107,19 +87,14 @@ class TestFlagCommitBuildToddler:
"build_id": 42, "build_id": 42,
} }
config = {"koji_url": "https://koji.fedoraproject.org"} config = {"koji_url": "https://koji.fedoraproject.org"}
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "No git url found in the extra information: None" == "No git url found in the extra information: None"
) )
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_invalid_git_url(self, mock_koji, caplog): def test_process_invalid_git_url(self, mock_koji, toddler, caplog):
client = Mock() client = Mock()
client.getBuild = Mock( client.getBuild = Mock(
return_value={"extra": {"source": {"original_url": "foobar"}}} return_value={"extra": {"source": {"original_url": "foobar"}}}
@ -136,17 +111,12 @@ class TestFlagCommitBuildToddler:
"build_id": 42, "build_id": 42,
} }
config = {"koji_url": "https://koji.fedoraproject.org"} config = {"koji_url": "https://koji.fedoraproject.org"}
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert caplog.records[-1].message == "No # in the git_url: foobar" assert caplog.records[-1].message == "No # in the git_url: foobar"
@patch("toddlers.plugins.flag_commit_build.requests_session") @patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_no_task_id(self, mock_koji, mock_requests, caplog): def test_process_flag_no_task_id(self, mock_koji, mock_requests, toddler, caplog):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid" ok=False, status_code=401, text="invalid"
) )
@ -182,12 +152,7 @@ class TestFlagCommitBuildToddler:
"pagure_url": "https://src.fedoraproject.org", "pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Request to https://src.fedoraproject.org returned: 401" == "Request to https://src.fedoraproject.org returned: 401"
@ -195,7 +160,7 @@ class TestFlagCommitBuildToddler:
@patch("toddlers.plugins.flag_commit_build.requests_session") @patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_failed(self, mock_koji, mock_requests, caplog): def test_process_flag_failed(self, mock_koji, mock_requests, toddler, caplog):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid" ok=False, status_code=401, text="invalid"
) )
@ -231,12 +196,7 @@ class TestFlagCommitBuildToddler:
"pagure_url": "https://src.fedoraproject.org", "pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Request to https://src.fedoraproject.org returned: 401" == "Request to https://src.fedoraproject.org returned: 401"
@ -244,7 +204,9 @@ class TestFlagCommitBuildToddler:
@patch("toddlers.plugins.flag_commit_build.requests_session") @patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_failed_cancel(self, mock_koji, mock_requests, caplog): def test_process_flag_failed_cancel(
self, mock_koji, mock_requests, toddler, caplog
):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid" ok=False, status_code=401, text="invalid"
) )
@ -280,12 +242,7 @@ class TestFlagCommitBuildToddler:
"pagure_url": "https://src.fedoraproject.org", "pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert ( assert (
caplog.records[-1].message caplog.records[-1].message
== "Request to https://src.fedoraproject.org returned: 401" == "Request to https://src.fedoraproject.org returned: 401"
@ -293,7 +250,7 @@ class TestFlagCommitBuildToddler:
@patch("toddlers.plugins.flag_commit_build.requests_session") @patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji") @patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_pass(self, mock_koji, mock_requests, caplog): def test_process_flag_pass(self, mock_koji, mock_requests, toddler, caplog):
mock_requests.request.return_value = MagicMock( mock_requests.request.return_value = MagicMock(
ok=True, status_code=200, text="woohoo!" ok=True, status_code=200, text="woohoo!"
) )
@ -328,12 +285,7 @@ class TestFlagCommitBuildToddler:
"pagure_url": "https://src.fedoraproject.org", "pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah", "pagure_token": "ahah",
} }
assert ( assert toddler.process(config=config, message=msg) is None
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
is None
)
assert ( assert (
caplog.records[-3].message caplog.records[-3].message
== "Request to https://src.fedoraproject.org returned: 200" == "Request to https://src.fedoraproject.org returned: 200"

View file

@ -2,17 +2,15 @@ from unittest.mock import Mock, patch
import pytest import pytest
import toddlers.plugins.packager_bugzilla_sync from toddlers.plugins.packager_bugzilla_sync import main, PackagerBugzillaSync
class TestPackagerBugzillaSyncToddler: class TestPackagerBugzillaSyncToddler:
def test_accepts_topic_invalid(self):
assert ( toddler_cls = PackagerBugzillaSync
toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.accepts_topic(
"foo.bar" def test_accepts_topic_invalid(self, toddler):
) assert toddler.accepts_topic("foo.bar") is False
is False
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"topic", "topic",
@ -22,26 +20,22 @@ class TestPackagerBugzillaSyncToddler:
"org.fedoraproject.stg.toddlers.trigger.packager_bugzilla_sync", "org.fedoraproject.stg.toddlers.trigger.packager_bugzilla_sync",
], ],
) )
def test_accepts_topic_valid(self, topic): def test_accepts_topic_valid(self, toddler, topic):
assert toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.accepts_topic( assert toddler.accepts_topic(topic)
topic
)
def test_process_no_email_override(self, capsys): def test_process_no_email_override(self, toddler, capsys):
with pytest.raises(KeyError, match=r"'email_overrides_file'"): with pytest.raises(KeyError, match=r"'email_overrides_file'"):
toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.process( toddler.process(config={}, message=None, username=False, dry_run=True)
config={}, message=None, username=False, dry_run=True
)
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out == "Failed to load the file containing the email-overrides\n" assert out == "Failed to load the file containing the email-overrides\n"
assert err == "" assert err == ""
def test_process_no_email_override_file(self, capsys): def test_process_no_email_override_file(self, toddler, capsys):
with pytest.raises( with pytest.raises(
FileNotFoundError, match=r"No such file or directory: 'test'" FileNotFoundError, match=r"No such file or directory: 'test'"
): ):
toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.process( toddler.process(
config={"email_overrides_file": "test"}, config={"email_overrides_file": "test"},
message=None, message=None,
username=False, username=False,
@ -60,14 +54,20 @@ class TestPackagerBugzillaSyncToddler:
@patch("toddlers.utils.bugzilla_system.add_user_to_group") @patch("toddlers.utils.bugzilla_system.add_user_to_group")
@patch("toml.load") @patch("toml.load")
def test_process( def test_process(
self, toml_load, bz_user_grp, get_bz_grp_mbr, get_bz_email, get_fas_grp_mbr self,
toml_load,
bz_user_grp,
get_bz_grp_mbr,
get_bz_email,
get_fas_grp_mbr,
toddler,
): ):
toml_load.return_value = {} toml_load.return_value = {}
get_fas_grp_mbr.return_value = ["pingou", "nils"] get_fas_grp_mbr.return_value = ["pingou", "nils"]
get_bz_email.side_effect = ["pingou@fp.o", "nils@fp.o"] get_bz_email.side_effect = ["pingou@fp.o", "nils@fp.o"]
get_bz_grp_mbr.return_value = ["pingou@fp.o", "nphilipp@fp.o"] get_bz_grp_mbr.return_value = ["pingou@fp.o", "nphilipp@fp.o"]
toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.process( toddler.process(
config={"email_overrides_file": "test", "bugzilla_group": "fedora_contrib"}, config={"email_overrides_file": "test", "bugzilla_group": "fedora_contrib"},
message=None, message=None,
username=False, username=False,
@ -92,13 +92,13 @@ class TestPackagerBugzillaSyncToddler:
@patch("toddlers.utils.bugzilla_system.add_user_to_group") @patch("toddlers.utils.bugzilla_system.add_user_to_group")
@patch("toml.load") @patch("toml.load")
def test_process_username( def test_process_username(
self, toml_load, bz_user_grp, get_bz_grp_mbr, get_bz_email self, toml_load, bz_user_grp, get_bz_grp_mbr, get_bz_email, toddler
): ):
toml_load.return_value = {} toml_load.return_value = {}
get_bz_email.side_effect = ["nils@fp.o"] get_bz_email.side_effect = ["nils@fp.o"]
get_bz_grp_mbr.return_value = ["pingou@fp.o"] get_bz_grp_mbr.return_value = ["pingou@fp.o"]
toddlers.plugins.packager_bugzilla_sync.PackagerBugzillaSync.process( toddler.process(
config={"email_overrides_file": "test", "bugzilla_group": "fedora_contrib"}, config={"email_overrides_file": "test", "bugzilla_group": "fedora_contrib"},
message=None, message=None,
username="nils", username="nils",
@ -117,7 +117,7 @@ class TestPackagerBugzillaSyncToddler:
def test_main_no_args(self, capsys): def test_main_no_args(self, capsys):
with pytest.raises(SystemExit): with pytest.raises(SystemExit):
toddlers.plugins.packager_bugzilla_sync.main([]) main([])
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out == "" assert out == ""
@ -131,7 +131,7 @@ class TestPackagerBugzillaSyncToddler:
@patch("toml.load", new=Mock(return_value={})) @patch("toml.load", new=Mock(return_value={}))
def test_main_debug(self, capsys): def test_main_debug(self, capsys):
with pytest.raises(KeyError, match=r"'email_overrides_file'"): with pytest.raises(KeyError, match=r"'email_overrides_file'"):
toddlers.plugins.packager_bugzilla_sync.main(["test.cfg", "--debug"]) main(["test.cfg", "--debug"])
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out == "Failed to load the file containing the email-overrides\n" assert out == "Failed to load the file containing the email-overrides\n"
assert err == "" assert err == ""
@ -139,7 +139,7 @@ class TestPackagerBugzillaSyncToddler:
@patch("toml.load", new=Mock(return_value={})) @patch("toml.load", new=Mock(return_value={}))
def test_main(self, capsys): def test_main(self, capsys):
with pytest.raises(KeyError, match=r"'email_overrides_file'"): with pytest.raises(KeyError, match=r"'email_overrides_file'"):
toddlers.plugins.packager_bugzilla_sync.main(["test.cfg"]) main(["test.cfg"])
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out == "Failed to load the file containing the email-overrides\n" assert out == "Failed to load the file containing the email-overrides\n"
assert err == "" assert err == ""

View file

@ -9,13 +9,11 @@ import toddlers.plugins.pdc_retired_packages
class TestPDCRetiredPackagesToddler: class TestPDCRetiredPackagesToddler:
def test_accepts_topic_invalid(self):
assert ( toddler_cls = toddlers.plugins.pdc_retired_packages.PDCRetiredPackages
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages.accepts_topic(
"foo.bar" def test_accepts_topic_invalid(self, toddler):
) assert toddler.accepts_topic("foo.bar") is False
is False
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"topic", "topic",
@ -28,14 +26,12 @@ class TestPDCRetiredPackagesToddler:
"org.fedoraproject.stg.git.receive", "org.fedoraproject.stg.git.receive",
], ],
) )
def test_accepts_topic_valid(self, topic): def test_accepts_topic_valid(self, toddler, topic):
assert toddlers.plugins.pdc_retired_packages.PDCRetiredPackages.accepts_topic( assert toddler.accepts_topic(topic)
topic
)
@patch("toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_dist_git") @patch("toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_dist_git")
@patch("pdc_client.PDCClient") @patch("pdc_client.PDCClient")
def test_process_full_dist_git(self, pdc, process_dg): def test_process_full_dist_git(self, pdc, process_dg, toddler):
client = Mock() client = Mock()
pdc.return_value = client pdc.return_value = client
@ -44,9 +40,7 @@ class TestPDCRetiredPackagesToddler:
msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages" msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages"
msg.body = {} msg.body = {}
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages.process( toddler.process({"config": "foobar"}, msg)
{"config": "foobar"}, msg
)
process_dg.assert_called_once_with({"config": "foobar"}, client) process_dg.assert_called_once_with({"config": "foobar"}, client)
@ -54,7 +48,7 @@ class TestPDCRetiredPackagesToddler:
"toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package" "toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package"
) )
@patch("pdc_client.PDCClient") @patch("pdc_client.PDCClient")
def test_process_single_package(self, pdc, process_dg): def test_process_single_package(self, pdc, process_dg, toddler):
client = Mock() client = Mock()
pdc.return_value = client pdc.return_value = client
@ -63,14 +57,12 @@ class TestPDCRetiredPackagesToddler:
msg.topic = "org.fedoraproject.prod.git.receive" msg.topic = "org.fedoraproject.prod.git.receive"
msg.body = {} msg.body = {}
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages.process( toddler.process({"config": "foobar"}, msg)
{"config": "foobar"}, msg
)
process_dg.assert_called_once_with({"config": "foobar"}, client, msg) process_dg.assert_called_once_with({"config": "foobar"}, client, msg)
@patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git") @patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git")
def test_process_dist_git(self, retired_in_dg): def test_process_dist_git(self, retired_in_dg, toddler):
page_component_branches = [ page_component_branches = [
{ {
"id": 44, "id": 44,
@ -116,9 +108,7 @@ class TestPDCRetiredPackagesToddler:
msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages" msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages"
msg.body = {} msg.body = {}
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_dist_git( toddler._process_dist_git({}, client)
{}, client
)
client.get_paged.assert_has_calls(calls=[call(page_component_branches)]) client.get_paged.assert_has_calls(calls=[call(page_component_branches)])
retired_in_dg.assert_has_calls( retired_in_dg.assert_has_calls(
@ -133,7 +123,9 @@ class TestPDCRetiredPackagesToddler:
) )
@patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git") @patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git")
def test_process_dist_git_invalid_pdc_namespace(self, retired_in_dg, caplog): def test_process_dist_git_invalid_pdc_namespace(
self, retired_in_dg, caplog, toddler
):
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)
page_component_branches = [ page_component_branches = [
{ {
@ -180,9 +172,7 @@ class TestPDCRetiredPackagesToddler:
msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages" msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages"
msg.body = {} msg.body = {}
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_dist_git( toddler._process_dist_git({}, client)
{}, client
)
client.get_paged.assert_has_calls(calls=[call(page_component_branches)]) client.get_paged.assert_has_calls(calls=[call(page_component_branches)])
retired_in_dg.assert_has_calls( retired_in_dg.assert_has_calls(
@ -201,7 +191,7 @@ class TestPDCRetiredPackagesToddler:
@patch("toddlers.plugins.pdc_retired_packages._retire_branch") @patch("toddlers.plugins.pdc_retired_packages._retire_branch")
@patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git") @patch("toddlers.plugins.pdc_retired_packages._is_retired_in_dist_git")
def test_process_dist_git_full_distgit(self, retired_in_dg, retire_branch): def test_process_dist_git_full_distgit(self, retired_in_dg, retire_branch, toddler):
page_component_branches = [ page_component_branches = [
{ {
"id": 44, "id": 44,
@ -247,9 +237,7 @@ class TestPDCRetiredPackagesToddler:
msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages" msg.topic = "org.fedoraproject.prod.toddlers.trigger.pdc_retired_packages"
msg.body = {} msg.body = {}
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_dist_git( toddler._process_dist_git({}, client)
{}, client
)
client.get_paged.assert_has_calls(calls=[call(page_component_branches)]) client.get_paged.assert_has_calls(calls=[call(page_component_branches)])
retired_in_dg.assert_has_calls( retired_in_dg.assert_has_calls(
@ -310,7 +298,7 @@ class TestPDCRetiredPackagesToddler:
] ]
) )
def test__process_single_package_regular_commit(self, caplog): def test__process_single_package_regular_commit(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
client = MagicMock() client = MagicMock()
@ -328,13 +316,11 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package({}, client, msg)
{}, client, msg
)
assert caplog.records[-1].message == "No dead.package in the commit, bailing" assert caplog.records[-1].message == "No dead.package in the commit, bailing"
def test__process_single_package_un_retirement(self, caplog): def test__process_single_package_un_retirement(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
client = MagicMock() client = MagicMock()
@ -353,13 +339,11 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package({}, client, msg)
{}, client, msg
)
assert caplog.records[-1].message == "dead.package file was not added, bailing" assert caplog.records[-1].message == "dead.package file was not added, bailing"
def test__process_single_package_incomplete_config(self, caplog): def test__process_single_package_incomplete_config(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
client = MagicMock() client = MagicMock()
@ -381,13 +365,11 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package({}, client, msg)
{}, client, msg
)
assert caplog.records[-1].message == "No check URL configured, ignoring" assert caplog.records[-1].message == "No check URL configured, ignoring"
def test__process_single_package_package_not_in_pdc(self, caplog): def test__process_single_package_package_not_in_pdc(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
page_component_branches = { page_component_branches = {
@ -414,7 +396,7 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package(
{ {
"file_check_url": "https://src.fedoraproject.org/" "file_check_url": "https://src.fedoraproject.org/"
"%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s", "%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s",
@ -425,7 +407,7 @@ class TestPDCRetiredPackagesToddler:
assert caplog.records[-1].message == '"rpms/0ad" was not found in PDC' assert caplog.records[-1].message == '"rpms/0ad" was not found in PDC'
def test__process_single_package_namespace_not_in_pdc(self, caplog): def test__process_single_package_namespace_not_in_pdc(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
page_component_branches = { page_component_branches = {
@ -452,7 +434,7 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package(
{ {
"file_check_url": "https://src.fedoraproject.org/" "file_check_url": "https://src.fedoraproject.org/"
"%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s", "%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s",
@ -466,7 +448,7 @@ class TestPDCRetiredPackagesToddler:
== "Ignoring namespace 'flatpack', error: The namespace \"flatpack\" is not supported" == "Ignoring namespace 'flatpack', error: The namespace \"flatpack\" is not supported"
) )
def test__process_single_package_package_inactive(self, caplog): def test__process_single_package_package_inactive(self, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
page_component_branches = { page_component_branches = {
@ -504,7 +486,7 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package(
{ {
"file_check_url": "https://src.fedoraproject.org/" "file_check_url": "https://src.fedoraproject.org/"
"%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s", "%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s",
@ -516,7 +498,7 @@ class TestPDCRetiredPackagesToddler:
assert caplog.records[-1].message == '"rpms/0ad" not active in PDC in master' assert caplog.records[-1].message == '"rpms/0ad" not active in PDC in master'
@patch("requests.head") @patch("requests.head")
def test__process_single_package_package_not_retired(self, req, caplog): def test__process_single_package_package_not_retired(self, req, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
resp = Mock() resp = Mock()
resp.status_code = 404 resp.status_code = 404
@ -557,7 +539,7 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package(
{ {
"file_check_url": "https://src.fedoraproject.org/" "file_check_url": "https://src.fedoraproject.org/"
"%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s", "%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s",
@ -573,7 +555,7 @@ class TestPDCRetiredPackagesToddler:
@patch("toddlers.plugins.pdc_retired_packages._retire_branch") @patch("toddlers.plugins.pdc_retired_packages._retire_branch")
@patch("requests.head") @patch("requests.head")
def test__process_single_package(self, req, retire, caplog): def test__process_single_package(self, req, retire, toddler, caplog):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
resp = Mock() resp = Mock()
resp.status_code = 200 resp.status_code = 200
@ -614,7 +596,7 @@ class TestPDCRetiredPackagesToddler:
} }
} }
toddlers.plugins.pdc_retired_packages.PDCRetiredPackages._process_single_package( toddler._process_single_package(
{ {
"file_check_url": "https://src.fedoraproject.org/" "file_check_url": "https://src.fedoraproject.org/"
"%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s", "%(namespace)s/%(repo)s/blob/%(branch)s/f/%(file)s",

View file

@ -1,15 +1,18 @@
import toddlers.base from toddlers.base import ToddlerBase
class TestToddlerBase: class TestToddlerBase:
def test_name(self):
assert toddlers.base.ToddlerBase.name.fget() == "base"
def test_amqp_topics(self): toddler_cls = ToddlerBase
assert toddlers.base.ToddlerBase.amqp_topics.fget() == []
def test_accepts_topic(self): def test_name(self, toddler):
assert toddlers.base.ToddlerBase.accepts_topic("foo.bar") is None assert toddler.name == "base"
def test_process(self): def test_amqp_topics(self, toddler):
assert toddlers.base.ToddlerBase.process(config={}, message={}) is None assert toddler.amqp_topics == []
def test_accepts_topic(self, toddler):
assert toddler.accepts_topic("foo.bar") is None
def test_process(self, toddler):
assert toddler.process(config={}, message={}) is None

View file

@ -6,13 +6,13 @@ class ToddlerBase(object):
@property @property
@abc.abstractmethod @abc.abstractmethod
def name(): def name(self):
"""Returns name of the plugin.""" """Returns name of the plugin."""
return "base" return "base"
@property @property
@abc.abstractmethod @abc.abstractmethod
def amqp_topics(): def amqp_topics(self):
"""Returns the list of topics of interest for this toddler in a format """Returns the list of topics of interest for this toddler in a format
that can be used directly when connecting to amqp. that can be used directly when connecting to amqp.
For example, it supports items like: For example, it supports items like:
@ -24,13 +24,13 @@ class ToddlerBase(object):
return [] return []
@abc.abstractmethod @abc.abstractmethod
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
return return
@abc.abstractmethod @abc.abstractmethod
def process(config, message): def process(self, config, message):
"""Process a given message.""" """Process a given message."""
return return

View file

@ -24,13 +24,13 @@ class DebugToddler(ToddlerBase):
amqp_topics = ["#"] amqp_topics = ["#"]
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
return True return True
def process(config, message): def process(self, config, message):
"""Process a given message.""" """Process a given message."""
print(f"Debug Toddler received message: id:{message.id}, topic:{message.topic}") print(f"Debug Toddler received message: id:{message.id}, topic:{message.topic}")
print("Debug Toddler - Processing done") print("Debug Toddler - Processing done")

View file

@ -49,7 +49,7 @@ class FlagCIPR(ToddlerBase):
"org.centos.*.ci.dist-git-pr.test.running", "org.centos.*.ci.dist-git-pr.test.running",
] ]
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
@ -59,7 +59,7 @@ class FlagCIPR(ToddlerBase):
and topic.endswith(("complete", "error", "running")) and topic.endswith(("complete", "error", "running"))
) )
def process(config, message): def process(self, config, message):
"""Process a given message.""" """Process a given message."""
pipeline_state = None pipeline_state = None

View file

@ -56,7 +56,7 @@ class FlagCommitBuild(ToddlerBase):
"org.fedoraproject.*.buildsys.build.state.change", "org.fedoraproject.*.buildsys.build.state.change",
] ]
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
@ -64,7 +64,7 @@ class FlagCommitBuild(ToddlerBase):
"buildsys.build.state.change" "buildsys.build.state.change"
) )
def process(config, message): def process(self, config, message):
"""Process a given message.""" """Process a given message."""
msg = message.body msg = message.body

View file

@ -50,7 +50,7 @@ class PackagerBugzillaSync(ToddlerBase):
"org.fedoraproject.*.toddlers.trigger.packager_bugzilla_sync", "org.fedoraproject.*.toddlers.trigger.packager_bugzilla_sync",
] ]
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
@ -58,7 +58,7 @@ class PackagerBugzillaSync(ToddlerBase):
"toddlers.trigger.packager_bugzilla_sync" "toddlers.trigger.packager_bugzilla_sync"
) )
def process(config, message, username=False, dry_run=False): def process(self, config, message, username=False, dry_run=False):
"""Process a given message.""" """Process a given message."""
try: try:
@ -206,7 +206,7 @@ def main(args):
setup_logging(log_level=args.log_level) setup_logging(log_level=args.log_level)
config = toml.load(args.conf) config = toml.load(args.conf)
PackagerBugzillaSync.process( PackagerBugzillaSync().process(
config=config.get("consumer_config", {}).get("packager_bugzilla_sync", {}), config=config.get("consumer_config", {}).get("packager_bugzilla_sync", {}),
message={}, message={},
username=args.username, username=args.username,

View file

@ -42,7 +42,7 @@ class PDCRetiredPackages(ToddlerBase):
"org.fedoraproject.*.git.receive", "org.fedoraproject.*.git.receive",
] ]
def accepts_topic(topic): def accepts_topic(self, topic):
"""Returns a boolean whether this toddler is interested in messages """Returns a boolean whether this toddler is interested in messages
from this specific topic. from this specific topic.
""" """
@ -50,7 +50,7 @@ class PDCRetiredPackages(ToddlerBase):
("toddlers.trigger.pdc_retired_packages", "git.receive") ("toddlers.trigger.pdc_retired_packages", "git.receive")
) )
def process(config, message): def process(self, config, message):
"""Process a given message.""" """Process a given message."""
pdc = pdc_client.PDCClient(**config.get("pdc_config", {})) pdc = pdc_client.PDCClient(**config.get("pdc_config", {}))
@ -59,7 +59,7 @@ class PDCRetiredPackages(ToddlerBase):
else: else:
PDCRetiredPackages._process_dist_git(config, pdc) PDCRetiredPackages._process_dist_git(config, pdc)
def _process_dist_git(config, pdc): def _process_dist_git(self, config, pdc):
""" Updates PDC retirement status from analyzing dist-git. """ Updates PDC retirement status from analyzing dist-git.
This steps over all the branches in dist-git and retires any branches This steps over all the branches in dist-git and retires any branches
@ -83,7 +83,7 @@ class PDCRetiredPackages(ToddlerBase):
if retired_in_dist_git: if retired_in_dist_git:
_retire_branch(pdc, branch) _retire_branch(pdc, branch)
def _process_single_package(config, pdc, message): def _process_single_package(self, config, pdc, message):
"""Handle an incoming bus message. """Handle an incoming bus message.
The message should be a dist-git retirement message (where someone adds The message should be a dist-git retirement message (where someone adds

View file

@ -32,7 +32,7 @@ class RunningToddler(object):
if toddler.name in blocked_toddlers: if toddler.name in blocked_toddlers:
_log.info("Toddler '%s' is blocked, skipping it", toddler.name) _log.info("Toddler '%s' is blocked, skipping it", toddler.name)
continue continue
self.toddlers.append(toddler) self.toddlers.append(toddler())
_log.info("Loaded: %s", self.toddlers) _log.info("Loaded: %s", self.toddlers)
if not self.toddlers: if not self.toddlers:
raise fedora_messaging.exceptions.ConfigurationException( raise fedora_messaging.exceptions.ConfigurationException(