1#ifdef TEST_EXT2
2
3#include <block/sched.h>
4#include <fs/ext2.h>
5#include <fs/vfs.h>
6#include <mem/alloc.h>
7#include <stdint.h>
8#include <string.h>
9#include <test.h>
10#include <time/spin_sleep.h>
11
12#define EXT2_INIT \
13 if (global.root_node->fs_type != FS_EXT2) { \
14 test_info("the mounted root is not ext2"); \
15 return TEST_SKIP(TEST_SKIP_NONE); \
16 } \
17 struct vfs_node *root = global.root_node;
18
19/*
20static void check_bcache(void) {
21 struct ext2_fs *fs = g_root_node->fs_data;
22 struct generic_disk *d = fs->drive;
23
24 uint64_t bcache_total_dirty = 42;
25 uint64_t bcache_total_present = 37;
26
27 bcache_stat(d, &bcache_total_dirty, &bcache_total_present);
28
29 char *msg = kmalloc(100);
30 snprintf(msg, 100, "Block cache has %d dirty entries and %d total entries",
31 bcache_total_dirty, bcache_total_present);
32
33 test_info(msg);
34
35 TEST_ASSERT(bcache_total_dirty == 0);
36}*/
37
38static void flush() {
39 struct ext2_fs *fs = global.root_node->fs_data;
40 struct block_device *d = fs->drive;
41
42 bio_sched_dispatch_all(disk: d);
43
44 /*
45 sleep_ms(500);
46 check_bcache();*/
47}
48
49TEST_DECLARE(ext2_stat_test, .tier = TEST_TIER_UNIT) {
50 EXT2_INIT;
51
52 FAIL_IF_FATAL(root->ops->create(root, "ext2_stat_test", VFS_MODE_FILE));
53
54 struct vfs_node *node;
55 struct vfs_dirent out;
56
57 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_stat_test", &out));
58
59 node = out.node;
60 TEST_ASSERT(node != NULL);
61
62 struct vfs_stat empty_stat = {0};
63 struct vfs_stat stat_out = {0};
64 node->ops->stat(node, &stat_out);
65
66 /* this should return something */
67 TEST_ASSERT(memcmp(&stat_out, &empty_stat, sizeof(struct vfs_stat)) != 0);
68
69 flush();
70 return TEST_SUCCESS;
71}
72
73TEST_DECLARE(ext2_rename_test, .tier = TEST_TIER_UNIT) {
74 EXT2_INIT;
75
76 FAIL_IF_FATAL(root->ops->create(root, "ext2_rename_test", VFS_MODE_FILE));
77
78 struct vfs_dirent out;
79 struct vfs_node *node;
80
81 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_rename_test", &out));
82
83 node = out.node;
84 TEST_ASSERT(node != NULL);
85
86 FAIL_IF_FATAL(
87 node->ops->rename(root, "ext2_rename_test", root, "ext2_rename_test2"));
88
89 enum errno e = root->ops->finddir(root, "ext2_rename_test", &out);
90 TEST_ASSERT(e == ERR_NO_ENT);
91
92 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_rename_test2", &out));
93
94 node = out.node;
95 TEST_ASSERT(node != NULL);
96
97 flush();
98 return TEST_SUCCESS;
99}
100
101TEST_DECLARE(ext2_chmod_test, .tier = TEST_TIER_UNIT) {
102 EXT2_INIT;
103
104 FAIL_IF_FATAL(root->ops->create(root, "ext2_chmod_test", VFS_MODE_FILE));
105
106 struct vfs_node *node;
107 struct vfs_dirent ent;
108
109 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_chmod_test", &ent));
110
111 node = ent.node;
112 TEST_ASSERT(node != NULL);
113
114 FAIL_IF_FATAL(root->ops->chmod(node, (uint16_t) VFS_MODE_O_EXEC));
115 TEST_ASSERT(node->mode & VFS_MODE_O_EXEC);
116
117 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_chmod_test", &ent));
118
119 node = ent.node;
120 TEST_ASSERT(node != NULL);
121 TEST_ASSERT(node->mode & VFS_MODE_O_EXEC);
122
123 flush();
124 return TEST_SUCCESS;
125}
126
127TEST_DECLARE(ext2_symlink_test, .tier = TEST_TIER_UNIT) {
128 EXT2_INIT;
129
130 FAIL_IF_FATAL(root->ops->symlink(root, "/tmp", "ext2_symlink_test"));
131
132 struct vfs_dirent ent;
133 struct vfs_node *node;
134
135 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_symlink_test", &ent));
136
137 node = ent.node;
138 TEST_ASSERT(node != NULL);
139
140 char *buf = kmalloc(5, ALLOC_FLAGS_ZERO);
141 TEST_ASSERT(buf != NULL);
142
143 FAIL_IF_FATAL(node->ops->readlink(node, buf, 4));
144
145 TEST_ASSERT(strcmp(buf, "/tmp") == 0);
146
147 flush();
148 return TEST_SUCCESS;
149}
150
151TEST_DECLARE(ext2_dir_test, .tier = TEST_TIER_UNIT) {
152 EXT2_INIT;
153
154 FAIL_IF_FATAL(root->ops->mkdir(root, "ext2_dir_test", VFS_MODE_DIR));
155
156 struct vfs_dirent ent;
157 struct vfs_node *node;
158
159 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_dir_test", &ent));
160
161 node = ent.node;
162 TEST_ASSERT(node != NULL);
163
164 FAIL_IF_FATAL(root->ops->rmdir(root, "ext2_dir_test"));
165
166 flush();
167 return TEST_SUCCESS;
168}
169
170TEST_DECLARE(ext2_integration_test, .tier = TEST_TIER_INTEGRATION) {
171 EXT2_INIT;
172
173 FAIL_IF_FATAL(
174 root->ops->create(root, "ext2_integration_test", VFS_MODE_FILE));
175
176 struct vfs_dirent ent;
177 struct vfs_node *node;
178 FAIL_IF_FATAL(root->ops->finddir(root, "ext2_integration_test", &ent));
179
180 node = ent.node;
181 TEST_ASSERT(node != NULL);
182
183 const char *lstr = large_test_string;
184 uint64_t len = strlen(str: lstr);
185
186 FAIL_IF_FATAL(node->ops->write(node, lstr, len, 0));
187 TEST_ASSERT(node->size == len);
188
189 char *out_buf = kmalloc(len, ALLOC_FLAGS_ZERO);
190 TEST_ASSERT(out_buf != NULL);
191
192 FAIL_IF_FATAL(node->ops->read(node, out_buf, len, 0));
193
194 TEST_ASSERT(memcmp(out_buf, lstr, len) == 0);
195
196 FAIL_IF_FATAL(node->ops->truncate(node, len / 2));
197
198 memset(out_buf, 0, len);
199
200 FAIL_IF_FATAL(node->ops->read(node, out_buf, len, 0));
201
202 TEST_ASSERT(strlen(out_buf) == len / 2);
203
204 FAIL_IF_FATAL(node->ops->unlink(root, "ext2_integration_test"));
205
206 enum errno e = root->ops->finddir(root, "ext2_integration_test", &ent);
207 TEST_ASSERT(e == ERR_NO_ENT);
208
209 flush();
210
211 return TEST_SUCCESS;
212}
213
214#endif
215