matrix-alertbot/tests/test_alert.py

199 lines
7 KiB
Python

import os
import re
import unittest
from typing import Dict
from matrix_alertbot.alert import Alert, AlertRenderer
TESTS_DIR = os.path.dirname(__file__)
class AlertTestCase(unittest.TestCase):
def setUp(self) -> None:
self.alert_dict: Dict = {
"fingerprint": "fingerprint1",
"generatorURL": "http://example.com",
"status": "unknown",
"labels": {"alertname": "alert1", "severity": "critical", "job": "job1"},
"annotations": {"description": "some description"},
}
def test_create_firing_alert_from_dict(self) -> None:
self.alert_dict["status"] = "firing"
alert = Alert.from_dict(self.alert_dict)
self.assertEqual("fingerprint1", alert.fingerprint)
self.assertEqual("http://example.com", alert.url)
self.assertTrue(alert.firing)
self.assertEqual("critical", alert.status)
self.assertDictEqual(
{"alertname": "alert1", "severity": "critical", "job": "job1"}, alert.labels
)
self.assertDictEqual({"description": "some description"}, alert.annotations)
def test_create_resolved_alert_from_dict(self) -> None:
self.alert_dict["status"] = "resolved"
alert = Alert.from_dict(self.alert_dict)
self.assertEqual("resolved", alert.status)
self.assertFalse(alert.firing)
def test_create_unknown_alert_from_dict(self) -> None:
alert = Alert.from_dict(self.alert_dict)
self.assertEqual("resolved", alert.status)
self.assertFalse(alert.firing)
def test_match_label(self) -> None:
alert = Alert.from_dict(self.alert_dict)
pattern = re.compile(r"^alert\d+$", re.I)
self.assertTrue(alert.match_label("alertname", pattern))
pattern = re.compile("alert2")
self.assertFalse(alert.match_label("alertname", pattern))
pattern = re.compile(r"^.*$", re.I)
self.assertFalse(alert.match_label("inexistent_label", pattern))
def test_match_all_labels(self) -> None:
alert = Alert.from_dict(self.alert_dict)
patterns = {
"alertname": re.compile(r"^alert\d+$", re.I),
"job": re.compile(r"^job\d+$", re.I),
}
self.assertTrue(alert.match_all_labels(patterns))
patterns = {
"alertname": re.compile(r"^alert\d+$", re.I),
"job": re.compile("job2"),
}
self.assertFalse(alert.match_all_labels(patterns))
patterns = {
"alertname": re.compile(r"^alert\d+$", re.I),
"inexistent_label": re.compile(r"^.*$", re.I),
}
self.assertFalse(alert.match_all_labels(patterns))
class AlertRendererTestCase(unittest.TestCase):
def setUp(self) -> None:
self.alert_dict: Dict = {
"fingerprint": "fingerprint1",
"generatorURL": "http://example.com",
"status": "unknown",
"labels": {"alertname": "alert1", "severity": "critical", "job": "job1"},
"annotations": {"description": "some description"},
}
self.renderer = AlertRenderer()
def test_render_firing_critical_alert(self) -> None:
self.alert_dict["status"] = "firing"
alert = Alert.from_dict(self.alert_dict)
alert.labels["severity"] = "critical"
html = self.renderer.render(alert, html=True)
self.assertEqual(
'<font color="#dc3545">\n <b>[🔥 CRITICAL]</b>\n</font> '
'<a href="http://example.com">alert1</a>\n (job1)<br/>\n'
"some description",
html,
)
plaintext = self.renderer.render(alert, html=False)
self.assertEqual("[🔥 CRITICAL] alert1: some description", plaintext)
def test_render_firing_warning_alert(self) -> None:
self.alert_dict["status"] = "firing"
self.alert_dict["labels"]["severity"] = "warning"
alert = Alert.from_dict(self.alert_dict)
html = self.renderer.render(alert, html=True)
self.assertEqual(
'<font color="#ffc107">\n <b>[⚠️ WARNING]</b>\n</font> '
'<a href="http://example.com">alert1</a>\n (job1)<br/>\n'
"some description",
html,
)
plaintext = self.renderer.render(alert, html=False)
self.assertEqual("[⚠️ WARNING] alert1: some description", plaintext)
def test_render_firing_unknown_alert(self) -> None:
self.alert_dict["status"] = "firing"
self.alert_dict["labels"]["severity"] = "unknown"
alert = Alert.from_dict(self.alert_dict)
with self.assertRaisesRegex(KeyError, "unknown"):
self.renderer.render(alert, html=True)
with self.assertRaisesRegex(KeyError, "unknown"):
self.renderer.render(alert, html=False)
def test_render_resolved_alert(self) -> None:
self.alert_dict["status"] = "resolved"
alert = Alert.from_dict(self.alert_dict)
html = self.renderer.render(alert, html=True)
self.assertEqual(
'<font color="#33cc33">\n <b>[🥦 RESOLVED]</b>\n</font> '
'<a href="http://example.com">alert1</a>\n (job1)<br/>\n'
"some description",
html,
)
plaintext = self.renderer.render(alert, html=False)
self.assertEqual("[🥦 RESOLVED] alert1: some description", plaintext)
def test_render_resolved_alert_without_job(self) -> None:
self.alert_dict["status"] = "resolved"
del self.alert_dict["labels"]["job"]
alert = Alert.from_dict(self.alert_dict)
html = self.renderer.render(alert, html=True)
self.assertEqual(
'<font color="#33cc33">\n <b>[🥦 RESOLVED]</b>\n</font> '
'<a href="http://example.com">alert1</a>\n<br/>\n'
"some description",
html,
)
plaintext = self.renderer.render(alert, html=False)
self.assertEqual("[🥦 RESOLVED] alert1: some description", plaintext)
def test_render_with_existing_filesystem_template(self) -> None:
alert = Alert.from_dict(self.alert_dict)
template_dir = os.path.join(TESTS_DIR, "resources/templates")
renderer = AlertRenderer(template_dir)
html = renderer.render(alert, html=True)
self.assertEqual(
"<b>hello world</b>",
html,
)
plaintext = renderer.render(alert, html=False)
self.assertEqual("hello world", plaintext)
def test_render_with_inexistent_filesystem_template(self) -> None:
self.alert_dict["status"] = "resolved"
alert = Alert.from_dict(self.alert_dict)
renderer = AlertRenderer(TESTS_DIR)
html = renderer.render(alert, html=True)
self.assertEqual(
'<font color="#33cc33">\n <b>[🥦 RESOLVED]</b>\n</font> '
'<a href="http://example.com">alert1</a>\n (job1)<br/>\n'
"some description",
html,
)
plaintext = renderer.render(alert, html=False)
self.assertEqual("[🥦 RESOLVED] alert1: some description", plaintext)
if __name__ == "__main__":
unittest.main()