Limit reconciliation apply mutations

This commit is contained in:
Lyncoln
2026-09-19 19:17:19 -04:00
parent 60dbd6a656
commit 7288a949bc
2 changed files with 104 additions and 2 deletions
+70 -1
View File
@@ -64,11 +64,24 @@ class ReconcileCliTests(unittest.TestCase):
)
self.assertTrue(args.include_disabled)
self.assertFalse(args.apply)
self.assertIsNone(args.max_changes)
apply_args = build_parser().parse_args(
["reconcile", "--apply"]
[
"reconcile",
"--apply",
"--max-changes",
"0",
]
)
self.assertTrue(apply_args.apply)
self.assertEqual(apply_args.max_changes, 0)
with redirect_stderr(io.StringIO()):
with self.assertRaises(SystemExit):
build_parser().parse_args(
["reconcile", "--max-changes", "-1"]
)
def test_reconcile_builds_plan_without_applying_it(self):
npm_endpoint = Endpoint("npm", "192.168.1.3:81")
@@ -162,6 +175,7 @@ class ReconcileCliTests(unittest.TestCase):
state_db=str(state_path),
include_disabled=False,
apply=False,
max_changes=None,
)
)
@@ -230,6 +244,7 @@ class ReconcileCliTests(unittest.TestCase):
state_db=str(state_path),
include_disabled=False,
apply=True,
max_changes=None,
)
)
@@ -244,6 +259,60 @@ class ReconcileCliTests(unittest.TestCase):
stdout.getvalue(),
)
def test_apply_budget_blocks_executor_before_mutation(self):
config = SimpleNamespace(
target_ip="192.168.1.101",
include_disabled=False,
domain_matching=False,
domain=None,
)
adapter = object()
action = SimpleNamespace(
operation=SimpleNamespace(value="create"),
)
plan = SimpleNamespace(actions=(action,))
reconciliation = SimpleNamespace(
observations=(),
desired=(),
plans=(plan,),
failures=(),
)
with tempfile.TemporaryDirectory() as directory:
state_path = Path(directory) / "state.sqlite3"
with patch(
"dns_sync.cli.AppConfig.from_env",
return_value=config,
), patch(
"dns_sync.cli._configured_adapters",
return_value=[adapter],
), patch(
"dns_sync.cli.discover_reconcile_plan",
return_value=reconciliation,
), patch(
"dns_sync.cli.print_endpoint_plans",
), patch(
"dns_sync.cli.execute_endpoint_plans",
) as execute, redirect_stdout(io.StringIO()):
with self.assertRaisesRegex(
RuntimeError,
(
r"Refusing to apply 1 change\(s\); "
r"--max-changes allows 0"
),
):
run_reconcile(
SimpleNamespace(
state_db=str(state_path),
include_disabled=False,
apply=True,
max_changes=0,
)
)
execute.assert_not_called()
if __name__ == "__main__":
unittest.main()