tests bsim: Add tests for unicast client/server samples

Add a test based on the unicase client/server samples
which runs them together and after waiting for a predefined
amount of time, checks how many audio packets has the
client received, and if over a threshold, passes the test.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-10-30 16:01:24 +01:00 committed by Alberto Escolar
parent 4368765e3c
commit a0ed29409b
15 changed files with 257 additions and 1 deletions

View File

@ -19,6 +19,8 @@
static void start_scan(void);
uint64_t unicast_audio_recv_ctr; /* This value is exposed to test code */
static struct bt_bap_unicast_client_cb unicast_client_cbs;
static struct bt_conn *default_conn;
static struct k_work_delayable audio_send_work;
@ -564,7 +566,9 @@ static void stream_recv(struct bt_bap_stream *stream,
struct net_buf *buf)
{
if (info->flags & BT_ISO_FLAGS_VALID) {
printk("Incoming audio on stream %p len %u\n", stream, buf->len);
unicast_audio_recv_ctr++;
printk("Incoming audio on stream %p len %u (%"PRIu64")\n", stream, buf->len,
unicast_audio_recv_ctr);
}
}

View File

@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Copyright 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
# Compile all the applications needed by the bsim tests in these subfolders
#set -x #uncomment this line for debugging
set -ue
: "${BSIM_COMPONENTS_PATH:?BSIM_COMPONENTS_PATH must be defined}"
: "${ZEPHYR_BASE:?ZEPHYR_BASE must be set to point to the zephyr root\
directory}"
WORK_DIR="${WORK_DIR:-${ZEPHYR_BASE}/bsim_out}"
BOARD_ROOT="${BOARD_ROOT:-${ZEPHYR_BASE}}"
mkdir -p ${WORK_DIR}
source ${ZEPHYR_BASE}/tests/bsim/compile.source
if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then
app=samples/bluetooth/unicast_audio_server sysbuild=1 compile
else
app=samples/bluetooth/unicast_audio_server conf_overlay=overlay-bt_ll_sw_split.conf \
exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile
fi
if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then
app=tests/bsim/bluetooth/audio_samples/unicast_audio_client sysbuild=1 compile
else
app=tests/bsim/bluetooth/audio_samples/unicast_audio_client \
conf_overlay=${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/overlay-bt_ll_sw_split.conf \
exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile
fi
wait_for_background_jobs

View File

@ -0,0 +1,24 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(unicast_audio_client_self_tets)
set(unicast_client_path ${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client)
target_sources(app PRIVATE
${unicast_client_path}/src/main.c
)
target_sources(app PRIVATE
src/unicast_client_sample_test.c
src/test_main.c
)
zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
zephyr_include_directories(
${BSIM_COMPONENTS_PATH}/libUtilv1/src/
${BSIM_COMPONENTS_PATH}/libPhyComv1/src/
)

View File

@ -0,0 +1,10 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
source "${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/Kconfig.sysbuild"
config NATIVE_SIMULATOR_PRIMARY_MCU_INDEX
int
# Let's pass the test arguments to the application MCU test
# otherwise by default they would have gone to the net core.
default 0 if $(BOARD) = "nrf5340bsim_nrf5340_cpuapp"

View File

@ -0,0 +1,7 @@
# This file content is just a copy of the equivalent one in the unicast client sample
# For LC3 the following configs are needed
CONFIG_FPU=y
CONFIG_LIBLC3=y
# LC3 lib requires floating point support in the c-lib.
CONFIG_REQUIRES_FULL_LIBC=y

View File

@ -0,0 +1,14 @@
# This file content is just a copy of the equivalent one in the unicast client sample
# For LC3 the following configs are needed
CONFIG_FPU=y
CONFIG_LIBLC3=y
# LC3 lib requires floating point support in the c-lib.
CONFIG_REQUIRES_FULL_LIBC=y
CONFIG_BT_BUF_EVT_RX_SIZE=255
CONFIG_BT_BUF_ACL_RX_SIZE=255
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_BUF_CMD_TX_SIZE=255
CONFIG_BT_TINYCRYPT_ECC=y

View File

@ -0,0 +1,7 @@
# This file content is just a copy of the equivalent one in the unicast client sample
# For LC3 the following configs are needed
CONFIG_FPU=y
CONFIG_LIBLC3=y
# LC3 lib requires floating point support in the c-lib.
CONFIG_REQUIRES_FULL_LIBC=y

View File

@ -0,0 +1,16 @@
# This file content is just a copy of the unicast client sample prj.conf
CONFIG_BT=y
CONFIG_LOG=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_AUDIO=y
CONFIG_BT_BAP_UNICAST_CLIENT=y
CONFIG_BT_ISO_TX_BUF_COUNT=4
# Support an ISO channel per ASE
CONFIG_BT_ISO_MAX_CHAN=4
CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT=4
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=2
CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=2
CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
CONFIG_BT_EXT_ADV=y

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bstests.h"
extern struct bst_test_list *test_unicast_client_sample_install(struct bst_test_list *tests);
bst_test_install_t test_installers[] = {
test_unicast_client_sample_install,
NULL
};

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
* Copyright (c) 2017-2019 Oticon A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bs_types.h"
#include "bs_tracing.h"
#include "bs_utils.h"
#include "time_machine.h"
#include "bstests.h"
#define WAIT_TIME 10 /* Seconds */
#define PASS_THRESHOLD 100 /* Audio packets */
extern enum bst_result_t bst_result;
#define FAIL(...) \
do { \
bst_result = Failed; \
bs_trace_error_time_line(__VA_ARGS__); \
} while (0)
#define PASS(...) \
do { \
bst_result = Passed; \
bs_trace_info_time(1, __VA_ARGS__); \
} while (0)
static void test_unicast_client_sample_init(void)
{
/* We set an absolute deadline in 30 seconds */
bst_ticker_set_next_tick_absolute(WAIT_TIME*1e6);
bst_result = In_progress;
}
static void test_unicast_client_sample_tick(bs_time_t HW_device_time)
{
/*
* If in WAIT_TIME seconds we did not get enough packets through
* we consider the test failed
*/
extern uint64_t unicast_audio_recv_ctr;
bs_trace_info_time(2, "%"PRIu64" packets received, expected >= %i\n",
unicast_audio_recv_ctr, PASS_THRESHOLD);
if (unicast_audio_recv_ctr >= PASS_THRESHOLD) {
PASS("unicast_client PASSED\n");
bs_trace_exit("Done, disconnecting from simulation\n");
} else {
FAIL("unicast_client FAILED (Did not pass after %i seconds)\n",
WAIT_TIME);
}
}
static const struct bst_test_instance test_sample[] = {
{
.test_id = "unicast_client",
.test_descr = "Test based on the unicast client sample. "
"It expects to be connected to a compatible unicast server, "
"waits for " STR(WAIT_TIME) " seconds, and checks how "
"many audio packets have been received correctly",
.test_post_init_f = test_unicast_client_sample_init,
.test_tick_f = test_unicast_client_sample_tick,
},
BSTEST_END_MARKER
};
struct bst_test_list *test_unicast_client_sample_install(struct bst_test_list *tests)
{
tests = bst_add_tests(tests, test_sample);
return tests;
}

View File

@ -0,0 +1,13 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
include(${ZEPHYR_BASE}/samples/bluetooth/unicast_audio_client/sysbuild.cmake)
if (NOT ("${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}" STREQUAL ""))
set_property(TARGET ${NET_APP} APPEND_STRING PROPERTY CONFIG
"CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n"
)
set_property(TARGET ${DEFAULT_IMAGE} APPEND_STRING PROPERTY CONFIG
"CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX=${SB_CONFIG_NATIVE_SIMULATOR_PRIMARY_MCU_INDEX}\n"
)
endif()

View File

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Copyright 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
# Simple selfchecking test for the unicast client/server samples,
# It relies on the bs_tests hooks to register a test timer callback, which after a deadline
# will check how many audio packets the unicast client has received, and if over a threshold
# it considers the test passed
simulation_id="unicast_samples_test"
verbosity_level=2
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
EXECUTE_TIMEOUT=100
cd ${BSIM_OUT_PATH}/bin
Execute ./bs_${BOARD}_samples_bluetooth_unicast_audio_server_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_samples_unicast_audio_client_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \
-testid=unicast_client
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=20e6 $@
wait_for_background_jobs #Wait for all programs in background and return != 0 if any fails

View File

@ -22,4 +22,6 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source
app=tests/bsim/bluetooth/ll/conn conf_file=prj_split_privacy.conf sysbuild=1 compile
app=tests/bsim/bluetooth/ll/bis sysbuild=1 compile
run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh
wait_for_background_jobs

View File

@ -24,6 +24,7 @@ source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
# On the other hand the audio compile script, only builds one image. So we parallelize it with
# the rest to save a couple of seconds.
run_in_background ${ZEPHYR_BASE}/tests/bsim/bluetooth/audio/compile.sh
${ZEPHYR_BASE}/tests/bsim/bluetooth/audio_samples/compile.sh
${ZEPHYR_BASE}/tests/bsim/bluetooth/host/compile.sh
${ZEPHYR_BASE}/tests/bsim/bluetooth/ll/compile.sh
${ZEPHYR_BASE}/tests/bsim/bluetooth/mesh/compile.sh

View File

@ -2,3 +2,4 @@
# This file is used in CI to select which tests are run
tests/bsim/bluetooth/ll/conn/tests_scripts/basic_conn_encrypted_split_privacy.sh
tests/bsim/bluetooth/ll/bis/tests_scripts/broadcast_iso.sh
tests/bsim/bluetooth/audio_samples/