Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf_rpc: Add test for ot_message allocations. #18902

Merged
merged 1 commit into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
canisLupus1313 marked this conversation as resolved.
Show resolved Hide resolved

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