memory/replace/dmd/check_test_output.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/memory/replace/dmd/check_test_output.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,128 @@
     1.4 +#! /usr/bin/python
     1.5 +
     1.6 +"""This script takes the file produced by DMD's test mode and checks its
     1.7 +correctness.
     1.8 +
     1.9 +It produces the following output files: $TMP/test-{fixed,filtered,diff}.dmd.
    1.10 +
    1.11 +It runs the appropriate fix* script to get nice stack traces.  It also
    1.12 +filters out platform-specific details from the test output file.
    1.13 +
    1.14 +Note: you must run this from the same directory that you invoked DMD's test
    1.15 +mode, otherwise the fix* script will not work properly, because some of the
    1.16 +paths in the test output are relative.
    1.17 +
    1.18 +"""
    1.19 +
    1.20 +from __future__ import print_function
    1.21 +
    1.22 +import os
    1.23 +import platform
    1.24 +import re
    1.25 +import subprocess
    1.26 +import sys
    1.27 +import tempfile
    1.28 +
    1.29 +
    1.30 +def main():
    1.31 +
    1.32 +    # Arguments
    1.33 +
    1.34 +    if (len(sys.argv) != 3):
    1.35 +        print("usage:", sys.argv[0], "<topsrcdir> <test.dmd>")
    1.36 +        sys.exit(1)
    1.37 +
    1.38 +    srcdir = sys.argv[1]
    1.39 +
    1.40 +    # Filenames
    1.41 +
    1.42 +    tempdir = tempfile.gettempdir()
    1.43 +    in_name       = sys.argv[2]
    1.44 +    fixed_name    = tempdir + os.sep + "test-fixed.dmd"
    1.45 +    filtered_name = tempdir + os.sep + "test-filtered.dmd"
    1.46 +    diff_name     = tempdir + os.sep + "test-diff.dmd"
    1.47 +    expected_name = srcdir + os.sep + \
    1.48 +                    "memory/replace/dmd/test-expected.dmd"
    1.49 +
    1.50 +    # Fix stack traces
    1.51 +
    1.52 +    print("fixing output to", fixed_name)
    1.53 +
    1.54 +    sysname = platform.system()
    1.55 +    if sysname == "Linux":
    1.56 +        fix = srcdir + os.sep + "tools/rb/fix-linux-stack.pl"
    1.57 +    elif sysname == "Darwin":
    1.58 +        fix = srcdir + os.sep + "tools/rb/fix_macosx_stack.py"
    1.59 +    else:
    1.60 +        print("unhandled platform: " + sysname, file=sys.stderr)
    1.61 +        sys.exit(1)
    1.62 +
    1.63 +    subprocess.call(fix, stdin=open(in_name, "r"),
    1.64 +                         stdout=open(fixed_name, "w"))
    1.65 +
    1.66 +    # Filter output
    1.67 +
    1.68 +    # In stack trace records we filter out most stack frames.  The only thing
    1.69 +    # we leave behind is a "DMD.cpp" entry if we see one or more frames that
    1.70 +    # have DMD.cpp in them.  There is simply too much variation to do anything
    1.71 +    # better than that.
    1.72 +    #
    1.73 +    # As for stack frame records, alas, we filter them out entirely because
    1.74 +    # they have even more variation.
    1.75 +
    1.76 +    print("filtering output to", filtered_name)
    1.77 +
    1.78 +    with open(fixed_name, "r") as fin, \
    1.79 +         open(filtered_name, "w") as fout:
    1.80 +
    1.81 +        test_frame_re = re.compile(r".*(DMD.cpp)")
    1.82 +
    1.83 +        for line in fin:
    1.84 +            if re.match(r" (Allocated at|Reported( again)? at)", line):
    1.85 +                # It's a stack trace record.
    1.86 +                print(line, end='', file=fout)
    1.87 +
    1.88 +                # Filter the stack trace -- print a single line if we see one
    1.89 +                # or more frames involving DMD.cpp.
    1.90 +                seen_DMD_frame = False
    1.91 +                for frame in fin:
    1.92 +                    if re.match(r"   ", frame):
    1.93 +                        m = test_frame_re.match(frame)
    1.94 +                        if m:
    1.95 +                            seen_DMD_frame = True
    1.96 +                    else:
    1.97 +                        # We're past the stack trace.
    1.98 +                        if seen_DMD_frame:
    1.99 +                            print("   ... DMD.cpp", file=fout)
   1.100 +                        print(frame, end='', file=fout)
   1.101 +                        break
   1.102 +
   1.103 +            elif re.search("in stack frame record", line):
   1.104 +                # Stack frame record.  Get the whole thing (we know how many
   1.105 +                # lines it has).
   1.106 +                line2 = fin.next()
   1.107 +                line3 = fin.next()
   1.108 +                line4 = fin.next()
   1.109 +                line5 = fin.next()
   1.110 +                line6 = fin.next()
   1.111 +
   1.112 +            else:
   1.113 +                # A line that needs no special handling.  Copy it through.
   1.114 +                print(line, end='', file=fout)
   1.115 +
   1.116 +    # Compare with expected output
   1.117 +
   1.118 +    print("diffing output to", diff_name)
   1.119 +
   1.120 +    ret = subprocess.call(["diff", "-u", expected_name, filtered_name],
   1.121 +                          stdout=open(diff_name, "w"))
   1.122 +
   1.123 +    if ret == 0:
   1.124 +        print("test PASSED")
   1.125 +    else:
   1.126 +        print("test FAILED (did you remember to run this script and Firefox "
   1.127 +              "in the same directory?)")
   1.128 +
   1.129 +
   1.130 +if __name__ == "__main__":
   1.131 +    main()

mercurial