18da2a883SGabriele Monaco /* SPDX-License-Identifier: GPL-2.0 */ 28da2a883SGabriele Monaco /* 38da2a883SGabriele Monaco * Copyright (C) 2026-2029 Red Hat, Inc. Gabriele Monaco <gmonaco@redhat.com> 48da2a883SGabriele Monaco * 5*cf8f191cSGabriele Monaco * Declaration of wrappers to allow mocking core functionality, like current, 6*cf8f191cSGabriele Monaco * and other testing utilities. 7*cf8f191cSGabriele Monaco * Necessary only when mocking may be needed. If the RV KUnit test is 8*cf8f191cSGabriele Monaco * enabled, the wrappers incur an additional function call overhead. 98da2a883SGabriele Monaco */ 108da2a883SGabriele Monaco 118da2a883SGabriele Monaco #ifndef _RV_KUNIT_H 128da2a883SGabriele Monaco #define _RV_KUNIT_H 138da2a883SGabriele Monaco 148da2a883SGabriele Monaco #if IS_ENABLED(CONFIG_RV_MONITORS_KUNIT_TEST) 158da2a883SGabriele Monaco 168da2a883SGabriele Monaco #include <kunit/test.h> 178da2a883SGabriele Monaco #include <kunit/test-bug.h> 188da2a883SGabriele Monaco #include <linux/delay.h> 198da2a883SGabriele Monaco 208da2a883SGabriele Monaco int rv_set_testing(struct kunit_suite *suite); 218da2a883SGabriele Monaco void rv_clear_testing(struct kunit_suite *suite); 228da2a883SGabriele Monaco 238da2a883SGabriele Monaco #define RV_KUNIT_MAX_MOCK_TASKS 8 248da2a883SGabriele Monaco 258da2a883SGabriele Monaco struct rv_kunit_ctx { 268da2a883SGabriele Monaco int reactions, expected; 278da2a883SGabriele Monaco int mock_task_count; 288da2a883SGabriele Monaco struct task_struct *mock_tasks[RV_KUNIT_MAX_MOCK_TASKS]; 298da2a883SGabriele Monaco }; 308da2a883SGabriele Monaco 318da2a883SGabriele Monaco #define RV_KUNIT_EXPECT_REACTION(test, ctx) \ 328da2a883SGabriele Monaco do { \ 338da2a883SGabriele Monaco KUNIT_EXPECT_EQ(test, ctx->reactions, ++ctx->expected); \ 348da2a883SGabriele Monaco if (ctx->reactions != ctx->expected) \ 358da2a883SGabriele Monaco ctx->expected = ctx->reactions; \ 368da2a883SGabriele Monaco } while (0) 378da2a883SGabriele Monaco 388da2a883SGabriele Monaco #define RV_KUNIT_EXPECT_NO_REACTION(test, ctx) \ 398da2a883SGabriele Monaco do { \ 408da2a883SGabriele Monaco KUNIT_EXPECT_EQ(test, ctx->reactions, ctx->expected); \ 418da2a883SGabriele Monaco if (ctx->reactions != ctx->expected) \ 428da2a883SGabriele Monaco ctx->expected = ctx->reactions; \ 438da2a883SGabriele Monaco } while (0) 448da2a883SGabriele Monaco 458da2a883SGabriele Monaco #define RV_KUNIT_EXPECT_REACTION_HERE(test, ctx) \ 468da2a883SGabriele Monaco for (int __done = ({ RV_KUNIT_EXPECT_NO_REACTION(test, ctx); 0; }); \ 478da2a883SGabriele Monaco !__done; \ 488da2a883SGabriele Monaco __done = ({ RV_KUNIT_EXPECT_REACTION(test, ctx); 1; })) 498da2a883SGabriele Monaco 508da2a883SGabriele Monaco struct rv_kunit_mon { 518da2a883SGabriele Monaco struct rv_monitor *rv_this; 528da2a883SGabriele Monaco int (*monitor_init)(void); 538da2a883SGabriele Monaco void (*monitor_destroy)(void); 548da2a883SGabriele Monaco bool is_per_task; 558da2a883SGabriele Monaco int *task_slot; 568da2a883SGabriele Monaco void (*task_reset)(struct task_struct *task); 578da2a883SGabriele Monaco }; 588da2a883SGabriele Monaco 598da2a883SGabriele Monaco void prepare_test(struct kunit *test, const struct rv_kunit_mon *mon); 608da2a883SGabriele Monaco void teardown_test(void *arg); 618da2a883SGabriele Monaco struct task_struct *rv_kunit_alloc_mock_task(struct kunit *test); 628da2a883SGabriele Monaco 63*cf8f191cSGabriele Monaco void rv_mock_current(struct task_struct *tsk); 64*cf8f191cSGabriele Monaco struct task_struct *rv_get_mock_current(void); 65*cf8f191cSGabriele Monaco 66*cf8f191cSGabriele Monaco #define rv_get_current() (unlikely(kunit_get_current_test()) ? rv_get_mock_current() : current) 67*cf8f191cSGabriele Monaco 68*cf8f191cSGabriele Monaco #else /* !CONFIG_RV_MONITORS_KUNIT_TEST */ 69*cf8f191cSGabriele Monaco 70*cf8f191cSGabriele Monaco #define rv_get_current() current 71*cf8f191cSGabriele Monaco 728da2a883SGabriele Monaco #endif /* CONFIG_RV_MONITORS_KUNIT_TEST */ 738da2a883SGabriele Monaco #endif /* _RV_KUNIT_H */ 74