Changeset: 19d5718834ec for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=19d5718834ec
Modified Files:
        testing/Mtest.py.in
Branch: Aug2011
Log Message:

Mtest: use exit codes to determine what went wrong.
We now also recognize abort() (i.e. assert()).


diffs (truncated from 517 to 300 lines):

diff --git a/testing/Mtest.py.in b/testing/Mtest.py.in
--- a/testing/Mtest.py.in
+++ b/testing/Mtest.py.in
@@ -208,19 +208,21 @@ F_OK = 0
 F_WARN = 1
 F_SOCK = 2
 F_TIME = 3
-F_RECU = 4
-F_SEGV = 5
-F_ERROR = 6
+F_ABRT = 4
+F_RECU = 5
+F_SEGV = 6
+F_ERROR = 7
 
 FAILURES = {
-    F_SKIP  : "F_SKIP",
-    F_OK    : "F_OK",
-    F_WARN  : "F_WARN",
-    F_SOCK  : "F_SOCK",
-    F_TIME  : "F_TIME",
-    F_RECU  : "F_RECU",
-    F_SEGV  : "F_SEGV",
-    F_ERROR : "F_ERROR"
+    F_SKIP  : ("F_SKIP",  '-'),
+    F_OK    : ("F_OK",    'o'),
+    F_WARN  : ("F_WARN",  'x'),
+    F_SOCK  : ("F_SOCK",  'S'),
+    F_TIME  : ("F_TIME",  'T'),
+    F_ABRT  : ("F_ABRT",  'A'),
+    F_RECU  : ("F_RECU",  'R'),
+    F_SEGV  : ("F_SEGV",  'C'),
+    F_ERROR : ("F_ERROR", 'X')
 }
 
 CONDITIONALS = {
@@ -445,6 +447,7 @@ purple = '#aa00aa'
 stylesheet = Element('style', None, Text('''
 .error     { font-weight: bold; font-style: italic; color: red; }
 .segfault  { font-weight: bold; font-style: italic; color: purple; }
+.abort     { font-weight: bold; font-style: italic; color: purple; }
 .recursion { font-weight: bold; font-style: italic; color: purple; }
 .timeout   { font-weight: bold; font-style: italic; color: purple; }
 .socket    { font-weight: bold; font-style: italic; color: purple; }
@@ -651,7 +654,7 @@ def CreateTstWhatXhtml (env, TST, stable
         f.close()
         diffclass = 'error'
         difftext = 'Major differences'
-    if diffclass == 'error' and SockTime in (F_SOCK, F_TIME, F_RECU, F_SEGV):
+    if diffclass == 'error' and SockTime in (F_SOCK, F_TIME, F_RECU, F_ABRT, 
F_SEGV):
         if SockTime == F_SOCK:
             diffclass = 'socket'
             difftext = difftext + ' (Socket)'
@@ -661,6 +664,9 @@ def CreateTstWhatXhtml (env, TST, stable
         if SockTime == F_RECU:
             diffclass = 'recursion'
             difftext = difftext + ' (Recursion)'
+        if SockTime == F_ABRT:
+            diffclass = 'abort'
+            difftext = difftext + ' (Aborted)'
         if SockTime == F_SEGV:
             diffclass = 'segfault'
             difftext = difftext + ' (Crash)'
@@ -867,6 +873,8 @@ def AddHref (href, target, linktext, dif
         klass = 'timeout'
     elif diff == F_SOCK:
         klass = 'socket'
+    elif diff == F_ABRT:
+        klass = 'abort'
     elif diff == F_SEGV:
         klass = 'segfault'
     elif diff == F_WARN:
@@ -915,7 +923,7 @@ def AddTstToHtmlIndex (env, TST, STABLEo
         ff.write("\n<!--MajorDiffs-->\n")
         ff.close()
         e = F_ERROR
-    if e == F_ERROR and SockTime in (F_SOCK, F_TIME, F_RECU, F_SEGV):
+    if e == F_ERROR and SockTime in (F_SOCK, F_TIME, F_RECU, F_ABRT, F_SEGV):
         e = SockTime
     if o == F_ERROR or e == F_ERROR:
         tstclass = 'error'
@@ -925,6 +933,8 @@ def AddTstToHtmlIndex (env, TST, STABLEo
         tstclass = 'timeout'
     elif e == F_SOCK:
         tstclass = 'socket'
+    elif e == F_ABRT:
+        tstclass = 'abort'
     elif e == F_SEGV:
         tstclass = 'segfault'
     elif o == F_WARN or e == F_WARN:
@@ -1308,6 +1318,61 @@ def expandvars(path, environ = os.enviro
             i = j
     return path
 
+def returnCode(proc, f = None):
+    '''Interpret the return code of a process.
+    If second arg sepcified, write a message to it.'''
+    if proc.killed:
+        # don't write for timeout, killProc did that already
+        return 'timeout'
+    if os.name == 'nt':
+        if proc.returncode == 3:
+            # heuristic: abort() causes exit code 3
+            if f is not None:
+                f.write('\nAborted\n')
+                f.flush()
+            return 'abort'
+        if proc.returncode == -1073741819: # 0xC0000005
+            if f is not None:
+                f.write('\nSegmentation fault\n')
+                f.flush()
+            return 'segfault'
+        if proc.returncode == -1073741510: # 0xC000013A
+            if f is not None:
+                f.write('\nInterrupt\n')
+                f.flush()
+            return 'interrupt'  # Interrupt
+        if proc.returncode != 0:
+            return 'error'
+    else:
+        if proc.returncode == -signal.SIGSEGV:
+            if f is not None:
+                f.write('\nSegmentation fault\n')
+                f.flush()
+            return 'segfault'   # Segmentation fault
+        if proc.returncode == -signal.SIGBUS:
+            if f is not None:
+                f.write('\nBus error\n')
+                f.flush()
+            return 'segfault'   # Bus error, treat as segfault
+        if proc.returncode == -signal.SIGABRT:
+            if f is not None:
+                f.write('\nAborted\n')
+                f.flush()
+            return 'abort'      # Aborted
+        if proc.returncode == -signal.SIGINT:
+            if f is not None:
+                f.write('\nInterrupt\n')
+                f.flush()
+            return 'interrupt'  # Interrupt
+        if proc.returncode < 0:
+            if f is not None:
+                f.write('\nSignal %d\n' % -proc.returncode)
+                f.flush()
+            return 'signal'     # some other signal
+        if proc.returncode > 0:
+            return 'error'
+    return None                 # no error
+
 def GetBitsAndOIDsAndModsAndStaticAndThreads(env) :
     rtrn = 0
     TSTPREF = env['TSTPREF']
@@ -1316,6 +1381,7 @@ def GetBitsAndOIDsAndModsAndStaticAndThr
     if procdebug:
         print 'GetBitsAndOIDsAndModsAndStaticAndThreads: starting process "%s" 
(inpipe, outpipe, errpipe)\n' % '" "'.join(cmd)
     proc = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = 
subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
+    proc.killed = False
     t = Timer(float(par['TIMEOUT']), killProc, args = [proc, proc.stderr, cmd])
     try:
         t.start()
@@ -1347,10 +1413,9 @@ def GetBitsAndOIDsAndModsAndStaticAndThr
         if procdebug:
             print 'GetBitsAndOIDsAndModsAndStaticAndThreads: process killed 
"%s"\n' % '" "'.join(cmd)
         raise
-    if proc.returncode < 0 or proc.returncode >= 256:
-        ErrExit('GetBitsAndOIDsAndModsAndStaticAndThreads: subcommand crashed')
-    elif proc.returncode != 0:
-        ErrExit('GetBitsAndOIDsAndModsAndStaticAndThreads: subcommand exited 
with error code %d' % proc.returncode)
+    returncode = returnCode(proc)
+    if returncode is not None:
+        ErrExit('GetBitsAndOIDsAndModsAndStaticAndThreads: subcommand failed: 
%s' % returncode)
     env['TST_MODS'] = []
     env['TST_BITS'] = ""
     env['TST_OIDS'] = ""
@@ -1696,19 +1761,21 @@ def RunTest(env, TST, BusyPorts, COND, o
         if not quiet:
             STDOUT.write(" %7.3fs " % TX)
 
-        timeout = F_OK
-        recursion = F_OK
-        segfaulted = F_OK
+        errcode = F_OK
+        if tres == 'timeout':
+            errcode = F_TIME
+        elif tres == 'recursion':
+            errcode = F_RECU
+        elif tres == 'segfault':
+            errcode = F_SEGV
+        elif tres == 'abort':
+            errcode = F_ABRT
+        elif tres == 'error':
+            errcode = F_WARN
+        elif tres is not None:
+            errcode = F_ERROR
 
-        if tres == 'timeout':
-            timeout = F_TIME
-        elif tres == 'recursion':
-            recursion = F_RECU
-        elif tres == 'segfault':
-            segfaulted = F_SEGV
-
-        sockerr = F_OK
-        sockerr = max(sockerr, CheckSocket3(env, "MAPI", TestErrFile))
+        sockerr = CheckSocket3(env, "MAPI", TestErrFile)
 
         #TODO:
         ##if [ ! -f $TSTTRGBASE/Tests/.old.left-over.tmp.bats. ] ; then  touch 
$TSTTRGBASE/Tests/.old.left-over.tmp.bats. ; fi
@@ -1725,24 +1792,30 @@ def RunTest(env, TST, BusyPorts, COND, o
         ##rm -f .new.left-over.tmp.bats. 
$TSTTRGBASE/Tests/.old.left-over.tmp.bats.
         ##if [ -f .all.left-over.tmp.bats. ] ; then  mv -f 
.all.left-over.tmp.bats. $TSTTRGBASE/Tests/.old.left-over.tmp.bats. ; fi
 
-        if timeout == F_TIME:
+        if tres == 'timeout':
             if quiet:
                 STDOUT.write("\n%s : Timeout!\n" % TST)
             elif verbose:
                 STDOUT.write("(Timeout!) ")
 
-        if recursion == F_RECU:
+        if tres == 'recursion':
             if quiet:
                 STDOUT.write("\n%s : Recursion!\n" % TST)
             elif verbose:
                 STDOUT.write("(Recursion!) ")
 
-        if segfaulted == F_SEGV:
+        if tres == 'segfault':
             if quiet:
                 STDOUT.write("\n%s : Crashed!\n" % TST)
             elif verbose:
                 STDOUT.write("(Crashed!) ")
 
+        if tres == 'signal':
+            if quiet:
+                STDOUT.write("\n%s : Signaled!\n" % TST)
+            elif verbose:
+                STDOUT.write("(Signaled!) ")
+
         if verbose:
             STDOUT.write("\n")
 
@@ -1773,8 +1846,8 @@ def RunTest(env, TST, BusyPorts, COND, o
         diff_html.write('<!--MajorDiffs-->\n')
         diff_html.close()
         timedout = True
-        if timeout == F_TIME or recursion == F_RECU or segfaulted == F_SEGV:
-            # test run timed out or crashed => expect major differences!
+        if tres is not None:
+            # test program exited with error => expect major differences!
             ACCURACYout = -1
         else:
             fs = open("%s%s.FILTERED" % (TST, STABLEout))
@@ -1843,8 +1916,8 @@ def RunTest(env, TST, BusyPorts, COND, o
         diff_html.write('<!--MajorDiffs-->\n')
         diff_html.close()
         timedout = True
-        if timeout == F_TIME or recursion == F_RECU or segfaulted == F_SEGV:
-            # test run timed out or crashed => expect major differences!
+        if tres is not None:
+            # test program exited with error => expect major differences!
             ACCURACYerr = -1
         else:
             fs = open("%s%s.FILTERED" % (TST, STABLEerr))
@@ -1908,15 +1981,19 @@ def RunTest(env, TST, BusyPorts, COND, o
             proc = subprocess.Popen(cmd)
             proc.wait()
 
-        FailedOut, FailedErr, elem = AddTstToHtmlIndex(env, TST, STABLEout, 
STABLEerr, EXT, max(sockerr, timeout, recursion, segfaulted))
+        FailedOut, FailedErr, elem = AddTstToHtmlIndex(env, TST, STABLEout, 
STABLEerr, EXT, max(sockerr, errcode))
 
         if not verbose and not quiet:
-            if timeout == F_TIME:
+            if tres == 'timeout':
                 STDOUT.write("TIMEOUT")
-            elif recursion == F_RECU:
+            elif tres == 'recursion':
                 STDOUT.write("RECURSION")
-            elif segfaulted == F_SEGV:
+            elif tres == 'segfault':
                 STDOUT.write("CRASHED")
+            elif tres == 'abort':
+                STDOUT.write('ABORTED')
+            elif tres == 'signal':
+                STDOUT.write('SIGNALED')
             else:
                 if FailedOut == F_OK:
                     STDOUT.write('OK   ')
@@ -2071,7 +2148,9 @@ def killProc(proc, outfile = None, cmd =
     except AttributeError:
         if procdebug:
             print 'killProc: starting process "taskkill" "/F" "/T" "/PID" 
"%s"\n' % str(proc.pid)
-        subprocess.Popen(['taskkill','/F','/T','/PID',str(proc.pid)]).wait()
+        p = subprocess.Popen(['taskkill','/F','/T','/PID',str(proc.pid)],
+                             stdout = subprocess.PIPE, stderr = 
subprocess.PIPE)
+        out, err = p.communicate()
         if procdebug:
             print 'killProc: process exited "taskkill" "/F" "/T" "/PID" "%s" 
(%s)\n' % (str(proc.pid), proc.returncode)
     except OSError:
@@ -2141,7 +2220,10 @@ def RunIt(cmd, TestIn, TestOut, TestErr,
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to