import unittest from dataclasses import dataclass, field from datetime import datetime, timezone from dns_sync.adapters import ( CERTIFICATES, ApplyResult, DNS_RECORDS, PROXY_HOSTS, Capability, CapabilityOperation, Endpoint, EndpointPlan, NormalizedObject, ObjectReference, Observation, PlanAction, PlanOperation, RetireRequest, ) from dns_sync.executor import execute_endpoint_plans from dns_sync.persistence import SQLiteStateStore NOW = datetime(2026, 9, 19, 23, 15, tzinfo=timezone.utc) def object_for( object_type: str, logical_key: str, *, references=(), ) -> NormalizedObject: if object_type == DNS_RECORDS: payload = { "hostname": logical_key, "ip": "192.168.1.101", "record_type": "A", "wildcard": False, } elif object_type == CERTIFICATES: payload = { "domain_names": [logical_key], "expires_on": "2026-12-15T00:00:00+00:00", } else: payload = { "domain_names": [logical_key], "forward_scheme": "http", "forward_host": "192.168.1.50", "forward_port": 8080, "enabled": True, } return NormalizedObject( object_type=object_type, logical_key=logical_key, payload=payload, references=references, ) def action( endpoint_id: str, operation: PlanOperation, object_type: str = DNS_RECORDS, logical_key: str = "app.example.com", *, references=(), ) -> PlanAction: return PlanAction( endpoint_id=endpoint_id, operation=operation, desired=object_for( object_type, logical_key, references=references, ), ) def capabilities( *object_types: str, verify: bool = True, ) -> frozenset[Capability]: result = { Capability( object_type, CapabilityOperation.APPLY, ) for object_type in object_types } if verify: result.update( Capability( object_type, CapabilityOperation.VERIFY, ) for object_type in object_types ) return frozenset(result) @dataclass class FakeAdapter: endpoint: Endpoint capabilities: frozenset[Capability] verify_result: bool = True apply_error: Exception | None = None verify_error: Exception | None = None apply_local_keys: dict[ tuple[str, str], str, ] = field(default_factory=dict) applied_actions: list[PlanAction] = field( default_factory=list ) events: list[tuple[str, str, str]] = field( default_factory=list ) retired: list[RetireRequest] = field( default_factory=list ) def apply(self, plan_action): desired = plan_action.desired self.events.append( ( "apply", desired.object_type, desired.logical_key, ) ) if self.apply_error is not None: raise self.apply_error self.applied_actions.append(plan_action) local_key = self.apply_local_keys.get( ( desired.object_type, desired.logical_key, ), desired.local_key or "test-local", ) return ApplyResult( object=NormalizedObject( object_type=desired.object_type, logical_key=desired.logical_key, local_key=local_key, payload=dict(desired.payload), references=desired.references, ), detail="test detail", ) def verify(self, object): self.events.append( ( "verify", object.object_type, object.logical_key, ) ) if self.verify_error is not None: raise self.verify_error return self.verify_result def retire(self, request): self.events.append( ( "retire", request.object.object_type, request.object.logical_key, ) ) self.retired.append(request) class ExecutionTests(unittest.TestCase): def test_successful_actions_are_applied_verified_and_persisted(self): endpoint = Endpoint("verizon", "192.168.1.1:443") adapter = FakeAdapter( endpoint, capabilities(DNS_RECORDS), ) plan = EndpointPlan( endpoint.identity, ( action( endpoint.identity, PlanOperation.CREATE, logical_key="add.example.com", ), action( endpoint.identity, PlanOperation.NOOP, logical_key="keep.example.com", ), action( endpoint.identity, PlanOperation.UPDATE, logical_key="update.example.com", ), ), ) with SQLiteStateStore(":memory:") as store: result = execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) persisted = store.load_applied_state( endpoint.identity, DNS_RECORDS, ) self.assertEqual(len(result.applied), 2) self.assertEqual(len(result.skipped), 1) self.assertTrue(all(row.is_verified for row in persisted)) self.assertEqual( {row.object.logical_key for row in persisted}, {"add.example.com", "update.example.com"}, ) self.assertEqual( tuple(event[0] for event in adapter.events), ("apply", "verify", "apply", "verify"), ) def test_replace_rebinds_dependent_before_retiring_old_object(self): endpoint = Endpoint( "npm", "192.168.1.4:81", ) class ReplacementAdapter(FakeAdapter): def apply(self, plan_action): result = super().apply(plan_action) if ( plan_action.operation == PlanOperation.REPLACE ): return ApplyResult( object=result.object, detail="replacement", retirements=( RetireRequest( object=plan_action.current, ), ), ) return result adapter = ReplacementAdapter( endpoint, capabilities( CERTIFICATES, PROXY_HOSTS, ), apply_local_keys={ ( CERTIFICATES, "app.example.com", ): "84", ( PROXY_HOSTS, "app.example.com", ): "12", }, ) old_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="67", payload={ "domain_names": ["app.example.com"], "valid_from": "2026-08-01T00:00:00+00:00", "expires_on": "2026-11-01T00:00:00+00:00", }, ) desired_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", payload={ "domain_names": ["app.example.com"], "valid_from": "2026-09-01T00:00:00+00:00", "expires_on": "2026-12-01T00:00:00+00:00", }, ) old_proxy = NormalizedObject( object_type=PROXY_HOSTS, logical_key="app.example.com", local_key="12", payload={ "domain_names": ["app.example.com"], "forward_scheme": "https", "forward_host": "backend.internal", "forward_port": 443, "enabled": True, }, references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="67", ), ), ) desired_proxy = NormalizedObject( object_type=PROXY_HOSTS, logical_key="app.example.com", payload=dict(old_proxy.payload), references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ) plan = EndpointPlan( endpoint.identity, ( PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.REPLACE, desired=desired_certificate, current=old_certificate, ), PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.UPDATE, desired=desired_proxy, current=old_proxy, ), ), ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, old_certificate, NOW, ) ], NOW, ) store.replace_observations( endpoint.identity, PROXY_HOSTS, [ Observation( endpoint.identity, old_proxy, NOW, ) ], NOW, ) execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) self.assertEqual( tuple(event[0] for event in adapter.events), ( "apply", "verify", "apply", "verify", "retire", ), ) proxy_apply = adapter.applied_actions[1] self.assertEqual( proxy_apply.desired.references, ( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="84", ), ), ) self.assertEqual( adapter.retired, [ RetireRequest( object=old_certificate, ) ], ) def test_restart_recovery_rebinds_before_planned_retirement(self): endpoint = Endpoint( "npm", "192.168.1.4:81", ) adapter = FakeAdapter( endpoint, capabilities( CERTIFICATES, PROXY_HOSTS, ), apply_local_keys={ ( PROXY_HOSTS, "app.example.com", ): "12", }, ) old_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="67", payload={ "domain_names": ["app.example.com"], "valid_from": "2026-08-01T00:00:00+00:00", "expires_on": "2026-11-01T00:00:00+00:00", }, ) new_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="84", payload={ "domain_names": ["app.example.com"], "valid_from": "2026-09-01T00:00:00+00:00", "expires_on": "2026-12-01T00:00:00+00:00", }, ) old_proxy = NormalizedObject( object_type=PROXY_HOSTS, logical_key="app.example.com", local_key="12", payload={ "domain_names": ["app.example.com"], "forward_scheme": "https", "forward_host": "backend.internal", "forward_port": 443, "enabled": True, }, references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="67", ), ), ) desired_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", payload=dict(new_certificate.payload), ) desired_proxy = NormalizedObject( object_type=PROXY_HOSTS, logical_key="app.example.com", payload=dict(old_proxy.payload), references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ) plan = EndpointPlan( endpoint.identity, ( PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.NOOP, desired=desired_certificate, current=new_certificate, ), PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.UPDATE, desired=desired_proxy, current=old_proxy, reason=( "referenced local object is being retired" ), ), ), retirements=( RetireRequest( object=old_certificate, ), ), ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, old_certificate, NOW, ), Observation( endpoint.identity, new_certificate, NOW, ), ], NOW, ) store.replace_observations( endpoint.identity, PROXY_HOSTS, [ Observation( endpoint.identity, old_proxy, NOW, ) ], NOW, ) execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) self.assertEqual( tuple(event[0] for event in adapter.events), ( "apply", "verify", "retire", ), ) proxy_action = adapter.applied_actions[0] self.assertEqual( proxy_action.desired.references, ( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="84", ), ), ) self.assertEqual( adapter.retired, [ RetireRequest( object=old_certificate, ) ], ) def test_failed_verification_is_persisted_and_raises(self): endpoint = Endpoint("verizon", "192.168.1.1:443") adapter = FakeAdapter( endpoint, capabilities(DNS_RECORDS), verify_result=False, ) plan = EndpointPlan( endpoint.identity, ( action( endpoint.identity, PlanOperation.CREATE, ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "verification failed", ): execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) persisted = store.load_applied_state() self.assertEqual(len(persisted), 1) self.assertFalse(persisted[0].is_verified) self.assertEqual( persisted[0].verification_error, "adapter returned false", ) def test_apply_failure_does_not_record_applied_state(self): endpoint = Endpoint("verizon", "192.168.1.1:443") adapter = FakeAdapter( endpoint, capabilities(DNS_RECORDS), apply_error=RuntimeError("write failed"), ) plan = EndpointPlan( endpoint.identity, ( action( endpoint.identity, PlanOperation.CREATE, ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex(RuntimeError, "write failed"): execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) self.assertEqual(store.load_applied_state(), []) def test_preflight_requires_verify_before_any_mutation(self): endpoint = Endpoint("verizon", "192.168.1.1:443") adapter = FakeAdapter( endpoint, capabilities(DNS_RECORDS, verify=False), ) plan = EndpointPlan( endpoint.identity, ( action( endpoint.identity, PlanOperation.CREATE, ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "lacks verify capability", ): execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) self.assertEqual(adapter.events, []) def test_certificates_execute_before_proxy_hosts(self): events: list[tuple[str, str, str]] = [] endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(CERTIFICATES, PROXY_HOSTS), events=events, ) plan = EndpointPlan( endpoint.identity, ( action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ), action( endpoint.identity, PlanOperation.CREATE, CERTIFICATES, "app.example.com", ), ), ) with SQLiteStateStore(":memory:") as store: execute_endpoint_plans( [adapter], [plan], store, executed_at=NOW, ) self.assertEqual( tuple((event[0], event[1]) for event in events), ( ("apply", CERTIFICATES), ("verify", CERTIFICATES), ("apply", PROXY_HOSTS), ("verify", PROXY_HOSTS), ), ) def test_existing_reference_resolves_from_observation(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) reference = ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=(reference,), ) observed_certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="67", payload={ "domain_names": ["app.example.com"], "expires_on": "2026-12-15T00:00:00+00:00", }, ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, observed_certificate, NOW, ), ], NOW, ) execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) applied_reference = ( adapter.applied_actions[0] .desired .references[0] ) self.assertEqual(applied_reference.local_key, "67") self.assertIsNone(applied_reference.logical_key) def test_created_reference_uses_apply_result_local_key(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(CERTIFICATES, PROXY_HOSTS), apply_local_keys={ ( CERTIFICATES, "app.example.com", ): "68", ( PROXY_HOSTS, "app.example.com", ): "12", }, ) certificate_action = action( endpoint.identity, PlanOperation.CREATE, CERTIFICATES, "app.example.com", ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ) with SQLiteStateStore(":memory:") as store: execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, ( proxy_action, certificate_action, ), ) ], store, executed_at=NOW, ) persisted = store.load_applied_state( endpoint.identity, ) self.assertEqual( tuple( item.desired.object_type for item in adapter.applied_actions ), (CERTIFICATES, PROXY_HOSTS), ) resolved = ( adapter.applied_actions[1] .desired .references[0] ) self.assertEqual(resolved.local_key, "68") self.assertIsNone(resolved.logical_key) persisted_by_type = { row.object.object_type: row.object for row in persisted } self.assertEqual( persisted_by_type[CERTIFICATES].local_key, "68", ) self.assertEqual( persisted_by_type[PROXY_HOSTS] .references[0] .local_key, "68", ) def test_unresolved_reference_fails_before_dependent_apply(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="missing.example.com", ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "Unresolved endpoint-local reference", ): execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) self.assertEqual( store.load_applied_state(), [], ) self.assertEqual(adapter.events, []) self.assertEqual(adapter.applied_actions, []) def test_existing_reference_falls_back_to_verified_applied_state(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="71", payload={ "domain_names": ["app.example.com"], }, ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ) with SQLiteStateStore(":memory:") as store: store.record_applied( endpoint.identity, certificate, NOW, ) store.record_verification_success( endpoint.identity, certificate, NOW, ) execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) resolved = ( adapter.applied_actions[0] .desired .references[0] ) self.assertEqual(resolved.local_key, "71") def test_ambiguous_logical_reference_fails_closed(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, logical_key="app.example.com", ), ), ) first = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="63", payload={ "domain_names": ["app.example.com"], }, ) second = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="67", payload={ "domain_names": ["app.example.com"], }, ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, first, NOW, ), Observation( endpoint.identity, second, NOW, ), ], NOW, ) with self.assertRaisesRegex( RuntimeError, "Ambiguous endpoint-local reference", ): execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) self.assertEqual(adapter.events, []) self.assertEqual(adapter.applied_actions, []) def test_unrelated_duplicate_identity_does_not_block_apply(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "unrelated.example.com", ) first = NormalizedObject( object_type=CERTIFICATES, logical_key="duplicate.example.com", local_key="63", payload={ "domain_names": ["duplicate.example.com"], }, ) second = NormalizedObject( object_type=CERTIFICATES, logical_key="duplicate.example.com", local_key="67", payload={ "domain_names": ["duplicate.example.com"], }, ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, first, NOW, ), Observation( endpoint.identity, second, NOW, ), ], NOW, ) result = execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) self.assertEqual(len(result.applied), 1) self.assertEqual(len(adapter.applied_actions), 1) def test_unknown_local_reference_is_not_trusted(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="999", ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "local key '999'", ): execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) self.assertEqual(adapter.events, []) self.assertEqual(adapter.applied_actions, []) def test_known_local_reference_is_preserved(self): endpoint = Endpoint("npm", "192.168.1.4:81") adapter = FakeAdapter( endpoint, capabilities(PROXY_HOSTS), ) certificate = NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key="67", payload={ "domain_names": ["app.example.com"], }, ) local_reference = ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="67", ) proxy_action = action( endpoint.identity, PlanOperation.CREATE, PROXY_HOSTS, "app.example.com", references=(local_reference,), ) with SQLiteStateStore(":memory:") as store: store.replace_observations( endpoint.identity, CERTIFICATES, [ Observation( endpoint.identity, certificate, NOW, ), ], NOW, ) execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, (proxy_action,), ) ], store, executed_at=NOW, ) self.assertEqual( adapter.applied_actions[0].desired.references, (local_reference,), ) def test_dependency_cycle_fails_before_any_mutation(self): endpoint = Endpoint("generic", "node.example:443") object_a = "object_a" object_b = "object_b" adapter = FakeAdapter( endpoint, capabilities(object_a, object_b), ) action_a = PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.CREATE, desired=NormalizedObject( object_type=object_a, logical_key="a", payload={}, references=( ObjectReference( relation="b", object_type=object_b, logical_key="b", ), ), ), ) action_b = PlanAction( endpoint_id=endpoint.identity, operation=PlanOperation.CREATE, desired=NormalizedObject( object_type=object_b, logical_key="b", payload={}, references=( ObjectReference( relation="a", object_type=object_a, logical_key="a", ), ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "dependency cycle", ): execute_endpoint_plans( [adapter], [ EndpointPlan( endpoint.identity, ( action_a, action_b, ), ) ], store, executed_at=NOW, ) self.assertEqual( store.load_applied_state(), [], ) self.assertEqual(adapter.events, []) self.assertEqual(adapter.applied_actions, []) def test_invalid_plan_fails_preflight_without_mutation(self): endpoint = Endpoint("verizon", "192.168.1.1:443") adapter = FakeAdapter( endpoint, capabilities(DNS_RECORDS), ) invalid = EndpointPlan( endpoint.identity, ( action( "verizon://different:443", PlanOperation.CREATE, ), ), ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( RuntimeError, "does not match", ): execute_endpoint_plans( [adapter], [invalid], store, executed_at=NOW, ) self.assertEqual(adapter.events, []) if __name__ == "__main__": unittest.main()