Shorten VDU names
[osm/SO.git] / common / python / rift / mano / utils / compare_desc.py
1 #
2 # Copyright 2016 RIFT.io Inc
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17
18 import argparse
19 import json
20 import logging
21 import logging.config
22 import pprint
23
24 from deepdiff import DeepDiff
25
26 from rift.mano.yang_translator.common.utils import _
27
28 import yaml
29
30
31 class CompareDescShell(object):
32
33 SUPPORTED_TYPES = ['yaml', 'json']
34 INDENT = 2
35
36 DIFF_KEYS = (
37 REMOVED_ITEMS,
38 ADDED_ITEMS,
39 ITER_ITEM_ADDED,
40 ITER_ITEM_REM,
41 TYPE_CHANGES,
42 VALUES_CHANGED,
43 ) = (
44 'dic_item_removed',
45 'dic_item_added',
46 'iterable_item_added',
47 'iterable_item_removed',
48 'type_changes',
49 'values_changed',
50 )
51
52 DIFF_MAP = {
53 REMOVED_ITEMS: 'Items removed',
54 ADDED_ITEMS: 'Items added',
55 ITER_ITEM_ADDED: 'Items added to list',
56 ITER_ITEM_REM: 'Items removed from list',
57 TYPE_CHANGES: 'Change in types',
58 VALUES_CHANGED: 'Change in values',
59 }
60
61 # Changes in following items are error
62 ERROR_ITEMS = [REMOVED_ITEMS, ADDED_ITEMS, ITER_ITEM_ADDED,
63 ITER_ITEM_REM, TYPE_CHANGES, ]
64
65 @classmethod
66 def compare_dicts(cls, generated, expected, log=None):
67 """Compare two dictionaries and generate error if required"""
68 if log:
69 log.debug(_("Generated: {0}").format(generated))
70 log.debug(_("Expected: {0}").format(expected))
71
72 diff = DeepDiff(expected, generated)
73 if log:
74 log.debug(_("Keys in diff: {0}").format(diff.keys()))
75 log.info(_("Differences:\n"))
76
77 if log:
78 d = pprint.pformat(diff, indent=cls.INDENT)
79 log.info("Differences:\n{0}".format(d))
80
81 if len(set(cls.ERROR_ITEMS).intersection(diff.keys())):
82 diff_str = pprint.pformat(diff)
83 msg = _("Found item changes: {0}").format(diff_str)
84 if log:
85 log.error(msg)
86 raise ValueError(msg)
87
88 def main(self, log, args):
89 self.log = log
90 self.log.debug(_("Args: {0}").format(args))
91 if args.type not in self.SUPPORTED_TYPES:
92 self.log.error(_("Unsupported file type {0}").
93 format(args.type))
94 exit(1)
95
96 with open(args.generated) as g:
97 gen_data = g.read()
98 if args.type == 'yaml':
99 y_gen = yaml.load(gen_data)
100 else:
101 y_gen = json.loads(gen_data)
102
103 with open(args.expected) as e:
104 exp_data = e.read()
105 if args.type == 'yaml':
106 y_exp = yaml.load(exp_data)
107 else:
108 y_exp = json.loads(exp_data)
109
110 self.compare_dicts(y_gen, y_exp, log=self.log)
111
112
113 def main(args=None, log=None):
114 parser = argparse.ArgumentParser(
115 description='Validate descriptors by comparing')
116 parser.add_argument(
117 "-g",
118 "--generated",
119 required=True,
120 help="Generated descriptor file")
121 parser.add_argument(
122 "-e",
123 "--expected",
124 required=True,
125 help="Descriptor file to compare")
126 parser.add_argument(
127 "-t",
128 "--type",
129 default='yaml',
130 help="File type. Default yaml")
131 parser.add_argument(
132 "--debug",
133 help="Enable debug logging",
134 action="store_true")
135
136 if args:
137 args = parser.parse_args(args)
138 else:
139 args = parser.parse_args()
140
141 if log is None:
142 if args.debug:
143 logging.basicConfig(level=logging.DEBUG)
144 else:
145 logging.basicConfig(level=logging.ERROR)
146 log = logging.getLogger("rwmano-translator")
147
148 CompareDescShell().main(log, args)
149
150
151 if __name__ == '__main__':
152 main()