Commit 6c43d28d6324eb46df3683e93b24dfb9941a4d90

Authored by Samir Aguiar
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.
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