-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathtest-harness
executable file
·136 lines (103 loc) · 4.66 KB
/
test-harness
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
#!/usr/bin/env python
# encoding: utf-8
"""
Run compliance tests for a BagIt command-line tool
This requires a tool which behaves like a standard Unix tool and returns 0 for
success and 1 for failures. This tool will check stderr and report its contents
for the warning test bags.
Example usage:
%(prog)s -- bagit.py --validate --quiet
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import argparse
import logging
import os
import platform
import subprocess
import sys
BASE_DIR = os.path.dirname(__file__)
SYSTEM = platform.system().lower()
DEFAULT_ENCODING = sys.stdout.encoding
if DEFAULT_ENCODING.upper() != 'UTF-8':
print('Default encoding is %s: use with caution, UTF-8 is recommended' % DEFAULT_ENCODING, file=sys.stderr)
def run_version_suite(test_program_argv, version_dir):
spec_version = os.path.basename(version_dir)
for test_category in os.listdir(version_dir):
test_subsuite_directory = os.path.join(version_dir, test_category)
if not os.path.isdir(test_subsuite_directory):
continue
if test_category.endswith('-only') and not test_category.startswith(SYSTEM):
logging.info('Skipping %s tests as we are running on %s', test_category, SYSTEM)
continue
logging.info('Running version %s %s tests', spec_version, test_category)
for test_bag in os.listdir(test_subsuite_directory):
if not os.path.isdir(os.path.join(test_subsuite_directory, test_bag)):
continue
proc = subprocess.run(test_program_argv + [test_bag],
capture_output=True,
cwd=test_subsuite_directory)
rc = proc.returncode
stdout = proc.stdout
stderr = proc.stderr
# We'll select the log level based on whether we expected an error:
log_f = logging.info
dump_stderr = False
if test_category == 'valid':
if rc != 0:
log_f = logging.error
dump_stderr = True
elif test_category == 'invalid':
if rc == 0:
log_f = logging.error
elif test_category == 'warning':
if rc == 0 and not stderr:
log_f = logging.warning
log_f('Expected %s test %s: rc=%d, stdout=%d bytes, stderr=%d bytes',
test_category, test_bag, rc, len(stdout), len(stderr))
log_captured_output(logging.info, 'stdout', stdout)
log_captured_output(log_f if dump_stderr else logging.info, 'stderr', stderr)
def log_captured_output(logger, stream_name, output):
output = output.decode(DEFAULT_ENCODING).strip()
if output:
logger('%s:\n\t%%s' % stream_name, output.replace('\n', '\n\t'))
def configure_logging(verbosity=0):
if verbosity > 1:
desired_level = logging.DEBUG
elif verbosity > 0:
desired_level = logging.INFO
else:
desired_level = logging.WARNING
try:
import coloredlogs
coloredlogs.install(level=desired_level, reconfigure=True)
return
except ImportError:
pass
if verbosity:
stdout_handler = logging.StreamHandler(stream=sys.stdout)
stdout_handler.setLevel(desired_level)
logging.getLogger().addHandler(stdout_handler)
logging.getLogger().setLevel(desired_level)
else:
logging.basicConfig(level=logging.WARNING, stream=sys.stderr)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__.strip(),
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--verbosity', '-v', action='count', default=0)
parser.add_argument('test_program', metavar='TEST_PROGRAM', help='Path to an executable')
parser.add_argument('test_program_arguments', nargs='*',
help='Arguments for the test executable - e.g. --validate for bagit.py.'
' Note that on many shells you may need to follow the common'
' convention of placing -- before the start of arguments which are'
' intended for the test executable rather than this program.')
args = parser.parse_args()
configure_logging(args.verbosity)
test_prog = [args.test_program]
test_prog.extend(args.test_program_arguments)
for i in os.listdir(os.path.normpath(BASE_DIR)):
if not os.path.isdir(i):
continue
if not i.startswith('v'):
continue
version_dir = os.path.join(BASE_DIR, i)
run_version_suite(test_prog, version_dir)