blob: bb00793997a73a0338b813505d3d59db554b526f [file] [log] [blame]
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +02001#!/usr/bin/env python3
2
3import os
4import sys
5import subprocess
6import time
7import difflib
8import argparse
Neels Hofmeyr3531a192017-03-28 14:30:28 +02009import re
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020010
11parser = argparse.ArgumentParser()
12parser.add_argument('testdir_or_test', nargs='*',
13 help='subdir name or test script name')
14parser.add_argument('-u', '--update', action='store_true',
15 help='Update test expecations instead of verifying them')
16args = parser.parse_args()
17
18def run_test(path):
19 print(path)
20 p = subprocess.Popen(path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
21 o,e = p.communicate()
22 while True:
23 retval = p.poll()
24 if retval is not None:
25 break;
26 p.kill()
27 time.sleep(.1)
28 return retval, o.decode('utf-8'), e.decode('utf-8')
29
30def udiff(expect, got, expect_path):
31 expect = expect.splitlines(1)
32 got = got.splitlines(1)
33 for line in difflib.unified_diff(expect, got,
34 fromfile=expect_path, tofile='got'):
35 sys.stderr.write(line)
36 if not line.endswith('\n'):
37 sys.stderr.write('[no-newline]\n')
38
39def verify_output(got, expect_file, update=False):
40 if os.path.isfile(expect_file):
Neels Hofmeyr3531a192017-03-28 14:30:28 +020041 ign_file = expect_file + '.ign'
42 if os.path.isfile(ign_file):
43 with open(ign_file, 'r') as f:
44 ign_rules = f.readlines()
45 for ign_rule in ign_rules:
46 if not ign_rule:
47 continue
48 if '\t' in ign_rule:
49 ign_rule, repl = ign_rule.split('\t')
50 repl = repl.strip()
51 else:
52 repl = '*'
53 ir = re.compile(ign_rule)
54 got = repl.join(ir.split(got))
55
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020056 if update:
57 with open(expect_file, 'w') as f:
58 f.write(got)
59 return True
60
61 with open(expect_file, 'r') as f:
62 expect = f.read()
Neels Hofmeyr3531a192017-03-28 14:30:28 +020063
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020064 if expect != got:
65 udiff(expect, got, expect_file)
66 sys.stderr.write('output mismatch: %r\n'
67 % os.path.basename(expect_file))
68 return False
69 return True
70
71
72script_dir = sys.path[0]
73
74tests = []
Pau Espin Pedrolab1904a2020-05-06 18:35:26 +020075for d in os.listdir(script_dir):
76 dir_path = os.path.join(script_dir, d)
77 if not os.path.isdir(dir_path):
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020078 continue
Pau Espin Pedrolab1904a2020-05-06 18:35:26 +020079 if not dir_path.endswith('_test'):
80 continue
81 for f in os.listdir(dir_path):
82 file_path = os.path.join(script_dir, d, f)
83 if not os.path.isfile(file_path):
84 continue
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020085
Pau Espin Pedrolab1904a2020-05-06 18:35:26 +020086 if not (file_path.endswith('_test.py') or file_path.endswith('_test.sh')):
87 continue
88 tests.append(file_path)
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +020089
90ran = []
91errors = []
92
93for test in sorted(tests):
94
95 if args.testdir_or_test:
96 if not any([t in test for t in args.testdir_or_test]):
97 continue
98
99 ran.append(test)
100
101 success = True
102
103 name, ext = os.path.splitext(test)
104 ok_file = name + '.ok'
105 err_file = name + '.err'
106
107 rc, out, err = run_test(test)
108
109 if rc != 0:
110 sys.stderr.write('%r: returned %d\n' % (os.path.basename(test), rc))
111 success = False
112
113 if not verify_output(out, ok_file, args.update):
114 success = False
115 if not verify_output(err, err_file, args.update):
116 success = False
117
118 if not success:
Neels Hofmeyr3531a192017-03-28 14:30:28 +0200119 sys.stderr.write('\nTest failed: %r\n\n' % os.path.basename(test))
Neels Hofmeyrdae3d3c2017-03-28 12:16:58 +0200120 errors.append(test)
121
122if errors:
123 print('%d of %d TESTS FAILED:\n %s' % (len(errors), len(ran), '\n '.join(errors)))
124 exit(1)
125
126print('%d tests ok' % len(ran))
127exit(0)
128
129# vim: expandtab tabstop=4 shiftwidth=4