From 33767540d92ec7a8fb41af65583ae8e3673ec6fb Mon Sep 17 00:00:00 2001 From: Mariusz Skamra Date: Mon, 27 Mar 2023 13:07:33 +0200 Subject: [PATCH] tests: Bluetooth: audio: Extend kernel mocks This adds basic functionality that mocks the k_work API. The ASCS uses delayed work to defer the CIS disconnection. Signed-off-by: Mariusz Skamra --- tests/bluetooth/audio/ascs/src/main.c | 3 +- .../audio/mocks/include/mock_kernel.h | 13 +--- tests/bluetooth/audio/mocks/src/kernel.c | 59 ++++++++++++++++++- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/tests/bluetooth/audio/ascs/src/main.c b/tests/bluetooth/audio/ascs/src/main.c index cde208d61599..a25edc76d330 100644 --- a/tests/bluetooth/audio/ascs/src/main.c +++ b/tests/bluetooth/audio/ascs/src/main.c @@ -73,7 +73,7 @@ static void mock_init_rule_before(const struct ztest_unit_test *test, void *fixt { mock_bap_unicast_server_init(); mock_bt_iso_init(); - KERNEL_FFF_FAKES_LIST(RESET_FAKE); + mock_kernel_init(); PACS_FFF_FAKES_LIST(RESET_FAKE); mock_bap_stream_init(); mock_bt_gatt_init(); @@ -83,6 +83,7 @@ static void mock_destroy_rule_after(const struct ztest_unit_test *test, void *fi { mock_bap_unicast_server_cleanup(); mock_bt_iso_cleanup(); + mock_kernel_cleanup(); mock_bap_stream_cleanup(); mock_bt_gatt_cleanup(); } diff --git a/tests/bluetooth/audio/mocks/include/mock_kernel.h b/tests/bluetooth/audio/mocks/include/mock_kernel.h index 239949dd2531..2224ea02c6b9 100644 --- a/tests/bluetooth/audio/mocks/include/mock_kernel.h +++ b/tests/bluetooth/audio/mocks/include/mock_kernel.h @@ -11,21 +11,12 @@ #include #include -/* List of fakes used by this unit tester */ -#define KERNEL_FFF_FAKES_LIST(FAKE) \ - FAKE(z_timeout_remaining) \ - FAKE(k_work_schedule) \ - FAKE(k_work_cancel_delayable_sync) \ - FAKE(k_work_init_delayable) \ - FAKE(k_work_cancel_delayable) \ - FAKE(k_work_reschedule) \ +void mock_kernel_init(void); +void mock_kernel_cleanup(void); DECLARE_FAKE_VALUE_FUNC(k_ticks_t, z_timeout_remaining, const struct _timeout *); DECLARE_FAKE_VALUE_FUNC(int, k_work_schedule, struct k_work_delayable *, k_timeout_t); DECLARE_FAKE_VALUE_FUNC(bool, k_work_cancel_delayable_sync, struct k_work_delayable *, struct k_work_sync *); -DECLARE_FAKE_VOID_FUNC(k_work_init_delayable, struct k_work_delayable *, k_work_handler_t); -DECLARE_FAKE_VALUE_FUNC(int, k_work_cancel_delayable, struct k_work_delayable *); -DECLARE_FAKE_VALUE_FUNC(int, k_work_reschedule, struct k_work_delayable *, k_timeout_t); #endif /* MOCKS_KERNEL_H_ */ diff --git a/tests/bluetooth/audio/mocks/src/kernel.c b/tests/bluetooth/audio/mocks/src/kernel.c index 3905898d9be6..bbd8d368a616 100644 --- a/tests/bluetooth/audio/mocks/src/kernel.c +++ b/tests/bluetooth/audio/mocks/src/kernel.c @@ -6,13 +6,66 @@ */ #include +#include #include "mock_kernel.h" +/* List of fakes used by this unit tester */ +#define FFF_FAKES_LIST(FAKE) \ + FAKE(z_timeout_remaining) \ + FAKE(k_work_schedule) \ + FAKE(k_work_cancel_delayable_sync) \ + +/* List of k_work items to be worked. */ +static sys_slist_t work_pending; + DEFINE_FAKE_VALUE_FUNC(k_ticks_t, z_timeout_remaining, const struct _timeout *); DEFINE_FAKE_VALUE_FUNC(int, k_work_schedule, struct k_work_delayable *, k_timeout_t); DEFINE_FAKE_VALUE_FUNC(bool, k_work_cancel_delayable_sync, struct k_work_delayable *, struct k_work_sync *); -DEFINE_FAKE_VOID_FUNC(k_work_init_delayable, struct k_work_delayable *, k_work_handler_t); -DEFINE_FAKE_VALUE_FUNC(int, k_work_cancel_delayable, struct k_work_delayable *); -DEFINE_FAKE_VALUE_FUNC(int, k_work_reschedule, struct k_work_delayable *, k_timeout_t); + +void k_work_init_delayable(struct k_work_delayable *dwork, k_work_handler_t handler) +{ + dwork->work.handler = handler; +} + +int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) +{ + struct k_work *work; + + /* Determine whether the work item is queued already. */ + SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) { + if (work == &dwork->work) { + return 0; + } + } + + sys_slist_append(&work_pending, &dwork->work.node); + + return 0; +} + +int k_work_cancel_delayable(struct k_work_delayable *dwork) +{ + (void)sys_slist_find_and_remove(&work_pending, &dwork->work.node); + + return 0; +} + +void mock_kernel_init(void) +{ + FFF_FAKES_LIST(RESET_FAKE); + + sys_slist_init(&work_pending); +} + +void mock_kernel_cleanup(void) +{ + struct k_work *work, *tmp; + + /* Run all pending works */ + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&work_pending, work, tmp, node) { + (void)sys_slist_remove(&work_pending, NULL, &work->node); + work->handler(work); + } +}