Files
dns-sync/tests/test_registry.py
T

226 lines
6.0 KiB
Python

import os
import tempfile
import textwrap
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
from dns_sync.adapters import Endpoint
from dns_sync.registry import (
enabled_plugins,
load_adapter,
)
class PluginRegistryTests(unittest.TestCase):
def test_default_enabled_plugin_is_npm(self):
with patch.dict(os.environ, {}, clear=True):
self.assertEqual(
enabled_plugins(),
frozenset({"npm"}),
)
def test_enabled_plugins_are_explicit(self):
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": (
"npm,verizon"
)
},
clear=True,
):
self.assertEqual(
enabled_plugins(),
frozenset(
{
"npm",
"verizon",
}
),
)
def test_duplicate_enabled_plugin_is_rejected(self):
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": "npm,npm",
},
clear=True,
):
with self.assertRaisesRegex(
RuntimeError,
"duplicate plugin",
):
enabled_plugins()
def test_disabled_adapter_is_not_loaded(self):
config = SimpleNamespace()
endpoint = Endpoint(
"verizon",
"192.168.1.1:443",
)
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": "npm",
},
clear=True,
):
with self.assertRaisesRegex(
RuntimeError,
"is not enabled",
):
load_adapter(
"verizon",
config,
endpoint,
)
def test_external_adapter_is_loaded(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
plugin = root / "example"
plugin.mkdir()
(plugin / "__init__.py").write_text(
textwrap.dedent(
"""
class Plugin:
name = "example"
def __init__(
self,
config,
endpoint,
):
self.config = config
self.endpoint = endpoint
"""
)
)
config = SimpleNamespace()
endpoint = Endpoint(
"example",
"example.test:443",
)
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": (
"example"
),
"DNS_SYNC_PLUGIN_PATH": (
directory
),
},
clear=True,
):
adapter = load_adapter(
"example",
config,
endpoint,
)
self.assertEqual(
adapter.name,
"example",
)
self.assertEqual(
adapter.endpoint,
endpoint,
)
def test_external_adapter_can_import_plugin_submodule(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
plugin = root / "example_package"
plugin.mkdir()
(plugin / "helper.py").write_text(
"VALUE = 'loaded-from-submodule'\n"
)
(plugin / "__init__.py").write_text(
textwrap.dedent(
"""
from .helper import VALUE
class Plugin:
name = "example_package"
def __init__(
self,
config,
endpoint,
):
self.config = config
self.endpoint = endpoint
self.value = VALUE
"""
)
)
config = SimpleNamespace()
endpoint = Endpoint(
"example_package",
"example.test:443",
)
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": (
"example_package"
),
"DNS_SYNC_PLUGIN_PATH": directory,
},
clear=True,
):
adapter = load_adapter(
"example_package",
config,
endpoint,
)
self.assertEqual(
adapter.value,
"loaded-from-submodule",
)
def test_missing_enabled_adapter_fails_closed(self):
with tempfile.TemporaryDirectory() as directory:
config = SimpleNamespace()
endpoint = Endpoint(
"missing",
"example.test:443",
)
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": "missing",
"DNS_SYNC_PLUGIN_PATH": (
directory
),
},
clear=True,
):
with self.assertRaisesRegex(
RuntimeError,
"Unknown adapter plugin",
):
load_adapter(
"missing",
config,
endpoint,
)
if __name__ == "__main__":
unittest.main()