SimpleKernel 1.17.0
Loading...
Searching...
No Matches
system_test.h
Go to the documentation of this file.
1
5#pragma once
6
7#include <etl/vector.h>
8
9#include <cstdint>
10#include <type_traits>
11
12#include "kernel_log.hpp"
13
14// ===========================================================================
15// Assertion helpers
16// ===========================================================================
17
18template <typename T1, typename T2>
19bool expect_eq_helper(const T1& val1, const T2& val2, const char* msg) {
20#pragma GCC diagnostic push
21#pragma GCC diagnostic ignored "-Wsign-compare"
22 if (val1 != val2) {
23#pragma GCC diagnostic pop
24 if constexpr (std::is_convertible_v<T1, uint64_t> &&
25 std::is_convertible_v<T2, uint64_t>) {
26 klog::Err("FAIL: {}. Expected {}, got {}", msg,
27 static_cast<uint64_t>(val2), static_cast<uint64_t>(val1));
28 } else {
29 klog::Err("FAIL: {}", msg);
30 }
31 return false;
32 }
33 return true;
34}
35
36template <typename T1, typename T2>
37bool expect_ne_helper(const T1& val1, const T2& val2, const char* msg) {
38#pragma GCC diagnostic push
39#pragma GCC diagnostic ignored "-Wsign-compare"
40 if (val1 == val2) {
41#pragma GCC diagnostic pop
42 if constexpr (std::is_convertible_v<T1, uint64_t> &&
43 std::is_convertible_v<T2, uint64_t>) {
44 klog::Err("FAIL: {}. Expected not {}, got {}", msg,
45 static_cast<uint64_t>(val2), static_cast<uint64_t>(val1));
46 } else {
47 klog::Err("FAIL: {}", msg);
48 }
49 return false;
50 }
51 return true;
52}
53
54template <typename T1, typename T2>
55bool expect_gt_helper(const T1& val1, const T2& val2, const char* msg) {
56#pragma GCC diagnostic push
57#pragma GCC diagnostic ignored "-Wsign-compare"
58 if (!(val1 > val2)) {
59#pragma GCC diagnostic pop
60 if constexpr (std::is_convertible_v<T1, uint64_t> &&
61 std::is_convertible_v<T2, uint64_t>) {
62 klog::Err("FAIL: {}. Expected {} > {}", msg, static_cast<uint64_t>(val1),
63 static_cast<uint64_t>(val2));
64 } else {
65 klog::Err("FAIL: {}", msg);
66 }
67 return false;
68 }
69 return true;
70}
71
72template <typename T1, typename T2>
73bool expect_lt_helper(const T1& val1, const T2& val2, const char* msg) {
74#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wsign-compare"
76 if (!(val1 < val2)) {
77#pragma GCC diagnostic pop
78 if constexpr (std::is_convertible_v<T1, uint64_t> &&
79 std::is_convertible_v<T2, uint64_t>) {
80 klog::Err("FAIL: {}. Expected {} < {}", msg, static_cast<uint64_t>(val1),
81 static_cast<uint64_t>(val2));
82 } else {
83 klog::Err("FAIL: {}", msg);
84 }
85 return false;
86 }
87 return true;
88}
89
90template <typename T1, typename T2>
91bool expect_ge_helper(const T1& val1, const T2& val2, const char* msg) {
92#pragma GCC diagnostic push
93#pragma GCC diagnostic ignored "-Wsign-compare"
94 if (!(val1 >= val2)) {
95#pragma GCC diagnostic pop
96 if constexpr (std::is_convertible_v<T1, uint64_t> &&
97 std::is_convertible_v<T2, uint64_t>) {
98 klog::Err("FAIL: {}. Expected {} >= {}", msg, static_cast<uint64_t>(val1),
99 static_cast<uint64_t>(val2));
100 } else {
101 klog::Err("FAIL: {}", msg);
102 }
103 return false;
104 }
105 return true;
106}
107
108template <typename T1, typename T2>
109bool expect_le_helper(const T1& val1, const T2& val2, const char* msg) {
110#pragma GCC diagnostic push
111#pragma GCC diagnostic ignored "-Wsign-compare"
112 if (!(val1 <= val2)) {
113#pragma GCC diagnostic pop
114 if constexpr (std::is_convertible_v<T1, uint64_t> &&
115 std::is_convertible_v<T2, uint64_t>) {
116 klog::Err("FAIL: {}. Expected {} <= {}", msg, static_cast<uint64_t>(val1),
117 static_cast<uint64_t>(val2));
118 } else {
119 klog::Err("FAIL: {}", msg);
120 }
121 return false;
122 }
123 return true;
124}
125
126#define EXPECT_EQ(val1, val2, msg) \
127 if (!expect_eq_helper(val1, val2, msg)) { \
128 return false; \
129 }
130
131#define EXPECT_NE(val1, val2, msg) \
132 if (!expect_ne_helper(val1, val2, msg)) { \
133 return false; \
134 }
135
136#define EXPECT_GT(val1, val2, msg) \
137 if (!expect_gt_helper(val1, val2, msg)) { \
138 return false; \
139 }
140
141#define EXPECT_LT(val1, val2, msg) \
142 if (!expect_lt_helper(val1, val2, msg)) { \
143 return false; \
144 }
145
146#define EXPECT_GE(val1, val2, msg) \
147 if (!expect_ge_helper(val1, val2, msg)) { \
148 return false; \
149 }
150
151#define EXPECT_LE(val1, val2, msg) \
152 if (!expect_le_helper(val1, val2, msg)) { \
153 return false; \
154 }
155
156#define EXPECT_TRUE(cond, msg) \
157 if (!(cond)) { \
158 klog::Err("FAIL: {}", msg); \
159 return false; \
160 }
161
162#define EXPECT_FALSE(cond, msg) \
163 if (cond) { \
164 klog::Err("FAIL: {}", msg); \
165 return false; \
166 }
167
168// ===========================================================================
169// Test declarations
170// ===========================================================================
171
172auto ctor_dtor_test() -> bool;
173auto spinlock_test() -> bool;
174auto virtual_memory_test() -> bool;
175auto interrupt_test() -> bool;
176auto fifo_scheduler_test() -> bool;
177auto rr_scheduler_test() -> bool;
178auto cfs_scheduler_test() -> bool;
179auto idle_scheduler_test() -> bool;
180auto thread_group_system_test() -> bool;
181auto wait_system_test() -> bool;
182auto clone_system_test() -> bool;
183auto exit_system_test() -> bool;
184auto ramfs_system_test() -> bool;
185auto fatfs_system_test() -> bool;
186auto memory_test() -> bool;
187auto kernel_task_test() -> bool;
188auto user_task_test() -> bool;
189auto mutex_test() -> bool;
190
191// ===========================================================================
192// QEMU exit
193// ===========================================================================
194
196inline void QemuExit([[maybe_unused]] bool success) {
197#if defined(__riscv)
198 // sifive_test device (virt machine 默认存在,地址 0x100000)
199 // 0x5555 = FINISHER_PASS, 0x3333 = FINISHER_FAIL
200 volatile auto* finisher = reinterpret_cast<volatile uint32_t*>(0x100000);
201 *finisher = success ? 0x5555 : 0x3333;
202#elif defined(__x86_64__)
203 // isa-debug-exit device (需要 QEMU 参数:
204 // -device isa-debug-exit,iobase=0xf4,iosize=0x04)
205 // QEMU 退出码 = (val << 1) | 1,所以 0 -> 1(pass), 1 -> 3(fail)
206 uint32_t code = success ? 0 : 1;
207 asm volatile("outl %0, %1" ::"a"(code), "Nd"(static_cast<uint16_t>(0xf4)));
208#elif defined(__aarch64__)
209 // PSCI SYSTEM_OFF (function id = 0x84000008)
210 // 需要 EL2/EL3 支持(ATF 已提供)
211 register uint64_t x0 asm("x0") = 0x84000008;
212 asm volatile("hvc #0" : "+r"(x0));
213#endif
214 __builtin_unreachable();
215}
216
217// ===========================================================================
218// Test thread result tracking
219// ===========================================================================
220
222enum class TestThreadStatus : uint8_t {
223 kPending,
224 kRunning,
225 kPassed,
226 kFailed,
227 kTimeout,
228};
229
232 const char* name = nullptr;
233 int64_t pid = 0;
235 int exit_code = -1;
236};
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
单个测试线程的结果记录
int64_t pid
const char * name
TestThreadStatus status
auto ramfs_system_test() -> bool
bool expect_ge_helper(const T1 &val1, const T2 &val2, const char *msg)
Definition system_test.h:91
auto idle_scheduler_test() -> bool
auto interrupt_test() -> bool
void QemuExit(bool success)
测试结束后退出 QEMU,success=true 表示全部通过
auto exit_system_test() -> bool
Exit 系统测试入口
auto wait_system_test() -> bool
Wait 系统测试入口
auto rr_scheduler_test() -> bool
auto clone_system_test() -> bool
bool expect_le_helper(const T1 &val1, const T2 &val2, const char *msg)
bool expect_gt_helper(const T1 &val1, const T2 &val2, const char *msg)
Definition system_test.h:55
auto user_task_test() -> bool
auto thread_group_system_test() -> bool
线程组系统测试入口
bool expect_ne_helper(const T1 &val1, const T2 &val2, const char *msg)
Definition system_test.h:37
auto mutex_test() -> bool
auto virtual_memory_test() -> bool
auto fatfs_system_test() -> bool
bool expect_eq_helper(const T1 &val1, const T2 &val2, const char *msg)
Definition system_test.h:19
auto fifo_scheduler_test() -> bool
auto cfs_scheduler_test() -> bool
auto spinlock_test() -> bool
bool expect_lt_helper(const T1 &val1, const T2 &val2, const char *msg)
Definition system_test.h:73
auto memory_test() -> bool
auto kernel_task_test() -> bool
TestThreadStatus
测试线程运行状态
@ kPassed
测试通过
@ kRunning
运行中
@ kTimeout
超时未完成
@ kPending
等待启动
@ kFailed
测试失败
auto ctor_dtor_test() -> bool