| /* SPDX-License-Identifier: GPL-2.0 */ |
| /* |
| * Copyright (C) 2026-2029 Red Hat, Inc. Gabriele Monaco <gmonaco@redhat.com> |
| * |
| * Declaration of wrappers to allow mocking core functionality, like current, |
| * and other testing utilities. |
| * Necessary only when mocking may be needed. If the RV KUnit test is |
| * enabled, the wrappers incur an additional function call overhead. |
| */ |
| |
| #ifndef _RV_KUNIT_H |
| #define _RV_KUNIT_H |
| |
| #if IS_ENABLED(CONFIG_RV_MONITORS_KUNIT_TEST) |
| |
| #include <kunit/test.h> |
| #include <kunit/test-bug.h> |
| #include <linux/delay.h> |
| |
| int rv_set_testing(struct kunit_suite *suite); |
| void rv_clear_testing(struct kunit_suite *suite); |
| |
| #define RV_KUNIT_MAX_MOCK_TASKS 8 |
| |
| struct rv_kunit_ctx { |
| int reactions, expected; |
| int mock_task_count; |
| struct task_struct *mock_tasks[RV_KUNIT_MAX_MOCK_TASKS]; |
| }; |
| |
| #define RV_KUNIT_EXPECT_REACTION(test, ctx) \ |
| do { \ |
| KUNIT_EXPECT_EQ(test, ctx->reactions, ++ctx->expected); \ |
| if (ctx->reactions != ctx->expected) \ |
| ctx->expected = ctx->reactions; \ |
| } while (0) |
| |
| #define RV_KUNIT_EXPECT_NO_REACTION(test, ctx) \ |
| do { \ |
| KUNIT_EXPECT_EQ(test, ctx->reactions, ctx->expected); \ |
| if (ctx->reactions != ctx->expected) \ |
| ctx->expected = ctx->reactions; \ |
| } while (0) |
| |
| #define RV_KUNIT_EXPECT_REACTION_HERE(test, ctx) \ |
| for (int __done = ({ RV_KUNIT_EXPECT_NO_REACTION(test, ctx); 0; }); \ |
| !__done; \ |
| __done = ({ RV_KUNIT_EXPECT_REACTION(test, ctx); 1; })) |
| |
| struct rv_kunit_mon { |
| struct rv_monitor *rv_this; |
| int (*monitor_init)(void); |
| void (*monitor_destroy)(void); |
| bool is_per_task; |
| int *task_slot; |
| void (*task_reset)(struct task_struct *task); |
| }; |
| |
| void prepare_test(struct kunit *test, const struct rv_kunit_mon *mon); |
| void teardown_test(void *arg); |
| struct task_struct *rv_kunit_alloc_mock_task(struct kunit *test); |
| |
| void rv_mock_current(struct task_struct *tsk); |
| struct task_struct *rv_get_mock_current(void); |
| |
| #define rv_get_current() (unlikely(kunit_get_current_test()) ? rv_get_mock_current() : current) |
| |
| #else /* !CONFIG_RV_MONITORS_KUNIT_TEST */ |
| |
| #define rv_get_current() current |
| |
| #endif /* CONFIG_RV_MONITORS_KUNIT_TEST */ |
| #endif /* _RV_KUNIT_H */ |