-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathintegration_tests.py
82 lines (67 loc) · 2.24 KB
/
integration_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
'''
This file runs all of the integration tests in the directory `integration_tests`
'''
import os
import re
import subprocess
ROOT = 'integration_tests'
OUTPUT = '.output.c'
def get_expected(file_name):
'''
Return the expected output for a given file.
'''
expected = []
with open(file_name) as fp:
for line in fp:
match = re.search(r'--.*OUT\((.*)\)', line)
if match:
expected.append(match.group(1))
return '\n'.join(expected)
def gen_executable(file_name):
'''
Generate an executable for a given file
'''
out = subprocess.check_output(f"cabal run haskell-in-haskell -- compile {file_name} .output.c", shell=True).decode('utf-8')
if 'Error' in out:
raise Exception('\n'.join(out.split('\n')[1:]))
subprocess.run("gcc -std=c99 -fsanitize=address -fsanitize=undefined .output.c", shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def get_output(file_name):
'''
Get the output for a given file
'''
gen_executable(file_name)
return subprocess.check_output("./a.out", shell=True).decode('utf-8')
def file_names():
'''
Yield all of the file names we need to run an integration test on
'''
for file_name in os.listdir(ROOT):
if file_name.endswith('.hs'):
yield os.path.join(ROOT, file_name)
def main():
'''
The main function for our script.
This will find all of the integration tests to run, and then
run them in order, checking that their expected output matches
what gets printed.
'''
for name in sorted(list(file_names())):
expected = get_expected(name).strip()
try:
actual = get_output(name).strip()
except BaseException as err:
print(f'{name}: FAIL')
print('Exception:')
print(err)
continue
if expected == actual:
print(f'\033[1m{name}\033[0m:\t\033[1m\033[32mPASS\033[0m')
else:
print(f'\033[1m{name}\033[0m:\t\033[1m\033[31mFAIL\033[0m')
print('Expected:\033[1m')
print(expected)
print('\033[0m\nBut Found:\033[1m')
print(actual)
print('\033[0m')
if __name__ == '__main__':
main()