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#ifndef COMMERCIAL
38/**
39 * @tc.number   SUB_KERNEL_FS_STAT_0100
40 * @tc.name     basic function test : umask set and get file mode creation mask
41 * @tc.desc     [C- SOFTWARE -0200]
42 */
43HWTEST_F(FileSystemTest, testUmask, Function | MediumTest | Level2)
44{
45    // set mode
46    mode_t maskNew = GetRandom(077);
47    mode_t maskPre = umask(maskNew);
48    LOG("> maskPre = %d", maskPre);
49    LOG("> maskNew = %d", maskNew);
50    EXPECT_EQ(umask(maskPre), maskNew) << "> umask error";
51}
52#endif
53#if defined(LITE_FS_JFFS2)
54#ifndef COMMERCIAL
55/**
56 * @tc.number   SUB_KERNEL_FS_STAT_0210
57 * @tc.name     basic function test : Run the stat function to test limt.
58 * @tc.desc     [C- SOFTWARE -0200]
59 */
60HWTEST_F(FileSystemTest, testStatLimt, Function | MediumTest | Level3)
61{
62    int fd = 0;
63    mode_t mode = 0777;
64    const char *filePath = TOP_DIR "/" FILE0;
65    struct stat buf;
66
67    // set mode
68    mode_t maskNew = GetRandom(077);
69    mode_t maskPre = umask(maskNew);
70    mode = 0700 + GetRandom(077);
71    LOG("> maskPre = %d", maskPre);
72    LOG("> maskNew = %d", maskNew);
73    LOG("> mode = %d", mode);
74
75    fd = open(FILE0, O_CREAT | O_RDWR, mode);
76    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
77    EXPECT_NE(stat(filePath, &buf), -1) << "> fstat errno = " << errno;
78
79    EXPECT_NE((buf.st_mode & S_IFREG), 0) << "> check file type faild";
80    EXPECT_EQ((buf.st_mode & 0777), (mode & (~maskNew))) << "> check file permission faild";
81    EXPECT_EQ(buf.st_nlink, 1) << "> buf.st_nlink not expect";                      // Number of (hard) links to file
82    EXPECT_EQ(buf.st_uid, getuid()) << "> The UIDs are different";                  // uid
83    EXPECT_EQ(buf.st_gid, getgid()) << "> The GIDs are different";                  // giu
84    umask(maskPre);
85}
86#endif
87#endif
88#if defined(LITE_FS_JFFS2)
89#ifndef COMMERCIAL
90/**
91 * @tc.number   SUB_KERNEL_FS_STAT_0310
92 * @tc.name     basic function test : Run the lstat function to test limt.
93 * @tc.desc     [C- SOFTWARE -0200]
94 */
95HWTEST_F(FileSystemTest, testLstatLimt, Function | MediumTest | Level3)
96{
97    int fd = 0;
98    mode_t mode = 0777;
99    const char *filePath = TOP_DIR "/" FILE0;
100    struct stat buf;
101
102    // set mode
103    mode_t maskNew = GetRandom(077);
104    mode_t maskPre = umask(maskNew);
105    mode = 0700 + GetRandom(077);
106    LOG("> maskPre = %d", maskPre);
107    LOG("> maskNew = %d", maskNew);
108    LOG("> mode = %d", mode);
109
110    fd = open(filePath, O_CREAT | O_RDWR, mode);
111    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
112    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
113
114    EXPECT_NE(lstat(filePath, &buf), -1) << "> fstat errno = " << errno;
115    EXPECT_NE((buf.st_mode & S_IFREG), 0) << "> check file type faild";
116    EXPECT_EQ((buf.st_mode & 0777), (mode & (~maskNew))) << "> check file permission faild";
117    EXPECT_EQ(buf.st_nlink, 1) << "> buf.st_nlink not expect";                      // Number of (hard) links to file
118    EXPECT_EQ(buf.st_uid, getuid()) << "> The UIDs are different";                  // uid
119    EXPECT_EQ(buf.st_gid, getgid()) << "> The GIDs are different";                  // giu
120    umask(maskPre);
121}
122#endif
123#endif
124#if defined(LITE_FS_JFFS2)
125#ifndef COMMERCIAL
126/**
127 * @tc.number   SUB_KERNEL_FS_STAT_0410
128 * @tc.name     basic function test : Run the fstat function to test limt
129 * @tc.desc     [C- SOFTWARE -0200]
130 */
131HWTEST_F(FileSystemTest, testFstatLimt, Function | MediumTest | Level3)
132{
133    int fd = 0;
134    mode_t mode = 0777;
135    struct stat buf;
136
137    // set mode
138    mode_t maskNew = GetRandom(077);
139    mode_t maskPre = umask(maskNew);
140    mode = 0700 + GetRandom(077);
141    LOG("> maskPre = %d", maskPre);
142    LOG("> maskNew = %d", maskNew);
143    LOG("> mode = %d", mode);
144
145    fd = open(FILE0, O_CREAT | O_RDWR, mode);
146    EXPECT_NE(fd, -1) << "> open faild errno = " << errno;
147
148    EXPECT_NE(fstat(fd, &buf), -1) << "> fstat errno = " << errno;
149    EXPECT_NE((buf.st_mode & S_IFREG), 0) << "> check file type faild";
150    EXPECT_EQ((buf.st_mode & 0777), (mode & (~maskNew))) << "> check file permission faild";
151    EXPECT_EQ(buf.st_nlink, 1) << "> buf.st_nlink not expect";                      // Number of (hard) links to file
152    EXPECT_EQ(buf.st_uid, getuid()) << "> The UIDs are different";                  // uid
153    EXPECT_EQ(buf.st_gid, getgid()) << "> The GIDs are different";                  // giu
154
155    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
156    umask(maskPre);
157}
158#endif
159#endif
160
161/**
162 * @tc.number   SUB_KERNEL_FS_STAT_0500
163 * @tc.name     basic function test : Run the {mkdirat} function to create a directory.
164 * @tc.desc     [C- SOFTWARE -0200]
165 */
166HWTEST_F(FileSystemTest, testMkdirat, Function | MediumTest | Level0)
167{
168    const char *pathName = TOP_DIR "/" DIR0;
169    EXPECT_NE(mkdirat(AT_FDCWD, pathName, 0777), -1) << "> creat faild errno = " << errno;
170    EXPECT_EQ(access(pathName, F_OK), 0) << "> access F_OK errno = " << errno;
171    EXPECT_EQ(remove(pathName), 0) << "> remove errno = " << errno;
172    EXPECT_NE(access(pathName, F_OK), 0) << "> access F_OK expect faild but success";
173}
174
175/**
176 * @tc.number   SUB_KERNEL_FS_STAT_0510
177 * @tc.name     basic function test : test mkdirat with error number EINVAL
178 * @tc.desc     [C- SOFTWARE -0200]
179 */
180HWTEST_F(FileSystemTest, testMkdiratEinval, Function | MediumTest | Level3)
181{
182    EXPECT_EQ(mkdirat(AT_FDCWD, nullptr, 0777), -1) << "> should be error";
183    EXPECT_EQ(errno, EINVAL);
184}
185
186/**
187 * @tc.number   SUB_KERNEL_FS_STAT_0520
188 * @tc.name     basic function test : test mkdirat with error number ENAMETOOLONG
189 * @tc.desc     [C- SOFTWARE -0200]
190 */
191HWTEST_F(FileSystemTest, testMkdiratEnametoolong, Function | MediumTest | Level3)
192{
193    const char *pathName = "12345678901234567890123456789012345678901234567890\
194                            12345678901234567890123456789012345678901234567890\
195                            12345678901234567890123456789012345678901234567890\
196                            12345678901234567890123456789012345678901234567890\
197                            12345678901234567890123456789012345678901234567890\
198                            12345678901234567890123456789012345678901234567890\
199                            12345678901234567890123456789012345678901234567890\
200                            12345678901234567890123456789012345678901234567890";
201    EXPECT_EQ(mkdirat(AT_FDCWD, pathName, 0777), -1) << "> should be error";
202    EXPECT_EQ(errno, ENAMETOOLONG);
203}
204
205/**
206 * @tc.number   SUB_KERNEL_FS_STAT_0530
207 * @tc.name     basic function test : test mkdirat with error number ENOENT
208 * @tc.desc     [C- SOFTWARE -0200]
209 */
210HWTEST_F(FileSystemTest, testMkdiratEnoent, Function | MediumTest | Level3)
211{
212    const char *pathName = TOP_DIR "/NoExist/NoExist";
213    EXPECT_EQ(mkdirat(AT_FDCWD, pathName, 0777), -1) << "> should be error";
214    EXPECT_EQ(errno, ENOENT);
215}
216
217/**
218 * @tc.number   SUB_KERNEL_FS_STAT_0540
219 * @tc.name     basic function test : test mkdirat with error number EEXIST
220 * @tc.desc     [C- SOFTWARE -0200]
221 */
222HWTEST_F(FileSystemTest, testMkdiratEexist, Function | MediumTest | Level3)
223{
224    const char *pathName = TOP_DIR "/" DIR0;
225    EXPECT_NE(mkdirat(AT_FDCWD, pathName, 0777), -1) << "> creat faild errno = " << errno;
226    EXPECT_EQ(access(pathName, F_OK), 0) << "> access F_OK errno = " << errno;
227    EXPECT_EQ(mkdirat(AT_FDCWD, pathName, 0777), -1) << "> should be error";
228    EXPECT_EQ(errno, EEXIST);
229}
230
231#if defined(LITE_FS_JFFS2)
232/**
233 * @tc.number   SUB_KERNEL_FS_STAT_0600
234 * @tc.name     basic function test : use chmod function to change mode
235 * @tc.desc     [C- SOFTWARE -0200]
236 */
237HWTEST_F(FileSystemTest, testChmod, Function | MediumTest | Level3)
238{
239    struct stat buf;
240    mode_t maskPre = umask(0);
241    const char *fileName = TOP_DIR "/" FILE0;
242    int fd = creat(FILE0, 0777);
243    EXPECT_NE(fd, -1) << "> creat faild errno = " << errno;
244    EXPECT_NE(close(fd), -1) << "> close errno = " << errno;
245
246    mode_t mode = 0666;
247    EXPECT_EQ(chmod(fileName, mode), 0);
248    EXPECT_NE(stat(fileName, &buf), -1) << "> fstat errno = " << errno;
249    EXPECT_EQ((buf.st_mode & 0777), mode) << "> check file permission faild";
250    umask(maskPre);
251}
252#endif
253