2 #include "../../src/fs.h"
3 #include "../../src/names.h"
4 #include "../../src/xalloc.h"
8 #define FAKE_PATH "nonexistentreallyfakepath"
15 static void test_absolute_path_on_absolute_returns_it(void **state) {
18 const char *paths[] = {"/", "/foo", "/foo/./../bar"};
20 for(size_t i = 0; i < sizeof(paths) / sizeof(*paths); ++i) {
21 char *got = absolute_path(paths[i]);
22 assert_ptr_not_equal(paths[i], got);
23 assert_string_equal(paths[i], got);
28 static void test_absolute_path_on_empty_returns_null(void **state) {
30 assert_null(absolute_path(NULL));
31 assert_null(absolute_path("\0"));
34 static void test_absolute_path_relative(void **state) {
37 testcase_t cases[] = {
40 {"./"FAKE_PATH, "/./"FAKE_PATH},
41 {"../foo/./../"FAKE_PATH, "/../foo/./../"FAKE_PATH},
44 for(size_t i = 0; i < sizeof(cases) / sizeof(*cases); ++i) {
45 char *got = absolute_path(cases[i].arg);
46 assert_string_equal(cases[i].want, got);
51 static int setup_path_unix(void **state) {
53 assert_int_equal(0, chdir("/"));
57 const char tmp_template[] = "/tmp/tinc.test.fs.XXXXXX";
58 char tmp[sizeof(tmp_template)];
60 static int setup_temp_dir(void **state) {
62 strcpy(tmp, tmp_template);
63 assert_ptr_equal(tmp, mkdtemp(tmp));
64 confdir = xstrdup(tmp);
65 xasprintf(&confbase, "%s/conf", tmp);
69 static int teardown_temp_dir(void **state) {
76 static void test_makedir(tinc_dir_t dir, bool exists) {
78 char container[PATH_MAX] = {0};
86 sprintf(path, "%s/conf", tmp);
87 strcpy(container, tmp);
91 sprintf(path, "%s/conf/cache", tmp);
92 sprintf(container, "%s/conf", tmp);
96 sprintf(path, "%s/conf/hosts", tmp);
97 sprintf(container, "%s/conf", tmp);
100 case DIR_INVITATIONS:
101 sprintf(path, "%s/conf/invitations", tmp);
102 sprintf(container, "%s/conf", tmp);
109 assert_int_equal(0, stat(path, &st));
111 assert_int_equal(-1, stat(path, &st));
112 assert_int_equal(ENOENT, errno);
115 // Deny write access and make sure makedirs() detects that
117 assert_int_equal(0, chmod(tmp, 0));
118 assert_false(makedirs(dir));
119 assert_int_equal(0, chmod(tmp, 0755));
122 // Now test the happy path
123 assert_true(makedirs(dir));
124 assert_int_equal(0, stat(path, &st));
125 assert_true(S_ISDIR(st.st_mode));
126 assert_int_equal(0, access(path, R_OK | W_OK));
128 // Make sure no other directories were created
130 DIR *d = opendir(container);
135 while((ent = readdir(d))) {
136 if(strcmp(".", ent->d_name) && strcmp("..", ent->d_name)) {
137 assert_int_equal(st.st_ino, ent->d_ino);
138 assert_true(ent->d_type & DT_DIR);
146 static void test_makedirs_cache(void **state) {
148 test_makedir(DIR_CACHE, false);
151 static void test_makedirs_confbase(void **state) {
153 test_makedir(DIR_CONFBASE, false);
156 static void test_makedirs_confdir(void **state) {
158 test_makedir(DIR_CONFDIR, true);
161 static void test_makedirs_hosts(void **state) {
163 test_makedir(DIR_HOSTS, false);
166 static void test_makedirs_invitations(void **state) {
168 test_makedir(DIR_INVITATIONS, false);
171 static int setup_umask(void **state) {
177 static void test_fopenmask_existing(void **state) {
181 strcpy(tmp, tmp_template);
183 int fd = mkstemp(tmp);
184 assert_int_not_equal(-1, fd);
187 assert_int_equal(0, chmod(tmp, 0755));
188 assert_int_equal(0, stat(tmp, &st));
189 assert_int_equal(0755, st.st_mode & 0777);
191 FILE *f = fopenmask(tmp, "r", 0700);
195 assert_int_equal(0, stat(tmp, &st));
196 assert_int_equal(0700, st.st_mode & 0777);
199 static void test_fopenmask_new(void **state) {
203 strcpy(tmp, tmp_template);
205 // mktemp() nags about safety and using better alternatives
206 int fd = mkstemp(tmp);
207 assert_int_not_equal(-1, fd);
211 FILE *f = fopenmask(tmp, "w", 0750);
215 assert_int_equal(0, stat(tmp, &st));
216 assert_int_equal(0750, st.st_mode & 0777);
219 #endif // HAVE_WINDOWS
221 static void test_makedirs_bad(void **state) {
224 assert_false(makedirs(0));
226 confbase = NULL; // free not needed, just make it obvious that confbase is NULL
227 assert_false(makedirs(DIR_CACHE));
228 assert_false(makedirs(DIR_CONFBASE));
229 assert_false(makedirs(DIR_HOSTS));
230 assert_false(makedirs(DIR_INVITATIONS));
232 confdir = NULL; // same
233 assert_false(makedirs(DIR_CONFDIR));
237 const struct CMUnitTest tests[] = {
239 cmocka_unit_test_setup(test_absolute_path_on_absolute_returns_it, setup_path_unix),
240 cmocka_unit_test_setup(test_absolute_path_on_empty_returns_null, setup_path_unix),
241 cmocka_unit_test_setup(test_absolute_path_relative, setup_path_unix),
242 cmocka_unit_test_setup_teardown(test_makedirs_cache, setup_temp_dir, teardown_temp_dir),
243 cmocka_unit_test_setup_teardown(test_makedirs_confbase, setup_temp_dir, teardown_temp_dir),
244 cmocka_unit_test_setup_teardown(test_makedirs_confdir, setup_temp_dir, teardown_temp_dir),
245 cmocka_unit_test_setup_teardown(test_makedirs_hosts, setup_temp_dir, teardown_temp_dir),
246 cmocka_unit_test_setup_teardown(test_makedirs_invitations, setup_temp_dir, teardown_temp_dir),
247 cmocka_unit_test_setup(test_fopenmask_existing, setup_umask),
248 cmocka_unit_test_setup(test_fopenmask_new, setup_umask),
250 cmocka_unit_test(test_makedirs_bad),
252 return cmocka_run_group_tests(tests, NULL, NULL);