Revamp zone sync and add tests
This commit is contained in:
1 parent
0123dd1e3b
commit
e96948080f
11 files changed
+792
-184
No files matched your search
@@ -0,0 +1,109 @@
|
||||
from io import StringIO
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from mdb.management.commands.zone_sync import Command as CommandClass
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cmd():
|
||||
c = CommandClass()
|
||||
c.stdout = StringIO()
|
||||
c.stderr = StringIO()
|
||||
return c
|
||||
|
||||
|
||||
def make_service(changes=None):
|
||||
svc = MagicMock()
|
||||
svc.changes = changes or {
|
||||
"example.org": {"errors": None, "diff": "- old\n+ new", "success": True}
|
||||
}
|
||||
svc.run_reload_commands.return_value = (True, "", "")
|
||||
return svc
|
||||
|
||||
|
||||
# --- run_reload_commands ---
|
||||
|
||||
def test_run_reload_commands_calls_all_on_success(service):
|
||||
with patch("mdb.services.zone_sync.getstatusoutput", return_value=(0, "")) as mock:
|
||||
success, _, _ = service.run_reload_commands()
|
||||
assert success is True
|
||||
assert mock.call_count == 3
|
||||
|
||||
|
||||
def test_run_reload_commands_stops_on_first_failure(service):
|
||||
with patch(
|
||||
"mdb.services.zone_sync.getstatusoutput",
|
||||
side_effect=[(0, ""), (1, "connection refused"), (0, "")],
|
||||
) as mock:
|
||||
success, failed_cmd, output = service.run_reload_commands()
|
||||
assert success is False
|
||||
assert "reload" in failed_cmd
|
||||
assert output == "connection refused"
|
||||
assert mock.call_count == 2 # thaw never reached
|
||||
|
||||
|
||||
# --- reload_and_notify ---
|
||||
|
||||
def test_reload_and_notify_success_writes_ok(cmd):
|
||||
svc = make_service()
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins"):
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones="example.org")
|
||||
assert "ok" in cmd.stdout.getvalue()
|
||||
|
||||
|
||||
def test_reload_and_notify_success_sends_mail(cmd):
|
||||
svc = make_service()
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins") as mock_mail:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="diff", zones="example.org")
|
||||
mock_mail.assert_called_once()
|
||||
assert "Success" in mock_mail.call_args.kwargs["subject"]
|
||||
|
||||
|
||||
def test_reload_and_notify_failure_writes_fail_and_exits(cmd):
|
||||
svc = make_service()
|
||||
svc.run_reload_commands.return_value = (False, "/usr/sbin/rndc freeze", "timed out")
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins"):
|
||||
with patch("os.getlogin", return_value="testuser"):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones="example.org")
|
||||
assert exc.value.code == 1
|
||||
assert "fail" in cmd.stdout.getvalue()
|
||||
|
||||
|
||||
def test_reload_and_notify_failure_mail_includes_command_and_output(cmd):
|
||||
svc = make_service()
|
||||
svc.run_reload_commands.return_value = (False, "/usr/sbin/rndc freeze", "timed out")
|
||||
with patch("mdb.management.commands.zone_sync.mail_admins") as mock_mail:
|
||||
with patch("os.getlogin", return_value="testuser"):
|
||||
with pytest.raises(SystemExit):
|
||||
cmd.reload_and_notify(svc, errors="", diffs="", zones="example.org")
|
||||
subject = mock_mail.call_args.kwargs["subject"]
|
||||
message = mock_mail.call_args.kwargs["message"]
|
||||
assert "FAIL" in subject
|
||||
assert "rndc freeze" in message
|
||||
assert "timed out" in message
|
||||
|
||||
|
||||
# --- handle ---
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_handle_exits_if_zone_not_found(cmd):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
cmd.handle(debug=True, force=False, zone="nonexistent.example")
|
||||
assert exc.value.code == 1
|
||||
assert "nonexistent.example" in cmd.stderr.getvalue()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_handle_skips_reload_in_debug_mode(cmd, db_domain):
|
||||
with patch.object(cmd, "reload_and_notify") as mock_reload:
|
||||
cmd.handle(debug=True, force=True, zone="example.org")
|
||||
mock_reload.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_handle_calls_reload_and_notify_when_changes_exist(cmd, db_domain):
|
||||
with patch.object(cmd, "reload_and_notify") as mock_reload:
|
||||
cmd.handle(debug=False, force=True, zone="example.org")
|
||||
mock_reload.assert_called_once()
|
||||
Reference in new issue
Block a user