Extract shared adapter validation helpers

This commit is contained in:
Lyncoln
2026-09-20 18:47:21 -04:00
parent d4ceb7e1df
commit 832928159d
6 changed files with 232 additions and 28 deletions
+106
View File
@@ -0,0 +1,106 @@
import unittest
from dns_sync.adapter_support import (
require_action_endpoint,
require_desired,
require_endpoint_plugin,
)
from dns_sync.adapters import (
Endpoint,
NormalizedObject,
PlanAction,
PlanOperation,
)
class AdapterSupportTests(unittest.TestCase):
def test_endpoint_plugin_accepts_matching_plugin(self):
endpoint = Endpoint("npm", "node.example:81")
require_endpoint_plugin(endpoint, "npm")
def test_endpoint_plugin_rejects_wrong_plugin(self):
endpoint = Endpoint("npm", "node.example:81")
with self.assertRaisesRegex(
RuntimeError,
"cannot use endpoint",
):
require_endpoint_plugin(
endpoint,
"verizon",
)
def test_endpoint_plugin_rejects_empty_expected_name(self):
endpoint = Endpoint("npm", "node.example:81")
with self.assertRaisesRegex(
ValueError,
"cannot be empty",
):
require_endpoint_plugin(endpoint, " ")
def test_action_endpoint_accepts_matching_endpoint(self):
endpoint = Endpoint("npm", "node.example:81")
action = PlanAction(
endpoint_id=endpoint.identity,
operation=PlanOperation.CREATE,
)
require_action_endpoint(action, endpoint)
def test_action_endpoint_rejects_other_endpoint(self):
endpoint = Endpoint("npm", "node.example:81")
action = PlanAction(
endpoint_id="npm://other.example:81",
operation=PlanOperation.CREATE,
)
with self.assertRaisesRegex(
RuntimeError,
"does not belong",
):
require_action_endpoint(action, endpoint)
def test_require_desired_returns_desired_object(self):
desired = NormalizedObject(
object_type="example",
logical_key="object",
payload={},
)
action = PlanAction(
endpoint_id="example://endpoint",
operation=PlanOperation.CREATE,
desired=desired,
)
self.assertIs(
require_desired(action),
desired,
)
def test_require_desired_fails_closed(self):
action = PlanAction(
endpoint_id="example://endpoint",
operation=PlanOperation.CREATE,
)
with self.assertRaisesRegex(
RuntimeError,
"Test mutation requires desired state",
):
require_desired(
action,
context="Test mutation",
)
if __name__ == "__main__":
unittest.main()
+24
View File
@@ -6,6 +6,7 @@ from dns_sync.adapters import (
CERTIFICATES,
PROXY_HOSTS,
Capability,
Endpoint,
CapabilityOperation,
NormalizedObject,
ObjectReference,
@@ -94,6 +95,29 @@ class NpmAdapterTests(unittest.TestCase):
self.assertIs(adapters[0].client, first_client)
self.assertIs(adapters[1].client, second_client)
def test_adapter_rejects_endpoint_for_other_plugin(self):
config = self.config()
endpoint = Endpoint(
"verizon",
"192.168.1.1:443",
)
with patch(
"dns_sync.plugins.adapters.npm.NpmClient"
) as client_class:
with self.assertRaisesRegex(
RuntimeError,
"cannot use endpoint",
):
load_adapter(
"npm",
config,
endpoint,
)
client_class.assert_not_called()
def test_capabilities_cover_discovery_apply_and_verify(self):
adapter = self.adapter(Mock())
+28 -1
View File
@@ -5,6 +5,7 @@ from unittest.mock import Mock, patch
from dns_sync.adapters import (
DNS_RECORDS,
Capability,
Endpoint,
CapabilityOperation,
NormalizedObject,
PlanAction,
@@ -79,6 +80,32 @@ class VerizonAdapterTests(unittest.TestCase):
},
)
def test_adapter_rejects_endpoint_for_other_plugin(self):
config = self.config()
endpoint = Endpoint(
"npm",
"192.168.1.3:81",
)
with patch.dict(
os.environ,
{
"ENABLED_PLUGINS": "npm,verizon",
"DNS_SYNC_PLUGIN_PATH": "external_plugins",
},
clear=False,
):
with self.assertRaisesRegex(
RuntimeError,
"cannot use endpoint",
):
load_adapter(
"verizon",
config,
endpoint,
)
def test_capabilities_cover_dns_discovery_apply_and_verify(self):
adapter = self.adapter(Mock())
@@ -259,7 +286,7 @@ class VerizonAdapterTests(unittest.TestCase):
with self.assertRaisesRegex(RuntimeError, "cannot discover"):
adapter.discover("certificates")
with self.assertRaisesRegex(RuntimeError, "different endpoint"):
with self.assertRaisesRegex(RuntimeError, "does not belong"):
adapter.apply(
PlanAction(
endpoint_id="verizon://different:443",