From f2d2fe46fc282fa28b5ab1ebd4c30e7dafa1c932 Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Fri, 27 Oct 2017 14:22:20 +0200 Subject: [PATCH] unittest: Create unittests for json output validity in msodde --- tests/json/__init__.py | 0 tests/json/test_output.py | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 0 deletions(-) create mode 100644 tests/json/__init__.py create mode 100644 tests/json/test_output.py diff --git a/tests/json/__init__.py b/tests/json/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/json/__init__.py diff --git a/tests/json/test_output.py b/tests/json/test_output.py new file mode 100644 index 0000000..0a796df --- /dev/null +++ b/tests/json/test_output.py @@ -0,0 +1,96 @@ +""" Test validity of json output + +Some scripts have a json output flag. Verify that at default log levels output +can be captured as-is and parsed by a json parser -- at least if the scripts +return 0 +""" + +import unittest +import sys +import json +import os +from os.path import join, dirname, normpath +from oletools import msodde +from tests.test_utils import OutputCapture + +if sys.version_info[0] <= 2: + from oletools import olevba +else: + from oletools import olevba3 as olevba + + +# Directory with test data, independent of current working directory +DATA_DIR = normpath(join(dirname(__file__), '..', 'test-data')) + + +class TestValidJson(unittest.TestCase): + """ Ensure that script output is valid json (if return code is 0) """ + + def iter_test_files(self): + """ Iterate over all test files in DATA_DIR """ + for dirpath, _, filenames in os.walk(DATA_DIR): + for filename in filenames: + yield join(dirpath, filename) + + def run_and_parse(self, program, args, print_output=False): + """ run single program with single file and parse output """ + return_code = None + with OutputCapture() as capturer: # capture stdout + try: + return_code = program(args) + except Exception: + return_code = 1 # would result in non-zero exit + except SystemExit as se: + return_code = se.code or 0 # se.code can be None + if return_code is not 0: + if print_output: + print('Command failed ({0}) -- not parsing output' + .format(return_code)) + return # no need to test + + self.assertNotEqual(return_code, None, + msg='self-test fail: return_code not set') + + # now test output + if print_output: + print(capturer.buffer.getvalue()) + capturer.buffer.seek(0) # re-set position in file-like stream + try: + json_data = json.load(capturer.buffer) + except ValueError: + self.fail('Invalid json:\n' + capturer.buffer.getvalue()) + self.assertNotEqual(len(json_data), 0, msg='Output was empty') + + def run_all_files(self, program, args_without_filename, print_output=False): + """ run test for a single program over all test files """ + n_files = 0 + for testfile in self.iter_test_files(): # loop over all input + args = args_without_filename + [testfile, ] + self.run_and_parse(program, args, print_output) + n_files += 1 + self.assertNotEqual(n_files, 0, + msg='self-test fail: No test files found') + + def test_msodde(self): + """ Test msodde.py """ + self.run_all_files(msodde.main, ['-j', ]) + + @unittest.skip('olevba needs patching to accept custom cmd line args') + def test_olevba(self): + """ Test olevba.py with default args """ + self.run_all_files(olevba.main, ['-j', ]) + + @unittest.skip('olevba needs patching to accept custom cmd line args') + def test_olevba_analysis(self): + """ Test olevba.py with default args """ + self.run_all_files(olevba.main, ['-j', '-a', ]) + + @unittest.skip('olevba needs patching to accept custom cmd line args') + def test_olevba_recurse(self): + """ Test olevba.py with default args """ + self.run_and_parse(olevba.main, ['-j', '-r', DATA_DIR], True) + + +# just in case somebody calls this file as a script +if __name__ == '__main__': + unittest.main() -- libgit2 0.21.4