Mercurial > ~astiob > upreckon > hgweb
annotate unix.py @ 85:741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Thu, 24 Feb 2011 23:59:48 +0000 |
parents | 06356af50bf9 |
children | 8cd7a732f2f3 |
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 subprocess import Popen |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
14 import os, sys |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
15 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
16 try: |
85
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
17 from testcases import clock |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
18 except ImportError: |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
19 if sys.platform.startswith('java'): |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
20 from time import clock |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
21 else: |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
22 from time import time as clock |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
23 |
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
24 try: |
82
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
25 from signal import SIGTERM, SIGKILL |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
26 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
27 SIGTERM = 15 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
28 SIGKILL = 9 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
29 |
85
741ae3391b61
Moved clock/time detection into platform-specific modules and testcases
Oleg Oshmyan <chortos@inbox.lv>
parents:
82
diff
changeset
|
30 __all__ = 'call', 'kill', 'terminate', 'pause', 'clock' |
82
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
31 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
32 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
33 if not sys.stdin.isatty(): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
34 pause = lambda: sys.stdin.read(1) |
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 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
38 from select import select |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
39 import termios, tty, atexit |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
40 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
41 pause = None |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
42 catch_escape = False |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
43 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
44 catch_escape = True |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
45 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
|
46 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
|
47 atexit.register(cleanup) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
48 tty.setcbreak(sys.stdin.fileno()) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
49 def pause(): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
50 sys.stdin.read(1) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
51 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
52 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
53 from signal import SIGCHLD, signal, SIG_DFL |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
54 from select import select, error as SelectError |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
55 from errno import EINTR |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
56 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
|
57 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
58 import cPickle as pickle |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
59 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
60 import pickle |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
61 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
62 def call(*args, **kwargs): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
63 case = kwargs.pop('case') |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
64 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
65 case.process = Popen(*args, **kwargs) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
66 except OSError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
67 raise CannotStartTestee(sys.exc_info()[1]) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
68 case.time_started = clock() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
69 if not case.maxtime: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
70 while True: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
71 exitcode, now = case.process.poll(), clock() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
72 if exitcode is not None: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
73 case.time_stopped = now |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
74 break |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
75 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
76 time.sleep(.001) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
77 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
78 time_end = case.time_started + case.maxtime |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
79 while True: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
80 exitcode, now = case.process.poll(), clock() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
81 if exitcode is not None: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
82 case.time_stopped = now |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
83 break |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
84 elif now >= time_end: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
85 raise TimeLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
86 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
87 time.sleep(.001) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
88 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
89 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
90 from fcntl import FD_CLOEXEC |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
91 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
92 FD_CLOEXEC = 1 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
93 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
94 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
95 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
|
96 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
97 from time import clock as cpuclock |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
98 getrusage = lambda who: None |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
99 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
100 def cpuclock(): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
101 rusage = getrusage(RUSAGE_SELF) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
102 return rusage.ru_utime + rusage.ru_stime |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
103 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
104 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
105 from resource import setrlimit |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
106 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
107 from resource import RLIMIT_AS |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
108 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
109 from resource import RLIMIT_VMEM |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
110 except ImportError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
111 setrlimit = None |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
112 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
113 # Make SIGCHLD interrupt sleep() and select() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
114 def bury_child(signum, frame): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
115 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
116 bury_child.case.time_stopped = clock() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
117 except Exception: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
118 pass |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
119 signal(SIGCHLD, bury_child) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
120 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
121 # 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
|
122 def call(*args, **kwargs): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
123 global last_rusage |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
124 bury_child.case = case = kwargs.pop('case') |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
125 read, write = os.pipe() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
126 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
|
127 def preexec_fn(): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
128 os.close(read) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
129 if setrlimit and case.maxmemory: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
130 maxmemory = ceil(case.maxmemory * 1048576) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
131 setrlimit(RLIMIT_AS, (maxmemory, maxmemory)) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
132 # 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
|
133 # 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
|
134 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
|
135 kwargs['preexec_fn'] = preexec_fn |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
136 old_rusage = getrusage(RUSAGE_CHILDREN) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
137 last_rusage = None |
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 case.process = Popen(*args, **kwargs) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
140 except OSError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
141 os.close(read) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
142 raise testcases.CannotStartTestee(sys.exc_info()[1]) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
143 finally: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
144 os.close(write) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
145 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
146 if not catch_escape: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
147 if case.maxwalltime: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
148 time.sleep(case.maxwalltime) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
149 if case.process.poll() is None: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
150 raise testcases.WallTimeLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
151 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
152 case.process.wait() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
153 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
154 if not case.maxwalltime: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
155 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
156 while case.process.poll() is None: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
157 if select((sys.stdin,), (), ())[0]: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
158 if sys.stdin.read(1) == '\33': |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
159 raise testcases.CanceledByUser |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
160 except SelectError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
161 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
|
162 raise |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
163 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
164 case.process.poll() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
165 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
166 time_end = clock() + case.maxwalltime |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
167 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
168 while case.process.poll() is None: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
169 remaining = time_end - clock() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
170 if remaining > 0: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
171 if select((sys.stdin,), (), (), remaining)[0]: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
172 if sys.stdin.read(1) == '\33': |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
173 raise testcases.CanceledByUser |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
174 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
175 raise testcases.WallTimeLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
176 except SelectError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
177 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
|
178 raise |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
179 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
180 case.process.poll() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
181 finally: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
182 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
|
183 os.close(read) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
184 del bury_child.case |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
185 new_rusage = getrusage(RUSAGE_CHILDREN) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
186 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
|
187 case.time_started = cpustart |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
188 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
|
189 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
|
190 if case.maxcputime and new_rusage: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
191 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
|
192 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
|
193 if newtime - oldtime - cpustart > case.maxcputime: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
194 raise testcases.CPUTimeLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
195 if case.maxmemory: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
196 if sys.platform != 'darwin': |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
197 maxrss = case.maxmemory * 1024 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
198 else: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
199 maxrss = case.maxmemory * 1048576 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
200 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
|
201 raise testcases.MemoryLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
202 elif (new_rusage and |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
203 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
|
204 new_rusage.ru_maxrss > maxrss): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
205 raise testcases.MemoryLimitExceeded |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
206 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
207 # 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
|
208 # 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
|
209 # 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
|
210 # 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
|
211 # 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
|
212 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
213 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
|
214 global last_rusage |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
215 pid, status, last_rusage = _wait4(pid, options) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
216 return pid, status |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
217 _waitpid = os.waitpid |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
218 os.waitpid = waitpid_emu |
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 defaults = Popen._internal_poll.__func__.__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 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
223 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
|
224 i = defaults.index(_waitpid) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
225 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
|
226 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
227 Popen._internal_poll.__func__.__defaults__ = defaults |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
228 except AttributeError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
229 # Python 2.5 again |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
230 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
|
231 except (AttributeError, ValueError): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
232 pass |
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 kill(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.kill() |
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, SIGKILL) |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
240 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
241 |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
242 def terminate(process): |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
243 try: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
244 process.terminate() |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
245 except AttributeError: |
06356af50bf9
Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff
changeset
|
246 os.kill(process.pid, SIGTERM) |