tests bsim: Add simple tests for broadcast audio source/sink samples

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

This test can be expanded after to cover more functionality from
these samples.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
This commit is contained in:
Alberto Escolar Piedras 2023-11-01 16:20:13 +01:00 committed by Carles Cufí
commit b3447ec068
10 changed files with 188 additions and 5 deletions

View file

@ -81,6 +81,8 @@ static uint32_t requested_bis_sync;
static uint32_t bis_index_bitfield;
static uint8_t sink_broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE];
uint64_t total_rx_iso_packet_count; /* This value is exposed to test code */
#if defined(CONFIG_LIBLC3)
#include "lc3.h"
@ -182,6 +184,7 @@ static void stream_started_cb(struct bt_bap_stream *stream)
printk("Stream %p started\n", stream);
total_rx_iso_packet_count = 0U;
sink_stream->recv_cnt = 0U;
sink_stream->loss_cnt = 0U;
sink_stream->valid_cnt = 0U;
@ -234,6 +237,7 @@ static void stream_recv_cb(struct bt_bap_stream *stream, const struct bt_iso_rec
#endif /* defined(CONFIG_LIBLC3) */
}
total_rx_iso_packet_count++;
sink_stream->recv_cnt++;
if ((sink_stream->recv_cnt % 1000U) == 0U) {
printk("Stream %p: received %u total ISO packets: Valid %u | Error %u | Loss %u\n",

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(broadcast_audio_sink_self_tets)
set(broadcast_audio_sink_path ${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink)
target_sources(app PRIVATE
${broadcast_audio_sink_path}/src/main.c
)
target_sources(app PRIVATE
src/broadcast_audio_sink_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,4 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
source "${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/Kconfig"

View file

@ -0,0 +1,10 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
source "${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/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,2 @@
# Please build using the sample configuration file:
# ${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf

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_broadcast_sink_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_broadcast_sink_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 total_rx_iso_packet_count;
bs_trace_info_time(2, "%"PRIu64" packets received, expected >= %i\n",
total_rx_iso_packet_count, PASS_THRESHOLD);
if (total_rx_iso_packet_count >= PASS_THRESHOLD) {
PASS("broadcast_sink PASSED\n");
bs_trace_exit("Done, disconnecting from simulation\n");
} else {
FAIL("broadcast_sink FAILED (Did not pass after %i seconds)\n",
WAIT_TIME);
}
}
static const struct bst_test_instance test_sample[] = {
{
.test_id = "broadcast_audio_sink",
.test_descr = "Test based on the broadcast audio sink sample. "
"It expects to be connected to a compatible broadcast audio source, "
"waits for " STR(WAIT_TIME) " seconds, and checks how "
"many ISO packets have been received correctly",
.test_post_init_f = test_broadcast_sink_sample_init,
.test_tick_f = test_broadcast_sink_sample_tick,
},
BSTEST_END_MARKER
};
struct bst_test_list *test_broadcast_sink_test_install(struct bst_test_list *tests)
{
tests = bst_add_tests(tests, test_sample);
return tests;
}

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_broadcast_sink_test_install(struct bst_test_list *tests);
bst_test_install_t test_installers[] = {
test_broadcast_sink_test_install,
NULL
};

View file

@ -0,0 +1,13 @@
# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
include(${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/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 broadcast audio sink/source 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 broadcast audio sink has received, and if over a threshold
# it considers the test passed
simulation_id="broadcast_audio_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_broadcast_audio_source_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1
Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_samples_broadcast_audio_sink_prj_conf \
-v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \
-testid=broadcast_audio_sink
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

@ -21,17 +21,23 @@ source ${ZEPHYR_BASE}/tests/bsim/compile.source
if [ "${BOARD}" == "nrf5340bsim_nrf5340_cpuapp" ]; then
app=samples/bluetooth/unicast_audio_server sysbuild=1 compile
app=samples/bluetooth/broadcast_audio_source sysbuild=1 compile
app=tests/bsim/bluetooth/audio_samples/unicast_audio_client sysbuild=1 compile
app=tests/bsim/bluetooth/audio_samples/broadcast_audio_sink sysbuild=1 \
conf_file=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf \
exe_name=bs_${BOARD}_${app}_prj_conf 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=samples/bluetooth/broadcast_audio_source conf_overlay=overlay-bt_ll_sw_split.conf \
exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile
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
app=tests/bsim/bluetooth/audio_samples/broadcast_audio_sink \
conf_file=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/prj.conf \
conf_overlay=${ZEPHYR_BASE}/samples/bluetooth/broadcast_audio_sink/overlay-bt_ll_sw_split.conf \
exe_name=bs_${BOARD}_${app}_prj_conf sysbuild=1 compile
fi
wait_for_background_jobs