new file: conftest.py
new file: netbox_dns_bridge/tests/__init__.py new file: netbox_dns_bridge/tests/_helpers.py new file: netbox_dns_bridge/tests/conftest.py new file: netbox_dns_bridge/tests/test_bootstrap.py new file: netbox_dns_bridge/tests/test_catalog_zone_manager.py new file: netbox_dns_bridge/tests/test_dns_server.py new file: netbox_dns_bridge/tests/test_management_commands.py new file: netbox_dns_bridge/tests/test_models.py new file: netbox_dns_bridge/tests/test_notify_handler.py new file: netbox_dns_bridge/tests/test_request_handler_integration.py new file: netbox_dns_bridge/tests/test_request_handler_unit.py new file: netbox_dns_bridge/tests/test_signals.py new file: netbox_dns_bridge/tests/test_smoke.py new file: netbox_dns_bridge/tests/test_utils.py new file: netbox_dns_bridge/tests/test_views.py modified: pyproject.toml Add some tests. #AI generated
This commit is contained in:
1 parent
e8762bf807
commit
4ad110ca53
17 files changed
+2680
No files matched your search
@@ -0,0 +1,197 @@
|
||||
"""Tests for management commands: dns-settings, dns-export-zone, dns-export-zones,
|
||||
dns-transfer-endpoint."""
|
||||
import os
|
||||
import tempfile
|
||||
from io import StringIO
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
import pytest
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import CommandError
|
||||
|
||||
from netbox_dns_bridge.models import IntegerKeyValueSetting
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestDnsSettingsCommand:
|
||||
def test_list_empty(self):
|
||||
IntegerKeyValueSetting.objects.all().delete()
|
||||
out = StringIO()
|
||||
call_command("dns-settings", "list", stdout=out)
|
||||
assert "No settings found" in out.getvalue()
|
||||
|
||||
def test_list_with_entries(self):
|
||||
IntegerKeyValueSetting.objects.create(key="k1", value=10)
|
||||
IntegerKeyValueSetting.objects.create(key="k2", value=20)
|
||||
out = StringIO()
|
||||
call_command("dns-settings", "list", stdout=out)
|
||||
output = out.getvalue()
|
||||
assert "k1: 10" in output
|
||||
assert "k2: 20" in output
|
||||
|
||||
def test_get_existing(self):
|
||||
IntegerKeyValueSetting.objects.create(key="serial", value=42)
|
||||
out = StringIO()
|
||||
call_command("dns-settings", "get", "serial", stdout=out)
|
||||
assert "serial: 42" in out.getvalue()
|
||||
|
||||
def test_get_missing_raises(self):
|
||||
with pytest.raises(CommandError, match="No setting"):
|
||||
call_command("dns-settings", "get", "nonexistent")
|
||||
|
||||
def test_get_without_key_raises(self):
|
||||
with pytest.raises(CommandError, match="key is required"):
|
||||
call_command("dns-settings", "get")
|
||||
|
||||
def test_set_existing(self):
|
||||
IntegerKeyValueSetting.objects.create(key="counter", value=5)
|
||||
out = StringIO()
|
||||
call_command("dns-settings", "set", "counter", 99, stdout=out)
|
||||
assert "Updated counter from 5 to 99" in out.getvalue()
|
||||
assert IntegerKeyValueSetting.objects.get(key="counter").value == 99
|
||||
|
||||
def test_set_missing_key_raises(self):
|
||||
with pytest.raises(CommandError, match="setting is required"):
|
||||
call_command("dns-settings", "set")
|
||||
|
||||
def test_set_without_value_raises(self):
|
||||
IntegerKeyValueSetting.objects.create(key="needval", value=1)
|
||||
with pytest.raises(CommandError, match="value is required"):
|
||||
call_command("dns-settings", "set", "needval")
|
||||
|
||||
def test_set_nonexistent_setting_raises(self):
|
||||
with pytest.raises(CommandError, match="No setting found"):
|
||||
call_command("dns-settings", "set", "ghost", 1)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestDnsExportZoneCommand:
|
||||
def test_exports_zone_file(self, make_zone, make_record):
|
||||
zone = make_zone(name="export-cmd.test")
|
||||
make_record(zone, name="www", type_="A", value="192.0.2.1")
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
path = os.path.join(td, "zone.db")
|
||||
out = StringIO()
|
||||
call_command(
|
||||
"dns-export-zone",
|
||||
"--view", zone.view.name,
|
||||
"--zone", "export-cmd.test",
|
||||
"--file", path,
|
||||
stdout=out,
|
||||
)
|
||||
assert os.path.exists(path)
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
assert "SOA" in content
|
||||
assert "192.0.2.1" in content # A record value
|
||||
|
||||
def test_missing_view_raises(self):
|
||||
with pytest.raises(CommandError, match="--view"):
|
||||
call_command("dns-export-zone", "--zone", "z.test", "--file", "/tmp/x")
|
||||
|
||||
def test_missing_zone_raises(self):
|
||||
with pytest.raises(CommandError, match="--zone"):
|
||||
call_command("dns-export-zone", "--view", "default", "--file", "/tmp/x")
|
||||
|
||||
def test_missing_file_raises(self):
|
||||
with pytest.raises(CommandError, match="--file"):
|
||||
call_command("dns-export-zone", "--view", "default", "--zone", "z.test")
|
||||
|
||||
def test_nonexistent_zone_raises(self, make_view):
|
||||
make_view(name="default")
|
||||
with pytest.raises(CommandError, match="Failed to export zone"):
|
||||
call_command(
|
||||
"dns-export-zone",
|
||||
"--view", "default",
|
||||
"--zone", "does-not-exist.test",
|
||||
"--file", "/tmp/x.zone",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestDnsExportZonesCommand:
|
||||
def test_exports_all_zones(self, make_zone, make_view):
|
||||
make_zone(name="batch1.test")
|
||||
make_zone(name="batch2.test")
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
out = StringIO()
|
||||
call_command("dns-export-zones", "--path", td, stdout=out)
|
||||
output = out.getvalue()
|
||||
assert "batch1.test" in output
|
||||
assert "batch2.test" in output
|
||||
for zone_name in ("batch1.test", "batch2.test"):
|
||||
for root, dirs, files in os.walk(td):
|
||||
if zone_name in files:
|
||||
break
|
||||
else:
|
||||
pytest.fail(f"Zone file for {zone_name} not found")
|
||||
|
||||
def test_creates_view_subdirectories(self, make_zone, make_view):
|
||||
make_zone(name="subdir.test")
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
out = StringIO()
|
||||
call_command("dns-export-zones", "--path", td, stdout=out)
|
||||
view_dirs = os.listdir(td)
|
||||
assert len(view_dirs) > 0
|
||||
|
||||
def test_missing_path_raises(self):
|
||||
with pytest.raises(CommandError, match="--path"):
|
||||
call_command("dns-export-zones")
|
||||
|
||||
def test_no_zones_warning(self):
|
||||
from netbox_dns.models import Zone
|
||||
|
||||
Zone.objects.all().delete()
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
out = StringIO()
|
||||
call_command("dns-export-zones", "--path", td, stdout=out)
|
||||
assert "No zones found" in out.getvalue()
|
||||
|
||||
def test_creates_path_if_not_exists(self, make_zone):
|
||||
make_zone(name="mkpath.test")
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
path = os.path.join(td, "subdir1", "subdir2")
|
||||
out = StringIO()
|
||||
call_command("dns-export-zones", "--path", path, stdout=out)
|
||||
assert os.path.isdir(path)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestDnsTransferEndpointCommand:
|
||||
def _get_cmd_module(self):
|
||||
"""Load the dns-transfer-endpoint command module (hyphen in filename)."""
|
||||
import sys
|
||||
from django.core.management import load_command_class
|
||||
|
||||
cmd = load_command_class("netbox_dns_bridge", "dns-transfer-endpoint")
|
||||
return sys.modules[cmd.__module__]
|
||||
|
||||
def test_missing_tsig_keys_raises(self, monkeypatch):
|
||||
cmd_mod = self._get_cmd_module()
|
||||
monkeypatch.setattr(cmd_mod, "SETTINGS", {})
|
||||
with pytest.raises(RuntimeError, match="tsig_keys variable not set"):
|
||||
call_command("dns-transfer-endpoint")
|
||||
|
||||
def test_loads_tsig_keys_and_starts_servers(
|
||||
self, monkeypatch, make_view
|
||||
):
|
||||
cmd_mod = self._get_cmd_module()
|
||||
|
||||
view = make_view(name="ep-view")
|
||||
monkeypatch.setattr(cmd_mod, "SETTINGS", {
|
||||
"tsig_keys": {
|
||||
"ep-view": {
|
||||
"keyname": "epkey.",
|
||||
"secret": "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWE=",
|
||||
"algorithm": "hmac-sha256",
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with patch.object(cmd_mod, "TCPDNSServer") as mock_tcp, \
|
||||
patch.object(cmd_mod, "UDPDNSServer") as mock_udp:
|
||||
mock_tcp.return_value.serve_forever = MagicMock()
|
||||
mock_udp.return_value.serve_forever = MagicMock()
|
||||
call_command("dns-transfer-endpoint", "--port", "0", "--address", "127.0.0.1")
|
||||
assert mock_tcp.called
|
||||
assert mock_udp.called
|
||||
Reference in new issue
Block a user