-
Notifications
You must be signed in to change notification settings - Fork 35
/
run_tests.py
133 lines (105 loc) · 3.76 KB
/
run_tests.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
# vim:fileencoding=utf-8
# License: Apache 2.0 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
import argparse
import importlib
import os
import sys
import unittest
if 'HTML5_PARSER_DLL_DIR' in os.environ:
sys.save_dll_dir = os.add_dll_directory(os.environ['HTML5_PARSER_DLL_DIR'])
print('Added DLL directory', sys.save_dll_dir, 'with contents:',
os.listdir(os.environ['HTML5_PARSER_DLL_DIR']))
print('Current sys.path:', sys.path)
self_path = os.path.abspath(__file__)
base = os.path.dirname(self_path)
html5lib_tests_path = os.path.join(base, 'test', 'html5lib-tests')
def itertests(suite):
stack = [suite]
while stack:
suite = stack.pop()
for test in suite:
if isinstance(test, unittest.TestSuite):
stack.append(test)
continue
if test.__class__.__name__ == 'ModuleImportFailure':
raise Exception('Failed to import a test module: %s' % test)
yield test
def filter_tests(suite, test_ok):
ans = unittest.TestSuite()
added = set()
for test in itertests(suite):
if test_ok(test) and test not in added:
ans.addTest(test)
added.add(test)
return ans
def filter_tests_by_name(suite, name):
if not name.startswith('test_'):
name = 'test_' + name
if name.endswith('_'):
def q(test):
return test._testMethodName.startswith(name)
else:
def q(test):
return test._testMethodName == name
return filter_tests(suite, q)
def filter_tests_by_module(suite, *names):
names = frozenset(names)
def q(test):
m = test.__class__.__module__.rpartition('.')[-1]
return m in names
return filter_tests(suite, q)
def find_tests():
suites = []
for f in os.listdir(os.path.join(base, 'test')):
n, ext = os.path.splitext(f)
if ext == '.py' and n not in ('__init__', 'html5lib_adapter'):
m = importlib.import_module('test.' + n)
suite = unittest.defaultTestLoader.loadTestsFromModule(m)
suites.append(suite)
if 'SKIP_HTML5LIB' not in os.environ:
from test.html5lib_adapter import find_tests
suites.extend(find_tests())
return unittest.TestSuite(suites)
def run_memleak_tests():
tests = find_tests()
tests = filter_tests_by_name(tests, 'asan_memleak')
r = unittest.TextTestRunner
result = r(verbosity=4).run(tests)
if not result.wasSuccessful():
raise SystemExit(1)
def main():
sys.path.insert(0, base)
if 'MEMLEAK_EXE' in os.environ:
return run_memleak_tests()
parser = argparse.ArgumentParser(
description='''\
Run the specified tests, or all tests if none are specified. Tests
can be specified as either the test method name (without the leading test_)
or a module name with a trailing period.
''')
parser.add_argument(
'test_name',
nargs='*',
help=(
'Test name (either a method name or a module name with a trailing period)'
'. Note that if the name ends with a trailing underscore all tests methods'
' whose names start with the specified name are run.'
)
)
args = parser.parse_args()
tests = find_tests()
suites = []
for name in args.test_name:
if name.endswith('.'):
suites.append(filter_tests_by_module(tests, name[:-1]))
else:
suites.append(filter_tests_by_name(tests, name))
tests = unittest.TestSuite(suites) if suites else tests
r = unittest.TextTestRunner
result = r().run(tests)
if not result.wasSuccessful():
raise SystemExit(1)
if __name__ == '__main__':
main()