Add unit-tests for toddlers

Signed-off-by: Pierre-Yves Chibon <pingou@pingoured.fr>
This commit is contained in:
Pierre-Yves Chibon 2020-06-19 17:10:01 +02:00
parent 6216256b38
commit edeafd6159
6 changed files with 582 additions and 0 deletions

View file

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

View file

@ -0,0 +1,159 @@
import logging
from unittest.mock import patch, MagicMock
import toddlers.plugins.flag_ci_pr
import pytest
import fedora_messaging.api
class TestFlagCIPRToddler:
def test_accepts_topic_invalid(self):
assert toddlers.plugins.flag_ci_pr.FlagCIPR.accepts_topic("foo.bar") == False
@pytest.mark.parametrize(
"topic",
[
"org.centos.#.ci.dist-git-pr.test.error",
"org.centos.prod.ci.dist-git-pr.test.error",
"org.centos.stage.ci.dist-git-pr.test.error",
"org.centos.#.ci.dist-git-pr.test.complete"
"org.centos.prod.ci.dist-git-pr.test.complete"
"org.centos.stg.ci.dist-git-pr.test.complete"
"org.centos.#.ci.dist-git-pr.test.running",
"org.centos.prod.ci.dist-git-pr.test.running",
"org.centos.stg.ci.dist-git-pr.test.running",
],
)
def test_accepts_topic_valid(self, topic):
assert toddlers.plugins.flag_ci_pr.FlagCIPR.accepts_topic(topic) == True
def test_process_invalid(self):
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "toddlers.test.topic"
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) == None
)
def test_process_invalid_status(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.invalid"
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) == None
)
assert (
caplog.records[-1].message
== "Pipeline state is not 'complete' or 'running' or 'error'."
)
def test_process_no_version(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete"
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) == None
)
assert caplog.records[-1].message == "Unsupported msg version, ignoring"
def test_process_invalid_complete_status(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete"
msg.body = {"version": "0.2.1", "test": {"result": "invalid",}}
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) == None
)
assert (
caplog.records[-1].message
== "Build is not in one of the expected status, ignoring"
)
def test_process_no_artifact(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.complete"
msg.body = {
"version": "0.2.1",
"test": {"result": "passed",},
"artifact": {"commit_hash": "abcdefghijklmnopqrst",},
}
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config={}, message=msg) == None
)
assert (
caplog.records[-1].message
== "Invalid message: {'commit_hash': 'abcdefghijklmnopqrst'}, could not extract the PR id from it"
)
@patch("toddlers.plugins.flag_ci_pr.requests_session")
def test_process_request_failed(self, mock_requests, caplog):
mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid"
)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.running"
msg.body = {
"version": "0.2.1",
"test": {"result": "passed",},
"artifact": {
"id": 456,
"commit_hash": "abcdefghijklmnopqrst",
"repository": "namespace/name",
},
"run": {"url": "https://example.com/testing",},
}
config = {
"pagure_token_seed": "example_seed",
"pagure_url": "https://pagure.io",
"pagure_token": "ahah",
}
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config=config, message=msg)
== 1
)
assert (
caplog.records[-1].message == "Request to https://pagure.io returned: 401"
)
@patch("toddlers.plugins.flag_ci_pr.requests_session")
def test_process_valid(self, mock_requests, caplog):
mock_requests.request.return_value = MagicMock(
ok=True, status_code=200, text="invalid"
)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.centos.stg.ci.dist-git-pr.test.error"
msg.body = {
"version": "0.2.1",
"test": {"result": "passed",},
"artifact": {
"id": 456,
"commit_hash": "abcdefghijklmnopqrst",
"repository": "namespace/name",
},
"run": {"url": "https://example.com/testing",},
}
config = {
"pagure_token_seed": "example_seed",
"pagure_url": "https://pagure.io",
"pagure_token": "ahah",
}
assert (
toddlers.plugins.flag_ci_pr.FlagCIPR.process(config=config, message=msg)
== None
)
assert (
caplog.records[-2].message == "Request to https://pagure.io returned: 200"
)
assert caplog.records[-1].message == "All clear"

