""" Tests for scripts/config_drift.py — Config drift detection. """ import json import tempfile import unittest from pathlib import Path import sys sys.path.insert(0, str(Path(__file__).parent.parent / "scripts")) from config_drift import ( get_nested_value, compare_configs, parse_yaml_basic, generate_report, ) class TestGetNestedValue(unittest.TestCase): def test_top_level(self): config = {"provider": "openrouter"} self.assertEqual(get_nested_value(config, "provider"), "openrouter") def test_nested(self): config = {"cron": {"enabled": True, "workers": 4}} self.assertEqual(get_nested_value(config, "cron.enabled"), True) self.assertEqual(get_nested_value(config, "cron.workers"), 4) def test_missing_key(self): config = {"provider": "openrouter"} self.assertIsNone(get_nested_value(config, "missing")) def test_missing_nested(self): config = {"cron": {}} self.assertIsNone(get_nested_value(config, "cron.enabled")) def test_deep_nesting(self): config = {"a": {"b": {"c": "value"}}} self.assertEqual(get_nested_value(config, "a.b.c"), "value") class TestCompareConfigs(unittest.TestCase): def test_no_diff(self): canonical = {"provider": "openrouter", "model": "mimo"} remote = {"provider": "openrouter", "model": "mimo"} diffs = compare_configs(canonical, remote, ["provider", "model"]) self.assertEqual(diffs, []) def test_single_diff(self): canonical = {"provider": "openrouter"} remote = {"provider": "anthropic"} diffs = compare_configs(canonical, remote, ["provider"]) self.assertEqual(len(diffs), 1) self.assertEqual(diffs[0][0], "provider") self.assertEqual(diffs[0][1], "openrouter") self.assertEqual(diffs[0][2], "anthropic") def test_multiple_diffs(self): canonical = {"provider": "openrouter", "model": "mimo"} remote = {"provider": "anthropic", "model": "claude"} diffs = compare_configs(canonical, remote, ["provider", "model"]) self.assertEqual(len(diffs), 2) def test_nested_diff(self): canonical = {"cron": {"enabled": True}} remote = {"cron": {"enabled": False}} diffs = compare_configs(canonical, remote, ["cron.enabled"]) self.assertEqual(len(diffs), 1) self.assertEqual(diffs[0][0], "cron.enabled") def test_missing_in_remote(self): canonical = {"provider": "openrouter"} remote = {} diffs = compare_configs(canonical, remote, ["provider"]) self.assertEqual(len(diffs), 1) def test_extra_in_remote(self): canonical = {} remote = {"provider": "openrouter"} diffs = compare_configs(canonical, remote, ["provider"]) self.assertEqual(len(diffs), 1) class TestParseYamlBasic(unittest.TestCase): def test_simple(self): content = "provider: openrouter\nmodel: mimo-v2-pro\n" result = parse_yaml_basic(content) self.assertEqual(result["provider"], "openrouter") self.assertEqual(result["model"], "mimo-v2-pro") def test_boolean(self): content = "enabled: true\ndisabled: false\n" result = parse_yaml_basic(content) self.assertEqual(result["enabled"], True) self.assertEqual(result["disabled"], False) def test_integer(self): content = "workers: 4\nport: 8080\n" result = parse_yaml_basic(content) self.assertEqual(result["workers"], 4) self.assertEqual(result["port"], 8080) def test_comments_skipped(self): content = "# This is a comment\nprovider: openrouter\n" result = parse_yaml_basic(content) self.assertNotIn("#", result) self.assertEqual(result["provider"], "openrouter") def test_quoted_values(self): content = 'name: "hello world"\nother: \'single quotes\'\n' result = parse_yaml_basic(content) self.assertEqual(result["name"], "hello world") self.assertEqual(result["other"], "single quotes") class TestGenerateReport(unittest.TestCase): def test_all_ok(self): results = { "node1": {"status": "ok", "diffs": []}, "node2": {"status": "ok", "diffs": []}, } report = generate_report(results, ["provider"]) self.assertIn("OK", report) self.assertIn("2 ok", report) def test_drift_reported(self): results = { "node1": { "status": "drift", "diffs": [("provider", "openrouter", "anthropic")] }, "node2": {"status": "ok", "diffs": []}, } report = generate_report(results, ["provider"]) self.assertIn("DRIFT DETECTED", report) self.assertIn("openrouter", report) self.assertIn("anthropic", report) def test_unreachable_reported(self): results = { "node1": {"status": "unreachable", "diffs": []}, } report = generate_report(results, ["provider"]) self.assertIn("UNREACHABLE", report) if __name__ == "__main__": unittest.main()