blob: c2ed5d390b3a5496e25606436bd81be92518e497 [file] [log] [blame]
Johnny Chenc5fa0052011-07-29 22:54:56 +00001#!/usr/bin/env python
2
3"""
4A simple utility to redo the failed/errored tests.
5
6You need to specify the session directory in order for this script to locate the
7tests which need to be re-run.
8
9See also dotest.py, the test driver running the test suite.
10
11Type:
12
13./dotest.py -h
14
15for help.
16"""
17
18import os, sys
19import re
20
21# If True, redo with no '-t' option for the test driver.
22no_trace = False
23
24# To be filled with the filterspecs found in the session logs.
25redo_specs = []
Johnny Chen9e643db2011-08-16 20:56:10 +000026
27# There is a known bug with respect to comp_specs and arch_specs, in that if we
28# encountered "-C clang" and "-C gcc" when visiting the session files, both
29# compilers will end up in the invocation of the test driver when rerunning.
30# That is: ./dotest -v -C clang^gcc ... -f ...". Ditto for "-A" flags.
Johnny Chene90a10e2011-08-16 20:57:05 +000031
Johnny Chen9e643db2011-08-16 20:56:10 +000032# The "-C compiler" for comp_specs.
Johnny Chen13fb6572011-08-16 20:02:59 +000033comp_specs = set()
Johnny Chen9e643db2011-08-16 20:56:10 +000034# The "-A arch" for arch_specs.
Johnny Chen13fb6572011-08-16 20:02:59 +000035arch_specs = set()
Johnny Chenc5fa0052011-07-29 22:54:56 +000036
37def usage():
38 print"""\
39Usage: redo.py [-n] session_dir
40where options:
41-n : when running the tests, do not turn on trace mode, i.e, no '-t' option
42 is passed to the test driver (this will run the tests faster)
43
44and session_dir specifies the session directory which contains previously
45recorded session infos for all the test cases which either failed or errored."""
46 sys.exit(0)
47
48def where(session_dir, test_dir):
49 """Returns the full path to the session directory; None if non-existent."""
50 abspath = os.path.abspath(session_dir)
51 if os.path.isdir(abspath):
52 return abspath
53
54 session_dir_path = os.path.join(test_dir, session_dir)
55 if os.path.isdir(session_dir_path):
56 return session_dir_path
57
58 return None
59
60# This is the pattern for the line from the log file to redo a test.
61# We want the filter spec.
Johnny Chen13fb6572011-08-16 20:02:59 +000062filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$")
63comp_pattern = re.compile(" -C ([^ ]+) ")
64arch_pattern = re.compile(" -A ([^ ]+) ")
Johnny Chenc5fa0052011-07-29 22:54:56 +000065def redo(suffix, dir, names):
66 """Visitor function for os.path.walk(path, visit, arg)."""
67 global redo_specs
Johnny Chen13fb6572011-08-16 20:02:59 +000068 global comp_specs
69 global arch_specs
70 global filter_pattern
71 global comp_pattern
72 global arch_pattern
Johnny Chenc5fa0052011-07-29 22:54:56 +000073
74 for name in names:
75 if name.endswith(suffix):
76 #print "Find a log file:", name
77 if name.startswith("Error") or name.startswith("Failure"):
78 with open(os.path.join(dir, name), 'r') as log:
79 content = log.read()
80 for line in content.splitlines():
Johnny Chen13fb6572011-08-16 20:02:59 +000081 match = filter_pattern.match(line)
Johnny Chenc5fa0052011-07-29 22:54:56 +000082 if match:
83 filterspec = match.group(1)
84 print "adding filterspec:", filterspec
85 redo_specs.append(filterspec)
Johnny Chen13fb6572011-08-16 20:02:59 +000086 comp = comp_pattern.search(line)
87 if comp:
88 comp_specs.add(comp.group(1))
89 arch = arch_pattern.search(line)
90 if arch:
91 arch_specs.add(arch.group(1))
Johnny Chenc5fa0052011-07-29 22:54:56 +000092 else:
93 continue
94
95def main():
96 """Read the session directory and run the failed test cases one by one."""
97 global no_trace
98 global redo_specs
99
100 if len(sys.argv) < 2 or len(sys.argv) > 3:
101 usage()
102
103 index = 1
104 while index < len(sys.argv):
Johnny Chen02dfe4a2011-11-30 19:46:37 +0000105 if sys.argv[index].startswith('-h'):
106 usage()
107
Johnny Chenc5fa0052011-07-29 22:54:56 +0000108 if sys.argv[index].startswith('-'):
109 # We should continue processing...
110 pass
111 else:
112 # End of option processing.
113 break
114
115 if sys.argv[index] == '-n':
116 no_trace = True
117 index += 1
118
119 session_dir = sys.argv[index]
120
121 test_dir = sys.path[0]
122 if not test_dir.endswith('test'):
123 print "This script expects to reside in lldb's test directory."
124 sys.exit(-1)
125
126 #print "The test directory:", test_dir
127 session_dir_path = where(session_dir, test_dir)
128
129 #print "Session dir path:", session_dir_path
130 os.chdir(test_dir)
131 os.path.walk(session_dir_path, redo, ".log")
132
Johnny Chenc5fa0052011-07-29 22:54:56 +0000133 filters = " -f ".join(redo_specs)
Johnny Chen13fb6572011-08-16 20:02:59 +0000134 compilers = (" -C %s" % "^".join(comp_specs)) if comp_specs else None
135 archs = (" -A %s" % "^".join(arch_specs)) if arch_specs else None
136
137 command = "./dotest.py %s %s -v %s -f " % (compilers if compilers else "",
138 archs if archs else "",
139 "" if no_trace else "-t")
140
Johnny Chenc5fa0052011-07-29 22:54:56 +0000141
142 print "Running %s" % (command + filters)
143 os.system(command + filters)
144
145if __name__ == '__main__':
146 main()