diff options
| author | Johnny Chen <johnny.chen@apple.com> | 2011-07-29 22:54:56 +0000 |
|---|---|---|
| committer | Johnny Chen <johnny.chen@apple.com> | 2011-07-29 22:54:56 +0000 |
| commit | 4a57d122fe53ac07dabd73f52ced2eafa37794cc (patch) | |
| tree | 6b62ee152cc54ca3dcce6c4964cf391995048859 | |
| parent | 9760f04ef9a30509817a24a4b27cb48e537a1242 (diff) | |
| download | llvm-4a57d122fe53ac07dabd73f52ced2eafa37794cc.zip llvm-4a57d122fe53ac07dabd73f52ced2eafa37794cc.tar.gz llvm-4a57d122fe53ac07dabd73f52ced2eafa37794cc.tar.bz2 | |
Add a redo.py script which takes a session directory name as arg and digs into the directory
to find out the tests which failed/errored and need re-running. The dotest.py test driver
script is modified to allow specifying multiple -f testclass.testmethod in the command line
to accommodate the redo functionality.
An example,
$ ./redo.py -n 2011-07-29-11_50_14
adding filterspec: TargetAPITestCase.test_find_global_variables_with_dwarf
adding filterspec: DisasmAPITestCase.test_with_dsym
Running ./dotest.py -v -f TargetAPITestCase.test_find_global_variables_with_dwarf -f DisasmAPITestCase.test_with_dsym
...
----------------------------------------------------------------------
Collected 2 tests
1: test_with_dsym (TestDisasmAPI.DisasmAPITestCase)
Exercise getting SBAddress objects, disassembly, and SBAddress APIs. ... ok
2: test_find_global_variables_with_dwarf (TestTargetAPI.TargetAPITestCase)
Exercise SBTarget.FindGlobalVariables() API. ... ok
----------------------------------------------------------------------
Ran 2 tests in 15.328s
OK
llvm-svn: 136533
| -rwxr-xr-x | lldb/test/dotest.py | 27 | ||||
| -rwxr-xr-x | lldb/test/redo.py | 114 |
2 files changed, 131 insertions, 10 deletions
diff --git a/lldb/test/dotest.py b/lldb/test/dotest.py index c6261c9..68cca8c6 100755 --- a/lldb/test/dotest.py +++ b/lldb/test/dotest.py @@ -102,8 +102,8 @@ dumpSysPath = False # By default, failfast is False. Use '-F' to overwrite it. failfast = False -# The filter (testclass.testmethod) used to admit tests into our test suite. -filterspec = None +# The filters (testclass.testmethod) used to admit tests into our test suite. +filters = [] # If '-g' is specified, the filterspec is not exclusive. If a test module does # not contain testclass.testmethod which matches the filterspec, the whole test @@ -296,7 +296,7 @@ def parseOptionsAndInitTestdirs(): global delay global dumpSysPath global failfast - global filterspec + global filters global fs4all global ignore global skipLongRunningTest @@ -381,7 +381,7 @@ def parseOptionsAndInitTestdirs(): index += 1 if index >= len(sys.argv) or sys.argv[index].startswith('-'): usage() - filterspec = sys.argv[index] + filters.append(sys.argv[index]) index += 1 elif sys.argv[index].startswith('-g'): fs4all = False @@ -662,7 +662,7 @@ def visit(prefix, dir, names): global suite global regexp - global filterspec + global filters global fs4all for name in names: @@ -689,7 +689,8 @@ def visit(prefix, dir, names): # Thoroughly check the filterspec against the base module and admit # the (base, filterspec) combination only when it makes sense. - if filterspec: + filterspec = None + for filterspec in filters: # Optimistically set the flag to True. filtered = True module = __import__(base) @@ -702,13 +703,19 @@ def visit(prefix, dir, names): # The filterspec has failed. filtered = False break - # Forgo this module if the (base, filterspec) combo is invalid - # and no '-g' option is specified - if fs4all and not filtered: - continue + + # If we reach here, we have a good filterspec. Add it. + if filtered: + break + + # Forgo this module if the (base, filterspec) combo is invalid + # and no '-g' option is specified + if filters and fs4all and not filtered: + continue # Add either the filtered test case or the entire test class. if filterspec and filtered: + #print "adding filter spec %s to module %s" % (filterspec, module) suite.addTests( unittest2.defaultTestLoader.loadTestsFromName(filterspec, module)) else: diff --git a/lldb/test/redo.py b/lldb/test/redo.py new file mode 100755 index 0000000..c3034bb1 --- /dev/null +++ b/lldb/test/redo.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +""" +A simple utility to redo the failed/errored tests. + +You need to specify the session directory in order for this script to locate the +tests which need to be re-run. + +See also dotest.py, the test driver running the test suite. + +Type: + +./dotest.py -h + +for help. +""" + +import os, sys +import re + +# If True, redo with no '-t' option for the test driver. +no_trace = False + +# To be filled with the filterspecs found in the session logs. +redo_specs = [] + +def usage(): + print"""\ +Usage: redo.py [-n] session_dir +where options: +-n : when running the tests, do not turn on trace mode, i.e, no '-t' option + is passed to the test driver (this will run the tests faster) + +and session_dir specifies the session directory which contains previously +recorded session infos for all the test cases which either failed or errored.""" + sys.exit(0) + +def where(session_dir, test_dir): + """Returns the full path to the session directory; None if non-existent.""" + abspath = os.path.abspath(session_dir) + if os.path.isdir(abspath): + return abspath + + session_dir_path = os.path.join(test_dir, session_dir) + if os.path.isdir(session_dir_path): + return session_dir_path + + return None + +# This is the pattern for the line from the log file to redo a test. +# We want the filter spec. +pattern = re.compile("^\./dotest\.py.*-f (.*)$") +def redo(suffix, dir, names): + """Visitor function for os.path.walk(path, visit, arg).""" + global redo_specs + + for name in names: + if name.endswith(suffix): + #print "Find a log file:", name + if name.startswith("Error") or name.startswith("Failure"): + with open(os.path.join(dir, name), 'r') as log: + content = log.read() + for line in content.splitlines(): + match = pattern.match(line) + if match: + filterspec = match.group(1) + print "adding filterspec:", filterspec + redo_specs.append(filterspec) + else: + continue + +def main(): + """Read the session directory and run the failed test cases one by one.""" + global no_trace + global redo_specs + + if len(sys.argv) < 2 or len(sys.argv) > 3: + usage() + + index = 1 + while index < len(sys.argv): + if sys.argv[index].startswith('-'): + # We should continue processing... + pass + else: + # End of option processing. + break + + if sys.argv[index] == '-n': + no_trace = True + index += 1 + + session_dir = sys.argv[index] + + test_dir = sys.path[0] + if not test_dir.endswith('test'): + print "This script expects to reside in lldb's test directory." + sys.exit(-1) + + #print "The test directory:", test_dir + session_dir_path = where(session_dir, test_dir) + + #print "Session dir path:", session_dir_path + os.chdir(test_dir) + os.path.walk(session_dir_path, redo, ".log") + + command = "./dotest.py -v %s -f " % ("" if no_trace else "-t") + filters = " -f ".join(redo_specs) + + print "Running %s" % (command + filters) + os.system(command + filters) + +if __name__ == '__main__': + main() |
