|
11 | 11 | import unittest |
12 | 12 | from test import support |
13 | 13 | from contextlib import closing |
14 | | -from test.script_helper import spawn_python |
| 14 | +from test.script_helper import assert_python_ok, spawn_python |
15 | 15 |
|
16 | 16 | if sys.platform in ('os2', 'riscos'): |
17 | 17 | raise unittest.SkipTest("Can't test signal on %s" % sys.platform) |
@@ -233,49 +233,80 @@ def test_issue9324(self): |
233 | 233 |
|
234 | 234 | @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") |
235 | 235 | class WakeupSignalTests(unittest.TestCase): |
236 | | - TIMEOUT_FULL = 10 |
237 | | - TIMEOUT_HALF = 5 |
| 236 | + def check_wakeup(self, test_body): |
| 237 | + # use a subprocess to have only one thread and to not change signal |
| 238 | + # handling of the parent process |
| 239 | + code = """if 1: |
| 240 | + import fcntl |
| 241 | + import os |
| 242 | + import signal |
| 243 | +
|
| 244 | + def handler(signum, frame): |
| 245 | + pass |
| 246 | +
|
| 247 | + {} |
| 248 | +
|
| 249 | + signal.signal(signal.SIGALRM, handler) |
| 250 | + read, write = os.pipe() |
| 251 | + flags = fcntl.fcntl(write, fcntl.F_GETFL, 0) |
| 252 | + flags = flags | os.O_NONBLOCK |
| 253 | + fcntl.fcntl(write, fcntl.F_SETFL, flags) |
| 254 | + signal.set_wakeup_fd(write) |
| 255 | +
|
| 256 | + test() |
| 257 | +
|
| 258 | + os.close(read) |
| 259 | + os.close(write) |
| 260 | + """.format(test_body) |
| 261 | + |
| 262 | + assert_python_ok('-c', code) |
238 | 263 |
|
239 | 264 | def test_wakeup_fd_early(self): |
240 | | - import select |
241 | | - |
242 | | - signal.alarm(1) |
243 | | - before_time = time.time() |
244 | | - # We attempt to get a signal during the sleep, |
245 | | - # before select is called |
246 | | - time.sleep(self.TIMEOUT_FULL) |
247 | | - mid_time = time.time() |
248 | | - self.assertTrue(mid_time - before_time < self.TIMEOUT_HALF) |
249 | | - select.select([self.read], [], [], self.TIMEOUT_FULL) |
250 | | - after_time = time.time() |
251 | | - self.assertTrue(after_time - mid_time < self.TIMEOUT_HALF) |
| 265 | + self.check_wakeup("""def test(): |
| 266 | + import select |
| 267 | + import time |
252 | 268 |
|
253 | | - def test_wakeup_fd_during(self): |
254 | | - import select |
| 269 | + TIMEOUT_FULL = 10 |
| 270 | + TIMEOUT_HALF = 5 |
255 | 271 |
|
256 | | - signal.alarm(1) |
257 | | - before_time = time.time() |
258 | | - # We attempt to get a signal during the select call |
259 | | - self.assertRaises(select.error, select.select, |
260 | | - [self.read], [], [], self.TIMEOUT_FULL) |
261 | | - after_time = time.time() |
262 | | - self.assertTrue(after_time - before_time < self.TIMEOUT_HALF) |
| 272 | + signal.alarm(1) |
| 273 | + before_time = time.time() |
| 274 | + # We attempt to get a signal during the sleep, |
| 275 | + # before select is called |
| 276 | + time.sleep(TIMEOUT_FULL) |
| 277 | + mid_time = time.time() |
| 278 | + dt = mid_time - before_time |
| 279 | + if dt >= TIMEOUT_HALF: |
| 280 | + raise Exception("%s >= %s" % (dt, TIMEOUT_HALF)) |
| 281 | + select.select([read], [], [], TIMEOUT_FULL) |
| 282 | + after_time = time.time() |
| 283 | + dt = after_time - mid_time |
| 284 | + if dt >= TIMEOUT_HALF: |
| 285 | + raise Exception("%s >= %s" % (dt, TIMEOUT_HALF)) |
| 286 | + """) |
263 | 287 |
|
264 | | - def setUp(self): |
265 | | - import fcntl |
| 288 | + def test_wakeup_fd_during(self): |
| 289 | + self.check_wakeup("""def test(): |
| 290 | + import select |
| 291 | + import time |
266 | 292 |
|
267 | | - self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None) |
268 | | - self.read, self.write = os.pipe() |
269 | | - flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0) |
270 | | - flags = flags | os.O_NONBLOCK |
271 | | - fcntl.fcntl(self.write, fcntl.F_SETFL, flags) |
272 | | - self.old_wakeup = signal.set_wakeup_fd(self.write) |
| 293 | + TIMEOUT_FULL = 10 |
| 294 | + TIMEOUT_HALF = 5 |
273 | 295 |
|
274 | | - def tearDown(self): |
275 | | - signal.set_wakeup_fd(self.old_wakeup) |
276 | | - os.close(self.read) |
277 | | - os.close(self.write) |
278 | | - signal.signal(signal.SIGALRM, self.alrm) |
| 296 | + signal.alarm(1) |
| 297 | + before_time = time.time() |
| 298 | + # We attempt to get a signal during the select call |
| 299 | + try: |
| 300 | + select.select([read], [], [], TIMEOUT_FULL) |
| 301 | + except select.error: |
| 302 | + pass |
| 303 | + else: |
| 304 | + raise Exception("select.error not raised") |
| 305 | + after_time = time.time() |
| 306 | + dt = after_time - before_time |
| 307 | + if dt >= TIMEOUT_HALF: |
| 308 | + raise Exception("%s >= %s" % (dt, TIMEOUT_HALF)) |
| 309 | + """) |
279 | 310 |
|
280 | 311 | @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") |
281 | 312 | class SiginterruptTest(unittest.TestCase): |
|
0 commit comments