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
35using 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 */
42HWTEST_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 */
79HWTEST_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 */
99HWTEST_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 */
139HWTEST_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 */
170HWTEST_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 */
227HWTEST_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 */
247HWTEST_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 */
265HWTEST_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 */
290HWTEST_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 */
308HWTEST_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 */
326HWTEST_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