Skip to content

Commit

Permalink
nrf_rpc: Add test for ot_message allocations.
Browse files Browse the repository at this point in the history
Commit adds unit tests for ot message manipulation in nrf rpc Openthread
part.

Signed-off-by: Przemyslaw Bida <[email protected]>
  • Loading branch information
canisLupus1313 authored and nordicjm committed Nov 20, 2024
1 parent 695f98a commit 78d6882
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 12 deletions.
12 changes: 12 additions & 0 deletions subsys/net/openthread/rpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion subsys/net/openthread/rpc/client/ot_rpc_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
12 changes: 8 additions & 4 deletions subsys/net/openthread/rpc/server/ot_rpc_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

#include <zephyr/net/openthread.h>

#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;
Expand Down Expand Up @@ -118,17 +122,17 @@ 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);
return;
}

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) {
Expand Down
9 changes: 2 additions & 7 deletions tests/subsys/net/openthread/rpc/server/src/coap_suite.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include <openthread/coap.h>

#include "common_fakes.h"

/* Message address used when testing serialization of a function that takes otMessage* */
#define MSG_ADDR UINT32_MAX

Expand All @@ -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,
Expand All @@ -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); \
Expand Down
14 changes: 14 additions & 0 deletions tests/subsys/net/openthread/rpc/server/src/common_fakes.c
Original file line number Diff line number Diff line change
@@ -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 *);
19 changes: 19 additions & 0 deletions tests/subsys/net/openthread/rpc/server/src/common_fakes.h
Original file line number Diff line number Diff line change
@@ -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 <zephyr/fff.h>
#include <openthread/message.h>

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
161 changes: 161 additions & 0 deletions tests/subsys/net/openthread/rpc/server/src/message_suite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <mock_nrf_rpc_transport.h>
#include <ot_rpc_ids.h>
#include <ot_rpc_message.h>
#include <test_rpc_env.h>

#include <zephyr/fff.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>

#include <openthread/message.h>
#include "common_fakes.h"
#include "zephyr/ztest_assert.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>

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);

0 comments on commit 78d6882

Please sign in to comment.