1 /*
2  * Copyright (c) 2022-2024 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 <gmock/gmock.h>
17 #include <gtest/gtest.h>
18 
19 #include "b_error/b_error.h"
20 #include "file_ex.h"
21 #include "test_manager.h"
22 #include "untar_file.h"
23 
24 namespace OHOS::FileManagement::Backup {
25 using namespace std;
26 using namespace testing;
27 
28 class UntarFileTest : public testing::Test {
29 public:
30     static void SetUpTestCase(void);
31     static void TearDownTestCase();
SetUp()32     void SetUp() override {};
TearDown()33     void TearDown() override {};
34 };
35 
SetUpTestCase()36 void UntarFileTest::SetUpTestCase()
37 {
38     GTEST_LOG_(INFO) << "SetUpTestCase enter";
39 }
40 
TearDownTestCase()41 void UntarFileTest::TearDownTestCase()
42 {
43     GTEST_LOG_(INFO) << "TearDownTestCase enter";
44 }
45 
ClearCache()46 static void ClearCache()
47 {
48     UntarFile::GetInstance().rootPath_.clear();
49     UntarFile::GetInstance().tarFileSize_ = 0;
50     UntarFile::GetInstance().tarFileBlockCnt_ = 0;
51     UntarFile::GetInstance().pos_ = 0;
52     UntarFile::GetInstance().readCnt_ = 0;
53     if (UntarFile::GetInstance().tarFilePtr_ != nullptr) {
54         fclose(UntarFile::GetInstance().tarFilePtr_);
55         UntarFile::GetInstance().tarFilePtr_ = nullptr;
56     }
57     TarFile::GetInstance().fileCount_ = 0;
58     TarFile::GetInstance().tarMap_.clear();
59     TarFile::GetInstance().rootPath_.clear();
60     TarFile::GetInstance().packagePath_.clear();
61     TarFile::GetInstance().baseTarName_.clear();
62     TarFile::GetInstance().tarFileName_.clear();
63     TarFile::GetInstance().ioBuffer_.clear();
64     TarFile::GetInstance().currentTarName_.clear();
65     TarFile::GetInstance().currentTarFileSize_ = 0;
66     TarFile::GetInstance().tarFileCount_ = 0;
67     TarFile::GetInstance().currentFileName_.clear();
68     if (TarFile::GetInstance().currentTarFile_ != nullptr) {
69         fclose(TarFile::GetInstance().currentTarFile_);
70         TarFile::GetInstance().currentTarFile_ = nullptr;
71     }
72 }
73 
74 /**
75  * @tc.number: SUB_Untar_File_GetInstance_0100
76  * @tc.name: SUB_Untar_File_GetInstance_0100
77  * @tc.desc: 测试 GetInstance 接口
78  * @tc.size: MEDIUM
79  * @tc.type: FUNC
80  * @tc.level Level 1
81  * @tc.require: I6F3GV
82  */
83 HWTEST_F(UntarFileTest, SUB_Untar_File_GetInstance_0100, testing::ext::TestSize.Level1)
84 {
85     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_GetInstance_0100";
86     try {
87         UntarFile::GetInstance();
88         EXPECT_TRUE(true);
89     } catch (...) {
90         EXPECT_TRUE(false);
91         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
92     }
93     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_GetInstance_0100";
94 }
95 
96 /**
97  * @tc.number: SUB_Untar_File_UnPacket_0100
98  * @tc.name: SUB_Untar_File_UnPacket_0100
99  * @tc.desc: 测试 UnPacket 接口
100  * @tc.size: MEDIUM
101  * @tc.type: FUNC
102  * @tc.level Level 1
103  * @tc.require: I6F3GV
104  */
105 HWTEST_F(UntarFileTest, SUB_Untar_File_UnPacket_0100, testing::ext::TestSize.Level1)
106 {
107     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_UnPacket_0100";
108     try {
109         string tarFile("");
110         string rootPath("");
111         auto [ret, fileInfos, errFileInfos] = UntarFile::GetInstance().UnPacket(tarFile, rootPath);
112         EXPECT_EQ(ret, ENOENT);
113         ClearCache();
114     } catch (...) {
115         EXPECT_TRUE(false);
116         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
117     }
118     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_UnPacket_0100";
119 }
120 
121 /**
122  * @tc.number: SUB_Untar_File_UnPacket_0200
123  * @tc.name: SUB_Untar_File_UnPacket_0200
124  * @tc.desc: 测试 UnPacket 接口
125  * @tc.size: MEDIUM
126  * @tc.type: FUNC
127  * @tc.level Level 1
128  * @tc.require: I6F3GV
129  */
130 HWTEST_F(UntarFileTest, SUB_Untar_File_UnPacket_0200, testing::ext::TestSize.Level1)
131 {
132     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_UnPacket_0200";
133     try {
134         // 预置文件和目录
135         TestManager tm("SUB_Untar_File_UnPacket_0200");
136         string root = tm.GetRootDirCurTest();
137         string testDir = root + "/testdir";
138         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
139             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
140             throw BError(errno);
141         }
142         string aFile = testDir + "/a.txt";
143         string bFile = testDir + "/b.txt";
144         SaveStringToFile(aFile, "hello");
145         SaveStringToFile(bFile, "world");
146 
147         string tarFile = root + "test.tar";
148         string cmd = "tar -cvf " + tarFile + " " + testDir;
149         string rootPath(root);
150         if (system(cmd.c_str()) != 0) {
151             GTEST_LOG_(INFO) << " execute tar failure, errno :" << errno;
152             throw BError(errno);
153         }
154         auto [ret, fileInfos, errFileInfos] = UntarFile::GetInstance().UnPacket(tarFile, rootPath);
155         EXPECT_EQ(ret, 0);
156         ClearCache();
157     } catch (...) {
158         EXPECT_TRUE(false);
159         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
160     }
161     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_UnPacket_0200";
162 }
163 
164 /**
165  * @tc.number: SUB_Untar_File_UnPacket_0300
166  * @tc.name: SUB_Untar_File_UnPacket_0300
167  * @tc.desc: 测试 UnPacket 接口
168  * @tc.size: MEDIUM
169  * @tc.type: FUNC
170  * @tc.level Level 1
171  * @tc.require: I6F3GV
172  */
173 HWTEST_F(UntarFileTest, SUB_Untar_File_UnPacket_0300, testing::ext::TestSize.Level1)
174 {
175     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_UnPacket_0300";
176     try {
177         // 预置文件和目录
178         TestManager tm("SUB_Untar_File_UnPacket_0300");
179         string root = tm.GetRootDirCurTest();
180         string testDir = root + "/testdir";
181         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
182             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
183             throw BError(errno);
184         }
185         string aFile = testDir + "/a.txt";
186         SaveStringToFile(aFile, "hello");
187 
188         string rootPath(root);
189         auto [ret, fileInfos, errFileInfos] = UntarFile::GetInstance().UnPacket(aFile, rootPath);
190         EXPECT_EQ(ret, 0);
191         ClearCache();
192     } catch (...) {
193         EXPECT_TRUE(false);
194         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
195     }
196     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_UnPacket_0300";
197 }
198 
199 /**
200  * @tc.number: SUB_Untar_File_UnPacket_0400
201  * @tc.name: SUB_Untar_File_UnPacket_0400
202  * @tc.desc: 测试 UnPacket 接口
203  * @tc.size: MEDIUM
204  * @tc.type: FUNC
205  * @tc.level Level 1
206  * @tc.require: I6F3GV
207  */
208 HWTEST_F(UntarFileTest, SUB_Untar_File_UnPacket_0400, testing::ext::TestSize.Level1)
209 {
210     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_UnPacket_0400";
211     try {
212         // 预置文件和目录
213         TestManager tm("SUB_Untar_File_UnPacket_0400");
214         string root = tm.GetRootDirCurTest();
215         string testDir = root + "/testdir";
216         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
217             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
218             throw BError(errno);
219         }
220         string tarFile = root + "test.tar";
221         string cmd = "tar -cvf " + tarFile + " " + testDir;
222         if (system(cmd.c_str()) != 0) {
223             GTEST_LOG_(INFO) << " execute tar failure, errno :" << errno;
224             throw BError(errno);
225         }
226 
227         string rootPath(root);
228         auto [ret, fileInfos, errFileInfos] = UntarFile::GetInstance().UnPacket(tarFile, rootPath);
229         EXPECT_EQ(ret, 0);
230         ClearCache();
231     } catch (...) {
232         EXPECT_TRUE(false);
233         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
234     }
235     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_UnPacket_0400";
236 }
237 
238 /**
239  * @tc.number: SUB_Untar_File_UnPacket_0500
240  * @tc.name: SUB_Untar_File_UnPacket_0500
241  * @tc.desc: 测试 UnPacket 接口
242  * @tc.size: MEDIUM
243  * @tc.type: FUNC
244  * @tc.level Level 1
245  * @tc.require: I6F3GV
246  */
247 HWTEST_F(UntarFileTest, SUB_Untar_File_UnPacket_0500, testing::ext::TestSize.Level1)
248 {
249     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_UnPacket_0500";
250     try {
251         // 预置文件和目录
252         TestManager tm("SUB_Untar_File_UnPacket_0500");
253         string root = tm.GetRootDirCurTest();
254         string testDir = root + "/testdir/";
255         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
256             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
257             throw BError(errno);
258         }
259         string aFile = testDir;
260         string bFile = testDir;
261         // 循环100次,用来构造超长路径和超长文件名
262         for (int i = 0; i < 100; i++) {
263             aFile += "test001/test002/test003/test004/test005/";
264             bFile += "ab";
265         }
266         aFile += "a.txt";
267         bFile += ".txt";
268         SaveStringToFile(aFile, "hello");
269         SaveStringToFile(bFile, "world");
270 
271         string tarFile = root + "/test.0.tar";
272         TarMap tarMap {};
273         vector<string> smallFiles;
274         smallFiles.emplace_back(aFile);
275         smallFiles.emplace_back(bFile);
__anon2ce965e40102(std::string msg, int err) 276         auto reportCb = [](std::string msg, int err) {
277             return;
278         };
279         TarFile::GetInstance().Packet(smallFiles, "test", root, tarMap, reportCb);
280 
281         string rootPath(root);
282         auto [ret, fileInfos, errFileInfos] = UntarFile::GetInstance().UnPacket(tarFile, rootPath);
283         EXPECT_EQ(ret, 0);
284         ClearCache();
285     } catch (...) {
286         EXPECT_TRUE(false);
287         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
288     }
289     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_UnPacket_0500";
290 }
291 
292 /**
293  * @tc.number: SUB_Untar_File_IncrementalUnPacket_0100
294  * @tc.name: SUB_Untar_File_IncrementalUnPacket_0100
295  * @tc.desc: 测试 IncrementalUnPacket 接口
296  * @tc.size: MEDIUM
297  * @tc.type: FUNC
298  * @tc.level Level 1
299  * @tc.require: I6F3GV
300  */
301 HWTEST_F(UntarFileTest, SUB_Untar_File_IncrementalUnPacket_0100, testing::ext::TestSize.Level1)
302 {
303     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_IncrementalUnPacket_0100";
304     try {
305         // 预置文件和目录
306         TestManager tm("SUB_Untar_File_IncrementalUnPacket_0100");
307         string root = tm.GetRootDirCurTest();
308         string testDir = root + "/testdir/";
309         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
310             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
311             throw BError(errno);
312         }
313         string aFile = testDir;
314         string bFile = testDir;
315         // 循环100次,用来构造超长路径和超长文件名
316         for (int i = 0; i < 100; i++) {
317             aFile += "test001/test002/test003/test004/test005/";
318             bFile += "ab";
319         }
320         aFile += "a.txt";
321         bFile += ".txt";
322         SaveStringToFile(aFile, "hello");
323         SaveStringToFile(bFile, "world");
324 
325         TarMap tarMap {};
326         vector<string> smallFiles;
327         smallFiles.emplace_back(aFile);
328         smallFiles.emplace_back(bFile);
__anon2ce965e40202(std::string msg, int err) 329         auto reportCb = [](std::string msg, int err) {
330             return;
331         };
332         TarFile::GetInstance().Packet(smallFiles, "test", root, tarMap, reportCb);
333 
334         string tarFile = root + "/test.0.tar";
335         string rootPath(root);
336         unordered_map<string, struct ReportFileInfo> cloudFiles;
337         auto [ret, fileInfos, errFileInfos] =
338             UntarFile::GetInstance().IncrementalUnPacket(tarFile, rootPath, cloudFiles);
339         EXPECT_EQ(ret, 0);
340         ClearCache();
341     } catch (...) {
342         EXPECT_TRUE(false);
343         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
344     }
345     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_IncrementalUnPacket_0100";
346 }
347 
348 /**
349  * @tc.number: SUB_Untar_File_IncrementalUnPacket_0200
350  * @tc.name: SUB_Untar_File_IncrementalUnPacket_0200
351  * @tc.desc: 测试 IncrementalUnPacket 接口
352  * @tc.size: MEDIUM
353  * @tc.type: FUNC
354  * @tc.level Level 1
355  * @tc.require: I6F3GV
356  */
357 HWTEST_F(UntarFileTest, SUB_Untar_File_IncrementalUnPacket_0200, testing::ext::TestSize.Level1)
358 {
359     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_IncrementalUnPacket_0200";
360     try {
361         // 预置文件和目录
362         TestManager tm("SUB_Untar_File_IncrementalUnPacket_0200");
363         string root = tm.GetRootDirCurTest();
364         // 构造tarFile不存在
365         string tarFile = root + "/empty.0.tar";
366         string rootPath(root);
367         unordered_map<string, struct ReportFileInfo> cloudFiles;
368         auto [ret, fileInfos, errFileInfos] =
369             UntarFile::GetInstance().IncrementalUnPacket(tarFile, rootPath, cloudFiles);
370         EXPECT_EQ(ret, 2); // 错误码2表示找不到文件或路径
371         ClearCache();
372     } catch (...) {
373         EXPECT_TRUE(false);
374         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
375     }
376     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_IncrementalUnPacket_0200";
377 }
378 
379 /**
380  * @tc.number: SUB_Untar_File_IncrementalUnPacket_0300
381  * @tc.name: SUB_Untar_File_IncrementalUnPacket_0300
382  * @tc.desc: 测试 IncrementalUnPacket 接口
383  * @tc.size: MEDIUM
384  * @tc.type: FUNC
385  * @tc.level Level 1
386  * @tc.require: I6F3GV
387  */
388 HWTEST_F(UntarFileTest, SUB_Untar_File_IncrementalUnPacket_0300, testing::ext::TestSize.Level1)
389 {
390     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_IncrementalUnPacket_0300";
391     try {
392         // 预置文件和目录
393         TestManager tm("SUB_Untar_File_IncrementalUnPacket_0300");
394         string root = tm.GetRootDirCurTest();
395         string testDir = root + "/testdir/";
396         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
397             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
398             throw BError(errno);
399         }
400         string aFile = "a.txt";
401         SaveStringToFile(aFile, "hello");
402 
403         TarMap tarMap {};
404         vector<string> smallFiles;
405         smallFiles.emplace_back(aFile);
__anon2ce965e40302(std::string msg, int err) 406         auto reportCb = [](std::string msg, int err) {
407             return;
408         };
409         TarFile::GetInstance().Packet(smallFiles, "test", root, tarMap, reportCb);
410 
411         string tarFile = root + "/test.0.tar";
412         string rootPath(root);
413         unordered_map<string, struct ReportFileInfo> cloudFiles;
414         // 构造文件标头为空
415         FILE *currentTarFile = fopen(tarFile.c_str(), "wb+");
416         fwrite("\0", sizeof(uint8_t), 1, currentTarFile);
417         fclose(currentTarFile);
418         auto [ret, fileInfos, errFileInfos] =
419             UntarFile::GetInstance().IncrementalUnPacket(tarFile, rootPath, cloudFiles);
420         EXPECT_EQ(ret, 0);
421         ClearCache();
422     } catch (...) {
423         EXPECT_TRUE(false);
424         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
425     }
426     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_IncrementalUnPacket_0300";
427 }
428 
429 /**
430  * @tc.number: SUB_Untar_File_IncrementalUnPacket_0400
431  * @tc.name: SUB_Untar_File_IncrementalUnPacket_0400
432  * @tc.desc: 测试 IncrementalUnPacket 接口
433  * @tc.size: MEDIUM
434  * @tc.type: FUNC
435  * @tc.level Level 1
436  * @tc.require: I6F3GV
437  */
438 HWTEST_F(UntarFileTest, SUB_Untar_File_IncrementalUnPacket_0400, testing::ext::TestSize.Level1)
439 {
440     GTEST_LOG_(INFO) << "UntarFileTest-begin SUB_Untar_File_IncrementalUnPacket_0400";
441     try {
442         // 预置文件和目录
443         TestManager tm("SUB_Untar_File_IncrementalUnPacket_0400");
444         string root = tm.GetRootDirCurTest();
445         string testDir = root + "/testdir/";
446         if (mkdir(testDir.data(), S_IRWXU) && errno != EEXIST) {
447             GTEST_LOG_(INFO) << " invoked mkdir failure, errno :" << errno;
448             throw BError(errno);
449         }
450         string aFile = testDir;
451         string bFile = testDir;
452         // 循环100次,用来构造超长路径和超长文件名
453         for (int i = 0; i < 100; i++) {
454             aFile += "test001/test002/test003/test004/test005/";
455             bFile += "ab";
456         }
457         aFile += "a.txt";
458         bFile += ".txt";
459         SaveStringToFile(aFile, "hello");
460         SaveStringToFile(bFile, "world");
461 
462         TarMap tarMap {};
463         vector<string> smallFiles;
464         smallFiles.emplace_back(aFile);
465         smallFiles.emplace_back(bFile);
__anon2ce965e40402(std::string msg, int err) 466         auto reportCb = [](std::string msg, int err) {
467             return;
468         };
469         TarFile::GetInstance().Packet(smallFiles, "test", root, tarMap, reportCb);
470 
471         string tarFile = root + "/test.0.tar";
472         string rootPath(root);
473         unordered_map<string, struct ReportFileInfo> cloudFiles;
474         // 构造文件标头为空
475         FILE *currentTarFile = fopen(tarFile.c_str(), "wb+");
476         fseeko(currentTarFile, 1L, SEEK_SET);
477         fwrite("\0", sizeof(uint8_t), 1, currentTarFile);
478         fclose(currentTarFile);
479         auto [ret, fileInfos, errFileInfos] =
480             UntarFile::GetInstance().IncrementalUnPacket(tarFile, rootPath, cloudFiles);
481         EXPECT_EQ(ret, 0);
482         ClearCache();
483     } catch (...) {
484         EXPECT_TRUE(false);
485         GTEST_LOG_(INFO) << "UntarFileTest-an exception occurred by UntarFile.";
486     }
487     GTEST_LOG_(INFO) << "UntarFileTest-end SUB_Untar_File_IncrementalUnPacket_0400";
488 }
489 
490 } // namespace OHOS::FileManagement::Backup