blob: c61078d62011bb2e72c6a26a8588cd6a8281569a [file] [log] [blame]
Guido van Rossumad50ca92002-12-30 22:30:22 +00001"""Generic thread tests.
2
3Meant to be used by dummy_thread and thread. To allow for different modules
4to be used, test_main() can be called with the module to use as the thread
5implementation as its sole argument.
6
7"""
Georg Brandl2067bfd2008-05-25 13:05:15 +00008import _dummy_thread as _thread
Guido van Rossumad50ca92002-12-30 22:30:22 +00009import time
Alexandre Vassalottif260e442008-05-11 19:59:59 +000010import queue
Guido van Rossumad50ca92002-12-30 22:30:22 +000011import random
12import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000013from test import support
Guido van Rossumad50ca92002-12-30 22:30:22 +000014
Georg Brandl2067bfd2008-05-25 13:05:15 +000015DELAY = 0 # Set > 0 when testing a module other than _dummy_thread, such as
16 # the '_thread' module.
Guido van Rossumad50ca92002-12-30 22:30:22 +000017
18class 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
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000027 self.assertTrue(not self.lock.locked(),
Guido van Rossumad50ca92002-12-30 22:30:22 +000028 "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()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000034 self.assertTrue(not self.lock.locked(),
Guido van Rossumad50ca92002-12-30 22:30:22 +000035 "Lock object did not release properly.")
Tim Petersf2715e02003-02-19 02:35:07 +000036
Guido van Rossumad50ca92002-12-30 22:30:22 +000037 def test_improper_release(self):
38 #Make sure release of an unlocked thread raises _thread.error
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000039 self.assertRaises(_thread.error, self.lock.release)
Guido van Rossumad50ca92002-12-30 22:30:22 +000040
41 def test_cond_acquire_success(self):
42 #Make sure the conditional acquiring of the lock works.
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000043 self.assertTrue(self.lock.acquire(0),
Guido van Rossumad50ca92002-12-30 22:30:22 +000044 "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)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000049 self.assertTrue(not self.lock.acquire(0),
Guido van Rossumad50ca92002-12-30 22:30:22 +000050 "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 Petersonc9c0f202009-06-30 23:06:06 +000056 self.assertTrue(self.lock.locked(),
Guido van Rossumad50ca92002-12-30 22:30:22 +000057 "Uncondional locking failed.")
58
59 def test_uncond_acquire_return_val(self):
60 #Make sure that an unconditional locking returns True.
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000061 self.assertTrue(self.lock.acquire(1) is True,
Guido van Rossumad50ca92002-12-30 22:30:22 +000062 "Unconditional locking did not return True.")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000063 self.assertTrue(self.lock.acquire() is True)
Tim Petersf2715e02003-02-19 02:35:07 +000064
Guido van Rossumad50ca92002-12-30 22:30:22 +000065 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 Rossumad50ca92002-12-30 22:30:22 +000073 start_time = int(time.time())
Brett Cannon13da5fa2003-04-30 03:03:37 +000074 _thread.start_new_thread(delay_unlock,(self.lock, DELAY))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000075 if support.verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000076 print()
77 print("*** Waiting for thread to release the lock "\
78 "(approx. %s sec.) ***" % DELAY)
Guido van Rossumad50ca92002-12-30 22:30:22 +000079 self.lock.acquire()
80 end_time = int(time.time())
Benjamin Petersonee8712c2008-05-20 21:35:26 +000081 if support.verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +000082 print("done")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000083 self.assertTrue((end_time - start_time) >= DELAY,
Guido van Rossumad50ca92002-12-30 22:30:22 +000084 "Blocking by unconditional acquiring failed.")
85
86class MiscTests(unittest.TestCase):
87 """Miscellaneous tests."""
88
89 def test_exit(self):
90 #Make sure _thread.exit() raises SystemExit
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000091 self.assertRaises(SystemExit, _thread.exit)
Guido van Rossumad50ca92002-12-30 22:30:22 +000092
93 def test_ident(self):
94 #Test sanity of _thread.get_ident()
Ezio Melottie9615932010-01-24 19:26:24 +000095 self.assertIsInstance(_thread.get_ident(), int,
96 "_thread.get_ident() returned a non-integer")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000097 self.assertTrue(_thread.get_ident() != 0,
Guido van Rossumad50ca92002-12-30 22:30:22 +000098 "_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 Melottie9615932010-01-24 19:26:24 +0000102 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 Rossumad50ca92002-12-30 22:30:22 +0000105
Brett Cannon4e64d782003-06-13 23:44:35 +0000106 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 Petersonc9c0f202009-06-30 23:06:06 +0000111 self.assertRaises(KeyboardInterrupt, _thread.start_new_thread,
Brett Cannon4e64d782003-06-13 23:44:35 +0000112 call_interrupt, tuple())
Tim Petersf545baa2003-06-15 23:26:30 +0000113
Brett Cannon91012fe2003-06-13 23:56:32 +0000114 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 Petersonc9c0f202009-06-30 23:06:06 +0000117 self.assertRaises(KeyboardInterrupt, _thread.interrupt_main)
Brett Cannon4e64d782003-06-13 23:44:35 +0000118
Guido van Rossumad50ca92002-12-30 22:30:22 +0000119class 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 Vassalottif260e442008-05-11 19:59:59 +0000128 testing_queue = queue.Queue(1)
Guido van Rossumad50ca92002-12-30 22:30:22 +0000129 _thread.start_new_thread(arg_tester, (testing_queue, True, True))
130 result = testing_queue.get()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000131 self.assertTrue(result[0] and result[1],
Guido van Rossumad50ca92002-12-30 22:30:22 +0000132 "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 Petersonc9c0f202009-06-30 23:06:06 +0000136 self.assertTrue(result[0] and result[1],
Guido van Rossumad50ca92002-12-30 22:30:22 +0000137 "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 Petersonc9c0f202009-06-30 23:06:06 +0000140 self.assertTrue(result[0] and result[1],
Guido van Rossumad50ca92002-12-30 22:30:22 +0000141 "Argument passing for thread creation using both tuple"
142 " and kwargs failed")
Tim Petersf2715e02003-02-19 02:35:07 +0000143
Guido van Rossumad50ca92002-12-30 22:30:22 +0000144 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 Petersf2715e02003-02-19 02:35:07 +0000150
Guido van Rossumad50ca92002-12-30 22:30:22 +0000151 thread_count = 5
Alexandre Vassalottif260e442008-05-11 19:59:59 +0000152 testing_queue = queue.Queue(thread_count)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000153 if support.verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000154 print()
155 print("*** Testing multiple thread creation "\
156 "(will take approx. %s to %s sec.) ***" % (DELAY, thread_count))
Guido van Rossum805365e2007-05-07 22:24:25 +0000157 for count in range(thread_count):
Brett Cannon13da5fa2003-04-30 03:03:37 +0000158 if DELAY:
159 local_delay = round(random.random(), 1)
160 else:
161 local_delay = 0
Guido van Rossumad50ca92002-12-30 22:30:22 +0000162 _thread.start_new_thread(queue_mark,
Brett Cannon13da5fa2003-04-30 03:03:37 +0000163 (testing_queue, local_delay))
164 time.sleep(DELAY)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000165 if support.verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000166 print('done')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000167 self.assertTrue(testing_queue.qsize() == thread_count,
Tim Petersf2715e02003-02-19 02:35:07 +0000168 "Not all %s threads executed properly after %s sec." %
Brett Cannon13da5fa2003-04-30 03:03:37 +0000169 (thread_count, DELAY))
Guido van Rossumad50ca92002-12-30 22:30:22 +0000170
171def test_main(imported_module=None):
Brett Cannon13da5fa2003-04-30 03:03:37 +0000172 global _thread, DELAY
Guido van Rossumad50ca92002-12-30 22:30:22 +0000173 if imported_module:
174 _thread = imported_module
Brett Cannon13da5fa2003-04-30 03:03:37 +0000175 DELAY = 2
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000176 if support.verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000177 print()
178 print("*** Using %s as _thread module ***" % _thread)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 support.run_unittest(LockTests, MiscTests, ThreadTests)
Guido van Rossumad50ca92002-12-30 22:30:22 +0000180
181if __name__ == '__main__':
182 test_main()