View file

@ -0,0 +1,292 @@
import logging
from unittest.mock import patch, MagicMock, Mock
import fedora_messaging.api
import pytest
import toddlers.plugins.flag_commit_build
class TestFlagCommitBuildToddler:
def test_accepts_topic_invalid(self):
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.accepts_topic("foo.bar")
== False
)
@pytest.mark.parametrize(
"topic",
[
"org.fedoraproject.#.buildsys.build.state.change",
"org.fedoraproject.stg.buildsys.build.state.change",
"org.fedoraproject.prod.buildsys.build.state.change",
],
)
def test_accepts_topic_valid(self, topic):
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.accepts_topic(topic)
== True
)
def test_process_containerbuild(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {"owner": "containerbuild"}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
== None
)
assert caplog.records[-1].message == "Skipping container build"
def test_process_mbs_build(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {"owner": "mbs/mbs.fedoraproject.org"}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
== None
)
assert caplog.records[-1].message == "Skipping MBS builds"
def test_process_secondary_instance(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "secondary",
}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
== None
)
assert caplog.records[-1].message == "Ignoring secondary arch task..."
def test_process_uninteresting_status(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 2,
}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config={}, message=msg
)
== None
)
assert (
caplog.records[-1].message
== "Build is not in a state we care about, skipping"
)
@patch("toddlers.plugins.flag_commit_build.koji")
def test_process_no_git_url(self, mock_koji, caplog):
client = Mock()
client.getBuild = Mock(return_value={})
mock_koji.ClientSession = Mock(return_value=client)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 1,
"build_id": 42,
}
config = {"koji_url": "https://koji.fedoraproject.org"}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
== None
)
assert (
caplog.records[-1].message
== "No git url found in the extra information: None"
)
@patch("toddlers.plugins.flag_commit_build.koji")
def test_process_invalid_git_url(self, mock_koji, caplog):
client = Mock()
client.getBuild = Mock(
return_value={"extra": {"source": {"original_url": "foobar"}}}
)
mock_koji.ClientSession = Mock(return_value=client)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 4,
"build_id": 42,
}
config = {"koji_url": "https://koji.fedoraproject.org"}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
== None
)
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.koji")
def test_process_flag_failed(self, mock_koji, mock_requests, caplog):
mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid"
)
client = Mock()
client.getBuild = Mock(
return_value={
"extra": {
"source": {
"original_url": "https://src.fedoraproject.org/rpms/guake.git#commit_hash123"
}
}
}
)
mock_koji.ClientSession = Mock(return_value=client)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 3,
"build_id": 42,
"epoch": "0",
"version": "1.0.0",
"name": "guake",
"release": "1",
"task_id": 84,
}
config = {
"koji_url": "https://koji.fedoraproject.org",
"pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah",
}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
== None
)
assert (
caplog.records[-1].message
== "Request to https://src.fedoraproject.org returned: 401"
)
@patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_failed_cancel(self, mock_koji, mock_requests, caplog):
mock_requests.request.return_value = MagicMock(
ok=False, status_code=401, text="invalid"
)
client = Mock()
client.getBuild = Mock(
return_value={
"extra": {
"source": {
"original_url": "https://src.fedoraproject.org/rpms/guake.git#commit_hash123"
}
}
}
)
mock_koji.ClientSession = Mock(return_value=client)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 4,
"build_id": 42,
"epoch": "0",
"version": "1.0.0",
"name": "guake",
"release": "1",
"task_id": 84,
}
config = {
"koji_url": "https://koji.fedoraproject.org",
"pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah",
}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
== None
)
assert (
caplog.records[-1].message
== "Request to https://src.fedoraproject.org returned: 401"
)
@patch("toddlers.plugins.flag_commit_build.requests_session")
@patch("toddlers.plugins.flag_commit_build.koji")
def test_process_flag_pass(self, mock_koji, mock_requests, caplog):
mock_requests.request.return_value = MagicMock(
ok=True, status_code=200, text="woohoo!"
)
client = Mock()
client.getBuild = Mock(
return_value={
"extra": {
"source": {
"original_url": "https://src.fedoraproject.org/rpms/guake.git#commit_hash123"
}
}
}
)
mock_koji.ClientSession = Mock(return_value=client)
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "org.fedoraproject.prod.buildsys.build.state.change"
msg.body = {
"owner": "username",
"instance": "primary",
"new": 1,
"build_id": 42,
"version": "1.0.0",
"name": "guake",
"release": "1",
"task_id": 84,
}
config = {
"koji_url": "https://koji.fedoraproject.org",
"pagure_url": "https://src.fedoraproject.org",
"pagure_token": "ahah",
}
assert (
toddlers.plugins.flag_commit_build.FlagCommitBuild.process(
config=config, message=msg
)
== None
)
assert (
caplog.records[-2].message
== "Request to https://src.fedoraproject.org returned: 200"
)
assert caplog.records[-1].message == "All clear"

