diff options
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()  | 
