xref: /linux/include/rv/kunit.h (revision 55ee4b931a7ffedc886175d265dd6e6d08fd4151)
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