1 /*
2 * Copyright (c) 2021-2025 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
16 #include <fcntl.h>
17 #include <sys/mount.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20
21 #include "gtest/gtest.h"
22 #include "common/help_utils.h"
23 #include "storage_service_errno.h"
24 #include "storage_service_log.h"
25 #include "utils/file_utils.h"
26 #include "utils/storage_radar.h"
27 #include "parameter.h"
28
29 namespace OHOS {
30 namespace StorageDaemon {
31 using namespace testing::ext;
32
33 constexpr int NOT_EXIST_FD_1 = 45678;
34 constexpr int NOT_EXIST_FD_2 = 45679;
35 namespace {
36 const uint32_t ALL_PERMS = (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
37 const std::string PATH_CHMOD = "/data/storage_daemon_chmod_test_dir";
38 const std::string PATH_CHOWN = "/data/storage_daemon_chown_test_dir";
39 const std::string PATH_RMDIR = "/data/storage_daemon_rmdir_test_dir";
40 const std::string PATH_MKDIR = "/data/storage_daemon_mkdir_test_dir";
41 const std::string PATH_MOUNT = "/data/storage_daemon_mount_test_dir";
42 }
43
44 int32_t ChMod(const std::string &path, mode_t mode);
45 int32_t ChOwn(const std::string &path, uid_t uid, gid_t gid);
46 int32_t MkDir(const std::string &path, mode_t mode);
47 int32_t RmDir(const std::string &path);
48
49 class FileUtilsTest : public testing::Test {
50 public:
SetUpTestCase(void)51 static void SetUpTestCase(void) {};
TearDownTestCase(void)52 static void TearDownTestCase(void) {};
53 void SetUp();
54 void TearDown();
55 };
56
SetUp(void)57 void FileUtilsTest::SetUp(void)
58 {
59 mode_t mode = 002;
60 umask(mode);
61 StorageTest::StorageTestUtils::RmDirRecurse(PATH_CHMOD);
62 StorageTest::StorageTestUtils::RmDirRecurse(PATH_CHOWN);
63 StorageTest::StorageTestUtils::RmDirRecurse(PATH_MKDIR);
64 StorageTest::StorageTestUtils::RmDirRecurse(PATH_RMDIR);
65 StorageTest::StorageTestUtils::RmDirRecurse(PATH_MOUNT);
66 }
67
TearDown(void)68 void FileUtilsTest::TearDown(void)
69 {
70 StorageTest::StorageTestUtils::RmDirRecurse(PATH_CHMOD);
71 StorageTest::StorageTestUtils::RmDirRecurse(PATH_CHOWN);
72 StorageTest::StorageTestUtils::RmDirRecurse(PATH_MKDIR);
73 StorageTest::StorageTestUtils::RmDirRecurse(PATH_RMDIR);
74 StorageTest::StorageTestUtils::RmDirRecurse(PATH_MOUNT);
75 }
76
77 /**
78 * @tc.name: FileUtilsTest_ChMod_001
79 * @tc.desc: Verify the ChMod function.
80 * @tc.type: FUNC
81 * @tc.require: AR000GK4HB
82 */
83 HWTEST_F(FileUtilsTest, FileUtilsTest_ChMod_001, TestSize.Level1)
84 {
85 GTEST_LOG_(INFO) << "FileUtilsTest_ChMod_001 start";
86
87 mode_t mode = 0660;
88 bool bRet = StorageTest::StorageTestUtils::MkDir(PATH_CHMOD, mode);
89 ASSERT_TRUE(bRet);
90 struct stat st;
91 int32_t ret = lstat(PATH_CHMOD.c_str(), &st);
92 ASSERT_TRUE(ret == 0);
93 EXPECT_TRUE((st.st_mode & ALL_PERMS) == mode);
94
95 mode = 0771;
96 ret = ChMod(std::string(PATH_CHMOD), mode);
97 ASSERT_TRUE(ret == E_OK);
98
99 ret = lstat(PATH_CHMOD.c_str(), &st);
100 ASSERT_TRUE(ret == 0);
101 EXPECT_TRUE((st.st_mode & ALL_PERMS) == mode);
102
103 GTEST_LOG_(INFO) << "FileUtilsTest_ChMod_001 end";
104 }
105
106 /**
107 * @tc.name: FileUtilsTest_ChOwn_001
108 * @tc.desc: Verify the ChOwn function.
109 * @tc.type: FUNC
110 * @tc.require: AR000GK4HB
111 */
112 HWTEST_F(FileUtilsTest, FileUtilsTest_ChOwn_001, TestSize.Level1)
113 {
114 GTEST_LOG_(INFO) << "FileUtilsTest_ChOwn_001 start";
115
116 mode_t mode = 0660;
117 bool bRet = StorageTest::StorageTestUtils::MkDir(PATH_CHOWN, mode);
118 ASSERT_TRUE(bRet);
119 ASSERT_TRUE(StorageTest::StorageTestUtils::CheckDir(PATH_CHOWN));
120
121 uid_t uid = 00;
122 gid_t gid = 01;
123 int32_t ret = ChOwn(PATH_CHOWN, uid, gid);
124 ASSERT_TRUE(ret == E_OK);
125
126 struct stat st;
127 ret = lstat(PATH_CHOWN.c_str(), &st);
128 ASSERT_TRUE(ret == 0);
129 EXPECT_TRUE(st.st_uid == uid);
130 EXPECT_TRUE(st.st_gid == gid);
131
132 uid = 01;
133 gid = 00;
134 ret = ChOwn(PATH_CHOWN, uid, gid);
135 ASSERT_TRUE(ret == E_OK);
136
137 ret = lstat(PATH_CHOWN.c_str(), &st);
138 ASSERT_TRUE(ret == 0);
139 EXPECT_TRUE(st.st_uid == uid);
140 EXPECT_TRUE(st.st_gid == gid);
141
142 GTEST_LOG_(INFO) << "FileUtilsTest_ChOwn_001 end";
143 }
144
145 /**
146 * @tc.name: FileUtilsTest_MkDir_001
147 * @tc.desc: Verify the MkDir function.
148 * @tc.type: FUNC
149 * @tc.require: AR000GK4HB
150 */
151 HWTEST_F(FileUtilsTest, FileUtilsTest_MkDir_001, TestSize.Level1)
152 {
153 GTEST_LOG_(INFO) << "FileUtilsTest_MkDir_001 start";
154
155 mode_t mode = 0771;
156 int32_t ret = MkDir(PATH_MKDIR.c_str(), mode);
157 ASSERT_TRUE(ret == E_OK);
158 ASSERT_TRUE(StorageTest::StorageTestUtils::CheckDir(PATH_MKDIR)) << "check the dir";
159
160 struct stat st;
161 ret = lstat(PATH_MKDIR.c_str(), &st);
162 ASSERT_TRUE(ret == 0);
163 EXPECT_TRUE((st.st_mode & ALL_PERMS) == mode);
164
165 GTEST_LOG_(INFO) << "FileUtilsTest_MkDir_001 end";
166 }
167
168 /**
169 * @tc.name: FileUtilsTest_RmDir_001
170 * @tc.desc: Verify the RmDir function.
171 * @tc.type: FUNC
172 * @tc.require: AR000GK4HB
173 */
174 HWTEST_F(FileUtilsTest, FileUtilsTest_RmDir_001, TestSize.Level1)
175 {
176 GTEST_LOG_(INFO) << "FileUtilsTest_RmDir_001 start";
177
178 mode_t mode = 0771;
179 bool bRet = StorageTest::StorageTestUtils::MkDir(PATH_RMDIR, mode);
180 ASSERT_TRUE(bRet);
181 ASSERT_TRUE(StorageTest::StorageTestUtils::CheckDir(PATH_RMDIR));
182
183 int32_t ret = RmDir(PATH_RMDIR);
184 ASSERT_TRUE(ret == E_OK);
185 EXPECT_TRUE(StorageTest::StorageTestUtils::CheckDir(PATH_RMDIR) == false);
186
187 GTEST_LOG_(INFO) << "FileUtilsTest_RmDir_001 end";
188 }
189
190 /**
191 * @tc.name: FileUtilsTest_PrepareDir_001
192 * @tc.desc: Verify the PrepareDir function.
193 * @tc.type: FUNC
194 * @tc.require: AR000GK4HB
195 */
196 HWTEST_F(FileUtilsTest, FileUtilsTest_PrepareDir_001, TestSize.Level1)
197 {
198 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_001 start";
199
200 mode_t mode = 0771;
201 uid_t uid = 00;
202 gid_t gid = 01;
203 int fd = open(PATH_MKDIR.c_str(), O_RDWR | O_CREAT, mode);
204 ASSERT_TRUE(fd > 0);
205
206 bool ret = PrepareDir(PATH_MKDIR, mode, uid, gid);
207 ASSERT_TRUE(ret != true) << "path is not a dir";
208
209 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_001 end";
210 (void)close(fd);
211 }
212
213 /**
214 * @tc.name: FileUtilsTest_PrepareDir_002
215 * @tc.desc: Verify the PrepareDir function.
216 * @tc.type: FUNC
217 * @tc.require: AR000GK4HB
218 */
219 HWTEST_F(FileUtilsTest, FileUtilsTest_PrepareDir_002, TestSize.Level1)
220 {
221 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_002 start";
222
223 mode_t mode = 0664;
224 StorageTest::StorageTestUtils::MkDir(PATH_MKDIR, mode);
225
226 mode = 0771;
227 uid_t uid = 00;
228 gid_t gid = 01;
229 bool bRet = PrepareDir(PATH_MKDIR, mode, uid, gid);
230 ASSERT_TRUE(bRet) << "check the dir is exists but mode is incorrect";
231
232 struct stat st;
233 int ret = lstat(PATH_MKDIR.c_str(), &st);
234 ASSERT_TRUE(ret == 0);
235 EXPECT_TRUE((st.st_mode & ALL_PERMS) == mode);
236 EXPECT_TRUE(st.st_uid == uid);
237 EXPECT_TRUE(st.st_gid == gid);
238
239 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_002 end";
240 }
241
242 /**
243 * @tc.name: FileUtilsTest_PrepareDir_003
244 * @tc.desc: Verify the PrepareDir function.
245 * @tc.type: FUNC
246 * @tc.require: AR000GK4HB
247 */
248 HWTEST_F(FileUtilsTest, FileUtilsTest_PrepareDir_003, TestSize.Level1)
249 {
250 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_003 start";
251
252 mode_t mode = 0771;
253 uid_t uid = 00;
254 gid_t gid = 01;
255 bool bRet = PrepareDir(PATH_MKDIR, mode, uid, gid);
256 ASSERT_TRUE(bRet);
257
258 struct stat st;
259 int ret = lstat(PATH_MKDIR.c_str(), &st);
260 ASSERT_TRUE(ret == 0);
261 EXPECT_TRUE((st.st_mode & ALL_PERMS) == mode);
262 EXPECT_TRUE(st.st_uid == uid);
263 EXPECT_TRUE(st.st_gid == gid);
264
265 GTEST_LOG_(INFO) << "FileUtilsTest_PrepareDir_003 end";
266 }
267
268 /**
269 * @tc.name: FileUtilsTest_Split_001
270 * @tc.desc: Verify the Split function.
271 * @tc.type: FUNC
272 * @tc.require: IBDKKD
273 */
274 HWTEST_F(FileUtilsTest, FileUtilsTest_Split_001, TestSize.Level1)
275 {
276 GTEST_LOG_(INFO) << "FileUtilsTest_Split_001 start";
277
278 std::string test = "this is a good idea";
279 std::string pattern = " ";
280 std::vector<std::string> expectVec{ "this", "is", "a", "good", "idea" };
281 auto ret = Split(test, pattern);
282 EXPECT_EQ(ret, expectVec);
283 GTEST_LOG_(INFO) << "FileUtilsTest_Split_001 end";
284 }
285
286 /**
287 * @tc.name: FileUtilsTest_DelFolder_001
288 * @tc.desc: Verify the DelFolder function.
289 * @tc.type: FUNC
290 * @tc.require: IBDKKD
291 */
292 HWTEST_F(FileUtilsTest, FileUtilsTest_DelFolder_001, TestSize.Level1)
293 {
294 GTEST_LOG_(INFO) << "FileUtilsTest_DelFolder_001 start";
295
296 std::string testPath = "/data/test/tdd";
297 EXPECT_TRUE(CreateFolder(testPath));
298 EXPECT_TRUE(DelFolder(testPath));
299 EXPECT_FALSE(DelFolder(testPath));
300 GTEST_LOG_(INFO) << "FileUtilsTest_DelFolder_001 end";
301 }
302
303 /**
304 * @tc.name: FileUtilsTest_IsFile_001
305 * @tc.desc: Verify the IsFile function.
306 * @tc.type: FUNC
307 * @tc.require: IBDKKD
308 */
309 HWTEST_F(FileUtilsTest, FileUtilsTest_IsFile_001, TestSize.Level1)
310 {
311 GTEST_LOG_(INFO) << "FileUtilsTest_IsFile_001 start";
312
313 std::string testPath = "/data/test/tdd";
314 EXPECT_TRUE(CreateFolder(testPath));
315 std::string fileName = testPath + "/test.txt";
316 auto fd = open(fileName.c_str(), O_RDWR | O_CREAT);
317 ASSERT_GT(fd, 0);
318 close(fd);
319 EXPECT_TRUE(IsFile(fileName));
320 EXPECT_TRUE(DeleteFile(fileName) == 0);
321 EXPECT_FALSE(IsFile(fileName));
322 EXPECT_TRUE(DelFolder(testPath));
323 GTEST_LOG_(INFO) << "FileUtilsTest_IsFile_001 end";
324 }
325
326 /**
327 * @tc.name: FileUtilsTest_TravelChmod_001
328 * @tc.desc: Verify the IsFile function.
329 * @tc.type: FUNC
330 * @tc.require: IBDKKD
331 */
332 HWTEST_F(FileUtilsTest, FileUtilsTest_TravelChmod_001, TestSize.Level1)
333 {
334 GTEST_LOG_(INFO) << "FileUtilsTest_TravelChmod_001 start";
335 std::string basePath = "/data/test/tdd";
336 std::string testPath = basePath + "/fold";
337 EXPECT_TRUE(CreateFolder(testPath));
338 std::string fileName = basePath + "/test.txt";
339 auto fd = open(fileName.c_str(), O_RDWR | O_CREAT);
340 ASSERT_GT(fd, 0);
341 close(fd);
342
343 mode_t mode = 0777;
344 TravelChmod(basePath, mode);
345 TravelChmod(fileName, mode);
346 EXPECT_TRUE(DeleteFile(basePath) == 0);
347 EXPECT_TRUE(DelFolder(basePath));
348 TravelChmod(basePath, mode);
349 GTEST_LOG_(INFO) << "FileUtilsTest_TravelChmod_001 end";
350 }
351
352 /**
353 * @tc.name: FileUtilsTest_IsTempFolder_001
354 * @tc.desc: Verify the IsTempFolder function.
355 * @tc.type: FUNC
356 * @tc.require: IBDKKD
357 */
358 HWTEST_F(FileUtilsTest, FileUtilsTest_IsTempFolder_001, TestSize.Level1)
359 {
360 GTEST_LOG_(INFO) << "FileUtilsTest_IsTempFolder_001 start";
361 std::string basePath = "/data/test/tdd/fold";
362 std::string sub = "fold";
363 std::string sub2 = "temp";
364 EXPECT_TRUE(CreateFolder(basePath));
365 EXPECT_TRUE(IsTempFolder(basePath, sub));
366 EXPECT_FALSE(IsTempFolder(basePath, sub2));
367 EXPECT_TRUE(DeleteFile(basePath) == 0);
368 EXPECT_TRUE(DelFolder(basePath));
369 GTEST_LOG_(INFO) << "FileUtilsTest_IsTempFolder_001 end";
370 }
371
372 /**
373 * @tc.name: FileUtilsTest_DelTemp_001
374 * @tc.desc: Verify the DelTemp function.
375 * @tc.type: FUNC
376 * @tc.require: IBDKKD
377 */
378 HWTEST_F(FileUtilsTest, FileUtilsTest_DelTemp_001, TestSize.Level1)
379 {
380 GTEST_LOG_(INFO) << "FileUtilsTest_DelTemp_001 start";
381 std::string basePath = "/data/test/tdd";
382 std::string subPath1 = basePath + "/fold";
383 std::string subPath2 = basePath + "/simple-mtpfs";
384 EXPECT_TRUE(CreateFolder(subPath1));
385 EXPECT_TRUE(CreateFolder(subPath2));
386 DelTemp(basePath);
387 EXPECT_TRUE(IsDir(subPath1));
388 EXPECT_FALSE(IsDir(subPath2));
389 EXPECT_TRUE(DeleteFile(basePath) == 0);
390 EXPECT_TRUE(DelFolder(basePath));
391 GTEST_LOG_(INFO) << "FileUtilsTest_DelTemp_001 end";
392 }
393
394 /**
395 * @tc.name: FileUtilsTest_KillProcess_001
396 * @tc.desc: Verify the KillProcess function.
397 * @tc.type: FUNC
398 * @tc.require: IBDKKD
399 */
400 HWTEST_F(FileUtilsTest, FileUtilsTest_KillProcess_001, TestSize.Level1)
401 {
402 GTEST_LOG_(INFO) << "FileUtilsTest_KillProcess_001 start";
403 std::vector<ProcessInfo> processList;
404 std::vector<ProcessInfo> killFailList;
405 KillProcess(processList, killFailList);
406
407 ProcessInfo info1 {.name = "test1", .pid = 65300 };
408 ProcessInfo info2 {.name = "test2", .pid = 65301 };
409 processList.push_back(info1);
410 processList.push_back(info2);
411
412 KillProcess(processList, killFailList);
413 EXPECT_EQ(killFailList.size(), 0);
414 GTEST_LOG_(INFO) << "FileUtilsTest_KillProcess_001 end";
415 }
416
417 /**
418 * @tc.name: FileUtilsTest_ForkExecWithExit_001
419 * @tc.desc: Verify the ForkExecWithExit function.
420 * @tc.type: FUNC
421 * @tc.require: IBDKKD
422 */
423 HWTEST_F(FileUtilsTest, FileUtilsTest_ForkExecWithExit_001, TestSize.Level1)
424 {
425 GTEST_LOG_(INFO) << "FileUtilsTest_ForkExecWithExit_001 start";
426
427 std::vector<std::string> cmd = {
428 "fsck.ntfs",
429 "/dev/block/vol-1-7",
430 };
431
432 EXPECT_EQ(ForkExecWithExit(cmd), E_WEXITSTATUS);
433 GTEST_LOG_(INFO) << "FileUtilsTest_ForkExecWithExit_001 end";
434 }
435
436 /**
437 * @tc.name: FileUtilsTest_IsFuse_001
438 * @tc.desc: Verify the IsUsbFuse function basic functionality.
439 * @tc.type: FUNC
440 * @tc.require: AR000GK4HB
441 */
442 HWTEST_F(FileUtilsTest, FileUtilsTest_IsFuse_001, TestSize.Level1)
443 {
444 GTEST_LOG_(INFO) << "FileUtilsTest_IsFuse_001 start";
445
446 // Test the IsUsbFuse function basic functionality
447 bool result = IsUsbFuse();
448
449 EXPECT_FALSE(result);
450
451 GTEST_LOG_(INFO) << "FileUtilsTest_IsFuse_001 end";
452 }
453
454 /**
455 * @tc.name: FileUtilsTest_ForkExec_001
456 * @tc.desc: Verify the ForkExec function.
457 * @tc.type: FUNC
458 * @tc.require: IBDKKD
459 */
460 HWTEST_F(FileUtilsTest, FileUtilsTest_ForkExec_001, TestSize.Level1)
461 {
462 GTEST_LOG_(INFO) << "FileUtilsTest_ForkExec_001 start";
463 std::vector<std::string> cmd = {
464 "ls",
465 "/dev/block/",
466 };
467 std::vector<std::string> output;
468 EXPECT_EQ(ForkExec(cmd, &output), E_OK);
469 GTEST_LOG_(INFO) << "FileUtilsTest_ForkExec_001 end";
470 }
471
472 /**
473 * @tc.name: FileUtilsTest_RedirectStdToPipe_001
474 * @tc.desc: Verify the RedirectStdToPipe function.
475 * @tc.type: FUNC
476 * @tc.require: IBDKKD
477 */
478 HWTEST_F(FileUtilsTest, FileUtilsTest_RedirectStdToPipe_001, TestSize.Level1)
479 {
480 GTEST_LOG_(INFO) << "FileUtilsTest_RedirectStdToPipe_001 start";
481 int logpipe[2] = {};
482 size_t len = 0;
483 int res = RedirectStdToPipe(logpipe, len);
484 EXPECT_EQ(res, E_ERR);
485
486 logpipe[0] = NOT_EXIST_FD_1;
487 logpipe[1] = NOT_EXIST_FD_2;
488 res = RedirectStdToPipe(logpipe, len);
489 EXPECT_EQ(res, E_ERR);
490
491 len = sizeof(logpipe);
492 res = RedirectStdToPipe(logpipe, len);
493 EXPECT_EQ(res, E_ERR);
494 GTEST_LOG_(INFO) << "FileUtilsTest_RedirectStdToPipe_001 end";
495 }
496 } // STORAGE_DAEMON
497 } // OHOS
498