def test_on_message(self): # Normal message class MyMessage(object): def __init__(self, payload): self.topic = "" self.qos = 2 self.payload = payload # Request message = MyMessage({ "id": 1234, "method": "get", "resource": "/test__dispatch_message", "sign": ["test"], "data": { "test": "OK" } }) smessage = Message(message.payload) self.test_model.on_message(None, None, message) data = self.test_model.req_queue.get() self.assertEqual(data.to_dict(), smessage.to_dict()) # Response message2 = MyMessage({ "id": 1234, "code": 200, "method": "get", "resource": "/test__dispatch_message", "sign": ["test"], "data": { "test": "OK" } }) smessage = Message(message2.payload) self.test_model.on_message(None, None, message2) data = self.test_model.res_queue.get() self.assertEqual(data.to_dict(), smessage.to_dict()) # Non-JSON String message message = MyMessage(None) self.test_model.on_message(None, None, message) with self.assertRaises(Empty): self.test_model.req_queue.get(timeout=0.1) # UNKNOW TYPE message message = MyMessage("{}") self.test_model.on_message(None, None, message) with self.assertRaises(Empty): self.test_model.req_queue.get(timeout=0.1)
def test__resolve_responses(self): """ It should put message into req_queue if response is not for me """ msg = Message({ "id": 3456, "code": 200, "method": "get", "resource": "/not_found/12345", "sign": ["test"], "data": None }) self.test_model.res_queue.put(msg) # start dispatch messages thread = Thread(target=self.test_model._resolve_responses) thread.daemon = True thread.start() while self.test_model.res_queue.empty() is False: pass event_msg_ans = Message({ "code": 200, "method": "get", "resource": "/not_found/12345", "data": None }, generate_id=False) event_msg = self.test_model.req_queue.get() self.assertEqual(event_msg_ans.to_dict(), event_msg.to_dict()) self.assertEqual(event_msg.type(), MessageType.EVENT) self.test_model.res_queue.put(None) thread.join()
def create(self, message, mid=None, age=60, force=True): """ create session force if you pass `force = False`, it may raise SessionError due to duplicate message id """ with self.session_lock: if self.session_list.get(message.id, None) is not None: if force is False: raise SessionError("Message id: %s duplicate!" % message.id) else: message = Message(message.to_dict(), generate_id=True) session = { "status": Status.CREATED, "message": message, "age": age, "mid": mid, "created_at": time(), "is_published": Event(), "is_resolved": Event() } self.session_list.update({ message.id: session }) return session
def create(self, message, mid=None, age=60, force=True): """ create session force if you pass `force = False`, it may raise SessionError due to duplicate message id """ with self.session_lock: if self.session_list.get(message.id, None) is not None: if force is False: raise SessionError("Message id: %s duplicate!" % message.id) else: message = Message(message.to_dict(), generate_id=True) session = { "status": Status.CREATED, "message": message, "age": age, "mid": mid, "created_at": time(), "is_published": Event(), "is_resolved": Event() } self.session_list.update({message.id: session}) return session
def test__resolve_responses(self): """ It should put message into req_queue if response is not for me """ msg = Message({ "id": 3456, "code": 200, "method": "get", "resource": "/not_found/12345", "sign": ["test"], "data": None }) self.test_model.res_queue.put(msg) # start dispatch messages thread = Thread(target=self.test_model._resolve_responses) thread.daemon = True thread.start() while self.test_model.res_queue.empty() is False: pass event_msg_ans = Message( { "code": 200, "method": "get", "resource": "/not_found/12345", "data": None }, generate_id=False) event_msg = self.test_model.req_queue.get() self.assertEqual(event_msg_ans.to_dict(), event_msg.to_dict()) self.assertEqual(event_msg.type(), MessageType.EVENT) self.test_model.res_queue.put(None) thread.join()
def test__dispatch_message(self): # noqa resp = Mock() self.test_model.publish.create_response = Mock(return_value=resp) # case 1: not found with patch.object(self.test_model.router, "dispatch") as dispatch: dispatch.return_value = [] m = Message({"resource": "/"}) self.test_model._Sanji__dispatch_message(m) resp.assert_called_once_with( code=404, data={"message": ANY}) # case 2: normal def cb(self, message, response): response(code=200, data=message.to_dict()) resp.reset_mock() with patch.object(self.test_model.router, "dispatch") as dispatch: dispatch.return_value = [{ "handlers": [{ "callback": cb, "method": "put", "reentrant": False, "schema": None }], "message": Message({}) }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=200, data={}) # case 3: internal error resp.reset_mock() dispatch.return_value = [{ "handlers": [{ "callback": Mock(side_effect=Exception("TEST")) }], "message": Message({}) }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with( code=500, data={"message": "Internal Error.", "traceback": ANY}) # case 4: schema resp.reset_mock() schema = Schema({ Required('q'): All(str, Length(min=1)), Required('per_page', default=5): All( int, Range(min=1, max=20)), 'page': All(int, Range(min=0)), }) def schema_cb(self, message, response): response(code=200, data=message.to_dict()) m = Message({ "data": { "q": "abc", "per_page": 5, "page": 12 } }) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=200, data=m.to_dict()) # case 5: schema error resp.reset_mock() m = Message({ "data": { "q": "abc", "per_page": 5, "page": "12" # change this to str } }) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with( code=400, data={"message": "expected int for dictionary value @ data['page']"}) # case 6: schema with extra resp.reset_mock() schema_extra = Schema({ Required('q'): All(str, Length(min=1)) }, extra=REMOVE_EXTRA) m = Message({ "data": { "q": "abc", "extram_data": "remove_me" # extra data } }) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema_extra }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with( code=200, data={ "data": { "q": "abc" } } )
def test_to_dict(self): msg = Message({}) for prop in msg.to_dict(): self.assertNotEqual(prop.find("_"), 0)
def test__dispatch_message(self): # noqa resp = Mock() self.test_model.publish.create_response = Mock(return_value=resp) # case 1: not found with patch.object(self.test_model.router, "dispatch") as dispatch: dispatch.return_value = [] m = Message({"resource": "/"}) self.test_model._Sanji__dispatch_message(m) resp.assert_called_once_with(code=404, data={"message": ANY}) # case 2: normal def cb(self, message, response): response(code=200, data=message.to_dict()) resp.reset_mock() with patch.object(self.test_model.router, "dispatch") as dispatch: dispatch.return_value = [{ "handlers": [{ "callback": cb, "method": "put", "reentrant": False, "schema": None }], "message": Message({}) }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=200, data={}) # case 3: internal error resp.reset_mock() dispatch.return_value = [{ "handlers": [{ "callback": Mock(side_effect=Exception("TEST")) }], "message": Message({}) }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=500, data={ "message": "Internal Error.", "traceback": ANY }) # case 4: schema resp.reset_mock() schema = Schema({ Required('q'): All(str, Length(min=1)), Required('per_page', default=5): All(int, Range(min=1, max=20)), 'page': All(int, Range(min=0)), }) def schema_cb(self, message, response): response(code=200, data=message.to_dict()) m = Message({"data": {"q": "abc", "per_page": 5, "page": 12}}) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=200, data=m.to_dict()) # case 5: schema error resp.reset_mock() m = Message({ "data": { "q": "abc", "per_page": 5, "page": "12" # change this to str } }) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with( code=400, data={ "message": "expected int for dictionary value @ data['page']" }) # case 6: schema with extra resp.reset_mock() schema_extra = Schema({Required('q'): All(str, Length(min=1))}, extra=REMOVE_EXTRA) m = Message({ "data": { "q": "abc", "extram_data": "remove_me" # extra data } }) dispatch.return_value = [{ "handlers": [{ "callback": schema_cb, "schema": schema_extra }], "message": m }] self.test_model._Sanji__dispatch_message(None) resp.assert_called_once_with(code=200, data={"data": {"q": "abc"}})