1 /*
2  * Copyright (c) 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 <fcntl.h>
23 #include <unistd.h>
24 #include <dirent.h>
25 #include <ftw.h>
26 #include <libgen.h>
27 
28 #include <gtest/gtest.h>
29 
30 #include "utils.h"
31 #include "log.h"
32 #include "KernelConstants.h"
33 #include "libfs.h"
34 
35 using namespace testing::ext;
36 
37 /**
38  * @tc.number   SUB_KERNEL_FS_DIRENT_0100
39  * @tc.name     basic function test : readdir read directory
40  * @tc.desc     [C- SOFTWARE -0200]
41  */
HWTEST_F(FileSystemTest, testReaddir, Function | MediumTest | Level3)42 HWTEST_F(FileSystemTest, testReaddir, Function | MediumTest | Level3)
43 {
44     struct dirent *dResult = nullptr;
45     DIR *dirp = nullptr;
46     int reIntDir = 0;
47     int reIntFile = 0;
48     CreateTestFolder();
49 
50     dirp = opendir(TOP_DIR "/" DIR0);
51     ASSERT_NE(dirp, nullptr) << "> opendir errno = " << errno;
52     for (int i = 0; i < 10; i++) {          // Prevents infinite loops.
53         dResult = readdir(dirp);
54         if (dResult == nullptr) {
55             break;
56         } else if (strcmp(dResult->d_name, DIR0_DIR0) == 0) {
57             LOG("> Read : %s OK", dResult->d_name);
58             reIntDir++;
59         }else if (strcmp(dResult->d_name, DIR0_DIR1) == 0) {
60             LOG("> Read : %s OK", dResult->d_name);
61             reIntDir++;
62         } else if (strcmp(dResult->d_name, DIR0_FILE0) == 0) {
63             LOG("> Read : %s OK", dResult->d_name);
64             reIntFile++;
65         } else {
66             LOG("> Read : %s", dResult->d_name);
67         }
68     }
69     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
70     EXPECT_EQ(reIntDir, 2) << "> read reIntDir = " << reIntDir;
71     EXPECT_EQ(reIntFile, 1) << "> read reIntFile = " << reIntFile;
72 }
73 
74 /**
75  * @tc.number   SUB_KERNEL_FS_DIRENT_0110
76  * @tc.name     basic function test : test readdir with error number EBADF
77  * @tc.desc     [C- SOFTWARE -0200]
78  */
HWTEST_F(FileSystemTest, testReaddirEbadf, Function | MediumTest | Level3)79 HWTEST_F(FileSystemTest, testReaddirEbadf, Function | MediumTest | Level3)
80 {
81     struct dirent *dResult = nullptr;
82     DIR *dirp = nullptr;
83     CreateTestFolder();
84 
85     dirp = opendir(TOP_DIR "/" DIR0);
86     ASSERT_NE(dirp, nullptr) << "> opendir errno = " << errno;
87     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
88 
89     dResult = readdir(dirp);
90     EXPECT_EQ(dResult, nullptr);
91     EXPECT_EQ(errno, EBADF);
92 }
93 
94 /**
95  * @tc.number   SUB_KERNEL_FS_DIRENT_0200
96  * @tc.name     basic function test : readdir_r read directory
97  * @tc.desc     [C- SOFTWARE -0200]
98  */
HWTEST_F(FileSystemTest, testReaddirR, Function | MediumTest | Level3)99 HWTEST_F(FileSystemTest, testReaddirR, Function | MediumTest | Level3)
100 {
101     struct dirent dEntry = {0};
102     struct dirent *dResult = nullptr;
103     DIR *dirp = nullptr;
104     int reIntDir = 0;
105     int reIntFile = 0;
106     CreateTestFolder();
107 
108     dirp = opendir(TOP_DIR "/" DIR0);
109     ASSERT_NE(dirp, nullptr) << "> opendir errno = " << errno;
110     for (int i = 0; i < 10; i++) {   // Prevents infinite loops.
111         if ((readdir_r(dirp, &dEntry, &dResult)) != 0) {
112             break;
113         }
114         if (dResult == nullptr) {
115             break;
116         } else if (strcmp(dResult->d_name, DIR0_DIR0) == 0) {
117             LOG("> Read : %s OK", dResult->d_name);
118             reIntDir++;
119         } else if (strcmp(dResult->d_name, DIR0_DIR1) == 0) {
120             LOG("> Read : %s OK", dResult->d_name);
121             reIntDir++;
122         } else if (strcmp(dResult->d_name, DIR0_FILE0) == 0) {
123             LOG("> Read : %s OK", dResult->d_name);
124             reIntFile++;
125         } else {
126             LOG("> Read : %s", dResult->d_name);
127         }
128     }
129     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
130     EXPECT_EQ(reIntDir, 2) << "> read reIntDir = " << reIntDir;
131     EXPECT_EQ(reIntFile, 1) << "> read reIntFile = " << reIntFile;
132 }
133 
134 /**
135  * @tc.number   SUB_KERNEL_FS_DIRENT_0300
136  * @tc.name     basic function test : scandir: scans a directory.
137  * @tc.desc     [C- SOFTWARE -0200]
138  */
HWTEST_F(FileSystemTest, testScandir, Function | MediumTest | Level3)139 HWTEST_F(FileSystemTest, testScandir, Function | MediumTest | Level3)
140 {
141     int sum = 0;
142     int reInt = 0;
143     struct dirent **fileList;
144     const char *scanDir = TOP_DIR "/" DIR0;
145     CreateTestFolder();
146 
147     sum = scandir(scanDir, &fileList, nullptr, alphasort);
148     EXPECT_NE(sum, -1) << "> scandir errno = " << errno;
149     for (int i = 0; i < sum; i++) {
150         if (i == 0) {
151             reInt = strncmp(fileList[i]->d_name, DIR0_DIR0, sizeof(DIR0_DIR0));
152         } else if (i == 1) {
153             reInt = strncmp(fileList[i]->d_name, DIR0_DIR1, sizeof(DIR0_DIR1));
154         } else if (i == 2) {
155             reInt = strncmp(fileList[i]->d_name, DIR0_FILE0, sizeof(DIR0_FILE0));
156         }
157         EXPECT_EQ(reInt, 0) << "> the " << i << "th d_name = " << fileList[i]->d_name;
158         LOG("> %s", fileList[i]->d_name);
159         free(fileList[i]);
160     }
161     free(fileList);
162 }
163 
164 #ifndef COMMERCIAL
165 /**
166  * @tc.number   SUB_KERNEL_FS_DIRENT_0400
167  * @tc.name     basic function test : Sets the location of the next {readdir} in the directory stream.
168  * @tc.desc     [C- SOFTWARE -0200]
169  */
HWTEST_F(FileSystemTest, testSeekdir, Function | MediumTest | Level3)170 HWTEST_F(FileSystemTest, testSeekdir, Function | MediumTest | Level3)
171 {
172     struct dirent *dResult = nullptr;
173     DIR *dirp = nullptr;
174     CreateTestFolder();
175 
176     dirp = opendir(TOP_DIR "/" DIR0);
177     ASSERT_NE(dirp, nullptr) << "> opendir errno = " << errno;
178 
179     dResult = readdir(dirp);
180     ASSERT_FALSE(dResult == nullptr) << "> readdir errno = " << errno;
181     EXPECT_EQ(telldir(dirp), dResult->d_off);
182     LOG("> dResult->d_name = %s", dResult->d_name);
183     LOG("> dResult->d_off = %lu", dResult->d_off);
184     long tellDir0 = dResult->d_off;
185 
186     dResult = readdir(dirp);
187     ASSERT_FALSE(dResult == nullptr) << "> readdir errno = " << errno;
188     EXPECT_EQ(telldir(dirp), dResult->d_off);
189     LOG("> dResult->d_name = %s", dResult->d_name);
190     LOG("> dResult->d_off = %lu", dResult->d_off);
191     long tellDir1 = dResult->d_off;
192 
193     dResult = readdir(dirp);
194     ASSERT_FALSE(dResult == nullptr) << "> readdir errno = " << errno;
195     LOG("> 111");
196     EXPECT_EQ(telldir(dirp), dResult->d_off);
197     LOG("> 222");
198     LOG("> dResult->d_name = %s", dResult->d_name);
199     LOG("> dResult->d_off = %lu", dResult->d_off);
200     long tellDir2 = dResult->d_off;
201 
202     rewinddir(dirp);
203     dResult = readdir(dirp);
204     ASSERT_FALSE(dResult == nullptr) << "> readdir errno = " << errno;
205     EXPECT_EQ(telldir(dirp), dResult->d_off);
206     EXPECT_EQ(telldir(dirp), tellDir0);
207     LOG("> dResult->d_name = %s", dResult->d_name);
208     LOG("> dResult->d_off = %lu", dResult->d_off);
209 
210     seekdir(dirp, tellDir1);
211     dResult = readdir(dirp);
212     ASSERT_FALSE(dResult == nullptr) << "> readdir errno = " << errno;
213     EXPECT_EQ(telldir(dirp), dResult->d_off);
214     EXPECT_EQ(telldir(dirp), tellDir2);
215     LOG("> dResult->d_name = %s", dResult->d_name);
216     LOG("> dResult->d_off = %lu", dResult->d_off);
217 
218     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
219 }
220 #endif
221 
222 /**
223  * @tc.number   SUB_KERNEL_FS_DIRENT_0500
224  * @tc.name     basic function test : test opendir return normal
225  * @tc.desc     [C- SOFTWARE -0200]
226  */
HWTEST_F(FileSystemTest, testOpendir, Function | MediumTest | Level2)227 HWTEST_F(FileSystemTest, testOpendir, Function | MediumTest | Level2)
228 {
229     DIR *dirp = nullptr;
230     CreateTestFolder();
231 
232     errno = 0;
233     dirp = opendir(TOP_DIR "/" DIR0);
234     if (dirp == nullptr) {
235         LOG("OPENDIR ERRNO +++");
236         ADD_FAILURE();
237     }
238     EXPECT_EQ(errno, 0);
239     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
240 }
241 
242 /**
243  * @tc.number   SUB_KERNEL_FS_DIRENT_0510
244  * @tc.name     basic function test : test opendir with error number EINVAL
245  * @tc.desc     [C- SOFTWARE -0200]
246  */
HWTEST_F(FileSystemTest, testOpendirEinval, Function | MediumTest | Level3)247 HWTEST_F(FileSystemTest, testOpendirEinval, Function | MediumTest | Level3)
248 {
249     DIR *dirp = nullptr;
250     CreateTestFolder();
251 
252     dirp = opendir(nullptr);
253     EXPECT_EQ(dirp, nullptr);
254     EXPECT_EQ(errno, EINVAL);
255     if (dirp != nullptr) {
256         EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
257     }
258 }
259 
260 /**
261  * @tc.number   SUB_KERNEL_FS_DIRENT_0520
262  * @tc.name     basic function test : test opendir with error number ENAMETOOLONG
263  * @tc.desc     [C- SOFTWARE -0200]
264  */
HWTEST_F(FileSystemTest, testOpendirEnametoolong, Function | MediumTest | Level3)265 HWTEST_F(FileSystemTest, testOpendirEnametoolong, Function | MediumTest | Level3)
266 {
267     const char *dirName = "12345678901234567890123456789012345678901234567890\
268     12345678901234567890123456789012345678901234567890\
269     12345678901234567890123456789012345678901234567890\
270     12345678901234567890123456789012345678901234567890\
271     12345678901234567890123456789012345678901234567890\
272     12345678901234567890123456789012345678901234567890\
273     12345678901234567890123456789012345678901234567890\
274     12345678901234567890123456789012345678901234567890";
275     DIR *dirp = nullptr;
276 
277     dirp = opendir(dirName);
278     EXPECT_EQ(dirp, nullptr);
279     EXPECT_EQ(errno, ENAMETOOLONG);
280     if (dirp != nullptr) {
281         EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
282     }
283 }
284 
285 /**
286  * @tc.number   SUB_KERNEL_FS_DIRENT_0530
287  * @tc.name     basic function test : test opendir with error number ENOENT
288  * @tc.desc     [C- SOFTWARE -0200]
289  */
HWTEST_F(FileSystemTest, testOpendirENOENT, Function | MediumTest | Level3)290 HWTEST_F(FileSystemTest, testOpendirENOENT, Function | MediumTest | Level3)
291 {
292     DIR *dirp = nullptr;
293     CreateTestFolder();
294 
295     dirp = opendir("noExistFile");
296     EXPECT_EQ(dirp, nullptr);
297     EXPECT_EQ(errno, ENOENT);
298     if (dirp != nullptr) {
299         EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
300     }
301 }
302 
303 /**
304  * @tc.number   SUB_KERNEL_FS_DIRENT_0540
305  * @tc.name     basic function test : test opendir with error number ENOTDIR
306  * @tc.desc     [C- SOFTWARE -0200]
307  */
HWTEST_F(FileSystemTest, testOpendirEnotdir, Function | MediumTest | Level3)308 HWTEST_F(FileSystemTest, testOpendirEnotdir, Function | MediumTest | Level3)
309 {
310     DIR *dirp = nullptr;
311     CreateTestFolder();
312 
313     dirp = opendir(TOP_DIR "/" DIR0 "/" DIR0_FILE0);
314     EXPECT_EQ(dirp, nullptr);
315     EXPECT_EQ(errno, ENOTDIR);
316     if (dirp != nullptr) {
317         EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
318     }
319 }
320 
321 /**
322  * @tc.number   SUB_KERNEL_FS_DIRENT_0600
323  * @tc.name     basic function test : test closedir
324  * @tc.desc     [C- SOFTWARE -0200]
325  */
HWTEST_F(FileSystemTest, testClosedir, Function | MediumTest | Level3)326 HWTEST_F(FileSystemTest, testClosedir, Function | MediumTest | Level3)
327 {
328     DIR *dirp = nullptr;
329     CreateTestFolder();
330 
331     dirp = opendir(TOP_DIR "/" DIR0);
332     if (dirp == nullptr) {
333         LOG("opendir errno ++");
334         ADD_FAILURE();
335     }
336     EXPECT_EQ(closedir(dirp), 0) << "> closedir errno = " << errno;
337 }
338