From f967e08364fa4de606f007edf585755cd1f2f042 Mon Sep 17 00:00:00 2001 From: Andries Kruithof Date: Tue, 6 Feb 2024 14:56:41 +0100 Subject: [PATCH] Bluetooth: audio: test: Refactor unit test The unittest for cap commander is refactored, so that tests for volumecontrol is in its own module. This avoids the problem of having all tests in one huge file. Due to their small size the tests for registering callbacks and discovery haven't been put into their own module. Signed-off-by: Andries Kruithof --- .../audio/cap_commander/CMakeLists.txt | 3 + .../audio/cap_commander/include/test_common.h | 12 + .../bluetooth/audio/cap_commander/src/main.c | 939 +----------------- .../audio/cap_commander/src/test_common.c | 43 + .../audio/cap_commander/src/test_micp.c | 293 ++++++ .../audio/cap_commander/src/test_vcp.c | 753 ++++++++++++++ 6 files changed, 1108 insertions(+), 935 deletions(-) create mode 100644 tests/bluetooth/audio/cap_commander/include/test_common.h create mode 100644 tests/bluetooth/audio/cap_commander/src/test_common.c create mode 100644 tests/bluetooth/audio/cap_commander/src/test_micp.c create mode 100644 tests/bluetooth/audio/cap_commander/src/test_vcp.c diff --git a/tests/bluetooth/audio/cap_commander/CMakeLists.txt b/tests/bluetooth/audio/cap_commander/CMakeLists.txt index 17f6ad2f4b25..11a19d9530d5 100644 --- a/tests/bluetooth/audio/cap_commander/CMakeLists.txt +++ b/tests/bluetooth/audio/cap_commander/CMakeLists.txt @@ -15,4 +15,7 @@ target_sources(testbinary PRIVATE ${ZEPHYR_BASE}/subsys/bluetooth/host/uuid.c src/main.c + src/test_common.c + src/test_vcp.c + src/test_micp.c ) diff --git a/tests/bluetooth/audio/cap_commander/include/test_common.h b/tests/bluetooth/audio/cap_commander/include/test_common.h new file mode 100644 index 000000000000..e60be9cc2335 --- /dev/null +++ b/tests/bluetooth/audio/cap_commander/include/test_common.h @@ -0,0 +1,12 @@ +/* test_common.h */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void test_mocks_init(void); +void test_mocks_cleanup(void); + +void test_conn_init(struct bt_conn *conn); diff --git a/tests/bluetooth/audio/cap_commander/src/main.c b/tests/bluetooth/audio/cap_commander/src/main.c index 435a9fe85dd8..a55a4442dae8 100644 --- a/tests/bluetooth/audio/cap_commander/src/main.c +++ b/tests/bluetooth/audio/cap_commander/src/main.c @@ -1,7 +1,7 @@ /* main.c - Application main entry point */ /* - * Copyright (c) 2023 Nordic Semiconductor ASA + * Copyright (c) 2023-2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,36 +9,24 @@ #include #include -#include -#include #include #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; static void mock_init_rule_before(const struct ztest_unit_test *test, void *fixture) { - mock_cap_commander_init(); - mock_bt_aics_init(); - mock_bt_csip_init(); - mock_bt_micp_init(); - mock_bt_vcp_init(); - mock_bt_vocs_init(); + test_mocks_init(); } static void mock_destroy_rule_after(const struct ztest_unit_test *test, void *fixture) { - mock_cap_commander_cleanup(); - mock_bt_aics_cleanup(); - mock_bt_csip_cleanup(); - mock_bt_micp_cleanup(); - mock_bt_vcp_cleanup(); - mock_bt_vocs_cleanup(); + test_mocks_cleanup(); } ZTEST_RULE(mock_rule, mock_init_rule_before, mock_destroy_rule_after); @@ -47,17 +35,6 @@ struct cap_commander_test_suite_fixture { struct bt_conn conns[CONFIG_BT_MAX_CONN]; }; -static void test_conn_init(struct bt_conn *conn) -{ - conn->index = 0; - conn->info.type = BT_CONN_TYPE_LE; - conn->info.role = BT_CONN_ROLE_PERIPHERAL; - conn->info.state = BT_CONN_STATE_CONNECTED; - conn->info.security.level = BT_SECURITY_L2; - conn->info.security.enc_key_size = BT_ENC_KEY_SIZE_MAX; - conn->info.security.flags = BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC; -} - static void cap_commander_test_suite_fixture_init(struct cap_commander_test_suite_fixture *fixture) { for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) { @@ -187,911 +164,3 @@ ZTEST_F(cap_commander_test_suite, test_commander_discover_inval_param_null) err = bt_cap_commander_discover(NULL); zassert_equal(-EINVAL, err, "Unexpected return value %d", err); } - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_changed", 1, - mock_cap_commander_volume_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_double) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_changed", 1, - mock_cap_commander_volume_changed_cb_fake.call_count); - - /* Verify that it still works as expected if we set the same value twice */ - err = bt_cap_commander_change_volume(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_changed", 2, - mock_cap_commander_volume_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_param_null) -{ - int err; - - err = bt_cap_commander_change_volume(NULL); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_param_null_members) -{ - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = NULL, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_param_null_member) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) { - members[i].member = &fixture->conns[i]; - } - members[ARRAY_SIZE(members) - 1].member = NULL; - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_missing_cas) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_missing_vcs) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .volume = 177, - }; - int err; - - for (size_t i = 0U; 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_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_param_zero_count) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = 0U, - .volume = 177, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { - members[i].member = &fixture->conns[i]; - } - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_inval_param_inval_count) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = CONFIG_BT_MAX_CONN + 1, - .volume = 177, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { - members[i].member = &fixture->conns[i]; - } - - err = bt_cap_commander_change_volume(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1, - mock_cap_commander_volume_offset_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_double) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1, - mock_cap_commander_volume_offset_changed_cb_fake.call_count); - - /* Verify that it still works as expected if we set the same value twice */ - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 2, - mock_cap_commander_volume_offset_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_null) -{ - int err; - - err = bt_cap_commander_change_volume_offset(NULL); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_null_param) -{ - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = NULL, - .count = ARRAY_SIZE(fixture->conns), - }; - int err; - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_null_member) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + i; - } - member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL; - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_missing_cas) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_missing_vocs) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + 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_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_zero_count) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = 0U, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + i; - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_inval_count) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = CONFIG_BT_MAX_CONN + 1, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = 100 + i; - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_inval_offset_max) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = BT_VOCS_MAX_OFFSET + 1; - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_offset_inval_param_inval_offset_min) -{ - struct bt_cap_commander_change_volume_offset_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_offset_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].offset = BT_VOCS_MIN_OFFSET - 1; - } - - err = bt_cap_commander_change_volume_offset(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1, - mock_cap_commander_volume_mute_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_double) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1, - mock_cap_commander_volume_mute_changed_cb_fake.call_count); - - /* Verify that it still works as expected if we set the same value twice */ - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 2, - mock_cap_commander_volume_mute_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_param_null) -{ - int err; - - err = bt_cap_commander_change_volume_mute_state(NULL); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_param_null_members) -{ - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = NULL, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_param_null_member) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) { - members[i].member = &fixture->conns[i]; - } - members[ARRAY_SIZE(members) - 1].member = NULL; - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_missing_cas) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - for (size_t i = 0U; 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++) { - struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ - - err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_missing_vcs) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = ARRAY_SIZE(fixture->conns), - .mute = true, - }; - int err; - - for (size_t i = 0U; 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_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_param_zero_count) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = 0U, - .mute = true, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { - members[i].member = &fixture->conns[i]; - } - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_volume_mute_state_inval_param_inval_count) -{ - union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_volume_mute_state_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .members = members, - .count = CONFIG_BT_MAX_CONN + 1, - .mute = true, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { - members[i].member = &fixture->conns[i]; - } - - err = bt_cap_commander_change_volume_mute_state(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_microphone_gain_setting) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + 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++) { - struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1, - mock_cap_commander_microphone_gain_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_microphone_gain_setting_double) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + 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++) { - struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ - - err = bt_cap_commander_discover(&fixture->conns[i]); - zassert_equal(0, err, "Unexpected return value %d", err); - - err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1, - mock_cap_commander_microphone_gain_changed_cb_fake.call_count); - - /* That that it still works as expected if we set the same value twice */ - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(0, err, "Unexpected return value %d", err); - - zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 2, - mock_cap_commander_microphone_gain_changed_cb_fake.call_count); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_microphone_gain_setting_inval_param_null) -{ - int err; - - err = bt_cap_commander_change_microphone_gain_setting(NULL); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, - test_commander_change_microphone_gain_setting_inval_param_null_param) -{ - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = NULL, - .count = ARRAY_SIZE(fixture->conns), - }; - int err; - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, - test_commander_change_microphone_gain_setting_inval_param_null_member) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + i; - } - member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL; - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_microphone_gain_setting_inval_missing_cas) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + 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++) { - struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ - - err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); - zassert_equal(0, err, "Unexpected return value %d", err); - } - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, test_commander_change_microphone_gain_setting_inval_missing_aics) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = ARRAY_SIZE(member_params), - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + 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_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, - test_commander_change_microphone_gain_setting_inval_param_zero_count) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = 0U, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + i; - } - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} - -ZTEST_F(cap_commander_test_suite, - test_commander_change_microphone_gain_setting_inval_param_inval_count) -{ - struct bt_cap_commander_change_microphone_gain_setting_member_param - member_params[ARRAY_SIZE(fixture->conns)]; - const struct bt_cap_commander_change_microphone_gain_setting_param param = { - .type = BT_CAP_SET_TYPE_AD_HOC, - .param = member_params, - .count = CONFIG_BT_MAX_CONN + 1, - }; - int err; - - for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { - member_params[i].member.member = &fixture->conns[i]; - member_params[i].gain = 10 + i; - } - - err = bt_cap_commander_change_microphone_gain_setting(¶m); - zassert_equal(-EINVAL, err, "Unexpected return value %d", err); -} diff --git a/tests/bluetooth/audio/cap_commander/src/test_common.c b/tests/bluetooth/audio/cap_commander/src/test_common.c new file mode 100644 index 000000000000..e254694c7d9e --- /dev/null +++ b/tests/bluetooth/audio/cap_commander/src/test_common.c @@ -0,0 +1,43 @@ +/* test_common.c - common procedures for unit test of CAP commander */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "cap_commander.h" +#include "conn.h" +#include "cap_mocks.h" +#include "test_common.h" + +void test_mocks_init(void) +{ + mock_cap_commander_init(); + mock_bt_aics_init(); + mock_bt_csip_init(); + mock_bt_micp_init(); + mock_bt_vcp_init(); + mock_bt_vocs_init(); +} + +void test_mocks_cleanup(void) +{ + mock_cap_commander_cleanup(); + mock_bt_aics_cleanup(); + mock_bt_csip_cleanup(); + mock_bt_micp_cleanup(); + mock_bt_vcp_cleanup(); + mock_bt_vocs_cleanup(); +} + +void test_conn_init(struct bt_conn *conn) +{ + conn->index = 0; + conn->info.type = BT_CONN_TYPE_LE; + conn->info.role = BT_CONN_ROLE_PERIPHERAL; + conn->info.state = BT_CONN_STATE_CONNECTED; + conn->info.security.level = BT_SECURITY_L2; + conn->info.security.enc_key_size = BT_ENC_KEY_SIZE_MAX; + conn->info.security.flags = BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC; +} diff --git a/tests/bluetooth/audio/cap_commander/src/test_micp.c b/tests/bluetooth/audio/cap_commander/src/test_micp.c new file mode 100644 index 000000000000..4d3958d0e449 --- /dev/null +++ b/tests/bluetooth/audio/cap_commander/src/test_micp.c @@ -0,0 +1,293 @@ +/* test_micp.c - unit test for microphone settings */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#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 + +struct cap_commander_test_micp_fixture { + struct bt_conn conns[CONFIG_BT_MAX_CONN]; +}; + +static void cap_commander_test_micp_fixture_init(struct cap_commander_test_micp_fixture *fixture) +{ + for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) { + test_conn_init(&fixture->conns[i]); + } +} + +static void *cap_commander_test_micp_setup(void) +{ + struct cap_commander_test_micp_fixture *fixture; + + fixture = malloc(sizeof(*fixture)); + zassert_not_null(fixture); + + return fixture; +} + +static void cap_commander_test_micp_before(void *f) +{ + memset(f, 0, sizeof(struct cap_commander_test_micp_fixture)); + cap_commander_test_micp_fixture_init(f); +} + +static void cap_commander_test_micp_after(void *f) +{ + struct cap_commander_test_micp_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_micp_teardown(void *f) +{ + free(f); +} + +ZTEST_SUITE(cap_commander_test_micp, NULL, cap_commander_test_micp_setup, + cap_commander_test_micp_before, cap_commander_test_micp_after, + cap_commander_test_micp_teardown); + + +ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + 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++) { + struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1, + mock_cap_commander_microphone_gain_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_double) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + 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++) { + struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 1, + mock_cap_commander_microphone_gain_changed_cb_fake.call_count); + + /* That that it still works as expected if we set the same value twice */ + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.microphone_gain_setting_changed", 2, + mock_cap_commander_microphone_gain_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_param_null) +{ + int err; + + err = bt_cap_commander_change_microphone_gain_setting(NULL); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, + test_commander_change_microphone_gain_setting_inval_param_null_param) +{ + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = NULL, + .count = ARRAY_SIZE(fixture->conns), + }; + int err; + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, + test_commander_change_microphone_gain_setting_inval_param_null_member) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + i; + } + member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL; + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_missing_cas) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + 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++) { + struct bt_micp_mic_ctlr *mic_ctlr; /* We don't care about this */ + + err = bt_micp_mic_ctlr_discover(&fixture->conns[i], &mic_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, test_commander_change_microphone_gain_setting_inval_missing_aics) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + 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_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, + test_commander_change_microphone_gain_setting_inval_param_zero_count) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = 0U, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + i; + } + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_micp, + test_commander_change_microphone_gain_setting_inval_param_inval_count) +{ + struct bt_cap_commander_change_microphone_gain_setting_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_microphone_gain_setting_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = CONFIG_BT_MAX_CONN + 1, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].gain = 10 + i; + } + + err = bt_cap_commander_change_microphone_gain_setting(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} diff --git a/tests/bluetooth/audio/cap_commander/src/test_vcp.c b/tests/bluetooth/audio/cap_commander/src/test_vcp.c new file mode 100644 index 000000000000..5d2773908d47 --- /dev/null +++ b/tests/bluetooth/audio/cap_commander/src/test_vcp.c @@ -0,0 +1,753 @@ +/* test_vcp.c - unit test for volume settings */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include + +#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 + +struct cap_commander_test_vcp_fixture { + struct bt_conn conns[CONFIG_BT_MAX_CONN]; +}; + +static void cap_commander_test_vcp_fixture_init(struct cap_commander_test_vcp_fixture *fixture) +{ + for (size_t i = 0; i < ARRAY_SIZE(fixture->conns); i++) { + test_conn_init(&fixture->conns[i]); + } +} + +static void *cap_commander_test_vcp_setup(void) +{ + struct cap_commander_test_vcp_fixture *fixture; + + fixture = malloc(sizeof(*fixture)); + zassert_not_null(fixture); + + return fixture; +} + +static void cap_commander_test_vcp_before(void *f) +{ + memset(f, 0, sizeof(struct cap_commander_test_vcp_fixture)); + cap_commander_test_vcp_fixture_init(f); +} + +static void cap_commander_test_vcp_after(void *f) +{ + struct cap_commander_test_vcp_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_vcp_teardown(void *f) +{ + free(f); +} + +ZTEST_SUITE(cap_commander_test_vcp, NULL, cap_commander_test_vcp_setup, + cap_commander_test_vcp_before, cap_commander_test_vcp_after, + cap_commander_test_vcp_teardown); + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_changed", 1, + mock_cap_commander_volume_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_double) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_changed", 1, + mock_cap_commander_volume_changed_cb_fake.call_count); + + /* Verify that it still works as expected if we set the same value twice */ + err = bt_cap_commander_change_volume(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_changed", 2, + mock_cap_commander_volume_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null) +{ + int err; + + err = bt_cap_commander_change_volume(NULL); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_members) +{ + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = NULL, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_null_member) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) { + members[i].member = &fixture->conns[i]; + } + members[ARRAY_SIZE(members) - 1].member = NULL; + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_cas) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_missing_vcs) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .volume = 177, + }; + int err; + + for (size_t i = 0U; 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_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_zero_count) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = 0U, + .volume = 177, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { + members[i].member = &fixture->conns[i]; + } + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_inval_param_inval_count) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = CONFIG_BT_MAX_CONN + 1, + .volume = 177, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { + members[i].member = &fixture->conns[i]; + } + + err = bt_cap_commander_change_volume(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1, + mock_cap_commander_volume_offset_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_double) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 1, + mock_cap_commander_volume_offset_changed_cb_fake.call_count); + + /* Verify that it still works as expected if we set the same value twice */ + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_offset_changed", 2, + mock_cap_commander_volume_offset_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null) +{ + int err; + + err = bt_cap_commander_change_volume_offset(NULL); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_param) +{ + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = NULL, + .count = ARRAY_SIZE(fixture->conns), + }; + int err; + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_null_member) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + i; + } + member_params[ARRAY_SIZE(member_params) - 1].member.member = NULL; + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_cas) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_missing_vocs) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + 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_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_zero_count) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = 0U, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + i; + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_count) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = CONFIG_BT_MAX_CONN + 1, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = 100 + i; + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_max) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = BT_VOCS_MAX_OFFSET + 1; + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_offset_inval_param_inval_offset_min) +{ + struct bt_cap_commander_change_volume_offset_member_param + member_params[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_offset_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .param = member_params, + .count = ARRAY_SIZE(member_params), + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(member_params); i++) { + member_params[i].member.member = &fixture->conns[i]; + member_params[i].offset = BT_VOCS_MIN_OFFSET - 1; + } + + err = bt_cap_commander_change_volume_offset(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1, + mock_cap_commander_volume_mute_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_double) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_cap_commander_discover(&fixture->conns[i]); + zassert_equal(0, err, "Unexpected return value %d", err); + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 1, + mock_cap_commander_volume_mute_changed_cb_fake.call_count); + + /* Verify that it still works as expected if we set the same value twice */ + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(0, err, "Unexpected return value %d", err); + + zexpect_call_count("bt_cap_commander_cb.volume_mute_changed", 2, + mock_cap_commander_volume_mute_changed_cb_fake.call_count); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null) +{ + int err; + + err = bt_cap_commander_change_volume_mute_state(NULL); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_members) +{ + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = NULL, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_null_member) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members) - 1; i++) { + members[i].member = &fixture->conns[i]; + } + members[ARRAY_SIZE(members) - 1].member = NULL; + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_cas) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + for (size_t i = 0U; 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++) { + struct bt_vcp_vol_ctlr *vol_ctlr; /* We don't care about this */ + + err = bt_vcp_vol_ctlr_discover(&fixture->conns[i], &vol_ctlr); + zassert_equal(0, err, "Unexpected return value %d", err); + } + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_missing_vcs) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = ARRAY_SIZE(fixture->conns), + .mute = true, + }; + int err; + + for (size_t i = 0U; 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_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_zero_count) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = 0U, + .mute = true, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { + members[i].member = &fixture->conns[i]; + } + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +} + +ZTEST_F(cap_commander_test_vcp, test_commander_change_volume_mute_state_inval_param_inval_count) +{ + union bt_cap_set_member members[ARRAY_SIZE(fixture->conns)]; + const struct bt_cap_commander_change_volume_mute_state_param param = { + .type = BT_CAP_SET_TYPE_AD_HOC, + .members = members, + .count = CONFIG_BT_MAX_CONN + 1, + .mute = true, + }; + int err; + + for (size_t i = 0U; i < ARRAY_SIZE(members); i++) { + members[i].member = &fixture->conns[i]; + } + + err = bt_cap_commander_change_volume_mute_state(¶m); + zassert_equal(-EINVAL, err, "Unexpected return value %d", err); +}