SimpleKernel 1.17.0
Loading...
Searching...
No Matches
ramfs_test.cpp
Go to the documentation of this file.
1
6#include "ramfs.hpp"
7
8#include <gtest/gtest.h>
9
10#include <vector>
11
13
14using namespace vfs;
15using namespace ramfs;
16
17class RamFsTest : public ::testing::Test {
18 protected:
21
22 void SetUp() override {
25 env_state_.BindThreadToCore(std::this_thread::get_id(), 0);
26 auto result = ramfs_.Mount(nullptr);
27 EXPECT_TRUE(result.has_value());
28 }
29
30 void TearDown() override {
31 (void)ramfs_.Unmount();
33 }
34};
35
36// 测试基本挂载/卸载
37TEST_F(RamFsTest, MountUnmount) {
38 // SetUp 中已经挂载,这里测试重复挂载
39 auto result = ramfs_.Mount(nullptr);
40 EXPECT_FALSE(result.has_value()); // 应该失败,因为已经挂载
41}
42
43TEST_F(RamFsTest, GetName) { EXPECT_STREQ(ramfs_.GetName(), "ramfs"); }
44
45TEST_F(RamFsTest, GetRootInode) {
46 Inode* root = ramfs_.GetRootInode();
47 EXPECT_NE(root, nullptr);
48 EXPECT_EQ(root->type, FileType::kDirectory);
49}
50
51// 测试 inode 分配
52TEST_F(RamFsTest, AllocateInode) {
53 // 分配多个 inode
54 std::vector<Inode*> inodes;
55 for (int i = 0; i < 10; ++i) {
56 auto result = ramfs_.AllocateInode();
57 EXPECT_TRUE(result.has_value());
58 EXPECT_NE(result.value(), nullptr);
59 inodes.push_back(result.value());
60 }
61
62 // 释放所有 inode
63 for (auto* inode : inodes) {
64 auto free_result = ramfs_.FreeInode(inode);
65 EXPECT_TRUE(free_result.has_value());
66 }
67}
68
69// 测试文件创建和查找
70TEST_F(RamFsTest, CreateAndLookupFile) {
71 Inode* root = ramfs_.GetRootInode();
72 ASSERT_NE(root, nullptr);
73 ASSERT_NE(root->ops, nullptr);
74
75 // 创建文件
76 auto create_result =
77 root->ops->Create(root, "testfile.txt", FileType::kRegular);
78 EXPECT_TRUE(create_result.has_value());
79
80 Inode* file_inode = create_result.value();
81 EXPECT_NE(file_inode, nullptr);
82 EXPECT_EQ(file_inode->type, FileType::kRegular);
83
84 // 查找文件
85 auto lookup_result = root->ops->Lookup(root, "testfile.txt");
86 EXPECT_TRUE(lookup_result.has_value());
87 EXPECT_EQ(lookup_result.value(), file_inode);
88
89 // 查找不存在的文件
90 lookup_result = root->ops->Lookup(root, "nonexistent.txt");
91 EXPECT_FALSE(lookup_result.has_value());
92}
93
94// 测试目录创建
95TEST_F(RamFsTest, CreateDirectory) {
96 Inode* root = ramfs_.GetRootInode();
97 ASSERT_NE(root, nullptr);
98 ASSERT_NE(root->ops, nullptr);
99
100 // 创建目录
101 auto mkdir_result = root->ops->Mkdir(root, "testdir");
102 EXPECT_TRUE(mkdir_result.has_value());
103
104 Inode* dir_inode = mkdir_result.value();
105 EXPECT_NE(dir_inode, nullptr);
106 EXPECT_EQ(dir_inode->type, FileType::kDirectory);
107}
108
109// 测试文件删除
110TEST_F(RamFsTest, UnlinkFile) {
111 Inode* root = ramfs_.GetRootInode();
112 ASSERT_NE(root, nullptr);
113
114 // 先创建文件
115 auto create_result =
116 root->ops->Create(root, "todelete.txt", FileType::kRegular);
117 ASSERT_TRUE(create_result.has_value());
118
119 // 删除文件
120 auto unlink_result = root->ops->Unlink(root, "todelete.txt");
121 EXPECT_TRUE(unlink_result.has_value());
122
123 // 确认文件已删除
124 auto lookup_result = root->ops->Lookup(root, "todelete.txt");
125 EXPECT_FALSE(lookup_result.has_value());
126}
127
128// 测试目录删除
130 Inode* root = ramfs_.GetRootInode();
131 ASSERT_NE(root, nullptr);
132
133 // 创建目录
134 auto mkdir_result = root->ops->Mkdir(root, "dir_to_remove");
135 ASSERT_TRUE(mkdir_result.has_value());
136
137 // 删除目录
138 auto rmdir_result = root->ops->Rmdir(root, "dir_to_remove");
139 EXPECT_TRUE(rmdir_result.has_value());
140
141 // 确认目录已删除
142 auto lookup_result = root->ops->Lookup(root, "dir_to_remove");
143 EXPECT_FALSE(lookup_result.has_value());
144}
145
146// 测试文件读写
147TEST_F(RamFsTest, FileReadWrite) {
148 Inode* root = ramfs_.GetRootInode();
149 ASSERT_NE(root, nullptr);
150
151 // 创建文件
152 auto create_result =
153 root->ops->Create(root, "rwtest.txt", FileType::kRegular);
154 ASSERT_TRUE(create_result.has_value());
155
156 Inode* file_inode = create_result.value();
157
158 // 创建 File 对象
159 File file;
160 file.inode = file_inode;
161 file.offset = 0;
162 file.ops = ramfs_.GetFileOps();
163
164 // 写入数据
165 const char* write_data = "Hello, RamFS!";
166 size_t write_len = strlen(write_data);
167
168 auto write_result = file.ops->Write(&file, write_data, write_len);
169 EXPECT_TRUE(write_result.has_value());
170 EXPECT_EQ(write_result.value(), write_len);
171
172 // 重置偏移量并读取
173 file.offset = 0;
174 char read_buffer[64] = {0};
175
176 auto read_result = file.ops->Read(&file, read_buffer, sizeof(read_buffer));
177 EXPECT_TRUE(read_result.has_value());
178 EXPECT_EQ(read_result.value(), write_len);
179 EXPECT_STREQ(read_buffer, write_data);
180}
181
182// 测试文件 seek
183TEST_F(RamFsTest, FileSeek) {
184 Inode* root = ramfs_.GetRootInode();
185 ASSERT_NE(root, nullptr);
186
187 // 创建文件并写入数据
188 auto create_result =
189 root->ops->Create(root, "seektest.txt", FileType::kRegular);
190 ASSERT_TRUE(create_result.has_value());
191
192 File file;
193 file.inode = create_result.value();
194 file.offset = 0;
195 file.ops = ramfs_.GetFileOps();
196
197 const char* data = "ABCDEFGHIJ";
198 (void)file.ops->Write(&file, data, strlen(data));
199
200 // SEEK_SET
201 auto seek_result = file.ops->Seek(&file, 5, SeekWhence::kSet);
202 EXPECT_TRUE(seek_result.has_value());
203 EXPECT_EQ(seek_result.value(), 5u);
204
205 // SEEK_CUR
206 seek_result = file.ops->Seek(&file, 2, SeekWhence::kCur);
207 EXPECT_TRUE(seek_result.has_value());
208 EXPECT_EQ(seek_result.value(), 7u);
209
210 // SEEK_END
211 seek_result = file.ops->Seek(&file, -3, SeekWhence::kEnd);
212 EXPECT_TRUE(seek_result.has_value());
213 EXPECT_EQ(seek_result.value(), strlen(data) - 3);
214}
215
216// 测试读取目录
217TEST_F(RamFsTest, ReadDirectory) {
218 Inode* root = ramfs_.GetRootInode();
219 ASSERT_NE(root, nullptr);
220
221 // 创建一些文件和目录
222 (void)root->ops->Create(root, "file1.txt", FileType::kRegular);
223 (void)root->ops->Create(root, "file2.txt", FileType::kRegular);
224 (void)root->ops->Mkdir(root, "dir1");
225
226 // 创建 File 对象用于 readdir
227 File dir_file;
228 dir_file.inode = root;
229 dir_file.offset = 0;
230 dir_file.ops = ramfs_.GetFileOps();
231
232 DirEntry entries[16];
233 auto readdir_result = dir_file.ops->ReadDir(&dir_file, entries, 16);
234 EXPECT_TRUE(readdir_result.has_value());
235
236 // 应该至少有 . 和 .. 加上我们创建的文件和目录
237 size_t count = readdir_result.value();
238 EXPECT_GE(count, 2u); // 至少包含 . 和 ..
239}
240
241// 测试重复创建文件
242TEST_F(RamFsTest, CreateDuplicateFile) {
243 Inode* root = ramfs_.GetRootInode();
244 ASSERT_NE(root, nullptr);
245
246 // 创建文件
247 auto create_result =
248 root->ops->Create(root, "duplicate.txt", FileType::kRegular);
249 EXPECT_TRUE(create_result.has_value());
250
251 // 重复创建应该失败
252 create_result = root->ops->Create(root, "duplicate.txt", FileType::kRegular);
253 EXPECT_FALSE(create_result.has_value());
254}
255
256// 测试删除非空目录
257TEST_F(RamFsTest, RmdirNonEmpty) {
258 Inode* root = ramfs_.GetRootInode();
259 ASSERT_NE(root, nullptr);
260
261 // 创建目录
262 auto mkdir_result = root->ops->Mkdir(root, "nonempty_dir");
263 ASSERT_TRUE(mkdir_result.has_value());
264
265 Inode* dir = mkdir_result.value();
266
267 // 在目录中创建文件
268 (void)dir->ops->Create(dir, "file_inside.txt", FileType::kRegular);
269
270 // 尝试删除非空目录应该失败
271 auto rmdir_result = root->ops->Rmdir(root, "nonempty_dir");
272 EXPECT_FALSE(rmdir_result.has_value());
273}
274
275// 测试删除不存在的文件
276TEST_F(RamFsTest, UnlinkNonExistent) {
277 Inode* root = ramfs_.GetRootInode();
278 ASSERT_NE(root, nullptr);
279
280 auto unlink_result = root->ops->Unlink(root, "nonexistent.txt");
281 EXPECT_FALSE(unlink_result.has_value());
282}
283
284// 测试 Sync(ramfs 应该立即返回成功)
286 auto sync_result = ramfs_.Sync();
287 EXPECT_TRUE(sync_result.has_value());
288}
void TearDown() override
RamFs ramfs_
void SetUp() override
test_env::TestEnvironmentState env_state_
ramfs 文件系统实现
Definition ramfs.hpp:16
auto Unmount() -> Expected< void > override
卸载 ramfs
Definition ramfs.cpp:77
auto Mount(vfs::BlockDevice *device) -> Expected< vfs::Inode * > override
挂载 ramfs
Definition ramfs.cpp:36
void ClearCurrentThreadEnvironment()
清除当前线程的环境实例指针
void BindThreadToCore(std::thread::id tid, size_t core_id)
将指定线程绑定到核心
void InitializeCores(size_t num_cores)
初始化指定数量的核心
void SetCurrentThreadEnvironment()
设置当前线程的环境实例指针
virtual auto Read(File *file, void *buf, size_t count) -> Expected< size_t >=0
从文件读取数据
virtual auto Seek(File *file, int64_t offset, SeekWhence whence) -> Expected< uint64_t >=0
调整文件偏移量
virtual auto ReadDir(File *file, DirEntry *dirent, size_t count) -> Expected< size_t >=0
读取目录项
virtual auto Write(File *file, const void *buf, size_t count) -> Expected< size_t >=0
向文件写入数据
virtual auto Unlink(Inode *dir, const char *name) -> Expected< void >=0
删除文件(解除链接)
virtual auto Create(Inode *dir, const char *name, FileType type) -> Expected< Inode * >=0
在目录中创建新文件
virtual auto Rmdir(Inode *dir, const char *name) -> Expected< void >=0
删除目录
virtual auto Mkdir(Inode *dir, const char *name) -> Expected< Inode * >=0
创建目录
virtual auto Lookup(Inode *dir, const char *name) -> Expected< Inode * >=0
在目录中查找指定名称的 inode
TEST_F(RamFsTest, MountUnmount)
#define strlen
目录项结构(用于 readdir)
File — 打开的文件实例(每次 open 产生一个)
Definition vfs.hpp:65
Inode * inode
关联的 inode
Definition vfs.hpp:67
uint64_t offset
当前读写偏移量
Definition vfs.hpp:71
FileOps * ops
文件操作接口
Definition vfs.hpp:76
Inode — 文件元数据(独立于路径名)
Definition vfs.hpp:16
FileType type
文件类型
Definition vfs.hpp:20
InodeOps * ops
文件操作接口
Definition vfs.hpp:33
#define EXPECT_TRUE(cond, msg)
#define EXPECT_NE(val1, val2, msg)
#define EXPECT_FALSE(cond, msg)
#define EXPECT_GE(val1, val2, msg)
#define EXPECT_EQ(val1, val2, msg)