2018-05-28 04:09:19 +00:00
|
|
|
import unittest2
|
|
|
|
|
|
|
|
import mitogen.core
|
|
|
|
import mitogen.service
|
|
|
|
import testlib
|
|
|
|
|
|
|
|
|
|
|
|
class MyService(mitogen.service.Service):
|
|
|
|
def __init__(self, router):
|
|
|
|
super(MyService, self).__init__(router)
|
|
|
|
self._counter = 0
|
|
|
|
|
|
|
|
@mitogen.service.expose(policy=mitogen.service.AllowParents())
|
|
|
|
def get_id(self):
|
|
|
|
self._counter += 1
|
|
|
|
return self._counter, id(self)
|
|
|
|
|
|
|
|
@mitogen.service.expose(policy=mitogen.service.AllowParents())
|
|
|
|
def privileged_op(self):
|
|
|
|
return 'privileged!'
|
|
|
|
|
|
|
|
@mitogen.service.expose(policy=mitogen.service.AllowAny())
|
|
|
|
def unprivileged_op(self):
|
|
|
|
return 'unprivileged!'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MyService2(MyService):
|
|
|
|
"""
|
|
|
|
A uniquely named service that lets us test framework activation and class
|
|
|
|
activation separately.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
def call_service_in(context, service_name, method_name):
|
|
|
|
return context.call_service(service_name, method_name)
|
|
|
|
|
|
|
|
|
|
|
|
class ActivationTest(testlib.RouterMixin, testlib.TestCase):
|
|
|
|
def test_parent_can_activate(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
counter, id_ = l1.call_service(MyService, 'get_id')
|
|
|
|
self.assertEquals(1, counter)
|
|
|
|
self.assertTrue(isinstance(id_, int))
|
|
|
|
|
|
|
|
def test_sibling_cannot_activate_framework(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
|
|
|
l2 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
exc = self.assertRaises(mitogen.core.CallError,
|
|
|
|
lambda: l2.call(call_service_in, l1, MyService2.name(), 'get_id'))
|
|
|
|
self.assertTrue(mitogen.core.Router.refused_msg in exc.args[0])
|
|
|
|
|
|
|
|
def test_sibling_cannot_activate_service(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
|
|
|
l2 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
l1.call_service(MyService, 'get_id') # force framework activation
|
2019-01-20 07:08:11 +00:00
|
|
|
capture = testlib.LogCapturer()
|
|
|
|
capture.start()
|
|
|
|
try:
|
|
|
|
exc = self.assertRaises(mitogen.core.CallError,
|
|
|
|
lambda: l2.call(call_service_in, l1, MyService2.name(), 'get_id'))
|
|
|
|
finally:
|
|
|
|
capture.stop()
|
2018-05-28 04:09:19 +00:00
|
|
|
msg = mitogen.service.Activator.not_active_msg % (MyService2.name(),)
|
|
|
|
self.assertTrue(msg in exc.args[0])
|
|
|
|
|
|
|
|
def test_activates_only_once(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
counter, id_ = l1.call_service(MyService, 'get_id')
|
|
|
|
counter2, id_2 = l1.call_service(MyService, 'get_id')
|
|
|
|
self.assertEquals(1, counter)
|
|
|
|
self.assertEquals(2, counter2)
|
|
|
|
self.assertEquals(id_, id_2)
|
|
|
|
|
|
|
|
|
|
|
|
class PermissionTest(testlib.RouterMixin, testlib.TestCase):
|
|
|
|
def test_sibling_unprivileged_ok(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
l1.call_service(MyService, 'get_id')
|
2019-01-23 12:44:08 +00:00
|
|
|
l2 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
self.assertEquals('unprivileged!',
|
|
|
|
l2.call(call_service_in, l1, MyService.name(), 'unprivileged_op'))
|
|
|
|
|
|
|
|
def test_sibling_privileged_bad(self):
|
2019-01-23 12:44:08 +00:00
|
|
|
l1 = self.router.local()
|
2018-05-28 04:09:19 +00:00
|
|
|
l1.call_service(MyService, 'get_id')
|
2019-01-23 12:44:08 +00:00
|
|
|
l2 = self.router.local()
|
2019-01-20 07:08:11 +00:00
|
|
|
capture = testlib.LogCapturer()
|
|
|
|
capture.start()
|
|
|
|
try:
|
|
|
|
exc = self.assertRaises(mitogen.core.CallError, lambda:
|
|
|
|
l2.call(call_service_in, l1, MyService.name(), 'privileged_op'))
|
|
|
|
finally:
|
|
|
|
capture.stop()
|
2018-05-28 04:09:19 +00:00
|
|
|
msg = mitogen.service.Invoker.unauthorized_msg % (
|
2018-06-26 07:25:40 +00:00
|
|
|
u'privileged_op',
|
2018-05-28 04:09:19 +00:00
|
|
|
MyService.name(),
|
|
|
|
)
|
|
|
|
self.assertTrue(msg in exc.args[0])
|
|
|
|
|
|
|
|
|
2019-01-19 08:15:08 +00:00
|
|
|
class CloseTest(testlib.RouterMixin, testlib.TestCase):
|
|
|
|
klass = mitogen.service.Pool
|
|
|
|
|
|
|
|
def test_receiver_closed(self):
|
|
|
|
pool = self.klass(router=self.router, services=[])
|
|
|
|
pool.stop()
|
|
|
|
self.assertEquals(None, pool._receiver.handle)
|
|
|
|
|
|
|
|
e = self.assertRaises(mitogen.core.ChannelError,
|
|
|
|
lambda: self.router.myself().call_service(MyService, 'foobar'))
|
|
|
|
self.assertEquals(e.args[0], self.router.invalid_handle_msg)
|
|
|
|
|
|
|
|
|
2018-05-28 04:09:19 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest2.main()
|