bluetooth: host: Unit tests for bt_le_cs_step_data_parse
Add unit tests for bt_le_cs_step_data_parse. Also exit early (without calling the function pointer) if the next step would seem to read out of bounds. Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
This commit is contained in:
parent
7d83419b6f
commit
635d03b7e0
12 changed files with 367 additions and 0 deletions
|
@ -0,0 +1,25 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
|
||||
project(bt_step_data_parse)
|
||||
|
||||
include_directories(BEFORE
|
||||
${ZEPHYR_BASE}/tests/bluetooth/host/cs/mocks
|
||||
)
|
||||
|
||||
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host host_mocks)
|
||||
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/host/cs/mocks mocks)
|
||||
|
||||
target_link_libraries(testbinary PRIVATE mocks host_mocks)
|
||||
|
||||
target_sources(testbinary
|
||||
PRIVATE
|
||||
src/main.c
|
||||
|
||||
${ZEPHYR_BASE}/subsys/bluetooth/host/cs.c
|
||||
${ZEPHYR_BASE}/lib/net_buf/buf_simple.c
|
||||
${ZEPHYR_BASE}/subsys/logging/log_minimal.c
|
||||
)
|
10
tests/bluetooth/host/cs/bt_le_cs_step_data_parse/prj.conf
Normal file
10
tests/bluetooth/host/cs/bt_le_cs_step_data_parse/prj.conf
Normal file
|
@ -0,0 +1,10 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_BT=y
|
||||
CONFIG_BT_HCI=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_CHANNEL_SOUNDING=y
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_ASSERT_LEVEL=2
|
||||
CONFIG_ASSERT_VERBOSE=y
|
||||
CONFIG_ASSERT_ON_ERRORS=y
|
||||
CONFIG_NET_BUF=y
|
171
tests/bluetooth/host/cs/bt_le_cs_step_data_parse/src/main.c
Normal file
171
tests/bluetooth/host/cs/bt_le_cs_step_data_parse/src/main.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "mocks/conn.h"
|
||||
#include "mocks/hci_core.h"
|
||||
#include "mocks/net_buf.h"
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/bluetooth/cs.h>
|
||||
#include <zephyr/fff.h>
|
||||
|
||||
DEFINE_FFF_GLOBALS;
|
||||
|
||||
FAKE_VALUE_FUNC(bool, bt_le_cs_step_data_parse_func, struct bt_le_cs_subevent_step *, void *);
|
||||
|
||||
static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
|
||||
{
|
||||
RESET_FAKE(bt_le_cs_step_data_parse_func);
|
||||
CONN_FFF_FAKES_LIST(RESET_FAKE);
|
||||
}
|
||||
|
||||
ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
|
||||
|
||||
ZTEST_SUITE(bt_le_cs_step_data_parse, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Test empty data buffer
|
||||
*
|
||||
* Constraints:
|
||||
* - buffer len set to 0
|
||||
*
|
||||
* Expected behaviour:
|
||||
* - Callback function is not called
|
||||
*/
|
||||
ZTEST(bt_le_cs_step_data_parse, test_parsing_empty_buf)
|
||||
{
|
||||
struct net_buf_simple *buf = NET_BUF_SIMPLE(0);
|
||||
|
||||
bt_le_cs_step_data_parse(buf, bt_le_cs_step_data_parse_func, NULL);
|
||||
|
||||
zassert_equal(bt_le_cs_step_data_parse_func_fake.call_count, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test malformed step data
|
||||
*
|
||||
* Constraints:
|
||||
* - step data with a step length going out of bounds
|
||||
*
|
||||
* Expected behaviour:
|
||||
* - Callback function is called once
|
||||
*/
|
||||
ZTEST(bt_le_cs_step_data_parse, test_parsing_invalid_length)
|
||||
{
|
||||
struct net_buf_simple buf;
|
||||
uint8_t data[] = {
|
||||
0x00, 0x01, 0x01, 0x00, /* mode 0 */
|
||||
0x03, 0x20, 0x03, 0x00, 0x11, /* mode 3 step with bad length */
|
||||
};
|
||||
|
||||
bt_le_cs_step_data_parse_func_fake.return_val = true;
|
||||
|
||||
net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
|
||||
|
||||
bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, NULL);
|
||||
|
||||
zassert_equal(1, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
|
||||
bt_le_cs_step_data_parse_func_fake.call_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test parsing stopped
|
||||
*
|
||||
* Constraints:
|
||||
* - Data contains valid step data
|
||||
* - Callback function returns false to stop parsing
|
||||
*
|
||||
* Expected behaviour:
|
||||
* - Once parsing is stopped, the callback is not called anymore
|
||||
*/
|
||||
ZTEST(bt_le_cs_step_data_parse, test_parsing_stopped)
|
||||
{
|
||||
struct net_buf_simple buf;
|
||||
uint8_t data[] = {
|
||||
0x00, 0x05, 0x01, 0x00, /* mode 0 */
|
||||
0x01, 0x10, 0x02, 0x00, 0x11, /* mode 1 */
|
||||
0x02, 0x11, 0x02, 0x00, 0x11, /* mode 2 */
|
||||
};
|
||||
|
||||
bt_le_cs_step_data_parse_func_fake.return_val = false;
|
||||
|
||||
net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
|
||||
|
||||
bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, NULL);
|
||||
|
||||
zassert_equal(1, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
|
||||
bt_le_cs_step_data_parse_func_fake.call_count);
|
||||
}
|
||||
|
||||
struct custom_user_data {
|
||||
const uint8_t *data;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static bool bt_le_cs_step_data_parse_func_custom_fake(struct bt_le_cs_subevent_step *step,
|
||||
void *user_data)
|
||||
{
|
||||
struct custom_user_data *ud = user_data;
|
||||
|
||||
/* mode check */
|
||||
zassert_true(ud->len-- > 0);
|
||||
zassert_equal(step->mode, *ud->data);
|
||||
ud->data++;
|
||||
|
||||
/* channel check */
|
||||
zassert_true(ud->len-- > 0);
|
||||
zassert_equal(step->channel, *ud->data);
|
||||
ud->data++;
|
||||
|
||||
/* step data length check */
|
||||
zassert_true(ud->len-- > 0);
|
||||
zassert_equal(step->data_len, *ud->data);
|
||||
ud->data++;
|
||||
|
||||
/* value check */
|
||||
zassert_true(ud->len >= step->data_len);
|
||||
zassert_mem_equal(step->data, ud->data, step->data_len);
|
||||
ud->data += step->data_len;
|
||||
ud->len -= step->data_len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test parsing successfully
|
||||
*
|
||||
* Constraints:
|
||||
* - Data contains valid step data
|
||||
* - Callback function returns false to stop parsing
|
||||
*
|
||||
* Expected behaviour:
|
||||
* - Data passed to the callback match the expected data
|
||||
*/
|
||||
ZTEST(bt_le_cs_step_data_parse, test_parsing_success)
|
||||
{
|
||||
struct net_buf_simple buf;
|
||||
uint8_t data[] = {
|
||||
0x00, 0x05, 0x01, 0x00, /* mode 0 */
|
||||
0x03, 0x11, 0x01, 0x11, /* mode 3 */
|
||||
0x02, 0x12, 0x02, 0x00, 0x11, /* mode 2 */
|
||||
0x03, 0x13, 0x01, 0x11, /* mode 3 */
|
||||
0x02, 0x14, 0x02, 0x00, 0x11, /* mode 2 */
|
||||
};
|
||||
|
||||
struct custom_user_data user_data = {
|
||||
.data = data,
|
||||
.len = ARRAY_SIZE(data),
|
||||
};
|
||||
|
||||
bt_le_cs_step_data_parse_func_fake.custom_fake = bt_le_cs_step_data_parse_func_custom_fake;
|
||||
|
||||
net_buf_simple_init_with_data(&buf, data, ARRAY_SIZE(data));
|
||||
|
||||
bt_le_cs_step_data_parse(&buf, bt_le_cs_step_data_parse_func, &user_data);
|
||||
|
||||
zassert_equal(5, bt_le_cs_step_data_parse_func_fake.call_count, "called %d",
|
||||
bt_le_cs_step_data_parse_func_fake.call_count);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
common:
|
||||
tags:
|
||||
- bluetooth
|
||||
- host
|
||||
tests:
|
||||
bluetooth.host.cs.bt_le_cs_step_data_parse:
|
||||
type: unit
|
17
tests/bluetooth/host/cs/mocks/CMakeLists.txt
Normal file
17
tests/bluetooth/host/cs/mocks/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_library(mocks STATIC
|
||||
conn.c
|
||||
hci_core.c
|
||||
net_buf.c
|
||||
)
|
||||
|
||||
target_include_directories(mocks PUBLIC
|
||||
..
|
||||
${ZEPHYR_BASE}/subsys/bluetooth
|
||||
${ZEPHYR_BASE}/subsys/bluetooth/host
|
||||
${ZEPHYR_BASE}/tests/bluetooth/host
|
||||
${ZEPHYR_BASE}/tests/bluetooth/host/cs/mocks
|
||||
)
|
||||
|
||||
target_link_libraries(mocks PRIVATE test_interface)
|
22
tests/bluetooth/host/cs/mocks/conn.c
Normal file
22
tests/bluetooth/host/cs/mocks/conn.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "mocks/conn.h"
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
DEFINE_FAKE_VOID_FUNC(bt_conn_unref, struct bt_conn *);
|
||||
DEFINE_FAKE_VALUE_FUNC(struct bt_conn *, bt_conn_lookup_handle, uint16_t, enum bt_conn_type);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_remote_cs_capabilities, struct bt_conn *,
|
||||
struct bt_conn_le_cs_capabilities);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_remote_cs_fae_table, struct bt_conn *, struct bt_conn_le_cs_fae_table);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_cs_config_created, struct bt_conn *, struct bt_conn_le_cs_config *);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_cs_config_removed, struct bt_conn *, uint8_t);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_cs_subevent_result, struct bt_conn *,
|
||||
struct bt_conn_le_cs_subevent_result *);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_cs_security_enable_available, struct bt_conn *);
|
||||
DEFINE_FAKE_VOID_FUNC(notify_cs_procedure_enable_available, struct bt_conn *,
|
||||
struct bt_conn_le_cs_procedure_enable_complete *);
|
37
tests/bluetooth/host/cs/mocks/conn.h
Normal file
37
tests/bluetooth/host/cs/mocks/conn.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/conn.h>
|
||||
#include <zephyr/fff.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <host/conn_internal.h>
|
||||
|
||||
/* List of fakes used by this unit tester */
|
||||
#define CONN_FFF_FAKES_LIST(FAKE) \
|
||||
FAKE(bt_conn_unref) \
|
||||
FAKE(bt_conn_lookup_handle) \
|
||||
FAKE(notify_remote_cs_capabilities) \
|
||||
FAKE(notify_cs_config_created) \
|
||||
FAKE(notify_cs_config_removed) \
|
||||
FAKE(notify_cs_subevent_result) \
|
||||
FAKE(notify_cs_security_enable_available) \
|
||||
FAKE(notify_cs_procedure_enable_available) \
|
||||
FAKE(notify_remote_cs_fae_table)
|
||||
|
||||
DECLARE_FAKE_VOID_FUNC(bt_conn_unref, struct bt_conn *);
|
||||
DECLARE_FAKE_VALUE_FUNC(struct bt_conn *, bt_conn_lookup_handle, uint16_t, enum bt_conn_type);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_remote_cs_capabilities, struct bt_conn *,
|
||||
struct bt_conn_le_cs_capabilities);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_remote_cs_fae_table, struct bt_conn *,
|
||||
struct bt_conn_le_cs_fae_table);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_cs_config_created, struct bt_conn *, struct bt_conn_le_cs_config *);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_cs_config_removed, struct bt_conn *, uint8_t);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_cs_subevent_result, struct bt_conn *,
|
||||
struct bt_conn_le_cs_subevent_result *);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_cs_security_enable_available, struct bt_conn *);
|
||||
DECLARE_FAKE_VOID_FUNC(notify_cs_procedure_enable_available, struct bt_conn *,
|
||||
struct bt_conn_le_cs_procedure_enable_complete *);
|
19
tests/bluetooth/host/cs/mocks/hci_core.c
Normal file
19
tests/bluetooth/host/cs/mocks/hci_core.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "mocks/hci_core.h"
|
||||
|
||||
#include <zephyr/bluetooth/hci.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <host/hci_core.h>
|
||||
|
||||
struct bt_dev bt_dev = {
|
||||
.manufacturer = 0x1234,
|
||||
};
|
||||
|
||||
DEFINE_FAKE_VALUE_FUNC(struct net_buf *, bt_hci_cmd_create, uint16_t, uint8_t);
|
||||
DEFINE_FAKE_VALUE_FUNC(int, bt_hci_cmd_send_sync, uint16_t, struct net_buf *, struct net_buf **);
|
16
tests/bluetooth/host/cs/mocks/hci_core.h
Normal file
16
tests/bluetooth/host/cs/mocks/hci_core.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/fff.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
/* List of fakes used by this unit tester */
|
||||
#define HCI_CORE_FFF_FAKES_LIST(FAKE) \
|
||||
FAKE(bt_hci_cmd_create) \
|
||||
FAKE(bt_hci_cmd_send_sync)
|
||||
|
||||
DECLARE_FAKE_VALUE_FUNC(struct net_buf *, bt_hci_cmd_create, uint16_t, uint8_t);
|
||||
DECLARE_FAKE_VALUE_FUNC(int, bt_hci_cmd_send_sync, uint16_t, struct net_buf *, struct net_buf **);
|
17
tests/bluetooth/host/cs/mocks/net_buf.c
Normal file
17
tests/bluetooth/host/cs/mocks/net_buf.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/net_buf.h>
|
||||
|
||||
#include "mocks/net_buf.h"
|
||||
|
||||
const struct net_buf_data_cb net_buf_fixed_cb;
|
||||
|
||||
DEFINE_FAKE_VOID_FUNC(net_buf_unref, struct net_buf *);
|
||||
DEFINE_FAKE_VOID_FUNC(net_buf_reset, struct net_buf *);
|
||||
DEFINE_FAKE_VOID_FUNC(net_buf_slist_put, sys_slist_t *, struct net_buf *);
|
||||
DEFINE_FAKE_VALUE_FUNC(struct net_buf *, net_buf_alloc_fixed, struct net_buf_pool *, k_timeout_t);
|
21
tests/bluetooth/host/cs/mocks/net_buf.h
Normal file
21
tests/bluetooth/host/cs/mocks/net_buf.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/fff.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/net_buf.h>
|
||||
|
||||
/* List of fakes used by this unit tester */
|
||||
#define NET_BUF_FFF_FAKES_LIST(FAKE) \
|
||||
FAKE(net_buf_unref) \
|
||||
FAKE(net_buf_reset) \
|
||||
FAKE(net_buf_slist_put) \
|
||||
FAKE(net_buf_alloc_fixed)
|
||||
|
||||
DECLARE_FAKE_VOID_FUNC(net_buf_unref, struct net_buf *);
|
||||
DECLARE_FAKE_VOID_FUNC(net_buf_reset, struct net_buf *);
|
||||
DECLARE_FAKE_VOID_FUNC(net_buf_slist_put, sys_slist_t *, struct net_buf *);
|
||||
DECLARE_FAKE_VALUE_FUNC(struct net_buf *, net_buf_alloc_fixed, struct net_buf_pool *, k_timeout_t);
|
Loading…
Add table
Add a link
Reference in a new issue