Skip to content

Commit

Permalink
Bluetooth: audio: test: Unit tests for the broadcast reception start …
Browse files Browse the repository at this point in the history
…command

Implement unit tests for the broadcast reception start, both with proper
and with improper parameters.

Add framework for the broadcast reception stop command

Signed-off-by: Andries Kruithof <[email protected]>
  • Loading branch information
kruithofa committed Feb 29, 2024
1 parent 7c66526 commit 94deb4c
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 2 deletions.
6 changes: 4 additions & 2 deletions tests/bluetooth/audio/cap_commander/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ target_include_directories(testbinary PRIVATE include)

target_sources(testbinary
PRIVATE
${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c
src/main.c
${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c
${ZEPHYR_BASE}/subsys/bluetooth/common/addr.c
src/main.c
src/test_common.c
src/test_volume.c
src/test_broadcast_reception.c
)
311 changes: 311 additions & 0 deletions tests/bluetooth/audio/cap_commander/src/test_broadcast_reception.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
/* test_change_volume.c - unit test for volume settings */

/*
* Copyright (c) 2023-2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdlib.h>

#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/audio/vcp.h>
#include <zephyr/fff.h>

#include "bluetooth.h"
#include "cap_commander.h"
#include "conn.h"
#include "expects_util.h"
#include "cap_mocks.h"
#include "test_common.h"

#define FFF_GLOBALS


#define ADDRESS 0x123456
#define SID 0x55
#define ADV_INTERVAL 10
#define BROADCAST_ID 0x80DEBEEF
#define NR_SUBGROUPS 1

struct cap_commander_test_broadcast_reception_fixture {
struct bt_conn conns[CONFIG_BT_MAX_CONN];
};

static void cap_commander_test_broadcast_reception_fixture_init(
struct cap_commander_test_broadcast_reception_fixture *fixture)
{
for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
test_conn_init(&fixture->conns[i]);
}
}

static void *cap_commander_test_broadcast_reception_setup(void)
{
struct cap_commander_test_broadcast_reception_fixture *fixture;

fixture = malloc(sizeof(*fixture));
zassert_not_null(fixture);

return fixture;
}

static void cap_commander_test_broadcast_reception_before(void *f)
{
memset(f, 0, sizeof(struct cap_commander_test_broadcast_reception_fixture));
cap_commander_test_broadcast_reception_fixture_init(f);
}

static void cap_commander_test_broadcast_reception_after(void *f)
{
struct cap_commander_test_broadcast_reception_fixture *fixture = f;

bt_cap_commander_unregister_cb(&mock_cap_commander_cb);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}
}

static void cap_commander_test_broadcast_reception_teardown(void *f)
{
free(f);
}

static struct bt_bap_bass_subgroup start_subgroups[NR_SUBGROUPS];
static struct bt_cap_commander_broadcast_reception_start_member_param
start_member_params[CONFIG_BT_MAX_CONN];
static struct bt_cap_commander_broadcast_reception_start_param start_param;

static void init_start_param(void *f)
{
struct cap_commander_test_broadcast_reception_fixture *fixture = f;

start_param.type = BT_CAP_SET_TYPE_AD_HOC;
start_param.param = start_member_params;

start_param.count = ARRAY_SIZE(start_member_params);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
mock_bt_conn_disconnected(&fixture->conns[i], BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}

for (size_t i = 0U; i < ARRAY_SIZE(start_member_params); i++) {
start_member_params[i].member.member = &fixture->conns[i];
bt_addr_le_copy(&start_member_params[i].addr, BT_ADDR_LE_ANY);
start_member_params[i].adv_sid = SID;
start_member_params[i].pa_interval = ADV_INTERVAL;
start_member_params[i].broadcast_id = BROADCAST_ID;
start_member_params[i].subgroups = &start_subgroups[0];
start_member_params[i].num_subgroups = NR_SUBGROUPS;
}

for (size_t i = 0; i < ARRAY_SIZE(start_subgroups); i++) {
start_subgroups[i].bis_sync = 0;
start_subgroups[i].metadata_len = 0;
}
}


ZTEST_SUITE(cap_commander_test_broadcast_reception, NULL,
cap_commander_test_broadcast_reception_setup,
cap_commander_test_broadcast_reception_before,
cap_commander_test_broadcast_reception_after,
cap_commander_test_broadcast_reception_teardown);

ZTEST_F(cap_commander_test_broadcast_reception, test_commander_reception_start)
{
int err;

init_start_param(fixture);

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

for (size_t i = 0U; i < ARRAY_SIZE(start_member_params); i++) {
start_member_params[i].member.member = &fixture->conns[i];
}

err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(0, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_start", 1,
mock_cap_commander_broadcast_reception_start_cb_fake.call_count);
}

ZTEST_F(cap_commander_test_broadcast_reception, test_commander_reception_start_double)
{
int err;

init_start_param(fixture);

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

for (size_t i = 0U; i < ARRAY_SIZE(start_member_params); i++) {
start_member_params[i].member.member = &fixture->conns[i];
}


err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(0, err, "Unexpected return value %d", err);

err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(0, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_start", 2,
mock_cap_commander_broadcast_reception_start_cb_fake.call_count);
}

ZTEST_F(cap_commander_test_broadcast_reception, test_commander_reception_start_inval_param_null)
{
int err;

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

err = bt_cap_commander_broadcast_reception_start(NULL);
zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
}

ZTEST_F(cap_commander_test_broadcast_reception,
test_commander_reception_start_inval_param_null_param)
{

int err;

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

start_param.type = BT_CAP_SET_TYPE_AD_HOC;
start_param.param = NULL;
start_param.count = ARRAY_SIZE(fixture->conns);

err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(-EINVAL, err, "Unexpected return value %d", err);
}


ZTEST_F(cap_commander_test_broadcast_reception,
test_commander_reception_start_inval_param_zero_count)
{
int err;

init_start_param(fixture);

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

start_param.count = 0;

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(-EINVAL, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_start", 0,
mock_cap_commander_broadcast_reception_start_cb_fake.call_count);
}

ZTEST_F(cap_commander_test_broadcast_reception,
test_commander_reception_start_inval_param_inval_count)
{
int err;

init_start_param(fixture);

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

start_param.count = CONFIG_BT_MAX_CONN + 1;

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

err = bt_cap_commander_broadcast_reception_start(&start_param);
zassert_equal(-EINVAL, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_start", 0,
mock_cap_commander_broadcast_reception_start_cb_fake.call_count);
}

#ifdef NOT_DEFINEDYET
ZTEST_F(cap_commander_test_broadcast_reception, test_commander_reception_stop)
{
union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
const struct bt_cap_commander_broadcast_reception_stop_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.members = members,
.count = ARRAY_SIZE(member_params),
};
int err;

for (size_t i = 0; i < ARRAY_SIZE(members); i++) {
members[i].member = &fixture->conns[i];
}

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

err = bt_cap_commander_broadcast_reception_stop(&param);
zassert_equal(0, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_stop", 1,
mock_cap_commander_broadcast_reception_stop_fake.call_count);
}

ZTEST_F(cap_commander_test_broadcast_reception, test_commander_reception_stop_double)
{
union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)];
const struct bt_cap_commander_broadcast_reception_stop_param param = {
.type = BT_CAP_SET_TYPE_AD_HOC,
.members = members,
.count = ARRAY_SIZE(member_params),
};
int err;

for (size_t i = 0; i < ARRAY_SIZE(members); i++) {
members[i].member = &fixture->conns[i];
}

err = bt_cap_commander_register_cb(&mock_cap_commander_cb);
zassert_equal(0, err, "Unexpected return value %d", err);

for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) {
err = bt_cap_commander_discover(&fixture->conns[i]);
zassert_equal(0, err, "Unexpected return value %d", err);
}

err = bt_cap_commander_broadcast_reception_stop(&param);
zassert_equal(0, err, "Unexpected return value %d", err);

err = bt_cap_commander_broadcast_reception_stop(&param);
zassert_equal(0, err, "Unexpected return value %d", err);

zexpect_call_count("bt_cap_commander_cb.broadcast_reception_stop", 2,
mock_cap_commander_broadcast_reception_stop_fake.call_count);
}

#endif


1 change: 1 addition & 0 deletions tests/bluetooth/audio/cap_commander/uut/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_library(uut STATIC
csip.c
vcp.c
vocs.c
bap_broadcast_assistant.c
)

add_subdirectory(${ZEPHYR_BASE}/tests/bluetooth/audio/mocks mocks)
Expand Down
1 change: 1 addition & 0 deletions tests/bluetooth/audio/mocks/include/cap_commander.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ DECLARE_FAKE_VOID_FUNC(mock_cap_commander_discovery_complete_cb, struct bt_conn
DECLARE_FAKE_VOID_FUNC(mock_cap_commander_volume_changed_cb, struct bt_conn *, int);
DECLARE_FAKE_VOID_FUNC(mock_cap_commander_volume_mute_changed_cb, struct bt_conn *, int);
DECLARE_FAKE_VOID_FUNC(mock_cap_commander_volume_offset_changed_cb, struct bt_conn *, int);
DECLARE_FAKE_VOID_FUNC(mock_cap_commander_broadcast_reception_start_cb, struct bt_conn *, int);

#endif /* MOCKS_CAP_COMMANDER_H_ */
4 changes: 4 additions & 0 deletions tests/bluetooth/audio/mocks/src/cap_commander.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
FAKE(mock_cap_commander_volume_changed_cb) \
FAKE(mock_cap_commander_volume_mute_changed_cb) \
FAKE(mock_cap_commander_volume_offset_changed_cb)
FAKE(mock_cap_commander_broadcast_reception_start_cb)

DEFINE_FAKE_VOID_FUNC(mock_cap_commander_discovery_complete_cb, struct bt_conn *, int,
const struct bt_csip_set_coordinator_csis_inst *);

DEFINE_FAKE_VOID_FUNC(mock_cap_commander_volume_changed_cb, struct bt_conn *, int);
DEFINE_FAKE_VOID_FUNC(mock_cap_commander_volume_mute_changed_cb, struct bt_conn *, int);
DEFINE_FAKE_VOID_FUNC(mock_cap_commander_volume_offset_changed_cb, struct bt_conn *, int);
DEFINE_FAKE_VOID_FUNC(mock_cap_commander_broadcast_reception_start_cb, struct bt_conn *, int);


const struct bt_cap_commander_cb mock_cap_commander_cb = {
.discovery_complete = mock_cap_commander_discovery_complete_cb,
Expand All @@ -31,6 +34,7 @@ const struct bt_cap_commander_cb mock_cap_commander_cb = {
.volume_offset_changed = mock_cap_commander_volume_offset_changed_cb,
#endif /* CONFIG_BT_VCP_VOL_CTLR */
#endif /* CONFIG_BT_VCP_VOL_CTLR */
.broadcast_reception_start = mock_cap_commander_broadcast_reception_start_cb,
};

void mock_cap_commander_init(void)
Expand Down

0 comments on commit 94deb4c

Please sign in to comment.