blob: 5eb3f7d4c755653d4a425444aa7f52c0b3ee9f5a [file] [log] [blame]
Tim Petersd66595f2001-02-04 03:09:53 +00001# Run the _testcapi module tests (tests for the Python/C API): by defn,
Guido van Rossum361c5352001-04-13 17:03:04 +00002# these are all functions _testcapi exports whose name begins with 'test_'.
Tim Peters9ea17ac2001-02-02 05:57:15 +00003
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +00004from __future__ import with_statement
Serhiy Storchakaef19fd22018-07-11 19:49:17 +03005import string
Martin v. Löwis6ce7ed22005-03-03 12:26:35 +00006import sys
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +00007import time
8import random
9import unittest
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030010from test import test_support as support
Victor Stinnerbe595d32010-04-27 23:01:29 +000011try:
Ezio Melottief1db542013-02-23 06:33:51 +020012 import thread
Victor Stinnerbe595d32010-04-27 23:01:29 +000013 import threading
14except ImportError:
Ezio Melottief1db542013-02-23 06:33:51 +020015 thread = None
Victor Stinnerbe595d32010-04-27 23:01:29 +000016 threading = None
Serhiy Storchaka76249ea2014-02-07 10:06:05 +020017# Skip this test if the _testcapi module isn't available.
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030018_testcapi = support.import_module('_testcapi')
Serhiy Storchaka76249ea2014-02-07 10:06:05 +020019
Serhiy Storchaka12cf60c2016-05-20 22:31:24 +030020class CAPITest(unittest.TestCase):
21
22 def test_buildvalue_N(self):
23 _testcapi.test_buildvalue_N()
24
Tim Peters9ea17ac2001-02-02 05:57:15 +000025
Victor Stinnerbe595d32010-04-27 23:01:29 +000026@unittest.skipUnless(threading, 'Threading required for this test.')
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000027class TestPendingCalls(unittest.TestCase):
28
29 def pendingcalls_submit(self, l, n):
30 def callback():
31 #this function can be interrupted by thread switching so let's
32 #use an atomic operation
33 l.append(None)
34
35 for i in range(n):
36 time.sleep(random.random()*0.02) #0.01 secs on average
37 #try submitting callback until successful.
38 #rely on regular interrupt to flush queue if we are
39 #unsuccessful.
40 while True:
41 if _testcapi._pending_threadfunc(callback):
42 break;
43
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000044 def pendingcalls_wait(self, l, n, context = None):
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000045 #now, stick around until l[0] has grown to 10
46 count = 0;
47 while len(l) != n:
48 #this busy loop is where we expect to be interrupted to
49 #run our callbacks. Note that callbacks are only run on the
50 #main thread
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030051 if False and support.verbose:
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000052 print "(%i)"%(len(l),),
53 for i in xrange(1000):
54 a = i*i
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000055 if context and not context.event.is_set():
56 continue
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000057 count += 1
Benjamin Peterson5c8da862009-06-30 22:57:08 +000058 self.assertTrue(count < 10000,
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000059 "timeout waiting for %i callbacks, got %i"%(n, len(l)))
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030060 if False and support.verbose:
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000061 print "(%i)"%(len(l),)
62
63 def test_pendingcalls_threaded(self):
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000064 #do every callback on a separate thread
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000065 n = 32 #total callbacks
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000066 threads = []
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000067 class foo(object):pass
68 context = foo()
69 context.l = []
70 context.n = 2 #submits per thread
Ezio Melottidde5b942010-02-03 05:37:26 +000071 context.nThreads = n // context.n
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000072 context.nFinished = 0
73 context.lock = threading.Lock()
74 context.event = threading.Event()
75
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030076 threads = [threading.Thread(target=self.pendingcalls_thread,
77 args=(context,))
78 for i in range(context.nThreads)]
79 with support.start_threads(threads):
80 self.pendingcalls_wait(context.l, n, context)
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000081
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000082 def pendingcalls_thread(self, context):
83 try:
84 self.pendingcalls_submit(context.l, context.n)
85 finally:
86 with context.lock:
87 context.nFinished += 1
88 nFinished = context.nFinished
Serhiy Storchakabd8c6292015-04-01 12:56:39 +030089 if False and support.verbose:
Kristján Valur Jónsson60e79ce2009-01-18 10:58:44 +000090 print "finished threads: ", nFinished
91 if nFinished == context.nThreads:
92 context.event.set()
93
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000094 def test_pendingcalls_non_threaded(self):
Ezio Melottic2077b02011-03-16 12:34:31 +020095 #again, just using the main thread, likely they will all be dispatched at
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +000096 #once. It is ok to ask for too many, because we loop until we find a slot.
97 #the loop can be interrupted to dispatch.
98 #there are only 32 dispatch slots, so we go for twice that!
99 l = []
100 n = 64
101 self.pendingcalls_submit(l, n)
102 self.pendingcalls_wait(l, n)
103
104
Xtreak2bea7712018-07-26 21:50:34 +0530105class TestGetIndices(unittest.TestCase):
106
107 def test_get_indices(self):
108 self.assertEqual(_testcapi.get_indices(slice(10L, 20, 1), 100), (0, 10, 20, 1))
109 self.assertEqual(_testcapi.get_indices(slice(10.1, 20, 1), 100), None)
110 self.assertEqual(_testcapi.get_indices(slice(10, 20L, 1), 100), (0, 10, 20, 1))
111 self.assertEqual(_testcapi.get_indices(slice(10, 20.1, 1), 100), None)
112
113 self.assertEqual(_testcapi.get_indices(slice(10L, 20, 1L), 100), (0, 10, 20, 1))
114 self.assertEqual(_testcapi.get_indices(slice(10.1, 20, 1L), 100), None)
115 self.assertEqual(_testcapi.get_indices(slice(10, 20L, 1L), 100), (0, 10, 20, 1))
116 self.assertEqual(_testcapi.get_indices(slice(10, 20.1, 1L), 100), None)
117
118
Ezio Melottief1db542013-02-23 06:33:51 +0200119@unittest.skipUnless(threading and thread, 'Threading required for this test.')
Ezio Melotti2fddfd82013-02-23 05:45:37 +0200120class TestThreadState(unittest.TestCase):
Tim Peters59b96c12006-03-21 03:58:41 +0000121
Serhiy Storchakabd8c6292015-04-01 12:56:39 +0300122 @support.reap_threads
Ezio Melotti2fddfd82013-02-23 05:45:37 +0200123 def test_thread_state(self):
124 # some extra thread-state tests driven via _testcapi
125 def target():
126 idents = []
127
128 def callback():
129 idents.append(thread.get_ident())
130
131 _testcapi._test_thread_state(callback)
132 a = b = callback
133 time.sleep(1)
134 # Check our main thread is in the list exactly 3 times.
135 self.assertEqual(idents.count(thread.get_ident()), 3,
136 "Couldn't find main thread correctly in the list")
137
138 target()
139 t = threading.Thread(target=target)
140 t.start()
141 t.join()
142
143
Serhiy Storchakad1c5e272018-08-06 18:06:14 +0300144class Test_testcapi(unittest.TestCase):
145 locals().update((name, getattr(_testcapi, name))
146 for name in dir(_testcapi)
147 if name.startswith('test_') and not name.endswith('_code'))
Tim Peters59b96c12006-03-21 03:58:41 +0000148
Serhiy Storchakad1c5e272018-08-06 18:06:14 +0300149
150def test_main():
151 support.run_unittest(CAPITest, TestPendingCalls,
152 TestThreadState, TestGetIndices, Test_testcapi)
Kristján Valur Jónsson0e2d8c32009-01-09 21:35:16 +0000153
Tim Peters59b96c12006-03-21 03:58:41 +0000154if __name__ == "__main__":
155 test_main()