4 A simple utility to redo the failed/errored tests.
6 You need to specify the session directory in order for this script to locate the
7 tests which need to be re-run.
9 See also dotest.py, the test driver running the test suite.
18 from __future__
import print_function
25 # If True, redo with no '-t' option for the test driver.
28 # To be filled with the filterspecs found in the session logs.
31 # The filename components to match for. Only files with the contained component names
32 # will be considered for re-run. Examples: ['X86_64', 'clang'].
33 filename_components
= []
37 # There is a known bug with respect to comp_specs and arch_specs, in that if we
38 # encountered "-C clang" and "-C gcc" when visiting the session files, both
39 # compilers will end up in the invocation of the test driver when rerunning.
40 # That is: ./dotest -v -C clang^gcc ... -f ...". Ditto for "-A" flags.
42 # The "-C compiler" for comp_specs.
44 # The "-A arch" for arch_specs.
50 Usage: redo.py [-F filename_component] [-n] [session_dir] [-d]
52 -F : only consider the test for re-run if the session filename contains the filename component
53 for example: -F x86_64
54 -n : when running the tests, do not turn on trace mode, i.e, no '-t' option
55 is passed to the test driver (this will run the tests faster)
56 -d : pass -d down to the test driver (introduces a delay so you can attach with a debugger)
58 and session_dir specifies the session directory which contains previously
59 recorded session infos for all the test cases which either failed or errored.
61 If sessin_dir is left unspecified, this script uses the heuristic to find the
62 possible session directories with names starting with %Y-%m-%d- (for example,
63 2012-01-23-) and employs the one with the latest timestamp.""")
67 def where(session_dir
, test_dir
):
68 """Returns the full path to the session directory; None if non-existent."""
69 abspath
= os
.path
.abspath(session_dir
)
70 if os
.path
.isdir(abspath
):
73 session_dir_path
= os
.path
.join(test_dir
, session_dir
)
74 if os
.path
.isdir(session_dir_path
):
75 return session_dir_path
79 # This is the pattern for the line from the log file to redo a test.
80 # We want the filter spec.
81 filter_pattern
= re
.compile("^\./dotest\.py.*-f (.*)$")
82 comp_pattern
= re
.compile(" -C ([^ ]+) ")
83 arch_pattern
= re
.compile(" -A ([^ ]+) ")
86 def redo(suffix
, dir, names
):
87 """Visitor function for os.path.walk(path, visit, arg)."""
94 global filename_components
98 if name
.endswith(suffix
):
99 #print("Find a log file:", name)
100 if name
.startswith("Error") or name
.startswith("Failure"):
101 if filename_components
:
102 if not all([comp
in name
for comp
in filename_components
]):
104 with
open(os
.path
.join(dir, name
), 'r') as log
:
106 for line
in content
.splitlines():
107 match
= filter_pattern
.match(line
)
109 filterspec
= match
.group(1)
110 print("adding filterspec:", filterspec
)
111 redo_specs
.append(filterspec
)
112 comp
= comp_pattern
.search(line
)
114 comp_specs
.add(comp
.group(1))
115 arch
= arch_pattern
.search(line
)
117 arch_specs
.add(arch
.group(1))
123 """Read the session directory and run the failed test cases one by one."""
126 global filename_components
129 test_dir
= sys
.path
[0]
131 test_dir
= os
.getcwd()
132 if not test_dir
.endswith('test'):
133 print("This script expects to reside in lldb's test directory.")
137 while index
< len(sys
.argv
):
138 if sys
.argv
[index
].startswith(
139 '-h') or sys
.argv
[index
].startswith('--help'):
142 if sys
.argv
[index
].startswith('-'):
143 # We should continue processing...
146 # End of option processing.
149 if sys
.argv
[index
] == '-F':
150 # Increment by 1 to fetch the filename component spec.
152 if index
>= len(sys
.argv
) or sys
.argv
[index
].startswith('-'):
154 filename_components
.append(sys
.argv
[index
])
155 elif sys
.argv
[index
] == '-n':
157 elif sys
.argv
[index
] == '-d':
162 if index
< len(sys
.argv
):
163 # Get the specified session directory.
164 session_dir
= sys
.argv
[index
]
166 # Use heuristic to find the latest session directory.
167 name
= datetime
.datetime
.now().strftime("%Y-%m-%d-")
168 dirs
= [d
for d
in os
.listdir(os
.getcwd()) if d
.startswith(name
)]
170 print("No default session directory found, please specify it explicitly.")
172 session_dir
= max(dirs
, key
=os
.path
.getmtime
)
173 if not session_dir
or not os
.path
.exists(session_dir
):
174 print("No default session directory found, please specify it explicitly.")
177 #print("The test directory:", test_dir)
178 session_dir_path
= where(session_dir
, test_dir
)
180 print("Using session dir path:", session_dir_path
)
182 os
.path
.walk(session_dir_path
, redo
, ".log")
185 print("No failures/errors recorded within the session directory, please specify a different session directory.\n")
188 filters
= " -f ".join(redo_specs
)
190 for comp
in comp_specs
:
191 compilers
+= " -C %s" % (comp
)
193 for arch
in arch_specs
:
194 archs
+= "--arch %s " % (arch
)
196 command
= "./dotest.py %s %s -v %s %s -f " % (
197 compilers
, archs
, "" if no_trace
else "-t", "-d" if do_delay
else "")
199 print("Running %s" % (command
+ filters
))
200 os
.system(command
+ filters
)
202 if __name__
== '__main__':