-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrun_tests_with_qemu.py
118 lines (100 loc) · 4.58 KB
/
run_tests_with_qemu.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
import os
import sys
import pathlib
import subprocess
from tqdm import tqdm
def enumerate_tests():
repo_path = pathlib.Path(__file__).parent.resolve()
all_tests_path = os.path.join(repo_path, 'examples/tests')
tests = []
for category in os.listdir(all_tests_path):
category_path = os.path.join(all_tests_path, category)
for subcategory in os.listdir(category_path):
subcategory_path = os.path.join(category_path, subcategory)
test_files = os.listdir(subcategory_path)
rust_files = [file for file in test_files if file.endswith('.rs')]
answer_files = [file for file in test_files if file.endswith('.py') or file.endswith('.txt')]
# Check that each test case is accompanied by a txt file or a python file
# as the groundtruth output answer.
for file_rs_ext in rust_files:
file_no_ext = os.path.basename(file_rs_ext)[:-3]
file_txt_ext = file_no_ext + '.txt'
file_py_ext = file_no_ext + '.py'
if file_txt_ext in answer_files:
tests.append((
(category, subcategory, file_no_ext),
os.path.join(subcategory_path, file_txt_ext)
))
elif file_py_ext in answer_files:
tests.append((
(category, subcategory, file_no_ext),
os.path.join(subcategory_path, file_py_ext)
))
else:
print(
f'Error: Test file {category}-{subcategory}-{file_rs_ext} does not have an answer file.',
file=sys.stderr
)
sys.exit(1)
return tests
def main():
# Get all test cases under ./examples/tests/
tests = enumerate_tests()
for (category, subcategory, file_no_ext), answer in tqdm(tests):
# Build the test case with `cargo build --example`
run_result = subprocess.run([
'cargo', 'build', '--release',
'--features', 'stm32f405',
'--features', 'qemu',
'--example', f'test-{category}-{subcategory}-{file_no_ext}'
], capture_output=True)
# Error handling for build error.
if run_result.returncode != 0:
print(
f'Error: Test case {category}-{subcategory}-{file_no_ext} failed to build.',
file=sys.stderr
)
print('Output from stdout:', file=sys.stderr)
print(str(run_result.stdout, encoding='utf-8'))
print('Output from stderr:', file=sys.stderr)
print(str(run_result.stderr, encoding='utf-8'))
exit(1)
# Run the test case with `cargo run --example`
run_result = subprocess.run([
'cargo', 'run', '--release',
'--features', 'stm32f405',
'--features', 'qemu',
'--example', f'test-{category}-{subcategory}-{file_no_ext}'
], capture_output=True)
# If the test execution returns an error, report the error.
if run_result.returncode != 0:
print(
f'Error: Test case {category}-{subcategory}-{file_no_ext} failed through execution.',
file=sys.stderr
)
print('Output from stdout:', file=sys.stderr)
print(str(run_result.stdout, encoding='utf-8'))
print('Output from stderr:', file=sys.stderr)
print(str(run_result.stderr, encoding='utf-8'))
exit(1)
# If the groundtruth is provided by a .txt file, compare the output against it.
if answer.endswith('.txt'):
with open(answer, 'rb') as f:
answer = f.read()
if answer != run_result.stdout:
print(
f'Error: Test case {category}-{subcategory}-{file_no_ext} failed to provide correct output.\nExpeted:\n{answer}\nGot:\n{run_result.stdout}',
file=sys.stderr
)
sys.exit(1)
# If the output is to be examined by a python script, run the script.
elif answer.endswith('.py'):
decision = subprocess.run(['python', answer], input=run_result.stdout, capture_output=True).stdout
if decision != 'Test Passed\n'.encode('utf-8'):
print(
f'Error: Test case {category}-{subcategory}-{file_no_ext} failed.\nGot:\n{run_result.stdout}',
file=sys.stderr
)
sys.exit(1)
if __name__ == '__main__':
main()