tests/run-tests.py
branchstable
changeset 682 1c7056415039
parent 681 d0a410e49776
child 683 26ca426a04e1
equal deleted inserted replaced
681:d0a410e49776 682:1c7056415039
    43 
    43 
    44 import difflib
    44 import difflib
    45 import errno
    45 import errno
    46 import optparse
    46 import optparse
    47 import os
    47 import os
       
    48 import signal
    48 import subprocess
    49 import subprocess
    49 import shutil
    50 import shutil
    50 import signal
    51 import signal
    51 import sys
    52 import sys
    52 import tempfile
    53 import tempfile
   281         if found:
   282         if found:
   282             vlog("# Found prerequisite", p, "at", found)
   283             vlog("# Found prerequisite", p, "at", found)
   283         else:
   284         else:
   284             print "WARNING: Did not find prerequisite tool: "+p
   285             print "WARNING: Did not find prerequisite tool: "+p
   285 
   286 
       
   287 def killdaemons():
       
   288     # Kill off any leftover daemon processes
       
   289     try:
       
   290         fp = open(DAEMON_PIDS)
       
   291         for line in fp:
       
   292             try:
       
   293                 pid = int(line)
       
   294             except ValueError:
       
   295                 continue
       
   296             try:
       
   297                 os.kill(pid, 0)
       
   298                 vlog('# Killing daemon process %d' % pid)
       
   299                 os.kill(pid, signal.SIGTERM)
       
   300                 time.sleep(0.25)
       
   301                 os.kill(pid, 0)
       
   302                 vlog('# Daemon process %d is stuck - really killing it' % pid)
       
   303                 os.kill(pid, signal.SIGKILL)
       
   304             except OSError, err:
       
   305                 if err.errno != errno.ESRCH:
       
   306                     raise
       
   307         fp.close()
       
   308         os.unlink(DAEMON_PIDS)
       
   309     except IOError:
       
   310         pass
       
   311 
   286 def cleanup(options):
   312 def cleanup(options):
   287     if not options.keep_tmpdir:
   313     if not options.keep_tmpdir:
   288         vlog("# Cleaning up HGTMP", HGTMP)
   314         vlog("# Cleaning up HGTMP", HGTMP)
   289         shutil.rmtree(HGTMP, True)
   315         shutil.rmtree(HGTMP, True)
   290 
   316 
   430         ret = fromchild.close()
   456         ret = fromchild.close()
   431         if ret == None:
   457         if ret == None:
   432             ret = 0
   458             ret = 0
   433     else:
   459     else:
   434         proc = Popen4(cmd)
   460         proc = Popen4(cmd)
       
   461         def cleanup():
       
   462             os.kill(proc.pid, signal.SIGTERM)
       
   463             ret = proc.wait()
       
   464             if ret == 0:
       
   465                 ret = signal.SIGTERM << 8
       
   466             killdaemons()
       
   467             return ret
       
   468 
   435         try:
   469         try:
   436             output = ''
   470             output = ''
   437             proc.tochild.close()
   471             proc.tochild.close()
   438             output = proc.fromchild.read()
   472             output = proc.fromchild.read()
   439             ret = proc.wait()
   473             ret = proc.wait()
   440             if os.WIFEXITED(ret):
   474             if os.WIFEXITED(ret):
   441                 ret = os.WEXITSTATUS(ret)
   475                 ret = os.WEXITSTATUS(ret)
   442         except Timeout:
   476         except Timeout:
   443             vlog('# Process %d timed out - killing it' % proc.pid)
   477             vlog('# Process %d timed out - killing it' % proc.pid)
   444             os.kill(proc.pid, signal.SIGTERM)
   478             ret = cleanup()
   445             ret = proc.wait()
       
   446             if ret == 0:
       
   447                 ret = signal.SIGTERM << 8
       
   448             output += ("\n### Abort: timeout after %d seconds.\n"
   479             output += ("\n### Abort: timeout after %d seconds.\n"
   449                        % options.timeout)
   480                        % options.timeout)
       
   481         except KeyboardInterrupt:
       
   482             vlog('# Handling keyboard interrupt')
       
   483             cleanup()
       
   484             raise
       
   485 
   450     return ret, splitnewlines(output)
   486     return ret, splitnewlines(output)
   451 
   487 
   452 def runone(options, test, skips, fails):
   488 def runone(options, test, skips, fails):
   453     '''tristate output:
   489     '''tristate output:
   454     None -> skipped
   490     None -> skipped
   587         f = open(err, "wb")
   623         f = open(err, "wb")
   588         for line in out:
   624         for line in out:
   589             f.write(line)
   625             f.write(line)
   590         f.close()
   626         f.close()
   591 
   627 
   592     # Kill off any leftover daemon processes
   628     killdaemons()
   593     try:
       
   594         fp = open(DAEMON_PIDS)
       
   595         for line in fp:
       
   596             try:
       
   597                 pid = int(line)
       
   598             except ValueError:
       
   599                 continue
       
   600             try:
       
   601                 os.kill(pid, 0)
       
   602                 vlog('# Killing daemon process %d' % pid)
       
   603                 os.kill(pid, signal.SIGTERM)
       
   604                 time.sleep(0.25)
       
   605                 os.kill(pid, 0)
       
   606                 vlog('# Daemon process %d is stuck - really killing it' % pid)
       
   607                 os.kill(pid, signal.SIGKILL)
       
   608             except OSError, err:
       
   609                 if err.errno != errno.ESRCH:
       
   610                     raise
       
   611         fp.close()
       
   612         os.unlink(DAEMON_PIDS)
       
   613     except IOError:
       
   614         pass
       
   615 
   629 
   616     os.chdir(TESTDIR)
   630     os.chdir(TESTDIR)
   617     if not options.keep_tmpdir:
   631     if not options.keep_tmpdir:
   618         shutil.rmtree(tmpd, True)
   632         shutil.rmtree(tmpd, True)
   619     if skipped:
   633     if skipped:
   670         for job in jobs:
   684         for job in jobs:
   671             if not tests:
   685             if not tests:
   672                 break
   686                 break
   673             job.append(tests.pop())
   687             job.append(tests.pop())
   674     fps = {}
   688     fps = {}
       
   689 
   675     for j, job in enumerate(jobs):
   690     for j, job in enumerate(jobs):
   676         if not job:
   691         if not job:
   677             continue
   692             continue
   678         rfd, wfd = os.pipe()
   693         rfd, wfd = os.pipe()
   679         childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
   694         childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
   681         childopts += ['--tmpdir', childtmp]
   696         childopts += ['--tmpdir', childtmp]
   682         cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
   697         cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
   683         vlog(' '.join(cmdline))
   698         vlog(' '.join(cmdline))
   684         fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
   699         fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
   685         os.close(wfd)
   700         os.close(wfd)
       
   701     signal.signal(signal.SIGINT, signal.SIG_IGN)
   686     failures = 0
   702     failures = 0
   687     tested, skipped, failed = 0, 0, 0
   703     tested, skipped, failed = 0, 0, 0
   688     skips = []
   704     skips = []
   689     fails = []
   705     fails = []
   690     while fps:
   706     while fps:
   691         pid, status = os.wait()
   707         pid, status = os.wait()
   692         fp = fps.pop(pid)
   708         fp = fps.pop(pid)
   693         l = fp.read().splitlines()
   709         l = fp.read().splitlines()
   694         test, skip, fail = map(int, l[:3])
   710         try:
       
   711             test, skip, fail = map(int, l[:3])
       
   712         except ValueError:
       
   713             test, skip, fail = 0, 0, 0
   695         split = -fail or len(l)
   714         split = -fail or len(l)
   696         for s in l[3:split]:
   715         for s in l[3:split]:
   697             skips.append(s.split(" ", 1))
   716             skips.append(s.split(" ", 1))
   698         for s in l[split:]:
   717         for s in l[split:]:
   699             fails.append(s.split(" ", 1))
   718             fails.append(s.split(" ", 1))
   922         if len(tests) > 1 and options.jobs > 1:
   941         if len(tests) > 1 and options.jobs > 1:
   923             runchildren(options, tests)
   942             runchildren(options, tests)
   924         else:
   943         else:
   925             runtests(options, tests)
   944             runtests(options, tests)
   926     finally:
   945     finally:
       
   946         time.sleep(1)
   927         cleanup(options)
   947         cleanup(options)
   928 
   948 
   929 main()
   949 main()