View file

@ -0,0 +1,14 @@
import toddlers.plugins
def test_toddlers_plugins():
variables = [var for var in dir(toddlers.plugins) if not var.startswith("__")]
assert sorted(variables) == [
"debug",
"flag_ci_pr",
"flag_commit_build",
"here",
"importlib",
"name",
"os",
]

15
tests/test_base.py Normal file
View file

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

86
tests/test_runner.py Normal file
View file

@ -0,0 +1,86 @@
import logging
from unittest.mock import patch, Mock
import fedora_messaging.api
import fedora_messaging.exceptions
import pytest
import toddlers.runner
class TestRunningToddler:
def test___init__(self):
runner = toddlers.runner.RunningToddler()
assert sorted([t.name for t in runner.toddlers]) == [
"debug",
"flag_ci_pr",
"flag_commit_build",
]
@patch("toddlers.base.ToddlerBase")
def test___init__no_toddlers(self, mock_base, caplog):
mock_base.__subclasses__ = Mock(return_value=[])
caplog.set_level(logging.INFO)
with pytest.raises(
fedora_messaging.exceptions.ConfigurationException,
match=r".* No toddlers found to run .*",
):
runner = toddlers.runner.RunningToddler()
assert sorted([t.name for t in runner.toddlers]) == [
"debug",
"flag_ci_pr",
"flag_commit_build",
]
assert caplog.records[-2].message == "Toddlers processing: 123 -- foo.bar"
assert (
caplog.records[-1].message
== "Toddler 'debug' accepted to process message id: 123"
)
@patch.dict(
"toddlers.runner.fedora_messaging.config.conf",
{"consumer_config": {"blocked_toddlers": ["debug", "flag_ci_pr"]}},
)
def test___init__blockedlist(self, caplog):
runner = toddlers.runner.RunningToddler()
assert sorted([t.name for t in runner.toddlers]) == ["flag_commit_build"]
def test___call__(self, caplog):
caplog.set_level(logging.INFO)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "foo.bar"
msg.body = {
"owner": "username",
"instance": "secondary",
}
runner = toddlers.runner.RunningToddler()
runner.__call__(msg)
assert caplog.records[-3].message.startswith("Topics of interest:")
assert caplog.records[-2].message == "Toddlers processing: 123 -- foo.bar"
assert (
caplog.records[-1].message
== "Toddler 'debug' accepted to process message id: 123"
)
@patch("toddlers.plugins.debug.DebugToddler.process", side_effect=Exception("haha"))
def test___call__exception(self, caplog):
caplog.set_level(logging.DEBUG)
msg = fedora_messaging.api.Message()
msg.id = 123
msg.topic = "foo.bar"
msg.body = {
"owner": "username",
"instance": "secondary",
}
runner = toddlers.runner.RunningToddler()
with pytest.raises(
fedora_messaging.exceptions.Nack, match=r"A toddler tripped"
):
runner.__call__(msg)
assert caplog.records[-3].message.startswith("Topics of interest:")
assert caplog.records[-2].message == "Toddlers processing: 123 -- foo.bar"
assert (
caplog.records[-1].message
== "Toddler 'debug' accepted to process message id: 123"
)