diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
| commit | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch) | |
| tree | dd2a1ddf0476664c2b823409c36cbccd52662ca7 /packages/Python/lldbsuite/test/redo.py | |
| parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
Notes
Diffstat (limited to 'packages/Python/lldbsuite/test/redo.py')
| -rw-r--r-- | packages/Python/lldbsuite/test/redo.py | 195 | 
1 files changed, 195 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/redo.py b/packages/Python/lldbsuite/test/redo.py new file mode 100644 index 0000000000000..e4eba8b278605 --- /dev/null +++ b/packages/Python/lldbsuite/test/redo.py @@ -0,0 +1,195 @@ +#!/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. +""" + +from __future__ import print_function + +import os, sys, datetime +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 = [] + +# The filename components to match for.  Only files with the contained component names +# will be considered for re-run.  Examples: ['X86_64', 'clang']. +filename_components = [] + +do_delay = False + +# There is a known bug with respect to comp_specs and arch_specs, in that if we +# encountered "-C clang" and "-C gcc" when visiting the session files, both +# compilers will end up in the invocation of the test driver when rerunning. +# That is: ./dotest -v -C clang^gcc ... -f ...".  Ditto for "-A" flags. + +# The "-C compiler" for comp_specs. +comp_specs = set() +# The "-A arch" for arch_specs. +arch_specs = set() + +def usage(): +    print("""\ +Usage: redo.py [-F filename_component] [-n] [session_dir] [-d] +where options: +-F : only consider the test for re-run if the session filename contains the filename component +     for example: -F x86_64 +-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) +-d : pass -d down to the test driver (introduces a delay so you can attach with a debugger) + +and session_dir specifies the session directory which contains previously +recorded session infos for all the test cases which either failed or errored. + +If sessin_dir is left unspecified, this script uses the heuristic to find the +possible session directories with names starting with %Y-%m-%d- (for example, +2012-01-23-) and employs the one with the latest timestamp.""") +    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. +filter_pattern = re.compile("^\./dotest\.py.*-f (.*)$") +comp_pattern = re.compile(" -C ([^ ]+) ") +arch_pattern = re.compile(" -A ([^ ]+) ") +def redo(suffix, dir, names): +    """Visitor function for os.path.walk(path, visit, arg).""" +    global redo_specs +    global comp_specs +    global arch_specs +    global filter_pattern +    global comp_pattern +    global arch_pattern +    global filename_components +    global do_delay + +    for name in names: +        if name.endswith(suffix): +            #print("Find a log file:", name) +            if name.startswith("Error") or name.startswith("Failure"): +                if filename_components: +                    if not all([comp in name for comp in filename_components]): +                        continue +                with open(os.path.join(dir, name), 'r') as log: +                    content = log.read() +                    for line in content.splitlines(): +                        match = filter_pattern.match(line) +                        if match: +                            filterspec = match.group(1) +                            print("adding filterspec:", filterspec) +                            redo_specs.append(filterspec) +                            comp = comp_pattern.search(line) +                            if comp: +                                comp_specs.add(comp.group(1)) +                            arch = arch_pattern.search(line) +                            if arch: +                                arch_specs.add(arch.group(1))                                 +            else: +                continue + +def main(): +    """Read the session directory and run the failed test cases one by one.""" +    global no_trace +    global redo_specs +    global filename_components +    global do_delay + +    test_dir = sys.path[0] +    if not test_dir: +        test_dir = os.getcwd() +    if not test_dir.endswith('test'): +        print("This script expects to reside in lldb's test directory.") +        sys.exit(-1) + +    index = 1 +    while index < len(sys.argv): +        if sys.argv[index].startswith('-h') or sys.argv[index].startswith('--help'): +            usage() + +        if sys.argv[index].startswith('-'): +            # We should continue processing... +            pass +        else: +            # End of option processing. +            break + +        if sys.argv[index] == '-F': +            # Increment by 1 to fetch the filename component spec. +            index += 1 +            if index >= len(sys.argv) or sys.argv[index].startswith('-'): +                usage() +            filename_components.append(sys.argv[index]) +        elif sys.argv[index] == '-n': +            no_trace = True +        elif sys.argv[index] == '-d': +            do_delay = True + +        index += 1 + +    if index < len(sys.argv): +        # Get the specified session directory. +        session_dir = sys.argv[index] +    else: +        # Use heuristic to find the latest session directory. +        name = datetime.datetime.now().strftime("%Y-%m-%d-") +        dirs = [d for d in os.listdir(os.getcwd()) if d.startswith(name)] +        if len(dirs) == 0: +            print("No default session directory found, please specify it explicitly.") +            usage() +        session_dir = max(dirs, key=os.path.getmtime) +        if not session_dir or not os.path.exists(session_dir): +            print("No default session directory found, please specify it explicitly.") +            usage() + +    #print("The test directory:", test_dir) +    session_dir_path = where(session_dir, test_dir) + +    print("Using session dir path:", session_dir_path) +    os.chdir(test_dir) +    os.path.walk(session_dir_path, redo, ".log") + +    if not redo_specs: +        print("No failures/errors recorded within the session directory, please specify a different session directory.\n") +        usage() + +    filters = " -f ".join(redo_specs) +    compilers = '' +    for comp in comp_specs: +        compilers += " -C %s" % (comp) +    archs = '' +    for arch in arch_specs: +        archs += "--arch %s " % (arch) + +    command = "./dotest.py %s %s -v %s %s -f " % (compilers, archs, "" if no_trace else "-t", "-d" if do_delay else "") + + +    print("Running %s" % (command + filters)) +    os.system(command + filters) + +if __name__ == '__main__': +    main()  | 
