Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 1 | """Generic thread tests. |
| 2 | |
| 3 | Meant to be used by dummy_thread and thread. To allow for different modules |
| 4 | to be used, test_main() can be called with the module to use as the thread |
| 5 | implementation as its sole argument. |
| 6 | |
| 7 | """ |
Georg Brandl | 2067bfd | 2008-05-25 13:05:15 +0000 | [diff] [blame] | 8 | import _dummy_thread as _thread |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 9 | import time |
Alexandre Vassalotti | f260e44 | 2008-05-11 19:59:59 +0000 | [diff] [blame] | 10 | import queue |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 11 | import random |
| 12 | import unittest |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 13 | from test import support |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 14 | |
Georg Brandl | 2067bfd | 2008-05-25 13:05:15 +0000 | [diff] [blame] | 15 | DELAY = 0 # Set > 0 when testing a module other than _dummy_thread, such as |
| 16 | # the '_thread' module. |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 17 | |
| 18 | class LockTests(unittest.TestCase): |
| 19 | """Test lock objects.""" |
| 20 | |
| 21 | def setUp(self): |
| 22 | # Create a lock |
| 23 | self.lock = _thread.allocate_lock() |
| 24 | |
| 25 | def test_initlock(self): |
| 26 | #Make sure locks start locked |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 27 | self.assertFalse(self.lock.locked(), |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 28 | "Lock object is not initialized unlocked.") |
| 29 | |
| 30 | def test_release(self): |
| 31 | # Test self.lock.release() |
| 32 | self.lock.acquire() |
| 33 | self.lock.release() |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 34 | self.assertFalse(self.lock.locked(), |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 35 | "Lock object did not release properly.") |
Tim Peters | f2715e0 | 2003-02-19 02:35:07 +0000 | [diff] [blame] | 36 | |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 37 | def test_improper_release(self): |
Antoine Pitrou | 819c40f | 2011-03-01 23:05:42 +0000 | [diff] [blame] | 38 | #Make sure release of an unlocked thread raises RuntimeError |
| 39 | self.assertRaises(RuntimeError, self.lock.release) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 40 | |
| 41 | def test_cond_acquire_success(self): |
| 42 | #Make sure the conditional acquiring of the lock works. |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 43 | self.assertTrue(self.lock.acquire(0), |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 44 | "Conditional acquiring of the lock failed.") |
| 45 | |
| 46 | def test_cond_acquire_fail(self): |
| 47 | #Test acquiring locked lock returns False |
| 48 | self.lock.acquire(0) |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 49 | self.assertFalse(self.lock.acquire(0), |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 50 | "Conditional acquiring of a locked lock incorrectly " |
| 51 | "succeeded.") |
| 52 | |
| 53 | def test_uncond_acquire_success(self): |
| 54 | #Make sure unconditional acquiring of a lock works. |
| 55 | self.lock.acquire() |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 56 | self.assertTrue(self.lock.locked(), |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 57 | "Uncondional locking failed.") |
| 58 | |
| 59 | def test_uncond_acquire_return_val(self): |
| 60 | #Make sure that an unconditional locking returns True. |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 61 | self.assertIs(self.lock.acquire(1), True, |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 62 | "Unconditional locking did not return True.") |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 63 | self.assertIs(self.lock.acquire(), True) |
Tim Peters | f2715e0 | 2003-02-19 02:35:07 +0000 | [diff] [blame] | 64 | |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 65 | def test_uncond_acquire_blocking(self): |
| 66 | #Make sure that unconditional acquiring of a locked lock blocks. |
| 67 | def delay_unlock(to_unlock, delay): |
| 68 | """Hold on to lock for a set amount of time before unlocking.""" |
| 69 | time.sleep(delay) |
| 70 | to_unlock.release() |
| 71 | |
| 72 | self.lock.acquire() |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 73 | start_time = int(time.time()) |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 74 | _thread.start_new_thread(delay_unlock,(self.lock, DELAY)) |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 75 | if support.verbose: |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 76 | print() |
| 77 | print("*** Waiting for thread to release the lock "\ |
| 78 | "(approx. %s sec.) ***" % DELAY) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 79 | self.lock.acquire() |
| 80 | end_time = int(time.time()) |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 81 | if support.verbose: |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 82 | print("done") |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 83 | self.assertGreaterEqual(end_time - start_time, DELAY, |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 84 | "Blocking by unconditional acquiring failed.") |
| 85 | |
| 86 | class MiscTests(unittest.TestCase): |
| 87 | """Miscellaneous tests.""" |
| 88 | |
| 89 | def test_exit(self): |
| 90 | #Make sure _thread.exit() raises SystemExit |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 91 | self.assertRaises(SystemExit, _thread.exit) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 92 | |
| 93 | def test_ident(self): |
| 94 | #Test sanity of _thread.get_ident() |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 95 | self.assertIsInstance(_thread.get_ident(), int, |
| 96 | "_thread.get_ident() returned a non-integer") |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 97 | self.assertNotEqual(_thread.get_ident(), 0, |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 98 | "_thread.get_ident() returned 0") |
| 99 | |
| 100 | def test_LockType(self): |
| 101 | #Make sure _thread.LockType is the same type as _thread.allocate_locke() |
Ezio Melotti | e961593 | 2010-01-24 19:26:24 +0000 | [diff] [blame] | 102 | self.assertIsInstance(_thread.allocate_lock(), _thread.LockType, |
| 103 | "_thread.LockType is not an instance of what " |
| 104 | "is returned by _thread.allocate_lock()") |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 105 | |
Brett Cannon | 4e64d78 | 2003-06-13 23:44:35 +0000 | [diff] [blame] | 106 | def test_interrupt_main(self): |
| 107 | #Calling start_new_thread with a function that executes interrupt_main |
| 108 | # should raise KeyboardInterrupt upon completion. |
| 109 | def call_interrupt(): |
| 110 | _thread.interrupt_main() |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 111 | self.assertRaises(KeyboardInterrupt, _thread.start_new_thread, |
Brett Cannon | 4e64d78 | 2003-06-13 23:44:35 +0000 | [diff] [blame] | 112 | call_interrupt, tuple()) |
Tim Peters | f545baa | 2003-06-15 23:26:30 +0000 | [diff] [blame] | 113 | |
Brett Cannon | 91012fe | 2003-06-13 23:56:32 +0000 | [diff] [blame] | 114 | def test_interrupt_in_main(self): |
| 115 | # Make sure that if interrupt_main is called in main threat that |
| 116 | # KeyboardInterrupt is raised instantly. |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 117 | self.assertRaises(KeyboardInterrupt, _thread.interrupt_main) |
Brett Cannon | 4e64d78 | 2003-06-13 23:44:35 +0000 | [diff] [blame] | 118 | |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 119 | class ThreadTests(unittest.TestCase): |
| 120 | """Test thread creation.""" |
| 121 | |
| 122 | def test_arg_passing(self): |
| 123 | #Make sure that parameter passing works. |
| 124 | def arg_tester(queue, arg1=False, arg2=False): |
| 125 | """Use to test _thread.start_new_thread() passes args properly.""" |
| 126 | queue.put((arg1, arg2)) |
| 127 | |
Alexandre Vassalotti | f260e44 | 2008-05-11 19:59:59 +0000 | [diff] [blame] | 128 | testing_queue = queue.Queue(1) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 129 | _thread.start_new_thread(arg_tester, (testing_queue, True, True)) |
| 130 | result = testing_queue.get() |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 131 | self.assertTrue(result[0] and result[1], |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 132 | "Argument passing for thread creation using tuple failed") |
| 133 | _thread.start_new_thread(arg_tester, tuple(), {'queue':testing_queue, |
| 134 | 'arg1':True, 'arg2':True}) |
| 135 | result = testing_queue.get() |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 136 | self.assertTrue(result[0] and result[1], |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 137 | "Argument passing for thread creation using kwargs failed") |
| 138 | _thread.start_new_thread(arg_tester, (testing_queue, True), {'arg2':True}) |
| 139 | result = testing_queue.get() |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 140 | self.assertTrue(result[0] and result[1], |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 141 | "Argument passing for thread creation using both tuple" |
| 142 | " and kwargs failed") |
Tim Peters | f2715e0 | 2003-02-19 02:35:07 +0000 | [diff] [blame] | 143 | |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 144 | def test_multi_creation(self): |
| 145 | #Make sure multiple threads can be created. |
| 146 | def queue_mark(queue, delay): |
| 147 | """Wait for ``delay`` seconds and then put something into ``queue``""" |
| 148 | time.sleep(delay) |
| 149 | queue.put(_thread.get_ident()) |
Tim Peters | f2715e0 | 2003-02-19 02:35:07 +0000 | [diff] [blame] | 150 | |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 151 | thread_count = 5 |
Alexandre Vassalotti | f260e44 | 2008-05-11 19:59:59 +0000 | [diff] [blame] | 152 | testing_queue = queue.Queue(thread_count) |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 153 | if support.verbose: |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 154 | print() |
| 155 | print("*** Testing multiple thread creation "\ |
| 156 | "(will take approx. %s to %s sec.) ***" % (DELAY, thread_count)) |
Guido van Rossum | 805365e | 2007-05-07 22:24:25 +0000 | [diff] [blame] | 157 | for count in range(thread_count): |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 158 | if DELAY: |
| 159 | local_delay = round(random.random(), 1) |
| 160 | else: |
| 161 | local_delay = 0 |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 162 | _thread.start_new_thread(queue_mark, |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 163 | (testing_queue, local_delay)) |
| 164 | time.sleep(DELAY) |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 165 | if support.verbose: |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 166 | print('done') |
Serhiy Storchaka | 8c0f0c5 | 2016-03-14 10:28:59 +0200 | [diff] [blame] | 167 | self.assertEqual(testing_queue.qsize(), thread_count, |
Tim Peters | f2715e0 | 2003-02-19 02:35:07 +0000 | [diff] [blame] | 168 | "Not all %s threads executed properly after %s sec." % |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 169 | (thread_count, DELAY)) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 170 | |
| 171 | def test_main(imported_module=None): |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 172 | global _thread, DELAY |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 173 | if imported_module: |
| 174 | _thread = imported_module |
Brett Cannon | 13da5fa | 2003-04-30 03:03:37 +0000 | [diff] [blame] | 175 | DELAY = 2 |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 176 | if support.verbose: |
Guido van Rossum | be19ed7 | 2007-02-09 05:37:30 +0000 | [diff] [blame] | 177 | print() |
| 178 | print("*** Using %s as _thread module ***" % _thread) |
Benjamin Peterson | ee8712c | 2008-05-20 21:35:26 +0000 | [diff] [blame] | 179 | support.run_unittest(LockTests, MiscTests, ThreadTests) |
Guido van Rossum | ad50ca9 | 2002-12-30 22:30:22 +0000 | [diff] [blame] | 180 | |
| 181 | if __name__ == '__main__': |
| 182 | test_main() |