1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "BackupManagerTest"
17 #include <condition_variable>
18 #include <gtest/gtest.h>
19 #include <vector>
20 
21 #include "dev_manager.h"
22 #include "file_ex.h"
23 #include "store_manager.h"
24 #include "store_util.h"
25 #include "sys/stat.h"
26 #include "types.h"
27 namespace OHOS::Test {
28 using namespace testing::ext;
29 using namespace OHOS::DistributedKv;
30 class BackupManagerTest : public testing::Test {
31 public:
32     static void SetUpTestCase(void);
33     static void TearDownTestCase(void);
34     void SetUp();
35     void TearDown();
36     Status DeleteBackUpFiles(std::shared_ptr<SingleKvStore> kvStore, std::string baseDir, StoreId storeId);
37     void MkdirPath(std::string baseDir, AppId appId, StoreId storeId);
38 
39     std::shared_ptr<SingleKvStore> CreateKVStore(std::string storeIdTest, std::string appIdTest, std::string baseDir,
40         KvStoreType type, bool encrypt);
41     std::shared_ptr<SingleKvStore> kvStore_;
42 };
43 
SetUpTestCase(void)44 void BackupManagerTest::SetUpTestCase(void)
45 {
46     std::string baseDir = "/data/service/el1/public/database/BackupManagerTest";
47     mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
48     mkdir((baseDir + "/key").c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
49 }
50 
TearDownTestCase(void)51 void BackupManagerTest::TearDownTestCase(void)
52 {
53     std::string baseDir = "/data/service/el1/public/database/BackupManagerTest";
54     StoreManager::GetInstance().Delete({ "BackupManagerTest" }, { "SingleKVStore" }, baseDir);
55 
56     (void)remove("/data/service/el1/public/database/BackupManagerTest/key");
57     (void)remove("/data/service/el1/public/database/BackupManagerTest/kvdb");
58     (void)remove("/data/service/el1/public/database/BackupManagerTest");
59 }
60 
SetUp(void)61 void BackupManagerTest::SetUp(void)
62 {
63     std::string baseDir = "/data/service/el1/public/database/BackupManagerTest";
64     kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", baseDir, SINGLE_VERSION, false);
65     if (kvStore_ == nullptr) {
66         kvStore_ = CreateKVStore("SingleKVStore", "BackupManagerTest", baseDir, SINGLE_VERSION, false);
67     }
68     ASSERT_NE(kvStore_, nullptr);
69 }
70 
TearDown(void)71 void BackupManagerTest::TearDown(void)
72 {
73     AppId appId = { "BackupManagerTest" };
74     StoreId storeId = { "SingleKVStore" };
75     std::string baseDir = "/data/service/el1/public/database/BackupManagerTest";
76     auto status = DeleteBackUpFiles(kvStore_, baseDir, storeId);
77     ASSERT_EQ(status, SUCCESS);
78     kvStore_ = nullptr;
79     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
80     ASSERT_EQ(status, SUCCESS);
81     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
82     ASSERT_EQ(status, SUCCESS);
83 }
84 
CreateKVStore(std::string storeIdTest,std::string appIdTest,std::string baseDir,KvStoreType type,bool encrypt)85 std::shared_ptr<SingleKvStore> BackupManagerTest::CreateKVStore(std::string storeIdTest, std::string appIdTest,
86     std::string baseDir, KvStoreType type, bool encrypt)
87 {
88     Options options;
89     options.kvStoreType = type;
90     options.securityLevel = S1;
91     options.encrypt = encrypt;
92     options.area = EL1;
93     options.baseDir = baseDir;
94 
95     AppId appId = { appIdTest };
96     StoreId storeId = { storeIdTest };
97     Status status = StoreManager::GetInstance().Delete(appId, storeId, options.baseDir);
98     return StoreManager::GetInstance().GetKVStore(appId, storeId, options, status);
99 }
DeleteBackUpFiles(std::shared_ptr<SingleKvStore> kvStore,string baseDir,StoreId storeId)100 Status BackupManagerTest::DeleteBackUpFiles(std::shared_ptr<SingleKvStore> kvStore, string baseDir, StoreId storeId)
101 {
102     std::vector<string> backupnames;
103     auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId);
104     for (auto file : files) {
105         auto filename = file.name.substr(0, file.name.length() - 4);
106         backupnames.emplace_back(filename);
107     }
108     if (backupnames.empty()) {
109         return SUCCESS;
110     }
111     std::map<std::string, OHOS::DistributedKv::Status> results;
112     return kvStore->DeleteBackup(backupnames, baseDir, results);
113 }
MkdirPath(std::string baseDir,AppId appId,StoreId storeId)114 void BackupManagerTest::MkdirPath(std::string baseDir, AppId appId, StoreId storeId)
115 {
116     mkdir(baseDir.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
117     mkdir((baseDir + "/key").c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
118     mkdir((baseDir + "/kvdb").c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
119     mkdir((baseDir + "/kvdb/backup").c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
120 
121     std::string backUpToPath = { baseDir + "/kvdb/backup/" + storeId.storeId };
122     mkdir(backUpToPath.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
123 
124     std::string backUpFile = backUpToPath + "/" + "testbackup.bak";
125     auto fl = OHOS::DistributedKv::StoreUtil::CreateFile(backUpFile);
126     ASSERT_EQ(fl, true);
127 }
128 
129 /**
130 * @tc.name: BackUp
131 * @tc.desc: the kvstore back up
132 * @tc.type: FUNC
133 * @tc.require:
134 * @tc.author: Wang Kai
135 */
136 HWTEST_F(BackupManagerTest, BackUp, TestSize.Level0)
137 {
138     ASSERT_NE(kvStore_, nullptr);
139     auto baseDir = "/data/service/el1/public/database/BackupManagerTest";
140     auto status = kvStore_->Backup("testbackup", baseDir);
141     ASSERT_EQ(status, SUCCESS);
142 }
143 /**
144 * @tc.name: BackUpInvalidArguments
145 * @tc.desc: the kvstore back up and the arguments is invalid
146 * @tc.type: FUNC
147 * @tc.require:
148 * @tc.author: Wang Kai
149 */
150 HWTEST_F(BackupManagerTest, BackUpInvalidArguments, TestSize.Level0)
151 {
152     ASSERT_NE(kvStore_, nullptr);
153     auto baseDir = "";
154     auto baseDir1 = "/data/service/el1/public/database/BackupManagerTest";
155     auto status = kvStore_->Backup("testbackup", baseDir);
156     ASSERT_EQ(status, INVALID_ARGUMENT);
157     status = kvStore_->Backup("", baseDir);
158     ASSERT_EQ(status, INVALID_ARGUMENT);
159     status = kvStore_->Backup("autoBackup", baseDir1);
160     ASSERT_EQ(status, INVALID_ARGUMENT);
161 }
162 /**
163 * @tc.name: BackUpSameFile
164 * @tc.desc: the kvstore back up the same file
165 * @tc.type: FUNC
166 * @tc.require:
167 * @tc.author: Wang Kai
168 */
169 HWTEST_F(BackupManagerTest, BackUpSameFile, TestSize.Level0)
170 {
171     ASSERT_NE(kvStore_, nullptr);
172     auto baseDir = "/data/service/el1/public/database/BackupManagerTest";
173     auto status = kvStore_->Backup("testbackup", baseDir);
174     ASSERT_EQ(status, SUCCESS);
175     status = kvStore_->Backup("testbackup", baseDir);
176     ASSERT_EQ(status, SUCCESS);
177 }
178 /**
179 * @tc.name: ReStore
180 * @tc.desc: the kvstore ReStore
181 * @tc.type: FUNC
182 * @tc.require:
183 * @tc.author: Wang Kai
184 */
185 HWTEST_F(BackupManagerTest, ReStore, TestSize.Level0)
186 {
187     ASSERT_NE(kvStore_, nullptr);
188     auto status = kvStore_->Put({ "Put Test" }, { "Put Value" });
189     ASSERT_EQ(status, SUCCESS);
190     Value value;
191     status = kvStore_->Get({ "Put Test" }, value);
192     ASSERT_EQ(status, SUCCESS);
193     ASSERT_EQ(std::string("Put Value"), value.ToString());
194 
195     auto baseDir = "/data/service/el1/public/database/BackupManagerTest";
196     auto baseDir1 = "";
197     status = kvStore_->Backup("testbackup", baseDir);
198     ASSERT_EQ(status, SUCCESS);
199     status = kvStore_->Delete("Put Test");
200     ASSERT_EQ(status, SUCCESS);
201     status = kvStore_->Restore("testbackup", baseDir);
202     ASSERT_EQ(status, SUCCESS);
203     value = {};
204     status = kvStore_->Get("Put Test", value);
205     ASSERT_EQ(status, SUCCESS);
206     ASSERT_EQ(std::string("Put Value"), value.ToString());
207     status = kvStore_->Restore("testbackup", baseDir1);
208     ASSERT_EQ(status, INVALID_ARGUMENT);
209 }
210 /**
211 * @tc.name: DeleteBackup
212 * @tc.desc: the kvstore DeleteBackup
213 * @tc.type: FUNC
214 * @tc.require:
215 * @tc.author: Wang Kai
216 */
217 HWTEST_F(BackupManagerTest, DeleteBackup, TestSize.Level0)
218 {
219     ASSERT_NE(kvStore_, nullptr);
220     auto baseDir = "/data/service/el1/public/database/BackupManagerTest";
221     std::string file1 = "testbackup1";
222     std::string file2 = "testbackup2";
223     std::string file3 = "testbackup3";
224     std::string file4 = "autoBackup";
225     kvStore_->Backup(file1, baseDir);
226     kvStore_->Backup(file2, baseDir);
227     kvStore_->Backup(file3, baseDir);
228     vector<std::string> files = { file1, file2, file3, file4 };
229     std::map<std::string, OHOS::DistributedKv::Status> results;
230     auto status = kvStore_->DeleteBackup(files, baseDir, results);
231     ASSERT_EQ(status, SUCCESS);
232     status = kvStore_->DeleteBackup(files, "", results);
233     ASSERT_EQ(status, INVALID_ARGUMENT);
234 }
235 /**
236 * @tc.name: RollbackKey
237 * @tc.desc: rollback the key
238 * @tc.type: FUNC
239 * @tc.require:
240 * @tc.author: Wang Kai
241 */
242 HWTEST_F(BackupManagerTest, RollbackKey, TestSize.Level0)
243 {
244     AppId appId = { "BackupManagerTestRollBackKey" };
245     StoreId storeId = { "SingleKVStoreEncrypt" };
246     std::string baseDir = "/data/service/el1/public/database/" + appId.appId;
247     MkdirPath(baseDir, appId, storeId);
248 
249     std::string buildKeyFile = "Prefix_backup_SingleKVStoreEncrypt_testbackup.key";
250     std::string path = { baseDir + "/key/" + buildKeyFile + ".bk" };
251     auto fl = OHOS::DistributedKv::StoreUtil::CreateFile(path);
252     ASSERT_EQ(fl, true);
253 
254     std::string autoBackUpFile = baseDir + "/kvdb/backup/" + storeId.storeId + "/" + "autoBackup.bak";
255     fl = OHOS::DistributedKv::StoreUtil::CreateFile(autoBackUpFile);
256     ASSERT_EQ(fl, true);
257 
258     std::shared_ptr<SingleKvStore> kvStoreEncrypt;
259     kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true);
260     ASSERT_NE(kvStoreEncrypt, nullptr);
261 
262     auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId);
263     auto keyfiles = StoreUtil::GetFiles(baseDir + "/key");
264     bool keyFlag = false;
265     for (auto keyfile : keyfiles) {
266         auto keyfilename = keyfile.name;
267         if (keyfilename == buildKeyFile + ".bk") {
268             keyFlag = true;
269         }
270     }
271     ASSERT_EQ(keyFlag, false);
272 
273     auto status = DeleteBackUpFiles(kvStoreEncrypt, baseDir, storeId);
274     ASSERT_EQ(status, SUCCESS);
275     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
276     ASSERT_EQ(status, SUCCESS);
277     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
278     ASSERT_EQ(status, SUCCESS);
279 }
280 
281 /**
282 * @tc.name: RollbackData
283 * @tc.desc: rollback the data
284 * @tc.type: FUNC
285 * @tc.require:
286 * @tc.author: Wang Kai
287 */
288 HWTEST_F(BackupManagerTest, RollbackData, TestSize.Level0)
289 {
290     AppId appId = { "BackupManagerTestRollBackData" };
291     StoreId storeId = { "SingleKVStoreEncrypt" };
292     std::string baseDir = "/data/service/el1/public/database/" + appId.appId;
293     MkdirPath(baseDir, appId, storeId);
294 
295     std::string buildBackUpFile = baseDir + "/kvdb/backup/" + storeId.storeId + "/" + "testbackup.bak.bk";
296     auto fl = OHOS::DistributedKv::StoreUtil::CreateFile(buildBackUpFile);
297     ASSERT_EQ(fl, true);
298 
299     std::shared_ptr<SingleKvStore> kvStoreEncrypt;
300     kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true);
301     ASSERT_NE(kvStoreEncrypt, nullptr);
302 
303     auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId);
304     bool dataFlag = false;
305     for (auto datafile : files) {
306         auto datafilename = datafile.name;
307         if (datafilename == "testbackup.bak.bk") {
308             dataFlag = true;
309         }
310     }
311     ASSERT_EQ(dataFlag, false);
312 
313     auto status = DeleteBackUpFiles(kvStoreEncrypt, baseDir, storeId);
314     ASSERT_EQ(status, SUCCESS);
315     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
316     ASSERT_EQ(status, SUCCESS);
317     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
318     ASSERT_EQ(status, SUCCESS);
319 }
320 
321 /**
322 * @tc.name: Rollback
323 * @tc.desc: rollback the key
324 * @tc.type: FUNC
325 * @tc.require:
326 * @tc.author: Wang Kai
327 */
328 HWTEST_F(BackupManagerTest, Rollback, TestSize.Level0)
329 {
330     AppId appId = { "BackupManagerTestRollBack" };
331     StoreId storeId = { "SingleKVStoreEncrypt" };
332     std::string baseDir = "/data/service/el1/public/database/" + appId.appId;
333     MkdirPath(baseDir, appId, storeId);
334 
335     std::string buildKeyFile = "Prefix_backup_SingleKVStoreEncrypt_testbackup.key";
336     std::string path = { baseDir + "/key/" + buildKeyFile + ".bk" };
337     auto fl = OHOS::DistributedKv::StoreUtil::CreateFile(path);
338     ASSERT_EQ(fl, true);
339 
340     std::string buildBackUpFile = baseDir + "/kvdb/backup/" + storeId.storeId + "/" + "testbackup.bak.bk";
341     fl = OHOS::DistributedKv::StoreUtil::CreateFile(buildBackUpFile);
342     ASSERT_EQ(fl, true);
343 
344     std::shared_ptr<SingleKvStore> kvStoreEncrypt;
345     kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true);
346     ASSERT_NE(kvStoreEncrypt, nullptr);
347 
348     auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId);
349     auto keyfiles = StoreUtil::GetFiles(baseDir + "/key");
350     bool keyFlag = false;
351     for (auto keyfile : keyfiles) {
352         auto keyfilename = keyfile.name;
353         if (keyfilename == buildKeyFile + ".bk") {
354             keyFlag = true;
355         }
356     }
357     ASSERT_EQ(keyFlag, false);
358 
359     bool dataFlag = false;
360     for (auto datafile : files) {
361         auto datafilename = datafile.name;
362         if (datafilename == "testbackup.bak.bk") {
363             dataFlag = true;
364         }
365     }
366     ASSERT_EQ(dataFlag, false);
367 
368     auto status = DeleteBackUpFiles(kvStoreEncrypt, baseDir, storeId);
369     ASSERT_EQ(status, SUCCESS);
370     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
371     ASSERT_EQ(status, SUCCESS);
372     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
373     ASSERT_EQ(status, SUCCESS);
374 }
375 
376 /**
377 * @tc.name: CleanTmp
378 * @tc.desc: Clean up temporary data
379 * @tc.type: FUNC
380 * @tc.require:
381 * @tc.author: Wang Kai
382 */
383 HWTEST_F(BackupManagerTest, CleanTmp, TestSize.Level0)
384 {
385     AppId appId = { "BackupManagerTestCleanTmp" };
386     StoreId storeId = { "SingleKVStoreEncrypt" };
387     std::string baseDir = "/data/service/el1/public/database/" + appId.appId;
388     MkdirPath(baseDir, appId, storeId);
389 
390     std::string buildKeyFile = "Prefix_backup_SingleKVStoreEncrypt_testbackup.key";
391     std::string path = { baseDir + "/key/" + buildKeyFile };
392     auto fl = OHOS::DistributedKv::StoreUtil::CreateFile(path);
393     ASSERT_EQ(fl, true);
394 
395     std::string buildBackUpFile = baseDir + "/kvdb/backup/" + storeId.storeId + "/" + "testbackup.bak.bk";
396     fl = OHOS::DistributedKv::StoreUtil::CreateFile(buildBackUpFile);
397     ASSERT_EQ(fl, true);
398 
399     std::shared_ptr<SingleKvStore> kvStoreEncrypt;
400     kvStoreEncrypt = CreateKVStore(storeId.storeId, appId.appId, baseDir, SINGLE_VERSION, true);
401     ASSERT_NE(kvStoreEncrypt, nullptr);
402 
403     auto files = StoreUtil::GetFiles(baseDir + "/kvdb/backup/" + storeId.storeId);
404     auto keyfiles = StoreUtil::GetFiles(baseDir + "/key");
405     bool keyFlag = false;
406     for (auto keyfile : keyfiles) {
407         auto keyfilename = keyfile.name;
408         if (keyfilename == buildKeyFile + ".bk") {
409             keyFlag = true;
410         }
411     }
412     ASSERT_EQ(keyFlag, false);
413 
414     bool dataFlag = false;
415     for (auto datafile : files) {
416         auto datafilename = datafile.name;
417         if (datafilename == "testbackup.bak.bk") {
418             dataFlag = true;
419         }
420     }
421     ASSERT_EQ(dataFlag, false);
422 
423     auto status = DeleteBackUpFiles(kvStoreEncrypt, baseDir, storeId);
424     ASSERT_EQ(status, SUCCESS);
425     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
426     ASSERT_EQ(status, SUCCESS);
427     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
428     ASSERT_EQ(status, SUCCESS);
429 }
430 
431 /**
432 * @tc.name: BackUpEncrypt
433 * @tc.desc: Back up an encrypt database and restore
434 * @tc.type: FUNC
435 * @tc.require:
436 * @tc.author: Wang Kai
437 */
438 HWTEST_F(BackupManagerTest, BackUpEntry, TestSize.Level0)
439 {
440     AppId appId = { "BackupManagerTest" };
441     StoreId storeId = { "SingleKVStoreEncrypt" };
442     std::string baseDir = "/data/service/el1/public/database/BackupManagerTest";
443 
444     auto kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", baseDir, SINGLE_VERSION, true);
445     if (kvStoreEncrypt == nullptr) {
446         kvStoreEncrypt = CreateKVStore(storeId.storeId, "BackupManagerTest", baseDir, SINGLE_VERSION, true);
447     }
448     ASSERT_NE(kvStoreEncrypt, nullptr);
449 
450     auto status = kvStoreEncrypt->Put({ "Put Test" }, { "Put Value" });
451     ASSERT_EQ(status, SUCCESS);
452     Value value;
453     status = kvStoreEncrypt->Get({ "Put Test" }, value);
454     ASSERT_EQ(status, SUCCESS);
455     ASSERT_EQ(std::string("Put Value"), value.ToString());
456 
457     status = kvStoreEncrypt->Backup("testbackup", baseDir);
458     ASSERT_EQ(status, SUCCESS);
459     status = kvStoreEncrypt->Delete("Put Test");
460     ASSERT_EQ(status, SUCCESS);
461     status = kvStoreEncrypt->Restore("testbackup", baseDir);
462     ASSERT_EQ(status, SUCCESS);
463     value = {};
464     status = kvStoreEncrypt->Get("Put Test", value);
465     ASSERT_EQ(status, SUCCESS);
466     ASSERT_EQ(std::string("Put Value"), value.ToString());
467 
468     status = DeleteBackUpFiles(kvStoreEncrypt, baseDir, storeId);
469     ASSERT_EQ(status, SUCCESS);
470     status = StoreManager::GetInstance().CloseKVStore(appId, storeId);
471     ASSERT_EQ(status, SUCCESS);
472     status = StoreManager::GetInstance().Delete(appId, storeId, baseDir);
473     ASSERT_EQ(status, SUCCESS);
474 }
475 } // namespace OHOS::Test