def test_gather(self, conn): def collect_replies(): yield 1 yield 2 yield 3 ticket = uuid() actor = Actor(conn) actor._collect_replies = Mock(return_value=collect_replies()) ares = AsyncResult(ticket, actor) ares.to_python = Mock() all = ares.gather() list(all) actor._collect_replies.assert_caleld_once_with(conn, ANY, ticket) self.assertEqual(ares.to_python.call_count, len(list(collect_replies()))) # test that the to_python is applied to all results actor._collect_replies.reset_mock() actor._collect_replies = Mock(return_value=collect_replies()) prev_to_python = ares.to_python new_to_python = lambda x, propagate = True: 'called_%s' % x ares.to_python = new_to_python all = ares.gather() vals = list(all) expected_vals = [new_to_python(i) for i in collect_replies()] actor._collect_replies.assert_caleld_once_with(conn, ANY, ticket) self.assertEqual(vals, expected_vals) ares.to_python = prev_to_python
def test_throw(self): # Set Up method, args, return_val = 'foo', {'args': 'foo_args'}, 'result' a = A() a.call_or_cast = Mock(return_value=Mock()) a.call_or_cast.return_value.get = Mock(return_value=return_val) a.call_or_cast.return_value.result = Mock(return_value=return_val) # when throw is invoked, # all its arguments are passed to call_ot_cast and result is returned result = a.throw(method, args) a.call_or_cast.assert_called_once_with(method, args, type=ACTOR_TYPE.RR, nowait=False) self.assertEquals(result.result(), return_val) a.call_or_cast.reset_mock() # when throw is invoked with no_wait=True, no result is returned result = a.throw(method, args, nowait=True) a.call_or_cast.assert_called_once_with(method, args, type=ACTOR_TYPE.RR, nowait=True) self.assertIsNone(result) a.call_or_cast.reset_mock() # when throw is invoked without arguments # empty list is passed to call_or_cast a.throw(method) a.call_or_cast.assert_called_once_with(method, {}, type=ACTOR_TYPE.RR, nowait=False)
def test_on_message_when_reply_to_not_set(self): ret_val = 'fooo' class Foo(Actor): class state(): foo_called = False def foo(self, bar): self.foo_called = True return (bar, ret_val) # when the property reply_to is not set, reply is not called body, message = get_test_message('foo', {'bar': 'foo_arg'}, Foo.__class__.__name__) message.ack = Mock() a = Foo() a.reply = Mock() result = a._on_message(body, message) self.assertTrue(a.state.foo_called) self.assertEquals(a.reply.call_count, 0) # message should be acknowledged after the method is executed message.ack.assert_called_once() # no result should be returned self.assertIsNone(result)
def test_cast_calls_basic_publish_with_correct_rk(self, conn): a = A(conn) exch = a.type_to_exchange[ACTOR_TYPE.DIRECT]().name a = A(conn) rk = a.routing_key self.assert_cast_calls_basic_publish_with(a, rk, exch, None) agent = Mock(id=uuid()) a = A(conn, agent=agent) rk = a.routing_key self.assertNotEqual(a.routing_key, agent.id) self.assert_cast_calls_basic_publish_with(a, rk, exch, None) agent = Mock(id=uuid()) id = '1234' a = A(conn, agent=agent, id=id) rk = a.routing_key self.assertEqual(a.routing_key, id) self.assert_cast_calls_basic_publish_with(a, rk, exch, None) self.assertEquals(a.routing_key, rk) self.assert_cast_calls_basic_publish_with(a, rk, exch, None) a = A(conn) a.default_routing_key = 'fooooooooo' rk = a.default_routing_key self.assertEquals(a.routing_key, rk) self.assert_cast_calls_basic_publish_with(a, rk, exch, None)
def mock_queue(self, actor, type): queue = actor.type_to_queue[type]() queue.bind_to = Mock() queue.unbind_from = Mock() queue.declare = Mock() actor.type_to_queue[type] = Mock(return_value=queue) return queue
def mock_exchange(self, actor, type): exchange = actor.type_to_exchange[type]() exchange.bind_to = Mock() exchange.exchange_unbind = Mock() exchange.declare = Mock() actor.type_to_exchange[type] = Mock(return_value=exchange) return exchange
def test_on_message_when_private_method_is_passed(self): body, message = get_test_message('_foo', {}, A.__class__.__name__) message.ack = Mock() a = A() a.state._foo = Mock() a._on_message(body, message) self.assertEqual(a.state._foo.call_count, 0) # message should be acknowledged even when method is not invoked message.ack.assert_called_once_with()
def test_on_message_when_unexisted_method_is_passed(self): body, message = get_test_message('bar', {'bar': 'foo_arg'}, A.__class__.__name__) message.ack = Mock() a = A() a.default_receive = Mock() result = a._on_message(body, message) # message should be acknowledged even when the method does not exist message.ack.assert_called_once_with() self.assertIsNone(result)
def test_scatter(self): # Set Up method, args, = 'foo', {'args': 'foo_args'} return_val, timeout, default_timeout = 'res', 1, 2 a = A() a.default_timeout = default_timeout a.call_or_cast = Mock(return_value=Mock()) a.call_or_cast.return_value.gather = Mock(return_value=return_val) # when scatter is invoked with default arguments result = a.scatter(method, args) a.call_or_cast.assert_called_once_with(method, args, type=ACTOR_TYPE.SCATTER, nowait=False, timeout=default_timeout) self.assertEquals(result, return_val) a.call_or_cast.reset_mock() # when scatter is invoked with explicit nowait and timeout nowait = False result = a.scatter(method, args, nowait, **{'timeout': timeout}) a.call_or_cast.assert_called_once_with(method, args, type=ACTOR_TYPE.SCATTER, nowait=nowait, timeout=timeout) self.assertEquals(result, return_val) a.call_or_cast.reset_mock() # when scatter is invoked with explicit nowait set to True nowait = True result = a.scatter(method, args, nowait) a.call_or_cast.assert_called_once_with(method, args, type=ACTOR_TYPE.SCATTER, nowait=nowait, timeout=default_timeout) self.assertIsNone(result, None) a.call_or_cast.reset_mock() # when scatter is invoked without args param set result = a.scatter(method) a.call_or_cast.assert_called_once_with(method, {}, type=ACTOR_TYPE.SCATTER, nowait=False, timeout=default_timeout)
def test_on_message_invokes_on_dispatch_when_reply_to_not_set(self): ret_val = 'fooo' body, message = get_test_message('foo', {'bar': 'foo_arg'}, A.__class__.__name__) a = A() a.reply = Mock() a._DISPATCH = Mock(return_value=ret_val) # when reply_to is not set: # dispatch result should be ignored result = a._on_message(body, message) a._DISPATCH.assert_called_once_wiith(message, body) self.assertIsNone(result) self.assertEqual(a.reply.call_count, 0)
def test_on_message_invokes_on_dispatch_when_reply_to_set(self): ret_val = 'fooo' ticket = uuid() body, message = get_test_message('foo', {'bar': 'foo_arg'}, A.__class__.__name__, reply_to=ticket) a = A() a.reply = Mock() a._DISPATCH = Mock(return_value=ret_val) # when reply_to is set: # dispatch result should be ignored a._on_message(body, message) a._DISPATCH.assert_called_once_with(body, ticket=ticket) a.reply.assert_called_once_with(message, ret_val)
def test_on_message_delegated_to_agent(self): body, message = get_test_message('bar', {'bar': 'foo_arg'}, A.__class__.__name__) a = A() a.agent = Mock() a.on_message(body, message) a.agent.process_message.assert_called_once_with(a, body, message)
def test_bind_with_agent(self): """test when Actor.bind(connection, agent)""" a = A() agent = Mock(id=uuid()) with Connection('memory://') as conn: bound = a.bind(conn, agent=agent) self.assertIs(bound.agent, agent) self.assertIs(bound.state.agent, agent)
def test_result_when_result_is_set(self): val = 'the quick brown fox' ares = self.get_async_result() ares.get = Mock() ares._result = val res = ares.result() self.assertEqual(res, val) self.assertEqual(ares.get.call_count, 0)
def test_get(self): id1, id2 = uuid(), uuid() def gather(): yield id1 yield id2 # test that it calls gather with limit = 1 and kwargs ares = self.get_async_result() ares.gather = Mock(return_value=['1']) ares.get() ares.gather.assert_called_once_with(limit=1) ares.gather.reset_mock() kwargs = {'timeout': 100, 'ignore_timeout': False, 'foo': 'bar', 'propaget': True} ares.get(**kwargs) ares.gather.assert_called_once_with(**dict(kwargs, limit=1)) ares.gather.reset_mock() kwargs = {'timeout': 100, 'ignore_timeout': False, 'limit': 10} ares.get(**kwargs) ares.gather.assert_called_once_with(**kwargs) ares.gather.reset_mock() # it returns the first value of whatever gather returns ares.gather = Mock(return_value=gather()) res = ares.get() self.assertEqual(res, id1) # if gather does not return result: # self.NoReplyError('No reply received within time constraint') ares.gather = Mock(return_value=None) with self.assertRaises(ares.NoReplyError): ares.get() ares.gather.reset_mock() ares.gather = Mock(return_value={}) with self.assertRaises(ares.NoReplyError): ares.get()
def test_result_when_result_is_not_set(self): val = 'the quick brown fox' ares = self.get_async_result() ares.get = Mock(return_value=val) res = ares.result() self.assertEqual(res, val) self.assertEqual(ares._result, res) ares.get.assert_called_once_with()
def test_send(self): # Set Up method, args, return_val = 'foo', {'args': 'foo_args'}, 'bar' a = A() a.call_or_cast = Mock(return_value=Mock()) a.call_or_cast.return_value.get = Mock(return_value=return_val) # when send is invoke all its arguments are passed to call_and_cast result = a.send(method, args) a.call_or_cast.assert_called_once_with(method, args, nowait=False, routing_key=a.id) self.assertIs(result, return_val) a.call_or_cast.reset_mock() # when send is invoke with nowait=True, result is returned result = a.send(method, args, nowait=False) a.call_or_cast.assert_called_with(method, args, nowait=False, routing_key=a.id) self.assertIs(result, return_val) a.call_or_cast.reset_mock() # when send is invoke with nowait=True, no result is returned result = a.send(method, args, nowait=True) a.call_or_cast.assert_called_once_with(method, args, nowait=True, routing_key=a.id) self.assertIsNone(result) a.call_or_cast.reset_mock() # when send is invoke without arguments # empty list is passed to call_or_cast result = a.send(method, nowait=True) a.call_or_cast.assert_called_with(method, {}, nowait=True, routing_key=a.id) self.assertIsNone(result)
def test_on_message_when_no_method_is_passed(self): args, ret_val = {'bar': 'foo_arg'}, 'fooo' class Foo(Actor): class state(): def foo(self, bar): self.foo_called = True return (bar, ret_val) body, message = get_test_message('', {'bar': 'foo_arg'}, Foo.__class__.__name__) message.ack = Mock() a = Foo() a.default_receive = Mock() result = a._on_message(body, message) a.default_receive.assert_called_once(args) # message should be acknowledged even when the method does not exist message.ack.assert_called_once_with() self.assertIsNone(result)
def test_init(self): ticket = uuid() actor = Mock() ares = AsyncResult(ticket, actor) self.assertEquals(ares.ticket, ticket) self.assertEqual(ares.actor, actor) self.assertIsNone(ares._result) self.assertEqual(ares.Error, CellError) self.assertEqual(ares.NoReplyError, NoReplyError) with self.assertRaises(TypeError): AsyncResult(ticket)
def assert_on_message_exception_raise(self, exception_cls, ack_count): body, message = get_test_message('bar', {'bar': 'foo_arg'}, A.__class__.__name__) a = A() message.ack = Mock() a.handle_cast = Mock(side_effect=exception_cls('Boom')) with self.assertRaises(exception_cls): a._on_message(body, message) self.assertEquals(message.ack.call_count, ack_count) a.handle_cast.reset_mock() message.ack.reset_mock() message.ack = Mock() a.handle_call = Mock(side_effect=exception_cls('Boom')) body, message = get_test_message('bar', {'bar': 'foo_arg'}, A.__class__.__name__, reply_to=[uuid]) with self.assertRaises(exception_cls): a._on_message(body, message) self.assertEquals(message.ack.call_count, ack_count)
def test_call_or_cast(self): a = A() method, args, return_val = 'foo', {'args': 'foo_args'}, 'bar' a.call = Mock(return_value=return_val) a.cast = Mock() # when call_or_cast is invoke with default arguments: # call is invoked, result is returned result = a.call_or_cast(method, args) a.call.assert_called_once_with(method, args) self.assertEquals(result, return_val) a.call.reset_mock() # when call_or_cast is invoke with nowait=True: # call is invoked, no result is returned result = a.call_or_cast(method, args, nowait=False) a.call.assert_called_once_with(method, args) self.assertEquals(result, return_val) a.call.reset_mock() # when call_or_cast is invoke with nowait=True: # cast is invoked, no result is returned result = a.call_or_cast(method, args, nowait=True) a.cast.assert_called_once_with(method, args)
def test_init(self, conn): """test that __init__ sets fields""" id = uuid() ag, res = Mock(), Mock() # we need to have wait for result, a1 = ActorProxy(qualname(A), id, connection=conn, agent=ag) self.assertEqual(a1.id, id) self.assertIsNone(a1.async_start_result) self.assertIsInstance(a1._actor, A) self.assertEqual(a1._actor.name, A().__class__.__name__) self.assertEqual(a1._actor.agent, ag) self.assertEqual(a1._actor.id, a1.id) self.assertEqual(a1._actor.connection, conn) a1 = ActorProxy(qualname(A), id, res, connection=conn, agent=ag) self.assertEqual(a1.id, id) self.assertEqual(a1.async_start_result, res) self.assertEqual(a1._actor.id, a1.id) self.assertIsInstance(a1._actor, A) self.assertEqual(a1._actor.name, A().__class__.__name__) self.assertEqual(a1._actor.agent, ag) self.assertEqual(a1._actor.connection, conn)
def test_reply_queue_is_declared_after_call(self, conn): ticket = uuid() with patch('cell.actors.uuid') as new_uuid: new_uuid.return_value = ticket a = A(conn) reply_q = a.get_reply_queue(ticket) a.get_reply_queue = Mock(return_value=reply_q) with self.assertRaises(ChannelError): reply_q(conn.channel()).queue_declare(passive=True) a.call(method='foo', args={}, type=ACTOR_TYPE.DIRECT) a.get_reply_queue.assert_called_once_with(ticket) self.assertTrue( reply_q(conn.channel()).queue_declare(passive=True))
def test_call(self, new_uuid): dummy_method, dummy_args, ticket = 'foo', {'foo': 1}, '12345' new_uuid.return_value = ticket a = A() a.cast = Mock() # when call is invoked: # cast is invoked with correct reply_to argument res = a.call(dummy_method, dummy_args) self.assertTrue(a.cast.called) (method, args), kwargs = a.cast.call_args self.assertEqual(method, dummy_method) self.assertEqual(args, dummy_args) self.assertDictContainsSubset({'reply_to': ticket}, kwargs) # returned result is correct self.assertIsInstance(res, AsyncResult) self.assertEquals(res.ticket, ticket)
def test_emit(self): method, args, retry = 'foo', {'args': 'foo_args'}, True a = A() a.cast = Mock() # when emit is invoked with default arguments a.emit(method) result = a.cast.assert_called_once_with(method, {}, retry=None, exchange=a.outbox) self.assertIsNone(result) a.cast.reset_mock() # when emit is invoked with explicit arguments a.emit(method, args, retry) result = a.cast.assert_called_once_with(method, args, retry=retry, exchange=a.outbox) self.assertIsNone(result)
def test_on_message_when_reply_to_is_set(self): class Foo(Actor): class state(): foo_called = False def foo(self, bar): self.foo_called = True return (bar, ret_val) args, ret_val = {'bar': 'foo_arg'}, 'foooo' ticket = uuid() body, message = get_test_message('foo', args, Foo.__class__.__name__, reply_to=[ticket]) a = Foo() a.reply = Mock() # when the property reply_to is set, reply is called a._on_message(body, message) self.assertTrue(a.state.foo_called) a.reply.assert_called_oncce()
def get_async_result(self): ticket = uuid() actor = Mock() ares = AsyncResult(ticket, actor) return ares
def test_dispatch_return_values(self): """In the case of a successful call the return value will be:: {'ok': return_value, **default_fields} If the method raised an exception the return value will be:: {'nok': [repr exc, str traceback], **default_fields} :raises KeyError: if the method specified is unknown or is a special method (name starting with underscore). """ # when result is correct ret_val = 'foooo' a = A() body, message = get_test_message('bar', {'bar': 'foo_arg'}, a.__class__.__name__) expected_result = {'ok': ret_val} a.state.bar = Mock(return_value=ret_val) result = a._DISPATCH(body) self.assertDictContainsSubset(expected_result, result) self.assertNotIn('nok', result) # when method called does not return a result a.state.bar.reset_mock() a.state.bar = Mock(return_value=None) expected_result = {'ok': None} result = a._DISPATCH(body) self.assertDictContainsSubset(expected_result, result) self.assertNotIn('nok', result) # when method does not exist body, message = get_test_message('foo', {'bar': 'foo_arg'}, a.__class__.__name__) result = a._DISPATCH(body) self.assertIn('nok', result) self.assertIn("KeyError('foo',)", result['nok']) # when calling a private method body, message = get_test_message('_foo', {'bar': 'foo_arg'}, a.__class__.__name__) a._foo = Mock() result = a._DISPATCH(body) self.assertIn('nok', result) self.assertIn("KeyError('_foo',)", result['nok']) # when calling a private method body, message = get_test_message('__foo', {'bar': 'foo_arg'}, a.__class__.__name__) a.__foo = Mock() result = a._DISPATCH(body) self.assertIn('nok', result) self.assertIn("KeyError('__foo',)", result['nok']) # when method called raises an exception body, message = get_test_message('foo_with_exception', {'bar': 'foo_arg'}, a.__class__.__name__) a.foo_with_exception = Mock(side_effect=Exception('FooError')) result = a._DISPATCH(body) self.assertIn('nok', result) self.assertIn("KeyError('foo_with_exception',)", result['nok'])