1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
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)
|