Esempio n. 1
0
    def test_send(self):
        rpc = MsgpackRpc()
        con_send_mock = mocks.rpc_connection_send(rpc)
        m1 = MRequest()

        with self.assertRaises(InvalidMessageError):
            rpc.send(m1)

        m1.function = "run"
        m1.arguments = []

        rpc.send(m1)
        self.assertIsNone(rpc._response_callbacks.get(m1.get_msgid()))

        con_send_mock.assert_called_once_with(m1.pack())
        con_send_mock.reset_mock()

        def r_cb():
            pass

        rpc.send(m1, r_cb)
        self.assertEqual(rpc._response_callbacks[m1.get_msgid()], r_cb)

        con_send_mock.side_effect = BrokenPipeError()
        with self.assertRaises(BrokenPipeError):
            rpc.send(m1)

        with self.assertRaises(InvalidMessageError):
            rpc.send(None)
Esempio n. 2
0
    def from_msgpack_request(msg: MRequest):
        """ Generates an ApiRun object from a given MRequest

        :param msg: A Request received and unpacked with MsgpackRpc. It is
                    assumed, that the strings in msg.body are still in
                    binary format!
        :return: ApiRun
        :raises  InvalidMessageError: if provided message is
                    not a valid Run call
        """

        if not isinstance(msg.function, str) or msg.function != "run":
            raise InvalidMessageError(
                "Invalid run Request, specified method is not run")

        if not isinstance(msg.arguments, list) or len(msg.arguments) != 3:
            raise InvalidMessageError("Message body is faulty")

        if not isinstance(msg.arguments[0],
                          list) or len(msg.arguments[0]) != 2:
            raise InvalidMessageError("First element of body has to be a list")

        if msg.arguments[0][0] is not None:
            raise InvalidMessageError("Plugin identifier set on incomming msg")

        if not isinstance(msg.arguments[0][1], int):
            raise InvalidMessageError("Call_id is invaild")

        if not isinstance(msg.arguments[1], bytes):
            raise InvalidMessageError("Function name is not bytes")

        if not isinstance(msg.arguments[2], list):
            raise InvalidMessageError("Third element of body has to be a list")

        msg = copy.deepcopy(msg)
        msg.arguments[1] = msg.arguments[1].decode('ascii')

        for arg in msg.arguments[2]:
            if not isinstance(arg, ApiRun._valid_types):
                raise InvalidMessageError("Invalid Argument type!")

        call = ApiRun("", msg.arguments[1], msg.arguments[2])
        call.msg._msgid = msg._msgid  # keep the original msg_id

        return call
    def test_complete_run(self):
        # In this test a plugin is created and is calling itself.
        # The called_lock is used to ensure that we receive
        # the response before the result
        called_lock = Lock()
        called_lock.acquire()

        def add(a: ctypes.c_int64, b: ctypes.c_int64):
            "add two ints"
            called_lock.acquire()
            return a + b

        RemoteFunction(add)

        core = Core()
        plug = Plugin("foo", "bar", "bob", "alice", core)
        rplug = RemotePlugin("plugin_id", "foo", "bar", "bob", "alice", core)

        mock_send = mocks.rpc_connection_send(core._rpc)
        result = rplug.run("add", [7, 8])

        # receive request
        msg = MRequest.from_unpacked(msgpack.unpackb(
            mock_send.call_args[0][0]))
        msg.arguments[0][0] = None  # remove plugin id
        msg.arguments[0][1] = 123  # set call id
        core._rpc._message_callback(msg.pack())

        # receive response
        data = mock_send.call_args_list[1][0][0]
        core._rpc._message_callback(data)

        # start execution
        called_lock.release()
        # wait for execution to finish
        plug._active_threads[123].join()
        # receive result
        data = mock_send.call_args_list[2][0][0]
        core._rpc._message_callback(data)

        self.assertEqual(result.get_result(blocking=True), 15)
        self.assertEqual(result.get_status(), 2)
        self.assertEqual(result._error, None)
        self.assertEqual(result.get_id(), 123)
Esempio n. 4
0
    def __init__(self, plugin_id: str, function_name: str, args: []):
        super().__init__()

        if not isinstance(plugin_id, str):
            raise InvalidApiCallError("plugin identifier has to be a string")

        if not isinstance(function_name, str):
            raise InvalidApiCallError("function name has to be a string")

        if args is None:
            args = []

        for arg in args:
            if not isinstance(arg, ApiRun._valid_types):
                raise InvalidApiCallError("Invalid Argument type!")

        self.msg = MRequest()
        self.msg.function = "run"
        self.msg.arguments = [[plugin_id, None], function_name, args]
