Commit 6c43d28d6324eb46df3683e93b24dfb9941a4d90
Committed by
Christian Herdtweck
1 parent
6bf5b9c9
msodde: simplify unit tests
Some msodde tests call the main() function from the module which tries to enable logging, causing lots of problems when running multiple tests due to the singleton dependency of the logging modules. Since what they want to test is whether msodde is finding links, we can use the process_file() function directly instead and check its output.
Showing
2 changed files
with
43 additions
and
78 deletions
tests/msodde/test_basic.py
| @@ -10,15 +10,13 @@ from __future__ import print_function | @@ -10,15 +10,13 @@ from __future__ import print_function | ||
| 10 | 10 | ||
| 11 | import unittest | 11 | import unittest |
| 12 | from oletools import msodde | 12 | from oletools import msodde |
| 13 | -from tests.test_utils import OutputCapture, DATA_BASE_DIR as BASE_DIR | ||
| 14 | -import shlex | 13 | +from tests.test_utils import DATA_BASE_DIR as BASE_DIR |
| 15 | from os.path import join | 14 | from os.path import join |
| 16 | from traceback import print_exc | 15 | from traceback import print_exc |
| 17 | 16 | ||
| 18 | 17 | ||
| 19 | class TestReturnCode(unittest.TestCase): | 18 | class TestReturnCode(unittest.TestCase): |
| 20 | """ check return codes and exception behaviour (not text output) """ | 19 | """ check return codes and exception behaviour (not text output) """ |
| 21 | - | ||
| 22 | def test_valid_doc(self): | 20 | def test_valid_doc(self): |
| 23 | """ check that a valid doc file leads to 0 exit status """ | 21 | """ check that a valid doc file leads to 0 exit status """ |
| 24 | for filename in ( | 22 | for filename in ( |
| @@ -59,87 +57,73 @@ class TestReturnCode(unittest.TestCase): | @@ -59,87 +57,73 @@ class TestReturnCode(unittest.TestCase): | ||
| 59 | 57 | ||
| 60 | def do_test_validity(self, args, expect_error=False): | 58 | def do_test_validity(self, args, expect_error=False): |
| 61 | """ helper for test_valid_doc[x] """ | 59 | """ helper for test_valid_doc[x] """ |
| 62 | - args = shlex.split(args) | ||
| 63 | - return_code = -1 | ||
| 64 | have_exception = False | 60 | have_exception = False |
| 65 | try: | 61 | try: |
| 66 | - return_code = msodde.main(args) | 62 | + msodde.process_file(args, msodde.FIELD_FILTER_BLACKLIST) |
| 67 | except Exception: | 63 | except Exception: |
| 68 | have_exception = True | 64 | have_exception = True |
| 69 | print_exc() | 65 | print_exc() |
| 70 | except SystemExit as exc: # sys.exit() was called | 66 | except SystemExit as exc: # sys.exit() was called |
| 71 | - return_code = exc.code | 67 | + have_exception = True |
| 72 | if exc.code is None: | 68 | if exc.code is None: |
| 73 | - return_code = 0 | 69 | + have_exception = False |
| 74 | 70 | ||
| 75 | - self.assertEqual(expect_error, have_exception or (return_code != 0), | ||
| 76 | - msg='Args={0}, expect={1}, exc={2}, return={3}' | ||
| 77 | - .format(args, expect_error, have_exception, | ||
| 78 | - return_code)) | 71 | + self.assertEqual(expect_error, have_exception, |
| 72 | + msg='Args={0}, expect={1}, exc={2}' | ||
| 73 | + .format(args, expect_error, have_exception)) | ||
| 79 | 74 | ||
| 80 | 75 | ||
| 81 | class TestDdeLinks(unittest.TestCase): | 76 | class TestDdeLinks(unittest.TestCase): |
| 82 | """ capture output of msodde and check dde-links are found correctly """ | 77 | """ capture output of msodde and check dde-links are found correctly """ |
| 83 | 78 | ||
| 84 | - def get_dde_from_output(self, capturer): | 79 | + @staticmethod |
| 80 | + def get_dde_from_output(output): | ||
| 85 | """ helper to read dde links from captured output | 81 | """ helper to read dde links from captured output |
| 86 | - | ||
| 87 | - duplicate in tests/msodde/test_csv | ||
| 88 | """ | 82 | """ |
| 89 | - have_start_line = False | ||
| 90 | - result = [] | ||
| 91 | - for line in capturer: | ||
| 92 | - if not line.strip(): | ||
| 93 | - continue # skip empty lines | ||
| 94 | - if have_start_line: | ||
| 95 | - result.append(line) | ||
| 96 | - elif line == 'DDE Links:': | ||
| 97 | - have_start_line = True | ||
| 98 | - | ||
| 99 | - self.assertTrue(have_start_line) # ensure output was complete | ||
| 100 | - return result | 83 | + return [o for o in output.splitlines()] |
| 101 | 84 | ||
| 102 | def test_with_dde(self): | 85 | def test_with_dde(self): |
| 103 | """ check that dde links appear on stdout """ | 86 | """ check that dde links appear on stdout """ |
| 104 | filename = 'dde-test-from-office2003.doc' | 87 | filename = 'dde-test-from-office2003.doc' |
| 105 | - with OutputCapture() as capturer: | ||
| 106 | - msodde.main([join(BASE_DIR, 'msodde', filename)]) | ||
| 107 | - self.assertNotEqual(len(self.get_dde_from_output(capturer)), 0, | 88 | + output = msodde.process_file( |
| 89 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_BLACKLIST) | ||
| 90 | + self.assertNotEqual(len(self.get_dde_from_output(output)), 0, | ||
| 108 | msg='Found no dde links in output of ' + filename) | 91 | msg='Found no dde links in output of ' + filename) |
| 109 | 92 | ||
| 110 | def test_no_dde(self): | 93 | def test_no_dde(self): |
| 111 | """ check that no dde links appear on stdout """ | 94 | """ check that no dde links appear on stdout """ |
| 112 | filename = 'harmless-clean.doc' | 95 | filename = 'harmless-clean.doc' |
| 113 | - with OutputCapture() as capturer: | ||
| 114 | - msodde.main([join(BASE_DIR, 'msodde', filename)]) | ||
| 115 | - self.assertEqual(len(self.get_dde_from_output(capturer)), 0, | 96 | + output = msodde.process_file( |
| 97 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_BLACKLIST) | ||
| 98 | + self.assertEqual(len(self.get_dde_from_output(output)), 0, | ||
| 116 | msg='Found dde links in output of ' + filename) | 99 | msg='Found dde links in output of ' + filename) |
| 117 | 100 | ||
| 118 | def test_with_dde_utf16le(self): | 101 | def test_with_dde_utf16le(self): |
| 119 | """ check that dde links appear on stdout """ | 102 | """ check that dde links appear on stdout """ |
| 120 | filename = 'dde-test-from-office2013-utf_16le-korean.doc' | 103 | filename = 'dde-test-from-office2013-utf_16le-korean.doc' |
| 121 | - with OutputCapture() as capturer: | ||
| 122 | - msodde.main([join(BASE_DIR, 'msodde', filename)]) | ||
| 123 | - self.assertNotEqual(len(self.get_dde_from_output(capturer)), 0, | 104 | + output = msodde.process_file( |
| 105 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_BLACKLIST) | ||
| 106 | + self.assertNotEqual(len(self.get_dde_from_output(output)), 0, | ||
| 124 | msg='Found no dde links in output of ' + filename) | 107 | msg='Found no dde links in output of ' + filename) |
| 125 | 108 | ||
| 126 | def test_excel(self): | 109 | def test_excel(self): |
| 127 | """ check that dde links are found in excel 2007+ files """ | 110 | """ check that dde links are found in excel 2007+ files """ |
| 128 | expect = ['DDE-Link cmd /c calc.exe', ] | 111 | expect = ['DDE-Link cmd /c calc.exe', ] |
| 129 | for extn in 'xlsx', 'xlsm', 'xlsb': | 112 | for extn in 'xlsx', 'xlsm', 'xlsb': |
| 130 | - with OutputCapture() as capturer: | ||
| 131 | - msodde.main([join(BASE_DIR, 'msodde', 'dde-test.' + extn), ]) | ||
| 132 | - self.assertEqual(expect, self.get_dde_from_output(capturer), | 113 | + output = msodde.process_file( |
| 114 | + join(BASE_DIR, 'msodde', 'dde-test.' + extn), msodde.FIELD_FILTER_BLACKLIST) | ||
| 115 | + | ||
| 116 | + self.assertEqual(expect, self.get_dde_from_output(output), | ||
| 133 | msg='unexpected output for dde-test.{0}: {1}' | 117 | msg='unexpected output for dde-test.{0}: {1}' |
| 134 | - .format(extn, capturer.get_data())) | 118 | + .format(extn, output)) |
| 135 | 119 | ||
| 136 | def test_xml(self): | 120 | def test_xml(self): |
| 137 | """ check that dde in xml from word / excel is found """ | 121 | """ check that dde in xml from word / excel is found """ |
| 138 | for name_part in 'excel2003', 'word2003', 'word2007': | 122 | for name_part in 'excel2003', 'word2003', 'word2007': |
| 139 | filename = 'dde-in-' + name_part + '.xml' | 123 | filename = 'dde-in-' + name_part + '.xml' |
| 140 | - with OutputCapture() as capturer: | ||
| 141 | - msodde.main([join(BASE_DIR, 'msodde', filename), ]) | ||
| 142 | - links = self.get_dde_from_output(capturer) | 124 | + output = msodde.process_file( |
| 125 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_BLACKLIST) | ||
| 126 | + links = self.get_dde_from_output(output) | ||
| 143 | self.assertEqual(len(links), 1, 'found {0} dde-links in {1}' | 127 | self.assertEqual(len(links), 1, 'found {0} dde-links in {1}' |
| 144 | .format(len(links), filename)) | 128 | .format(len(links), filename)) |
| 145 | self.assertTrue('cmd' in links[0], 'no "cmd" in dde-link for {0}' | 129 | self.assertTrue('cmd' in links[0], 'no "cmd" in dde-link for {0}' |
| @@ -150,16 +134,16 @@ class TestDdeLinks(unittest.TestCase): | @@ -150,16 +134,16 @@ class TestDdeLinks(unittest.TestCase): | ||
| 150 | def test_clean_rtf_blacklist(self): | 134 | def test_clean_rtf_blacklist(self): |
| 151 | """ find a lot of hyperlinks in rtf spec """ | 135 | """ find a lot of hyperlinks in rtf spec """ |
| 152 | filename = 'RTF-Spec-1.7.rtf' | 136 | filename = 'RTF-Spec-1.7.rtf' |
| 153 | - with OutputCapture() as capturer: | ||
| 154 | - msodde.main([join(BASE_DIR, 'msodde', filename)]) | ||
| 155 | - self.assertEqual(len(self.get_dde_from_output(capturer)), 1413) | 137 | + output = msodde.process_file( |
| 138 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_BLACKLIST) | ||
| 139 | + self.assertEqual(len(self.get_dde_from_output(output)), 1413) | ||
| 156 | 140 | ||
| 157 | def test_clean_rtf_ddeonly(self): | 141 | def test_clean_rtf_ddeonly(self): |
| 158 | """ find no dde links in rtf spec """ | 142 | """ find no dde links in rtf spec """ |
| 159 | filename = 'RTF-Spec-1.7.rtf' | 143 | filename = 'RTF-Spec-1.7.rtf' |
| 160 | - with OutputCapture() as capturer: | ||
| 161 | - msodde.main(['-d', join(BASE_DIR, 'msodde', filename)]) | ||
| 162 | - self.assertEqual(len(self.get_dde_from_output(capturer)), 0, | 144 | + output = msodde.process_file( |
| 145 | + join(BASE_DIR, 'msodde', filename), msodde.FIELD_FILTER_DDE) | ||
| 146 | + self.assertEqual(len(self.get_dde_from_output(output)), 0, | ||
| 163 | msg='Found dde links in output of ' + filename) | 147 | msg='Found dde links in output of ' + filename) |
| 164 | 148 | ||
| 165 | 149 |
tests/msodde/test_csv.py
| @@ -9,7 +9,7 @@ import os | @@ -9,7 +9,7 @@ import os | ||
| 9 | from os.path import join | 9 | from os.path import join |
| 10 | 10 | ||
| 11 | from oletools import msodde | 11 | from oletools import msodde |
| 12 | -from tests.test_utils import OutputCapture, DATA_BASE_DIR | 12 | +from tests.test_utils import DATA_BASE_DIR |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | class TestCSV(unittest.TestCase): | 15 | class TestCSV(unittest.TestCase): |
| @@ -69,11 +69,8 @@ class TestCSV(unittest.TestCase): | @@ -69,11 +69,8 @@ class TestCSV(unittest.TestCase): | ||
| 69 | def test_file(self): | 69 | def test_file(self): |
| 70 | """ test simple small example file """ | 70 | """ test simple small example file """ |
| 71 | filename = join(DATA_BASE_DIR, 'msodde', 'dde-in-csv.csv') | 71 | filename = join(DATA_BASE_DIR, 'msodde', 'dde-in-csv.csv') |
| 72 | - with OutputCapture() as capturer: | ||
| 73 | - capturer.reload_module(msodde) # re-create logger | ||
| 74 | - ret_code = msodde.main([filename, ]) | ||
| 75 | - self.assertEqual(ret_code, 0) | ||
| 76 | - links = self.get_dde_from_output(capturer) | 72 | + output = msodde.process_file(filename, msodde.FIELD_FILTER_BLACKLIST) |
| 73 | + links = self.get_dde_from_output(output) | ||
| 77 | self.assertEqual(len(links), 1) | 74 | self.assertEqual(len(links), 1) |
| 78 | self.assertEqual(links[0], | 75 | self.assertEqual(links[0], |
| 79 | r"cmd '/k \..\..\..\Windows\System32\calc.exe'") | 76 | r"cmd '/k \..\..\..\Windows\System32\calc.exe'") |
| @@ -91,12 +88,10 @@ class TestCSV(unittest.TestCase): | @@ -91,12 +88,10 @@ class TestCSV(unittest.TestCase): | ||
| 91 | if self.DO_DEBUG: | 88 | if self.DO_DEBUG: |
| 92 | args += ['-l', 'debug'] | 89 | args += ['-l', 'debug'] |
| 93 | 90 | ||
| 94 | - with OutputCapture() as capturer: | ||
| 95 | - capturer.reload_module(msodde) # re-create logger | ||
| 96 | - ret_code = msodde.main(args) | ||
| 97 | - self.assertEqual(ret_code, 0, 'checking sample resulted in ' | ||
| 98 | - 'error:\n' + sample_text) | ||
| 99 | - return capturer | 91 | + processed_args = msodde.process_args(args) |
| 92 | + | ||
| 93 | + return msodde.process_file( | ||
| 94 | + processed_args.filepath, processed_args.field_filter_mode) | ||
| 100 | 95 | ||
| 101 | except Exception: | 96 | except Exception: |
| 102 | raise | 97 | raise |
| @@ -111,25 +106,11 @@ class TestCSV(unittest.TestCase): | @@ -111,25 +106,11 @@ class TestCSV(unittest.TestCase): | ||
| 111 | os.remove(filename) | 106 | os.remove(filename) |
| 112 | filename = None # just in case | 107 | filename = None # just in case |
| 113 | 108 | ||
| 114 | - def get_dde_from_output(self, capturer): | 109 | + @staticmethod |
| 110 | + def get_dde_from_output(output): | ||
| 115 | """ helper to read dde links from captured output | 111 | """ helper to read dde links from captured output |
| 116 | - | ||
| 117 | - duplicate in tests/msodde/test_basic | ||
| 118 | """ | 112 | """ |
| 119 | - have_start_line = False | ||
| 120 | - result = [] | ||
| 121 | - for line in capturer: | ||
| 122 | - if self.DO_DEBUG: | ||
| 123 | - print('captured: ' + line) | ||
| 124 | - if not line.strip(): | ||
| 125 | - continue # skip empty lines | ||
| 126 | - if have_start_line: | ||
| 127 | - result.append(line) | ||
| 128 | - elif line == 'DDE Links:': | ||
| 129 | - have_start_line = True | ||
| 130 | - | ||
| 131 | - self.assertTrue(have_start_line) # ensure output was complete | ||
| 132 | - return result | 113 | + return [o for o in output.splitlines()] |
| 133 | 114 | ||
| 134 | def test_regex(self): | 115 | def test_regex(self): |
| 135 | """ check that regex captures other ways to include dde commands | 116 | """ check that regex captures other ways to include dde commands |