Index: tools/test.py
|
===================================================================
|
--- tools/test.py (revision 623)
|
+++ tools/test.py (working copy)
|
@@ -63,6 +63,7 @@
|
self.remaining = len(cases)
|
self.total = len(cases)
|
self.failed = [ ]
|
+ self.crashed = 0
|
self.terminate = False
|
self.lock = threading.Lock()
|
|
@@ -124,6 +125,8 @@
|
self.lock.acquire()
|
if output.UnexpectedOutput():
|
self.failed.append(output)
|
+ if output.HasCrashed():
|
+ self.crashed += 1
|
else:
|
self.succeeded += 1
|
self.remaining -= 1
|
@@ -159,6 +162,8 @@
|
print "--- stdout ---"
|
print failed.output.stdout.strip()
|
print "Command: %s" % EscapeCommand(failed.command)
|
+ if failed.HasCrashed():
|
+ print "--- CRASHED ---"
|
if len(self.failed) == 0:
|
print "==="
|
print "=== All tests succeeded"
|
@@ -167,6 +172,8 @@
|
print
|
print "==="
|
print "=== %i tests failed" % len(self.failed)
|
+ if self.crashed > 0:
|
+ print "=== %i tests CRASHED" % self.crashed
|
print "==="
|
|
|
@@ -178,7 +185,10 @@
|
|
def HasRun(self, output):
|
if output.UnexpectedOutput():
|
- outcome = 'FAIL'
|
+ if output.HasCrashed():
|
+ outcome = 'CRASH'
|
+ else:
|
+ outcome = 'FAIL'
|
else:
|
outcome = 'pass'
|
print 'Done running %s: %s' % (output.test.GetLabel(), outcome)
|
@@ -194,8 +204,12 @@
|
if (total > 1) and (total % 50 == 1):
|
sys.stdout.write('\n')
|
if output.UnexpectedOutput():
|
- sys.stdout.write('F')
|
- sys.stdout.flush()
|
+ if output.HasCrashed():
|
+ sys.stdout.write('C')
|
+ sys.stdout.flush()
|
+ else:
|
+ sys.stdout.write('F')
|
+ sys.stdout.flush()
|
else:
|
sys.stdout.write('.')
|
sys.stdout.flush()
|
@@ -229,6 +243,8 @@
|
if len(stderr):
|
print self.templates['stderr'] % stderr
|
print "Command: %s" % EscapeCommand(output.command)
|
+ if output.HasCrashed():
|
+ print "--- CRASHED ---"
|
|
def Truncate(self, str, length):
|
if length and (len(str) > (length - 3)):
|
@@ -344,12 +360,20 @@
|
self.output = output
|
|
def UnexpectedOutput(self):
|
- if self.HasFailed():
|
+ if self.HasCrashed():
|
+ outcome = CRASH
|
+ elif self.HasFailed():
|
outcome = FAIL
|
else:
|
outcome = PASS
|
return not outcome in self.test.outcomes
|
|
+ def HasCrashed(self):
|
+ if platform.system() == 'Windows':
|
+ return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.output.exit_code)
|
+ else:
|
+ return False
|
+
|
def HasFailed(self):
|
execution_failed = self.test.DidFail(self.output)
|
if self.test.IsNegative():
|
@@ -369,17 +393,34 @@
|
INITIAL_SLEEP_TIME = 0.0001
|
SLEEP_TIME_FACTOR = 1.25
|
|
+SEM_INVALID_VALUE = -1
|
+SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h
|
|
+def Win32SetErrorMode(mode):
|
+ prev_error_mode = SEM_INVALID_VALUE
|
+ try:
|
+ import ctypes
|
+ prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode);
|
+ except ImportError:
|
+ pass
|
+ return prev_error_mode
|
+
|
def RunProcess(context, timeout, args, **rest):
|
if context.verbose: print "#", " ".join(args)
|
popen_args = args
|
+ prev_error_mode = SEM_INVALID_VALUE;
|
if platform.system() == 'Windows':
|
popen_args = '"' + subprocess.list2cmdline(args) + '"'
|
+ if context.supress_dialogs:
|
+ # Try to change the error mode to avoid dialogs on fatal errors.
|
+ Win32SetErrorMode(SEM_NOGPFAULTERRORBOX)
|
process = subprocess.Popen(
|
shell = (platform.system() == 'Windows'),
|
args = popen_args,
|
**rest
|
)
|
+ if platform.system() == 'Windows' and context.supress_dialogs and prev_error_mode != SEM_INVALID_VALUE:
|
+ Win32SetErrorMode(prev_error_mode)
|
# Compute the end time - if the process crosses this limit we
|
# consider it timed out.
|
if timeout is None: end_time = None
|
@@ -543,13 +584,14 @@
|
|
class Context(object):
|
|
- def __init__(self, workspace, buildspace, verbose, vm, timeout, processor):
|
+ def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, supress_dialogs):
|
self.workspace = workspace
|
self.buildspace = buildspace
|
self.verbose = verbose
|
self.vm_root = vm
|
self.timeout = timeout
|
self.processor = processor
|
+ self.supress_dialogs = supress_dialogs
|
|
def GetVm(self, mode):
|
name = self.vm_root + PREFIX[mode]
|
@@ -1030,6 +1072,11 @@
|
default=1, type="int")
|
result.add_option("--time", help="Print timing information after running",
|
default=False, action="store_true")
|
+ if platform.system() == 'Windows':
|
+ result.add_option("--supress-dialogs", help="Supress Windows dialogs for crashing tests",
|
+ dest="supress_dialogs", default=True, action="store_true")
|
+ result.add_option("--no-supress-dialogs", help="Display Windows dialogs for crashing tests",
|
+ dest="supress_dialogs", action="store_false")
|
return result
|
|
|
@@ -1159,7 +1206,8 @@
|
context = Context(workspace, buildspace, VERBOSE,
|
join(buildspace, 'shell'),
|
options.timeout,
|
- GetSpecialCommandProcessor(options.special_command))
|
+ GetSpecialCommandProcessor(options.special_command),
|
+ options.supress_dialogs)
|
if options.j != 1:
|
options.scons_flags += ['-j', str(options.j)]
|
if not options.no_build:
|
|