You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.2 KiB
Python

5 years ago
import sys
import gevent.testing as greentest
import gevent
from gevent.hub import get_hub
def raise_(ex):
raise ex
MSG = 'should be re-raised and caught'
class Test(greentest.TestCase):
x = None
error_fatal = False
def start(self, *args):
raise NotImplementedError
def setUp(self):
self.x = None
def test_sys_exit(self):
self.start(sys.exit, MSG)
try:
gevent.sleep(0.001)
except SystemExit as ex:
assert str(ex) == MSG, repr(str(ex))
else:
raise AssertionError('must raise SystemExit')
def test_keyboard_interrupt(self):
self.start(raise_, KeyboardInterrupt)
try:
gevent.sleep(0.001)
except KeyboardInterrupt:
pass
else:
raise AssertionError('must raise KeyboardInterrupt')
def test_keyboard_interrupt_stderr_patched(self):
# XXX: This one non-top-level call prevents us from being
# run in a process with other tests.
from gevent import monkey
monkey.patch_sys(stdin=False, stdout=False, stderr=True)
try:
try:
self.start(raise_, KeyboardInterrupt)
while True:
gevent.sleep(0.1)
except KeyboardInterrupt:
pass # expected
finally:
sys.stderr = monkey.get_original('sys', 'stderr')
def test_system_error(self):
self.start(raise_, SystemError(MSG))
with self.assertRaisesRegex(SystemError,
MSG):
gevent.sleep(0.002)
def test_exception(self):
self.start(raise_, Exception('regular exception must not kill the program'))
gevent.sleep(0.001)
class TestCallback(Test):
def tearDown(self):
if self.x is not None:
# libuv: See the notes in libuv/loop.py:loop._start_callback_timer
# If that's broken, test_exception can fail sporadically.
# If the issue is the same, then adding `gevent.sleep(0)` here
# will solve it. There's also a race condition for the first loop,
# so we sleep twice.
assert not self.x.pending, self.x
def start(self, *args):
self.x = get_hub().loop.run_callback(*args)
if greentest.LIBUV:
def test_exception(self):
# This call will enter the loop for the very first time (if we're running
# standalone). On libuv, where timers run first, that means that depending on the
# amount of time that elapses between the call to uv_timer_start and uv_run,
# this timer might fire before our check or prepare watchers, and hence callbacks,
# run.
# We make this call now so that the call in the super class is guaranteed to be
# somewhere in the loop and not subject to that race condition.
gevent.sleep(0.001)
super(TestCallback, self).test_exception()
class TestSpawn(Test):
def tearDown(self):
gevent.sleep(0.0001)
if self.x is not None:
assert self.x.dead, self.x
def start(self, *args):
self.x = gevent.spawn(*args)
del Test
if __name__ == '__main__':
greentest.main()