1 /*
2 * Copyright (c) 2018 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdio.h>
8 #include <fcntl.h>
9 #include <zephyr/posix/unistd.h>
10 #include <zephyr/posix/dirent.h>
11 #include "test_fs.h"
12
13 extern int test_file_write(void);
14 extern int test_file_close(void);
15 extern int file;
16
test_mkdir(void)17 static int test_mkdir(void)
18 {
19 int res;
20
21 TC_PRINT("\nmkdir tests:\n");
22
23 /* Verify fs_mkdir() */
24 res = mkdir(TEST_DIR, S_IRWXG);
25 if (res) {
26 TC_PRINT("Error creating dir[%d]\n", res);
27 return res;
28 }
29
30 res = open(TEST_DIR_FILE, O_CREAT | O_RDWR, 0770);
31
32 if (res < 0) {
33 TC_PRINT("Failed opening file [%d]\n", res);
34 return res;
35 }
36 file = res;
37
38 res = test_file_write();
39 if (res) {
40 return res;
41 }
42
43 res = close(file);
44 if (res) {
45 TC_PRINT("Error closing file [%d]\n", res);
46 return res;
47 }
48
49 TC_PRINT("Created dir %s!\n", TEST_DIR);
50
51 return res;
52 }
53
readdir_wrap(DIR * dirp,bool thread_safe)54 static struct dirent *readdir_wrap(DIR *dirp, bool thread_safe)
55 {
56 if (thread_safe) {
57 /* cannot declare on stack otherwise this test fails for qemu_x86/atom */
58 static struct dirent entry;
59 struct dirent *result = NULL;
60
61 zassert_ok(readdir_r(dirp, &entry, &result));
62
63 return result;
64 } else {
65 return readdir(dirp);
66 }
67 }
68
test_lsdir(const char * path,bool thread_safe)69 static int test_lsdir(const char *path, bool thread_safe)
70 {
71 DIR *dirp;
72 int res = 0;
73 struct dirent *entry;
74
75 TC_PRINT("\nreaddir test:\n");
76
77 /* Verify fs_opendir() */
78 dirp = opendir(path);
79 if (dirp == NULL) {
80 TC_PRINT("Error opening dir %s\n", path);
81 return -EIO;
82 }
83
84 TC_PRINT("\nListing dir %s:\n", path);
85 /* Verify fs_readdir() */
86 errno = 0;
87 while ((entry = readdir_wrap(dirp, thread_safe)) != NULL) {
88 if (entry->d_name[0] == 0) {
89 res = -EIO;
90 break;
91 }
92
93 TC_PRINT("[FILE] %s\n", entry->d_name);
94 }
95
96 if (errno) {
97 res = -EIO;
98 }
99
100 /* Verify fs_closedir() */
101 closedir(dirp);
102
103 return res;
104 }
105
after_fn(void * unused)106 static void after_fn(void *unused)
107 {
108 ARG_UNUSED(unused);
109
110 unlink(TEST_DIR_FILE);
111 unlink(TEST_DIR);
112 }
113
114 /* FIXME: restructure tests as per #46897 */
115 ZTEST_SUITE(posix_fs_dir_test, NULL, test_mount, NULL, after_fn,
116 test_unmount);
117
118 /**
119 * @brief Test for POSIX mkdir API
120 *
121 * @details Test creates a new directory through POSIX
122 * mkdir API and open a new file under the directory and
123 * writes some data into the file.
124 */
ZTEST(posix_fs_dir_test,test_fs_mkdir)125 ZTEST(posix_fs_dir_test, test_fs_mkdir)
126 {
127 /* FIXME: restructure tests as per #46897 */
128 zassert_true(test_mkdir() == TC_PASS);
129 }
130
131 /**
132 * @brief Test for POSIX opendir, readdir and closedir API
133 *
134 * @details Test opens an existing directory through POSIX
135 * opendir API, reads the contents of the directory through
136 * readdir API and closes it through closedir API.
137 */
ZTEST(posix_fs_dir_test,test_fs_readdir)138 ZTEST(posix_fs_dir_test, test_fs_readdir)
139 {
140 /* FIXME: restructure tests as per #46897 */
141 zassert_true(test_mkdir() == TC_PASS);
142 zassert_true(test_lsdir(TEST_DIR, false) == TC_PASS);
143 }
144
145 /**
146 * Same test as `test_fs_readdir`, but use thread-safe `readdir_r()` function
147 */
ZTEST(posix_fs_dir_test,test_fs_readdir_threadsafe)148 ZTEST(posix_fs_dir_test, test_fs_readdir_threadsafe)
149 {
150 /* FIXME: restructure tests as per #46897 */
151 zassert_true(test_mkdir() == TC_PASS);
152 zassert_true(test_lsdir(TEST_DIR, true) == TC_PASS);
153 }
154
155 /**
156 * @brief Test for POSIX rmdir API
157 *
158 * @details Test creates a new directory through POSIX
159 * mkdir API and remove directory using rmdir.
160 */
ZTEST(posix_fs_dir_test,test_fs_rmdir)161 ZTEST(posix_fs_dir_test, test_fs_rmdir)
162 {
163 #define IRWXG 0070
164 /* Create and remove empty directory */
165 zassert_ok(mkdir(TEST_DIR, IRWXG), "Error creating dir: %d", errno);
166 zassert_ok(rmdir(TEST_DIR), "Error removing dir: %d\n", errno);
167
168 /* Create directory and open a file in the directory
169 * now removing the directory will fail, test will
170 * fail in removal of non empty directory
171 */
172 zassert_ok(mkdir(TEST_DIR, IRWXG), "Error creating dir: %d", errno);
173 zassert_not_equal(open(TEST_DIR_FILE, O_CREAT | O_RDWR), -1,
174 "Error creating file: %d", errno);
175 zassert_not_ok(rmdir(TEST_DIR), "Error Non empty dir removed");
176 zassert_not_ok(rmdir(""), "Error Invalid path removed");
177 zassert_not_ok(rmdir(NULL), "Error Invalid path removed");
178 zassert_not_ok(rmdir("TEST_DIR."), "Error Invalid path removed");
179 zassert_not_ok(rmdir(TEST_FILE), "Error file removed");
180 }
181