typing and refactoring on the way
diff --git a/wally/config.py b/wally/config.py
index c5d1db0..59db0e1 100644
--- a/wally/config.py
+++ b/wally/config.py
@@ -1,141 +1,60 @@
-import os
-import uuid
-import functools
-
-import yaml
-
-try:
- from petname import Generate as pet_generate
-except ImportError:
- def pet_generate(x, y):
- return str(uuid.uuid4())
-
-from . import pretty_yaml
-
+from typing import Any, Dict
+from .storage import IStorable, IStorage
class NoData:
@classmethod
- def get(cls, name, x):
+ def get(cls: type, name: str, x: Any) -> type:
return cls
-class Config:
- def __init__(self, val=None):
- if val is not None:
- self.update(val)
- self.results_dir = None
- self.run_uuid = None
- self.settings = {}
- self.run_params_file = None
- self.default_test_local_folder = None
- self.hwinfo_directory = None
- self.hwreport_fname = None
+class Config(IStorable):
+ # for mypy only
+ run_uuid = None # type: str
+ storage_url = None # type: str
+ comment = None # type: str
+ keep_vm = None # type: bool
+ no_tests = None # type: bool
+ dont_discover_nodes = None # type: bool
+ build_id = None # type: str
+ build_description = None # type: str
+ build_type = None # type: str
- def get(self, name, defval=None):
- obj = self.__dict__
- for cname in name.split("."):
- obj = obj.get(cname, NoData)
+ def __init__(self, dct: Dict[str, Any]) -> None:
+ self.__dict__['_dct'] = dct
- if obj is NoData:
- return defval
- return obj
+ def get(self, path: str, default: Any = NoData) -> Any:
+ curr = self
- def update(self, val):
- self.__dict__.update(val)
+ while path:
+ if '/' in path:
+ name, path = path.split('/', 1)
+ else:
+ name = path
+ path = ""
+
+ try:
+ curr = getattr(curr, name)
+ except AttributeError:
+ return default
+
+ return curr
+
+ def __getattr__(self, name: str) -> Any:
+ try:
+ val = self.__dct[name]
+ except KeyError:
+ raise AttributeError(name)
+
+ if isinstance(val, dict):
+ val = self.__class__(val)
+
+ return val
+
+ def __setattr__(self, name: str, val: Any):
+ self.__dct[name] = val
-def get_test_files(results_dir):
- in_var_dir = functools.partial(os.path.join, results_dir)
-
- res = dict(
- run_params_file='run_params.yaml',
- saved_config_file='config.yaml',
- vm_ids_fname='os_vm_ids',
- html_report_file='{0}_report.html',
- load_report_file='load_report.html',
- text_report_file='report.txt',
- log_file='log.txt',
- sensor_storage='sensor_storage',
- nodes_report_file='nodes.yaml',
- results_storage='results',
- hwinfo_directory='hwinfo',
- hwreport_fname='hwinfo.txt',
- raw_results='raw_results.yaml')
-
- res = dict((k, in_var_dir(v)) for k, v in res.items())
- res['results_dir'] = results_dir
- return res
-
-
-def load_config(file_name):
- file_name = os.path.abspath(file_name)
-
- defaults = dict(
- testnode_log_root='/tmp/wally',
- settings={}
- )
-
- raw_cfg = yaml.load(open(file_name).read())
- raw_cfg['config_folder'] = os.path.dirname(file_name)
- if 'include' in raw_cfg:
- default_path = os.path.join(raw_cfg['config_folder'],
- raw_cfg.pop('include'))
- default_cfg = yaml.load(open(default_path).read())
-
- # TODO: Need more intelectual configs merge?
- default_cfg.update(raw_cfg)
- raw_cfg = default_cfg
-
- cfg = Config(defaults)
- cfg.update(raw_cfg)
-
- results_storage = cfg.settings.get('results_storage', '/tmp')
- results_storage = os.path.abspath(results_storage)
-
- existing = file_name.startswith(results_storage)
-
- if existing:
- cfg.results_dir = os.path.dirname(file_name)
- cfg.run_uuid = os.path.basename(cfg.results_dir)
- else:
- # genarate result folder name
- for i in range(10):
- cfg.run_uuid = pet_generate(2, "_")
- cfg.results_dir = os.path.join(results_storage,
- cfg.run_uuid)
- if not os.path.exists(cfg.results_dir):
- break
- else:
- cfg.run_uuid = str(uuid.uuid4())
- cfg.results_dir = os.path.join(results_storage,
- cfg.run_uuid)
-
- # setup all files paths
- cfg.update(get_test_files(cfg.results_dir))
-
- if existing:
- cfg.update(load_run_params(cfg.run_params_file))
-
- testnode_log_root = cfg.get('testnode_log_root')
- testnode_log_dir = os.path.join(testnode_log_root, "{0}/{{name}}")
- cfg.default_test_local_folder = testnode_log_dir.format(cfg.run_uuid)
-
- return cfg
-
-
-def save_run_params(cfg):
- params = {
- 'comment': cfg.comment,
- 'run_uuid': cfg.run_uuid
- }
-
- with open(cfg.run_params_file, 'w') as fd:
- fd.write(pretty_yaml.dumps(params))
-
-
-def load_run_params(run_params_file):
- with open(run_params_file) as fd:
- dt = yaml.load(fd)
-
- return dict(run_uuid=dt['run_uuid'],
- comment=dt.get('comment'))
+class Context:
+ def __init__(self, config: Config, storage: IStorage):
+ self.config = config
+ self.storage = storage
\ No newline at end of file