[NFVBENCH-59] Add Unit Testing of the NDR/PDR convergence algorithm using the dummy...
[nfvbench.git] / nfvbench / config.py
1 # Copyright 2016 Cisco Systems, Inc.  All rights reserved.
2 #
3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
4 #    not use this file except in compliance with the License. You may obtain
5 #    a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #    Unless required by applicable law or agreed to in writing, software
10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 #    License for the specific language governing permissions and limitations
13 #    under the License.
14 #
15
16 from attrdict import AttrDict
17 import yaml
18
19 from log import LOG
20
21 def config_load(file_name, from_cfg=None, whitelist_keys=None):
22     """Load a yaml file into a config dict, merge with from_cfg if not None
23     The config file content taking precedence in case of duplicate
24     """
25     try:
26         with open(file_name) as fileobj:
27             cfg = AttrDict(yaml.safe_load(fileobj))
28     except IOError:
29         raise Exception("Configuration file at '{}' was not found. Please use correct path "
30                         "and verify it is visible to container if you run nfvbench in container."
31                         .format(file_name))
32
33     if from_cfg:
34         if not whitelist_keys:
35             whitelist_keys = []
36         _validate_config(cfg, from_cfg, whitelist_keys)
37         cfg = from_cfg + cfg
38
39     return cfg
40
41
42 def config_loads(cfg_text, from_cfg=None, whitelist_keys=None):
43     """Same as config_load but load from a string
44     """
45     try:
46         cfg = AttrDict(yaml.load(cfg_text))
47     except TypeError:
48         # empty string
49         cfg = AttrDict()
50     if from_cfg:
51         if not whitelist_keys:
52             whitelist_keys = []
53         _validate_config(cfg, from_cfg, whitelist_keys)
54         return from_cfg + cfg
55     return cfg
56
57
58 def _validate_config(subset, superset, whitelist_keys):
59     def get_err_config(subset, superset):
60         result = {}
61         for k, v in subset.items():
62             if k not in whitelist_keys:
63                 if k not in superset:
64                     result.update({k: v})
65                 elif v is not None and superset[k] is not None:
66                     if not isinstance(v, type(superset[k])):
67                         result.update({k: v})
68                         continue
69                 if isinstance(v, dict):
70                     res = get_err_config(v, superset[k])
71                     if res:
72                         result.update({k: res})
73         if not result:
74             return None
75         return result
76
77     err_cfg = get_err_config(subset, superset)
78     if err_cfg:
79         err_msg = 'The provided configuration has unknown options or values with invalid type: '\
80                   + str(err_cfg)
81         LOG.error(err_msg)
82         raise Exception(err_msg)