Bluetooth: Host: Add advertising events stress test
More information in the test description. Why: At the time of writing, this test exposes a bug in the Bluetooth stack where all the RX buffers are in use, and the controller driver fails to synchronously allocate a command response buffer. This is manifested in an assertion failure in `hci_common.c`. Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
This commit is contained in:
parent
6d5cce662a
commit
edeb529c9f
8 changed files with 295 additions and 0 deletions
|
@ -40,5 +40,6 @@ run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/privacy/legacy/compil
|
|||
|
||||
run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/id/settings/compile.sh
|
||||
run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/scan/start_stop/compile.sh
|
||||
run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/host/scan/slow/compile.sh
|
||||
|
||||
wait_for_background_jobs
|
||||
|
|
27
tests/bsim/bluetooth/host/scan/slow/CMakeLists.txt
Normal file
27
tests/bsim/bluetooth/host/scan/slow/CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
|
||||
project(slow)
|
||||
|
||||
# This contains a variety of helper functions that abstract away common tasks,
|
||||
# like scanning, setting up a connection, querying the peer for a given
|
||||
# characteristic, etc..
|
||||
add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/common/testlib testlib)
|
||||
target_link_libraries(app PRIVATE testlib)
|
||||
|
||||
# This contains babblesim-specific helpers, e.g. device synchronization.
|
||||
add_subdirectory(${ZEPHYR_BASE}/tests/bsim/babblekit babblekit)
|
||||
target_link_libraries(app PRIVATE babblekit)
|
||||
|
||||
zephyr_include_directories(
|
||||
$ENV{BSIM_COMPONENTS_PATH}/libUtilv1/src/
|
||||
$ENV{BSIM_COMPONENTS_PATH}/libPhyComv1/src/
|
||||
)
|
||||
|
||||
target_sources(app PRIVATE
|
||||
src/main.c
|
||||
src/peer.c
|
||||
src/dut.c
|
||||
)
|
14
tests/bsim/bluetooth/host/scan/slow/compile.sh
Executable file
14
tests/bsim/bluetooth/host/scan/slow/compile.sh
Executable file
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -eu
|
||||
: "${ZEPHYR_BASE:?ZEPHYR_BASE must be defined}"
|
||||
|
||||
INCR_BUILD=1
|
||||
|
||||
source ${ZEPHYR_BASE}/tests/bsim/compile.source
|
||||
|
||||
app="$(guess_test_relpath)" compile
|
||||
|
||||
wait_for_background_jobs
|
21
tests/bsim/bluetooth/host/scan/slow/prj.conf
Normal file
21
tests/bsim/bluetooth/host/scan/slow/prj.conf
Normal file
|
@ -0,0 +1,21 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_BT_BROADCASTER=y
|
||||
CONFIG_BT_CENTRAL=y
|
||||
CONFIG_BT_OBSERVER=y
|
||||
CONFIG_BT_EXT_ADV=y
|
||||
CONFIG_BT_DEVICE_NAME="Scanner Test"
|
||||
|
||||
# Enable privacy with frequent address refreshes
|
||||
CONFIG_BT_SMP=y
|
||||
CONFIG_BT_PRIVACY=y
|
||||
CONFIG_BT_RPA_TIMEOUT=2
|
||||
|
||||
# Log & debug options
|
||||
CONFIG_LOG=y
|
||||
CONFIG_LOG_RUNTIME_FILTERING=y
|
||||
CONFIG_LOG_THREAD_ID_PREFIX=y
|
||||
|
||||
CONFIG_ASSERT=y
|
||||
CONFIG_THREAD_NAME=y
|
||||
CONFIG_LOG_THREAD_ID_PREFIX=y
|
||||
CONFIG_ARCH_POSIX_TRAP_ON_FATAL=y
|
83
tests/bsim/bluetooth/host/scan/slow/src/dut.c
Normal file
83
tests/bsim/bluetooth/host/scan/slow/src/dut.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/addr.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/atomic.h>
|
||||
#include <zephyr/sys/atomic_builtin.h>
|
||||
|
||||
#include "testlib/log_utils.h"
|
||||
#include "babblekit/flags.h"
|
||||
#include "babblekit/testcase.h"
|
||||
|
||||
LOG_MODULE_REGISTER(dut, LOG_LEVEL_DBG);
|
||||
|
||||
extern unsigned long runtime_log_level;
|
||||
|
||||
static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
|
||||
struct net_buf_simple *ad)
|
||||
{
|
||||
char addr_str[BT_ADDR_LE_STR_LEN];
|
||||
|
||||
k_msleep(500); /* simulate a slow memcpy (or user processing the scan data) */
|
||||
|
||||
bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
|
||||
LOG_DBG("Device found: %s (RSSI %d), type %u, AD data len %u", addr_str, rssi, type,
|
||||
ad->len);
|
||||
}
|
||||
|
||||
#define BT_LE_SCAN_ACTIVE_CONTINUOUS_WITH_DUPLICATES \
|
||||
BT_LE_SCAN_PARAM(BT_LE_SCAN_TYPE_ACTIVE, 0, BT_GAP_SCAN_FAST_INTERVAL_MIN, \
|
||||
BT_GAP_SCAN_FAST_WINDOW)
|
||||
|
||||
void entrypoint_dut(void)
|
||||
{
|
||||
/* Test purpose:
|
||||
*
|
||||
* Verifies that the host can handle running out of HCI RX buffers.
|
||||
*
|
||||
* To test this, we use a scanner with privacy enabled and sleep a bit
|
||||
* when we get every advertising report. This sleep period simulates a
|
||||
* slow "memcpy" operation on actual hardware. In effect, this uses up
|
||||
* the event buffer pools.
|
||||
*
|
||||
* A short RPA timeout is used to prompt the host into periodically
|
||||
* sending a bunch of commands to the controller. Those commands should
|
||||
* not fail.
|
||||
*
|
||||
* Note: This test only fails by the stack crashing.
|
||||
*
|
||||
* It is a regression test for
|
||||
* https://github.com/zephyrproject-rtos/zephyr/issues/78223
|
||||
*
|
||||
* Two devices:
|
||||
* - `dut`: active-scans with privacy ON
|
||||
* - `peer`: bog-standard advertiser
|
||||
*
|
||||
* [verdict]
|
||||
* - dut is able to run for a long enough time without triggering asserts
|
||||
*/
|
||||
int err;
|
||||
|
||||
TEST_START("DUT");
|
||||
|
||||
/* Set the log level given by the `log_level` CLI argument */
|
||||
bt_testlib_log_level_set("dut", runtime_log_level);
|
||||
|
||||
err = bt_enable(NULL);
|
||||
TEST_ASSERT(!err, "Bluetooth init failed (err %d)\n", err);
|
||||
|
||||
LOG_DBG("Bluetooth initialised");
|
||||
|
||||
err = bt_le_scan_start(BT_LE_SCAN_ACTIVE_CONTINUOUS_WITH_DUPLICATES, device_found);
|
||||
TEST_ASSERT(!err, "Scanner setup failed (err %d)\n", err);
|
||||
LOG_DBG("Explicit scanner started");
|
||||
|
||||
/* 40 seconds ought to be enough for anyone */
|
||||
k_sleep(K_SECONDS(40));
|
||||
|
||||
TEST_PASS_AND_EXIT("DUT passed");
|
||||
}
|
74
tests/bsim/bluetooth/host/scan/slow/src/main.c
Normal file
74
tests/bsim/bluetooth/host/scan/slow/src/main.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include "bs_tracing.h"
|
||||
#include "bstests.h"
|
||||
#include "babblekit/testcase.h"
|
||||
#include "testlib/log_utils.h"
|
||||
|
||||
extern void entrypoint_dut(void);
|
||||
extern void entrypoint_peer(void);
|
||||
extern enum bst_result_t bst_result;
|
||||
|
||||
unsigned long runtime_log_level = LOG_LEVEL_INF;
|
||||
|
||||
static void test_args(int argc, char *argv[])
|
||||
{
|
||||
size_t argn = 0;
|
||||
const char *arg = argv[argn];
|
||||
|
||||
if (strcmp(arg, "log_level") == 0) {
|
||||
|
||||
runtime_log_level = strtoul(argv[++argn], NULL, 10);
|
||||
|
||||
if (runtime_log_level >= LOG_LEVEL_NONE && runtime_log_level <= LOG_LEVEL_DBG) {
|
||||
TEST_PRINT("Runtime log level configuration: %d", runtime_log_level);
|
||||
} else {
|
||||
TEST_FAIL("Invalid arguments to set log level: %d", runtime_log_level);
|
||||
}
|
||||
} else {
|
||||
TEST_PRINT("Default runtime log level configuration: INFO");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_end_cb(void)
|
||||
{
|
||||
if (bst_result != Passed) {
|
||||
TEST_PRINT("Test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
static const struct bst_test_instance entrypoints[] = {
|
||||
{
|
||||
.test_id = "dut",
|
||||
.test_delete_f = test_end_cb,
|
||||
.test_main_f = entrypoint_dut,
|
||||
.test_args_f = test_args,
|
||||
},
|
||||
{
|
||||
.test_id = "peer",
|
||||
.test_delete_f = test_end_cb,
|
||||
.test_main_f = entrypoint_peer,
|
||||
.test_args_f = test_args,
|
||||
},
|
||||
BSTEST_END_MARKER,
|
||||
};
|
||||
|
||||
static struct bst_test_list *install(struct bst_test_list *tests)
|
||||
{
|
||||
return bst_add_tests(tests, entrypoints);
|
||||
};
|
||||
|
||||
bst_test_install_t test_installers[] = {install, NULL};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bst_main();
|
||||
|
||||
return 0;
|
||||
}
|
48
tests/bsim/bluetooth/host/scan/slow/src/peer.c
Normal file
48
tests/bsim/bluetooth/host/scan/slow/src/peer.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/bluetooth/addr.h>
|
||||
#include <zephyr/bluetooth/bluetooth.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/sys/atomic.h>
|
||||
#include <zephyr/sys/atomic_builtin.h>
|
||||
|
||||
#include "testlib/log_utils.h"
|
||||
#include "babblekit/flags.h"
|
||||
#include "babblekit/testcase.h"
|
||||
|
||||
LOG_MODULE_REGISTER(peer, LOG_LEVEL_DBG);
|
||||
|
||||
extern unsigned long runtime_log_level;
|
||||
|
||||
void entrypoint_peer(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
TEST_START("peer");
|
||||
|
||||
/* Set the log level given by the `log_level` CLI argument */
|
||||
bt_testlib_log_level_set("peer", runtime_log_level);
|
||||
|
||||
err = bt_enable(NULL);
|
||||
TEST_ASSERT(!err, "Bluetooth init failed (err %d)\n", err);
|
||||
|
||||
LOG_DBG("Bluetooth initialised");
|
||||
|
||||
struct bt_le_ext_adv *adv;
|
||||
|
||||
struct bt_le_adv_param adv_param = BT_LE_ADV_PARAM_INIT(
|
||||
BT_LE_ADV_OPT_EXT_ADV, BT_GAP_ADV_FAST_INT_MIN_1, BT_GAP_ADV_FAST_INT_MAX_1, NULL);
|
||||
|
||||
err = bt_le_ext_adv_create(&adv_param, NULL, &adv);
|
||||
TEST_ASSERT(!err, "Failed to create advertising set: %d", err);
|
||||
LOG_DBG("Created extended advertising set.");
|
||||
|
||||
err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
|
||||
TEST_ASSERT(!err, "Failed to start extended advertising: %d", err);
|
||||
LOG_DBG("Started extended advertising.");
|
||||
|
||||
TEST_PASS("Tester done");
|
||||
}
|
27
tests/bsim/bluetooth/host/scan/slow/test_scripts/run.sh
Executable file
27
tests/bsim/bluetooth/host/scan/slow/test_scripts/run.sh
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
# Copyright 2024 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
|
||||
|
||||
test_name="$(guess_test_long_name)"
|
||||
test_exe="${BSIM_OUT_PATH}/bin/bs_${BOARD_TS}_${test_name}_prj_conf"
|
||||
|
||||
simulation_id=${test_name}
|
||||
verbosity_level=2
|
||||
zephyr_log_level=3
|
||||
|
||||
cd ${BSIM_OUT_PATH}/bin
|
||||
|
||||
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s="${simulation_id}" \
|
||||
-D=2 -sim_length=100e6
|
||||
|
||||
Execute "${test_exe}" \
|
||||
-v=${verbosity_level} -s="${simulation_id}" -d=1 \
|
||||
-testid=peer -argstest log_level ${zephyr_log_level}
|
||||
|
||||
Execute "${test_exe}" \
|
||||
-v=${verbosity_level} -s="${simulation_id}" -d=0 \
|
||||
-testid=dut -argstest log_level ${zephyr_log_level}
|
||||
|
||||
wait_for_background_jobs
|
Loading…
Add table
Add a link
Reference in a new issue