diff --git a/src/bin/stats/tests/isc/config/ccsession.py b/src/bin/stats/tests/isc/config/ccsession.py index a4e9c37c1f5560bc0d17bfaabd700fda461b4545..50f7c1b163db0ec222847e3812b22ba37a7911e7 100644 --- a/src/bin/stats/tests/isc/config/ccsession.py +++ b/src/bin/stats/tests/isc/config/ccsession.py @@ -23,6 +23,7 @@ external module. import json import os +import time from isc.cc.session import Session COMMAND_CONFIG_UPDATE = "config_update" @@ -72,6 +73,9 @@ class ModuleSpecError(Exception): class ModuleSpec: def __init__(self, module_spec, check = True): + # check only confi_data for testing + if check and "config_data" in module_spec: + _check_config_spec(module_spec["config_data"]) self._module_spec = module_spec def get_config_spec(self): @@ -83,6 +87,91 @@ class ModuleSpec: def get_module_name(self): return self._module_spec['module_name'] +def _check_config_spec(config_data): + # config data is a list of items represented by dicts that contain + # things like "item_name", depending on the type they can have + # specific subitems + """Checks a list that contains the configuration part of the + specification. Raises a ModuleSpecError if there is a + problem.""" + if type(config_data) != list: + raise ModuleSpecError("config_data is of type " + str(type(config_data)) + ", not a list of items") + for config_item in config_data: + _check_item_spec(config_item) + +def _check_item_spec(config_item): + """Checks the dict that defines one config item + (i.e. containing "item_name", "item_type", etc. + Raises a ModuleSpecError if there is an error""" + if type(config_item) != dict: + raise ModuleSpecError("item spec not a dict") + if "item_name" not in config_item: + raise ModuleSpecError("no item_name in config item") + if type(config_item["item_name"]) != str: + raise ModuleSpecError("item_name is not a string: " + str(config_item["item_name"])) + item_name = config_item["item_name"] + if "item_type" not in config_item: + raise ModuleSpecError("no item_type in config item") + item_type = config_item["item_type"] + if type(item_type) != str: + raise ModuleSpecError("item_type in " + item_name + " is not a string: " + str(type(item_type))) + if item_type not in ["integer", "real", "boolean", "string", "list", "map", "any"]: + raise ModuleSpecError("unknown item_type in " + item_name + ": " + item_type) + if "item_optional" in config_item: + if type(config_item["item_optional"]) != bool: + raise ModuleSpecError("item_default in " + item_name + " is not a boolean") + if not config_item["item_optional"] and "item_default" not in config_item: + raise ModuleSpecError("no default value for non-optional item " + item_name) + else: + raise ModuleSpecError("item_optional not in item " + item_name) + if "item_default" in config_item: + item_default = config_item["item_default"] + if (item_type == "integer" and type(item_default) != int) or \ + (item_type == "real" and type(item_default) != float) or \ + (item_type == "boolean" and type(item_default) != bool) or \ + (item_type == "string" and type(item_default) != str) or \ + (item_type == "list" and type(item_default) != list) or \ + (item_type == "map" and type(item_default) != dict): + raise ModuleSpecError("Wrong type for item_default in " + item_name) + # TODO: once we have check_type, run the item default through that with the list|map_item_spec + if item_type == "list": + if "list_item_spec" not in config_item: + raise ModuleSpecError("no list_item_spec in list item " + item_name) + if type(config_item["list_item_spec"]) != dict: + raise ModuleSpecError("list_item_spec in " + item_name + " is not a dict") + _check_item_spec(config_item["list_item_spec"]) + if item_type == "map": + if "map_item_spec" not in config_item: + raise ModuleSpecError("no map_item_sepc in map item " + item_name) + if type(config_item["map_item_spec"]) != list: + raise ModuleSpecError("map_item_spec in " + item_name + " is not a list") + for map_item in config_item["map_item_spec"]: + if type(map_item) != dict: + raise ModuleSpecError("map_item_spec element is not a dict") + _check_item_spec(map_item) + if 'item_format' in config_item and 'item_default' in config_item: + item_format = config_item["item_format"] + item_default = config_item["item_default"] + if not _check_format(item_default, item_format): + raise ModuleSpecError( + "Wrong format for " + str(item_default) + " in " + str(item_name)) + +def _check_format(value, format_name): + """Check if specified value and format are correct. Return True if + is is correct.""" + # TODO: should be added other format types if necessary + time_formats = { 'date-time' : "%Y-%m-%dT%H:%M:%SZ", + 'date' : "%Y-%m-%d", + 'time' : "%H:%M:%S" } + for fmt in time_formats: + if format_name == fmt: + try: + time.strptime(value, time_formats[fmt]) + return True + except (ValueError, TypeError): + break + return False + class ModuleCCSessionError(Exception): pass