151 lines
4.6 KiB
Python
151 lines
4.6 KiB
Python
from datetime import datetime
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from minitor.main import InvalidMonitorException
|
|
from minitor.main import MinitorAlert
|
|
from minitor.main import Monitor
|
|
from minitor.main import validate_monitor_settings
|
|
from tests.util import assert_called_once
|
|
|
|
|
|
class TestMonitor(object):
|
|
@pytest.fixture
|
|
def monitor(self):
|
|
return Monitor(
|
|
{
|
|
"name": "Sample Monitor",
|
|
"command": ["echo", "foo"],
|
|
"alert_down": ["log"],
|
|
"alert_up": ["log"],
|
|
"check_interval": 1,
|
|
"alert_after": 1,
|
|
"alert_every": 1,
|
|
}
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"settings",
|
|
[
|
|
{"alert_after": 0},
|
|
{"alert_every": 0},
|
|
{"check_interval": 0},
|
|
{"alert_after": "invalid"},
|
|
{"alert_every": "invalid"},
|
|
{"check_interval": "invalid"},
|
|
],
|
|
)
|
|
def test_monitor_invalid_configuration(self, settings):
|
|
with pytest.raises(InvalidMonitorException):
|
|
validate_monitor_settings(settings)
|
|
|
|
@pytest.mark.parametrize(
|
|
"alert_after",
|
|
[1, 20],
|
|
ids=lambda arg: "alert_after({})".format(arg),
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"alert_every",
|
|
[-1, 1, 2, 1440],
|
|
ids=lambda arg: "alert_every({})".format(arg),
|
|
)
|
|
def test_monitor_alert_after(self, monitor, alert_after, alert_every):
|
|
monitor.alert_after = alert_after
|
|
monitor.alert_every = alert_every
|
|
|
|
# fail a bunch of times before the final failure
|
|
for _ in range(alert_after - 1):
|
|
monitor.failure()
|
|
|
|
# this time should raise an alert
|
|
with pytest.raises(MinitorAlert):
|
|
monitor.failure()
|
|
|
|
@pytest.mark.parametrize(
|
|
"alert_after",
|
|
[1, 20],
|
|
ids=lambda arg: "alert_after({})".format(arg),
|
|
)
|
|
@pytest.mark.parametrize(
|
|
"alert_every",
|
|
[1, 2, 1440],
|
|
ids=lambda arg: "alert_every({})".format(arg),
|
|
)
|
|
def test_monitor_alert_every(self, monitor, alert_after, alert_every):
|
|
monitor.alert_after = alert_after
|
|
monitor.alert_every = alert_every
|
|
|
|
# fail a bunch of times before the final failure
|
|
for _ in range(alert_after - 1):
|
|
monitor.failure()
|
|
|
|
# this time should raise an alert
|
|
with pytest.raises(MinitorAlert):
|
|
monitor.failure()
|
|
|
|
# fail a bunch more times until the next alert
|
|
for _ in range(alert_every - 1):
|
|
monitor.failure()
|
|
|
|
# this failure should alert now
|
|
with pytest.raises(MinitorAlert):
|
|
monitor.failure()
|
|
|
|
def test_monitor_alert_every_exponential(self, monitor):
|
|
monitor.alert_after = 1
|
|
monitor.alert_every = -1
|
|
|
|
failure_count = 16
|
|
expect_failures_on = {1, 2, 4, 8, 16}
|
|
|
|
for i in range(failure_count):
|
|
if i + 1 in expect_failures_on:
|
|
with pytest.raises(MinitorAlert):
|
|
monitor.failure()
|
|
else:
|
|
monitor.failure()
|
|
|
|
@pytest.mark.parametrize("last_check", [None, datetime(2018, 4, 10)])
|
|
def test_monitor_should_check(self, monitor, last_check):
|
|
monitor.last_check = last_check
|
|
assert monitor.should_check()
|
|
|
|
def test_monitor_check_fail(self, monitor):
|
|
assert monitor.last_output is None
|
|
with patch.object(monitor, "failure") as mock_failure:
|
|
monitor.command = ["ls", "--not-real"]
|
|
assert not monitor.check()
|
|
assert_called_once(mock_failure)
|
|
assert monitor.last_output is not None
|
|
|
|
def test_monitor_check_success(self, monitor):
|
|
assert monitor.last_output is None
|
|
with patch.object(monitor, "success") as mock_success:
|
|
assert monitor.check()
|
|
assert_called_once(mock_success)
|
|
assert monitor.last_output is not None
|
|
|
|
@pytest.mark.parametrize("failure_count", [0, 1])
|
|
def test_monitor_success(self, monitor, failure_count):
|
|
monitor.alert_count = 0
|
|
monitor.total_failure_count = failure_count
|
|
assert monitor.last_success is None
|
|
|
|
monitor.success()
|
|
|
|
assert monitor.alert_count == 0
|
|
assert monitor.last_success is not None
|
|
assert monitor.total_failure_count == 0
|
|
|
|
def test_monitor_success_back_up(self, monitor):
|
|
monitor.total_failure_count = 1
|
|
monitor.alert_count = 1
|
|
|
|
with pytest.raises(MinitorAlert):
|
|
monitor.success()
|
|
|
|
assert monitor.alert_count == 0
|
|
assert monitor.last_success is not None
|
|
assert monitor.total_failure_count == 0
|