Example #1
0
    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)
Example #2
0
    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()
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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()
Example #6
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"
                    }
                }
            )
Example #7
0
 def test_to_dict(self):
     msg = Message({})
     for prop in msg.to_dict():
         self.assertNotEqual(prop.find("_"), 0)
Example #8
0
 def test_to_dict(self):
     msg = Message({})
     for prop in msg.to_dict():
         self.assertNotEqual(prop.find("_"), 0)
Example #9
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"}})