• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <chrono>
17 #include <functional>
18 #include <gtest/gtest.h>
19 #include <thread>
20 
21 #include "db_common.h"
22 #include "db_constant.h"
23 #include "distributeddb_tools_unit_test.h"
24 
25 using namespace testing::ext;
26 using namespace DistributedDB;
27 using namespace DistributedDBUnitTest;
28 
29 namespace {
30     const std::string APP_NAME = "app";
31     const std::string USER_NAME = "account0";
32     const int PASSWD_SIZE = 20;
33     const int WAIT_CALLBACK_TIME = 100;
34     KvStoreDelegateManager g_mgr(APP_NAME, USER_NAME);
35     string g_testDir;
36     KvStoreConfig g_config;
37 
38     DBStatus g_kvDelegateStatus = INVALID_ARGS;
39     DBStatus g_kvNbDelegateStatus = INVALID_ARGS;
40     KvStoreDelegate *g_kvDelegatePtr = nullptr;
41     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
42     auto g_kvDelegateCallback = std::bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, std::placeholders::_1,
43         std::placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvDelegatePtr));
44     auto g_kvNbDelegateCallback = std::bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
45         std::placeholders::_1, std::placeholders::_2, std::ref(g_kvNbDelegateStatus), std::ref(g_kvNbDelegatePtr));
46 
GetKvStoreDirectory(const std::string & storeId,int databaseType)47     std::string GetKvStoreDirectory(const std::string &storeId, int databaseType)
48     {
49         std::string identifier = USER_NAME + "-" + APP_NAME + "-" + storeId;
50         std::string hashIdentifierName = DBCommon::TransferHashString(identifier);
51         std::string identifierName = DBCommon::TransferStringToHex(hashIdentifierName);
52         std::string filePath = g_testDir + "/" + identifierName + "/";
53         if (databaseType == DBConstant::DB_TYPE_LOCAL) { // local
54             filePath += (DBConstant::LOCAL_SUB_DIR + "/" + DBConstant::LOCAL_DATABASE_NAME +
55                 DBConstant::SQLITE_DB_EXTENSION);
56         } else if (databaseType == DBConstant::DB_TYPE_SINGLE_VER) { // single ver
57             filePath += (DBConstant::SINGLE_SUB_DIR + "/" + DBConstant::MAINDB_DIR + "/" +
58                 DBConstant::SINGLE_VER_DATA_STORE + DBConstant::SQLITE_DB_EXTENSION);
59         } else if (databaseType == DBConstant::DB_TYPE_MULTI_VER) { // multi ver
60             filePath += (DBConstant::MULTI_SUB_DIR + "/" + DBConstant::MULTI_VER_DATA_STORE +
61                 DBConstant::SQLITE_DB_EXTENSION);
62         } else {
63             filePath = "";
64         }
65 
66         return filePath;
67     }
68 
PutDataIntoDatabase(KvStoreDelegate * kvDelegate,KvStoreNbDelegate * kvNbDelegate)69     int PutDataIntoDatabase(KvStoreDelegate *kvDelegate, KvStoreNbDelegate *kvNbDelegate)
70     {
71         if (kvDelegate == nullptr && kvNbDelegate == nullptr) {
72             return DBStatus::DB_ERROR;
73         }
74         Key key;
75         Value value;
76         DistributedDBToolsUnitTest::GetRandomKeyValue(key);
77         DistributedDBToolsUnitTest::GetRandomKeyValue(value);
78         DBStatus status = OK;
79         if (kvDelegate != nullptr) {
80             status = kvDelegate->Put(key, value);
81             if (status != OK) {
82                 return status;
83             }
84         }
85         if (kvNbDelegate != nullptr) {
86             status = kvNbDelegate->Put(key, value);
87             if (status != OK) {
88                 return status;
89             }
90         }
91         return status;
92     }
93 }
94 
95 class DistributedDBInterfacesDatabaseCorruptTest : public testing::Test {
96 public:
97     static void SetUpTestCase(void);
98     static void TearDownTestCase(void);
99     void SetUp();
100     void TearDown();
101 };
102 
SetUpTestCase(void)103 void DistributedDBInterfacesDatabaseCorruptTest::SetUpTestCase(void)
104 {
105     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
106     g_config.dataDir = g_testDir;
107     g_mgr.SetKvStoreConfig(g_config);
108 }
109 
TearDownTestCase(void)110 void DistributedDBInterfacesDatabaseCorruptTest::TearDownTestCase(void)
111 {
112     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
113         LOGE("rm test db files error!");
114     }
115 }
116 
SetUp(void)117 void DistributedDBInterfacesDatabaseCorruptTest::SetUp(void)
118 {
119     DistributedDBToolsUnitTest::PrintTestCaseInfo();
120     g_kvDelegateStatus = INVALID_ARGS;
121     g_kvDelegatePtr = nullptr;
122 }
123 
TearDown(void)124 void DistributedDBInterfacesDatabaseCorruptTest::TearDown(void)
125 {
126     g_mgr.SetKvStoreCorruptionHandler(nullptr);
127 }
128 
129 /**
130   * @tc.name: DatabaseCorruptionHandleTest001
131   * @tc.desc: Check the corruption detect without setting the corrupt handler.
132   * @tc.type: FUNC
133   * @tc.require: AR000D487C SR000D4878
134   * @tc.author: wangbingquan
135   */
136 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseCorruptionHandleTest001, TestSize.Level3)
137 {
138     /**
139      * @tc.steps: step1. Obtain the kvStore.
140      * @tc.steps: step2. Put one data into the store.
141      * @tc.steps: step3. Close the store.
142      */
143     CipherPassword passwd;
144     Key randomPassword;
145     DistributedDBToolsUnitTest::GetRandomKeyValue(randomPassword, PASSWD_SIZE);
146     int errCode = passwd.SetValue(randomPassword.data(), randomPassword.size());
147     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
148     KvStoreDelegate::Option option = {true, true, false, CipherType::DEFAULT, passwd};
149     g_mgr.GetKvStore("corrupt1", option, g_kvDelegateCallback);
150     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
151     EXPECT_TRUE(g_kvDelegateStatus == OK);
152     ASSERT_EQ(PutDataIntoDatabase(g_kvDelegatePtr, nullptr), OK);
153     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
154     g_kvDelegatePtr = nullptr;
155 
156     /**
157      * @tc.steps: step4. Modify the database file.
158      */
159     std::string filePath = GetKvStoreDirectory("corrupt1", DBConstant::DB_TYPE_LOCAL); // local database.
160     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
161 
162     /**
163      * @tc.steps: step5. Re-obtain the kvStore.
164      * @tc.expected: step5. Returns null kvstore.
165      */
166     g_mgr.GetKvStore("corrupt1", option, g_kvDelegateCallback);
167     ASSERT_TRUE(g_kvDelegatePtr == nullptr);
168     EXPECT_TRUE(g_kvDelegateStatus == INVALID_PASSWD_OR_CORRUPTED_DB);
169     g_mgr.DeleteKvStore("corrupt1");
170 }
171 
172 /**
173   * @tc.name: DatabaseCorruptionHandleTest002
174   * @tc.desc: Get kv store through different parameters for the same storeID.
175   * @tc.type: FUNC
176   * @tc.require: AR000D487C SR000D4878
177   * @tc.author: wangbingquan
178   */
179 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseCorruptionHandleTest002, TestSize.Level1)
180 {
181     /**
182      * @tc.steps: step1. Get the kvStore.
183      * @tc.steps: step2. Put data into the store.
184      * @tc.steps: step3. Close the store.
185      */
186     CipherPassword passwd;
187     Key randomPassword;
188     DistributedDBToolsUnitTest::GetRandomKeyValue(randomPassword, PASSWD_SIZE);
189     int errCode = passwd.SetValue(randomPassword.data(), randomPassword.size());
190     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
191     KvStoreDelegate::Option option = {true, false, false, CipherType::DEFAULT, passwd};
192     KvStoreNbDelegate::Option nbOption = {true, false, false, CipherType::DEFAULT, passwd};
193 
194     g_mgr.GetKvStore("corrupt2", option, g_kvDelegateCallback);
195     g_mgr.GetKvStore("corrupt3", nbOption, g_kvNbDelegateCallback);
196     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
197     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
198     ASSERT_EQ(PutDataIntoDatabase(g_kvDelegatePtr, g_kvNbDelegatePtr), OK);
199     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
200     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
201     g_kvDelegatePtr = nullptr;
202     g_kvNbDelegatePtr = nullptr;
203 
204     /**
205      * @tc.steps: step4. Modify the database file.
206      */
207     std::string filePath = GetKvStoreDirectory("corrupt2", DBConstant::DB_TYPE_MULTI_VER);
208     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
209     filePath = GetKvStoreDirectory("corrupt3", DBConstant::DB_TYPE_SINGLE_VER); // single ver database.
210     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
211     KvStoreCorruptInfo corruptInfo;
212     auto notifier = bind(&KvStoreCorruptInfo::CorruptCallBack, &corruptInfo, std::placeholders::_1,
213         std::placeholders::_2, std::placeholders::_3);
214     g_mgr.SetKvStoreCorruptionHandler(notifier);
215     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_CALLBACK_TIME));
216     /**
217      * @tc.steps: step5. Re-obtain the kvStore.
218      * @tc.expected: step5. Returns null kvstore.
219      */
220     g_mgr.GetKvStore("corrupt2", option, g_kvDelegateCallback);
221     g_mgr.GetKvStore("corrupt3", nbOption, g_kvNbDelegateCallback);
222     ASSERT_TRUE(g_kvDelegateStatus != OK);
223     ASSERT_TRUE(g_kvNbDelegateStatus != OK);
224     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_CALLBACK_TIME));
225     EXPECT_EQ(corruptInfo.GetDatabaseInfoSize(), 2UL); // 2 callback
226     EXPECT_EQ(corruptInfo.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt2"), true);
227     EXPECT_EQ(corruptInfo.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt3"), true);
228     g_mgr.DeleteKvStore("corrupt2");
229     g_mgr.DeleteKvStore("corrupt3");
230 }
231 
232 /**
233   * @tc.name: DatabaseCorruptionHandleTest003
234   * @tc.desc: Test the CloseKvStore Interface and check whether the database file can be closed.
235   * @tc.type: FUNC
236   * @tc.require: AR000D487C SR000D4878
237   * @tc.author: wangbingquan
238   */
239 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseCorruptionHandleTest003, TestSize.Level1)
240 {
241     /**
242      * @tc.steps: step1. Get the kvStore.
243      * @tc.steps: step2. Put data into the store.
244      * @tc.steps: step3. Close the store.
245      */
246     CipherPassword passwd;
247     Key randomPassword;
248     DistributedDBToolsUnitTest::GetRandomKeyValue(randomPassword, PASSWD_SIZE);
249     int errCode = passwd.SetValue(randomPassword.data(), randomPassword.size());
250     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
251     KvStoreDelegate::Option option = {true, true, false, CipherType::DEFAULT, passwd};
252     KvStoreNbDelegate::Option nbOption = {true, false, false, CipherType::DEFAULT, passwd};
253 
254     g_mgr.GetKvStore("corrupt4", option, g_kvDelegateCallback);
255     g_mgr.GetKvStore("corrupt5", nbOption, g_kvNbDelegateCallback);
256     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
257     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
258     ASSERT_EQ(PutDataIntoDatabase(g_kvDelegatePtr, g_kvNbDelegatePtr), OK);
259 
260     /**
261      * @tc.steps: step4. Modify the database file.
262      */
263     std::string filePath = GetKvStoreDirectory("corrupt4", DBConstant::DB_TYPE_LOCAL); // local database.
264     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
265     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath + "-wal");
266     filePath = GetKvStoreDirectory("corrupt5", DBConstant::DB_TYPE_SINGLE_VER); // single ver database.
267     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
268     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath + "-wal");
269     KvStoreCorruptInfo corruptInfo;
270     auto notifier = bind(&KvStoreCorruptInfo::CorruptCallBack, &corruptInfo, std::placeholders::_1,
271         std::placeholders::_2, std::placeholders::_3);
272     g_mgr.SetKvStoreCorruptionHandler(notifier);
273 
274     /**
275      * @tc.steps: step5. Put data into the kvStore.
276      * @tc.expected: step5. The corrupt handler is called twice.
277      */
278     ASSERT_NE(PutDataIntoDatabase(g_kvDelegatePtr, nullptr), OK);
279     ASSERT_NE(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
280     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_CALLBACK_TIME));
281     EXPECT_TRUE(corruptInfo.GetDatabaseInfoSize() >= 2UL); // 2 more callback
282     EXPECT_EQ(corruptInfo.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt4"), true);
283     EXPECT_EQ(corruptInfo.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt5"), true);
284     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
285     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
286     g_kvDelegatePtr = nullptr;
287     g_kvNbDelegatePtr = nullptr;
288     EXPECT_EQ(g_mgr.DeleteKvStore("corrupt4"), OK);
289     EXPECT_EQ(g_mgr.DeleteKvStore("corrupt5"), OK);
290 }
291 
292 /**
293   * @tc.name: DatabaseCorruptionHandleTest004
294   * @tc.desc: Test the DeleteKvStore Interface and check whether the database files can be removed.
295   * @tc.type: FUNC
296   * @tc.require: AR000D487C SR000D4878
297   * @tc.author: wangbingquan
298   */
299 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseCorruptionHandleTest004, TestSize.Level1)
300 {
301     /**
302      * @tc.steps: step1. Get the kvStore.
303      * @tc.steps: step2. Put data into the store.
304      * @tc.steps: step3. Close the store.
305      */
306     CipherPassword passwd;
307     Key randomPassword;
308     DistributedDBToolsUnitTest::GetRandomKeyValue(randomPassword, PASSWD_SIZE);
309     int errCode = passwd.SetValue(randomPassword.data(), randomPassword.size());
310     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
311     KvStoreDelegate::Option option = {true, true, false, CipherType::DEFAULT, passwd};
312     KvStoreNbDelegate::Option nbOption = {true, false, false, CipherType::DEFAULT, passwd};
313 
314     g_mgr.GetKvStore("corrupt6", option, g_kvDelegateCallback);
315     g_mgr.GetKvStore("corrupt7", nbOption, g_kvNbDelegateCallback);
316     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
317     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
318     ASSERT_EQ(PutDataIntoDatabase(g_kvDelegatePtr, g_kvNbDelegatePtr), OK);
319 
320     /**
321      * @tc.steps: step4. Modify the database file.
322      */
323     std::string filePath = GetKvStoreDirectory("corrupt6", DBConstant::DB_TYPE_LOCAL); // local database.
324     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
325     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath + "-wal");
326     filePath = GetKvStoreDirectory("corrupt7", DBConstant::DB_TYPE_SINGLE_VER); // single ver database.
327     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath);
328     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath + "-wal");
329     KvStoreCorruptInfo corruptInfo;
330     KvStoreCorruptInfo corruptInfoNew;
331     auto notifier = bind(&KvStoreCorruptInfo::CorruptCallBack, &corruptInfo, std::placeholders::_1,
332         std::placeholders::_2, std::placeholders::_3);
333     g_mgr.SetKvStoreCorruptionHandler(notifier);
334     auto notifierNew = bind(&KvStoreCorruptInfo::CorruptCallBack, &corruptInfoNew, std::placeholders::_1,
335         std::placeholders::_2, std::placeholders::_3);
336     g_mgr.SetKvStoreCorruptionHandler(notifierNew);
337     /**
338      * @tc.steps: step5. Re-obtain the kvStore.
339      * @tc.expected: step5. Returns null kvstore.
340      */
341     ASSERT_NE(PutDataIntoDatabase(g_kvDelegatePtr, nullptr), OK);
342     ASSERT_NE(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
343     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_CALLBACK_TIME));
344     EXPECT_EQ(corruptInfo.GetDatabaseInfoSize(), 0UL); // no callback
345     EXPECT_TRUE(corruptInfoNew.GetDatabaseInfoSize() >= 2UL); // 2 more callback
346     EXPECT_EQ(corruptInfoNew.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt6"), true);
347     EXPECT_EQ(corruptInfoNew.IsDataBaseCorrupted(APP_NAME, USER_NAME, "corrupt7"), true);
348     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
349     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
350     g_kvDelegatePtr = nullptr;
351     g_kvNbDelegatePtr = nullptr;
352     EXPECT_EQ(g_mgr.DeleteKvStore("corrupt6"), OK);
353     EXPECT_EQ(g_mgr.DeleteKvStore("corrupt7"), OK);
354 }
355 
356 namespace {
357 const uint32_t MODIFY_SIZE = 12; // Modify size is 12 * sizeof(uint32_t);
358 const uint32_t MODIFY_VALUE = 0xF3F3F3F3; // random value, make sure to destroy the page header.
TestDatabaseIntegrityCheckOption(const std::string & storeId,bool isEncrypted)359 void TestDatabaseIntegrityCheckOption(const std::string &storeId, bool isEncrypted)
360 {
361     KvStoreNbDelegate::Option nbOption = {true, false, isEncrypted};
362     nbOption.isNeedIntegrityCheck = false;
363     nbOption.isNeedRmCorruptedDb = false;
364     if (isEncrypted) {
365         Key randPassword;
366         DistributedDBToolsUnitTest::GetRandomKeyValue(randPassword, PASSWD_SIZE);
367         ASSERT_EQ(nbOption.passwd.SetValue(randPassword.data(), randPassword.size()), CipherPassword::ErrorCode::OK);
368     }
369     auto filePath = GetKvStoreDirectory(storeId, DBConstant::DB_TYPE_SINGLE_VER);
370     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
371     ASSERT_EQ(g_kvNbDelegateStatus, OK);
372     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
373     ASSERT_EQ(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
374     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
375 
376     /**
377      * @tc.steps: step1. Modify the database file header to destroy the header and call the GetKvStore.
378      * @tc.expected: step1. Returns null kv store and the errCode is INVALID_PASSWD_OR_CORRUPTED_DB.
379      */
380     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath, 0, MODIFY_SIZE, MODIFY_VALUE);
381     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
382     ASSERT_EQ(g_kvNbDelegateStatus, INVALID_PASSWD_OR_CORRUPTED_DB);
383     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
384 
385     /**
386      * @tc.steps: step2. call the GetKvStore with integrity check option is true.
387      * @tc.expected: step2. Returns null kv store and the errCode is INVALID_PASSWD_OR_CORRUPTED_DB.
388      */
389     nbOption.isNeedIntegrityCheck = true;
390     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
391     ASSERT_EQ(g_kvNbDelegateStatus, INVALID_PASSWD_OR_CORRUPTED_DB);
392     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
393 
394     /**
395      * @tc.steps: step3. call the GetKvStore with remove corrupted database option is true.
396      * @tc.expected: step3. Returns non-null kv store and the errCode is OK.
397      */
398     nbOption.isNeedIntegrityCheck = false;
399     nbOption.isNeedRmCorruptedDb = true;
400     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
401     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
402 
403     ASSERT_EQ(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
404     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
405 
406     /**
407      * @tc.steps: step4. Modify the second page of the database file and Get the kv store.
408      * @tc.expected: step4. Returns non-null kv store and the errCode is OK(GetKvStore skip the check of the page 2).
409      */
410     size_t filePos = isEncrypted ? 1024 : 4096; // 1024 and 4096 is the page size.
411     DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath, filePos, MODIFY_SIZE, MODIFY_VALUE);
412     nbOption.isNeedRmCorruptedDb = false;
413     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
414     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
415     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
416 
417     /**
418      * @tc.steps: step5. Get the kv store with check the integrity.
419      * @tc.expected: step5. Returns null kv store and the errCode is INVALID_PASSWD_OR_CORRUPTED_DB.
420      */
421     nbOption.isNeedIntegrityCheck = true;
422     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
423     ASSERT_EQ(g_kvNbDelegateStatus, INVALID_PASSWD_OR_CORRUPTED_DB);
424     ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
425 
426     /**
427      * @tc.steps: step5. Get the kv store with check the integrity and the rm corrupted database option.
428      * @tc.expected: step5. Returns non-null kv store and the errCode is OK.
429      */
430     nbOption.isNeedRmCorruptedDb = true;
431     g_mgr.GetKvStore(storeId, nbOption, g_kvNbDelegateCallback);
432     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
433     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
434     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
435 }
436 }
437 
438 /**
439   * @tc.name: DatabaseIntegrityCheck001
440   * @tc.desc: Test the integrity check option.
441   * @tc.type: FUNC
442   * @tc.require: AR000D487C SR000D4878
443   * @tc.author: wangbingquan
444   */
445 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseIntegrityCheck001, TestSize.Level2)
446 {
447     LOGI("Begin to check the unencrypted database");
448     TestDatabaseIntegrityCheckOption("integrity_check001", false);
449     std::this_thread::sleep_for(std::chrono::milliseconds(500));
450     LOGI("Begin to check the encrypted database");
451     TestDatabaseIntegrityCheckOption("integrity_check002", true);
452 }
453 
454 /**
455   * @tc.name: DatabaseIntegrityCheck002
456   * @tc.desc: Test the integrity check interface.
457   * @tc.type: FUNC
458   * @tc.require: AR000D487C SR000D4878
459   * @tc.author: wangbingquan
460   */
461 HWTEST_F(DistributedDBInterfacesDatabaseCorruptTest, DatabaseIntegrityCheck002, TestSize.Level1)
462 {
463     CipherPassword passwd;
464     KvStoreNbDelegate::Option nbOption = {true, false, false, CipherType::DEFAULT, passwd};
465     nbOption.isNeedIntegrityCheck = true;
466     nbOption.isNeedRmCorruptedDb = true;
467     auto filePath = GetKvStoreDirectory("integrity021", DBConstant::DB_TYPE_SINGLE_VER);
468     for (uint32_t i = 1; i < 4; i++) {
469         LOGI("%u th test!", i);
470         g_mgr.GetKvStore("integrity021", nbOption, g_kvNbDelegateCallback);
471         ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
472         ASSERT_EQ(g_kvNbDelegatePtr->CheckIntegrity(), OK);
473         ASSERT_EQ(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
474         EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
475         DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath, i * 4096, MODIFY_SIZE, MODIFY_VALUE); // page size 4096
476         g_mgr.GetKvStore("integrity021", nbOption, g_kvNbDelegateCallback);
477         ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
478         EXPECT_EQ(g_kvNbDelegatePtr->CheckIntegrity(), OK);
479         EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
480         EXPECT_EQ(g_mgr.DeleteKvStore("integrity021"), OK);
481     }
482     LOGI("Begin the encrypted check");
483     Key randomPassword;
484     DistributedDBToolsUnitTest::GetRandomKeyValue(randomPassword, PASSWD_SIZE);
485     int errCode = passwd.SetValue(randomPassword.data(), randomPassword.size());
486     ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
487     nbOption = {true, false, true, CipherType::DEFAULT, passwd};
488     nbOption.isNeedIntegrityCheck = true;
489     nbOption.isNeedRmCorruptedDb = true;
490     filePath = GetKvStoreDirectory("integrity022", DBConstant::DB_TYPE_SINGLE_VER);
491     for (uint32_t i = 1; i < 4; i++) {
492         LOGI("%u th test the encrypted database!", i);
493         g_mgr.GetKvStore("integrity022", nbOption, g_kvNbDelegateCallback);
494         ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
495         ASSERT_EQ(g_kvNbDelegatePtr->CheckIntegrity(), OK);
496         ASSERT_EQ(PutDataIntoDatabase(nullptr, g_kvNbDelegatePtr), OK);
497         EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
498         DistributedDBToolsUnitTest::ModifyDatabaseFile(filePath, i * 1024, MODIFY_SIZE, MODIFY_VALUE); // page size 1024
499         g_mgr.GetKvStore("integrity022", nbOption, g_kvNbDelegateCallback);
500         ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
501         EXPECT_EQ(g_kvNbDelegatePtr->CheckIntegrity(), OK);
502         EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
503         EXPECT_EQ(g_mgr.DeleteKvStore("integrity022"), OK);
504     }
505 }