Mercurial > ~astiob > upreckon > hgweb
annotate unix.py @ 82:06356af50bf9
Finished testcases reorganization and CPU time limit implementation
We now have:
* Win32-specific code in the win32 module (including bug fixes),
* UNIX-specific and generic code in the unix module,
* a much cleaner testcases module,
* wait4-based resource limits working on Python 3 (this is a bug fix),
* no warning/error reported on non-Win32 when -x is not passed
  but standard input does not come from a terminal,
* the maxtime configuration variable replaced with two new variables
  named maxcputime and maxwalltime,
* CPU time reported if it can be determined unless an error occurs sooner
  than it is determined (e. g. if the wall-clock time limit is exceeded),
* memory limits enforced even if Upreckon's forking already breaks them,
* CPU time limits and private virtual memory limits honoured on Win32,
* CPU time limits honoured on UNIX(-like) platforms supporting wait4
  or getrusage,
* address space limits honoured on UNIX(-like) platforms supporting
  setrlimit with RLIMIT_AS/RLIMIT_VMEM,
* resident set size limits honoured on UNIX(-like) platforms supporting
  wait4.
| author | Oleg Oshmyan <chortos@inbox.lv> | 
|---|---|
| date | Wed, 23 Feb 2011 23:35:27 +0000 | 
| parents | |
| children | 741ae3391b61 | 
| rev | line source | 
|---|---|
| 82 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 1 # Copyright (c) 2010-2011 Chortos-2 <chortos@inbox.lv> | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 2 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 3 from __future__ import division, with_statement | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 4 import sys | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 5 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 6 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 7 from compat import * | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 8 import testcases # mutual import | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 9 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 10 import __main__ | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 11 __main__.import_error(sys.exc_info()[1]) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 12 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 13 from __main__ import clock | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 14 from subprocess import Popen | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 15 import os, sys | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 16 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 17 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 18 from signal import SIGTERM, SIGKILL | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 19 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 20 SIGTERM = 15 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 21 SIGKILL = 9 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 22 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 23 __all__ = 'call', 'kill', 'terminate', 'pause' | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 24 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 25 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 26 if not sys.stdin.isatty(): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 27 pause = lambda: sys.stdin.read(1) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 28 catch_escape = False | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 29 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 30 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 31 from select import select | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 32 import termios, tty, atexit | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 33 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 34 pause = None | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 35 catch_escape = False | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 36 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 37 catch_escape = True | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 38 def cleanup(old=termios.tcgetattr(sys.stdin.fileno())): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 39 termios.tcsetattr(sys.stdin.fileno(), termios.TCSAFLUSH, old) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 40 atexit.register(cleanup) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 41 tty.setcbreak(sys.stdin.fileno()) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 42 def pause(): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 43 sys.stdin.read(1) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 44 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 45 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 46 from signal import SIGCHLD, signal, SIG_DFL | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 47 from select import select, error as SelectError | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 48 from errno import EINTR | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 49 from fcntl import fcntl, F_SETFD, F_GETFD | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 50 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 51 import cPickle as pickle | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 52 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 53 import pickle | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 54 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 55 def call(*args, **kwargs): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 56 case = kwargs.pop('case') | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 57 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 58 case.process = Popen(*args, **kwargs) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 59 except OSError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 60 raise CannotStartTestee(sys.exc_info()[1]) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 61 case.time_started = clock() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 62 if not case.maxtime: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 63 while True: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 64 exitcode, now = case.process.poll(), clock() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 65 if exitcode is not None: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 66 case.time_stopped = now | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 67 break | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 68 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 69 time.sleep(.001) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 70 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 71 time_end = case.time_started + case.maxtime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 72 while True: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 73 exitcode, now = case.process.poll(), clock() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 74 if exitcode is not None: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 75 case.time_stopped = now | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 76 break | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 77 elif now >= time_end: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 78 raise TimeLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 79 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 80 time.sleep(.001) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 81 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 82 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 83 from fcntl import FD_CLOEXEC | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 84 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 85 FD_CLOEXEC = 1 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 86 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 87 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 88 from resource import getrusage, RUSAGE_SELF, RUSAGE_CHILDREN | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 89 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 90 from time import clock as cpuclock | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 91 getrusage = lambda who: None | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 92 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 93 def cpuclock(): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 94 rusage = getrusage(RUSAGE_SELF) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 95 return rusage.ru_utime + rusage.ru_stime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 96 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 97 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 98 from resource import setrlimit | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 99 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 100 from resource import RLIMIT_AS | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 101 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 102 from resource import RLIMIT_VMEM | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 103 except ImportError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 104 setrlimit = None | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 105 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 106 # Make SIGCHLD interrupt sleep() and select() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 107 def bury_child(signum, frame): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 108 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 109 bury_child.case.time_stopped = clock() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 110 except Exception: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 111 pass | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 112 signal(SIGCHLD, bury_child) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 113 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 114 # If you want this to work portably, don't set any stdio argument to PIPE | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 115 def call(*args, **kwargs): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 116 global last_rusage | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 117 bury_child.case = case = kwargs.pop('case') | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 118 read, write = os.pipe() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 119 fcntl(write, F_SETFD, fcntl(write, F_GETFD) | FD_CLOEXEC) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 120 def preexec_fn(): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 121 os.close(read) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 122 if setrlimit and case.maxmemory: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 123 maxmemory = ceil(case.maxmemory * 1048576) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 124 setrlimit(RLIMIT_AS, (maxmemory, maxmemory)) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 125 # I would also set a CPU time limit but I do not want the time | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 126 # passing between the calls to fork and exec to be counted in | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 127 os.write(write, pickle.dumps((clock(), cpuclock()), 1)) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 128 kwargs['preexec_fn'] = preexec_fn | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 129 old_rusage = getrusage(RUSAGE_CHILDREN) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 130 last_rusage = None | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 131 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 132 case.process = Popen(*args, **kwargs) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 133 except OSError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 134 os.close(read) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 135 raise testcases.CannotStartTestee(sys.exc_info()[1]) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 136 finally: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 137 os.close(write) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 138 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 139 if not catch_escape: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 140 if case.maxwalltime: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 141 time.sleep(case.maxwalltime) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 142 if case.process.poll() is None: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 143 raise testcases.WallTimeLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 144 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 145 case.process.wait() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 146 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 147 if not case.maxwalltime: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 148 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 149 while case.process.poll() is None: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 150 if select((sys.stdin,), (), ())[0]: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 151 if sys.stdin.read(1) == '\33': | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 152 raise testcases.CanceledByUser | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 153 except SelectError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 154 if sys.exc_info()[1].args[0] != EINTR: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 155 raise | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 156 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 157 case.process.poll() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 158 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 159 time_end = clock() + case.maxwalltime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 160 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 161 while case.process.poll() is None: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 162 remaining = time_end - clock() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 163 if remaining > 0: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 164 if select((sys.stdin,), (), (), remaining)[0]: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 165 if sys.stdin.read(1) == '\33': | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 166 raise testcases.CanceledByUser | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 167 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 168 raise testcases.WallTimeLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 169 except SelectError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 170 if sys.exc_info()[1].args[0] != EINTR: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 171 raise | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 172 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 173 case.process.poll() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 174 finally: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 175 case.time_started, cpustart = pickle.loads(os.read(read, 512)) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 176 os.close(read) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 177 del bury_child.case | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 178 new_rusage = getrusage(RUSAGE_CHILDREN) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 179 if new_rusage and (case.maxcputime or not case.maxwalltime): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 180 case.time_started = cpustart | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 181 case.time_stopped = new_rusage.ru_utime + new_rusage.ru_stime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 182 case.time_limit_string = case.cpu_time_limit_string | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 183 if case.maxcputime and new_rusage: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 184 oldtime = old_rusage.ru_utime + old_rusage.ru_stime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 185 newtime = new_rusage.ru_utime + new_rusage.ru_stime | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 186 if newtime - oldtime - cpustart > case.maxcputime: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 187 raise testcases.CPUTimeLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 188 if case.maxmemory: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 189 if sys.platform != 'darwin': | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 190 maxrss = case.maxmemory * 1024 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 191 else: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 192 maxrss = case.maxmemory * 1048576 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 193 if last_rusage and last_rusage.ru_maxrss > maxrss: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 194 raise testcases.MemoryLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 195 elif (new_rusage and | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 196 new_rusage.ru_maxrss > old_rusage.ru_maxrss and | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 197 new_rusage.ru_maxrss > maxrss): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 198 raise testcases.MemoryLimitExceeded | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 199 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 200 # Emulate memory limits on platforms compatible with 4.3BSD but not XSI | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 201 # I say 'emulate' because the OS will allow excessive memory usage | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 202 # anyway; Upreckon will just treat the test case as not passed. | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 203 # To do this, we not only require os.wait4 to be present but also | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 204 # assume things about the implementation of subprocess.Popen. | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 205 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 206 def waitpid_emu(pid, options, _wait4=os.wait4): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 207 global last_rusage | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 208 pid, status, last_rusage = _wait4(pid, options) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 209 return pid, status | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 210 _waitpid = os.waitpid | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 211 os.waitpid = waitpid_emu | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 212 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 213 defaults = Popen._internal_poll.__func__.__defaults__ | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 214 except AttributeError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 215 # Python 2.5 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 216 defaults = Popen._internal_poll.im_func.func_defaults | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 217 i = defaults.index(_waitpid) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 218 defaults = defaults[:i] + (waitpid_emu,) + defaults[i+1:] | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 219 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 220 Popen._internal_poll.__func__.__defaults__ = defaults | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 221 except AttributeError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 222 # Python 2.5 again | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 223 Popen._internal_poll.im_func.func_defaults = defaults | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 224 except (AttributeError, ValueError): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 225 pass | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 226 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 227 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 228 def kill(process): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 229 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 230 process.kill() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 231 except AttributeError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 232 os.kill(process.pid, SIGKILL) | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 233 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 234 | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 235 def terminate(process): | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 236 try: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 237 process.terminate() | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 238 except AttributeError: | 
| 
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
 Oleg Oshmyan <chortos@inbox.lv> parents: diff
changeset | 239 os.kill(process.pid, SIGTERM) | 
