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.
155 lines
5.0 KiB
Python
155 lines
5.0 KiB
Python
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())
|
|
@mitogen.service.arg_spec({
|
|
'foo': int
|
|
})
|
|
def test_arg_spec(self, foo):
|
|
return foo
|
|
|
|
@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 CallTest(testlib.RouterMixin, testlib.TestCase):
|
|
def test_local(self):
|
|
pool = mitogen.service.get_or_create_pool(router=self.router)
|
|
self.assertEqual(
|
|
'privileged!',
|
|
mitogen.service.call(MyService, 'privileged_op')
|
|
)
|
|
pool.stop()
|
|
|
|
def test_remote_bad_arg(self):
|
|
c1 = self.router.local()
|
|
self.assertRaises(
|
|
mitogen.core.CallError,
|
|
lambda: mitogen.service.call(
|
|
MyService.name(),
|
|
'test_arg_spec',
|
|
foo='x',
|
|
call_context=c1
|
|
)
|
|
)
|
|
|
|
def test_local_unicode(self):
|
|
pool = mitogen.service.get_or_create_pool(router=self.router)
|
|
self.assertEqual(
|
|
'privileged!',
|
|
mitogen.service.call(MyService.name(), 'privileged_op')
|
|
)
|
|
pool.stop()
|
|
|
|
def test_remote(self):
|
|
c1 = self.router.local()
|
|
self.assertEqual(
|
|
'privileged!',
|
|
mitogen.service.call(MyService, 'privileged_op',
|
|
call_context=c1)
|
|
)
|
|
|
|
|
|
class ActivationTest(testlib.RouterMixin, testlib.TestCase):
|
|
def test_parent_can_activate(self):
|
|
l1 = self.router.local()
|
|
counter, id_ = l1.call_service(MyService, 'get_id')
|
|
self.assertEqual(1, counter)
|
|
self.assertIsInstance(id_, int)
|
|
|
|
def test_sibling_cannot_activate_framework(self):
|
|
l1 = self.router.local(name='l1')
|
|
l2 = self.router.local(name='l2')
|
|
exc = self.assertRaises(mitogen.core.CallError,
|
|
lambda: l2.call(call_service_in, l1, MyService2.name(), 'get_id'))
|
|
self.assertIn(mitogen.core.Router.refused_msg, exc.args[0])
|
|
|
|
def test_sibling_cannot_activate_service(self):
|
|
l1 = self.router.local()
|
|
l2 = self.router.local()
|
|
l1.call_service(MyService, 'get_id') # force framework activation
|
|
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()
|
|
msg = mitogen.service.Activator.not_active_msg % (MyService2.name(),)
|
|
self.assertIn(msg, exc.args[0])
|
|
|
|
def test_activates_only_once(self):
|
|
l1 = self.router.local()
|
|
counter, id_ = l1.call_service(MyService, 'get_id')
|
|
counter2, id_2 = l1.call_service(MyService, 'get_id')
|
|
self.assertEqual(1, counter)
|
|
self.assertEqual(2, counter2)
|
|
self.assertEqual(id_, id_2)
|
|
|
|
|
|
class PermissionTest(testlib.RouterMixin, testlib.TestCase):
|
|
def test_sibling_unprivileged_ok(self):
|
|
l1 = self.router.local()
|
|
l1.call_service(MyService, 'get_id')
|
|
l2 = self.router.local()
|
|
self.assertEqual('unprivileged!',
|
|
l2.call(call_service_in, l1, MyService.name(), 'unprivileged_op'))
|
|
|
|
def test_sibling_privileged_bad(self):
|
|
l1 = self.router.local()
|
|
l1.call_service(MyService, 'get_id')
|
|
l2 = self.router.local()
|
|
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()
|
|
msg = mitogen.service.Invoker.unauthorized_msg % (
|
|
u'privileged_op',
|
|
MyService.name(),
|
|
)
|
|
self.assertIn(msg, exc.args[0])
|
|
|
|
|
|
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.assertEqual(None, pool._receiver.handle)
|
|
|
|
e = self.assertRaises(mitogen.core.ChannelError,
|
|
lambda: self.router.myself().call_service(MyService, 'foobar'))
|
|
self.assertEqual(e.args[0], self.router.invalid_handle_msg)
|