2013-01-06 19:18:13 -08:00
|
|
|
#! /usr/bin/python
|
|
|
|
|
|
|
|
"""This script takes the file produced by DMD's test mode and checks its
|
|
|
|
correctness.
|
|
|
|
|
|
|
|
It produces the following output files: $TMP/test-{fixed,filtered,diff}.dmd.
|
|
|
|
|
|
|
|
It runs the appropriate fix* script to get nice stack traces. It also
|
|
|
|
filters out platform-specific details from the test output file.
|
|
|
|
|
|
|
|
Note: you must run this from the same directory that you invoked DMD's test
|
|
|
|
mode, otherwise the fix* script will not work properly, because some of the
|
|
|
|
paths in the test output are relative.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
import os
|
|
|
|
import platform
|
|
|
|
import re
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
|
|
# Arguments
|
|
|
|
|
|
|
|
if (len(sys.argv) != 3):
|
2013-12-18 13:58:08 -08:00
|
|
|
print("usage:", sys.argv[0], "<topsrcdir> <test.dmd>")
|
2013-01-06 19:18:13 -08:00
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
srcdir = sys.argv[1]
|
|
|
|
|
|
|
|
# Filenames
|
|
|
|
|
|
|
|
tempdir = tempfile.gettempdir()
|
|
|
|
in_name = sys.argv[2]
|
|
|
|
fixed_name = tempdir + os.sep + "test-fixed.dmd"
|
|
|
|
filtered_name = tempdir + os.sep + "test-filtered.dmd"
|
|
|
|
diff_name = tempdir + os.sep + "test-diff.dmd"
|
|
|
|
expected_name = srcdir + os.sep + \
|
|
|
|
"memory/replace/dmd/test-expected.dmd"
|
|
|
|
|
|
|
|
# Fix stack traces
|
|
|
|
|
|
|
|
print("fixing output to", fixed_name)
|
|
|
|
|
|
|
|
sysname = platform.system()
|
|
|
|
if sysname == "Linux":
|
|
|
|
fix = srcdir + os.sep + "tools/rb/fix-linux-stack.pl"
|
|
|
|
elif sysname == "Darwin":
|
|
|
|
fix = srcdir + os.sep + "tools/rb/fix_macosx_stack.py"
|
|
|
|
else:
|
|
|
|
print("unhandled platform: " + sysname, file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
subprocess.call(fix, stdin=open(in_name, "r"),
|
|
|
|
stdout=open(fixed_name, "w"))
|
|
|
|
|
|
|
|
# Filter output
|
|
|
|
|
2013-12-18 13:58:08 -08:00
|
|
|
# In stack trace records we filter out most stack frames. The only thing
|
|
|
|
# we leave behind is a "DMD.cpp" entry if we see one or more frames that
|
|
|
|
# have DMD.cpp in them. There is simply too much variation to do anything
|
|
|
|
# better than that.
|
2013-01-06 19:18:13 -08:00
|
|
|
#
|
2013-12-18 13:58:08 -08:00
|
|
|
# As for stack frame records, alas, we filter them out entirely because
|
|
|
|
# they have even more variation.
|
2013-01-06 19:18:13 -08:00
|
|
|
|
|
|
|
print("filtering output to", filtered_name)
|
|
|
|
|
|
|
|
with open(fixed_name, "r") as fin, \
|
|
|
|
open(filtered_name, "w") as fout:
|
|
|
|
|
2013-12-18 13:58:08 -08:00
|
|
|
test_frame_re = re.compile(r".*(DMD.cpp)")
|
2013-01-06 19:18:13 -08:00
|
|
|
|
|
|
|
for line in fin:
|
|
|
|
if re.match(r" (Allocated at|Reported( again)? at)", line):
|
|
|
|
# It's a stack trace record.
|
|
|
|
print(line, end='', file=fout)
|
|
|
|
|
2013-12-18 13:58:08 -08:00
|
|
|
# Filter the stack trace -- print a single line if we see one
|
|
|
|
# or more frames involving DMD.cpp.
|
|
|
|
seen_DMD_frame = False
|
2013-01-06 19:18:13 -08:00
|
|
|
for frame in fin:
|
|
|
|
if re.match(r" ", frame):
|
|
|
|
m = test_frame_re.match(frame)
|
|
|
|
if m:
|
2013-12-18 13:58:08 -08:00
|
|
|
seen_DMD_frame = True
|
2013-01-06 19:18:13 -08:00
|
|
|
else:
|
|
|
|
# We're past the stack trace.
|
2013-12-18 13:58:08 -08:00
|
|
|
if seen_DMD_frame:
|
|
|
|
print(" ... DMD.cpp", file=fout)
|
2013-01-06 19:18:13 -08:00
|
|
|
print(frame, end='', file=fout)
|
|
|
|
break
|
|
|
|
|
|
|
|
elif re.search("in stack frame record", line):
|
|
|
|
# Stack frame record. Get the whole thing (we know how many
|
|
|
|
# lines it has).
|
|
|
|
line2 = fin.next()
|
|
|
|
line3 = fin.next()
|
|
|
|
line4 = fin.next()
|
2013-12-18 13:58:08 -08:00
|
|
|
line5 = fin.next()
|
2013-01-06 19:18:13 -08:00
|
|
|
line6 = fin.next()
|
|
|
|
|
|
|
|
else:
|
2013-12-18 13:58:08 -08:00
|
|
|
# A line that needs no special handling. Copy it through.
|
2013-01-06 19:18:13 -08:00
|
|
|
print(line, end='', file=fout)
|
|
|
|
|
|
|
|
# Compare with expected output
|
|
|
|
|
|
|
|
print("diffing output to", diff_name)
|
|
|
|
|
2013-01-07 18:01:07 -08:00
|
|
|
ret = subprocess.call(["diff", "-u", expected_name, filtered_name],
|
2013-01-06 19:18:13 -08:00
|
|
|
stdout=open(diff_name, "w"))
|
|
|
|
|
|
|
|
if ret == 0:
|
|
|
|
print("test PASSED")
|
|
|
|
else:
|
|
|
|
print("test FAILED (did you remember to run this script and Firefox "
|
|
|
|
"in the same directory?)")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|