1 /*
2 * Copyright (c) 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 #define LOG_TAG "BackupManagerServiceTest"
16
17 #include <random>
18 #include <thread>
19 #include <gtest/gtest.h>
20 #include "backup_manager.h"
21 #include "backuprule/backup_rule_manager.h"
22 #include "bootstrap.h"
23 #include "crypto/crypto_manager.h"
24 #include "device_manager_adapter.h"
25 #include "directory/directory_manager.h"
26 #include "file_ex.h"
27 #include "ipc_skeleton.h"
28 #include "log_print.h"
29 #include "metadata/meta_data_manager.h"
30 #include "kvstore_meta_manager.h"
31 #include "types.h"
32
33 using namespace testing::ext;
34 using namespace std;
35 using namespace OHOS::DistributedData;
36 namespace OHOS::Test {
37 namespace DistributedDataTest {
38 static constexpr int32_t LOOP_NUM = 2;
39 static constexpr uint32_t SKEY_SIZE = 32;
40 static constexpr int MICROSEC_TO_SEC_TEST = 1000;
41 static constexpr const char *TEST_BACKUP_BUNDLE = "test_backup_bundleName";
42 static constexpr const char *TEST_BACKUP_STOREID = "test_backup_storeId";
43 static constexpr const char *BASE_DIR = "/data/service/el1/public/database/test_backup_bundleName";
44 static constexpr const char *DATA_DIR = "/data/service/el1/public/database/test_backup_bundleName/rdb";
45 static constexpr const char *BACKUP_DIR = "/data/service/el1/public/database/test_backup_bundleName/rdb/backup";
46 static constexpr const char *STORE_DIR =
47 "/data/service/el1/public/database/test_backup_bundleName/rdb/backup/test_backup_storeId";
48 static constexpr const char *AUTO_BACKUP_NAME = "/autoBackup.bak";
49 class BackupManagerServiceTest : public testing::Test {
50 public:
51 class TestRule : public BackupRuleManager::BackupRule {
52 public:
TestRule()53 TestRule()
54 {
55 BackupRuleManager::GetInstance().RegisterPlugin("TestRule", [this]() -> auto {
56 return this;
57 });
58 }
CanBackup()59 bool CanBackup() override
60 {
61 return false;
62 }
63 };
64 static void SetUpTestCase(void);
65 static void TearDownTestCase(void);
66 void SetUp();
67 void TearDown();
68 static std::vector<uint8_t> Random(uint32_t len);
69 static void InitMetaData();
70 static void Exporter(const StoreMetaData &meta, const std::string &backupPath, bool &result);
71 static void ConfigExport(bool flag);
72
73 static StoreMetaData metaData_;
74 static bool isExport_;
75 };
76
77 StoreMetaData BackupManagerServiceTest::metaData_;
78 bool BackupManagerServiceTest::isExport_ = false;
79
SetUpTestCase(void)80 void BackupManagerServiceTest::SetUpTestCase(void)
81 {
82 auto executors = std::make_shared<ExecutorPool>(1, 0);
83 Bootstrap::GetInstance().LoadComponents();
84 Bootstrap::GetInstance().LoadDirectory();
85 Bootstrap::GetInstance().LoadCheckers();
86 DeviceManagerAdapter::GetInstance().Init(executors);
87 DistributedKv::KvStoreMetaManager::GetInstance().BindExecutor(executors);
88 DistributedKv::KvStoreMetaManager::GetInstance().InitMetaParameter();
89 DistributedKv::KvStoreMetaManager::GetInstance().InitMetaListener();
90 InitMetaData();
91 MetaDataManager::GetInstance().DelMeta(metaData_.GetSecretKey(), true);
92 MetaDataManager::GetInstance().DelMeta(metaData_.GetBackupSecretKey(), true);
93 }
94
TearDownTestCase()95 void BackupManagerServiceTest::TearDownTestCase()
96 {
97 }
98
SetUp()99 void BackupManagerServiceTest::SetUp()
100 {
101 }
102
TearDown()103 void BackupManagerServiceTest::TearDown()
104 {
105 }
106
InitMetaData()107 void BackupManagerServiceTest::InitMetaData()
108 {
109 metaData_.deviceId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid;
110 metaData_.bundleName = TEST_BACKUP_BUNDLE;
111 metaData_.appId = TEST_BACKUP_BUNDLE;
112 metaData_.user = "0";
113 metaData_.area = OHOS::DistributedKv::EL1;
114 metaData_.instanceId = 0;
115 metaData_.isAutoSync = true;
116 metaData_.storeType = StoreMetaData::StoreType::STORE_KV_BEGIN;
117 metaData_.storeId = TEST_BACKUP_STOREID;
118 metaData_.dataDir = "/data/service/el1/public/database/" + std::string(TEST_BACKUP_BUNDLE) + "/kvdb";
119 metaData_.securityLevel = OHOS::DistributedKv::SecurityLevel::S2;
120 metaData_.tokenId = IPCSkeleton::GetSelfTokenID();
121 }
122
Random(uint32_t len)123 std::vector<uint8_t> BackupManagerServiceTest::Random(uint32_t len)
124 {
125 std::random_device randomDevice;
126 std::uniform_int_distribution<int> distribution(0, std::numeric_limits<uint8_t>::max());
127 std::vector<uint8_t> key(len);
128 for (uint32_t i = 0; i < len; i++) {
129 key[i] = static_cast<uint8_t>(distribution(randomDevice));
130 }
131 return key;
132 }
133
ConfigExport(bool flag)134 void BackupManagerServiceTest::ConfigExport(bool flag)
135 {
136 isExport_ = flag;
137 }
138
Exporter(const StoreMetaData & meta,const std::string & backupPath,bool & result)139 void BackupManagerServiceTest::Exporter(const StoreMetaData &meta, const std::string &backupPath, bool &result)
140 {
141 (void)meta;
142 result = isExport_;
143 if (isExport_) {
144 std::vector<char> content(TEST_BACKUP_BUNDLE, TEST_BACKUP_BUNDLE + std::strlen(TEST_BACKUP_BUNDLE));
145 result = SaveBufferToFile(backupPath, content);
146 }
147 }
148
149 /**
150 * @tc.name: Init
151 * @tc.desc: Init testing exception branching scenarios.
152 * @tc.type: FUNC
153 * @tc.require:
154 * @tc.author: suoqilong
155 */
156 HWTEST_F(BackupManagerServiceTest, Init, TestSize.Level1)
157 {
158 BackupManagerServiceTest::InitMetaData();
159 StoreMetaData meta1;
160 meta1 = metaData_;
161 meta1.isBackup = false;
162 meta1.isDirty = false;
163 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(StoreMetaData::GetPrefix(
164 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), meta1, true));
165 BackupManager::GetInstance().Init();
166
167 StoreMetaData meta2;
168 meta2 = metaData_;
169 meta2.isBackup = true;
170 meta2.isDirty = false;
171 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(StoreMetaData::GetPrefix(
172 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), meta2, true));
173 BackupManager::GetInstance().Init();
174
175 StoreMetaData meta3;
176 meta3 = metaData_;
177 meta3.isBackup = false;
178 meta3.isDirty = true;
179 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(StoreMetaData::GetPrefix(
180 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), meta3, true));
181 BackupManager::GetInstance().Init();
182
183 StoreMetaData meta4;
184 meta4 = metaData_;
185 meta4.isBackup = true;
186 meta4.isDirty = true;
187 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(StoreMetaData::GetPrefix(
188 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), meta4, true));
189 BackupManager::GetInstance().Init();
190 }
191
192 /**
193 * @tc.name: RegisterExporter
194 * @tc.desc: RegisterExporter testing exception branching scenarios.
195 * @tc.type: FUNC
196 * @tc.require:
197 * @tc.author: suoqilong
198 */
199 HWTEST_F(BackupManagerServiceTest, RegisterExporter, TestSize.Level1)
200 {
201 int32_t type = DistributedKv::KvStoreType::DEVICE_COLLABORATION;
202 BackupManager::Exporter exporter =
203 [](const StoreMetaData &meta, const std::string &backupPath, bool &result)
__anonddd990510202(const StoreMetaData &meta, const std::string &backupPath, bool &result) 204 { result = true; };
205 BackupManager instance;
206 instance.RegisterExporter(type, exporter);
207 EXPECT_FALSE(instance.exporters_[type] == nullptr);
208 instance.RegisterExporter(type, exporter);
209 }
210
211 /**
212 * @tc.name: BackSchedule
213 * @tc.desc: BackSchedule testing exception branching scenarios.
214 * @tc.type: FUNC
215 * @tc.require:
216 * @tc.author: suoqilong
217 */
218 HWTEST_F(BackupManagerServiceTest, BackSchedule, TestSize.Level1)
219 {
220 std::shared_ptr<ExecutorPool> executors = std::make_shared<ExecutorPool>(0, 1);
221 BackupManager instance;
222 instance.executors_ = nullptr;
223 instance.BackSchedule(executors);
224 EXPECT_FALSE(instance.executors_ == nullptr);
225 }
226
227 /**
228 * @tc.name: CanBackup001
229 * @tc.desc: CanBackup testing exception branching scenarios.
230 * @tc.type: FUNC
231 * @tc.require:
232 * @tc.author: suoqilong
233 */
234 HWTEST_F(BackupManagerServiceTest, CanBackup001, TestSize.Level1)
235 {
236 BackupManager instance;
237 instance.backupSuccessTime_ = 0;
238 instance.backupInternal_ = 0;
239 bool status = instance.CanBackup(); // false false
240 EXPECT_TRUE(status);
241
242 instance.backupInternal_ = MICROSEC_TO_SEC_TEST;
243 status = instance.CanBackup(); // true false
244 EXPECT_TRUE(status);
245
246 instance.backupSuccessTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
247 instance.backupInternal_ = 0;
248 status = instance.CanBackup(); // false true
249 EXPECT_TRUE(status);
250
251 instance.backupSuccessTime_ = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
252 instance.backupInternal_ = MICROSEC_TO_SEC_TEST;
253 status = instance.CanBackup(); // true true
254 EXPECT_FALSE(status);
255 }
256
257 /**
258 * @tc.name: CanBackup
259 * @tc.desc: CanBackup testing exception branching scenarios.
260 * @tc.type: FUNC
261 * @tc.require:
262 * @tc.author: suoqilong
263 */
264 HWTEST_F(BackupManagerServiceTest, CanBackup, TestSize.Level1)
265 {
266 BackupManagerServiceTest::TestRule();
267 std::vector<std::string> rule = { "TestRule" };
268 BackupRuleManager::GetInstance().LoadBackupRules(rule);
269 EXPECT_FALSE(BackupRuleManager::GetInstance().CanBackup());
270 bool status = BackupManager::GetInstance().CanBackup();
271 EXPECT_FALSE(status);
272 }
273
274 /**
275 * @tc.name: SaveData
276 * @tc.desc: SaveData testing exception branching scenarios.
277 * @tc.type: FUNC
278 * @tc.require:
279 * @tc.author: suoqilong
280 */
281 HWTEST_F(BackupManagerServiceTest, SaveData, TestSize.Level1)
282 {
283 std::string path = "test";
284 std::string key = "test";
285 std::vector<uint8_t> randomKey = BackupManagerServiceTest::Random(SKEY_SIZE);
286 SecretKeyMetaData secretKey;
287 secretKey.storeType = DistributedKv::KvStoreType::SINGLE_VERSION;
288 secretKey.sKey = randomKey;
289 EXPECT_EQ(secretKey.sKey.size(), SKEY_SIZE);
290 BackupManager::GetInstance().SaveData(path, key, secretKey);
291 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(key, secretKey, true));
292 randomKey.assign(randomKey.size(), 0);
293 }
294
295 /**
296 * @tc.name: GetClearType001
297 * @tc.desc: GetClearType testing exception branching scenarios.
298 * @tc.type: FUNC
299 * @tc.require:
300 * @tc.author: suoqilong
301 */
302 HWTEST_F(BackupManagerServiceTest, GetClearType001, TestSize.Level1)
303 {
304 StoreMetaData meta;
305 MetaDataManager::GetInstance().SaveMeta(StoreMetaData::GetPrefix(
306 { DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid }), metaData_, true);
307 BackupManager::ClearType status = BackupManager::GetInstance().GetClearType(meta);
308 EXPECT_EQ(status, BackupManager::ClearType::DO_NOTHING);
309 }
310
311 /**
312 * @tc.name: GetClearType002
313 * @tc.desc: GetClearType testing exception branching scenarios.
314 * @tc.type: FUNC
315 * @tc.require:
316 * @tc.author: suoqilong
317 */
318 HWTEST_F(BackupManagerServiceTest, GetClearType002, TestSize.Level1)
319 {
320 BackupManagerServiceTest::InitMetaData();
321 StoreMetaData meta;
322 meta = metaData_;
323 EXPECT_TRUE(MetaDataManager::GetInstance().SaveMeta(meta.GetSecretKey(), meta, true));
324
325 SecretKeyMetaData dbPassword;
326 EXPECT_TRUE(MetaDataManager::GetInstance().LoadMeta(meta.GetSecretKey(), dbPassword, true));
327 SecretKeyMetaData backupPassword;
328 EXPECT_FALSE(MetaDataManager::GetInstance().LoadMeta(meta.GetBackupSecretKey(), backupPassword, true));
329 EXPECT_FALSE(dbPassword.sKey != backupPassword.sKey);
330 BackupManager::ClearType status = BackupManager::GetInstance().GetClearType(meta);
331 EXPECT_EQ(status, BackupManager::ClearType::DO_NOTHING);
332 }
333
334 /**
335 * @tc.name: GetPassWordTest001
336 * @tc.desc: get password fail with exception branch
337 * @tc.type: FUNC
338 */
339 HWTEST_F(BackupManagerServiceTest, GetPassWordTest001, TestSize.Level1)
340 {
341 StoreMetaData meta;
342 auto password = BackupManager::GetInstance().GetPassWord(meta);
343 ASSERT_TRUE(password.empty());
344
345 SecretKeyMetaData secretKey;
346 secretKey.area = metaData_.area;
347 secretKey.storeType = metaData_.storeType;
348 auto result = MetaDataManager::GetInstance().SaveMeta(metaData_.GetBackupSecretKey(), secretKey, true);
349 ASSERT_TRUE(result);
350 password = BackupManager::GetInstance().GetPassWord(metaData_);
351 ASSERT_TRUE(password.empty());
352
353 auto key = Random(SKEY_SIZE);
354 ASSERT_FALSE(key.empty());
355 secretKey.sKey = key;
356 secretKey.nonce = key;
357 result = MetaDataManager::GetInstance().SaveMeta(metaData_.GetBackupSecretKey(), secretKey, true);
358 ASSERT_TRUE(result);
359 password = BackupManager::GetInstance().GetPassWord(metaData_);
360 ASSERT_TRUE(password.empty());
361
362 MetaDataManager::GetInstance().DelMeta(metaData_.GetBackupSecretKey(), true);
363 }
364
365 /**
366 * @tc.name: GetPassWordTest002
367 * @tc.desc: get backup password success
368 * @tc.type: FUNC
369 */
370 HWTEST_F(BackupManagerServiceTest, GetPassWordTest002, TestSize.Level1)
371 {
372 auto key = Random(SKEY_SIZE);
373 ASSERT_FALSE(key.empty());
374 CryptoManager::CryptoParams encryptParams;
375 auto encryptKey = CryptoManager::GetInstance().Encrypt(key, encryptParams);
376 ASSERT_FALSE(encryptKey.empty());
377
378 SecretKeyMetaData secretKey;
379 secretKey.area = encryptParams.area;
380 secretKey.storeType = metaData_.storeType;
381 secretKey.sKey = encryptKey;
382 secretKey.nonce = encryptParams.nonce;
383 auto result = MetaDataManager::GetInstance().SaveMeta(metaData_.GetBackupSecretKey(), secretKey, true);
384 ASSERT_TRUE(result);
385
386 for (int32_t index = 0; index < LOOP_NUM; ++index) {
387 auto password = BackupManager::GetInstance().GetPassWord(metaData_);
388 ASSERT_FALSE(password.empty());
389 ASSERT_EQ(password.size(), key.size());
390 for (size_t i = 0; i < key.size(); ++i) {
391 ASSERT_EQ(password[i], key[i]);
392 }
393 }
394
395 MetaDataManager::GetInstance().DelMeta(metaData_.GetBackupSecretKey(), true);
396 }
397
398 /**
399 * @tc.name: DoBackupTest001
400 * @tc.desc: do backup with every condition
401 * @tc.type: FUNC
402 */
403 HWTEST_F(BackupManagerServiceTest, DoBackupTest001, TestSize.Level1)
404 {
405 metaData_.storeType = StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN;
406 mkdir(BASE_DIR, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
407 mkdir(DATA_DIR, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
408 mkdir(BACKUP_DIR, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
409 mkdir(STORE_DIR, (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH));
410
411 auto backupPath = DirectoryManager::GetInstance().GetStoreBackupPath(metaData_);
412 ASSERT_EQ(backupPath, STORE_DIR);
413
414 std::string backupFilePath = backupPath + AUTO_BACKUP_NAME;
415
416 std::shared_ptr<BackupManager> testManager = std::make_shared<BackupManager>();
417 testManager->DoBackup(metaData_);
418 ASSERT_NE(access(backupFilePath.c_str(), F_OK), 0);
419
420 testManager->RegisterExporter(metaData_.storeType, Exporter);
421 ConfigExport(false);
422 testManager->DoBackup(metaData_);
423 ASSERT_NE(access(backupFilePath.c_str(), F_OK), 0);
424
425 ConfigExport(true);
426 metaData_.isEncrypt = false;
427 testManager->DoBackup(metaData_);
428 ASSERT_EQ(access(backupFilePath.c_str(), F_OK), 0);
429 (void)remove(backupFilePath.c_str());
430
431 MetaDataManager::GetInstance().DelMeta(metaData_.GetSecretKey(), true);
432 SecretKeyMetaData secretKey;
433 auto result = MetaDataManager::GetInstance().LoadMeta(metaData_.GetSecretKey(), secretKey, true);
434 ASSERT_FALSE(result);
435
436 metaData_.isEncrypt = true;
437 testManager->DoBackup(metaData_);
438 ASSERT_NE(access(backupFilePath.c_str(), F_OK), 0);
439
440 SecretKeyMetaData backupSecretKey;
441 result = MetaDataManager::GetInstance().LoadMeta(metaData_.GetBackupSecretKey(), backupSecretKey, true);
442 ASSERT_FALSE(result);
443
444 secretKey.area = metaData_.area;
445 secretKey.storeType = metaData_.storeType;
446 auto key = Random(SKEY_SIZE);
447 ASSERT_FALSE(key.empty());
448 secretKey.sKey = key;
449 result = MetaDataManager::GetInstance().SaveMeta(metaData_.GetSecretKey(), secretKey, true);
450 ASSERT_TRUE(result);
451 testManager->DoBackup(metaData_);
452 ASSERT_EQ(access(backupFilePath.c_str(), F_OK), 0);
453 result = MetaDataManager::GetInstance().LoadMeta(metaData_.GetBackupSecretKey(), backupSecretKey, true);
454 ASSERT_TRUE(result);
455
456 MetaDataManager::GetInstance().DelMeta(metaData_.GetSecretKey(), true);
457 MetaDataManager::GetInstance().DelMeta(metaData_.GetBackupSecretKey(), true);
458 (void)remove(backupFilePath.c_str());
459 (void)remove(STORE_DIR);
460 (void)remove(BACKUP_DIR);
461 (void)remove(DATA_DIR);
462 (void)remove(BASE_DIR);
463 }
464
465 /**
466 * @tc.name: IsFileExist
467 * @tc.desc: IsFileExist testing exception branching scenarios.
468 * @tc.type: FUNC
469 * @tc.require:
470 * @tc.author: suoqilong
471 */
472 HWTEST_F(BackupManagerServiceTest, IsFileExist, TestSize.Level1)
473 {
474 std::string path;
475 bool status = BackupManager::GetInstance().IsFileExist(path);
476 EXPECT_FALSE(status);
477 }
478 } // namespace DistributedDataTest
479 } // namespace OHOS::Test