• 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 DB_DEBUG_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);
__anonf63d79d80102() 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);
__anonf63d79d80202null271     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);
__anonf63d79d80302() 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);
__anonf63d79d80402null325     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);
__anonf63d79d80502() 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);
__anonf63d79d80602null372     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);
__anonf63d79d80702() 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);
__anonf63d79d80802null436     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 #ifndef OMIT_MULTI_VER
666 HWTEST_F(DistributeddbNbBackupTest, ImportTest004, TestSize.Level1)
667 {
668     KvStoreDelegate *multiEncryptDelegate = nullptr;
669     KvStoreDelegateManager *multiEncryptManager = nullptr;
670 
671     KvOption option = g_kvOption;
672     multiEncryptDelegate = DistributedTestTools::GetDelegateSuccess(multiEncryptManager, g_kvdbParameter2, option);
673     ASSERT_TRUE(multiEncryptManager != nullptr && multiEncryptDelegate != nullptr);
674     const std::string multiImportPath = DIRECTOR + "export";
675     SetDir(multiImportPath);
676     std::string multiFilePath1 = multiImportPath + "/bkpDB1.bin";
677     multiEncryptDelegate->Export(multiFilePath1, g_filePasswd1);
678 
679     KvStoreDelegate *localDelegate = nullptr;
680     KvStoreDelegateManager *localManager = nullptr;
681     option.localOnly = true;
682     localDelegate = DistributedTestTools::GetDelegateSuccess(localManager, g_kvdbParameter3, option);
683     ASSERT_TRUE(localManager != nullptr && localDelegate != nullptr);
684 
685     std::string multiFilePath2 = multiImportPath + "/bkpDB2.bin";
686     localDelegate->Export(multiFilePath2, g_filePasswd1);
687 
688     const std::string nbImportPath = DistributedDBConstant::NB_DIRECTOR + "export";
689     SetDir(nbImportPath);
690     std::string nbFilePath = nbImportPath + "/bkpDB1.bin";
691     g_nbBackupDelegate->Export(nbFilePath, g_filePasswd1);
692     /**
693      * @tc.steps: step1. the multi DB1 import the nb DB backup file with the password f1.
694      * @tc.expected: step1. call failed and return INVALID_FILE.
695      */
696     EXPECT_EQ(multiEncryptDelegate->Import(nbFilePath, g_filePasswd1), INVALID_FILE);
697     /**
698      * @tc.steps: step2. the multi DB1 import backup file of local db with the password f1.
699      * @tc.expected: step2. call failed and return INVALID_FILE.
700      */
701     EXPECT_EQ(multiEncryptDelegate->Import(multiFilePath2, g_filePasswd1), INVALID_FILE);
702     /**
703      * @tc.steps: step3. the nb DB import the multi DB backup file with the password f1.
704      * @tc.expected: step3. call failed and return INVALID_FILE.
705      */
706     EXPECT_EQ(g_nbBackupDelegate->Import(multiFilePath1, g_filePasswd1), INVALID_FILE);
707     /**
708      * @tc.steps: step4. the nb DB import the noexsit nb DB backup file with the password f1.
709      * @tc.expected: step4. call failed and return INVALID_FILE.
710      */
711     EXPECT_EQ(g_nbBackupDelegate->Import(multiFilePath2, g_filePasswd1), INVALID_FILE);
712 
713     /**
714      * @tc.steps: step5. Local DB import nb-backup file with the password f1.
715      * @tc.expected: step5. call failed and return INVALID_FILE.
716      */
717     EXPECT_EQ(localDelegate->Import(nbFilePath, g_filePasswd1), INVALID_FILE);
718     /**
719      * @tc.steps: step6. Local DB import multi-backup file with the password f1.
720      * @tc.expected: step6. call failed and return INVALID_FILE.
721      */
722     EXPECT_EQ(localDelegate->Import(multiFilePath1, g_filePasswd1), INVALID_FILE);
723     EXPECT_EQ(multiEncryptManager->CloseKvStore(multiEncryptDelegate), OK);
724     multiEncryptDelegate = nullptr;
725     EXPECT_EQ(multiEncryptManager->DeleteKvStore(STORE_ID_2), OK);
726     delete multiEncryptManager;
727     multiEncryptManager = nullptr;
728     EXPECT_EQ(localManager->CloseKvStore(localDelegate), OK);
729     localDelegate = nullptr;
730     EXPECT_EQ(localManager->DeleteKvStore(STORE_ID_3), OK);
731     delete localManager;
732     localManager = nullptr;
733     RemoveDir(multiImportPath);
734     RemoveDir(nbImportPath);
735 }
736 #endif // OMIT_MULTI_VER
737 /*
738  * @tc.name: ImportTest 006
739  * @tc.desc: Verify that many kvstore of one DB or the DB registered observer can't import the backup file.
740  * @tc.type: FUNC
741  * @tc.require: SR000D4878
742  * @tc.author: fengxiaoyun
743  */
744 HWTEST_F(DistributeddbNbBackupTest, ImportTest006, TestSize.Level1)
745 {
746     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
747     SetDir(importPath);
748     std::string filePath = importPath + "/bkpDB.bin";
749     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, g_filePasswd1), OK);
750 
751     /**
752      * @tc.steps: step1. create another delegate of the same storeId.
753      * @tc.expected: step1. create success.
754      */
755     KvStoreNbDelegate *delegate2 = nullptr;
756     KvStoreDelegateManager *manager2 = nullptr;
757     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter1, g_option);
758     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
759 
760     /**
761      * @tc.steps: step2. use the second delegate to import the backup file.
762      * @tc.expected: step2. import failed and return busy
763      */
764     EXPECT_EQ(delegate2->Import(filePath, g_filePasswd1), BUSY);
765 
766     EXPECT_TRUE(manager2->CloseKvStore(delegate2) == OK);
767     delegate2 = nullptr;
768     delete manager2;
769     manager2 = nullptr;
770     /**
771      * @tc.steps: step3. delegate1 register observer.
772      * @tc.expected: step3. register success
773      */
774     KvStoreObserverImpl observerSync;
775     EXPECT_EQ(g_nbBackupDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observerSync), OK);
776     /**
777      * @tc.steps: step4. delegate1 import the backup file with the password f1.
778      * @tc.expected: step4. register success
779      */
780     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
781     RemoveDir(importPath);
782 }
783 
784 /*
785  * @tc.name: ImportTest 007
786  * @tc.desc: Verify that the DB registered conflict notifier or hadn't resultSet can't import the backup file.
787  * @tc.type: FUNC
788  * @tc.require: SR000D4878
789  * @tc.author: fengxiaoyun
790  */
791 HWTEST_F(DistributeddbNbBackupTest, ImportTest007, TestSize.Level1)
792 {
793     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
794     SetDir(importPath);
795     std::string filePath = importPath + "/bkpDB.bin";
796     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, g_filePasswd1), OK);
797 
798     /**
799      * @tc.steps: step1. register conflict notifier.
800      * @tc.expected: step1. register successfully.
801      */
802     ConflictNbCallback callback;
803     std::vector<ConflictData> conflictData;
804     auto notifier = bind(&ConflictNbCallback::NotifyCallBack, &callback, placeholders::_1, &conflictData);
805     EXPECT_EQ(g_nbBackupDelegate->SetConflictNotifier(CONFLICT_NATIVE_ALL, notifier), OK);
806     /**
807      * @tc.steps: step2. import the backup file with the password f1.
808      * @tc.expected: step2. import failed and returned BUSY.
809      */
810     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
811     EXPECT_EQ(g_nbBackupDelegate->SetConflictNotifier(CONFLICT_NATIVE_ALL, nullptr), OK);
812 
813     /**
814      * @tc.steps: step3. call GetEntries to get resultSet.
815      * @tc.expected: step3. get successfully.
816      */
817     KvStoreResultSet *resultSet;
818     EXPECT_EQ(g_nbBackupDelegate->GetEntries(KEY_K, resultSet), OK);
819     /**
820      * @tc.steps: step4. import the backup file with the password f1.
821      * @tc.expected: step4. import failed and returned BUSY.
822      */
823     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
824     EXPECT_EQ(g_nbBackupDelegate->CloseResultSet(resultSet), OK);
825 
826     RemoveDir(importPath);
827 }
828 
829 #ifndef LOW_LEVEL_MEM_DEV
830 /*
831  * @tc.name: ImportTest 008
832  * @tc.desc: Verify that it will return busy when GetKvStore again or crud during it is importing.
833  * @tc.type: FUNC
834  * @tc.require: SR000D4878
835  * @tc.author: fengxiaoyun
836  */
837 HWTEST_F(DistributeddbNbBackupTest, ImportTest008, TestSize.Level3)
838 {
839     vector<Entry> entries;
840     std::vector<DistributedDB::Key> allKeys;
841     GenerateFixedRecords(entries, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, TWO_M_LONG_STRING);
842     for (auto iter = entries.begin(); iter != entries.end(); iter++) {
843         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
844     }
845 
846     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
847     SetDir(importPath);
848     std::string filePath = importPath + "/bkpDB.bin";
849     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
850 
851     /**
852      * @tc.steps: step1. start subthread to import the backup file with empty password.
853      * @tc.expected: step1. start successfully if step1 running before step2, else return BUSY.
854      */
855     g_readyFlag.store(false);
__anonf63d79d80902() 856     thread subThread([&filePath]() {
857         DBStatus importStatus = g_nbBackupDelegate->Import(filePath, NULL_PASSWD);
858         EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
859         g_readyFlag.store(true);
860         g_backupVar.notify_one();
861     });
862     subThread.detach();
863 
864     /**
865      * @tc.steps: step2. GetKvStore again during the subthread is importing.
866      * @tc.expected: step2. GetKvStore failed and returned BUSY if step1 is running, else return OK.
867      */
868     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
869     KvStoreDelegateManager *manager = nullptr;
870     DBStatus statusReturn;
871     DistributedDBNbTestTools::GetNbDelegateStatus(manager, statusReturn, g_dbParameter1, g_option);
872     EXPECT_TRUE(statusReturn == BUSY || statusReturn == OK);
873     /**
874      * @tc.steps: step3. put (k1, v1) during the subthread is importing.
875      * @tc.expected: step3. put failed and returned BUSY if step1 is running, else return OK.
876      */
877     statusReturn = g_nbBackupDelegate->Put(KEY_1, VALUE_1);
878     EXPECT_TRUE(statusReturn == BUSY || statusReturn == OK);
879     std::mutex rekeyMtx;
880     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonf63d79d80a02null881     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
882     RemoveDir(importPath);
883 }
884 
885 #ifndef LOW_LEVEL_MEM_DEV
886 /*
887  * @tc.name: ImportTest 009
888  * @tc.desc: Verify that it will return busy when rekey during it is importing.
889  * @tc.type: FUNC
890  * @tc.require: SR000D4878
891  * @tc.author: fengxiaoyun
892  */
893 HWTEST_F(DistributeddbNbBackupTest, ImportTest009, TestSize.Level3)
894 {
895     vector<Entry> entriesRekey;
896     std::vector<DistributedDB::Key> allKeys;
897     GenerateFixedRecords(entriesRekey, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
898     for (auto iter = entriesRekey.begin(); iter != entriesRekey.end(); iter++) {
899         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
900     }
901 
902     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
903     SetDir(importPath);
904     std::string filePath = importPath + "/bkpDB.bin";
905     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
906 
907     /**
908      * @tc.steps: step1. start subthread to import the backup file with empty password.
909      * @tc.expected: step1. start successfully if step1 running before step2, else return BUSY.
910      */
911     g_readyFlag.store(false);
__anonf63d79d80b02() 912     thread subThread([&filePath]() {
913         DBStatus importStatus = g_nbBackupDelegate->Import(filePath, NULL_PASSWD);
914         EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
915         g_readyFlag.store(true);
916         g_backupVar.notify_one();
917     });
918     subThread.detach();
919     /**
920      * @tc.steps: step2. rekey  during the subthread is importing.
921      * @tc.expected: step2. rekey failed and returned BUSY if step1 is running, else return OK.
922      */
923     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LAST_SYNC));
924     DBStatus status = g_nbBackupDelegate->Rekey(g_passwd1);
925     EXPECT_TRUE(status == BUSY || status == OK);
926 
927     std::mutex rekeyMtx;
928     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonf63d79d80c02null929     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
930     RemoveDir(importPath);
931 }
932 #endif
933 
934 /*
935  * @tc.name: ImportTest 010
936  * @tc.desc: Verify that it will return busy when rekey during it is importing.
937  * @tc.type: FUNC
938  * @tc.require: SR000D4878
939  * @tc.author: fengxiaoyun
940  */
941 HWTEST_F(DistributeddbNbBackupTest, ImportTest010, TestSize.Level3)
942 {
943     vector<Entry> entriesRekey2;
944     std::vector<DistributedDB::Key> allKeys;
945     GenerateFixedRecords(entriesRekey2, allKeys, FIFTY_RECORDS, KEY_SIX_BYTE, TWO_M_LONG_STRING);
946     for (auto iter = entriesRekey2.begin(); iter != entriesRekey2.end(); iter++) {
947         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
948     }
949 
950     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
951     SetDir(importPath);
952     std::string filePath = importPath + "/bkpDB.bin";
953     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
954 
955     /**
956      * @tc.steps: step1. start subthread to rekey DB with password 1.
957      * @tc.expected: step1. start successfully.
958      */
959     g_readyFlag.store(false);
__anonf63d79d80d02() 960     thread subThread([]() {
961         EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
962         g_readyFlag.store(true);
963         g_backupVar.notify_one();
964     });
965     subThread.detach();
966     /**
967      * @tc.steps: step2. import the backup file during the subthread is rekeying.
968      * @tc.expected: step2. import failed and returned BUSY.
969      */
970     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LAST_SYNC));
971     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), BUSY);
972 
973     std::mutex rekeyMtx;
974     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonf63d79d80e02null975     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
976     RemoveDir(importPath);
977 }
978 #endif
979 
980 /*
981  * @tc.name: ImportTest 011
982  * @tc.desc: Verify that it will allow to import backup file again during it is importing.
983  * @tc.type: FUNC
984  * @tc.require: SR000D4878
985  * @tc.author: fengxiaoyun
986  */
987 HWTEST_F(DistributeddbNbBackupTest, ImportTest011, TestSize.Level3)
988 {
989     vector<Entry> entriesReImport;
990     std::vector<DistributedDB::Key> allKeys;
991     GenerateFixedRecords(entriesReImport, allKeys, TEN_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
992     for (auto iter = entriesReImport.begin(); iter != entriesReImport.end(); iter++) {
993         EXPECT_TRUE(g_nbBackupDelegate->Put(iter->key, iter->value) == OK);
994     }
995 
996     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
997     SetDir(importPath);
998     std::string filePath = importPath + "/bkpDB.bin";
999     EXPECT_EQ(g_nbBackupDelegate->Export(filePath, NULL_PASSWD), OK);
1000 
1001     /**
1002      * @tc.steps: step1. start subthread to import the backup file.
1003      * @tc.expected: step1. start successfully.
1004      */
1005     g_readyFlag.store(false);
__anonf63d79d80f02() 1006     thread subThread([&filePath]() {
1007         EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), OK);
1008         g_readyFlag.store(true);
1009         g_backupVar.notify_one();
1010     });
1011     subThread.detach();
1012     /**
1013      * @tc.steps: step2. import the backup file during the subthread is importing with empty password.
1014      * @tc.expected: step2. import successfully and return OK.
1015      */
1016     EXPECT_EQ(g_nbBackupDelegate->Import(filePath, NULL_PASSWD), OK);
1017 
1018     std::mutex rekeyMtx;
1019     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonf63d79d81002null1020     g_backupVar.wait(lck, [&]{ return g_readyFlag.load(); });
1021 
1022     RemoveDir(importPath);
1023 }
1024 
NbSubImportThread(int index,std::string importPath)1025 void NbSubImportThread(int index, std::string importPath)
1026 {
1027     vector<Entry> tenEntries;
1028     std::vector<DistributedDB::Key> allKeys;
1029     GenerateFixedRecords(tenEntries, allKeys, FIVE_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
1030     /**
1031      * @tc.steps: step1. every thread create one DB put 10 entries into the DB.
1032      * @tc.expected: step1. put successfully.
1033      */
1034     KvStoreNbDelegate *delegate2 = nullptr;
1035     KvStoreDelegateManager *manager2 = nullptr;
1036     DBParameters parameter[] = {g_dbParameter2, g_dbParameter3, g_dbParameter4, g_dbParameter5, g_dbParameter6};
1037     Option option[] = {g_createDiskUnencrypted, g_createDiskUnencrypted, g_createDiskUnencrypted,
1038         g_createDiskEncrypted, g_createDiskEncrypted};
1039     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, parameter[index], option[index]);
1040     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
1041 
1042     for (auto iter = tenEntries.begin(); iter != tenEntries.end(); iter++) {
1043         EXPECT_TRUE(delegate2->Put(iter->key, iter->value) == OK);
1044     }
1045 
1046     /**
1047      * @tc.steps: step2. every thread export DB to backup file.
1048      * @tc.expected: step2. export successfully.
1049      */
1050     DistributedDB::CipherPassword passwd[] = {NULL_PASSWD, NULL_PASSWD, NULL_PASSWD, g_filePasswd1, g_filePasswd2};
1051 
1052     const std::string backupFile[] = {"/bkpDB1.bin", "/bkpDB2.bin", "/bkpDB3.bin", "/bkpDB4.bin", "/bkpDB5.bin"};
1053     std::string nbFilePath[] = {(importPath + backupFile[INDEX_ZEROTH]), (importPath + backupFile[INDEX_FIRST]),
1054         (importPath + backupFile[INDEX_SECOND]), (importPath + backupFile[INDEX_THIRD]),
1055         (importPath + backupFile[INDEX_FORTH])};
1056     delegate2->Export(nbFilePath[index], passwd[index]);
1057 
1058     /**
1059      * @tc.steps: step3. every thread import backup file to DB.
1060      * @tc.expected: step3. import successfully.
1061      */
1062     EXPECT_EQ(delegate2->Import(nbFilePath[index], passwd[index]), OK);
1063     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
1064     delegate2 = nullptr;
1065     std::string storeId[] = {STORE_ID_2, STORE_ID_3, STORE_ID_4, STORE_ID_5, STORE_ID_6};
1066     EXPECT_TRUE(manager2->DeleteKvStore(storeId[index]) == OK);
1067     delete manager2;
1068     manager2 = nullptr;
1069 }
1070 
1071 /*
1072  * @tc.name: ImportTest 012
1073  * @tc.desc: Verify that different DB export and import in the same time won't affect each other.
1074  * @tc.type: FUNC
1075  * @tc.require: SR000D4878
1076  * @tc.author: fengxiaoyun
1077  */
1078 HWTEST_F(DistributeddbNbBackupTest, ImportTest012, TestSize.Level3)
1079 {
1080     std::vector<std::thread> threads;
1081     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
1082     SetDir(importPath);
1083     for (int index = 0; index < FIVE_TIMES; ++index) {
1084         threads.push_back(std::thread(NbSubImportThread, index, std::ref(importPath)));
1085     }
1086 
1087     for (auto& th : threads) {
1088         th.join();
1089     }
1090     RemoveDir(importPath);
1091 }
1092 
1093 /*
1094  * @tc.name: Exchange 001
1095  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1096  * @tc.type: FUNC
1097  * @tc.require: SR000D4878
1098  * @tc.author: fengxiaoyun
1099  */
1100 HWTEST_F(DistributeddbNbBackupTest, Exchange001, TestSize.Level1)
1101 {
1102     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1103     SetDir(exportPath);
1104     std::string filePath1 = exportPath + "/bkpDB1.bin";
1105     std::string filePath2 = exportPath + "/bkpDB2.bin";
1106     /**
1107      * @tc.steps: step1. export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1108      * @tc.expected: step1. call successfully.
1109      */
1110     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1111     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1112     /**
1113      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1114      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1115      */
1116     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1117     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1118     /**
1119      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1120      * @tc.expected: step3. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1121      */
1122     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1123     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1124     /**
1125      * @tc.steps: step4. rekey db1 with g_passwd1, and then import "bkpDB1.bin" and "bkpDB2.bin" with p1.
1126      * @tc.expected: step4. rekey succeeded and import failed.
1127      */
1128     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1129     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1130     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1131     /**
1132      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1133      * @tc.expected: step5. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1134      */
1135     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1136     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1137     /**
1138      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1139      * @tc.expected: step6. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1140      */
1141     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1142     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1143     RemoveDir(exportPath);
1144 }
1145 
1146 /*
1147  * @tc.name: Exchange 002
1148  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1149  * @tc.type: FUNC
1150  * @tc.require: SR000D4878
1151  * @tc.author: fengxiaoyun
1152  */
1153 HWTEST_F(DistributeddbNbBackupTest, Exchange002, TestSize.Level1)
1154 {
1155     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1156     SetDir(exportPath);
1157     std::string filePath1 = exportPath + "/bkpDB1.bin";
1158     std::string filePath2 = exportPath + "/bkpDB2.bin";
1159     /**
1160      * @tc.steps: step1. rekey db1 with g_passwd1,
1161      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1162      * @tc.expected: step1. call successfully.
1163      */
1164     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1165     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1166     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1167     /**
1168      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1169      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1170      */
1171     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1172     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1173     /**
1174      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1175      * @tc.expected: step3. rekey succeeded and import failed.
1176      */
1177     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1178     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1179     /**
1180      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1181      * @tc.expected: step4. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1182      */
1183     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1184     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1185     /**
1186      * @tc.steps: step5. rekey db1 with NULL_PASSWD,
1187      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1188      * @tc.expected: step5. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1189      */
1190     EXPECT_EQ(g_nbBackupDelegate->Rekey(NULL_PASSWD), OK);
1191     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1192     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1193     /**
1194      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1195      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1196      */
1197     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1198     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1199     RemoveDir(exportPath);
1200 }
1201 
1202 /*
1203  * @tc.name: Exchange 003
1204  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1205  * @tc.type: FUNC
1206  * @tc.require: SR000D4878
1207  * @tc.author: fengxiaoyun
1208  */
1209 HWTEST_F(DistributeddbNbBackupTest, Exchange003, TestSize.Level1)
1210 {
1211     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1212     SetDir(exportPath);
1213     std::string filePath1 = exportPath + "/bkpDB1.bin";
1214     std::string filePath2 = exportPath + "/bkpDB2.bin";
1215     /**
1216      * @tc.steps: step1. rekey db1 with g_passwd1,
1217      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1218      * @tc.expected: step1. call successfully.
1219      */
1220     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd1), OK);
1221     EXPECT_EQ(g_nbBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1222     EXPECT_EQ(g_nbBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1223     /**
1224      * @tc.steps: step2. rekey db1 with g_passwd2,
1225      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1226      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1227      */
1228     EXPECT_EQ(g_nbBackupDelegate->Rekey(g_passwd2), OK);
1229     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1230     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1231     /**
1232      * @tc.steps: step3. Put (k1,v1), close db, open db with g_passwd2 and delete (k1,v1)
1233      * @tc.expected: step3. operate successfully.
1234      */
1235     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), OK);
1236     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1237     g_nbBackupDelegate = nullptr;
1238     delete g_manager;
1239     g_manager = nullptr;
1240     Option encrypted(true, false, true, DistributedDB::CipherType::DEFAULT, PASSWD_VECTOR_2);
1241     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, encrypted);
1242     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1243     EXPECT_EQ(g_nbBackupDelegate->Delete(KEY_1), OK);
1244     /**
1245      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1246      * @tc.expected: step4. import failed.
1247      */
1248     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1249     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1250     /**
1251      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd2.
1252      * @tc.expected: step5. import failed.
1253      */
1254     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_passwd2), INVALID_FILE);
1255     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_passwd2), INVALID_FILE);
1256     /**
1257      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1258      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1259      */
1260     EXPECT_EQ(g_nbBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1261     EXPECT_EQ(g_nbBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1262     /**
1263      * @tc.steps: step7. Put (k2,v2), close db, open db with g_passwd2 and delete (k2,v2)
1264      * @tc.expected: step7. operate successfully.
1265      */
1266     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_2, VALUE_2), OK);
1267     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1268     g_nbBackupDelegate = nullptr;
1269     delete g_manager;
1270     g_manager = nullptr;
1271     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, encrypted);
1272     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1273     EXPECT_EQ(g_nbBackupDelegate->Delete(KEY_2), OK);
1274     RemoveDir(exportPath);
1275 }
1276 
1277 /*
1278  * @tc.name: CorruptionHandler 001
1279  * @tc.desc: Verify that the Corruption Handler can be set only one, if set many times, the last one is valid.
1280  * @tc.type: FUNC
1281  * @tc.require: SR000D4878
1282  * @tc.author: fengxiaoyun
1283  */
1284 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler001, TestSize.Level1)
1285 {
1286     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1287     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1288     SetDir(exportPath);
1289     std::string filePath = exportPath + "/bkpDB.bin";
1290     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
1291     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_1) == OK);
1292 
1293     /**
1294      * @tc.steps: step1. device A call SetKvStoreCorruptionHandler.
1295      * @tc.expected: step1. call successfully.
1296      */
1297     KvStoreNbCorruptInfo corruptInfo;
1298     KvStoreNbCorruptInfo corruptInfoNew;
1299     bool isCalled = false;
1300     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
1301         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
1302     g_manager->SetKvStoreCorruptionHandler(notifier);
1303     /**
1304      * @tc.steps: step2. device A call SetKvStoreCorruptionHandler the second time.
1305      * @tc.expected: step2. call successfully.
1306      */
1307     CallBackParam pathResult = {filePath, true};
1308     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptNewCallBack, &corruptInfoNew,
1309         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(g_manager), pathResult);
1310     g_manager->SetKvStoreCorruptionHandler(notifierNew);
1311     EXPECT_TRUE(pathResult.result);
1312     /**
1313      * @tc.steps: step3. make file corrupted and call GetKvStore to trigger callback function.
1314      * @tc.expected: step3. call successfully.
1315      */
1316     EXPECT_EQ((g_manager->CloseKvStore(g_nbBackupDelegate)), OK);
1317     g_nbBackupDelegate = nullptr;
1318     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1319     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1320     DBStatus status;
1321     KvStoreDelegateManager *manager = nullptr;
1322     EXPECT_EQ(DistributedDBNbTestTools::GetNbDelegateStatus(manager, status, g_dbParameter1, g_option), nullptr);
1323     EXPECT_EQ(status, INVALID_PASSWD_OR_CORRUPTED_DB);
1324     /**
1325      * @tc.steps: step4. open db and Get(k1) to verify importing in callback is successful.
1326      * @tc.expected: step4. Get(k1)=v1.
1327      */
1328     g_nbBackupDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
1329     ASSERT_TRUE(g_manager != nullptr && g_nbBackupDelegate != nullptr);
1330     Value valueResult;
1331     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, valueResult) == OK);
1332     EXPECT_EQ(valueResult, VALUE_1);
1333     g_manager->SetKvStoreCorruptionHandler(nullptr);
1334     RemoveDir(exportPath);
1335 }
1336 
1337 /*
1338  * @tc.name: CorruptionHandler 002
1339  * @tc.desc: Verify that can import db files and can't export in the Corruption Handler callback when db files
1340  * are corrupted in using.
1341  * @tc.type: FUNC
1342  * @tc.require: SR000D4878
1343  * @tc.author: fengxiaoyun
1344  */
1345 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler002, TestSize.Level2)
1346 {
1347     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1348     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1349     SetDir(exportPath);
1350     std::string filePath = exportPath + "/bkpDB.bin";
1351     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, g_filePasswd1) == OK);
1352 
1353     /**
1354      * @tc.steps: step1. device A call SetKvStoreCorruptionHandler to register CorruptCallBackOfImport.
1355      * @tc.expected: step1. call successfully.
1356      */
1357     KvStoreNbCorruptInfo corruptInfo;
1358     CallBackParam pathResult = {filePath, true};
1359     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfImport, &corruptInfo,
1360         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1361     g_manager->SetKvStoreCorruptionHandler(notifier);
1362     EXPECT_TRUE(pathResult.result);
1363     /**
1364      * @tc.steps: step2. device A modify the db files to trigger the CorruptCallBackOfImport and check.
1365      * @tc.expected: step2. operate successfully and import the recover db files in callback successfully.
1366      */
1367     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_1) == OK);
1368     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1369     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1370     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1371     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1372     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND)); // wait for callback complete for 1 second.
1373     Value valueResult;
1374     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, valueResult) == OK);
1375     EXPECT_EQ(valueResult, VALUE_1);
1376 
1377     /**
1378      * @tc.steps: step3. device A call SetKvStoreCorruptionHandler again to register CorruptCallBackOfExport.
1379      * @tc.expected: step3. call successfully.
1380      */
1381     filePath = exportPath + "/bkpDB1.bin";
1382     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfExport, &corruptInfo,
1383         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1384     g_manager->SetKvStoreCorruptionHandler(notifierNew);
1385     EXPECT_TRUE(pathResult.result);
1386 
1387     /**
1388      * @tc.steps: step4. device A modify the db files to trigger the CorruptCallBackOfExport and check.
1389      * @tc.expected: step4. operate successfully and export the recover db data in callback failed.
1390      */
1391     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1392     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1393     g_manager->SetKvStoreCorruptionHandler(nullptr);
1394     RemoveDir(exportPath);
1395 }
1396 
1397 /*
1398  * @tc.name: CorruptionHandler 003
1399  * @tc.desc: Verify that if call SetKvStoreCorruptionHandler(nullptr) will unregister the Corruption Handler.
1400  * @tc.type: FUNC
1401  * @tc.require: SR000D4878
1402  * @tc.author: fengxiaoyun
1403  */
1404 HWTEST_F(DistributeddbNbBackupTest, CorruptionHandler003, TestSize.Level2)
1405 {
1406     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1407     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
1408     SetDir(exportPath);
1409     std::string filePath = exportPath + "/bkpDB.bin";
1410     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, g_filePasswd1) == OK);
1411 
1412     /**
1413      * @tc.steps: step1. device A's db1 call SetKvStoreCorruptionHandler to register CorruptCallBack.
1414      * @tc.expected: step1. call successfully.
1415      */
1416     KvStoreNbCorruptInfo corruptInfo;
1417     bool isCalled = false;
1418     auto notifier = bind(&KvStoreNbCorruptInfo::CorruptCallBack, &corruptInfo,
1419         placeholders::_1, placeholders::_2, placeholders::_3, std::ref(isCalled));
1420     g_manager->SetKvStoreCorruptionHandler(notifier);
1421 
1422     /**
1423      * @tc.steps: step2. device A's db2 call SetKvStoreCorruptionHandler to register CorruptCallBackOfImport.
1424      * @tc.expected: step2. call successfully.
1425      */
1426     KvStoreDelegateManager *manager = nullptr;
1427     KvStoreNbDelegate *delegate = nullptr;
1428     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, g_option);
1429     ASSERT_TRUE(manager != nullptr && delegate != nullptr);
1430     KvStoreNbCorruptInfo corruptInfoNew;
1431     CallBackParam pathResult = {filePath, true};
1432     auto notifierNew = bind(&KvStoreNbCorruptInfo::CorruptCallBackOfImport, &corruptInfoNew,
1433         placeholders::_1, placeholders::_2, placeholders::_3, g_nbBackupDelegate, pathResult);
1434     manager->SetKvStoreCorruptionHandler(notifierNew);
1435     EXPECT_TRUE(pathResult.result);
1436 
1437     /**
1438      * @tc.steps: step3. device A modify the db files to trigger the CorruptCallBackOfImport and check.
1439      * @tc.expected: step3. operate successfully and import the recover db files in callback successfully.
1440      */
1441     std::string dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter1);
1442     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1443     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1444     EXPECT_EQ(g_nbBackupDelegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1445     std::this_thread::sleep_for(std::chrono::seconds(TWO_SECONDS)); // wait for callback complete for 1 second.
1446     Value valueResult;
1447     EXPECT_EQ(g_nbBackupDelegate->Get(KEY_1, valueResult), OK);
1448     EXPECT_EQ(valueResult, VALUE_1);
1449 
1450     /**
1451      * @tc.steps: step4. device A call SetKvStoreCorruptionHandler again to register nullptr.
1452      * @tc.expected: step4. call successfully.
1453      */
1454     manager->SetKvStoreCorruptionHandler(nullptr);
1455 
1456     /**
1457      * @tc.steps: step5. device A modify the db files to trigger the CorruptCallBack and check.
1458      * @tc.expected: step5. put return error but trigger the CorruptCallBack failed.
1459      */
1460     EXPECT_TRUE(delegate->Put(KEY_1, VALUE_1) == OK);
1461     dbFliePath = DistributedDBNbTestTools::GetKvNbStoreDirectory(g_dbParameter2);
1462     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath));
1463     EXPECT_TRUE(DistributedDBNbTestTools::ModifyDatabaseFile(dbFliePath + "-wal"));
1464     EXPECT_EQ(delegate->Put(KEY_1, VALUE_1), INVALID_PASSWD_OR_CORRUPTED_DB);
1465     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND)); // wait for callback complete for 1 second.
1466     EXPECT_EQ(delegate->Get(KEY_1, valueResult), INVALID_PASSWD_OR_CORRUPTED_DB);
1467 
1468     EXPECT_EQ((manager->CloseKvStore(delegate)), OK);
1469     delegate = nullptr;
1470     manager->DeleteKvStore(STORE_ID_2);
1471     delete manager;
1472     manager = nullptr;
1473     RemoveDir(exportPath);
1474 }
1475 #ifndef DB_DEBUG_ENV
1476 /*
1477  * @tc.name: CompatibilityTest 001
1478  * @tc.desc: test that use RELEASE_VERSION11.0.0 can import the export file by RELEASE_VERSION10.1.0.
1479  * @tc.type: Compatibility
1480  * @tc.require: SR000EPA24
1481  * @tc.author: fengxiaoyun
1482  */
1483 #ifdef NB_BACKUP
1484 HWTEST_F(DistributeddbNbBackupTest, CompatibilityTest001, TestSize.Level3)
1485 {
1486     const std::string exportPath = "/data/";
1487     std::string filePath = exportPath + "/RELEASE_VERSION1010.bin";
1488 #define COMPATIBILITYTEST_001
1489 #ifndef COMPATIBILITYTEST_001
1490     /**
1491      * @tc.steps: step1. create the db and put some data then export in RELEASE_VERSION10.1.0.
1492      * @tc.expected: step1. operate successfully.
1493      */
1494     EXPECT_TRUE(g_nbBackupDelegate->PutLocal(KEY_1, VALUE_1) == OK);
1495     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_1, VALUE_1) == OK);
1496     EXPECT_TRUE(g_nbBackupDelegate->PutLocal(KEY_2, VALUE_1) == OK);
1497     EXPECT_TRUE(g_nbBackupDelegate->Put(KEY_2, VALUE_2) == OK);
1498     EXPECT_TRUE(g_nbBackupDelegate->Delete(KEY_2) == OK);
1499     EXPECT_TRUE(g_nbBackupDelegate->Export(filePath, NULL_PASSWD) == OK);
1500 #else
1501     /**
1502      * @tc.steps: step2. import the export file by step1 and check data.
1503      * @tc.expected: step2. import successfully.
1504      */
1505     EXPECT_TRUE(g_nbBackupDelegate->Import(filePath, NULL_PASSWD) == OK);
1506     Value resultValue;
1507     EXPECT_TRUE(g_nbBackupDelegate->GetLocal(KEY_1, resultValue) == OK);
1508     EXPECT_TRUE(resultValue == VALUE_1);
1509     EXPECT_TRUE(g_nbBackupDelegate->GetLocal(KEY_2, resultValue) == OK);
1510     EXPECT_TRUE(resultValue == VALUE_1);
1511     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_1, resultValue) == OK);
1512     EXPECT_TRUE(resultValue == VALUE_1);
1513     EXPECT_TRUE(g_nbBackupDelegate->Get(KEY_2, resultValue) == NOT_FOUND);
1514 #endif
1515 }
1516 #endif
1517 #endif
1518 }