-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Commit adds nfc rpc unit tests. Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
- Loading branch information
Showing
10 changed files
with
792 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(nfc_rpc_t2t_client_test) | ||
|
||
FILE(GLOB app_sources src/*.c) | ||
|
||
target_include_directories(app PRIVATE | ||
# Needed to access OpenThread RPC command IDs. | ||
${ZEPHYR_NRF_MODULE_DIR}/subsys/nfc/rpc/common | ||
../common | ||
) | ||
|
||
target_sources(app PRIVATE | ||
${app_sources} | ||
../common/nrf_rpc_single_thread.c | ||
) | ||
|
||
zephyr_include_directories(${ZEPHYR_NRFXLIB_MODULE_DIR}/nfc/include/) | ||
|
||
# Enforce single-threaded nRF RPC command processing. | ||
target_link_options(app PUBLIC | ||
-Wl,--wrap=nrf_rpc_os_init,--wrap=nrf_rpc_os_thread_pool_send | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
CONFIG_ZTEST=y | ||
|
||
CONFIG_NFC_RPC=y | ||
CONFIG_NFC_RPC_CLIENT=y | ||
|
||
CONFIG_NRF_RPC_CBKPROXY_OUT_SLOTS=0 | ||
|
||
CONFIG_MOCK_NRF_RPC=y | ||
CONFIG_MOCK_NRF_RPC_TRANSPORT=y | ||
|
||
CONFIG_KERNEL_MEM_POOL=y | ||
CONFIG_HEAP_MEM_POOL_SIZE=4096 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
#include <mock_nrf_rpc_transport.h> | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/kernel.h> | ||
|
||
#include <nfc_t2t_lib.h> | ||
|
||
#include <nrf_rpc/nrf_rpc_cbkproxy.h> | ||
|
||
#include <nfc_rpc_ids.h> | ||
#include <nfc_rpc_common.h> | ||
#include <test_rpc_env.h> | ||
|
||
static int slot_cnt; | ||
static bool cb_called; | ||
|
||
static void nrf_rpc_err_handler(const struct nrf_rpc_err_report *report) | ||
{ | ||
zassert_ok(report->code); | ||
} | ||
|
||
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(); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_setup() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_setup) | ||
{ | ||
int error; | ||
nfc_t2t_callback_t cb = (nfc_t2t_callback_t)0xdeadbeef; | ||
void *cb_ctx = (void *)0xcafeface; | ||
|
||
mock_nrf_rpc_tr_expect_add( | ||
RPC_CMD(NFC_RPC_CMD_T2T_SETUP, slot_cnt, CBOR_UINT32(0xcafeface)), RPC_RSP(0)); | ||
error = nfc_t2t_setup(cb, cb_ctx); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_parameter_set() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_parameter_set) | ||
{ | ||
int error; | ||
uint8_t data[DATA_SIZE] = {INT_SEQUENCE(DATA_SIZE)}; | ||
|
||
mock_nrf_rpc_tr_expect_add( | ||
RPC_CMD(NFC_RPC_CMD_T2T_PARAMETER_SET, NFC_T2T_PARAM_NFCID1, NFC_DATA), RPC_RSP(0)); | ||
error = nfc_t2t_parameter_set(NFC_T2T_PARAM_NFCID1, data, DATA_SIZE); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_parameter_set() with NULL data */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_parameter_set_null) | ||
{ | ||
int error; | ||
|
||
error = nfc_t2t_parameter_set(NFC_T2T_PARAM_NFCID1, NULL, 10); | ||
zassert_equal(error, -NRF_EINVAL); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_parameter_get() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_parameter_get) | ||
{ | ||
int error; | ||
uint8_t expected_data[DATA_SIZE] = {INT_SEQUENCE(DATA_SIZE)}; | ||
uint8_t data[DATA_SIZE]; | ||
size_t max_data_length = DATA_SIZE; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_PARAMETER_GET, NFC_T2T_PARAM_FDT_MIN, | ||
CBOR_UINT8(DATA_SIZE)), | ||
RPC_RSP(NFC_DATA)); | ||
error = nfc_t2t_parameter_get(NFC_T2T_PARAM_FDT_MIN, data, &max_data_length); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
zassert_mem_equal(data, expected_data, DATA_SIZE); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_parameter_get() with NULL data */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_parameter_get_null) | ||
{ | ||
int error; | ||
uint8_t data[DATA_SIZE]; | ||
size_t max_data_length = DATA_SIZE; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_PARAMETER_GET, NFC_T2T_PARAM_FDT_MIN, | ||
CBOR_UINT8(DATA_SIZE)), | ||
RPC_RSP(CBOR_NULL)); | ||
error = nfc_t2t_parameter_get(NFC_T2T_PARAM_FDT_MIN, data, &max_data_length); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, -NRF_EINVAL); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_payload_set() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_payload_set) | ||
{ | ||
int error; | ||
uint8_t data[NFC_T2T_MAX_PAYLOAD_SIZE]; | ||
mock_nrf_rpc_pkt_t expected_pkt; | ||
uint8_t expected_data[NFC_T2T_MAX_PAYLOAD_SIZE + 9] = { | ||
0x80, NFC_RPC_CMD_T2T_PAYLOAD_SET, 0xff, 0x00, 0x00, 0x59, 0x03, 0xdc}; | ||
|
||
for (int i = 0; i < NFC_T2T_MAX_PAYLOAD_SIZE; i++) { | ||
data[i] = i + 1; | ||
expected_data[8 + i] = i + 1; | ||
} | ||
expected_data[NFC_T2T_MAX_PAYLOAD_SIZE + 8] = 0xf6; | ||
|
||
expected_pkt.data = expected_data; | ||
expected_pkt.len = sizeof(expected_data); | ||
mock_nrf_rpc_tr_expect_add(expected_pkt, RPC_RSP(0)); | ||
error = nfc_t2t_payload_set(data, NFC_T2T_MAX_PAYLOAD_SIZE); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_payload_set() with NULL data */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_payload_set_null) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_PAYLOAD_SET, CBOR_NULL), RPC_RSP(0)); | ||
error = nfc_t2t_payload_set(NULL, NFC_T2T_MAX_PAYLOAD_SIZE); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_payload_set() with zero length */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_payload_set_zero) | ||
{ | ||
int error; | ||
uint8_t data[DATA_SIZE] = {INT_SEQUENCE(DATA_SIZE)}; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_PAYLOAD_SET, 0x40), RPC_RSP(0)); | ||
error = nfc_t2t_payload_set(data, 0); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_payload_raw_set() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_payload_raw_set) | ||
{ | ||
int error; | ||
uint8_t data[NFC_T2T_MAX_PAYLOAD_SIZE_RAW]; | ||
mock_nrf_rpc_pkt_t expected_pkt; | ||
uint8_t expected_data[NFC_T2T_MAX_PAYLOAD_SIZE_RAW + 9] = { | ||
0x80, NFC_RPC_CMD_T2T_PAYLOAD_RAW_SET, 0xff, 0, 0, 0x59, 0x03, 0xf0}; | ||
|
||
for (int i = 0; i < NFC_T2T_MAX_PAYLOAD_SIZE_RAW; i++) { | ||
data[i] = i + 1; | ||
expected_data[8 + i] = i + 1; | ||
} | ||
expected_data[NFC_T2T_MAX_PAYLOAD_SIZE_RAW + 8] = 0xf6; | ||
|
||
expected_pkt.data = expected_data; | ||
expected_pkt.len = sizeof(expected_data); | ||
mock_nrf_rpc_tr_expect_add(expected_pkt, RPC_RSP(0)); | ||
error = nfc_t2t_payload_raw_set(data, NFC_T2T_MAX_PAYLOAD_SIZE_RAW); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_payload_raw_set() with NULL data */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_payload_raw_set_null) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_PAYLOAD_RAW_SET, CBOR_NULL), RPC_RSP(0)); | ||
error = nfc_t2t_payload_raw_set(NULL, NFC_T2T_MAX_PAYLOAD_SIZE_RAW); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_internal_set() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_internal_set) | ||
{ | ||
int error; | ||
uint8_t data[DATA_SIZE] = {INT_SEQUENCE(DATA_SIZE)}; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_INTERNAL_SET, NFC_DATA), RPC_RSP(0)); | ||
error = nfc_t2t_internal_set(data, DATA_SIZE); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_internal_set() with NULL data */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_internal_set_null) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_INTERNAL_SET, CBOR_NULL), RPC_RSP(0)); | ||
error = nfc_t2t_internal_set(NULL, DATA_SIZE); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_emulation_start() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_emulation_start) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_EMULATION_START), RPC_RSP(0)); | ||
error = nfc_t2t_emulation_start(); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_emulation_stop() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_emulation_stop) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_EMULATION_STOP), RPC_RSP(0)); | ||
error = nfc_t2t_emulation_stop(); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
/* Test serialization of nfc_t2t_done() */ | ||
ZTEST(nfc_rpc_t2t_cli, test_nfc_t2t_done) | ||
{ | ||
int error; | ||
|
||
mock_nrf_rpc_tr_expect_add(RPC_CMD(NFC_RPC_CMD_T2T_DONE), RPC_RSP(0)); | ||
error = nfc_t2t_done(); | ||
mock_nrf_rpc_tr_expect_done(); | ||
zassert_equal(error, 0); | ||
} | ||
|
||
static void t2t_cb(void *context, nfc_t2t_event_t event, const uint8_t *data, size_t data_length) | ||
{ | ||
uint8_t expected_data[DATA_SIZE] = {INT_SEQUENCE(DATA_SIZE)}; | ||
|
||
cb_called = true; | ||
zassert_not_null(data); | ||
zassert_not_null(context); | ||
zassert_equal_ptr(context, (void *)0xdeadbeef); | ||
zassert_equal(event, NFC_T2T_EVENT_DATA_READ); | ||
zassert_equal(data_length, DATA_SIZE); | ||
zassert_mem_equal(data, expected_data, data_length); | ||
} | ||
|
||
/* Test reception of t2t callback. */ | ||
ZTEST(nfc_rpc_t2t_cli, test_t2t_cb_handler) | ||
{ | ||
|
||
int in_slot = nrf_rpc_cbkproxy_in_set(t2t_cb); | ||
|
||
slot_cnt++; | ||
cb_called = false; | ||
mock_nrf_rpc_tr_expect_add(RPC_RSP(), NO_RSP); | ||
mock_nrf_rpc_tr_receive(RPC_CMD(NFC_RPC_CMD_T2T_CB, NFC_T2T_EVENT_DATA_READ, NFC_DATA, | ||
CBOR_UINT32(0xdeadbeef), in_slot)); | ||
mock_nrf_rpc_tr_expect_done(); | ||
|
||
zassert_true(cb_called); | ||
} | ||
|
||
ZTEST_SUITE(nfc_rpc_t2t_cli, NULL, NULL, tc_setup, NULL, NULL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
tests: | ||
nfc.rpc.client: | ||
sysbuild: true | ||
platform_allow: native_sim | ||
tags: nfc ci_build sysbuild | ||
integration_platforms: | ||
- native_sim |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
/* | ||
* Replacement implementation of selected nRF RPC OS functions, which enables single-threaded | ||
* processing of a received nRF RPC command. | ||
* | ||
* Typically, an nRF RPC command that initiates a conversation is dispatched by the nRF RPC core | ||
* using a dedicated thread pool. In unit tests, however, it is preferable to dispatch the command | ||
* synchronously so that no operation timeouts are needed to detect a test case failure. | ||
*/ | ||
|
||
#include <nrf_rpc_os.h> | ||
|
||
#include <zephyr/ztest.h> | ||
|
||
static nrf_rpc_os_work_t receive_callback; | ||
|
||
int __real_nrf_rpc_os_init(nrf_rpc_os_work_t callback); | ||
|
||
int __wrap_nrf_rpc_os_init(nrf_rpc_os_work_t callback) | ||
{ | ||
receive_callback = callback; | ||
|
||
return __real_nrf_rpc_os_init(callback); | ||
} | ||
|
||
void __wrap_nrf_rpc_os_thread_pool_send(const uint8_t *data, size_t len) | ||
{ | ||
zassert_not_null(receive_callback); | ||
|
||
receive_callback(data, len); | ||
} |
Oops, something went wrong.