-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_helpers.c
More file actions
178 lines (148 loc) · 5.88 KB
/
test_helpers.c
File metadata and controls
178 lines (148 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/**
* Unit test for mount point visibility helper functions
* Tests the is_direct_child_mount and get_basename functions
*/
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
// Copy the helper functions from dmvfs.c for testing
static bool is_direct_child_mount(const char* dir_path, const char* mount_path)
{
if (!dir_path || !mount_path) {
return false;
}
size_t dir_len = strlen(dir_path);
size_t mount_len = strlen(mount_path);
// Mount path must be longer than directory path
if (mount_len <= dir_len) {
return false;
}
// Check if mount_path starts with dir_path
if (strncmp(dir_path, mount_path, dir_len) != 0) {
return false;
}
// For root directory "/", check that mount path doesn't have more than one additional slash
if (dir_len == 1 && dir_path[0] == '/') {
// Find first slash after root
const char* next_slash = strchr(mount_path + 1, '/');
// It's a direct child if there's no slash after the first character
return (next_slash == NULL);
}
// For non-root directories, ensure the mount point is exactly one level deeper
// mount_path should be: dir_path + "/" + name (no additional slashes)
const char* remainder = mount_path + dir_len;
if (remainder[0] != '/') {
return false;
}
// Check that there are no more slashes after this point
const char* next_slash = strchr(remainder + 1, '/');
return (next_slash == NULL);
}
static void get_basename(const char* path, char* buffer, size_t buffer_size)
{
if (!path || !buffer || buffer_size == 0) {
return;
}
// Find the last slash
const char* last_slash = strrchr(path, '/');
if (!last_slash) {
// No slash found, use the entire path
strncpy(buffer, path, buffer_size - 1);
buffer[buffer_size - 1] = '\0';
return;
}
// If it's the root "/" itself
if (last_slash == path && last_slash[1] == '\0') {
buffer[0] = '\0';
return;
}
// Copy everything after the last slash
strncpy(buffer, last_slash + 1, buffer_size - 1);
buffer[buffer_size - 1] = '\0';
}
// Test framework
static int tests_passed = 0;
static int tests_failed = 0;
#define TEST_ASSERT(condition, test_name) \
do { \
if (condition) { \
printf("✓ PASS: %s\n", test_name); \
tests_passed++; \
} else { \
printf("✗ FAIL: %s\n", test_name); \
tests_failed++; \
} \
} while(0)
void test_is_direct_child_mount() {
printf("\n=== Testing is_direct_child_mount ===\n");
// Test root directory "/"
TEST_ASSERT(is_direct_child_mount("/", "/configs") == true,
"/ is parent of /configs");
TEST_ASSERT(is_direct_child_mount("/", "/mnt") == true,
"/ is parent of /mnt");
TEST_ASSERT(is_direct_child_mount("/", "/a") == true,
"/ is parent of /a");
// Test that nested paths are NOT direct children
TEST_ASSERT(is_direct_child_mount("/", "/configs/app") == false,
"/ is NOT direct parent of /configs/app");
TEST_ASSERT(is_direct_child_mount("/", "/a/b/c") == false,
"/ is NOT direct parent of /a/b/c");
// Test non-root directories
TEST_ASSERT(is_direct_child_mount("/configs", "/configs/app") == true,
"/configs is parent of /configs/app");
TEST_ASSERT(is_direct_child_mount("/mnt", "/mnt/sd") == true,
"/mnt is parent of /mnt/sd");
// Test that deeply nested paths are NOT direct children
TEST_ASSERT(is_direct_child_mount("/configs", "/configs/app/data") == false,
"/configs is NOT direct parent of /configs/app/data");
// Test edge cases
TEST_ASSERT(is_direct_child_mount("/", "/") == false,
"/ is NOT parent of itself");
TEST_ASSERT(is_direct_child_mount("/configs", "/configs") == false,
"/configs is NOT parent of itself");
TEST_ASSERT(is_direct_child_mount("/con", "/configs") == false,
"Partial match should not work");
TEST_ASSERT(is_direct_child_mount("/configs", "/mnt") == false,
"Unrelated paths should not match");
}
void test_get_basename() {
printf("\n=== Testing get_basename ===\n");
char buffer[256];
get_basename("/configs", buffer, sizeof(buffer));
TEST_ASSERT(strcmp(buffer, "configs") == 0,
"Basename of /configs is 'configs'");
get_basename("/mnt", buffer, sizeof(buffer));
TEST_ASSERT(strcmp(buffer, "mnt") == 0,
"Basename of /mnt is 'mnt'");
get_basename("/a/b/c", buffer, sizeof(buffer));
TEST_ASSERT(strcmp(buffer, "c") == 0,
"Basename of /a/b/c is 'c'");
get_basename("/", buffer, sizeof(buffer));
TEST_ASSERT(buffer[0] == '\0',
"Basename of / is empty string");
get_basename("/test.txt", buffer, sizeof(buffer));
TEST_ASSERT(strcmp(buffer, "test.txt") == 0,
"Basename of /test.txt is 'test.txt'");
}
int main(void) {
printf("========================================\n");
printf(" Mount Point Helper Functions Test\n");
printf("========================================\n");
test_is_direct_child_mount();
test_get_basename();
printf("\n========================================\n");
printf(" Test Summary\n");
printf("========================================\n");
printf("Total tests: %d\n", tests_passed + tests_failed);
printf("Passed: %d\n", tests_passed);
printf("Failed: %d\n", tests_failed);
printf("========================================\n");
if (tests_failed == 0) {
printf("\n✓ ALL TESTS PASSED\n\n");
return 0;
} else {
printf("\n✗ SOME TESTS FAILED\n\n");
return 1;
}
}