2017-09-30 15:27:14 +00:00
|
|
|
import logging
|
2017-10-03 10:38:38 +00:00
|
|
|
import time
|
2017-09-16 09:57:30 +00:00
|
|
|
import unittest
|
2017-09-30 15:27:14 +00:00
|
|
|
|
2017-09-16 09:57:30 +00:00
|
|
|
import mitogen.core
|
|
|
|
import mitogen.master
|
|
|
|
|
2017-09-30 15:27:14 +00:00
|
|
|
import testlib
|
|
|
|
|
2017-09-16 09:57:30 +00:00
|
|
|
|
|
|
|
class CrazyType(object):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2017-09-21 08:11:47 +00:00
|
|
|
def function_that_adds_numbers(x, y):
|
|
|
|
return x + y
|
|
|
|
|
|
|
|
|
2017-09-16 09:57:30 +00:00
|
|
|
def function_that_fails():
|
|
|
|
raise ValueError('exception text')
|
|
|
|
|
|
|
|
|
|
|
|
def func_with_bad_return_value():
|
|
|
|
return CrazyType()
|
|
|
|
|
|
|
|
|
|
|
|
def func_returns_dead():
|
|
|
|
return mitogen.core._DEAD
|
|
|
|
|
|
|
|
|
2017-09-16 14:26:59 +00:00
|
|
|
def func_accepts_returns_context(context):
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
2017-09-30 15:27:14 +00:00
|
|
|
class CallFunctionTest(testlib.RouterMixin, testlib.TestCase):
|
2017-09-30 09:38:40 +00:00
|
|
|
def setUp(self):
|
|
|
|
super(CallFunctionTest, self).setUp()
|
|
|
|
self.local = self.router.local()
|
2017-09-16 09:57:30 +00:00
|
|
|
|
2017-09-21 08:11:47 +00:00
|
|
|
def test_succeeds(self):
|
|
|
|
assert 3 == self.local.call(function_that_adds_numbers, 1, 2)
|
|
|
|
|
2017-09-16 10:04:55 +00:00
|
|
|
def test_crashes(self):
|
2017-09-30 15:27:14 +00:00
|
|
|
exc = self.assertRaises(mitogen.core.CallError,
|
|
|
|
lambda: self.local.call(function_that_fails))
|
2017-09-16 09:57:30 +00:00
|
|
|
|
2017-09-30 15:27:14 +00:00
|
|
|
s = str(exc)
|
2017-09-16 09:57:30 +00:00
|
|
|
etype, _, s = s.partition(': ')
|
|
|
|
assert etype == 'exceptions.ValueError'
|
|
|
|
|
|
|
|
msg, _, s = s.partition('\n')
|
|
|
|
assert msg == 'exception text'
|
|
|
|
|
|
|
|
# Traceback
|
|
|
|
assert len(s) > 0
|
|
|
|
|
|
|
|
def test_bad_return_value(self):
|
2017-09-30 15:27:14 +00:00
|
|
|
exc = self.assertRaises(mitogen.core.StreamError,
|
|
|
|
lambda: self.local.call(func_with_bad_return_value))
|
|
|
|
self.assertEquals(exc[0], "cannot unpickle '__main__'/'CrazyType'")
|
2017-09-16 09:57:30 +00:00
|
|
|
|
2017-09-16 10:04:55 +00:00
|
|
|
def test_returns_dead(self):
|
2017-09-16 09:57:30 +00:00
|
|
|
assert mitogen.core._DEAD == self.local.call(func_returns_dead)
|
2017-09-16 10:04:55 +00:00
|
|
|
|
2017-10-03 10:24:55 +00:00
|
|
|
def test_aborted_on_local_context_disconnect(self):
|
|
|
|
stream = self.router._stream_by_id[self.local.context_id]
|
|
|
|
self.broker.stop_receive(stream)
|
|
|
|
recv = self.local.call_async(time.sleep, 120)
|
|
|
|
self.broker.defer(stream.on_disconnect, self.broker)
|
|
|
|
exc = self.assertRaises(mitogen.core.ChannelError,
|
|
|
|
lambda: recv.get())
|
|
|
|
self.assertEquals(exc[0], mitogen.core.ChannelError.local_msg)
|
2017-09-16 10:04:55 +00:00
|
|
|
|
|
|
|
def test_aborted_on_local_broker_shutdown(self):
|
2017-10-03 10:38:38 +00:00
|
|
|
stream = self.router._stream_by_id[self.local.context_id]
|
|
|
|
recv = self.local.call_async(time.sleep, 120)
|
|
|
|
time.sleep(0.1) # Ensure GIL is released
|
|
|
|
self.broker.shutdown()
|
|
|
|
exc = self.assertRaises(mitogen.core.ChannelError,
|
|
|
|
lambda: recv.get())
|
|
|
|
self.assertEquals(exc[0], mitogen.core.ChannelError.local_msg)
|
2017-09-16 14:26:59 +00:00
|
|
|
|
|
|
|
def test_accepts_returns_context(self):
|
|
|
|
context = self.local.call(func_accepts_returns_context, self.local)
|
|
|
|
assert context is not self.local
|
|
|
|
assert context.context_id == self.local.context_id
|
|
|
|
assert context.name == self.local.name
|
2017-09-21 11:15:36 +00:00
|
|
|
|
|
|
|
|
2017-09-22 08:07:50 +00:00
|
|
|
if __name__ == '__main__':
|
2017-09-21 11:15:36 +00:00
|
|
|
unittest.main()
|