-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathredo.py
executable file
·146 lines (114 loc) · 4.52 KB
/
redo.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env python
"""
A simple utility to redo the failed/errored tests.
You need to specify the session directory in order for this script to locate the
tests which need to be re-run.
See also dotest.py, the test driver running the test suite.
Type:
./dotest.py -h
for help.
"""
import os, sys
import re
# If True, redo with no '-t' option for the test driver.
no_trace = False
# To be filled with the filterspecs found in the session logs.
redo_specs = []
# There is a known bug with respect to comp_specs and arch_specs, in that if we
# encountered "-C clang" and "-C gcc" when visiting the session files, both
# compilers will end up in the invocation of the test driver when rerunning.
# That is: ./dotest -v -C clang^gcc ... -f ...". Ditto for "-A" flags.
# The "-C compiler" for comp_specs.
comp_specs = set()
# The "-A arch" for arch_specs.
arch_specs = set()
def usage():
print"""\
Usage: redo.py [-n] session_dir
where options:
-n : when running the tests, do not turn on trace mode, i.e, no '-t' option
is passed to the test driver (this will run the tests faster)
and session_dir specifies the session directory which contains previously
recorded session infos for all the test cases which either failed or errored."""
sys.exit(0)
def where(session_dir, test_dir):
"""Returns the full path to the session directory; None if non-existent."""
abspath = os.path.abspath(session_dir)
if os.path.isdir(abspath):
return abspath
session_dir_path = os.path.join(test_dir, session_dir)
if os.path.isdir(session_dir_path):
return session_dir_path
return None
# This is the pattern for the line from the log file to redo a test.
# We want the filter spec.
filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$")
comp_pattern = re.compile(" -C ([^ ]+) ")
arch_pattern = re.compile(" -A ([^ ]+) ")
def redo(suffix, dir, names):
"""Visitor function for os.path.walk(path, visit, arg)."""
global redo_specs
global comp_specs
global arch_specs
global filter_pattern
global comp_pattern
global arch_pattern
for name in names:
if name.endswith(suffix):
#print "Find a log file:", name
if name.startswith("Error") or name.startswith("Failure"):
with open(os.path.join(dir, name), 'r') as log:
content = log.read()
for line in content.splitlines():
match = filter_pattern.match(line)
if match:
filterspec = match.group(1)
print "adding filterspec:", filterspec
redo_specs.append(filterspec)
comp = comp_pattern.search(line)
if comp:
comp_specs.add(comp.group(1))
arch = arch_pattern.search(line)
if arch:
arch_specs.add(arch.group(1))
else:
continue
def main():
"""Read the session directory and run the failed test cases one by one."""
global no_trace
global redo_specs
if len(sys.argv) < 2 or len(sys.argv) > 3:
usage()
index = 1
while index < len(sys.argv):
if sys.argv[index].startswith('-h'):
usage()
if sys.argv[index].startswith('-'):
# We should continue processing...
pass
else:
# End of option processing.
break
if sys.argv[index] == '-n':
no_trace = True
index += 1
session_dir = sys.argv[index]
test_dir = sys.path[0]
if not test_dir.endswith('test'):
print "This script expects to reside in lldb's test directory."
sys.exit(-1)
#print "The test directory:", test_dir
session_dir_path = where(session_dir, test_dir)
#print "Session dir path:", session_dir_path
os.chdir(test_dir)
os.path.walk(session_dir_path, redo, ".log")
filters = " -f ".join(redo_specs)
compilers = (" -C %s" % "^".join(comp_specs)) if comp_specs else None
archs = (" -A %s" % "^".join(arch_specs)) if arch_specs else None
command = "./dotest.py %s %s -v %s -f " % (compilers if compilers else "",
archs if archs else "",
"" if no_trace else "-t")
print "Running %s" % (command + filters)
os.system(command + filters)
if __name__ == '__main__':
main()