-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathrun-tests.py
125 lines (98 loc) · 3.53 KB
/
run-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
"""
Copyright (c) 2019 Ash Wilding. All rights reserved.
SPDX-License-Identifier: MIT
This script attempts to compile every test source + header generated by the
run-build.py script.
Usage:
python3.8 run-tests.py [--keep] COMPILER_PATH [COMPILER_FLAGS]
Where the optional `--keep` flag prevents the script from cleaning up the
generated .o object files.
Example:
python3.8 run-tests.py aarch64-none-elf-gcc
python3.8 run-tests.py --keep clang -std=c99 -O3
"""
import os
import shutil
import sys
import subprocess
def abort( msg:object, errno:int=1 ) -> None:
print(msg)
sys.exit(1)
if __name__ == "__main__":
USAGE = (f"usage: python3.8 {sys.argv[0]} [--keep] COMPILER_PATH [COMPILER_FLAGS]\n\n"
f"example: python3.8 {sys.argv[0]} aarch64-none-elf-gcc\n"
f"example: python3.8 {sys.argv[0]} --keep clang -std=c99 -O3")
if len(sys.argv) < 2:
abort(USAGE)
if len(sys.argv) == 2 and sys.argv[1] == "--keep":
abort(USAGE)
print("========== test setup ==========")
keep_objs = False
argv_compiler = 1
argv_flags = 2
if sys.argv[1] == "--keep":
keep_objs = True
argv_compiler = 2
argv_flags = 3
compiler = sys.argv[argv_compiler]
try:
os.chdir("test")
except FileNotFoundError:
abort("failed to cd into 'test/' directory; have you built the library?")
def cleanup_test_dir_and_return_list_of_sources() -> str:
files = []
try:
for (_, _, f) in os.walk("."):
files.extend(f)
break
sources = sorted(list(filter(lambda s: s.endswith(".c"), files)))
others = list(filter(lambda s: not s.endswith(".c"), files))
if others:
for o in others:
(shutil.rmtree if os.path.isdir(o) else os.remove)(o)
except OSError as e:
abort(e, e.errno if hasattr(e, "errno") else 1)
return sources
base_command = [
compiler,
"-g",
"-c",
"-I../include",
"-Wall",
"-Wextra",
"-pedantic",
"-Werror",
]
if len(sys.argv) > argv_flags:
base_command += sys.argv[argv_flags:]
base_command_str = " ".join(base_command)
if not "-O" in base_command_str:
base_command.append("-O2")
if not "-std" in base_command_str:
base_command.append("-std=c11")
if "clang" in compiler:
if not "--target" in base_command_str:
base_command.append("--target=aarch64-none-elf")
ok = []
failures = []
print("========== test start ==========")
with open(os.devnull, "wb") as devnull:
for source in cleanup_test_dir_and_return_list_of_sources():
command = f"{' '.join(base_command)} {source}"
print(f"{command}")
with subprocess.Popen(command.split()) as p:
p.wait()
if 0 == p.returncode:
ok.append(source)
else:
failures.append(source)
print("\n\n")
if failures:
print("========== test failures ==========")
print("\n".join(failures))
print("========== test results ==========")
print(f"using compiler: {subprocess.check_output([compiler, '--version']).splitlines()[0].decode('UTF-8')}")
print(f"successfully built {len(ok)} sources out of {len(ok)+len(failures)} ({len(failures)} failures)")
if not keep_objs:
cleanup_test_dir_and_return_list_of_sources()
sys.exit(not not len(failures))