blob: e4eba8b27860591e6a09bc7f14d49503f531130a [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
Zachary Turnerff890da2015-10-19 23:45:41 +000018from __future__ import print_function
19
Johnny Chend0077902012-01-24 01:53:02 +000020import os, sys, datetime
Johnny Chen4a57d122011-07-29 22:54:56 +000021import re
22
23# If True, redo with no '-t' option for the test driver.
24no_trace = False
25
26# To be filled with the filterspecs found in the session logs.
27redo_specs = []
Johnny Chen4d9d9682011-08-16 20:56:10 +000028
Johnny Chenddb14902012-05-07 22:59:00 +000029# The filename components to match for. Only files with the contained component names
30# will be considered for re-run. Examples: ['X86_64', 'clang'].
31filename_components = []
32
Enrico Granata56768392013-04-23 20:05:05 +000033do_delay = False
34
Johnny Chen4d9d9682011-08-16 20:56:10 +000035# There is a known bug with respect to comp_specs and arch_specs, in that if we
36# encountered "-C clang" and "-C gcc" when visiting the session files, both
37# compilers will end up in the invocation of the test driver when rerunning.
38# That is: ./dotest -v -C clang^gcc ... -f ...". Ditto for "-A" flags.
Johnny Chenb7e62d02011-08-16 20:57:05 +000039
Johnny Chen4d9d9682011-08-16 20:56:10 +000040# The "-C compiler" for comp_specs.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000041comp_specs = set()
Johnny Chen4d9d9682011-08-16 20:56:10 +000042# The "-A arch" for arch_specs.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000043arch_specs = set()
Johnny Chen4a57d122011-07-29 22:54:56 +000044
45def usage():
Zachary Turnerff890da2015-10-19 23:45:41 +000046 print("""\
Enrico Granata56768392013-04-23 20:05:05 +000047Usage: redo.py [-F filename_component] [-n] [session_dir] [-d]
Johnny Chen4a57d122011-07-29 22:54:56 +000048where options:
Bruce Mitchener58ef3912015-06-18 05:27:05 +000049-F : only consider the test for re-run if the session filename contains the filename component
Johnny Chenddb14902012-05-07 22:59:00 +000050 for example: -F x86_64
Johnny Chen4a57d122011-07-29 22:54:56 +000051-n : when running the tests, do not turn on trace mode, i.e, no '-t' option
52 is passed to the test driver (this will run the tests faster)
Enrico Granata56768392013-04-23 20:05:05 +000053-d : pass -d down to the test driver (introduces a delay so you can attach with a debugger)
Johnny Chen4a57d122011-07-29 22:54:56 +000054
55and session_dir specifies the session directory which contains previously
Johnny Chend0077902012-01-24 01:53:02 +000056recorded session infos for all the test cases which either failed or errored.
57
58If sessin_dir is left unspecified, this script uses the heuristic to find the
59possible session directories with names starting with %Y-%m-%d- (for example,
Zachary Turnerff890da2015-10-19 23:45:41 +0000602012-01-23-) and employs the one with the latest timestamp.""")
Johnny Chen4a57d122011-07-29 22:54:56 +000061 sys.exit(0)
62
63def where(session_dir, test_dir):
64 """Returns the full path to the session directory; None if non-existent."""
65 abspath = os.path.abspath(session_dir)
66 if os.path.isdir(abspath):
67 return abspath
68
69 session_dir_path = os.path.join(test_dir, session_dir)
70 if os.path.isdir(session_dir_path):
71 return session_dir_path
72
73 return None
74
75# This is the pattern for the line from the log file to redo a test.
76# We want the filter spec.
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000077filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$")
78comp_pattern = re.compile(" -C ([^ ]+) ")
79arch_pattern = re.compile(" -A ([^ ]+) ")
Johnny Chen4a57d122011-07-29 22:54:56 +000080def redo(suffix, dir, names):
81 """Visitor function for os.path.walk(path, visit, arg)."""
82 global redo_specs
Johnny Chen9fd6bbb2011-08-16 20:02:59 +000083 global comp_specs
84 global arch_specs
85 global filter_pattern
86 global comp_pattern
87 global arch_pattern
Johnny Chenddb14902012-05-07 22:59:00 +000088 global filename_components
Enrico Granata56768392013-04-23 20:05:05 +000089 global do_delay
Johnny Chen4a57d122011-07-29 22:54:56 +000090
91 for name in names:
92 if name.endswith(suffix):
Zachary Turner35d017f2015-10-23 17:04:29 +000093 #print("Find a log file:", name)
Johnny Chen4a57d122011-07-29 22:54:56 +000094 if name.startswith("Error") or name.startswith("Failure"):
Johnny Chenddb14902012-05-07 22:59:00 +000095 if filename_components:
96 if not all([comp in name for comp in filename_components]):
97 continue
Johnny Chen4a57d122011-07-29 22:54:56 +000098 with open(os.path.join(dir, name), 'r') as log:
99 content = log.read()
100 for line in content.splitlines():
Johnny Chen9fd6bbb2011-08-16 20:02:59 +0000101 match = filter_pattern.match(line)
Johnny Chen4a57d122011-07-29 22:54:56 +0000102 if match:
103 filterspec = match.group(1)
Zachary Turnerff890da2015-10-19 23:45:41 +0000104 print("adding filterspec:", filterspec)
Johnny Chen4a57d122011-07-29 22:54:56 +0000105 redo_specs.append(filterspec)
Johnny Chen9fd6bbb2011-08-16 20:02:59 +0000106 comp = comp_pattern.search(line)
107 if comp:
108 comp_specs.add(comp.group(1))
109 arch = arch_pattern.search(line)
110 if arch:
111 arch_specs.add(arch.group(1))
Johnny Chen4a57d122011-07-29 22:54:56 +0000112 else:
113 continue
114
115def main():
116 """Read the session directory and run the failed test cases one by one."""
117 global no_trace
118 global redo_specs
Johnny Chenddb14902012-05-07 22:59:00 +0000119 global filename_components
Enrico Granata56768392013-04-23 20:05:05 +0000120 global do_delay
Johnny Chen4a57d122011-07-29 22:54:56 +0000121
Johnny Chend0077902012-01-24 01:53:02 +0000122 test_dir = sys.path[0]
Johnny Chenb8684b32012-05-16 19:43:14 +0000123 if not test_dir:
124 test_dir = os.getcwd()
Johnny Chend0077902012-01-24 01:53:02 +0000125 if not test_dir.endswith('test'):
Zachary Turnerff890da2015-10-19 23:45:41 +0000126 print("This script expects to reside in lldb's test directory.")
Johnny Chend0077902012-01-24 01:53:02 +0000127 sys.exit(-1)
128
Johnny Chen4a57d122011-07-29 22:54:56 +0000129 index = 1
130 while index < len(sys.argv):
Johnny Chen039330c2012-08-23 23:45:26 +0000131 if sys.argv[index].startswith('-h') or sys.argv[index].startswith('--help'):
Johnny Chen442b57c2011-11-30 19:46:37 +0000132 usage()
133
Johnny Chen4a57d122011-07-29 22:54:56 +0000134 if sys.argv[index].startswith('-'):
135 # We should continue processing...
136 pass
137 else:
138 # End of option processing.
139 break
140
Johnny Chena21bd402012-05-09 21:00:03 +0000141 if sys.argv[index] == '-F':
Johnny Chenddb14902012-05-07 22:59:00 +0000142 # Increment by 1 to fetch the filename component spec.
143 index += 1
144 if index >= len(sys.argv) or sys.argv[index].startswith('-'):
145 usage()
146 filename_components.append(sys.argv[index])
Johnny Chenddb14902012-05-07 22:59:00 +0000147 elif sys.argv[index] == '-n':
Johnny Chen4a57d122011-07-29 22:54:56 +0000148 no_trace = True
Enrico Granata56768392013-04-23 20:05:05 +0000149 elif sys.argv[index] == '-d':
150 do_delay = True
Filipe Cabecinhas3a9b6e72012-05-09 19:02:19 +0000151
152 index += 1
Johnny Chen4a57d122011-07-29 22:54:56 +0000153
Johnny Chend0077902012-01-24 01:53:02 +0000154 if index < len(sys.argv):
155 # Get the specified session directory.
156 session_dir = sys.argv[index]
157 else:
158 # Use heuristic to find the latest session directory.
159 name = datetime.datetime.now().strftime("%Y-%m-%d-")
160 dirs = [d for d in os.listdir(os.getcwd()) if d.startswith(name)]
Filipe Cabecinhas3a9b6e72012-05-09 19:02:19 +0000161 if len(dirs) == 0:
Zachary Turnerff890da2015-10-19 23:45:41 +0000162 print("No default session directory found, please specify it explicitly.")
Filipe Cabecinhas3a9b6e72012-05-09 19:02:19 +0000163 usage()
Johnny Chend0077902012-01-24 01:53:02 +0000164 session_dir = max(dirs, key=os.path.getmtime)
165 if not session_dir or not os.path.exists(session_dir):
Zachary Turnerff890da2015-10-19 23:45:41 +0000166 print("No default session directory found, please specify it explicitly.")
Johnny Chend0077902012-01-24 01:53:02 +0000167 usage()
Johnny Chen4a57d122011-07-29 22:54:56 +0000168
Zachary Turner35d017f2015-10-23 17:04:29 +0000169 #print("The test directory:", test_dir)
Johnny Chen4a57d122011-07-29 22:54:56 +0000170 session_dir_path = where(session_dir, test_dir)
171
Zachary Turnerff890da2015-10-19 23:45:41 +0000172 print("Using session dir path:", session_dir_path)
Johnny Chen4a57d122011-07-29 22:54:56 +0000173 os.chdir(test_dir)
174 os.path.walk(session_dir_path, redo, ".log")
175
Johnny Chend0077902012-01-24 01:53:02 +0000176 if not redo_specs:
Zachary Turnerff890da2015-10-19 23:45:41 +0000177 print("No failures/errors recorded within the session directory, please specify a different session directory.\n")
Johnny Chend0077902012-01-24 01:53:02 +0000178 usage()
179
Johnny Chen4a57d122011-07-29 22:54:56 +0000180 filters = " -f ".join(redo_specs)
Greg Clayton85c2a722012-10-09 16:54:55 +0000181 compilers = ''
182 for comp in comp_specs:
183 compilers += " -C %s" % (comp)
184 archs = ''
185 for arch in arch_specs:
186 archs += "--arch %s " % (arch)
Johnny Chen9fd6bbb2011-08-16 20:02:59 +0000187
Enrico Granata56768392013-04-23 20:05:05 +0000188 command = "./dotest.py %s %s -v %s %s -f " % (compilers, archs, "" if no_trace else "-t", "-d" if do_delay else "")
Johnny Chen9fd6bbb2011-08-16 20:02:59 +0000189
Johnny Chen4a57d122011-07-29 22:54:56 +0000190
Zachary Turnerff890da2015-10-19 23:45:41 +0000191 print("Running %s" % (command + filters))
Johnny Chen4a57d122011-07-29 22:54:56 +0000192 os.system(command + filters)
193
194if __name__ == '__main__':
195 main()