blob: ac42b2b69b862ce7a24fa632b6e4c1c46987e617 [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
Johnny Chen4fda4672012-01-24 01:53:02 +000018import os, sys, datetime
Johnny Chenc5fa0052011-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 Chen9e643db2011-08-16 20:56:10 +000026
Johnny Chencf0bc6d2012-05-07 22:59:00 +000027# The filename components to match for. Only files with the contained component names
28# will be considered for re-run. Examples: ['X86_64', 'clang'].
29filename_components = []
30
Enrico Granata66cd2b52013-04-23 20:05:05 +000031do_delay = False
32
Johnny Chen9e643db2011-08-16 20:56:10 +000033# There is a known bug with respect to comp_specs and arch_specs, in that if we
34# encountered "-C clang" and "-C gcc" when visiting the session files, both
35# compilers will end up in the invocation of the test driver when rerunning.
36# That is: ./dotest -v -C clang^gcc ... -f ...". Ditto for "-A" flags.
Johnny Chene90a10e2011-08-16 20:57:05 +000037
Johnny Chen9e643db2011-08-16 20:56:10 +000038# The "-C compiler" for comp_specs.
Johnny Chen13fb6572011-08-16 20:02:59 +000039comp_specs = set()
Johnny Chen9e643db2011-08-16 20:56:10 +000040# The "-A arch" for arch_specs.
Johnny Chen13fb6572011-08-16 20:02:59 +000041arch_specs = set()
Johnny Chenc5fa0052011-07-29 22:54:56 +000042
43def usage():
44 print"""\
Enrico Granata66cd2b52013-04-23 20:05:05 +000045Usage: redo.py [-F filename_component] [-n] [session_dir] [-d]
Johnny Chenc5fa0052011-07-29 22:54:56 +000046where options:
Johnny Chencf0bc6d2012-05-07 22:59:00 +000047-F : only consider the test for re-run if the session filename conatins the filename component
48 for example: -F x86_64
Johnny Chenc5fa0052011-07-29 22:54:56 +000049-n : when running the tests, do not turn on trace mode, i.e, no '-t' option
50 is passed to the test driver (this will run the tests faster)
Enrico Granata66cd2b52013-04-23 20:05:05 +000051-d : pass -d down to the test driver (introduces a delay so you can attach with a debugger)
Johnny Chenc5fa0052011-07-29 22:54:56 +000052
53and session_dir specifies the session directory which contains previously
Johnny Chen4fda4672012-01-24 01:53:02 +000054recorded session infos for all the test cases which either failed or errored.
55
56If sessin_dir is left unspecified, this script uses the heuristic to find the
57possible session directories with names starting with %Y-%m-%d- (for example,
582012-01-23-) and employs the one with the latest timestamp."""
Johnny Chenc5fa0052011-07-29 22:54:56 +000059 sys.exit(0)
60
61def where(session_dir, test_dir):
62 """Returns the full path to the session directory; None if non-existent."""
63 abspath = os.path.abspath(session_dir)
64 if os.path.isdir(abspath):
65 return abspath
66
67 session_dir_path = os.path.join(test_dir, session_dir)
68 if os.path.isdir(session_dir_path):
69 return session_dir_path
70
71 return None
72
73# This is the pattern for the line from the log file to redo a test.
74# We want the filter spec.
Johnny Chen13fb6572011-08-16 20:02:59 +000075filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$")
76comp_pattern = re.compile(" -C ([^ ]+) ")
77arch_pattern = re.compile(" -A ([^ ]+) ")
Johnny Chenc5fa0052011-07-29 22:54:56 +000078def redo(suffix, dir, names):
79 """Visitor function for os.path.walk(path, visit, arg)."""
80 global redo_specs
Johnny Chen13fb6572011-08-16 20:02:59 +000081 global comp_specs
82 global arch_specs
83 global filter_pattern
84 global comp_pattern
85 global arch_pattern
Johnny Chencf0bc6d2012-05-07 22:59:00 +000086 global filename_components
Enrico Granata66cd2b52013-04-23 20:05:05 +000087 global do_delay
Johnny Chenc5fa0052011-07-29 22:54:56 +000088
89 for name in names:
90 if name.endswith(suffix):
91 #print "Find a log file:", name
92 if name.startswith("Error") or name.startswith("Failure"):
Johnny Chencf0bc6d2012-05-07 22:59:00 +000093 if filename_components:
94 if not all([comp in name for comp in filename_components]):
95 continue
Johnny Chenc5fa0052011-07-29 22:54:56 +000096 with open(os.path.join(dir, name), 'r') as log:
97 content = log.read()
98 for line in content.splitlines():
Johnny Chen13fb6572011-08-16 20:02:59 +000099 match = filter_pattern.match(line)
Johnny Chenc5fa0052011-07-29 22:54:56 +0000100 if match:
101 filterspec = match.group(1)
102 print "adding filterspec:", filterspec
103 redo_specs.append(filterspec)
Johnny Chen13fb6572011-08-16 20:02:59 +0000104 comp = comp_pattern.search(line)
105 if comp:
106 comp_specs.add(comp.group(1))
107 arch = arch_pattern.search(line)
108 if arch:
109 arch_specs.add(arch.group(1))
Johnny Chenc5fa0052011-07-29 22:54:56 +0000110 else:
111 continue
112
113def main():
114 """Read the session directory and run the failed test cases one by one."""
115 global no_trace
116 global redo_specs
Johnny Chencf0bc6d2012-05-07 22:59:00 +0000117 global filename_components
Enrico Granata66cd2b52013-04-23 20:05:05 +0000118 global do_delay
Johnny Chenc5fa0052011-07-29 22:54:56 +0000119
Johnny Chen4fda4672012-01-24 01:53:02 +0000120 test_dir = sys.path[0]
Johnny Chen47dcd1e2012-05-16 19:43:14 +0000121 if not test_dir:
122 test_dir = os.getcwd()
Johnny Chen4fda4672012-01-24 01:53:02 +0000123 if not test_dir.endswith('test'):
124 print "This script expects to reside in lldb's test directory."
125 sys.exit(-1)
126
Johnny Chenc5fa0052011-07-29 22:54:56 +0000127 index = 1
128 while index < len(sys.argv):
Johnny Chen11595f52012-08-23 23:45:26 +0000129 if sys.argv[index].startswith('-h') or sys.argv[index].startswith('--help'):
Johnny Chen02dfe4a2011-11-30 19:46:37 +0000130 usage()
131
Johnny Chenc5fa0052011-07-29 22:54:56 +0000132 if sys.argv[index].startswith('-'):
133 # We should continue processing...
134 pass
135 else:
136 # End of option processing.
137 break
138
Johnny Chen6884bdd2012-05-09 21:00:03 +0000139 if sys.argv[index] == '-F':
Johnny Chencf0bc6d2012-05-07 22:59:00 +0000140 # Increment by 1 to fetch the filename component spec.
141 index += 1
142 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
143 usage()
144 filename_components.append(sys.argv[index])
Johnny Chencf0bc6d2012-05-07 22:59:00 +0000145 elif sys.argv[index] == '-n':
Johnny Chenc5fa0052011-07-29 22:54:56 +0000146 no_trace = True
Enrico Granata66cd2b52013-04-23 20:05:05 +0000147 elif sys.argv[index] == '-d':
148 do_delay = True
Filipe Cabecinhas1b8de0a2012-05-09 19:02:19 +0000149
150 index += 1
Johnny Chenc5fa0052011-07-29 22:54:56 +0000151
Johnny Chen4fda4672012-01-24 01:53:02 +0000152 if index < len(sys.argv):
153 # Get the specified session directory.
154 session_dir = sys.argv[index]
155 else:
156 # Use heuristic to find the latest session directory.
157 name = datetime.datetime.now().strftime("%Y-%m-%d-")
158 dirs = [d for d in os.listdir(os.getcwd()) if d.startswith(name)]
Filipe Cabecinhas1b8de0a2012-05-09 19:02:19 +0000159 if len(dirs) == 0:
160 print "No default session directory found, please specify it explicitly."
161 usage()
Johnny Chen4fda4672012-01-24 01:53:02 +0000162 session_dir = max(dirs, key=os.path.getmtime)
163 if not session_dir or not os.path.exists(session_dir):
164 print "No default session directory found, please specify it explicitly."
165 usage()
Johnny Chenc5fa0052011-07-29 22:54:56 +0000166
167 #print "The test directory:", test_dir
168 session_dir_path = where(session_dir, test_dir)
169
Johnny Chen4fda4672012-01-24 01:53:02 +0000170 print "Using session dir path:", session_dir_path
Johnny Chenc5fa0052011-07-29 22:54:56 +0000171 os.chdir(test_dir)
172 os.path.walk(session_dir_path, redo, ".log")
173
Johnny Chen4fda4672012-01-24 01:53:02 +0000174 if not redo_specs:
Johnny Chen8aa684d2012-05-16 18:32:05 +0000175 print "No failures/errors recorded within the session directory, please specify a different session directory.\n"
Johnny Chen4fda4672012-01-24 01:53:02 +0000176 usage()
177
Johnny Chenc5fa0052011-07-29 22:54:56 +0000178 filters = " -f ".join(redo_specs)
Greg Clayton8b409152012-10-09 16:54:55 +0000179 compilers = ''
180 for comp in comp_specs:
181 compilers += " -C %s" % (comp)
182 archs = ''
183 for arch in arch_specs:
184 archs += "--arch %s " % (arch)
Johnny Chen13fb6572011-08-16 20:02:59 +0000185
Enrico Granata66cd2b52013-04-23 20:05:05 +0000186 command = "./dotest.py %s %s -v %s %s -f " % (compilers, archs, "" if no_trace else "-t", "-d" if do_delay else "")
Johnny Chen13fb6572011-08-16 20:02:59 +0000187
Johnny Chenc5fa0052011-07-29 22:54:56 +0000188
189 print "Running %s" % (command + filters)
190 os.system(command + filters)
191
192if __name__ == '__main__':
193 main()