Esempio n. 5
0
    def test_10_handle_run(self):
        core = Core()
        plug = Plugin("foo", "bar", "bob", "alice", core)
        send = mocks.core_rpc_send(core)  # catch results/responses

        mock = Mock()
        mock.__name__ = "foo"
        mock.return_value = "return"
        plug.functions["foo"] = mock
        plug.function_meta["foo"] = (["", []])

        msg = MRequest()
        msg.function = "run"
        msg.arguments = [[None, 123], b'foo', [1, 1.1, "hi"]]

        error, response = plug._handle_run(msg)
        self.assertIsNotNone(plug._active_threads.get(123))

        plug._active_threads.pop(123).join()
        mock.assert_called_with([1, 1.1, "hi"])
        # request was valid  + 1x result
        self.assertEqual(send.call_count, 1)
        self.assertEqual(send.call_args_list[0][0][0].arguments[0][0], 123)
        self.assertEqual(send.call_args_list[0][0][0].arguments[1][0],
                         "return")

        # (response is sent by msgpack-rpc handler)
        self.assertEqual(response, [123])
        self.assertIsNone(error)

        send.reset_mock()  # reset call count
        msg.arguments = [[None, 123], b'mock', [1, 1.1, "hi"]]
        error, response = plug._handle_run(msg)
        # request was invalid -> error response
        self.assertEqual(error, [404, "Function does not exist!"])
        self.assertIsNone(response)
        with self.assertRaises(KeyError):
            plug._active_threads[123]

        send.reset_mock()  # reset call count
        msg.arguments = [None, b'mock', [1, 1.1, "hi"]]
        error, response = plug._handle_run(msg)
        # request was invalid -> error response
        self.assertEqual(error, [400, "Message is not a valid run call"])
        self.assertIsNone(response)

        with self.assertRaises(KeyError):
            plug._active_threads[123]
Esempio n. 6
0
    def test_message_callback(self):
        rpc = MsgpackRpc()
        mock_send = mocks.rpc_send(rpc)

        dispatch = mocks.rpc_dispatch(rpc, "run")
        m_req = MRequest()
        m_req.function = "run"
        m_req.arguments = []
        dispatch.return_value = (None, [])

        rpc._message_callback(m_req.pack())
        dispatch.assert_called_once_with(m_req)

        handle_response = mocks.rpc_handle_response(rpc)
        m_res = MResponse(1)
        m_res.response = []
        rpc._message_callback(m_res.pack())
        handle_response.assert_called_once_with(m_res)

        handle_notify = mocks.rpc_handle_notify(rpc)
        m_not = MNotify("test", [])
        rpc._message_callback(m_not.pack())
        handle_notify.assert_called_once_with(m_not)

        handle_notify.side_effect = InvalidMessageError("not")
        handle_response.side_effect = InvalidMessageError("res")
        dispatch.side_effect = InvalidMessageError("req")

        rpc._message_callback(m_req.pack())
        self.assertEqual(mock_send.call_args[0][0].error[1],
                         "Could not handle request! req")

        rpc._message_callback(msgpack.packb(["hi"]))
        self.assertEqual(mock_send.call_args[0][0].error[0], 400)

        # handle unexpected exception
        dispatch.side_effect = TypeError()
        rpc._message_callback(m_req.pack())
        self.assertEqual(mock_send.call_args[0][0].error[1],
                         "Unexpected exception occurred!")
Esempio n. 7
0
 def __init__(self):
     self.msg = MRequest()
Esempio n. 8
0
    def test_MRequest(self):
        msg = MRequest()
        msg.function = "foo"
        msg.arguments = []
        self.assertEqual(msg.pack(), msgpack.packb([0, msg._msgid, "foo", []]))

        with self.assertRaises(InvalidMessageError):
            msg.arguments = None
            msg.pack()

        with self.assertRaises(InvalidMessageError):
            msg.function = None
            msg.arguments = []
            msg.pack()
        pass
Esempio n. 9
0
    def test_30_run_from_msgpack_request(self):
        msg = MRequest()
        msg.function = "run"

        msg.arguments = [[None, 123], b'fun', []]
        call = ApiRun.from_msgpack_request(msg)
        self.assertEqual(call.__class__, ApiRun("a", "b", []).__class__)
        self.assertEqual(call.msg.arguments[1],
                         msg.arguments[1].decode('ascii'))

        msg.function = None
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.function = "run"
        msg.arguments = [[None], b'fun', []]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = [[b'id should not be set', 123], b'fun', []]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = ["not a list", b'fun', []]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = [[None, 123], b'fun', "not a list"]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = [[None, "not an int"], b'fun', []]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = [[None, 123], "not bytes", []]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = 123
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = []
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)

        msg.arguments = [[None, 123], b'fun', [None]]
        with self.assertRaises(InvalidMessageError):
            ApiRun.from_msgpack_request(msg)