blob: 4c405abab2eaf7038a20f4013a08f3b9c9eff1a3 [file] [log] [blame]
Johnny Chen4a57d122011-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
Johnny Chend0077902012-01-24 01:53:02 +000018import os, sys, datetime
Johnny Chen4a57d122011-07-29 22:54:56 +000019import 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 Chen4d9d9682011-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 Chenb7e62d02011-08-16 20:57:05 +000031
Johnny Chen4d9d9682011-08-16 20:56:10 +000032# The "-C compiler" for comp_specs.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000033comp_specs = set()
Johnny Chen4d9d9682011-08-16 20:56:10 +000034# The "-A arch" for arch_specs.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000035arch_specs = set()
Johnny Chen4a57d122011-07-29 22:54:56 +000036
37def usage():
38 print"""\
Johnny Chend0077902012-01-24 01:53:02 +000039Usage: redo.py [-n] [session_dir]
Johnny Chen4a57d122011-07-29 22:54:56 +000040where 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
Johnny Chend0077902012-01-24 01:53:02 +000045recorded session infos for all the test cases which either failed or errored.
46
47If sessin_dir is left unspecified, this script uses the heuristic to find the
48possible session directories with names starting with %Y-%m-%d- (for example,
492012-01-23-) and employs the one with the latest timestamp."""
Johnny Chen4a57d122011-07-29 22:54:56 +000050 sys.exit(0)
51
52def where(session_dir, test_dir):
53 """Returns the full path to the session directory; None if non-existent."""
54 abspath = os.path.abspath(session_dir)
55 if os.path.isdir(abspath):
56 return abspath
57
58 session_dir_path = os.path.join(test_dir, session_dir)
59 if os.path.isdir(session_dir_path):
60 return session_dir_path
61
62 return None
63
64# This is the pattern for the line from the log file to redo a test.
65# We want the filter spec.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000066filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$")
67comp_pattern = re.compile(" -C ([^ ]+) ")
68arch_pattern = re.compile(" -A ([^ ]+) ")
Johnny Chen4a57d122011-07-29 22:54:56 +000069def redo(suffix, dir, names):
70 """Visitor function for os.path.walk(path, visit, arg)."""
71 global redo_specs
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000072 global comp_specs
73 global arch_specs
74 global filter_pattern
75 global comp_pattern
76 global arch_pattern
Johnny Chen4a57d122011-07-29 22:54:56 +000077
78 for name in names:
79 if name.endswith(suffix):
80 #print "Find a log file:", name
81 if name.startswith("Error") or name.startswith("Failure"):
82 with open(os.path.join(dir, name), 'r') as log:
83 content = log.read()
84 for line in content.splitlines():
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000085 match = filter_pattern.match(line)
Johnny Chen4a57d122011-07-29 22:54:56 +000086 if match:
87 filterspec = match.group(1)
88 print "adding filterspec:", filterspec
89 redo_specs.append(filterspec)
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000090 comp = comp_pattern.search(line)
91 if comp:
92 comp_specs.add(comp.group(1))
93 arch = arch_pattern.search(line)
94 if arch:
95 arch_specs.add(arch.group(1))
Johnny Chen4a57d122011-07-29 22:54:56 +000096 else:
97 continue
98
99def main():
100 """Read the session directory and run the failed test cases one by one."""
101 global no_trace
102 global redo_specs
103
Johnny Chend0077902012-01-24 01:53:02 +0000104 test_dir = sys.path[0]
105 if not test_dir.endswith('test'):
106 print "This script expects to reside in lldb's test directory."
107 sys.exit(-1)
108
109 if len(sys.argv) > 3:
Johnny Chen4a57d122011-07-29 22:54:56 +0000110 usage()
111
112 index = 1
113 while index < len(sys.argv):
Johnny Chen442b57c2011-11-30 19:46:37 +0000114 if sys.argv[index].startswith('-h'):
115 usage()
116
Johnny Chen4a57d122011-07-29 22:54:56 +0000117 if sys.argv[index].startswith('-'):
118 # We should continue processing...
119 pass
120 else:
121 # End of option processing.
122 break
123
124 if sys.argv[index] == '-n':
125 no_trace = True
126 index += 1
127
Johnny Chend0077902012-01-24 01:53:02 +0000128 if index < len(sys.argv):
129 # Get the specified session directory.
130 session_dir = sys.argv[index]
131 else:
132 # Use heuristic to find the latest session directory.
133 name = datetime.datetime.now().strftime("%Y-%m-%d-")
134 dirs = [d for d in os.listdir(os.getcwd()) if d.startswith(name)]
135 session_dir = max(dirs, key=os.path.getmtime)
136 if not session_dir or not os.path.exists(session_dir):
137 print "No default session directory found, please specify it explicitly."
138 usage()
Johnny Chen4a57d122011-07-29 22:54:56 +0000139
140 #print "The test directory:", test_dir
141 session_dir_path = where(session_dir, test_dir)
142
Johnny Chend0077902012-01-24 01:53:02 +0000143 print "Using session dir path:", session_dir_path
Johnny Chen4a57d122011-07-29 22:54:56 +0000144 os.chdir(test_dir)
145 os.path.walk(session_dir_path, redo, ".log")
146
Johnny Chend0077902012-01-24 01:53:02 +0000147 if not redo_specs:
148 print "No failures/errors recorded within the session directory, please specify a different session directory."
149 usage()
150
Johnny Chen4a57d122011-07-29 22:54:56 +0000151 filters = " -f ".join(redo_specs)
Johnny Chen9fd6bbb2011-08-16 20:02:59 +0000152 compilers = (" -C %s" % "^".join(comp_specs)) if comp_specs else None
153 archs = (" -A %s" % "^".join(arch_specs)) if arch_specs else None
154
155 command = "./dotest.py %s %s -v %s -f " % (compilers if compilers else "",
156 archs if archs else "",
157 "" if no_trace else "-t")
158
Johnny Chen4a57d122011-07-29 22:54:56 +0000159
160 print "Running %s" % (command + filters)
161 os.system(command + filters)
162
163if __name__ == '__main__':
164 main()