Add mock RPC interface
Add comparators for the RPC parameter types and mock RPC interface.
Signed-off-by: Imre Kis <imre.kis@arm.com>
Change-Id: I9a927cc35a5dcb346d4c2e2a04b34c8a8d2460fb
diff --git a/components/rpc/common/test/call_param_buf_comparator.h b/components/rpc/common/test/call_param_buf_comparator.h
new file mode 100644
index 0000000..6bfa727
--- /dev/null
+++ b/components/rpc/common/test/call_param_buf_comparator.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef CALL_PARAM_BUF_COMPARATOR_H_
+#define CALL_PARAM_BUF_COMPARATOR_H_
+
+#include <CppUTestExt/MockSupport.h>
+#include "../endpoint/rpc_interface.h"
+
+class call_param_buf_comparator : public MockNamedValueComparator
+{
+public:
+ enum check_mode {
+ mode_normal = 0,
+ mode_ignore_data_len
+ };
+
+ call_param_buf_comparator(check_mode mode = mode_normal) : mode(mode)
+ {
+ }
+
+ virtual bool isEqual(const void *object1, const void *object2)
+ {
+ struct call_param_buf *buf1 = (struct call_param_buf *)object1;
+ struct call_param_buf *buf2 = (struct call_param_buf *)object2;
+
+ return (buf1->size == buf2->size) &&
+ (mode == mode_ignore_data_len || (buf1->data_len == buf2->data_len)) &&
+ (buf1->data == buf2->data);
+ }
+
+ // LCOV_EXCL_START
+ virtual SimpleString valueToString(const void *object)
+ {
+ struct call_param_buf *buf = (struct call_param_buf *)object;
+
+ return StringFromFormat("<size = %zu, data_len = %zu%s, data = %p>",
+ buf->size, buf->data_len,
+ (mode == mode_ignore_data_len) ? " (ignored)" : "",
+ buf->data);
+ }
+ // LCOV_EXCL_STOP
+
+private:
+ check_mode mode;
+};
+
+#endif /* CALL_PARAM_BUF_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/call_req_comparator.h b/components/rpc/common/test/call_req_comparator.h
new file mode 100644
index 0000000..753bab2
--- /dev/null
+++ b/components/rpc/common/test/call_req_comparator.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef CALL_REQ_COMPARATOR_H_
+#define CALL_REQ_COMPARATOR_H_
+
+#include <CppUTestExt/MockSupport.h>
+#include <inttypes.h>
+#include "call_param_buf_comparator.h"
+
+class call_req_comparator : public MockNamedValueComparator
+{
+public:
+ enum check_mode {
+ mode_normal = 0,
+ mode_ignore_opstatus
+ };
+
+ call_req_comparator(check_mode mode) : mode(mode)
+ {
+ }
+
+ virtual bool isEqual(const void *object1, const void *object2)
+ {
+ struct call_req *req1 = (struct call_req *)object1;
+ struct call_req *req2 = (struct call_req *)object2;
+ call_param_buf_comparator buf_comparator_normal;
+ call_param_buf_comparator buf_comparator_ignore_data_len(
+ call_param_buf_comparator::mode_ignore_data_len);
+
+ return (req1->caller_id == req2->caller_id) &&
+ (req1->interface_id == req2->interface_id) &&
+ (req1->opcode == req2->opcode) &&
+ (req1->encoding == req2->encoding) &&
+ (mode == mode_ignore_opstatus || req1->opstatus == req2->opstatus) &&
+ buf_comparator_normal.isEqual(&req1->req_buf, &req2->req_buf) &&
+ buf_comparator_ignore_data_len.isEqual(&req1->resp_buf, &req2->resp_buf);
+ }
+
+ // LCOV_EXCL_START
+ virtual SimpleString valueToString(const void *object)
+ {
+ struct call_req *req = (struct call_req *)object;
+ call_param_buf_comparator buf_comparator_normal;
+ call_param_buf_comparator buf_comparator_ignore_data_len(
+ call_param_buf_comparator::mode_ignore_data_len);
+ SimpleString req_buf_str = buf_comparator_normal.valueToString(&req->req_buf);
+ SimpleString resp_buf_str =
+ buf_comparator_ignore_data_len.valueToString(&req->resp_buf);
+
+ return StringFromFormat("caller_id = 0x%" PRIx32 ", interface_id = %" PRIu32 ", " \
+ "opcode = %" PRIu32 ", encoding = %" PRIu32 ", " \
+ "opstatus = 0x%" PRIx64 "%s, req_buf = %s, " \
+ "resp_buf = %s",
+ req->caller_id, req->interface_id, req->opcode,
+ req->encoding, req->opstatus,
+ (mode == mode_ignore_opstatus) ? " (ignore)" : "",
+ req_buf_str.asCharString(), resp_buf_str.asCharString());
+ }
+ // LCOV_EXCL_STOP
+
+private:
+ check_mode mode;
+};
+
+#endif /* CALL_REQ_COMPARATOR_H_ */
diff --git a/components/rpc/common/test/mock_rpc_interface.cpp b/components/rpc/common/test/mock_rpc_interface.cpp
new file mode 100644
index 0000000..af3836d
--- /dev/null
+++ b/components/rpc/common/test/mock_rpc_interface.cpp
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <CppUTestExt/MockSupport.h>
+#include "mock_rpc_interface.h"
+#include "call_req_comparator.h"
+
+static call_req_comparator req_comparator(call_req_comparator::mode_ignore_opstatus);
+
+void mock_rpc_interface_init(void)
+{
+ mock().installComparator("call_req", req_comparator);
+}
+
+void expect_mock_rpc_interface_receive(struct rpc_interface *iface,
+ const struct call_req *req, rpc_status_t result)
+{
+ mock().expectOneCall("rpc_interface_receive").
+ onObject(iface).
+ withOutputParameterReturning("opstatus", &req->opstatus, sizeof(req->opstatus)).
+ withOutputParameterReturning("resp_buf_data_len", &req->resp_buf.data_len,
+ sizeof(req->resp_buf.data_len)).
+ withParameterOfType("call_req", "req", req).
+ andReturnValue(result);
+}
+
+rpc_status_t mock_rpc_interface_receive(struct rpc_interface *iface,
+ struct call_req *req)
+{
+ return mock().actualCall("rpc_interface_receive").
+ onObject(iface).
+ withOutputParameter("opstatus", &req->opstatus).
+ withOutputParameter("resp_buf_data_len", &req->resp_buf.data_len).
+ withParameterOfType("call_req", "req", req).
+ returnIntValue();
+}
diff --git a/components/rpc/common/test/mock_rpc_interface.h b/components/rpc/common/test/mock_rpc_interface.h
new file mode 100644
index 0000000..7e80c4a
--- /dev/null
+++ b/components/rpc/common/test/mock_rpc_interface.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef MOCK_RPC_INTERFACE_H_
+#define MOCK_RPC_INTERFACE_H_
+
+#include "../endpoint/rpc_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mock_rpc_interface_init(void);
+
+void expect_mock_rpc_interface_receive(struct rpc_interface *iface,
+ const struct call_req *req, rpc_status_t result);
+
+rpc_status_t mock_rpc_interface_receive(struct rpc_interface *iface,
+ struct call_req *req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MOCK_RPC_INTERFACE_H_ */
diff --git a/components/rpc/common/test/test_mock_rpc_interface.cpp b/components/rpc/common/test/test_mock_rpc_interface.cpp
new file mode 100644
index 0000000..f3390f0
--- /dev/null
+++ b/components/rpc/common/test/test_mock_rpc_interface.cpp
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+#include <string.h>
+#include "mock_rpc_interface.h"
+
+TEST_GROUP(mock_rpc_interface)
+{
+ TEST_SETUP()
+ {
+ mock_rpc_interface_init();
+ memset(&iface, 0x00, sizeof(iface));
+ }
+
+ TEST_TEARDOWN()
+ {
+ mock().checkExpectations();
+ mock().removeAllComparatorsAndCopiers();
+ mock().clear();
+ }
+
+ struct rpc_interface iface;
+};
+
+TEST(mock_rpc_interface, receive)
+{
+ rpc_status_t res = TS_RPC_ERROR_INTERNAL;
+ struct call_req expected_req = { 0 };
+ struct call_req req = { 0 };
+
+ iface.context = (void *)1;
+ iface.receive = mock_rpc_interface_receive;
+
+ expected_req.caller_id = 0x01234567;
+ expected_req.interface_id = 0x89abcdef;
+ expected_req.opcode = 0xfedcba98;
+ expected_req.encoding = 0x76543210;
+ expected_req.opstatus = (rpc_opstatus_t)-1;
+
+ expected_req.req_buf.size = 1;
+ expected_req.req_buf.data_len = 2;
+ expected_req.req_buf.data = (void *)3;
+
+ expected_req.resp_buf.size = 4;
+ expected_req.resp_buf.data_len = 5;
+ expected_req.resp_buf.data = (void *)6;
+
+ memcpy(&req, &expected_req, sizeof(req));
+ req.opstatus = 0;
+ req.resp_buf.data_len = 0;
+
+ expect_mock_rpc_interface_receive(&iface, &expected_req, res);
+ LONGS_EQUAL(res, mock_rpc_interface_receive(&iface, &req));
+
+ UNSIGNED_LONGLONGS_EQUAL(expected_req.opstatus, req.opstatus);
+ UNSIGNED_LONGLONGS_EQUAL(expected_req.resp_buf.data_len, req.resp_buf.data_len);
+}
diff --git a/components/rpc/common/tests.cmake b/components/rpc/common/tests.cmake
new file mode 100644
index 0000000..edacfca
--- /dev/null
+++ b/components/rpc/common/tests.cmake
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include(UnitTest)
+
+unit_test_add_suite(
+ NAME mock_rpc_interface
+ SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/test/mock_rpc_interface.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/test/test_mock_rpc_interface.cpp
+ INCLUDE_DIRECTORIES
+ ${CMAKE_CURRENT_LIST_DIR}/test
+ ${UNIT_TEST_PROJECT_PATH}
+ ${UNIT_TEST_PROJECT_PATH}/components/rpc/common/interface
+ COMPILE_DEFINITIONS
+ -DARM64
+)