From be36abd53d23ea76859ad58c6cf6222347de5670 Mon Sep 17 00:00:00 2001 From: Sahil Lenka <76817449+Sahil-u07@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:30:44 +0530 Subject: [PATCH] protect config.telemetry access with fallback to empty dict (#1427) * protect config.telemetry access with fallback to empty dict If the YAML config does not include a telemetry section, three spots in main() crash with KeyError because they access config.telemetry directly. Everything else in the file uses get_yaml_item_value which handles missing keys gracefully. Added config.telemetry = get_yaml_item_value(config, telemetry, {}) before the first usage. This ensures the key always exists as at least an empty dict, protecting all downstream .get() calls and assignments (archive_path, run_tag, telemetry_group, etc.). Wrote a test that passes a config without a telemetry section and asserts main() returns -1 (no kubeconfig) instead of crashing with KeyError. Signed-off-by: Sahil Lenka * clean up test imports and prevent filesystem side effects Remove unused imports (Mock, get_yaml_item_value). Add rollback_versions_directory to mock config so the test does not write ~/.krkn/rollback to disk. Signed-off-by: Sahil Lenka --------- Signed-off-by: Sahil Lenka Co-authored-by: Paige Patton <64206430+paigerube14@users.noreply.github.com> --- run_kraken.py | 1 + tests/test_run_kraken.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/test_run_kraken.py diff --git a/run_kraken.py b/run_kraken.py index e8ddda27..b78491f9 100644 --- a/run_kraken.py +++ b/run_kraken.py @@ -206,6 +206,7 @@ def main(options, command: Optional[str], out: Optional[dict] = None) -> int: check_critical_alerts = get_yaml_item_value( config["performance_monitoring"], "check_critical_alerts", False ) + config["telemetry"] = get_yaml_item_value(config, "telemetry", {}) telemetry_api_url = config["telemetry"].get("api_url", "") telemetry_enabled = config["telemetry"].get("enabled", True) diff --git a/tests/test_run_kraken.py b/tests/test_run_kraken.py new file mode 100644 index 00000000..98aab312 --- /dev/null +++ b/tests/test_run_kraken.py @@ -0,0 +1,32 @@ +import unittest +from unittest.mock import patch, mock_open +from types import SimpleNamespace + +from run_kraken import main + + +class TestRunKraken(unittest.TestCase): + + @patch('run_kraken.yaml.safe_load') + @patch('run_kraken.os.path.isfile') + @patch('builtins.open', new_callable=mock_open) + def test_main_without_telemetry_config(self, mock_file, mock_isfile, mock_yaml_load): + """ + Test that main() doesn't crash when config has no telemetry section + """ + mock_isfile.side_effect = lambda p: p == "/fake/config.yaml" + mock_yaml_load.return_value = { + "kraken": {"rollback_versions_directory": "/tmp/krkn-test-rollback"}, + "tunings": {}, + "performance_monitoring": {}, + "elastic": {}, + } + + options = SimpleNamespace(cfg="/fake/config.yaml") + result = main(options, None) + + self.assertEqual(result, -1) + + +if __name__ == "__main__": + unittest.main()