• 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 #include <gtest/gtest.h>
16 
17 #include <atomic>
18 #include <ctime>
19 #include <cmath>
20 #include <random>
21 #include <chrono>
22 #include <string>
23 #include <thread>
24 #include <mutex>
25 #include <fstream>
26 
27 #include "kv_store_nb_delegate.h"
28 #include "kv_store_delegate_manager.h"
29 #include "distributeddb_nb_test_tools.h"
30 #include "distributeddb_data_generator.h"
31 #include "process_communicator_test_stub.h"
32 
33 using namespace std;
34 using namespace chrono;
35 using namespace testing;
36 #if defined TESTCASES_USING_GTEST_EXT
37 using namespace testing::ext;
38 #endif
39 using namespace std::placeholders;
40 using namespace DistributedDB;
41 using namespace DistributedDBDataGenerator;
42 
43 namespace DistributeddbNbBackup {
44 KvStoreNbDelegate *g_nbBackupDelegate = nullptr;
45 KvStoreDelegateManager *g_manager = nullptr;
46 static std::condition_variable g_backupVar;
47 std::atomic<bool> g_readyFlag(false);
48 
49 DistributedDB::CipherPassword g_passwd1;
50 DistributedDB::CipherPassword g_passwd2;
51 DistributedDB::CipherPassword g_filePasswd1;
52 DistributedDB::CipherPassword g_filePasswd2;
53 
54 class DistributeddbNbBackupTest : public testing::Test {
55 public:
56     static void SetUpTestCase(void);
57     static void TearDownTestCase(void);
58     void SetUp();
59     void TearDown();
60 private:
61 };
62 
SetUpTestCase(void)63 void DistributeddbNbBackupTest::SetUpTestCase(void)
64 {
65     KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(APP_ID_1, USER_ID_1);
66     ASSERT_NE(manager, nullptr);
67     manager->SetProcessLabel("MST", "GetDevicesID");
68     manager->SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
69     delete manager;
70     manager = nullptr;
71     (void)g_passwd1.SetValue(PASSWD_VECTOR_1.data(), PASSWD_VECTOR_1.size());
72     (void)g_passwd2.SetValue(PASSWD_VECTOR_2.data(), PASSWD_VECTOR_2.size());
73     (void)g_filePasswd1.SetValue(FILE_PASSWD_VECTOR_1.data(), FILE_PASSWD_VECTOR_1.size());
74     (void)g_filePasswd2.SetValue(FILE_PASSWD_VECTOR_2.data(), FILE_PASSWD_VECTOR_2.size());
75 }
76 
TearDownTestCase(void)77 void DistributeddbNbBackupTest::TearDownTestCase(void)
78 {
79 }
80 
SetUp(void)81 void DistributeddbNbBackupTest::SetUp(void)
82 {
83     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
84     RemoveDir(exportPath);
85     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
86 
87     UnitTest *test = UnitTest::GetInstance();
88     ASSERT_NE(test, nullptr);
89     const TestInfo *testinfo = test->current_test_info();
90     ASSERT_NE(testinfo, nullptr);
91     string testCaseName = string(testinfo->name());
92     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
93 
94     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
95     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
96 }
97 
TearDown(void)98 void DistributeddbNbBackupTest::TearDown(void)
99 {
100     MST_LOG("TearDown after case.");
101     ASSERT_NE(g_manager, nullptr);
102     EXPECT_TRUE(EndCaseDeleteDB(g_manager, g_nbBackupDelegate, STORE_ID_1, g_option.isMemoryDb));
103 }
104 
105 /*
106  * @tc.name: ExportTest001
107  * @tc.desc: test checking in parameter of filepath of export interface.
108  * @tc.type: FUNC
109  * @tc.require: SR000D4878
110  * @tc.author: fengxiaoyun
111  */
112 HWTEST_F(DistributeddbNbBackupTest, ExportTest001, TestSize.Level1)
113 {
114     /**
115      * @tc.steps: step1. call export interface and the dir of filepath is nonexistent.
116      * @tc.expected: step1. call failed and return INVALID_ARGS.
117      */
118     int fileCount = 0;
119     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
120     const std::string filePath = exportPath + "/bkpDB.bin";
121     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), INVALID_ARGS);
122 
123     /**
124      * @tc.steps: step2. call export interface, the filepath is absolute path and legal then check file number.
125      * @tc.expected: step2. call successfully and the file number is 1.
126      */
127     SetDir(exportPath);
128     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
129     CheckFileNumber(exportPath, fileCount);
130     EXPECT_EQ(fileCount, 1);
131     RemoveDir(exportPath);
132     RemoveDatabaseDirectory(exportPath);
133 
134     /**
135      * @tc.steps: step3. call export interface to export data and the dir of filepath is no r,w right.
136      * @tc.expected: step3. call failed return INVALID_ARGS.
137      */
138 #ifdef RUNNING_ON_SIMULATED_ENV
139     const std::string noRightPath = "../noright";
140     const int authRight = 0111;
141     SetDir(noRightPath, authRight);
142     std::string filePath2 = noRightPath + "/bkpDB.bin";
143     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), NO_PERMISSION);
144     RemoveDatabaseDirectory(noRightPath);
145 #endif
146     /**
147      * @tc.steps: step4. call export interface, the filepath is relative path and legal then check file number.
148      * @tc.expected: step4. call successfully and the file number is 1.
149      */
150     const std::string exportPath2 = "../export";
151     SetDir(exportPath2);
152     const std::string filePath3 = exportPath2 + "/bkpDB.bin";
153     EXPECT_EQ(g_nbBackupDelegate->Export(filePath3, NULL_PASSWD), OK);
154     CheckFileNumber(exportPath2, fileCount);
155     EXPECT_EQ(fileCount, 1);
156     RemoveDir(exportPath2);
157 }
158 
159 /*
160  * @tc.name: ExportTest 002
161  * @tc.desc: Verify that the export interface will return FILE_ALREADY_EXISTED if the export file has been exist and
162  * the memory db doesn't support export.
163  * @tc.type: FUNC
164  * @tc.require: SR000D4878
165  * @tc.author: fengxiaoyun
166  */
167 HWTEST_F(DistributeddbNbBackupTest, ExportTest002, TestSize.Level1)
168 {
169     /**
170      * @tc.steps: step1. call export interface and the dir of filepath is legal then check file number.
171      * @tc.expected: step1. call successfully and the file number of filepath is 1.
172      */
173     int fileCount = 0;
174     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
175     SetDir(exportPath);
176     std::string filePath = exportPath + "/bkpDB.bin";
177     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
178     CheckFileNumber(exportPath, fileCount);
179     EXPECT_EQ(fileCount, 1);
180 
181     /**
182      * @tc.steps: step2. call export interface and the directory of file is existent.
183      * @tc.expected: step2. call failed and return FILE_ALREADY_EXISTED.
184      */
185     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == FILE_ALREADY_EXISTED);
186     CheckFileNumber(exportPath, fileCount);
187     EXPECT_EQ(fileCount, 1); // the number of files is 1.
188 
189     /**
190      * @tc.steps: step3. create memory db and call export interface.
191      * @tc.expected: step3. call failed and return NOT_SUPPORT.
192      */
193     KvStoreNbDelegate *delegate = nullptr;
194     KvStoreDelegateManager *manager = nullptr;
195     Option option;
196     option.isMemoryDb = true;
197     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, option);
198     ASSERT_TRUE(manager != nullptr && delegate != nullptr);
199     filePath = exportPath + "/bkpDB1.bin";
200     EXPECT_TRUE(delegate->Export(filePath, NULL_PASSWD) == NOT_SUPPORT);
201     EXPECT_EQ((manager->CloseKvStore(delegate)), OK);
202 
203     /**
204      * @tc.steps: step4. call export interface when there is unclosed resultset and check the number of files.
205      * @tc.expected: step4. call successfully and the number of files is 2.
206      */
207     KvStoreResultSet *resultSet;
208     EXPECT_EQ(g_nbBackupDelegate->GetEntries(KEY_EMPTY, resultSet), OK);
209     filePath = exportPath + "/bkpDB2.bin";
210     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
211     CheckFileNumber(exportPath, fileCount);
212     EXPECT_EQ(fileCount, 2); // the number of files is 2.
213     EXPECT_EQ(g_nbBackupDelegate->CloseResultSet(resultSet), OK);
214     RemoveDir(exportPath);
215     delete manager;
216     manager = nullptr;
217 }
218 
219 /*
220  * @tc.name: ExportTest 003
221  * @tc.desc: Verify that the export interface will return busy when the import hasn't completed.
222  * @tc.type: FUNC
223  * @tc.require: SR000D4878
224  * @tc.author: fengxiaoyun
225  */
226 HWTEST_F(DistributeddbNbBackupTest, ExportTest003, TestSize.Level2)
227 {
228     std::vector<DistributedDB::Entry> entriesBatch;
229     std::vector<DistributedDB::Key> allKeys;
230     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
231     for (vector<Entry>::iterator iter = entriesBatch.begin(); iter != entriesBatch.end(); iter++) {
232         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
233     }
234     int fileCount = 0;
235     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
236     SetDir(exportPath);
237     std::string filePath = exportPath + "/bkpDB.bin";
238     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
239     CheckFileNumber(exportPath, fileCount);
240     EXPECT_EQ(fileCount, 1);
241 
242     /**
243      * @tc.steps: step1. call import interface to import the file that prepared in advance.
244      * @tc.expected: step1. call successfully.
245      */
246     g_readyFlag.store(false);
__anonced11ad80102() 247     thread subThread([&filePath]() {
248         EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), OK);
249         g_readyFlag.store(true);
250         g_backupVar.notify_all();
251     });
252     subThread.detach();
253 
254     /**
255      * @tc.steps: step2. call export interface when step1 is running.
256      * @tc.expected: step2. return busy if step1 hasn't completed, else return OK.
257      */
258     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_TWO_HUNDREDS_MS));
259     filePath = exportPath + "/bkpDB1.bin";
260     DBStatus status = g_nbBackupDelegate->Export(filePath, NULL_PASSWD);
261     EXPECT_TRUE(status == BUSY || status == OK);
262     CheckFileNumber(exportPath, fileCount);
263     if (status == BUSY) {
264         EXPECT_EQ(fileCount, 1);
265     } else {
266         EXPECT_EQ(fileCount, 2); // if export success, the number of file is 2.
267     }
268 
269     std::mutex count;
270     std::unique_lock<std::mutex> lck(count);
__anonced11ad80202null271     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
272     RemoveDir(exportPath);
273 }
274 
275 #ifndef LOW_LEVEL_MEM_DEV
276 /*
277  * @tc.name: ExportTest 004
278  * @tc.desc: Verify that the export interface will return busy when the rekey hasn't completed.
279  * @tc.type: FUNC
280  * @tc.require: SR000D4878
281  * @tc.author: fengxiaoyun
282  */
283 HWTEST_F(DistributeddbNbBackupTest, ExportTest004, TestSize.Level3)
284 {
285     std::vector<DistributedDB::Entry> entriesBatch;
286     std::vector<DistributedDB::Key> allKeys;
287     GenerateFixedRecords(entriesBatch, allKeys, NB_PREDATA_NUM, ONE_K_LONG_STRING, TWO_M_LONG_STRING);
288     for (vector<Entry>::iterator iter = entriesBatch.begin(); iter != entriesBatch.end(); iter++) {
289         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
290     }
291     /**
292      * @tc.steps: step1. call import interface to import the file that prepared in advance.
293      * @tc.expected: step1. call successfully if step1 running before step2, else return busy.
294      */
295     g_readyFlag.store(false);
__anonced11ad80302() 296     thread subThread([]() {
297         DBStatus rekeyStatus = g_nbBackupDelegate->Rekey(g_passwd1);
298         EXPECT_TRUE(rekeyStatus == OK || rekeyStatus == BUSY);
299         MST_LOG("The rekeyStatus is %d", rekeyStatus);
300         g_readyFlag.store(true);
301         g_backupVar.notify_all();
302     });
303     subThread.detach();
304 
305     /**
306      * @tc.steps: step2. call export interface when step1 is running.
307      * @tc.expected: step2. return busy if step1 is running, else return OK.
308      */
309     int fileCount = 0;
310     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
311     SetDir(exportPath);
312     const std::string filePath = exportPath + "/bkpDB.bin";
313     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
314     DBStatus status = g_nbBackupDelegate->Export(filePath, NULL_PASSWD);
315     EXPECT_TRUE(status == BUSY || status == OK);
316     CheckFileNumber(exportPath, fileCount);
317     if (status == BUSY) {
318         EXPECT_EQ(fileCount, 0);
319     } else {
320         EXPECT_EQ(fileCount, 1);
321     }
322 
323     std::mutex count;
324     std::unique_lock<std::mutex> lck(count);
__anonced11ad80402null325     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
326     RemoveDir(exportPath);
327 }
328 #endif
329 
330 /*
331  * @tc.name: ExportTest 005
332  * @tc.desc: Verify that the export interface will execute blockly when last export hasn't completed.
333  * @tc.type: FUNC
334  * @tc.require: SR000D4878
335  * @tc.author: fengxiaoyun
336  */
337 HWTEST_F(DistributeddbNbBackupTest, ExportTest005, TestSize.Level2)
338 {
339     int fileCount = 0;
340     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
341     SetDir(exportPath);
342     std::string filePath = exportPath + "/bkpDB.bin";
343     std::vector<DistributedDB::Entry> entriesBatch;
344     std::vector<DistributedDB::Key> allKeys;
345     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, FOUR_M_LONG_STRING);
346     for (vector<Entry>::iterator iter = entriesBatch.begin(); iter != entriesBatch.end(); iter++) {
347         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
348     }
349     /**
350      * @tc.steps: step1. call import interface to import the file that prepared in advance.
351      * @tc.expected: step1. call successfully.
352      */
353     g_readyFlag.store(false);
__anonced11ad80502() 354     thread subThread([&filePath]() {
355         std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
356         DBStatus exportStatus = g_nbBackupDelegate->Export(filePath, NULL_PASSWD);
357         EXPECT_EQ(exportStatus, OK);
358         g_readyFlag.store(true);
359         g_backupVar.notify_one();
360     });
361     subThread.detach();
362 
363     /**
364      * @tc.steps: step2. call export interface when step1 is running.
365      * @tc.expected: step2. it can be called after last export finished.
366      */
367     std::string filePath2 = exportPath + "/bkpDB1.bin";
368     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
369 
370     std::mutex count;
371     std::unique_lock<std::mutex> lck(count);
__anonced11ad80602null372     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
373     CheckFileNumber(exportPath, fileCount);
374     EXPECT_EQ(fileCount, 2); // the export file number is 2.
375     RemoveDir(exportPath);
376 }
377 
378 /*
379  * @tc.name: ExportTest 006
380  * @tc.desc: Verify that the put/delete operation will execute blockly when export hasn't completed.
381  * @tc.type: FUNC
382  * @tc.require: SR000D4878
383  * @tc.author: fengxiaoyun
384  */
385 HWTEST_F(DistributeddbNbBackupTest, ExportTest006, TestSize.Level3)
386 {
387     int fileCount = 0;
388     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
389     SetDir(exportPath);
390     std::string filePath = exportPath + "/bkpDB.bin";
391     std::vector<DistributedDB::Entry> entriesBatch;
392     std::vector<DistributedDB::Key> allKeys;
393     GenerateFixedRecords(entriesBatch, allKeys, FIFTY_RECORDS, ONE_K_LONG_STRING, TWO_M_LONG_STRING);
394     for (vector<Entry>::iterator iter = entriesBatch.begin(); iter != entriesBatch.end(); iter++) {
395         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
396         EXPECT_TRUE(g_nbBackupDelegate->PutLocal(iter->key, iter->value) == OK);
397     }
398     /**
399      * @tc.steps: step1. call export interface in subthread.
400      * @tc.expected: step1. call successfully.
401      */
402     g_readyFlag.store(false);
__anonced11ad80702() 403     thread subThread([&filePath]() {
404         DBStatus exportStatus = g_nbBackupDelegate->Export(filePath, NULL_PASSWD);
405         EXPECT_EQ(exportStatus, OK);
406         g_readyFlag.store(true);
407         g_backupVar.notify_all();
408     });
409     subThread.detach();
410 
411     /**
412      * @tc.steps: step2. call Get,GetLocal,GetEntries to query data from db.
413      * @tc.expected: step2. call successfully(if export continued over 30s, put will return busy).
414      */
415     Value valueResult;
416     EXPECT_TRUE(g_nbBackupDelegate->Get(allKeys[0], valueResult) == OK);
417     EXPECT_EQ(valueResult, entriesBatch[0].value);
418     EXPECT_TRUE(g_nbBackupDelegate->GetLocal(allKeys[1], valueResult) == OK);
419     EXPECT_EQ(valueResult, entriesBatch[1].value);
420     std::vector<Entry> entries;
421     EXPECT_TRUE(g_nbBackupDelegate->GetEntries(KEY_EMPTY, entries) == OK);
422     EXPECT_EQ(entries.size(), entriesBatch.size());
423     /**
424      * @tc.steps: step3. call put/delete/putlocal/deletelocal interface when step1 is running.
425      * @tc.expected: step3. return ok, if step1 need more than 30s to finish, it will return busy.
426      */
427     DBStatus status = g_nbBackupDelegate->Put(entriesBatch[0].key, entriesBatch[0].value);
428     EXPECT_TRUE((status == OK) || (status == BUSY));
429     status = g_nbBackupDelegate->PutLocal(entriesBatch[1].key, entriesBatch[1].value);
430     EXPECT_TRUE((status == OK) || (status == BUSY));
431     status = g_nbBackupDelegate->Delete(allKeys[0]);
432     EXPECT_TRUE((status == OK) || (status == BUSY));
433 
434     std::mutex count;
435     std::unique_lock<std::mutex> lck(count);
__anonced11ad80802null436     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
437     CheckFileNumber(exportPath, fileCount);
438     EXPECT_EQ(fileCount, 1);
439     RemoveDir(exportPath);
440 }
441 
442 /*
443  * @tc.name: ExportTest 007
444  * @tc.desc: Verify that passwd parameter of export interface decide the file exported is encrypted or not.
445  * @tc.type: FUNC
446  * @tc.require: SR000D4878
447  * @tc.author: fengxiaoyun
448  */
449 HWTEST_F(DistributeddbNbBackupTest, ExportTest007, TestSize.Level1)
450 {
451     int fileCount = 0;
452     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
453     SetDir(exportPath);
454     std::string filePath = exportPath + "/bkpDB1.bin";
455 
456     /**
457      * @tc.steps: step1. call export interface with NULL_PASSWD.
458      * @tc.expected: step1. call successfully.
459      */
460     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
461     CheckFileNumber(exportPath, fileCount);
462     EXPECT_EQ(fileCount, 1);
463 
464     /**
465      * @tc.steps: step2. call export interface with the passwd = password(129B).
466      * @tc.expected: step2. return INVALID_ARGS.
467      */
468     filePath = exportPath + "/bkpDB2.bin";
469     vector<uint8_t> passwordVector(PASSWD_BYTE, 'a');
470     CipherPassword password;
471     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OVERSIZE);
472     CheckFileNumber(exportPath, fileCount);
473     EXPECT_EQ(fileCount, 1);
474 
475     /**
476      * @tc.steps: step3. call export interface with the passwd = password(1B).
477      * @tc.expected: step3. return OK.
478      */
479     filePath = exportPath + "/bkpDB3.bin";
480     passwordVector.assign(1, 'b'); // 1 Byte of passwd.
481     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OK);
482     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, password), OK);
483     CheckFileNumber(exportPath, fileCount);
484     EXPECT_EQ(fileCount, 2); // the number of file is 2.
485 
486     /**
487      * @tc.steps: step3. call export interface with the passwd = password(128B).
488      * @tc.expected: step3. return OK.
489      */
490     filePath = exportPath + "/bkpDB4.bin";
491     passwordVector.assign(BATCH_RECORDS, 'b'); // 1 Byte of passwd.
492     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OK);
493     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, password), OK);
494     CheckFileNumber(exportPath, fileCount);
495     EXPECT_EQ(fileCount, 3); // the number of file is 3.
496     RemoveDir(exportPath);
497 }
498 
499 /*
500  * @tc.name: ImportTest 001
501  * @tc.desc: Verify that it can only import success when the pass word is rightly match(exist and rightly or not).
502  * @tc.type: FUNC
503  * @tc.require: SR000D4878
504  * @tc.author: fengxiaoyun
505  */
506 HWTEST_F(DistributeddbNbBackupTest, ImportTest001, TestSize.Level1)
507 {
508     /**
509      * @tc.steps: step1. device put (k1, v2) to DB and then update it to (k1, v1).
510      * @tc.expected: step1. put successfully.
511      */
512     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), OK);
513     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
514     SetDir(importPath);
515     std::string filePath1 = importPath + "/bkpDB1.bin";
516     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, NULL_PASSWD), OK);
517     std::string filePath2 = importPath + "/bkpDB2.bin";
518     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, g_filePasswd1), OK);
519     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_2), OK);
520 
521     /**
522      * @tc.steps: step2. import backup file bkpDB1.bin with passwd f1.
523      * @tc.expected: step2. import failed and return INVALID_FILE.
524      */
525     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), INVALID_FILE);
526 
527     /**
528      * @tc.steps: step3. import backup file bkpDB1.bin with empty passwd and get the value of key1.
529      * @tc.expected: step3. import successfully, and the value of key1 is value1.
530      */
531     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), OK);
532     Value valueResult;
533     g_nbBackupDelegate->Get(KEY_1, valueResult);
534     EXPECT_EQ(valueResult, VALUE_1);
535 
536     /**
537      * @tc.steps: step4. update the entry (k1, v1) to (k1, v2).
538      * @tc.expected: step4. update success.
539      */
540     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_2), OK);
541     /**
542      * @tc.steps: step5. import backup file bkpDB2.bin with empty passwd.
543      * @tc.expected: step5. import failed and return INVALID_FILE.
544      */
545     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), INVALID_FILE);
546     /**
547      * @tc.steps: step6. import backup file bkpDB2.bin with DB passwd p1.
548      * @tc.expected: step6. import failed and return INVALID_FILE.
549      */
550     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
551     /**
552      * @tc.steps: step7. import backup file bkpDB2.bin with passwd = password(129B).
553      * @tc.expected: step7. import failed and return INVALID_FILE.
554      */
555     vector<uint8_t> passwordVector(PASSWD_BYTE, 'a');
556     CipherPassword password;
557     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OVERSIZE);
558     /**
559      * @tc.steps: step8. import backup file bkpDB2.bin with DB passwd f1 and get the value of k1.
560      * @tc.expected: step8. import success and return INVALID_FILE.
561      */
562     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), OK);
563     g_nbBackupDelegate->Get(KEY_1, valueResult);
564     EXPECT_EQ(valueResult, VALUE_1);
565     RemoveDir(importPath);
566 }
567 
568 /*
569  * @tc.name: ImportTest 002
570  * @tc.desc: Verify that memory DB can't support to import.
571  * @tc.type: FUNC
572  * @tc.require: SR000D4878
573  * @tc.author: fengxiaoyun
574  */
575 HWTEST_F(DistributeddbNbBackupTest, ImportTest002, TestSize.Level1)
576 {
577     std::string importPath1 = DistributedDBConstant::NB_DIRECTOR + "export";
578     SetDir(importPath1);
579     std::string filePath = importPath1 + "/bkpDB.bin";
580     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
581 
582     /**
583      * @tc.steps: step1. create memory DB and import the backup file.
584      * @tc.expected: step1. create success but import failed and return NOT_SUPPORT.
585      */
586     KvStoreNbDelegate *delegate2 = nullptr;
587     KvStoreDelegateManager *manager2 = nullptr;
588     Option option;
589     option.isMemoryDb = true;
590     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, option);
591     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
592     EXPECT_EQ(delegate2->Import(filePath, NULL_PASSWD), NOT_SUPPORT);
593     /**
594      * @tc.steps: step2. the disk DB import backup file bkpDB1.bin from noexsit path with empty passwd.
595      * @tc.expected: step2. import failed and returned INVALID_FILE.
596      */
597     std::string importPath2 = DistributedDBConstant::NB_DIRECTOR + "/noexsit";
598     std::string filePath2 = importPath2 + "/bkpDB.bin";
599     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), INVALID_ARGS);
600 
601     /**
602      * @tc.steps: step3. the disk DB import noexsit backup file bkpDB1.bin from noexsit path with empty passwd..
603      * @tc.expected: step3. import failed and returned INVALID_FILE.
604      */
605     std::string filePath3 = importPath1 + "/bkpDB2.bin";
606     EXPECT_EQ(g_nbBackupDelegate->Import(filePath3, NULL_PASSWD), INVALID_FILE);
607 
608     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
609     delegate2 = nullptr;
610     delete manager2;
611     manager2 = nullptr;
612     RemoveDir(importPath1);
613 }
614 
615 /*
616  * @tc.name: ImportTest 003
617  * @tc.desc: Verify that it can't import the not DB file and damaged file.
618  * @tc.type: FUNC
619  * @tc.require: SR000D4878
620  * @tc.author: fengxiaoyun
621  */
622 HWTEST_F(DistributeddbNbBackupTest, ImportTest003, TestSize.Level1)
623 {
624     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
625     SetDir(importPath);
626     std::string filePath = importPath + "/bkpDB.bin";
627     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
628 
629     /**
630      * @tc.steps: step1. import a.txt in the right path.
631      * @tc.expected: step1. call failed and return INVALID_FILE.
632      */
633     std::string filePath1 = importPath + "/a.txt";
634     ofstream createFile(filePath1);
635     if (createFile) {
636         createFile << '1' << endl;
637         createFile.close();
638     }
639     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
640 
641     /**
642      * @tc.steps: step2. write some data to DB file1.
643      * @tc.expected: step2. write successfully
644      */
645     ofstream damageFile(filePath, ios::out | ios::binary);
646     ASSERT_TRUE(damageFile.is_open());
647     damageFile.write(reinterpret_cast<char *>(&filePath), filePath.size());
648     damageFile.close();
649 
650     /**
651      * @tc.steps: step3. import DB file with empty password.
652      * @tc.expected: step3. import failed and returned INVALID_FILE
653      */
654     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_FILE);
655     RemoveDir(importPath);
656 }
657 
658 /*
659  * @tc.name: ImportTest 004
660  * @tc.desc: Verify that multi-DB can't import nb-DB backup file, and nb-DB can't import multi-DB backup file too.
661  * @tc.type: FUNC
662  * @tc.require: SR000D4878
663  * @tc.author: fengxiaoyun
664  */
665 HWTEST_F(DistributeddbNbBackupTest, ImportTest004, TestSize.Level1)
666 {
667     KvStoreDelegate *multiEncryptDelegate = nullptr;
668     KvStoreDelegateManager *multiEncryptManager = nullptr;
669 
670     KvOption option = g_kvOption;
671     multiEncryptDelegate = DistributedTestTools::GetDelegateSuccess(multiEncryptManager, g_kvdbParameter2, option);
672     ASSERT_TRUE(multiEncryptManager != nullptr && multiEncryptDelegate != nullptr);
673     const std::string multiImportPath = DIRECTOR + "export";
674     SetDir(multiImportPath);
675     std::string multiFilePath1 = multiImportPath + "/bkpDB1.bin";
676     multiEncryptDelegate->Export(multiFilePath1, g_filePasswd1);
677 
678     KvStoreDelegate *localDelegate = nullptr;
679     KvStoreDelegateManager *localManager = nullptr;
680     option.localOnly = true;
681     localDelegate = DistributedTestTools::GetDelegateSuccess(localManager, g_kvdbParameter3, option);
682     ASSERT_TRUE(localManager != nullptr && localDelegate != nullptr);
683 
684     std::string multiFilePath2 = multiImportPath + "/bkpDB2.bin";
685     localDelegate->Export(multiFilePath2, g_filePasswd1);
686 
687     const std::string nbImportPath = DistributedDBConstant::NB_DIRECTOR + "export";
688     SetDir(nbImportPath);
689     std::string nbFilePath = nbImportPath + "/bkpDB1.bin";
690     g_nbBackupDelegate->Export(nbFilePath, g_filePasswd1);
691     /**
692      * @tc.steps: step1. the multi DB1 import the nb DB backup file with the password f1.
693      * @tc.expected: step1. call failed and return INVALID_FILE.
694      */
695     EXPECT_EQ(multiEncryptDelegate->Import(nbFilePath, g_filePasswd1), INVALID_FILE);
696     /**
697      * @tc.steps: step2. the multi DB1 import backup file of local db with the password f1.
698      * @tc.expected: step2. call failed and return INVALID_FILE.
699      */
700     EXPECT_EQ(multiEncryptDelegate->Import(multiFilePath2, g_filePasswd1), INVALID_FILE);
701     /**
702      * @tc.steps: step3. the nb DB import the multi DB backup file with the password f1.
703      * @tc.expected: step3. call failed and return INVALID_FILE.
704      */
705     EXPECT_EQ(g_nbBackupDelegate->Import(multiFilePath1, g_filePasswd1), INVALID_FILE);
706     /**
707      * @tc.steps: step4. the nb DB import the noexsit nb DB backup file with the password f1.
708      * @tc.expected: step4. call failed and return INVALID_FILE.
709      */
710     EXPECT_EQ(g_nbBackupDelegate->Import(multiFilePath2, g_filePasswd1), INVALID_FILE);
711 
712     /**
713      * @tc.steps: step5. Local DB import nb-backup file with the password f1.
714      * @tc.expected: step5. call failed and return INVALID_FILE.
715      */
716     EXPECT_EQ(localDelegate->Import(nbFilePath, g_filePasswd1), INVALID_FILE);
717     /**
718      * @tc.steps: step6. Local DB import multi-backup file with the password f1.
719      * @tc.expected: step6. call failed and return INVALID_FILE.
720      */
721     EXPECT_EQ(localDelegate->Import(multiFilePath1, g_filePasswd1), INVALID_FILE);
722     EXPECT_EQ(multiEncryptManager->CloseKvStore(multiEncryptDelegate), OK);
723     multiEncryptDelegate = nullptr;
724     EXPECT_EQ(multiEncryptManager->DeleteKvStore(STORE_ID_2), OK);
725     delete multiEncryptManager;
726     multiEncryptManager = nullptr;
727     EXPECT_EQ(localManager->CloseKvStore(localDelegate), OK);
728     localDelegate = nullptr;
729     EXPECT_EQ(localManager->DeleteKvStore(STORE_ID_3), OK);
730     delete localManager;
731     localManager = nullptr;
732     RemoveDir(multiImportPath);
733     RemoveDir(nbImportPath);
734 }
735 
736 /*
737  * @tc.name: ImportTest 006
738  * @tc.desc: Verify that many kvstore of one DB or the DB registered observer can't import the backup file.
739  * @tc.type: FUNC
740  * @tc.require: SR000D4878
741  * @tc.author: fengxiaoyun
742  */
743 HWTEST_F(DistributeddbNbBackupTest, ImportTest006, TestSize.Level1)
744 {
745     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
746     SetDir(importPath);
747     std::string filePath = importPath + "/bkpDB.bin";
748     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, g_filePasswd1), OK);
749 
750     /**
751      * @tc.steps: step1. create another delegate of the same storeId.
752      * @tc.expected: step1. create success.
753      */
754     KvStoreNbDelegate *delegate2 = nullptr;
755     KvStoreDelegateManager *manager2 = nullptr;
756     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter1, g_option);
757     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
758 
759     /**
760      * @tc.steps: step2. use the second delegate to import the backup file.
761      * @tc.expected: step2. import failed and return busy
762      */
763     EXPECT_EQ(delegate2->Import(filePath, g_filePasswd1), BUSY);
764 
765     EXPECT_TRUE(manager2->CloseKvStore(delegate2) == OK);
766     delegate2 = nullptr;
767     delete manager2;
768     manager2 = nullptr;
769     /**
770      * @tc.steps: step3. delegate1 register observer.
771      * @tc.expected: step3. register success
772      */
773     KvStoreObserverImpl observerSync;
774     EXPECT_EQ(g_nbBackupDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observerSync), OK);
775     /**
776      * @tc.steps: step4. delegate1 import the backup file with the password f1.
777      * @tc.expected: step4. register success
778      */
779     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
780     RemoveDir(importPath);
781 }
782 
783 /*
784  * @tc.name: ImportTest 007
785  * @tc.desc: Verify that the DB registered conflict notifier or hadn't resultSet can't import the backup file.
786  * @tc.type: FUNC
787  * @tc.require: SR000D4878
788  * @tc.author: fengxiaoyun
789  */
790 HWTEST_F(DistributeddbNbBackupTest, ImportTest007, TestSize.Level1)
791 {
792     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
793     SetDir(importPath);
794     std::string filePath = importPath + "/bkpDB.bin";
795     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, g_filePasswd1), OK);
796 
797     /**
798      * @tc.steps: step1. register conflict notifier.
799      * @tc.expected: step1. register successfully.
800      */
801     ConflictNbCallback callback;
802     std::vector<ConflictData> conflictData;
803     auto notifier = bind(&ConflictNbCallback::NotifyCallBack, &callback, placeholders::_1, &conflictData);
804     EXPECT_EQ(g_nbBackupDelegate->SetConflictNotifier(CONFLICT_NATIVE_ALL, notifier), OK);
805     /**
806      * @tc.steps: step2. import the backup file with the password f1.
807      * @tc.expected: step2. import failed and returned BUSY.
808      */
809     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
810     EXPECT_EQ(g_nbBackupDelegate->SetConflictNotifier(CONFLICT_NATIVE_ALL, nullptr), OK);
811 
812     /**
813      * @tc.steps: step3. call GetEntries to get resultSet.
814      * @tc.expected: step3. get successfully.
815      */
816     KvStoreResultSet *resultSet;
817     EXPECT_EQ(g_nbBackupDelegate->GetEntries(KEY_K, resultSet), OK);
818     /**
819      * @tc.steps: step4. import the backup file with the password f1.
820      * @tc.expected: step4. import failed and returned BUSY.
821      */
822     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
823     EXPECT_EQ(g_nbBackupDelegate->CloseResultSet(resultSet), OK);
824 
825     RemoveDir(importPath);
826 }
827 
828 #ifndef LOW_LEVEL_MEM_DEV
829 /*
830  * @tc.name: ImportTest 008
831  * @tc.desc: Verify that it will return busy when GetKvStore again or crud during it is importing.
832  * @tc.type: FUNC
833  * @tc.require: SR000D4878
834  * @tc.author: fengxiaoyun
835  */
836 HWTEST_F(DistributeddbNbBackupTest, ImportTest008, TestSize.Level3)
837 {
838     vector<Entry> entries;
839     std::vector<DistributedDB::Key> allKeys;
840     GenerateFixedRecords(entries, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, TWO_M_LONG_STRING);
841     for (auto iter = entries.begin(); iter != entries.end(); iter++) {
842         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
843     }
844 
845     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
846     SetDir(importPath);
847     std::string filePath = importPath + "/bkpDB.bin";
848     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
849 
850     /**
851      * @tc.steps: step1. start subthread to import the backup file with empty password.
852      * @tc.expected: step1. start successfully if step1 running before step2, else return BUSY.
853      */
854     g_readyFlag.store(false);
__anonced11ad80902() 855     thread subThread([&filePath]() {
856         DBStatus importStatus = g_nbBackupDelegate->Import(filePath, NULL_PASSWD);
857         EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
858         g_readyFlag.store(true);
859         g_backupVar.notify_one();
860     });
861     subThread.detach();
862 
863     /**
864      * @tc.steps: step2. GetKvStore again during the subthread is importing.
865      * @tc.expected: step2. GetKvStore failed and returned BUSY if step1 is running, else return OK.
866      */
867     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
868     KvStoreDelegateManager *manager = nullptr;
869     DBStatus statusReturn;
870     DistributedDBNbTestTools::GetNbDelegateStatus(manager, statusReturn, g_dbParameter1, g_option);
871     EXPECT_TRUE(statusReturn == BUSY || statusReturn == OK);
872     /**
873      * @tc.steps: step3. put (k1, v1) during the subthread is importing.
874      * @tc.expected: step3. put failed and returned BUSY if step1 is running, else return OK.
875      */
876     statusReturn = g_nbBackupDelegate->Put(KEY_1, VALUE_1);
877     EXPECT_TRUE(statusReturn == BUSY || statusReturn == OK);
878     std::mutex rekeyMtx;
879     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonced11ad80a02null880     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
881     RemoveDir(importPath);
882 }
883 
884 #ifndef LOW_LEVEL_MEM_DEV
885 /*
886  * @tc.name: ImportTest 009
887  * @tc.desc: Verify that it will return busy when rekey during it is importing.
888  * @tc.type: FUNC
889  * @tc.require: SR000D4878
890  * @tc.author: fengxiaoyun
891  */
892 HWTEST_F(DistributeddbNbBackupTest, ImportTest009, TestSize.Level3)
893 {
894     vector<Entry> entriesRekey;
895     std::vector<DistributedDB::Key> allKeys;
896     GenerateFixedRecords(entriesRekey, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
897     for (auto iter = entriesRekey.begin(); iter != entriesRekey.end(); iter++) {
898         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
899     }
900 
901     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
902     SetDir(importPath);
903     std::string filePath = importPath + "/bkpDB.bin";
904     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
905 
906     /**
907      * @tc.steps: step1. start subthread to import the backup file with empty password.
908      * @tc.expected: step1. start successfully if step1 running before step2, else return BUSY.
909      */
910     g_readyFlag.store(false);
__anonced11ad80b02() 911     thread subThread([&filePath]() {
912         DBStatus importStatus = g_nbBackupDelegate->Import(filePath, NULL_PASSWD);
913         EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
914         g_readyFlag.store(true);
915         g_backupVar.notify_one();
916     });
917     subThread.detach();
918     /**
919      * @tc.steps: step2. rekey  during the subthread is importing.
920      * @tc.expected: step2. rekey failed and returned BUSY if step1 is running, else return OK.
921      */
922     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LAST_SYNC));
923     DBStatus status = g_nbBackupDelegate->Rekey(g_passwd1);
924     EXPECT_TRUE(status == BUSY || status == OK);
925 
926     std::mutex rekeyMtx;
927     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonced11ad80c02null928     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
929     RemoveDir(importPath);
930 }
931 #endif
932 
933 /*
934  * @tc.name: ImportTest 010
935  * @tc.desc: Verify that it will return busy when rekey during it is importing.
936  * @tc.type: FUNC
937  * @tc.require: SR000D4878
938  * @tc.author: fengxiaoyun
939  */
940 HWTEST_F(DistributeddbNbBackupTest, ImportTest010, TestSize.Level3)
941 {
942     vector<Entry> entriesRekey2;
943     std::vector<DistributedDB::Key> allKeys;
944     GenerateFixedRecords(entriesRekey2, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, TWO_M_LONG_STRING);
945     for (auto iter = entriesRekey2.begin(); iter != entriesRekey2.end(); iter++) {
946         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
947     }
948 
949     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
950     SetDir(importPath);
951     std::string filePath = importPath + "/bkpDB.bin";
952     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
953 
954     /**
955      * @tc.steps: step1. start subthread to rekey DB with password 1.
956      * @tc.expected: step1. start successfully.
957      */
958     g_readyFlag.store(false);
__anonced11ad80d02() 959     thread subThread([]() {
960         EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
961         g_readyFlag.store(true);
962         g_backupVar.notify_one();
963     });
964     subThread.detach();
965     /**
966      * @tc.steps: step2. import the backup file during the subthread is rekeying.
967      * @tc.expected: step2. import failed and returned BUSY.
968      */
969     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LAST_SYNC));
970     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), BUSY);
971 
972     std::mutex rekeyMtx;
973     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonced11ad80e02null974     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
975     RemoveDir(importPath);
976 }
977 #endif
978 
979 /*
980  * @tc.name: ImportTest 011
981  * @tc.desc: Verify that it will allow to import backup file again during it is importing.
982  * @tc.type: FUNC
983  * @tc.require: SR000D4878
984  * @tc.author: fengxiaoyun
985  */
986 HWTEST_F(DistributeddbNbBackupTest, ImportTest011, TestSize.Level3)
987 {
988     vector<Entry> entriesReImport;
989     std::vector<DistributedDB::Key> allKeys;
990     GenerateFixedRecords(entriesReImport, allKeys, TEN_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
991     for (auto iter = entriesReImport.begin(); iter != entriesReImport.end(); iter++) {
992         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
993     }
994 
995     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
996     SetDir(importPath);
997     std::string filePath = importPath + "/bkpDB.bin";
998     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
999 
1000     /**
1001      * @tc.steps: step1. start subthread to import the backup file.
1002      * @tc.expected: step1. start successfully.
1003      */
1004     g_readyFlag.store(false);
__anonced11ad80f02() 1005     thread subThread([&filePath]() {
1006         EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), OK);
1007         g_readyFlag.store(true);
1008         g_backupVar.notify_one();
1009     });
1010     subThread.detach();
1011     /**
1012      * @tc.steps: step2. import the backup file during the subthread is importing with empty password.
1013      * @tc.expected: step2. import successfully and return OK.
1014      */
1015     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), OK);
1016 
1017     std::mutex rekeyMtx;
1018     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonced11ad81002null1019     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
1020 
1021     RemoveDir(importPath);
1022 }
1023 
NbSubImportThread(int index,std::string importPath)1024 void NbSubImportThread(int index, std::string importPath)
1025 {
1026     vector<Entry> tenEntries;
1027     std::vector<DistributedDB::Key> allKeys;
1028     GenerateFixedRecords(tenEntries, allKeys, FIVE_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
1029     /**
1030      * @tc.steps: step1. every thread create one DB put 10 entries into the DB.
1031      * @tc.expected: step1. put successfully.
1032      */
1033     KvStoreNbDelegate *delegate2 = nullptr;
1034     KvStoreDelegateManager *manager2 = nullptr;
1035     DBParameters parameter[] = {g_dbParameter2, g_dbParameter3, g_dbParameter4, g_dbParameter5, g_dbParameter6};
1036     Option option[] = {g_createDiskUnencrypted, g_createDiskUnencrypted, g_createDiskUnencrypted,
1037         g_createDiskEncrypted, g_createDiskEncrypted};
1038     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, parameter[index], option[index]);
1039     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
1040 
1041     for (auto iter = tenEntries.begin(); iter != tenEntries.end(); iter++) {
1042         EXPECT_TRUE(delegate2->Put(iter->key, iter->value) == OK);
1043     }
1044 
1045     /**
1046      * @tc.steps: step2. every thread export DB to backup file.
1047      * @tc.expected: step2. export successfully.
1048      */
1049     DistributedDB::CipherPassword passwd[] = {NULL_PASSWD, NULL_PASSWD, NULL_PASSWD, g_filePasswd1, g_filePasswd2};
1050 
1051     const std::string backupFile[] = {"/bkpDB1.bin", "/bkpDB2.bin", "/bkpDB3.bin", "/bkpDB4.bin", "/bkpDB5.bin"};
1052     std::string nbFilePath[] = {(importPath + backupFile[INDEX_ZEROTH]), (importPath + backupFile[INDEX_FIRST]),
1053         (importPath + backupFile[INDEX_SECOND]), (importPath + backupFile[INDEX_THIRD]),
1054         (importPath + backupFile[INDEX_FORTH])};
1055     delegate2->Export(nbFilePath[index], passwd[index]);
1056 
1057     /**
1058      * @tc.steps: step3. every thread import backup file to DB.
1059      * @tc.expected: step3. import successfully.
1060      */
1061     EXPECT_EQ(delegate2->Import(nbFilePath[index], passwd[index]), OK);
1062     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
1063     delegate2 = nullptr;
1064     std::string storeId[] = {STORE_ID_2, STORE_ID_3, STORE_ID_4, STORE_ID_5, STORE_ID_6};
1065     EXPECT_TRUE(manager2->DeleteKvStore(storeId[index]) == OK);
1066     for (auto &password : passwd) {
1067         password.Clear();
1068     }
1069     delete manager2;
1070     manager2 = nullptr;
1071 }
1072 
1073 /*
1074  * @tc.name: ImportTest 012
1075  * @tc.desc: Verify that different DB export and import in the same time won't affect each other.
1076  * @tc.type: FUNC
1077  * @tc.require: SR000D4878
1078  * @tc.author: fengxiaoyun
1079  */
1080 HWTEST_F(DistributeddbNbBackupTest, ImportTest012, TestSize.Level3)
1081 {
1082     std::vector<std::thread> threads;
1083     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
1084     SetDir(importPath);
1085     for (int index = 0; index < FIVE_TIMES; ++index) {
1086         threads.push_back(std::thread(NbSubImportThread, index, std::ref(importPath)));
1087     }
1088 
1089     for (auto& th : threads) {
1090         th.join();
1091     }
1092     RemoveDir(importPath);
1093 }
1094 
1095 /*
1096  * @tc.name: Exchange 001
1097  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1098  * @tc.type: FUNC
1099  * @tc.require: SR000D4878
1100  * @tc.author: fengxiaoyun
1101  */
1102 HWTEST_F(DistributeddbNbBackupTest, Exchange001, TestSize.Level1)
1103 {
1104     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1105     SetDir(exportPath);
1106     std::string filePath1 = exportPath + "/bkpDB1.bin";
1107     std::string filePath2 = exportPath + "/bkpDB2.bin";
1108     /**
1109      * @tc.steps: step1. export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1110      * @tc.expected: step1. call successfully.
1111      */
1112     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1113     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1114     /**
1115      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1116      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1117      */
1118     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1119     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1120     /**
1121      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1122      * @tc.expected: step3. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1123      */
1124     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1125     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1126     /**
1127      * @tc.steps: step4. rekey db1 with g_passwd1, and then import "bkpDB1.bin" and "bkpDB2.bin" with p1.
1128      * @tc.expected: step4. rekey succeeded and import failed.
1129      */
1130     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1131     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1132     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1133     /**
1134      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1135      * @tc.expected: step5. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1136      */
1137     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1138     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1139     /**
1140      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1141      * @tc.expected: step6. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1142      */
1143     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1144     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1145     RemoveDir(exportPath);
1146 }
1147 
1148 /*
1149  * @tc.name: Exchange 002
1150  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1151  * @tc.type: FUNC
1152  * @tc.require: SR000D4878
1153  * @tc.author: fengxiaoyun
1154  */
1155 HWTEST_F(DistributeddbNbBackupTest, Exchange002, TestSize.Level1)
1156 {
1157     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1158     SetDir(exportPath);
1159     std::string filePath1 = exportPath + "/bkpDB1.bin";
1160     std::string filePath2 = exportPath + "/bkpDB2.bin";
1161     /**
1162      * @tc.steps: step1. rekey db1 with g_passwd1,
1163      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1164      * @tc.expected: step1. call successfully.
1165      */
1166     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1167     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1168     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1169     /**
1170      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1171      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1172      */
1173     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1174     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1175     /**
1176      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1177      * @tc.expected: step3. rekey succeeded and import failed.
1178      */
1179     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1180     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1181     /**
1182      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1183      * @tc.expected: step4. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1184      */
1185     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1186     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1187     /**
1188      * @tc.steps: step5. rekey db1 with NULL_PASSWD,
1189      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1190      * @tc.expected: step5. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1191      */
1192     EXPECT_EQ(g_nbBackupDelegate->Rekey(NULL_PASSWD), OK);
1193     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1194     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1195     /**
1196      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1197      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1198      */
1199     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1200     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1201     RemoveDir(exportPath);
1202 }
1203 
1204 /*
1205  * @tc.name: Exchange 003
1206  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1207  * @tc.type: FUNC
1208  * @tc.require: SR000D4878
1209  * @tc.author: fengxiaoyun
1210  */
1211 HWTEST_F(DistributeddbNbBackupTest, Exchange003, TestSize.Level1)
1212 {
1213     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1214     SetDir(exportPath);
1215     std::string filePath1 = exportPath + "/bkpDB1.bin";
1216     std::string filePath2 = exportPath + "/bkpDB2.bin";
1217     /**
1218      * @tc.steps: step1. rekey db1 with g_passwd1,
1219      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1220      * @tc.expected: step1. call successfully.
1221      */
1222     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1223     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1224     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1225     /**
1226      * @tc.steps: step2. rekey db1 with g_passwd2,
1227      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1228      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1229      */
1230     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd2), OK);
1231     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1232     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1233     /**
1234      * @tc.steps: step3. Put (k1,v1), close db, open db with g_passwd2 and delete (k1,v1)
1235      * @tc.expected: step3. operate successfully.
1236      */
1237     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), OK);
1238     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1239     g_nbBackupDelegate = nullptr;
1240     delete g_manager;
1241     g_manager = nullptr;
1242     Option encrypted(true, false, true, DistributedDB::CipherType::DEFAULT, PASSWD_VECTOR_2);
1243     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, encrypted);
1244     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1245     EXPECT_EQ(g_nbBackupDelegate->Delete(KEY_1), OK);
1246     /**
1247      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1248      * @tc.expected: step4. import failed.
1249      */
1250     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1251     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1252     /**
1253      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd2.
1254      * @tc.expected: step5. import failed.
1255      */
1256     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd2), INVALID_FILE);
1257     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd2), INVALID_FILE);
1258     /**
1259      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1260      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1261      */
1262     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1263     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1264     /**
1265      * @tc.steps: step7. Put (k2,v2), close db, open db with g_passwd2 and delete (k2,v2)
1266      * @tc.expected: step7. operate successfully.
1267      */
1268     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_2, VALUE_2), OK);
1269     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1270     g_nbBackupDelegate = nullptr;
1271     delete g_manager;
1272     g_manager = nullptr;
1273     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, encrypted);
1274     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1275     EXPECT_EQ(g_nbBackupDelegate->Delete(KEY_2), OK);
1276     RemoveDir(exportPath);
1277 }
1278 
1279 /*
1280  * @tc.name: CorruptionHandler 001
1281  * @tc.desc: Verify that the Corruption Handler can be set only one, if set many times, the last one is valid.
1282  * @tc.type: FUNC
1283  * @tc.require: SR000D4878
1284  * @tc.author: fengxiaoyun
1285  */
1286 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler001, TestSize.Level1)
1287 {
1288     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1289     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1290     SetDir(exportPath);
1291     std::string filePath = exportPath + "/bkpDB.bin";
1292     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
1293     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_1) == OK);
1294 
1295     /**
1296      * @tc.steps: step1. device A call SetKvStoreCorruptionHandler.
1297      * @tc.expected: step1. call successfully.
1298      */
1299     KvStoreNbCorruptInfo corruptInfo;
1300     KvStoreNbCorruptInfo corruptInfoNew;
1301     bool isCalled = false;
1302     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
1303         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
1304     g_manager->SetKvStoreCorruptionHandler(notifier);
1305     /**
1306      * @tc.steps: step2. device A call SetKvStoreCorruptionHandler the second time.
1307      * @tc.expected: step2. call successfully.
1308      */
1309     CallBackParam pathResult = {filePath, true};
1310     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptNewCallBack, &corruptInfoNew,
1311         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(g_manager), pathResult);
1312     g_manager->SetKvStoreCorruptionHandler(notifierNew);
1313     EXPECT_TRUE(pathResult.result);
1314     /**
1315      * @tc.steps: step3. make file corrupted and call GetKvStore to trigger callback function.
1316      * @tc.expected: step3. call successfully.
1317      */
1318     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1319     g_nbBackupDelegate = nullptr;
1320     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1321     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1322     DBStatus status;
1323     KvStoreDelegateManager *manager = nullptr;
1324     EXPECT_EQ(DistributedDBNbTestTools::GetNbDelegateStatus(manager, status, g_dbParameter1, g_option), nullptr);
1325     EXPECT_EQ(status, INVALID_PASSWD_OR_CORRUPTED_DB);
1326     /**
1327      * @tc.steps: step4. open db and Get(k1) to verify importing in callback is successful.
1328      * @tc.expected: step4. Get(k1)=v1.
1329      */
1330     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
1331     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1332     Value valueResult;
1333     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, valueResult) == OK);
1334     EXPECT_EQ(valueResult, VALUE_1);
1335     g_manager->SetKvStoreCorruptionHandler(nullptr);
1336     RemoveDir(exportPath);
1337 }
1338 
1339 /*
1340  * @tc.name: CorruptionHandler 002
1341  * @tc.desc: Verify that can import db files and can't export in the Corruption Handler callback when db files
1342  * are corrupted in using.
1343  * @tc.type: FUNC
1344  * @tc.require: SR000D4878
1345  * @tc.author: fengxiaoyun
1346  */
1347 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler002, TestSize.Level2)
1348 {
1349     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1350     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1351     SetDir(exportPath);
1352     std::string filePath = exportPath + "/bkpDB.bin";
1353     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, g_filePasswd1) == OK);
1354 
1355     /**
1356      * @tc.steps: step1. device A call SetKvStoreCorruptionHandler to register CorruptCallBackOfImport.
1357      * @tc.expected: step1. call successfully.
1358      */
1359     KvStoreNbCorruptInfo corruptInfo;
1360     CallBackParam pathResult = {filePath, true};
1361     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfImport, &corruptInfo,
1362         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1363     g_manager->SetKvStoreCorruptionHandler(notifier);
1364     EXPECT_TRUE(pathResult.result);
1365     /**
1366      * @tc.steps: step2. device A modify the db files to trigger the CorruptCallBackOfImport and check.
1367      * @tc.expected: step2. operate successfully and import the recover db files in callback successfully.
1368      */
1369     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_1) == OK);
1370     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1371     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1372     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1373     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1374     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND)); // wait for callback complete for 1 second.
1375     Value valueResult;
1376     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, valueResult) == OK);
1377     EXPECT_EQ(valueResult, VALUE_1);
1378 
1379     /**
1380      * @tc.steps: step3. device A call SetKvStoreCorruptionHandler again to register CorruptCallBackOfExport.
1381      * @tc.expected: step3. call successfully.
1382      */
1383     filePath = exportPath + "/bkpDB1.bin";
1384     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfExport, &corruptInfo,
1385         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1386     g_manager->SetKvStoreCorruptionHandler(notifierNew);
1387     EXPECT_TRUE(pathResult.result);
1388 
1389     /**
1390      * @tc.steps: step4. device A modify the db files to trigger the CorruptCallBackOfExport and check.
1391      * @tc.expected: step4. operate successfully and export the recover db data in callback failed.
1392      */
1393     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1394     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1395     g_manager->SetKvStoreCorruptionHandler(nullptr);
1396     RemoveDir(exportPath);
1397 }
1398 
1399 /*
1400  * @tc.name: CorruptionHandler 003
1401  * @tc.desc: Verify that if call SetKvStoreCorruptionHandler(nullptr) will unregister the Corruption Handler.
1402  * @tc.type: FUNC
1403  * @tc.require: SR000D4878
1404  * @tc.author: fengxiaoyun
1405  */
1406 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler003, TestSize.Level2)
1407 {
1408     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1409     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1410     SetDir(exportPath);
1411     std::string filePath = exportPath + "/bkpDB.bin";
1412     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, g_filePasswd1) == OK);
1413 
1414     /**
1415      * @tc.steps: step1. device A's db1 call SetKvStoreCorruptionHandler to register CorruptCallBack.
1416      * @tc.expected: step1. call successfully.
1417      */
1418     KvStoreNbCorruptInfo corruptInfo;
1419     bool isCalled = false;
1420     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
1421         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
1422     g_manager->SetKvStoreCorruptionHandler(notifier);
1423 
1424     /**
1425      * @tc.steps: step2. device A's db2 call SetKvStoreCorruptionHandler to register CorruptCallBackOfImport.
1426      * @tc.expected: step2. call successfully.
1427      */
1428     KvStoreDelegateManager *manager = nullptr;
1429     KvStoreNbDelegate *delegate = nullptr;
1430     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, g_option);
1431     ASSERT_TRUE(manager != nullptr && delegate != nullptr);
1432     KvStoreNbCorruptInfo corruptInfoNew;
1433     CallBackParam pathResult = {filePath, true};
1434     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfImport, &corruptInfoNew,
1435         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1436     manager->SetKvStoreCorruptionHandler(notifierNew);
1437     EXPECT_TRUE(pathResult.result);
1438 
1439     /**
1440      * @tc.steps: step3. device A modify the db files to trigger the CorruptCallBackOfImport and check.
1441      * @tc.expected: step3. operate successfully and import the recover db files in callback successfully.
1442      */
1443     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1444     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1445     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1446     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1447     std::this_thread::sleep_for(std::chrono::seconds(TWO_SECONDS)); // wait for callback complete for 1 second.
1448     Value valueResult;
1449     EXPECT_EQ(g_nbBackupDelegate->Get(KEY_1, valueResult), OK);
1450     EXPECT_EQ(valueResult, VALUE_1);
1451 
1452     /**
1453      * @tc.steps: step4. device A call SetKvStoreCorruptionHandler again to register nullptr.
1454      * @tc.expected: step4. call successfully.
1455      */
1456     manager->SetKvStoreCorruptionHandler(nullptr);
1457 
1458     /**
1459      * @tc.steps: step5. device A modify the db files to trigger the CorruptCallBack and check.
1460      * @tc.expected: step5. put return error but trigger the CorruptCallBack failed.
1461      */
1462     EXPECT_TRUE(delegate->Put(KEY_1, VALUE_1) == OK);
1463     dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter2);
1464     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1465     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1466     EXPECT_EQ(delegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1467     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND)); // wait for callback complete for 1 second.
1468     EXPECT_EQ(delegate->Get(KEY_1, valueResult), INVALID_PASSWD_OR_CORRUPTED_DB);
1469 
1470     EXPECT_EQ((manager->CloseKvStore(delegate)), OK);
1471     delegate = nullptr;
1472     manager->DeleteKvStore(STORE_ID_2);
1473     delete manager;
1474     manager = nullptr;
1475     RemoveDir(exportPath);
1476 }
1477 #ifndef RUNNING_ON_SIMULATED_ENV
1478 /*
1479  * @tc.name: CompatibilityTest 001
1480  * @tc.desc: test that use RELEASE_VERSION11.0.0 can import the export file by RELEASE_VERSION10.1.0.
1481  * @tc.type: Compatibility
1482  * @tc.require: SR000EPA24
1483  * @tc.author: fengxiaoyun
1484  */
1485 #ifdef NB_BACKUP
1486 HWTEST_F(DistributeddbNbBackupTest, CompatibilityTest001, TestSize.Level3)
1487 {
1488     const std::string exportPath = "/data/";
1489     std::string filePath = exportPath + "/RELEASE_VERSION1010.bin";
1490 #define COMPATIBILITYTEST_001
1491 #ifndef COMPATIBILITYTEST_001
1492     /**
1493      * @tc.steps: step1. create the db and put some data then export in RELEASE_VERSION10.1.0.
1494      * @tc.expected: step1. operate successfully.
1495      */
1496     EXPECT_TRUE(g_nbBackupDelegate->PutLocal(KEY_1, VALUE_1) == OK);
1497     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1498     EXPECT_TRUE(g_nbBackupDelegate->PutLocal(KEY_2, VALUE_1) == OK);
1499     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_2, VALUE_2) == OK);
1500     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_2) == OK);
1501     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
1502 #else
1503     /**
1504      * @tc.steps: step2. import the export file by step1 and check data.
1505      * @tc.expected: step2. import successfully.
1506      */
1507     EXPECT_TRUE(g_nbBackupDelegate->Import(filePath, NULL_PASSWD) == OK);
1508     Value resultValue;
1509     EXPECT_TRUE(g_nbBackupDelegate->GetLocal(KEY_1, resultValue) == OK);
1510     EXPECT_TRUE(resultValue == VALUE_1);
1511     EXPECT_TRUE(g_nbBackupDelegate->GetLocal(KEY_2, resultValue) == OK);
1512     EXPECT_TRUE(resultValue == VALUE_1);
1513     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, resultValue) == OK);
1514     EXPECT_TRUE(resultValue == VALUE_1);
1515     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_2, resultValue) == NOT_FOUND);
1516 #endif
1517 }
1518 #endif
1519 #endif
1520 }
1521