diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2017-07-07 17:03:42 +0000 |
| commit | 33a9b234e7087f573ef08cd7318c6497ba08b439 (patch) | |
| tree | d0ea40ad3bf5463a3c55795977c71bcb7d781b4b /src/tests/jsonwalker.py | |
Diffstat (limited to 'src/tests/jsonwalker.py')
| -rw-r--r-- | src/tests/jsonwalker.py | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/tests/jsonwalker.py b/src/tests/jsonwalker.py new file mode 100644 index 000000000000..265c69c703a2 --- /dev/null +++ b/src/tests/jsonwalker.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +import sys +try: + import cjson +except ImportError: + print "Warning: skipping audit log verification because the cjson module" \ + " is unavailable" + sys.exit(0) +from collections import defaultdict +from optparse import OptionParser + +class Parser(object): + DEFAULTS = {int:0, + str:'', + list:[]} + + def __init__(self, defconf=None): + self.defaults = None + if defconf is not None: + self.defaults = self.flatten(defconf) + + def run(self, logs, verbose=None): + result = self.parse(logs) + if len(result) != len(self.defaults): + diff = set(self.defaults.keys()).difference(result.keys()) + print 'Test failed.' + print 'The following attributes were not set:' + for it in diff: + print it + sys.exit(1) + + def flatten(self, defaults): + """ + Flattens pathes to attributes. + + Parameters + ---------- + defaults : a dictionaries populated with default values + + Returns : + dict : with flattened attributes + """ + result = dict() + for path,value in self._walk(defaults): + if path in result: + print 'Warning: attribute path %s already exists' % path + result[path] = value + + return result + + def parse(self, logs): + result = defaultdict(list) + for msg in logs: + # each message is treated as a dictionary of dictionaries + for a,v in self._walk(msg): + # see if path is registered in defaults + if a in self.defaults: + dv = self.defaults.get(a) + if dv is None: + # determine default value by type + if v is not None: + dv = self.DEFAULTS[type(v)] + else: + print 'Warning: attribute %s is set to None' % a + continue + # by now we have default value + if v != dv: + # test passed + result[a].append(v) + return result + + def _walk(self, adict): + """ + Generator that works through dictionary. + """ + for a,v in adict.iteritems(): + if isinstance(v,dict): + for (attrpath,u) in self._walk(v): + yield (a+'.'+attrpath,u) + else: + yield (a,v) + + +if __name__ == '__main__': + + parser = OptionParser() + parser.add_option("-i", "--logfile", dest="filename", + help="input log file in json fmt", metavar="FILE") + parser.add_option("-d", "--defaults", dest="defaults", + help="dictionary with defaults", metavar="FILE") + + (options, args) = parser.parse_args() + if options.filename is not None: + with open(options.filename, 'r') as f: + content = list() + for l in f: + content.append(cjson.decode(l.rstrip())) + f.close() + else: + print 'Input file in jason format is required' + exit() + + defaults = None + if options.defaults is not None: + with open(options.defaults, 'r') as f: + defaults = cjson.decode(f.read()) + f.close() + + # run test + p = Parser(defaults) + p.run(content) + exit() |
