From bf937c8ecb3d36d906c47323f05e3f1337c1bdab Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Fri, 15 Nov 2024 00:51:58 +0100 Subject: [PATCH] nrf_rpc: Add test for ot_message allocations. Commit adds unit tests for ot message manipulation in nrf rpc Openthread part. Signed-off-by: Przemyslaw Bida --- subsys/net/openthread/rpc/Kconfig | 12 ++ .../openthread/rpc/client/ot_rpc_message.c | 2 +- .../openthread/rpc/server/ot_rpc_message.c | 12 +- .../openthread/rpc/server/src/coap_suite.c | 9 +- .../openthread/rpc/server/src/common_fakes.c | 14 ++ .../openthread/rpc/server/src/common_fakes.h | 19 +++ .../openthread/rpc/server/src/message_suite.c | 161 ++++++++++++++++++ 7 files changed, 217 insertions(+), 12 deletions(-) create mode 100644 tests/subsys/net/openthread/rpc/server/src/common_fakes.c create mode 100644 tests/subsys/net/openthread/rpc/server/src/common_fakes.h create mode 100644 tests/subsys/net/openthread/rpc/server/src/message_suite.c diff --git a/subsys/net/openthread/rpc/Kconfig b/subsys/net/openthread/rpc/Kconfig index f2c5748e5cd4..d02fb42417ea 100644 --- a/subsys/net/openthread/rpc/Kconfig +++ b/subsys/net/openthread/rpc/Kconfig @@ -59,6 +59,18 @@ config OPENTHREAD_RPC_CLIENT_NUM_SENT_COAP_REQUESTS endmenu # "OpenThread over RPC client configuration" +menu "OpenThread over RPC client configuration" + depends on OPENTHREAD_RPC_SERVER + +config OPENTHREAD_RPC_MESSAGE_POOL + int "Maximum number of messages key identifiers that can be allocated on server" + default 8 + help + Defines maximum number of messages key indentifiers that can be allocated on server at + the same time. + +endmenu + config OPENTHREAD_RPC_INITIALIZE_NRF_RPC bool "Automatically initialize nRF RPC library" default n diff --git a/subsys/net/openthread/rpc/client/ot_rpc_message.c b/subsys/net/openthread/rpc/client/ot_rpc_message.c index 099893d7a913..510c9ca45842 100644 --- a/subsys/net/openthread/rpc/client/ot_rpc_message.c +++ b/subsys/net/openthread/rpc/client/ot_rpc_message.c @@ -45,7 +45,7 @@ otMessage *otUdpNewMessage(otInstance *aInstance, const otMessageSettings *aSett NRF_RPC_CBOR_ALLOC(&ot_group, ctx, sizeof(otMessageSettings) + 3); - nrf_rpc_encode_buffer(&ctx, (const void *)aSettings, sizeof(otMessageSettings)); + ot_rpc_encode_message_settings(&ctx, aSettings); nrf_rpc_cbor_cmd_rsp_no_err(&ot_group, OT_RPC_CMD_UDP_NEW_MESSAGE, &ctx); diff --git a/subsys/net/openthread/rpc/server/ot_rpc_message.c b/subsys/net/openthread/rpc/server/ot_rpc_message.c index fa2daa338a08..ca8f6880eed4 100644 --- a/subsys/net/openthread/rpc/server/ot_rpc_message.c +++ b/subsys/net/openthread/rpc/server/ot_rpc_message.c @@ -16,12 +16,16 @@ #include -#define OT_MESSAGES_POOL 8 +#define OT_MESSAGES_POOL CONFIG_OPENTHREAD_RPC_MESSAGE_POOL static otMessage *ot_message_registry[OT_MESSAGES_POOL]; ot_msg_key ot_reg_msg_alloc(otMessage *msg) { + if (msg == NULL) { + return 0; + } + for (ot_msg_key i = 0; i < OT_MESSAGES_POOL; i++) { if (ot_message_registry[i] == NULL) { ot_message_registry[i] = msg; @@ -118,9 +122,9 @@ static void ot_rpc_msg_udp_new(const struct nrf_rpc_group *group, struct nrf_rpc ot_msg_key key; struct nrf_rpc_cbor_ctx rsp_ctx; otMessageSettings settings; - otMessageSettings *pSettings; + otMessageSettings *p_settings = &settings; - pSettings = nrf_rpc_decode_buffer(ctx, &settings, sizeof(otMessageSettings)); + p_settings = ot_rpc_decode_message_settings(ctx, &settings); if (!nrf_rpc_decoding_done_and_check(group, ctx)) { ot_rpc_report_cmd_decoding_error(OT_RPC_CMD_UDP_NEW_MESSAGE); @@ -128,7 +132,7 @@ static void ot_rpc_msg_udp_new(const struct nrf_rpc_group *group, struct nrf_rpc } openthread_api_mutex_lock(openthread_get_default_context()); - key = ot_reg_msg_alloc(otUdpNewMessage(openthread_get_default_instance(), pSettings)); + key = ot_reg_msg_alloc(otUdpNewMessage(openthread_get_default_instance(), p_settings)); openthread_api_mutex_unlock(openthread_get_default_context()); if (ot_msg_get(key) == NULL) { diff --git a/tests/subsys/net/openthread/rpc/server/src/coap_suite.c b/tests/subsys/net/openthread/rpc/server/src/coap_suite.c index 0a4459a8bc07..08f6002b4766 100644 --- a/tests/subsys/net/openthread/rpc/server/src/coap_suite.c +++ b/tests/subsys/net/openthread/rpc/server/src/coap_suite.c @@ -15,6 +15,8 @@ #include +#include "common_fakes.h" + /* Message address used when testing serialization of a function that takes otMessage* */ #define MSG_ADDR UINT32_MAX @@ -28,12 +30,6 @@ /* Fake functions */ -FAKE_VALUE_FUNC(otMessage *, otUdpNewMessage, otInstance *, const otMessageSettings *); -FAKE_VALUE_FUNC(uint16_t, otMessageGetLength, const otMessage *); -FAKE_VALUE_FUNC(uint16_t, otMessageGetOffset, const otMessage *); -FAKE_VALUE_FUNC(uint16_t, otMessageRead, const otMessage *, uint16_t, void *, uint16_t); -FAKE_VOID_FUNC(otMessageFree, otMessage *); -FAKE_VALUE_FUNC(otError, otMessageAppend, otMessage *, const void *, uint16_t); FAKE_VALUE_FUNC(otMessage *, otCoapNewMessage, otInstance *, const otMessageSettings *); FAKE_VOID_FUNC(otCoapMessageInit, otMessage *, otCoapType, otCoapCode); FAKE_VALUE_FUNC(otError, otCoapMessageInitResponse, otMessage *, const otMessage *, otCoapType, @@ -56,7 +52,6 @@ FAKE_VALUE_FUNC(otError, otCoapSendResponseWithParameters, otInstance *, otMessa const otMessageInfo *, const otCoapTxParameters *); #define FOREACH_FAKE(f) \ - f(otUdpNewMessage); \ f(otMessageGetLength); \ f(otMessageGetOffset); \ f(otMessageRead); \ diff --git a/tests/subsys/net/openthread/rpc/server/src/common_fakes.c b/tests/subsys/net/openthread/rpc/server/src/common_fakes.c new file mode 100644 index 000000000000..eeaee964a812 --- /dev/null +++ b/tests/subsys/net/openthread/rpc/server/src/common_fakes.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "common_fakes.h" + +DEFINE_FAKE_VALUE_FUNC(uint16_t, otMessageGetLength, const otMessage *); +DEFINE_FAKE_VALUE_FUNC(uint16_t, otMessageGetOffset, const otMessage *); +DEFINE_FAKE_VALUE_FUNC(uint16_t, otMessageRead, const otMessage *, uint16_t, void *, uint16_t); +DEFINE_FAKE_VOID_FUNC(otMessageFree, otMessage *); +DEFINE_FAKE_VALUE_FUNC(otError, otMessageAppend, otMessage *, const void *, uint16_t); +DEFINE_FAKE_VALUE_FUNC(otMessage *, otUdpNewMessage, otInstance *, const otMessageSettings *); diff --git a/tests/subsys/net/openthread/rpc/server/src/common_fakes.h b/tests/subsys/net/openthread/rpc/server/src/common_fakes.h new file mode 100644 index 000000000000..d240357753a9 --- /dev/null +++ b/tests/subsys/net/openthread/rpc/server/src/common_fakes.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef __COMMON_FAKES_H__ +#define __COMMON_FAKES_H__ +#include +#include + +DECLARE_FAKE_VALUE_FUNC(otMessage *, otUdpNewMessage, otInstance *, const otMessageSettings *); +DECLARE_FAKE_VALUE_FUNC(uint16_t, otMessageGetLength, const otMessage *); +DECLARE_FAKE_VALUE_FUNC(uint16_t, otMessageGetOffset, const otMessage *); +DECLARE_FAKE_VALUE_FUNC(uint16_t, otMessageRead, const otMessage *, uint16_t, void *, uint16_t); +DECLARE_FAKE_VOID_FUNC(otMessageFree, otMessage *); +DECLARE_FAKE_VALUE_FUNC(otError, otMessageAppend, otMessage *, const void *, uint16_t); + +#endif diff --git a/tests/subsys/net/openthread/rpc/server/src/message_suite.c b/tests/subsys/net/openthread/rpc/server/src/message_suite.c new file mode 100644 index 000000000000..da838767393f --- /dev/null +++ b/tests/subsys/net/openthread/rpc/server/src/message_suite.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "common_fakes.h" +#include "zephyr/ztest_assert.h" +#include +#include +#include + +static void nrf_rpc_err_handler(const struct nrf_rpc_err_report *report) +{ + zassert_ok(report->code); +} + +#define FOREACH_FAKE(f) \ + f(otMessageGetLength); \ + f(otMessageGetOffset); \ + f(otMessageRead); \ + f(otMessageFree); \ + f(otMessageAppend); \ + f(otUdpNewMessage); + +static void tc_setup(void *f) +{ + mock_nrf_rpc_tr_expect_add(RPC_INIT_REQ, RPC_INIT_RSP); + zassert_ok(nrf_rpc_init(nrf_rpc_err_handler)); + mock_nrf_rpc_tr_expect_reset(); + + FOREACH_FAKE(RESET_FAKE); + FFF_RESET_HISTORY(); +} + +ZTEST(ot_rpc_message, test_otUdpNewMessage_failing) +{ + const uint8_t prio = 40; + + otUdpNewMessage_fake.return_val = NULL; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(0), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_UDP_NEW_MESSAGE, CBOR_NULL)); + + zassert_is_null(otUdpNewMessage_fake.arg1_val); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(0), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_UDP_NEW_MESSAGE, CBOR_TRUE, CBOR_UINT8(prio))); + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otUdpNewMessage_fake.call_count, 2); + zassert_true(otUdpNewMessage_fake.arg1_val->mLinkSecurityEnabled); + zassert_equal(otUdpNewMessage_fake.arg1_val->mPriority, prio); +} + +ZTEST(ot_rpc_message, test_otUdpNewMessage_free_working) +{ + const uint8_t prio = 40; + + otUdpNewMessage_fake.return_val = (otMessage *)1; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(1), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_UDP_NEW_MESSAGE, CBOR_NULL)); + + zassert_is_null(otUdpNewMessage_fake.arg1_val); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(2), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_UDP_NEW_MESSAGE, CBOR_TRUE, CBOR_UINT8(prio))); + + zassert_equal(otUdpNewMessage_fake.call_count, 2); + zassert_true(otUdpNewMessage_fake.arg1_val->mLinkSecurityEnabled); + zassert_equal(otUdpNewMessage_fake.arg1_val->mPriority, prio); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_FREE, 1)); + + zassert_equal(otMessageFree_fake.arg0_val, (otMessage *)1); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_FREE, 2)); + + zassert_equal(otMessageFree_fake.arg0_val, (otMessage *)1); + + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otMessageFree_fake.call_count, 2); +} + +ZTEST(ot_rpc_message, test_ot_reg_msg_alloc_free) +{ + + for (size_t i = 1; i < CONFIG_OPENTHREAD_RPC_MESSAGE_POOL + 1; i++) { + zassert_equal(ot_reg_msg_alloc((otMessage *)i), i); + } + + zassert_equal(ot_reg_msg_alloc((otMessage *)UINT32_MAX), 0); + + for (size_t i = 1; i < CONFIG_OPENTHREAD_RPC_MESSAGE_POOL + 1; i++) { + ot_msg_free(i); + } +} + +ZTEST(ot_rpc_message, test_ot_reg_msg_get) +{ + + zassert_equal(ot_reg_msg_alloc((otMessage *)1), 1); + + zassert_equal(ot_msg_get(1), (otMessage *)1); + + zassert_equal(ot_msg_get(CONFIG_OPENTHREAD_RPC_MESSAGE_POOL), NULL); + + ot_msg_free(1); +} + +ZTEST(ot_rpc_message, test_get_length_offset) +{ + otUdpNewMessage_fake.return_val = (otMessage *)1; + otMessageGetLength_fake.return_val = 1; + otMessageGetOffset_fake.return_val = 1; + + mock_nrf_rpc_tr_expect_add(RPC_RSP(1), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_UDP_NEW_MESSAGE, CBOR_NULL)); + + zassert_equal(otUdpNewMessage_fake.call_count, 1); + zassert_is_null(otUdpNewMessage_fake.arg1_val); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(1), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_GET_LENGTH, 1)); + + zassert_equal(otMessageGetLength_fake.arg0_val, (otMessage *)1); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(1), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_GET_OFFSET, 1)); + + zassert_equal(otMessageGetOffset_fake.arg0_val, (otMessage *)1); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(0), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_GET_LENGTH, 0)); + + mock_nrf_rpc_tr_expect_add(RPC_RSP(), NO_RSP); + mock_nrf_rpc_tr_receive(RPC_CMD(OT_RPC_CMD_MESSAGE_FREE, 1)); + + zassert_equal(otMessageFree_fake.arg0_val, (otMessage *)1); + + mock_nrf_rpc_tr_expect_done(); + + zassert_equal(otMessageGetLength_fake.call_count, 1); + zassert_equal(otMessageFree_fake.call_count, 1); +} + +ZTEST_SUITE(ot_rpc_message, NULL, NULL, tc_setup, NULL, NULL);