/
all_tests.py
executable file
·155 lines (125 loc) · 5.71 KB
/
all_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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
# ----------------------------------------------------------------------------
# Copyright (c) 2013--, emperor development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE.md, distributed with this software.
# ----------------------------------------------------------------------------
"""Run all tests.
Originally based on the all_tests.py script from the QIIME project
(http://github.com/qiime/qiime) project at svn revision 3290, now taken from
the E-vident (http://github.com/qiime/evident) project master branch at git SHA
dde2a06f2d990db8b09da65764cd27fc047db788
"""
import re
import sys
import click
import subprocess
from os import walk
from glob import glob
from os.path import join, abspath, dirname, split
from emperor import __version__
def console(cmd, stdout=None, stderr=None):
"""Small subprocess helper function
Originally based on this SO answer:
http://stackoverflow.com/a/33542403/379593
"""
if stdout is None:
stdout = subprocess.PIPE
if stderr is None:
stderr = subprocess.PIPE
process = subprocess.Popen(cmd, shell=True, stdout=stdout, stderr=stderr)
o, e = process.communicate()
return '' if o is None else o, '' if e is None else e, process.returncode
@click.command()
@click.option('--suppress_unit_tests', help="suppress execution of Emperor's "
"unit tests", default=False, is_flag=True, show_default=True)
@click.option('--suppress_javascript_unit_tests', help="suppress Emperor's "
"JavaScript unit tests.", default=False, is_flag=True,
show_default=True)
@click.option('--unittest_glob', help='wildcard pattern to match the unit '
'tests to execute.', default=None, is_flag=True,
show_default=True)
@click.version_option(__version__)
def test(suppress_unit_tests, suppress_javascript_unit_tests, unittest_glob):
"""Run Emperor's test suite.
Run the Python unit tests or the JavaScript unit tests (requires
phantomjs to be installed).
"""
# make a sanity check
if suppress_unit_tests and suppress_javascript_unit_tests:
raise click.UsageError("All tests have been suppresed. Nothing to "
"run.")
test_dir = abspath(dirname(__file__))
unittest_good_pattern = re.compile(b'OK\s*$')
application_not_found_pattern = re.compile(b'ApplicationNotFoundError')
python_name = 'python'
bad_tests = []
missing_application_tests = []
# Run through all of Emperor's unit tests, and keep track of any files
# which fail unit tests, note that these are the unit tests only
if not suppress_unit_tests:
unittest_names = []
if not unittest_glob:
for root, dirs, files in walk(test_dir):
for name in files:
if name.startswith('test_') and name.endswith('.py'):
unittest_names.append(join(root, name))
else:
for fp in glob(unittest_glob):
fn = split(fp)[1]
if fn.startswith('test_') and fn.endswith('.py'):
unittest_names.append(abspath(fp))
unittest_names.sort()
for unittest_name in unittest_names:
print("Testing %s:\n" % unittest_name)
command = '%s %s -v' % (python_name, unittest_name)
stdout, stderr, return_value = console(command)
print(stderr.decode("utf-8"))
if not unittest_good_pattern.search(stderr):
if application_not_found_pattern.search(stderr):
missing_application_tests.append(unittest_name)
else:
bad_tests.append(unittest_name)
if not suppress_javascript_unit_tests:
print("JavaScript Test Suite")
runner = join(test_dir, 'javascript_tests', 'runner.js')
index = join(test_dir, 'javascript_tests', 'index.html')
# phantomjs has some problems where the program will not terminate if
# an error occurs during the execution of the test suite. That's why
# all output is sent to standard output and standard error.
_, _, r = console('phantomjs %s %s' % (runner, index), sys.stdout,
sys.stderr)
# if all the tests passed
javascript_tests_passed = True if r == 0 else False
else:
javascript_tests_passed = True
print("==============\nResult summary\n==============")
if not suppress_unit_tests:
print("\nUnit test result summary\n------------------------\n")
if bad_tests:
print("\nThe following unit tests failed.\n%s"
% '\n'.join(bad_tests))
if missing_application_tests:
print("\nThe following unit tests failed, in part or whole due "
"to missing external applications.\nDepending on the "
"Emperor features you plan to use, this may not be "
"critical.\n%s" % '\n'.join(missing_application_tests))
if not(missing_application_tests or bad_tests):
print("\nAll unit tests passed.\n")
if not suppress_javascript_unit_tests:
print('\nJavaScript unit tests result summary\n'
'------------------------------------\n')
if javascript_tests_passed:
print('All JavaScript unit tests passed.\n')
else:
print('JavaScript unit tests failed, check the summary above.')
# In case there were no failures of any type, exit with a return code of 0
return_code = 1
if (len(bad_tests) == 0 and len(missing_application_tests) == 0 and
javascript_tests_passed):
return_code = 0
exit(return_code)
if __name__ == "__main__":
test()