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 * limitations under the License.
13 */
14#include "FileSystemTest.h"
15#include <stdio.h>
16#include <string.h>
17#include <stdlib.h>
18
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <fcntl.h>
22#include <unistd.h>
23#include <dirent.h>
24#include <ftw.h>
25#include <libgen.h>
26
27#include <gtest/gtest.h>
28
29#include "utils.h"
30#include "log.h"
31#include "KernelConstants.h"
32#include "libfs.h"
33
34using namespace testing::ext;
35
36/**
37 * @tc.number   SUB_KERNEL_FS_UNISTD_0100
38 * @tc.name     basic function test : access check file exists.
39 * @tc.desc     [C- SOFTWARE -0200]
40 */
41HWTEST_F(FileSystemTest, testAccess, Function | MediumTest | Level0)
42{
43    int fd = 0;
44    fd = creat(FILE0, 0777);
45    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
46    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
47    EXPECT_EQ(access(FILE0, F_OK), 0) << "> access F_OK errno = " << errno;
48}
49
50/**
51 * @tc.number   SUB_KERNEL_FS_UNISTD_0110
52 * @tc.name     basic function test : test access with ENOENT
53 * @tc.desc     [C- SOFTWARE -0200]
54 */
55HWTEST_F(FileSystemTest, testAccessEnoent, Function | MediumTest | Level0)
56{
57    EXPECT_EQ(access(FILE0, F_OK), -1) << "> access F_OK expect faild but success";
58    EXPECT_EQ(errno, ENOENT);
59}
60
61#if defined(LITE_FS_JFFS2)
62/**
63 * @tc.number   SUB_KERNEL_FS_UNISTD_0120
64 * @tc.name     basic function test : access check file R_OK.
65 * @tc.desc     [C- SOFTWARE -0200]
66 */
67HWTEST_F(FileSystemTest, testAccessRok, Function | MediumTest | Level1)
68{
69    int fd = 0;
70    fd = creat(FILE0, 0777);
71    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
72    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
73    EXPECT_EQ(access(FILE0, R_OK), 0) << "> access F_OK errno = " << errno;
74}
75#endif
76
77#if defined(LITE_FS_JFFS2)
78/**
79 * @tc.number   SUB_KERNEL_FS_UNISTD_0130
80 * @tc.name     basic function test : access check file W_OK.
81 * @tc.desc     [C- SOFTWARE -0200]
82 */
83HWTEST_F(FileSystemTest, testAccessWok, Function | MediumTest | Level1)
84{
85    int fd = 0;
86    fd = creat(FILE0, 0777);
87    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
88    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
89    EXPECT_EQ(access(FILE0, W_OK), 0) << "> access F_OK errno = " << errno;
90}
91#endif
92
93#if defined(LITE_FS_JFFS2)
94/**
95 * @tc.number   SUB_KERNEL_FS_UNISTD_0140
96 * @tc.name     basic function test : access check file X_OK
97 * @tc.desc     [C- SOFTWARE -0200]
98 */
99HWTEST_F(FileSystemTest, testAccessXok, Function | MediumTest | Level1)
100{
101    int fd = 0;
102    fd = creat(FILE0, 0777);
103    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
104    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
105    EXPECT_EQ(access(FILE0, X_OK), 0) << "> access F_OK errno = " << errno;
106}
107#endif
108
109/**
110 * @tc.number   SUB_KERNEL_FS_UNISTD_0200
111 * @tc.name     basic function test : switch to the current working directory.
112 * @tc.desc     [C- SOFTWARE -0200]
113 */
114HWTEST_F(FileSystemTest, testChdir, Function | MediumTest | Level1)
115{
116    char testDir[MAX_PATH_SIZE];
117    const char *expectDirStandard = TOP_DIR "/" DIR0;
118    EXPECT_NE(mkdir(DIR0, 0777), -1) << "> mkdir errno = " << errno;
119    EXPECT_NE(chdir(DIR0), -1) << "> chdir errno = " << errno;
120    EXPECT_NE(getcwd(testDir, sizeof(testDir)), nullptr) << "> getcwd errno = " << errno;
121    EXPECT_NE(chdir(TOP_DIR), -1) << "> chdir errno = " << errno;
122
123    EXPECT_STREQ(testDir, expectDirStandard);
124    LOG("> expectDirStandard  = %s", expectDirStandard);
125    LOG("> testDir   = %s", testDir);
126}
127
128/**
129 * @tc.number   SUB_KERNEL_FS_UNISTD_0210
130 * @tc.name     basic function test : test chdir with ENOENT
131 * @tc.desc     [C- SOFTWARE -0200]
132 */
133HWTEST_F(FileSystemTest, testChdirEnoent, Function | MediumTest | Level3)
134{
135    const char *fileName = "not_exist_file";
136    EXPECT_EQ(chdir(fileName), -1) << "> chdir errno = " << errno;
137    EXPECT_EQ(errno, ENOENT);
138    EXPECT_NE(chdir(TOP_DIR), -1) << "> chdir errno = " << errno;
139}
140
141/**
142 * @tc.number   SUB_KERNEL_FS_UNISTD_0220
143 * @tc.name     basic function test : test chdir with ENAMETOOLONG
144 * @tc.desc     [C- SOFTWARE -0200]
145 */
146HWTEST_F(FileSystemTest, testChdirEnametoolong, Function | MediumTest | Level3)
147{
148    const char *fileName = "12345678901234567890123456789012345678901234567890\
149                            12345678901234567890123456789012345678901234567890\
150                            12345678901234567890123456789012345678901234567890\
151                            12345678901234567890123456789012345678901234567890\
152                            12345678901234567890123456789012345678901234567890\
153                            12345678901234567890123456789012345678901234567890\
154                            12345678901234567890123456789012345678901234567890\
155                            12345678901234567890123456789012345678901234567890";
156    EXPECT_EQ(chdir(fileName), -1) << "> chdir errno = " << errno;
157    EXPECT_EQ(errno, ENAMETOOLONG);
158    EXPECT_NE(chdir(TOP_DIR), -1) << "> chdir errno = " << errno;
159}
160
161/**
162 * @tc.number   SUB_KERNEL_FS_UNISTD_0230
163 * @tc.name     basic function test : test chdir with ENOTDIR
164 * @tc.desc     [C- SOFTWARE -0200]
165 */
166HWTEST_F(FileSystemTest, testChdirEnotdir, Function | MediumTest | Level3)
167{
168    int fd = 0;
169    const char *fileName = FILE0;
170    fd = creat(FILE0, 0777);
171    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
172    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
173    EXPECT_EQ(chdir(fileName), -1) << "> chdir errno = " << errno;
174    EXPECT_EQ(errno, ENOTDIR);
175    EXPECT_NE(chdir(TOP_DIR), -1) << "> chdir errno = " << errno;
176}
177#if defined(LITE_FS_VFAT)
178/**
179 * @tc.number   SUB_KERNEL_FS_UNISTD_0500
180 * @tc.name     basic function test : using ftruncate to change the file size
181 * @tc.desc     [C- SOFTWARE -0200]
182 */
183HWTEST_F(FileSystemTest, testFtruncate, Function | MediumTest | Level1)
184{
185    struct stat statbuf;
186    char writeBuf[] = "this is a file";
187    int fd = 0;
188
189    fd = open(FILE0, O_CREAT | O_RDWR, 0777);
190    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
191    EXPECT_NE(write(fd, writeBuf, sizeof(writeBuf)), -1) << "> write errno = " << errno;
192
193    EXPECT_NE(ftruncate(fd, 1000), -1) << "truncate errno = " << errno;
194    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
195
196    EXPECT_NE(stat(FILE0, &statbuf), -1) << "> fstat errno = " << errno;
197    EXPECT_EQ(statbuf.st_size, 1000);
198}
199#endif
200
201#if defined(LITE_FS_VFAT)
202/**
203 * @tc.number   SUB_KERNEL_FS_UNISTD_0501
204 * @tc.name     basic function test : test ftruncate with EINVAL
205 * @tc.desc     [C- SOFTWARE -0200]
206 */
207HWTEST_F(FileSystemTest, testFtruncateEinval, Function | MediumTest | Level3)
208{
209    char writeBuf[] = "this is a file";
210    int fd = 0;
211
212    fd = open(FILE0, O_CREAT | O_RDWR, 0777);
213    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
214    EXPECT_NE(write(fd, writeBuf, sizeof(writeBuf)), -1) << "> write errno = " << errno;
215
216    EXPECT_EQ(ftruncate(fd, -1), -1);
217    EXPECT_EQ(errno, EINVAL);
218    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
219}
220#endif
221
222#if defined(LITE_FS_VFAT)
223/**
224 * @tc.number   SUB_KERNEL_FS_UNISTD_0502
225 * @tc.name     basic function test : test ftruncate with ENOSYS
226 * @tc.desc     [C- SOFTWARE -0200]
227 */
228HWTEST_F(FileSystemTest, testFtruncateEacces, Function | MediumTest | Level3)
229{
230    EXPECT_EQ(ftruncate(STDERR_FILENO, 10), -1);
231    EXPECT_EQ(errno, ENOSYS);
232}
233#endif
234
235#if defined(LITE_FS_VFAT)
236/**
237 * @tc.number   SUB_KERNEL_FS_UNISTD_0503
238 * @tc.name     basic function test : test ftruncate with EBADF
239 * @tc.desc     [C- SOFTWARE -0200]
240 */
241HWTEST_F(FileSystemTest, testFtruncateEbadf, Function | MediumTest | Level3)
242{
243    int invalidFd = 99999;
244    EXPECT_EQ(ftruncate(invalidFd, 10), -1);
245    EXPECT_EQ(errno, EBADF);
246}
247#endif
248
249#if defined(LITE_FS_VFAT)
250/**
251 * @tc.number   SUB_KERNEL_FS_UNISTD_0510
252 * @tc.name     basic function test : using truncate functions to change the file size
253 * @tc.desc     [C- SOFTWARE -0200]
254 */
255HWTEST_F(FileSystemTest, testTruncate, Function | MediumTest | Level1)
256{
257    struct stat statbuf;
258    char writeBuf[] = "this is a file";
259    int fd = 0;
260
261    fd = open(FILE0, O_CREAT | O_RDWR, 0777);
262    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
263    EXPECT_NE(write(fd, writeBuf, sizeof(writeBuf)), -1) << "> write errno = " << errno;
264    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
265
266    EXPECT_NE(truncate(FILE0, 100), -1) << "truncate errno = " << errno;
267    EXPECT_NE(stat(FILE0, &statbuf), -1) << "> fstat errno = " << errno;
268    EXPECT_EQ(statbuf.st_size, 100);
269}
270#endif
271
272#if defined(LITE_FS_VFAT)
273/**
274 * @tc.number   SUB_KERNEL_FS_UNISTD_0511
275 * @tc.name     basic function test : test truncate with EINVAL
276 * @tc.desc     [C- SOFTWARE -0200]
277 */
278HWTEST_F(FileSystemTest, testTruncateEinval, Function | MediumTest | Level3)
279{
280    char writeBuf[] = "this is a file";
281    int fd = 0;
282
283    fd = open(FILE0, O_CREAT | O_RDWR, 0777);
284    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
285    EXPECT_NE(write(fd, writeBuf, sizeof(writeBuf)), -1) << "> write errno = " << errno;
286    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
287
288    EXPECT_EQ(truncate(FILE0, -1), -1);
289    EXPECT_EQ(errno, EINVAL);
290}
291#endif
292
293#if defined(LITE_FS_VFAT)
294/**
295 * @tc.number   SUB_KERNEL_FS_UNISTD_0512
296 * @tc.name     basic function test : test truncate with EACCES
297 * @tc.desc     [C- SOFTWARE -0200]
298 */
299HWTEST_F(FileSystemTest, testTruncateEacces, Function | MediumTest | Level3)
300{
301    EXPECT_EQ(truncate("/", 10), -1);
302    printf("errno = %d\n", errno);
303    EXPECT_EQ(errno, EISDIR);
304}
305#endif
306
307#if defined(LITE_FS_VFAT)
308/**
309 * @tc.number   SUB_KERNEL_FS_UNISTD_0513
310 * @tc.name     basic function test : test truncate with ENAMETOOLONG
311 * @tc.desc     [C- SOFTWARE -0200]
312 */
313HWTEST_F(FileSystemTest, testTruncateEnametoolong, Function | MediumTest | Level3)
314{
315    const char *fileName = "12345678901234567890123456789012345678901234567890\
316                            12345678901234567890123456789012345678901234567890\
317                            12345678901234567890123456789012345678901234567890\
318                            12345678901234567890123456789012345678901234567890\
319                            12345678901234567890123456789012345678901234567890\
320                            12345678901234567890123456789012345678901234567890\
321                            12345678901234567890123456789012345678901234567890\
322                            12345678901234567890123456789012345678901234567890";
323    EXPECT_EQ(truncate(fileName, 10), -1);
324    EXPECT_EQ(errno, ENAMETOOLONG);
325}
326#endif
327
328#if defined(LITE_FS_VFAT)
329/**
330 * @tc.number   SUB_KERNEL_FS_UNISTD_0514
331 * @tc.name     basic function test : test truncate with ENOENT
332 * @tc.desc     [C- SOFTWARE -0200]
333 */
334HWTEST_F(FileSystemTest, testTruncateEnoent, Function | MediumTest | Level3)
335{
336    const char invalidPath[] = "noExit";
337    EXPECT_EQ(truncate(invalidPath, 10), -1);
338    EXPECT_EQ(errno, ENOENT);
339}
340#endif
341
342#ifdef LITE_FS_PATHCONF
343/**
344 * @tc.number   SUB_KERNEL_FS_UNISTD_0600
345 * @tc.name     basic function test : Use the pathconf function to get the configuration value of the file
346 * @tc.desc     [C- SOFTWARE -0200]
347 */
348HWTEST_F(FileSystemTest, testPathconf, Function | MediumTest | Level2)
349{
350    const char filePath[] = TOP_DIR "/" DIR0 "/" DIR0_FILE0;
351    CreateTestFolder();
352
353    // use correctly
354    int param[] = {
355        _PC_LINK_MAX,
356        _PC_MAX_CANON,
357        _PC_MAX_INPUT,
358        _PC_NAME_MAX,
359        _PC_PATH_MAX,
360        _PC_PIPE_BUF,
361        _PC_CHOWN_RESTRICTED,
362        _PC_NO_TRUNC,
363        _PC_VDISABLE,
364        _PC_SYNC_IO,
365        _PC_ASYNC_IO,
366        _PC_PRIO_IO,
367        _PC_SOCK_MAXBUF,
368        _PC_FILESIZEBITS,
369        _PC_REC_INCR_XFER_SIZE,
370        _PC_REC_MAX_XFER_SIZE,
371        _PC_REC_MIN_XFER_SIZE,
372        _PC_REC_XFER_ALIGN,
373        _PC_ALLOC_SIZE_MIN,
374        _PC_SYMLINK_MAX,
375        _PC_2_SYMLINKS
376    };
377    int size = sizeof(param) / sizeof(int);
378    for (int i = 0; i < size; i++) {
379        errno = 0;
380        if (pathconf(filePath, param[i]) == -1) {
381            EXPECT_EQ(errno, 0) << "fpathconf i = " << i << " errno = " << errno;
382        }
383    }
384}
385#endif
386
387#ifdef LITE_FS_PATHCONF
388/**
389 * @tc.number   SUB_KERNEL_FS_UNISTD_0610
390 * @tc.name     basic function test : test pathconf function with error number EINVAL
391 * @tc.desc     [C- SOFTWARE -0200]
392 */
393HWTEST_F(FileSystemTest, testPathconfEinval, Function | MediumTest | Level2)
394{
395    const char filePath[] = TOP_DIR "/" DIR0 "/" DIR0_FILE0;
396    CreateTestFolder();
397
398    // invalid name
399    EXPECT_EQ(pathconf(filePath, -100), -1);
400    EXPECT_EQ(errno, EINVAL) << "fpathconf invalidPath errno = " << errno;
401}
402#endif
403
404#ifdef LITE_FS_PATHCONF
405/**
406 * @tc.number   SUB_KERNEL_FS_UNISTD_0620
407 * @tc.name     basic function test : test pathconf function with error number EFAULT
408 * @tc.desc     [C- SOFTWARE -0200]
409 */
410HWTEST_F(FileSystemTest, testPathconfEfault, Function | MediumTest | Level2)
411{
412    // null path
413    EXPECT_EQ(pathconf(nullptr, _PC_LINK_MAX), -1);
414    EXPECT_EQ(errno, EFAULT) << "fpathconf invalidPath errno = " << errno;
415}
416#endif
417
418#ifdef LITE_FS_PATHCONF
419/**
420 * @tc.number   SUB_KERNEL_FS_UNISTD_0630
421 * @tc.name     basic function test : test pathconf function with error number ENOENT
422 * @tc.desc     [C- SOFTWARE -0200]
423 */
424HWTEST_F(FileSystemTest, testPathconfEnoent, Function | MediumTest | Level2)
425{
426    // path not exit
427    const char invalidPath[] = "noExit";
428    EXPECT_EQ(pathconf(invalidPath, _PC_LINK_MAX), -1);
429    EXPECT_EQ(errno, ENOENT) << "fpathconf invalidPath errno = " << errno;
430}
431#endif
432
433#ifdef LITE_FS_PATHCONF
434/**
435* @tc.number    SUB_KERNEL_FS_UNISTD_0700
436* @tc.name      basic function test : Use the fpathconf function to get the configuration value of the file
437* @tc.desc      [C- SOFTWARE -0200]
438*/
439HWTEST_F(FileSystemTest, testFpathconf, Function | MediumTest | Level2)
440{
441    int fd = open(FILE0, O_CREAT | O_RDWR, 0777);
442    EXPECT_NE(fd, -1) << "> open errno = " << errno;
443
444    // use correctly
445    int param[] = {
446        _PC_LINK_MAX,
447        _PC_MAX_CANON,
448        _PC_MAX_INPUT,
449        _PC_NAME_MAX,
450        _PC_PATH_MAX,
451        _PC_PIPE_BUF,
452        _PC_CHOWN_RESTRICTED,
453        _PC_NO_TRUNC,
454        _PC_VDISABLE,
455        _PC_SYNC_IO,
456        _PC_ASYNC_IO,
457        _PC_PRIO_IO,
458        _PC_SOCK_MAXBUF,
459        _PC_FILESIZEBITS,
460        _PC_REC_INCR_XFER_SIZE,
461        _PC_REC_MAX_XFER_SIZE,
462        _PC_REC_MIN_XFER_SIZE,
463        _PC_REC_XFER_ALIGN,
464        _PC_ALLOC_SIZE_MIN,
465        _PC_SYMLINK_MAX,
466        _PC_2_SYMLINKS
467    };
468    int size = sizeof(param) / sizeof(int);
469    for (int i = 0; i < size; i++) {
470        errno = 0;
471        if (fpathconf(fd, param[i]) == -1) {
472            EXPECT_EQ(errno, 0) << "fpathconf i = " << i << " errno = " << errno;
473        }
474    }
475    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
476}
477#endif
478
479#ifdef LITE_FS_PATHCONF
480/**
481* @tc.number    SUB_KERNEL_FS_UNISTD_0710
482* @tc.name      basic function test : test fpathconf function with error number EINVAL
483* @tc.desc      [C- SOFTWARE -0200]
484*/
485HWTEST_F(FileSystemTest, testFpathconfEinval, Function | MediumTest | Level2)
486{
487    int fd = open(FILE0, O_CREAT | O_RDWR, 0777);
488    EXPECT_NE(fd, -1) << "> open errno = " << errno;
489
490    // invalid name
491    errno = 0;
492    EXPECT_EQ(fpathconf(fd, -100), -1);
493    EXPECT_EQ(errno, EINVAL) << "fpathconf invalidPath errno = " << errno;
494
495    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
496}
497#endif
498
499#ifdef LITE_FS_PATHCONF
500/**
501* @tc.number    SUB_KERNEL_FS_UNISTD_0720
502* @tc.name      basic function test : test fpathconf function with error number EBADF
503* @tc.desc      [C- SOFTWARE -0200]
504*/
505HWTEST_F(FileSystemTest, testFpathconfEbadf, Function | MediumTest | Level2)
506{
507    // invalid file description
508    EXPECT_EQ(fpathconf(-100, _PC_LINK_MAX), -1);
509    EXPECT_EQ(errno, EBADF) << "fpathconf invalidPath errno = " << errno;
510}
511#endif
512