1#ifdef TEST_TMPFS
2
3#include <fs/tmpfs.h>
4#include <fs/vfs.h>
5#include <mem/alloc.h>
6#include <test.h>
7
8#include "errno.h"
9#include "string.h"
10
11#define TMPFS_SETUP_NODE(root, node, name, e) \
12 struct vfs_node *root = tmpfs_mkroot("tmp"); \
13 TEST_ASSERT(root != NULL); \
14 FAIL_IF_FATAL(root->ops->create(root, name, VFS_MODE_FILE)); \
15 struct vfs_dirent ent; \
16 struct vfs_node *node; \
17 FAIL_IF_FATAL(root->ops->finddir(root, name, &ent)); \
18 node = ent.node; \
19 TEST_ASSERT(node != NULL);
20
21TEST_DECLARE(tmpfs_rw_test, .tier = TEST_TIER_INTEGRATION) {
22 TMPFS_SETUP_NODE(root, node, "place", e);
23 TEST_ASSERT(node->size == 0);
24
25 const char *lstr = large_test_string;
26 uint64_t len = strlen(str: lstr);
27
28 FAIL_IF_FATAL(node->ops->write(node, lstr, len, 0));
29
30 TEST_ASSERT(node->size == len);
31
32 char *out_buf = kmalloc(len + 1, ALLOC_FLAGS_ZERO);
33 TEST_ASSERT(out_buf != NULL);
34
35 FAIL_IF_FATAL(node->ops->read(node, out_buf, len, 0));
36
37 TEST_ASSERT(memcmp(out_buf, lstr, len) == 0);
38
39 FAIL_IF_FATAL(node->ops->truncate(node, len / 2));
40 TEST_ASSERT(node->size == len / 2);
41
42 memset(out_buf, 0, len);
43
44 FAIL_IF_FATAL(node->ops->read(node, out_buf, len, 0));
45 FAIL_IF_FATAL(node->ops->unlink(root, "place"));
46
47 enum errno e = root->ops->finddir(root, "place", &ent);
48 TEST_ASSERT(e == ERR_NO_ENT);
49
50 TEST_ASSERT(strlen(out_buf) == len / 2);
51 return TEST_SUCCESS;
52}
53
54TEST_DECLARE(tmpfs_dir_test, .tier = TEST_TIER_INTEGRATION) {
55 struct vfs_node *root = tmpfs_mkroot(mount_point: "tmp");
56 const char *lstr = large_test_string;
57 uint64_t len = strlen(str: lstr);
58
59 char *out_buf = kmalloc(len + 1, ALLOC_FLAGS_ZERO);
60 TEST_ASSERT(out_buf != NULL);
61
62 FAIL_IF_FATAL(root->ops->mkdir(root, "place", VFS_MODE_DIR));
63
64 struct vfs_dirent ent;
65 struct vfs_node *dir;
66
67 FAIL_IF_FATAL(root->ops->finddir(root, "place", &ent));
68
69 dir = ent.node;
70 TEST_ASSERT(dir != NULL);
71
72 enum errno e = dir->ops->write(dir, lstr, len, 0);
73 TEST_ASSERT(e == ERR_IS_DIR);
74
75 e = dir->ops->read(dir, out_buf, len, 0);
76 TEST_ASSERT(e == ERR_IS_DIR);
77
78 FAIL_IF_FATAL(dir->ops->rmdir(root, "place"));
79
80 e = root->ops->finddir(root, "place", &ent);
81 TEST_ASSERT(e == ERR_NO_ENT);
82
83 return TEST_SUCCESS;
84}
85
86TEST_DECLARE(tmpfs_general_tests, .tier = TEST_TIER_INTEGRATION) {
87 TMPFS_SETUP_NODE(root, node, "place", e);
88
89 FAIL_IF_FATAL(node->ops->chmod(node, VFS_MODE_EXEC));
90
91 TEST_ASSERT(node->mode == VFS_MODE_EXEC);
92
93 FAIL_IF_FATAL(node->ops->chown(node, 42, 37));
94
95 TEST_ASSERT(node->uid == 42 && node->gid == 37);
96
97 FAIL_IF_FATAL(root->ops->mkdir(root, "bingbong", VFS_MODE_DIR));
98 FAIL_IF_FATAL(root->ops->finddir(root, "bingbong", &ent));
99
100 node = ent.node;
101 TEST_ASSERT(node != NULL);
102
103 FAIL_IF_FATAL(node->ops->symlink(node, "/tmp", "bang"));
104
105 struct vfs_node *bang;
106 FAIL_IF_FATAL(node->ops->finddir(node, "bang", &ent));
107
108 bang = ent.node;
109 TEST_ASSERT(bang != NULL);
110
111 char *buf = kmalloc(10, ALLOC_FLAGS_ZERO);
112 TEST_ASSERT(bang != NULL);
113
114 FAIL_IF_FATAL(bang->ops->readlink(bang, buf, 10));
115
116 TEST_ASSERT(strcmp(buf, "/tmp") == 0);
117
118 return TEST_SUCCESS;
119}
120
121#endif
122