1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "FileSystemTest.h"
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/statvfs.h>
23 #include <sys/statfs.h>
24 #include <sys/mount.h>
25 #include <wchar.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <dirent.h>
29 #include <ftw.h>
30 #include <libgen.h>
31 #include <glob.h>
32
33 #include <gtest/gtest.h>
34
35 #include "utils.h"
36 #include "log.h"
37 #include "KernelConstants.h"
38 #include "libfs.h"
39
40 using namespace testing::ext;
41
42 /**
43 * @tc.number SUB_KERNEL_FS_OTHER_0100
44 * @tc.name basic function test : get dirname
45 * @tc.desc [C- SOFTWARE -0200]
46 */
47 HWTEST_F(FileSystemTest, testPath, Function | MediumTest | Level1)
48 {
49 int fd = 0;
50 fd = creat(FILE0, 0777);
51 EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
52 EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
53
54 // get dir
55 char *workDir = dirname((char*)FILE0);
56 ASSERT_NE(workDir, nullptr) << "> dirname errno = " << errno;
57 EXPECT_STREQ(".", workDir);
58 LOG("> workDir = %s", workDir);
59 }
60
61 /**
62 * @tc.number SUB_KERNEL_FS_OTHER_0110
63 * @tc.name basic function test : get current dir name
64 * @tc.desc [C- SOFTWARE -0200]
65 */
66 HWTEST_F(FileSystemTest, testGetCurrentDirName, Function | MediumTest | Level1)
67 {
68 int fd = 0;
69 fd = creat(FILE0, 0777);
70 EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
71 EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
72
73 // get current dir name
74 const char *currentDirStandard = TOP_DIR;
75 char *currentDir = get_current_dir_name();
76 ASSERT_NE(currentDir, nullptr);
77 EXPECT_STREQ(currentDir, currentDirStandard);
78 LOG("> currentDir = %s", currentDir);
79 }
80
81 /**
82 * @tc.number SUB_KERNEL_FS_OTHER_0120
83 * @tc.name basic function test : get basename
84 * @tc.desc [C- SOFTWARE -0200]
85 */
86 HWTEST_F(FileSystemTest, testBasename, Function | MediumTest | Level1)
87 {
88 int fd = 0;
89 fd = creat(FILE0, 0777);
90 EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
91 EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
92
93 // get file name
94 char *desName = basename((char*)FILE0);
95 ASSERT_NE(desName, nullptr) << "> basename errno = " << errno;
96 EXPECT_STREQ(desName, FILE0);
97 LOG("> desName = %s", desName);
98 }
99
FtwCheckDirTree(const char * path,const struct stat * sb,int flag)100 int FtwCheckDirTree(const char *path, const struct stat *sb, int flag)
101 {
102 const char file0[] = DIR0 "/" DIR0_FILE0;
103 const char file1[] = DIR0 "/" DIR0_DIR1 "/" DIR0_DIR1_FILE0;
104 const char dir0[] = DIR0;
105 const char dir1[] = DIR0 "/" DIR0_DIR0;
106 const char dir2[] = DIR0 "/" DIR0_DIR1;
107 const char dir3[] = DIR0 "/" DIR0_DIR1"/" DIR0_DIR1_DIR0;
108 if (flag == FTW_F) {
109 if (strncmp(path, file0, sizeof(file0)) == 0) {
110 LOG("> File %s", file0);
111 } else if (strncmp(path, file1, sizeof(file1)) == 0) {
112 LOG("> File %s", file1);
113 } else {
114 LOG("> File error %s", path);
115 return -1;
116 }
117 } else if (flag == FTW_D) {
118 if (strncmp(path, dir0, sizeof(dir0)) == 0) {
119 LOG("> Dir %s", DIR0);
120 } else if (strncmp(path, dir1, sizeof(dir1)) == 0) {
121 LOG("> Dir %s", dir1);
122 } else if (strncmp(path, dir2, sizeof(dir2)) == 0) {
123 LOG("> Dir %s", dir2);
124 } else if (strncmp(path, dir3, sizeof(dir3)) == 0) {
125 LOG("> Dir %s", dir3);
126 } else {
127 LOG("> File error %s", path);
128 return -1;
129 }
130 }
131 return 0;
132 }
133
134 /**
135 * @tc.number SUB_KERNEL_FS_OTHER_0200
136 * @tc.name basic function test : use ftw check file tree
137 * @tc.desc [C- SOFTWARE -0200]
138 */
139 HWTEST_F(FileSystemTest, testFtw, Function | MediumTest | Level3)
140 {
141 CreateTestFolder();
142 EXPECT_EQ(ftw(DIR0, FtwCheckDirTree, 100), 0) << "> ftw error";
143 }
144
NftwCheckDirTree(const char * path,const struct stat * sb,int flag,struct FTW * s)145 int NftwCheckDirTree(const char *path, const struct stat *sb, int flag, struct FTW *s)
146 {
147 const char file0[] = DIR0 "/" DIR0_FILE0;
148 const char file1[] = DIR0 "/" DIR0_DIR1 "/" DIR0_DIR1_FILE0;
149 const char dir0[] = DIR0;
150 const char dir1[] = DIR0 "/" DIR0_DIR0;
151 const char dir2[] = DIR0 "/" DIR0_DIR1;
152 const char dir3[] = DIR0 "/" DIR0_DIR1"/" DIR0_DIR1_DIR0;
153 if (flag == FTW_F) {
154 if (strncmp(path, file0, sizeof(file0)) == 0) {
155 LOG("> File %s", file0);
156 } else if (strncmp(path, file1, sizeof(file1)) == 0) {
157 LOG("> File %s", file1);
158 } else {
159 LOG("> File %s", path);
160 return -1;
161 }
162 } else if (flag == FTW_D) {
163 if (strncmp(path, dir0, sizeof(dir0)) == 0) {
164 LOG("> Dir %s", DIR0);
165 } else if (strncmp(path, dir1, sizeof(dir1)) == 0) {
166 LOG("> Dir %s", dir1);
167 } else if (strncmp(path, dir2, sizeof(dir2)) == 0) {
168 LOG("> Dir %s", dir2);
169 } else if (strncmp(path, dir3, sizeof(dir3)) == 0) {
170 LOG("> Dir %s", dir3);
171 } else {
172 LOG("> File %s", path);
173 return -1;
174 }
175 }
176 return 0;
177 }
178
179 /**
180 * @tc.number SUB_KERNEL_FS_OTHER_0210
181 * @tc.name basic function test : use nftw check file tree
182 * @tc.desc [C- SOFTWARE -0200]
183 */
184 HWTEST_F(FileSystemTest, testNftw, Function | MediumTest | Level3)
185 {
186 CreateTestFolder();
187 EXPECT_EQ(nftw(DIR0, NftwCheckDirTree, 100, 0), 0) << "> ftw error";
188 }
189
190 /**
191 * @tc.number SUB_KERNEL_FS_OTHER_0300
192 * @tc.name basic function test : use statvfs and statfs check file system information.
193 * @tc.desc [C- SOFTWARE -0200]
194 */
195 HWTEST_F(FileSystemTest, testStatvfs, Function | MediumTest | Level2)
196 {
197 struct statvfs vfsBuf = {0};
198 struct statfs fsBuf = {0};
199
200 statvfs(".", &vfsBuf);
201 LOG("vfsBuf.f_bsize = %lu", vfsBuf.f_bsize); // File system block size.
202 LOG("vfsBuf.f_frsize = %lu", vfsBuf.f_frsize); // Fundamental file system block size.
203 LOG("vfsBuf.f_blocks = %lu", vfsBuf.f_blocks); // Total number of blocks on file system in units of f_frsize.
204 LOG("vfsBuf.f_bfree = %lu", vfsBuf.f_bfree); // Total number of free blocks.
205 LOG("vfsBuf.f_bavail = %lu", vfsBuf.f_bavail); // Number of free blocks available to non-privileged process.
206 LOG("vfsBuf.f_files = %lu", vfsBuf.f_files); // Total number of file serial numbers.
207 LOG("vfsBuf.f_ffree = %lu", vfsBuf.f_ffree); // Total number of free file serial numbers.
208 LOG("vfsBuf.f_favail = %lu", vfsBuf.f_favail); // Number of i-nodes available to unprivileged process.
209 LOG("vfsBuf.f_fsid = %lu", vfsBuf.f_fsid); // File system ID.
210 LOG("vfsBuf.f_flag = %lu", vfsBuf.f_flag); // Bit mask of f_flag values.
211 LOG("vfsBuf.f_namemax = %lu", vfsBuf.f_namemax); // Maximum filename length.
212
213 statfs(".", &fsBuf);
214 LOG("fsBuf.f_type = %lu", fsBuf.f_type); // Type of filesystem.
215 LOG("fsBuf.f_bsize = %lu", fsBuf.f_bsize); // Optimal transfer block size.
216 LOG("fsBuf.f_blocks = %lu", fsBuf.f_blocks); // Total data blocks in filesystem.
217 LOG("fsBuf.f_bfree = %lu", fsBuf.f_bfree); // Total data blocks in filesystem.
218 LOG("fsBuf.f_bavail = %lu", fsBuf.f_bavail); // Free blocks available to unprivileged user.
219 LOG("fsBuf.f_files = %lu", fsBuf.f_files); // Total file nodes in filesystem.
220 LOG("fsBuf.f_ffree = %lu", fsBuf.f_ffree); // Free file nodes in filesystem.
221 LOG("fsBuf.f_fsid.__val[0] = %d", fsBuf.f_fsid.__val[0]); // Filesystem ID.
222 LOG("fsBuf.f_fsid.__val[1] = %d", fsBuf.f_fsid.__val[1]); // Filesystem ID.
223 LOG("fsBuf.f_namelen = %ld", fsBuf.f_namelen); // Maximum length of filenames.
224
225 EXPECT_EQ(vfsBuf.f_bsize, fsBuf.f_bsize);
226 EXPECT_EQ(vfsBuf.f_blocks, fsBuf.f_blocks);
227 EXPECT_EQ(vfsBuf.f_files, fsBuf.f_files);
228 EXPECT_EQ(vfsBuf.f_ffree, fsBuf.f_ffree);
229 EXPECT_EQ(vfsBuf.f_namemax, fsBuf.f_namelen);
230 }
231
232 /**
233 * @tc.number SUB_KERNEL_FS_OTHER_0400
234 * @tc.name basic function test : Use glob function and globfree function for path generation and release
235 * @tc.desc [C- SOFTWARE -0200]
236 */
237 HWTEST_F(FileSystemTest, testGlob, Function | MediumTest | Level3)
238 {
239 glob_t buf;
240 CreateTestFolder();
241 EXPECT_EQ(glob(TOP_DIR "/" DIR0 "/*", GLOB_ERR, NULL, &buf), 0) << "> glod errno = " << errno;
242 if (buf.gl_pathc == 3) {
243 EXPECT_STREQ(buf.gl_pathv[0], TOP_DIR "/" DIR0 "/" DIR0_DIR0);
244 EXPECT_STREQ(buf.gl_pathv[1], TOP_DIR "/" DIR0 "/" DIR0_DIR1);
245 EXPECT_STREQ(buf.gl_pathv[2], TOP_DIR "/" DIR0 "/" DIR0_FILE0);
246 } else {
247 ADD_FAILURE();
248 }
249 globfree(&buf);
250 }
251 #if 0
252 /**
253 * @tc.number SUB_KERNEL_FS_OTHER_0500
254 * @tc.name basic function test : Use fwprintf function to write wide characters
255 * @tc.desc [C- SOFTWARE -0200]
256 */
257 HWTEST_F(FileSystemTest, testFwprintf, Function | MediumTest | Level3)
258 {
259 const char filePath[] = TOP_DIR "/" DIR0 "/" DIR0_FILE0;
260 FILE *fp = nullptr;
261 wchar_t writeBuf[30] = L"this is a file";
262 wchar_t readBuf[30];
263
264 // write
265 CreateTestFolder();
266 fp = fopen(filePath, "w+");
267 EXPECT_NE(fwprintf(fp, L"%ls", writeBuf), -1);
268 EXPECT_NE(fclose(fp), -1) << "> fclose errno =" << errno;
269
270 // read
271 fp = fopen(filePath, "r");
272 ASSERT_NE(fp, nullptr) << "> fopen errno = " << errno;
273 EXPECT_NE(fgetws(readBuf, 30, fp), nullptr) << "fgetws error";
274 EXPECT_TRUE(wcscmp(writeBuf, readBuf) == 0) << "writeBuf != readBuf";
275 EXPECT_NE(fclose(fp), -1) << "> fclose errno =" << errno;
276 }
277 #endif
278