From 860ab82b1b4273968deeb0e4a1a3a309e43a3865 Mon Sep 17 00:00:00 2001 From: Martin Engesvold Date: Mon, 18 Aug 2025 14:48:21 +0200 Subject: [PATCH] tests: unittest: Added unittests for bm_nus Added unit tests for subsys bm_nus Signed-off-by: Martin Engesvold --- CODEOWNERS | 1 + .../bluetooth/services/ble_nus/CMakeLists.txt | 44 ++ .../bluetooth/services/ble_nus/prj.conf | 6 + .../services/ble_nus/src/unity_test.c | 551 ++++++++++++++++++ .../bluetooth/services/ble_nus/testcase.yaml | 4 + 5 files changed, 606 insertions(+) create mode 100644 tests/subsys/bluetooth/services/ble_nus/CMakeLists.txt create mode 100644 tests/subsys/bluetooth/services/ble_nus/prj.conf create mode 100644 tests/subsys/bluetooth/services/ble_nus/src/unity_test.c create mode 100644 tests/subsys/bluetooth/services/ble_nus/testcase.yaml diff --git a/CODEOWNERS b/CODEOWNERS index ea8a3dc8ec..b0cc54e444 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -91,6 +91,7 @@ /tests/lib/ble_racp/ @nrfconnect/ncs-bm /tests/lib/ble_adv/ @nrfconnect/ncs-bm-test /tests/lib/bm_storage/ @nrfconnect/ncs-bm +/tests/subsys/bluetooth/services/ble_nus/ @nrfconnect/ncs-bm @nrfconnect/ncs-bm-test # Zephyr module /zephyr/ @nrfconnect/ncs-co-build-system diff --git a/tests/subsys/bluetooth/services/ble_nus/CMakeLists.txt b/tests/subsys/bluetooth/services/ble_nus/CMakeLists.txt new file mode 100644 index 0000000000..83c857e82b --- /dev/null +++ b/tests/subsys/bluetooth/services/ble_nus/CMakeLists.txt @@ -0,0 +1,44 @@ +# +# Copyright (c) 2025 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(unit_test_ble_nus) + +set(SOFTDEVICE_VARIANT "s115") +set(SOFTDEVICE_INCLUDE_DIR + "${ZEPHYR_NRF_BM_MODULE_DIR}/components/softdevice/\ +${SOFTDEVICE_VARIANT}/${SOFTDEVICE_VARIANT}_API/include" +) + +cmock_handle(${SOFTDEVICE_INCLUDE_DIR}/ble.h) +cmock_handle(${SOFTDEVICE_INCLUDE_DIR}/ble_gatts.h) +cmock_handle(${ZEPHYR_NRF_BM_MODULE_DIR}/include/nrf_sdh_ble.h) + +target_compile_definitions(app PRIVATE + NRF54L15_XXAA + SVCALL_AS_NORMAL_FUNCTION + SUPPRESS_INLINE_IMPLEMENTATION + CONFIG_NRF_SDH_BLE_GATT_MAX_MTU_SIZE=498 + CONFIG_NRF_SDH_BLE_TOTAL_LINK_COUNT=3 +) + +target_include_directories(app PRIVATE + ${ZEPHYR_NRF_BM_MODULE_DIR}/include + ${SOFTDEVICE_INCLUDE_DIR} + ${ZEPHYR_HAL_NORDIC_MODULE_DIR}/nrfx/mdk +) + +# Generate and add test file +test_runner_generate(src/unity_test.c) +target_sources(app PRIVATE src/unity_test.c) + +# Unit under test +target_sources(app PRIVATE + ${ZEPHYR_NRF_BM_MODULE_DIR}/subsys/bluetooth/services/ble_nus/nus.c +) diff --git a/tests/subsys/bluetooth/services/ble_nus/prj.conf b/tests/subsys/bluetooth/services/ble_nus/prj.conf new file mode 100644 index 0000000000..a8788847da --- /dev/null +++ b/tests/subsys/bluetooth/services/ble_nus/prj.conf @@ -0,0 +1,6 @@ +# +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# +CONFIG_UNITY=y diff --git a/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c b/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c new file mode 100644 index 0000000000..6aeb599336 --- /dev/null +++ b/tests/subsys/bluetooth/services/ble_nus/src/unity_test.c @@ -0,0 +1,551 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include +#include +#include + +#include +#include + +#include "cmock_ble_gatts.h" +#include "cmock_ble.h" +#include "cmock_nrf_sdh_ble.h" + +BLE_NUS_DEF(ble_nus); +uint16_t test_case_conn_handle = 0x1000; +bool evt_handler_called; +struct ble_nus_client_context *last_link_ctx; + +static uint32_t stub_sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, + uint16_t *p_handle, int calls) +{ + ble_uuid_t expected_uuid = { + .type = 123, + .uuid = BLE_UUID_NUS_SERVICE, + }; + uint16_t expected_conn_handle = BLE_CONN_HANDLE_INVALID; + + TEST_ASSERT_EQUAL(BLE_GATTS_SRVC_TYPE_PRIMARY, type); + TEST_ASSERT_EQUAL(expected_uuid.type, p_uuid->type); + TEST_ASSERT_EQUAL(expected_uuid.uuid, p_uuid->uuid); + TEST_ASSERT_EQUAL(expected_conn_handle, *p_handle); + + return NRF_SUCCESS; +} + +static uint32_t stub_sd_ble_gatts_characteristic_add(uint16_t service_handle, + const ble_gatts_char_md_t *p_char_md, + const ble_gatts_attr_t *p_attr_char_value, + ble_gatts_char_handles_t *p_handles, int calls) +{ + ble_uuid_t expected_char_uuid = {.type = 123}; + + TEST_ASSERT_EQUAL(expected_char_uuid.type, p_attr_char_value->p_uuid->type); + + p_handles->cccd_handle = 0x101; + p_handles->value_handle = 0x102; + + return NRF_SUCCESS; +} + +static uint32_t stub_sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, + ble_gatts_value_t *p_value, int calls) +{ + TEST_ASSERT_EQUAL(test_case_conn_handle, conn_handle); + TEST_ASSERT_EQUAL(0x101, handle); + + *p_value->p_value = BLE_GATT_HVX_NOTIFICATION; + + return NRF_SUCCESS; +} + +static uint32_t stub_sd_ble_gatts_value_get_err(uint16_t conn_handle, uint16_t handle, + ble_gatts_value_t *p_value, int calls) +{ + TEST_ASSERT_EQUAL(test_case_conn_handle, conn_handle); + TEST_ASSERT_EQUAL(0x101, handle); + + switch (calls) { + case 0: + *p_value->p_value = BLE_GATT_HVX_NOTIFICATION; + return NRF_ERROR_INVALID_PARAM; + case 1: + *p_value->p_value = BLE_GATT_HVX_INDICATION; + return NRF_SUCCESS; + default: + return -1; + } + +} + +static void ble_nus_evt_handler_on_connect(const struct ble_nus_evt *evt) +{ + last_link_ctx = evt->link_ctx; + TEST_ASSERT_EQUAL(BLE_NUS_EVT_COMM_STARTED, evt->type); + TEST_ASSERT_TRUE(evt->link_ctx->is_notification_enabled); + evt_handler_called = true; +} + +static void ble_nus_evt_handler_on_connect_null_ctx(const struct ble_nus_evt *evt) +{ + TEST_ASSERT_EQUAL(BLE_NUS_EVT_COMM_STARTED, evt->type); + TEST_ASSERT_NULL(evt->link_ctx); + evt_handler_called = true; +} + +static void ble_nus_evt_handler_on_write_notif(const struct ble_nus_evt *evt) +{ + TEST_ASSERT_EQUAL(BLE_NUS_EVT_COMM_STARTED, evt->type); + TEST_ASSERT_TRUE(evt->link_ctx->is_notification_enabled); + evt_handler_called = true; +} + +static void ble_nus_evt_handler_on_write_indica(const struct ble_nus_evt *evt) +{ + TEST_ASSERT_EQUAL(BLE_NUS_EVT_COMM_STOPPED, evt->type); + TEST_ASSERT_FALSE(evt->link_ctx->is_notification_enabled); + evt_handler_called = true; +} + +static void ble_nus_evt_handler_on_write_value(const struct ble_nus_evt *evt) +{ + TEST_ASSERT_EQUAL(BLE_NUS_EVT_RX_DATA, evt->type); + TEST_ASSERT_EQUAL(0xAB, evt->params.rx_data.data[0]); + TEST_ASSERT_EQUAL(0xCD, evt->params.rx_data.data[1]); + TEST_ASSERT_EQUAL(2, evt->params.rx_data.length); + evt_handler_called = true; +} + +static void ble_nus_evt_handler_on_hvx_tx_complete(const struct ble_nus_evt *evt) +{ + TEST_ASSERT_EQUAL(BLE_NUS_EVT_TX_RDY, evt->type); + TEST_ASSERT_EQUAL_PTR(last_link_ctx, evt->link_ctx); + evt_handler_called = true; +} + +static void init_nus(struct ble_nus_config *nus_cfg) +{ + int ret; + uint8_t expected_uuid_type = 123; + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_uuid_vs_add_ReturnThruPtr_p_uuid_type(&expected_uuid_type); + __cmock_sd_ble_gatts_service_add_Stub(stub_sd_ble_gatts_service_add); + __cmock_sd_ble_gatts_characteristic_add_Stub(stub_sd_ble_gatts_characteristic_add); + + ret = ble_nus_init(&ble_nus, nus_cfg); + TEST_ASSERT_EQUAL(0, ret); + TEST_ASSERT_EQUAL_PTR(nus_cfg->evt_handler, ble_nus.evt_handler); +} + +static void setup_with_notif_enabled(uint16_t conn_handle) +{ + ble_evt_t const ble_evt = { + .evt.gap_evt.conn_handle = conn_handle, + .header.evt_id = BLE_GAP_EVT_CONNECTED + }; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_connect }; + + init_nus(&nus_cfg); + + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get); + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(conn_handle, 0); + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + __cmock_sd_ble_gatts_value_get_Stub(NULL); + + TEST_ASSERT_TRUE(evt_handler_called); +} + +void test_ble_nus_init_efault(void) +{ + int ret; + struct ble_nus_config nus_cfg = {0}; + + ret = ble_nus_init(NULL, &nus_cfg); + TEST_ASSERT_EQUAL(-EFAULT, ret); + + ret = ble_nus_init(&ble_nus, NULL); + TEST_ASSERT_EQUAL(-EFAULT, ret); +} + +void test_ble_nus_init_einval(void) +{ + int ret; + struct ble_nus_config nus_cfg = {0}; + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_PARAM); + ret = ble_nus_init(&ble_nus, &nus_cfg); + TEST_ASSERT_EQUAL(-EINVAL, ret); + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_service_add_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_PARAM); + ret = ble_nus_init(&ble_nus, &nus_cfg); + TEST_ASSERT_EQUAL(-EINVAL, ret); + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_service_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_characteristic_add_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_PARAM); + ret = ble_nus_init(&ble_nus, &nus_cfg); + TEST_ASSERT_EQUAL(-EINVAL, ret); + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_service_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_characteristic_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_gatts_characteristic_add_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_PARAM); + ret = ble_nus_init(&ble_nus, &nus_cfg); + TEST_ASSERT_EQUAL(-EINVAL, ret); +} + +void test_ble_nus_init_success(void) +{ + int ret; + struct ble_nus_config nus_cfg = {0}; + uint8_t expected_uuid_type = 123; + + __cmock_sd_ble_uuid_vs_add_ExpectAnyArgsAndReturn(NRF_SUCCESS); + __cmock_sd_ble_uuid_vs_add_ReturnThruPtr_p_uuid_type(&expected_uuid_type); + + __cmock_sd_ble_gatts_service_add_Stub(stub_sd_ble_gatts_service_add); + __cmock_sd_ble_gatts_characteristic_add_Stub(stub_sd_ble_gatts_characteristic_add); + + ret = ble_nus_init(&ble_nus, &nus_cfg); +} + +void test_ble_nus_on_ble_evt_gap_evt_do_nothing(void) +{ + ble_evt_t const ble_evt = {}; + struct ble_nus nus_ctx = {}; + ble_evt_t empty_ble_evt = {}; + struct ble_nus empty_nus_ctx = {}; + + ble_nus_on_ble_evt(NULL, &nus_ctx); + ble_nus_on_ble_evt(&ble_evt, NULL); + ble_nus_on_ble_evt(&ble_evt, &nus_ctx); + + TEST_ASSERT_EQUAL_MEMORY(&empty_ble_evt, &ble_evt, sizeof(ble_evt_t)); + TEST_ASSERT_EQUAL_MEMORY(&empty_nus_ctx, &nus_ctx, sizeof(struct ble_nus)); +} + +void test_ble_nus_on_ble_evt_gap_evt_on_connect_readiness(void) +{ + ble_evt_t const ble_evt = {.evt.gap_evt.conn_handle = test_case_conn_handle, + .header.evt_id = BLE_GAP_EVT_CONNECTED}; + struct ble_nus_config nus_cfg = { .evt_handler = NULL }; + + init_nus(&nus_cfg); + + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get); + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_FALSE(evt_handler_called); + + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get_err); + ble_nus.evt_handler = ble_nus_evt_handler_on_connect; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_FALSE(evt_handler_called); + + ble_nus.evt_handler = ble_nus_evt_handler_on_connect; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_FALSE(evt_handler_called); +} + +void test_ble_nus_on_ble_evt_gap_evt_on_connect(void) +{ + ble_evt_t const ble_evt = {.evt.gap_evt.conn_handle = test_case_conn_handle, + .header.evt_id = BLE_GAP_EVT_CONNECTED}; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_connect }; + + init_nus(&nus_cfg); + + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get); + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_TRUE(evt_handler_called); +} + +void test_ble_nus_on_ble_evt_gap_evt_on_connect_null_ctx(void) +{ + ble_evt_t const ble_evt = {.evt.gap_evt.conn_handle = test_case_conn_handle, + .header.evt_id = BLE_GAP_EVT_CONNECTED}; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_connect_null_ctx }; + + init_nus(&nus_cfg); + + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get); + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, -1); + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_TRUE(evt_handler_called); +} + +void test_ble_nus_on_ble_evt_gap_evt_on_write(void) +{ + ble_evt_t ble_evt = { + .header.evt_id = BLE_GATTS_EVT_WRITE, + .evt.gatts_evt = { + .conn_handle = test_case_conn_handle, + .params.write = { + .handle = 0x101, + .len = 2, + }, + }, + }; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_write_notif }; + uint16_t *const data_notif_enable = (uint16_t *)ble_evt.evt.gatts_evt.params.write.data; + + init_nus(&nus_cfg); + + *data_notif_enable = BLE_GATT_HVX_NOTIFICATION; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_TRUE(evt_handler_called); + + evt_handler_called = false; + *data_notif_enable = BLE_GATT_HVX_INDICATION; + ble_nus.evt_handler = ble_nus_evt_handler_on_write_indica; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_TRUE(evt_handler_called); + + evt_handler_called = false; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, -1); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_FALSE(evt_handler_called); + + uint8_t *const data_ptr = ble_evt.evt.gatts_evt.params.write.data; + + evt_handler_called = false; + ble_evt.evt.gatts_evt.params.write.handle = 0x102; + ble_nus.evt_handler = ble_nus_evt_handler_on_write_value; + data_ptr[0] = 0xAB; + data_ptr[1] = 0xCD; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_TRUE(evt_handler_called); +} + +void test_ble_nus_on_hvx_tx_complete(void) +{ + ble_evt_t ble_evt = {.evt.gap_evt.conn_handle = test_case_conn_handle, + .header.evt_id = BLE_GAP_EVT_CONNECTED}; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_connect }; + + init_nus(&nus_cfg); + + /* Setup context */ + __cmock_sd_ble_gatts_value_get_Stub(stub_sd_ble_gatts_value_get); + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + + TEST_ASSERT_TRUE(evt_handler_called); + + /* Test a non relevant event */ + evt_handler_called = false; + ble_evt.header.evt_id = BLE_GATTS_EVT_HVN_TX_COMPLETE; + ble_nus.evt_handler = NULL; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_FALSE(evt_handler_called); + + /* Test a relevant event */ + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + ble_nus.evt_handler = ble_nus_evt_handler_on_hvx_tx_complete; + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_TRUE(evt_handler_called); +} + +void test_ble_nus_data_send_efault(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + ret = ble_nus_data_send(NULL, NULL, NULL, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EFAULT, ret); + + ret = ble_nus_data_send(&ble_nus, data, NULL, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EFAULT, ret); + + ret = ble_nus_data_send(&ble_nus, NULL, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EFAULT, ret); + + ret = ble_nus_data_send(NULL, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EFAULT, ret); +} + +void test_ble_nus_data_send_einval(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + ble_evt_t ble_evt = { + .header.evt_id = BLE_GATTS_EVT_WRITE, + .evt.gatts_evt = { + .conn_handle = test_case_conn_handle, + .params.write = { + .handle = 0x101, + .len = 2, + }, + }, + }; + struct ble_nus_config nus_cfg = { .evt_handler = ble_nus_evt_handler_on_write_notif }; + uint16_t *const data_notif_enable = (uint16_t *)ble_evt.evt.gatts_evt.params.write.data; + + init_nus(&nus_cfg); + + /* Set context is_notification_enabled to `false` */ + evt_handler_called = false; + *data_notif_enable = BLE_GATT_HVX_INDICATION; + ble_nus.evt_handler = ble_nus_evt_handler_on_write_indica; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + + ble_nus_on_ble_evt(&ble_evt, &ble_nus); + TEST_ASSERT_TRUE(evt_handler_called); + + /* Test for -EINVAL */ + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EINVAL, ret); + + length = (BLE_NUS_MAX_DATA_LEN + 1); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EINVAL, ret); +} + +void test_ble_nus_data_send_enoent(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + uint16_t conn_handle_inval = BLE_CONN_HANDLE_INVALID; + + ret = ble_nus_data_send(&ble_nus, data, &length, conn_handle_inval); + TEST_ASSERT_EQUAL(-ENOENT, ret); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, -1); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-ENOENT, ret); +} + +void test_ble_nus_data_send_eio(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + setup_with_notif_enabled(test_case_conn_handle); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_PARAM); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EIO, ret); +} + +void test_ble_nus_data_send_enotconn(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + setup_with_notif_enabled(test_case_conn_handle); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(BLE_ERROR_INVALID_CONN_HANDLE); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-ENOTCONN, ret); +} + +void test_ble_nus_data_send_epipe(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + setup_with_notif_enabled(test_case_conn_handle); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(NRF_ERROR_INVALID_STATE); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EPIPE, ret); +} + +void test_ble_nus_data_send_ebadf(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + setup_with_notif_enabled(test_case_conn_handle); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(NRF_ERROR_NOT_FOUND); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EBADF, ret); +} + +void test_ble_nus_data_send_eagain(void) +{ + int ret; + uint8_t data[2]; + uint16_t length = sizeof(data); + + setup_with_notif_enabled(test_case_conn_handle); + + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAnyArgsAndReturn(NRF_ERROR_RESOURCES); + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(-EAGAIN, ret); +} + +void test_ble_nus_data_send_success(void) +{ + int ret; + uint8_t data[2] = {0x01, 0x02}; + uint16_t length = sizeof(data); + ble_gatts_hvx_params_t expected_hvx_params = { + .p_data = data, + .p_len = &length, + .type = BLE_GATT_HVX_NOTIFICATION, + }; + + setup_with_notif_enabled(test_case_conn_handle); + expected_hvx_params.handle = ble_nus.tx_handles.value_handle; + __cmock_nrf_sdh_ble_idx_get_ExpectAndReturn(test_case_conn_handle, 0); + __cmock_sd_ble_gatts_hvx_ExpectAndReturn(test_case_conn_handle, + &expected_hvx_params, NRF_SUCCESS); + + ret = ble_nus_data_send(&ble_nus, data, &length, test_case_conn_handle); + TEST_ASSERT_EQUAL(0, ret); +} + +void setUp(void) +{ + memset(&ble_nus, 0, sizeof(ble_nus)); + evt_handler_called = false; + test_case_conn_handle++; +} + +extern int unity_main(void); + +int main(void) +{ + return unity_main(); +} diff --git a/tests/subsys/bluetooth/services/ble_nus/testcase.yaml b/tests/subsys/bluetooth/services/ble_nus/testcase.yaml new file mode 100644 index 0000000000..9d5805faed --- /dev/null +++ b/tests/subsys/bluetooth/services/ble_nus/testcase.yaml @@ -0,0 +1,4 @@ +tests: + bluetooth.ble_nus: + platform_allow: native_sim + tags: unittest