Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(169945)

Delta Between Two Patch Sets: Lib/test/_test_multiprocessing.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 6 years ago
Right Patch Set: Created 5 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_module.py ('k') | Lib/test/test_os.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #!/usr/bin/env python3
2
3 # 1 #
4 # Unit tests for the multiprocessing package 2 # Unit tests for the multiprocessing package
5 # 3 #
6 4
7 import unittest 5 import unittest
8 import queue as pyqueue 6 import queue as pyqueue
9 import time 7 import time
10 import io 8 import io
11 import itertools 9 import itertools
12 import sys 10 import sys
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 # 189 #
192 # Testcases 190 # Testcases
193 # 191 #
194 192
195 class _TestProcess(BaseTestCase): 193 class _TestProcess(BaseTestCase):
196 194
197 ALLOWED_TYPES = ('processes', 'threads') 195 ALLOWED_TYPES = ('processes', 'threads')
198 196
199 def test_current(self): 197 def test_current(self):
200 if self.TYPE == 'threads': 198 if self.TYPE == 'threads':
201 return 199 self.skipTest('test not appropriate for {}'.format(self.TYPE))
202 200
203 current = self.current_process() 201 current = self.current_process()
204 authkey = current.authkey 202 authkey = current.authkey
205 203
206 self.assertTrue(current.is_alive()) 204 self.assertTrue(current.is_alive())
207 self.assertFalse(current.daemon) 205 self.assertFalse(current.daemon)
208 self.assertIsInstance(authkey, bytes) 206 self.assertIsInstance(authkey, bytes)
209 self.assertGreater(len(authkey), 0) 207 self.assertGreater(len(authkey), 0)
210 self.assertEqual(current.ident, os.getpid()) 208 self.assertEqual(current.ident, os.getpid())
211 self.assertEqual(current.exitcode, None) 209 self.assertEqual(current.exitcode, None)
212 210
213 def test_daemon_argument(self): 211 def test_daemon_argument(self):
214 if self.TYPE == "threads": 212 if self.TYPE == "threads":
215 return 213 self.skipTest('test not appropriate for {}'.format(self.TYPE))
216 214
217 # By default uses the current process's daemon flag. 215 # By default uses the current process's daemon flag.
218 proc0 = self.Process(target=self._test) 216 proc0 = self.Process(target=self._test)
219 self.assertEqual(proc0.daemon, self.current_process().daemon) 217 self.assertEqual(proc0.daemon, self.current_process().daemon)
220 proc1 = self.Process(target=self._test, daemon=True) 218 proc1 = self.Process(target=self._test, daemon=True)
221 self.assertTrue(proc1.daemon) 219 self.assertTrue(proc1.daemon)
222 proc2 = self.Process(target=self._test, daemon=False) 220 proc2 = self.Process(target=self._test, daemon=False)
223 self.assertFalse(proc2.daemon) 221 self.assertFalse(proc2.daemon)
224 222
225 @classmethod 223 @classmethod
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 self.assertEqual(p.exitcode, 0) 268 self.assertEqual(p.exitcode, 0)
271 self.assertEqual(p.is_alive(), False) 269 self.assertEqual(p.is_alive(), False)
272 self.assertNotIn(p, self.active_children()) 270 self.assertNotIn(p, self.active_children())
273 271
274 @classmethod 272 @classmethod
275 def _test_terminate(cls): 273 def _test_terminate(cls):
276 time.sleep(100) 274 time.sleep(100)
277 275
278 def test_terminate(self): 276 def test_terminate(self):
279 if self.TYPE == 'threads': 277 if self.TYPE == 'threads':
280 return 278 self.skipTest('test not appropriate for {}'.format(self.TYPE))
281 279
282 p = self.Process(target=self._test_terminate) 280 p = self.Process(target=self._test_terminate)
283 p.daemon = True 281 p.daemon = True
284 p.start() 282 p.start()
285 283
286 self.assertEqual(p.is_alive(), True) 284 self.assertEqual(p.is_alive(), True)
287 self.assertIn(p, self.active_children()) 285 self.assertIn(p, self.active_children())
288 self.assertEqual(p.exitcode, None) 286 self.assertEqual(p.exitcode, None)
289 287
290 join = TimingWrapper(p.join) 288 join = TimingWrapper(p.join)
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 [1, 1] 376 [1, 1]
379 ] 377 ]
380 self.assertEqual(result, expected) 378 self.assertEqual(result, expected)
381 379
382 @classmethod 380 @classmethod
383 def _test_sentinel(cls, event): 381 def _test_sentinel(cls, event):
384 event.wait(10.0) 382 event.wait(10.0)
385 383
386 def test_sentinel(self): 384 def test_sentinel(self):
387 if self.TYPE == "threads": 385 if self.TYPE == "threads":
388 return 386 self.skipTest('test not appropriate for {}'.format(self.TYPE))
389 event = self.Event() 387 event = self.Event()
390 p = self.Process(target=self._test_sentinel, args=(event,)) 388 p = self.Process(target=self._test_sentinel, args=(event,))
391 with self.assertRaises(ValueError): 389 with self.assertRaises(ValueError):
392 p.sentinel 390 p.sentinel
393 p.start() 391 p.start()
394 self.addCleanup(p.join) 392 self.addCleanup(p.join)
395 sentinel = p.sentinel 393 sentinel = p.sentinel
396 self.assertIsInstance(sentinel, int) 394 self.assertIsInstance(sentinel, int)
397 self.assertFalse(wait_for_handle(sentinel, timeout=0.0)) 395 self.assertFalse(wait_for_handle(sentinel, timeout=0.0))
398 event.set() 396 event.set()
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 uppercaser.daemon = True 432 uppercaser.daemon = True
435 uppercaser.start() 433 uppercaser.start()
436 self.assertEqual(uppercaser.submit('hello'), 'HELLO') 434 self.assertEqual(uppercaser.submit('hello'), 'HELLO')
437 self.assertEqual(uppercaser.submit('world'), 'WORLD') 435 self.assertEqual(uppercaser.submit('world'), 'WORLD')
438 uppercaser.stop() 436 uppercaser.stop()
439 uppercaser.join() 437 uppercaser.join()
440 438
441 def test_stderr_flush(self): 439 def test_stderr_flush(self):
442 # sys.stderr is flushed at process shutdown (issue #13812) 440 # sys.stderr is flushed at process shutdown (issue #13812)
443 if self.TYPE == "threads": 441 if self.TYPE == "threads":
444 return 442 self.skipTest('test not appropriate for {}'.format(self.TYPE))
445 443
446 testfn = test.support.TESTFN 444 testfn = test.support.TESTFN
447 self.addCleanup(test.support.unlink, testfn) 445 self.addCleanup(test.support.unlink, testfn)
448 proc = self.Process(target=self._test_stderr_flush, args=(testfn,)) 446 proc = self.Process(target=self._test_stderr_flush, args=(testfn,))
449 proc.start() 447 proc.start()
450 proc.join() 448 proc.join()
451 with open(testfn, 'r') as f: 449 with open(testfn, 'r') as f:
452 err = f.read() 450 err = f.read()
453 # The whole traceback was printed 451 # The whole traceback was printed
454 self.assertIn("ZeroDivisionError", err) 452 self.assertIn("ZeroDivisionError", err)
455 self.assertIn("test_multiprocessing.py", err) 453 self.assertIn("test_multiprocessing.py", err)
456 self.assertIn("1/0 # MARKER", err) 454 self.assertIn("1/0 # MARKER", err)
457 455
458 @classmethod 456 @classmethod
459 def _test_stderr_flush(cls, testfn): 457 def _test_stderr_flush(cls, testfn):
460 sys.stderr = open(testfn, 'w') 458 sys.stderr = open(testfn, 'w')
461 1/0 # MARKER 459 1/0 # MARKER
462 460
463 461
464 @classmethod 462 @classmethod
465 def _test_sys_exit(cls, reason, testfn): 463 def _test_sys_exit(cls, reason, testfn):
466 sys.stderr = open(testfn, 'w') 464 sys.stderr = open(testfn, 'w')
467 sys.exit(reason) 465 sys.exit(reason)
468 466
469 def test_sys_exit(self): 467 def test_sys_exit(self):
470 # See Issue 13854 468 # See Issue 13854
471 if self.TYPE == 'threads': 469 if self.TYPE == 'threads':
472 return 470 self.skipTest('test not appropriate for {}'.format(self.TYPE))
473 471
474 testfn = test.support.TESTFN 472 testfn = test.support.TESTFN
475 self.addCleanup(test.support.unlink, testfn) 473 self.addCleanup(test.support.unlink, testfn)
476 474
477 for reason, code in (([1, 2, 3], 1), ('ignore this', 0)): 475 for reason, code in (([1, 2, 3], 1), ('ignore this', 1)):
478 p = self.Process(target=self._test_sys_exit, args=(reason, testfn)) 476 p = self.Process(target=self._test_sys_exit, args=(reason, testfn))
479 p.daemon = True 477 p.daemon = True
480 p.start() 478 p.start()
481 p.join(5) 479 p.join(5)
482 self.assertEqual(p.exitcode, code) 480 self.assertEqual(p.exitcode, code)
483 481
484 with open(testfn, 'r') as f: 482 with open(testfn, 'r') as f:
485 self.assertEqual(f.read().rstrip(), str(reason)) 483 self.assertEqual(f.read().rstrip(), str(reason))
486 484
487 for reason in (True, False, 8): 485 for reason in (True, False, 8):
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 self.assertEqual(queue.get(), i) 669 self.assertEqual(queue.get(), i)
672 self.assertRaises(pyqueue.Empty, queue.get, False) 670 self.assertRaises(pyqueue.Empty, queue.get, False)
673 671
674 p.join() 672 p.join()
675 673
676 def test_qsize(self): 674 def test_qsize(self):
677 q = self.Queue() 675 q = self.Queue()
678 try: 676 try:
679 self.assertEqual(q.qsize(), 0) 677 self.assertEqual(q.qsize(), 0)
680 except NotImplementedError: 678 except NotImplementedError:
681 return 679 self.skipTest('qsize method not implemented')
682 q.put(1) 680 q.put(1)
683 self.assertEqual(q.qsize(), 1) 681 self.assertEqual(q.qsize(), 1)
684 q.put(5) 682 q.put(5)
685 self.assertEqual(q.qsize(), 2) 683 self.assertEqual(q.qsize(), 2)
686 q.get() 684 q.get()
687 self.assertEqual(q.qsize(), 1) 685 self.assertEqual(q.qsize(), 1)
688 q.get() 686 q.get()
689 self.assertEqual(q.qsize(), 0) 687 self.assertEqual(q.qsize(), 0)
690 688
691 @classmethod 689 @classmethod
692 def _test_task_done(cls, q): 690 def _test_task_done(cls, q):
693 for obj in iter(q.get, None): 691 for obj in iter(q.get, None):
694 time.sleep(DELTA) 692 time.sleep(DELTA)
695 q.task_done() 693 q.task_done()
696 694
697 def test_task_done(self): 695 def test_task_done(self):
698 queue = self.JoinableQueue() 696 queue = self.JoinableQueue()
699
700 if sys.version_info < (2, 5) and not hasattr(queue, 'task_done'):
701 self.skipTest("requires 'queue.task_done()' method")
702 697
703 workers = [self.Process(target=self._test_task_done, args=(queue,)) 698 workers = [self.Process(target=self._test_task_done, args=(queue,))
704 for i in range(4)] 699 for i in range(4)]
705 700
706 for p in workers: 701 for p in workers:
707 p.daemon = True 702 p.daemon = True
708 p.start() 703 p.start()
709 704
710 for i in range(10): 705 for i in range(10):
711 queue.put(i) 706 queue.put(i)
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 def test_bounded_semaphore(self): 774 def test_bounded_semaphore(self):
780 sem = self.BoundedSemaphore(2) 775 sem = self.BoundedSemaphore(2)
781 self._test_semaphore(sem) 776 self._test_semaphore(sem)
782 # Currently fails on OS/X 777 # Currently fails on OS/X
783 #if HAVE_GETVALUE: 778 #if HAVE_GETVALUE:
784 # self.assertRaises(ValueError, sem.release) 779 # self.assertRaises(ValueError, sem.release)
785 # self.assertReturnsIfImplemented(2, get_value, sem) 780 # self.assertReturnsIfImplemented(2, get_value, sem)
786 781
787 def test_timeout(self): 782 def test_timeout(self):
788 if self.TYPE != 'processes': 783 if self.TYPE != 'processes':
789 return 784 self.skipTest('test not appropriate for {}'.format(self.TYPE))
790 785
791 sem = self.Semaphore(0) 786 sem = self.Semaphore(0)
792 acquire = TimingWrapper(sem.acquire) 787 acquire = TimingWrapper(sem.acquire)
793 788
794 self.assertEqual(acquire(False), False) 789 self.assertEqual(acquire(False), False)
795 self.assertTimingAlmostEqual(acquire.elapsed, 0.0) 790 self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
796 791
797 self.assertEqual(acquire(False, None), False) 792 self.assertEqual(acquire(False, None), False)
798 self.assertTimingAlmostEqual(acquire.elapsed, 0.0) 793 self.assertTimingAlmostEqual(acquire.elapsed, 0.0)
799 794
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 1394
1400 @classmethod 1395 @classmethod
1401 def _test_thousand_f(cls, barrier, passes, conn, lock): 1396 def _test_thousand_f(cls, barrier, passes, conn, lock):
1402 for i in range(passes): 1397 for i in range(passes):
1403 barrier.wait() 1398 barrier.wait()
1404 with lock: 1399 with lock:
1405 conn.send(i) 1400 conn.send(i)
1406 1401
1407 def test_thousand(self): 1402 def test_thousand(self):
1408 if self.TYPE == 'manager': 1403 if self.TYPE == 'manager':
1409 return 1404 self.skipTest('test not appropriate for {}'.format(self.TYPE))
1410 passes = 1000 1405 passes = 1000
1411 lock = self.Lock() 1406 lock = self.Lock()
1412 conn, child_conn = self.Pipe(False) 1407 conn, child_conn = self.Pipe(False)
1413 for j in range(self.N): 1408 for j in range(self.N):
1414 p = self.Process(target=self._test_thousand_f, 1409 p = self.Process(target=self._test_thousand_f,
1415 args=(self.barrier, passes, child_conn, lock)) 1410 args=(self.barrier, passes, child_conn, lock))
1416 p.start() 1411 p.start()
1417 1412
1418 for i in range(passes): 1413 for i in range(passes):
1419 for j in range(self.N): 1414 for j in range(self.N):
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 self.assertEqual([1], call_args[0]) 1689 self.assertEqual([1], call_args[0])
1695 self.pool.map_async(int, ['a'], 1690 self.pool.map_async(int, ['a'],
1696 callback=call_args.append, 1691 callback=call_args.append,
1697 error_callback=call_args.append).wait() 1692 error_callback=call_args.append).wait()
1698 self.assertEqual(2, len(call_args)) 1693 self.assertEqual(2, len(call_args))
1699 self.assertIsInstance(call_args[1], ValueError) 1694 self.assertIsInstance(call_args[1], ValueError)
1700 1695
1701 def test_map_unplicklable(self): 1696 def test_map_unplicklable(self):
1702 # Issue #19425 -- failure to pickle should not cause a hang 1697 # Issue #19425 -- failure to pickle should not cause a hang
1703 if self.TYPE == 'threads': 1698 if self.TYPE == 'threads':
1704 return 1699 self.skipTest('test not appropriate for {}'.format(self.TYPE))
1705 class A(object): 1700 class A(object):
1706 def __reduce__(self): 1701 def __reduce__(self):
1707 raise RuntimeError('cannot pickle') 1702 raise RuntimeError('cannot pickle')
1708 with self.assertRaises(RuntimeError): 1703 with self.assertRaises(RuntimeError):
1709 self.pool.map(sqr, [A()]*10) 1704 self.pool.map(sqr, [A()]*10)
1710 1705
1711 def test_map_chunksize(self): 1706 def test_map_chunksize(self):
1712 try: 1707 try:
1713 self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1) 1708 self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)
1714 except multiprocessing.TimeoutError: 1709 except multiprocessing.TimeoutError:
1715 self.fail("pool.map_async with chunksize stalled on null list") 1710 self.fail("pool.map_async with chunksize stalled on null list")
1716 1711
1717 def test_async(self): 1712 def test_async(self):
1718 res = self.pool.apply_async(sqr, (7, TIMEOUT1,)) 1713 res = self.pool.apply_async(sqr, (7, TIMEOUT1,))
1719 get = TimingWrapper(res.get) 1714 get = TimingWrapper(res.get)
1720 self.assertEqual(get(), 49) 1715 self.assertEqual(get(), 49)
1721 self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1) 1716 self.assertTimingAlmostEqual(get.elapsed, TIMEOUT1)
1722 1717
1723 def test_async_timeout(self): 1718 def test_async_timeout(self):
1724 res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 0.2)) 1719 res = self.pool.apply_async(sqr, (6, TIMEOUT2 + 1.0))
1725 get = TimingWrapper(res.get) 1720 get = TimingWrapper(res.get)
1726 self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2) 1721 self.assertRaises(multiprocessing.TimeoutError, get, timeout=TIMEOUT2)
1727 self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2) 1722 self.assertTimingAlmostEqual(get.elapsed, TIMEOUT2)
1728 1723
1729 def test_imap(self): 1724 def test_imap(self):
1730 it = self.pool.imap(sqr, list(range(10))) 1725 it = self.pool.imap(sqr, list(range(10)))
1731 self.assertEqual(list(it), list(map(sqr, list(range(10))))) 1726 self.assertEqual(list(it), list(map(sqr, list(range(10)))))
1732 1727
1733 it = self.pool.imap(sqr, list(range(10))) 1728 it = self.pool.imap(sqr, list(range(10)))
1734 for i in range(10): 1729 for i in range(10):
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 msg = latin('hello') 2212 msg = latin('hello')
2218 conn.send_bytes(msg) 2213 conn.send_bytes(msg)
2219 self.assertEqual(conn.recv_bytes(), msg) 2214 self.assertEqual(conn.recv_bytes(), msg)
2220 2215
2221 conn.send_bytes(SENTINEL) 2216 conn.send_bytes(SENTINEL)
2222 conn.close() 2217 conn.close()
2223 p.join() 2218 p.join()
2224 2219
2225 def test_sendbytes(self): 2220 def test_sendbytes(self):
2226 if self.TYPE != 'processes': 2221 if self.TYPE != 'processes':
2227 return 2222 self.skipTest('test not appropriate for {}'.format(self.TYPE))
2228 2223
2229 msg = latin('abcdefghijklmnopqrstuvwxyz') 2224 msg = latin('abcdefghijklmnopqrstuvwxyz')
2230 a, b = self.Pipe() 2225 a, b = self.Pipe()
2231 2226
2232 a.send_bytes(msg) 2227 a.send_bytes(msg)
2233 self.assertEqual(b.recv_bytes(), msg) 2228 self.assertEqual(b.recv_bytes(), msg)
2234 2229
2235 a.send_bytes(msg, 5) 2230 a.send_bytes(msg, 5)
2236 self.assertEqual(b.recv_bytes(), msg[5:]) 2231 self.assertEqual(b.recv_bytes(), msg[5:])
2237 2232
(...skipping 1588 matching lines...) Expand 10 before | Expand all | Expand 10 after
3826 tmp = set(multiprocessing.process._dangling) - set(dangling[0]) 3821 tmp = set(multiprocessing.process._dangling) - set(dangling[0])
3827 if tmp: 3822 if tmp:
3828 print('Dangling processes:', tmp, file=sys.stderr) 3823 print('Dangling processes:', tmp, file=sys.stderr)
3829 del tmp 3824 del tmp
3830 tmp = set(threading._dangling) - set(dangling[1]) 3825 tmp = set(threading._dangling) - set(dangling[1])
3831 if tmp: 3826 if tmp:
3832 print('Dangling threads:', tmp, file=sys.stderr) 3827 print('Dangling threads:', tmp, file=sys.stderr)
3833 3828
3834 remote_globs['setUpModule'] = setUpModule 3829 remote_globs['setUpModule'] = setUpModule
3835 remote_globs['tearDownModule'] = tearDownModule 3830 remote_globs['tearDownModule'] = tearDownModule
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+