• 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 #ifndef OMIT_MULTI_VER
16 #include <gtest/gtest.h>
17 #include <ctime>
18 #include <cmath>
19 #include <random>
20 #include <chrono>
21 #include <fstream>
22 #include <string>
23 
24 #include "delegate_kv_mgr_callback.h"
25 #include "distributeddb_data_generator.h"
26 #include "distributed_test_tools.h"
27 #include "distributeddb_nb_test_tools.h"
28 #include "kv_store_delegate.h"
29 #include "kv_store_delegate_manager.h"
30 #include "process_communicator_test_stub.h"
31 
32 using namespace std;
33 using namespace chrono;
34 using namespace testing;
35 #if defined TESTCASES_USING_GTEST_EXT
36 using namespace testing::ext;
37 #endif
38 using namespace DistributedDB;
39 using namespace DistributedDBDataGenerator;
40 
41 namespace DistributeddbKvBackup {
42 static std::condition_variable g_kvBackupVar;
43 class DistributeddbKvBackupTest : public testing::Test {
44 public:
45     static void SetUpTestCase(void);
46     static void TearDownTestCase(void);
47     void SetUp();
48     void TearDown();
49 private:
50 };
51 
52 KvStoreDelegate *g_kvBackupDelegate = nullptr; // the delegate used in this suit.
53 KvStoreDelegateManager *g_manager = nullptr;
54 DistributedDB::CipherPassword g_passwd1;
55 DistributedDB::CipherPassword g_passwd2;
56 DistributedDB::CipherPassword g_filePasswd1;
57 DistributedDB::CipherPassword g_filePasswd2;
SetUpTestCase(void)58 void DistributeddbKvBackupTest::SetUpTestCase(void)
59 {
60     KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(APP_ID_1, USER_ID_1);
61     ASSERT_NE(manager, nullptr);
62     manager->SetProcessLabel("MST", "GetDevicesID");
63     manager->SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
64     delete manager;
65     manager = nullptr;
66     (void)g_passwd1.SetValue(PASSWD_VECTOR_1.data(), PASSWD_VECTOR_1.size());
67     (void)g_passwd2.SetValue(PASSWD_VECTOR_2.data(), PASSWD_VECTOR_2.size());
68     (void)g_filePasswd1.SetValue(FILE_PASSWD_VECTOR_1.data(), FILE_PASSWD_VECTOR_1.size());
69     (void)g_filePasswd2.SetValue(FILE_PASSWD_VECTOR_2.data(), FILE_PASSWD_VECTOR_2.size());
70 }
71 
TearDownTestCase(void)72 void DistributeddbKvBackupTest::TearDownTestCase(void)
73 {
74 }
75 
SetUp(void)76 void DistributeddbKvBackupTest::SetUp(void)
77 {
78     const std::string exportPath = DIRECTOR + "export";
79     RemoveDatabaseDirectory(exportPath);
80 
81     UnitTest *test = UnitTest::GetInstance();
82     ASSERT_NE(test, nullptr);
83     const TestInfo *testinfo = test->current_test_info();
84     ASSERT_NE(testinfo, nullptr);
85     string testCaseName = string(testinfo->name());
86     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
87 
88     KvOption option = g_kvOption;
89     g_kvBackupDelegate = DistributedTestTools::GetDelegateSuccess(g_manager, g_kvdbParameter1, option);
90     ASSERT_TRUE(g_manager != nullptr && g_kvBackupDelegate != nullptr);
91 }
92 
TearDown(void)93 void DistributeddbKvBackupTest::TearDown(void)
94 {
95     MST_LOG("TearDown after case.");
96     EXPECT_EQ(g_manager->CloseKvStore(g_kvBackupDelegate), OK);
97     g_kvBackupDelegate = nullptr;
98     DBStatus status = g_manager->DeleteKvStore(STORE_ID_1);
99     EXPECT_EQ(status, OK) << "fail to delete exist kvdb";
100     delete g_manager;
101     g_manager = nullptr;
102 }
103 
104 /*
105  * @tc.name: ExportTest 001
106  * @tc.desc: test checking in parameter of filepath of export interface .
107  * @tc.type: FUNC
108  * @tc.require: SR000D4878
109  * @tc.author: fengxiaoyun
110  */
111 HWTEST_F(DistributeddbKvBackupTest, ExportTest001, TestSize.Level1)
112 {
113     /**
114      * @tc.steps: step1. call export interface and the dir of filepath is nonexistent.
115      * @tc.expected: step1. call failed and return INVALID_ARGS.
116      */
117     int fileCount = 0;
118     const std::string exportPath = DIRECTOR + "export";
119     const std::string filePath = exportPath + "/bkpDB.bin";
120     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), INVALID_ARGS);
121 
122     /**
123      * @tc.steps: step2. call export interface, the filepath is absolute path and legal then check file number.
124      * @tc.expected: step2. call successfully and the file number is 1.
125      */
126     SetDir(exportPath);
127     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
128     CheckFileNumber(exportPath, fileCount);
129     EXPECT_EQ(fileCount, 1);
130     RemoveDir(exportPath);
131     RemoveDatabaseDirectory(exportPath);
132 
133     /**
134      * @tc.steps: step3. call export interface to export data and the dir of filepath is no r,w right.
135      * @tc.expected: step3. call failed return INVALID_ARGS.
136      */
137 #ifdef DB_DEBUG_ENV
138     const std::string noRightPath = "../noright";
139     const int authRight = 0111;
140     SetDir(noRightPath, authRight);
141     const std::string filePath2 = noRightPath + "/bkpDB.bin";
142     EXPECT_EQ(g_kvBackupDelegate->Export(filePath2, NULL_PASSWD), NO_PERMISSION);
143     RemoveDatabaseDirectory(noRightPath);
144 #endif
145     /**
146      * @tc.steps: step4. call export interface, the filepath is relative path and legal then check file number.
147      * @tc.expected: step4. call successfully and the file number is 1.
148      */
149     const std::string exportPath2 = "../export";
150     SetDir(exportPath2);
151     const std::string filePath3 = exportPath2 + "/bkpDB.bin";
152     EXPECT_EQ(g_kvBackupDelegate->Export(filePath3, NULL_PASSWD), OK);
153     CheckFileNumber(exportPath2, fileCount);
154     EXPECT_EQ(fileCount, 1);
155     RemoveDir(exportPath2);
156 }
157 
158 /*
159  * @tc.name: ExportTest 002
160  * @tc.desc: Verify that the export interface will return FILE_ALREADY_EXISTED if the export file has been exist.
161  * @tc.type: FUNC
162  * @tc.require: SR000D4878
163  * @tc.author: fengxiaoyun
164  */
165 HWTEST_F(DistributeddbKvBackupTest, ExportTest002, TestSize.Level1)
166 {
167     /**
168      * @tc.steps: step1. call export interface and the dir of filepath is legal then check file number.
169      * @tc.expected: step1. call successfully and the file number of filepath is 1.
170      */
171     int fileCount = 0;
172     const std::string exportPath = DIRECTOR + "export";
173     SetDir(exportPath);
174     const std::string filePath = exportPath + "/bkpDB.bin";
175     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
176     CheckFileNumber(exportPath, fileCount);
177     EXPECT_EQ(fileCount, 1); // the number of files is 1.
178 
179     /**
180      * @tc.steps: step2. call export interface and the directory of file is existent.
181      * @tc.expected: step2. call failed and return FILE_ALREADY_EXISTED.
182      */
183     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), FILE_ALREADY_EXISTED);
184     CheckFileNumber(exportPath, fileCount);
185     EXPECT_EQ(fileCount, 1); // the number of files is 1.
186     RemoveDir(exportPath);
187 }
188 
189 /*
190  * @tc.name: ExportTest003
191  * @tc.desc: Verify that call export will be block when there is uncommit or rollback transaction.
192  * @tc.type: FUNC
193  * @tc.require: SR000D4878
194  * @tc.author: fengxiaoyun
195  */
196 HWTEST_F(DistributeddbKvBackupTest, ExportTest003, TestSize.Level3)
197 {
198     /**
199      * @tc.steps: step1. start transaction and call export interface to export data.
200      * @tc.expected: step1. start transaction successfully call export is blocked.
201      */
202     EXPECT_EQ(g_kvBackupDelegate->StartTransaction(), OK);
203     int fileCount = 0;
204     const std::string exportPath = DIRECTOR + "export";
205     SetDir(exportPath);
206     std::string filePath = exportPath + "/bkpDB1.bin";
207     DBStatus status = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
208 
209     /**
210      * @tc.steps: step2. start thread to commit transaction and check the number of files in the exportion directory.
211      * @tc.expected: step2. commit successfully and the number of files is 1.
212      */
213     bool exportFlag = false;
__anonf52ba0670102() 214     thread subThread1([&]() {
215         DBStatus status = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
216         EXPECT_EQ(status, OK);
217         exportFlag = true;
218         g_kvBackupVar.notify_one();
219     });
220     subThread1.detach();
221     EXPECT_EQ(g_kvBackupDelegate->Commit(), OK);
222     std::mutex count;
223     {
224         std::unique_lock<std::mutex> lck(count);
__anonf52ba0670202null225         g_kvBackupVar.wait(lck, [&]{return exportFlag;});
226     }
227     CheckFileNumber(exportPath, fileCount);
228     EXPECT_EQ(fileCount, 1); // the number of files is 1.
229 
230     /**
231      * @tc.steps: step3. start transaction and call export interface to export data.
232      * @tc.expected: step3. start transaction successfully call export is blocked.
233      */
234     exportFlag = false;
235     EXPECT_EQ(g_kvBackupDelegate->StartTransaction(), OK);
236     filePath = exportPath + "/bkpDB2.bin";
237 
238     /**
239      * @tc.steps: step3. start thread to rollback transaction and check the number of files in the exportion directory.
240      * @tc.expected: step3. rollback successfully and the number of files is 2.
241      */
__anonf52ba0670302() 242     thread subThread2([&]() {
243         status = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
244         EXPECT_EQ(status, OK);
245         exportFlag = true;
246         g_kvBackupVar.notify_one();
247     });
248     subThread2.detach();
249     EXPECT_EQ(g_kvBackupDelegate->Rollback(), OK);
250     {
251         std::unique_lock<std::mutex> lck(count);
__anonf52ba0670402null252         g_kvBackupVar.wait(lck, [&]{return exportFlag;});
253     }
254     CheckFileNumber(exportPath, fileCount);
255     EXPECT_EQ(fileCount, 2); // the number of files is 2.
256     RemoveDir(exportPath);
257 }
258 
259 /*
260  * @tc.name: ExportTest 004
261  * @tc.desc: Verify that the export interface will return busy when the import hasn't completed.
262  * @tc.type: FUNC
263  * @tc.require: SR000D4878
264  * @tc.author: fengxiaoyun
265  */
266 HWTEST_F(DistributeddbKvBackupTest, ExportTest004, TestSize.Level2)
267 {
268     std::vector<DistributedDB::Entry> entriesBatch;
269     std::vector<DistributedDB::Key> allKeys;
270     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
271     DBStatus status = DistributedTestTools::PutBatch(*g_kvBackupDelegate, entriesBatch);
272     ASSERT_TRUE(status == DBStatus::OK);
273     int fileCount = 0;
274     const std::string exportPath = DIRECTOR + "export";
275     SetDir(exportPath);
276     std::string filePath = exportPath + "/bkpDB.bin";
277     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
278     CheckFileNumber(exportPath, fileCount);
279     EXPECT_EQ(fileCount, 1);
280 
281     /**
282      * @tc.steps: step1. call import interface to import the file that prepared in advance.
283      * @tc.expected: step1. call successfully.
284      */
285     bool importFlag = false;
__anonf52ba0670502() 286     thread subThread([&]() {
287         EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), OK);
288         importFlag = true;
289         g_kvBackupVar.notify_one();
290     });
291     subThread.detach();
292 
293     /**
294      * @tc.steps: step2. call export interface when step1 is running.
295      * @tc.expected: step2. return busy if step1 hasn't completed, else return OK.
296      */
297     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_TWO_HUNDREDS_MS));
298     filePath = exportPath + "/bkpDB1.bin";
299     status = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
300     EXPECT_TRUE(status == BUSY || status == OK);
301     CheckFileNumber(exportPath, fileCount);
302     if (status == BUSY) {
303         EXPECT_EQ(fileCount, 1); // the number of file is 1(Export is busy).
304     } else {
305         EXPECT_EQ(fileCount, 2); // the number of file is 2(Export is OK).
306     }
307 
308     std::mutex count;
309     std::unique_lock<std::mutex> lck(count);
__anonf52ba0670602null310     g_kvBackupVar.wait(lck, [&]{return importFlag;});
311     RemoveDir(exportPath);
312 }
313 
314 /*
315  * @tc.name: ExportTest 005
316  * @tc.desc: Verify that the export interface will return busy when the rekey hasn't completed.
317  * @tc.type: FUNC
318  * @tc.require: SR000D4878
319  * @tc.author: fengxiaoyun
320  */
321 HWTEST_F(DistributeddbKvBackupTest, ExportTest005, TestSize.Level2)
322 {
323     std::vector<DistributedDB::Entry> entriesBatch;
324     std::vector<DistributedDB::Key> allKeys;
325     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
326     DBStatus status = DistributedTestTools::PutBatch(*g_kvBackupDelegate, entriesBatch);
327     ASSERT_TRUE(status == DBStatus::OK);
328     /**
329      * @tc.steps: step1. call import interface to import the file that prepared in advance.
330      * @tc.expected: step1. call successfully.
331      */
332     bool rekeyFlag = false;
__anonf52ba0670702() 333     thread subThread([&]() {
334         DBStatus rekeyStatus = g_kvBackupDelegate->Rekey(g_passwd1);
335         EXPECT_EQ(rekeyStatus, OK);
336         rekeyFlag = true;
337         g_kvBackupVar.notify_one();
338     });
339     subThread.detach();
340 
341     /**
342      * @tc.steps: step2. call export interface when step1 is running.
343      * @tc.expected: step2. return busy if step1 hasn't completed, else return OK.
344      */
345     int fileCount = 0;
346     const std::string exportPath = DIRECTOR + "export";
347     SetDir(exportPath);
348     const std::string filePath = exportPath + "/bkpDB.bin";
349     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_TWO_HUNDREDS_MS));
350     status = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
351     EXPECT_TRUE(status == BUSY || status == OK);
352     CheckFileNumber(exportPath, fileCount);
353     if (status == BUSY) {
354         EXPECT_EQ(fileCount, 0); // 0 file if export failed.
355     } else {
356         EXPECT_EQ(fileCount, 1); // 1 file if export success.
357     }
358 
359     std::mutex count;
360     std::unique_lock<std::mutex> lck(count);
__anonf52ba0670802null361     g_kvBackupVar.wait(lck, [&]{return rekeyFlag;});
362     RemoveDir(exportPath);
363 }
364 
365 /*
366  * @tc.name: ExportTest 006
367  * @tc.desc: Verify that the export interface will execute blockly when last export hasn't completed.
368  * @tc.type: FUNC
369  * @tc.require: SR000D4878
370  * @tc.author: fengxiaoyun
371  */
372 HWTEST_F(DistributeddbKvBackupTest, ExportTest006, TestSize.Level2)
373 {
374     int fileCount = 0;
375     const std::string exportPath = DIRECTOR + "export";
376     SetDir(exportPath);
377     std::string filePath = exportPath + "/bkpDB.bin";
378     std::vector<DistributedDB::Entry> entriesBatch;
379     std::vector<DistributedDB::Key> allKeys;
380     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
381     DBStatus status = DistributedTestTools::PutBatch(*g_kvBackupDelegate, entriesBatch);
382     ASSERT_TRUE(status == DBStatus::OK);
383     /**
384      * @tc.steps: step1. call import interface to import the file that prepared in advance.
385      * @tc.expected: step1. call successfully.
386      */
387     bool exportFlag = false;
__anonf52ba0670902() 388     thread subThread([&]() {
389         DBStatus exportStatus = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
390         EXPECT_EQ(exportStatus, OK);
391         exportFlag = true;
392         g_kvBackupVar.notify_one();
393     });
394     subThread.detach();
395 
396     /**
397      * @tc.steps: step2. call export interface when step1 is running.
398      * @tc.expected: step2. return OK.
399      */
400     std::string filePath2 = exportPath + "/bkpDB1.bin";
401     std::this_thread::sleep_for(std::chrono::microseconds(MILLSECONDS_PER_SECOND));
402     EXPECT_EQ(g_kvBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
403 
404     std::mutex count;
405     std::unique_lock<std::mutex> lck(count);
__anonf52ba0670a02null406     g_kvBackupVar.wait(lck, [&]{return exportFlag;});
407     CheckFileNumber(exportPath, fileCount);
408     EXPECT_EQ(fileCount, 2); // the file number is 2.
409     RemoveDir(exportPath);
410 }
411 
412 /*
413  * @tc.name: ExportTest 007
414  * @tc.desc: Verify that the put/delete operation will execute blockly when export hasn't completed.
415  * @tc.type: FUNC
416  * @tc.require: SR000D4878
417  * @tc.author: fengxiaoyun
418  */
419 HWTEST_F(DistributeddbKvBackupTest, ExportTest007, TestSize.Level2)
420 {
421     vector<Entry> entriesPut;
422     entriesPut.push_back(ENTRY_1);
423     entriesPut.push_back(ENTRY_2);
424     int fileCount = 0;
425     const std::string exportPath = DIRECTOR + "export";
426     SetDir(exportPath);
427     std::string filePath = exportPath + "/bkpDB.bin";
428     std::vector<DistributedDB::Entry> entriesBatch;
429     std::vector<DistributedDB::Key> allKeys;
430     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
431     ASSERT_TRUE(DistributedTestTools::PutBatch(*g_kvBackupDelegate, entriesBatch) == OK);
432 
433     /**
434      * @tc.steps: step1. call export interface in subthread.
435      * @tc.expected: step1. call successfully.
436      */
437     bool exportFlag = false;
__anonf52ba0670b02() 438     thread subThread([&]() {
439         DBStatus exportStatus = g_kvBackupDelegate->Export(filePath, NULL_PASSWD);
440         EXPECT_EQ(exportStatus, OK);
441         exportFlag = true;
442         g_kvBackupVar.notify_all();
443     });
444     subThread.detach();
445 
446     /**
447      * @tc.steps: step2. call Get,GetLocal,GetEntries to query data from db.
448      * @tc.expected: step2. call successfully.
449      */
450     Value valueResult = DistributedTestTools::Get(*g_kvBackupDelegate, allKeys[0]);
451     EXPECT_NE(valueResult.size(), size_t(0));
452     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, entriesBatch[0].value));
453     vector<Entry> entries = DistributedTestTools::GetEntries(*g_kvBackupDelegate, KEY_EMPTY);
454     ASSERT_EQ(entries.size(), entriesBatch.size());
455 
456     /**
457      * @tc.steps: step3. call put/delete/putlocal/deletelocal interface when step1 is running.
458      * @tc.expected: step3. return ok.
459      */
460     DBStatus status = DistributedTestTools::Put(*g_kvBackupDelegate, entriesBatch[0].key, entriesBatch[0].value);
461     EXPECT_EQ(status, OK);
462     EXPECT_EQ(DistributedTestTools::PutBatch(*g_kvBackupDelegate, entriesPut), OK);
463     EXPECT_EQ(DistributedTestTools::Delete(*g_kvBackupDelegate, KEY_1), OK);
464     EXPECT_EQ(DistributedTestTools::DeleteBatch(*g_kvBackupDelegate, allKeys), OK);
465 
466     std::mutex count;
467     std::unique_lock<std::mutex> lck(count);
__anonf52ba0670c02null468     g_kvBackupVar.wait(lck, [&]{return exportFlag;});
469     CheckFileNumber(exportPath, fileCount);
470     EXPECT_EQ(fileCount, 1);
471     RemoveDir(exportPath);
472 }
473 
474 /*
475  * @tc.name: ExportTest 008
476  * @tc.desc: Verify that passwd parameter of export interface decide the file exported is encrypted or not.
477  * @tc.type: FUNC
478  * @tc.require: SR000D4878
479  * @tc.author: fengxiaoyun
480  */
481 HWTEST_F(DistributeddbKvBackupTest, ExportTest008, TestSize.Level1)
482 {
483     int fileCount = 0;
484     const std::string exportPath = DIRECTOR + "export";
485     SetDir(exportPath);
486     std::string filePath = exportPath + "/bkpDB1.bin";
487 
488     /**
489      * @tc.steps: step1. call export interface in subthread.
490      * @tc.expected: step1. call successfully.
491      */
492     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
493     CheckFileNumber(exportPath, fileCount);
494     EXPECT_EQ(fileCount, 1);
495 
496     /**
497      * @tc.steps: step2. call export interface with the passwd = password(129B).
498      * @tc.expected: step2. return INVALID_ARGS.
499      */
500     filePath = exportPath + "/bkpDB2.bin";
501     vector<uint8_t> passwordVector(PASSWD_BYTE, 'a');
502     CipherPassword password;
503     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OVERSIZE);
504     CheckFileNumber(exportPath, fileCount);
505     EXPECT_EQ(fileCount, 1);
506 
507     /**
508      * @tc.steps: step3. call export interface with the passwd = password(1B).
509      * @tc.expected: step3. return OK.
510      */
511     filePath = exportPath + "/bkpDB3.bin";
512     passwordVector.assign(1, 'b'); // 1 Byte of passwd.
513     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OK);
514     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, password), OK);
515     CheckFileNumber(exportPath, fileCount);
516     EXPECT_EQ(fileCount, 2); // the number of file is 2.
517 
518     /**
519      * @tc.steps: step3. call export interface with the passwd = password(128B).
520      * @tc.expected: step3. return OK.
521      */
522     filePath = exportPath + "/bkpDB4.bin";
523     passwordVector.assign(BATCH_RECORDS, 'b'); // 1 Byte of passwd.
524     EXPECT_EQ(password.SetValue(passwordVector.data(), passwordVector.size()), CipherPassword::ErrorCode::OK);
525     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, password), OK);
526     CheckFileNumber(exportPath, fileCount);
527     EXPECT_EQ(fileCount, 3); // the number of file is 3.
528     RemoveDir(exportPath);
529 }
530 
531 /*
532  * @tc.name: ImportTest 001
533  * @tc.desc: Verify that call import bkpfile with right password: none <-> none, password1 <-> password1.
534  * @tc.type: FUNC
535  * @tc.require: SR000D4878
536  * @tc.author: fengxiaoyun
537  */
538 HWTEST_F(DistributeddbKvBackupTest, ImportTest001, TestSize.Level2)
539 {
540     /**
541      * @tc.steps: step1. put (k1, v1) to device and update it to (k1, v2) after export the backup file.
542      * @tc.expected: step1. put and update successfully.
543      */
544     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
545     const std::string importPath = DIRECTOR + "export";
546     SetDir(importPath);
547     std::string filePath = importPath + "/bkpDB1.bin";
548     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
549     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_2), OK);
550 
551     /**
552      * @tc.steps: step2. call import interface with password f1.
553      * @tc.expected: step2. call failed and return INVALID_FILE.
554      */
555     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, g_filePasswd1), INVALID_FILE);
556 
557     /**
558      * @tc.steps: step3. call import interface with empty password and get the value of k1.
559      * @tc.expected: step3. call import interface successfully and the value of k1 is v1
560      */
561     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), OK);
562     Value valueGot = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_1);
563     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueGot, VALUE_1));
564 
565     /**
566      * @tc.steps: step4. put (k1, v2) to device for there is already encrypted backup file to update it to (k1, v1).
567      * @tc.expected: step4. put and update successfully.
568      */
569     filePath = importPath + "/bkpDB2.bin";
570     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, g_filePasswd1), OK);
571     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_2), OK);
572     /**
573      * @tc.steps: step5. call import interface with empty password.
574      * @tc.expected: step5. call failed and return INVALID_FILE.
575      */
576     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_FILE);
577 
578     /**
579      * @tc.steps: step6. call import interface with db password p1.
580      * @tc.expected: step6. call failed and return INVALID_FILE
581      */
582     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, g_passwd1), INVALID_FILE);
583 
584     /**
585      * @tc.steps: step7. call import interface with passwd = password(129B).
586      * @tc.expected: step7. call failed and return INVALID_ARGS
587      */
588     vector<uint8_t> passwordVector(PASSWD_BYTE, 'a');
589     CipherPassword invalidPassword;
590     EXPECT_EQ(invalidPassword.SetValue(passwordVector.data(), passwordVector.size()),
591         CipherPassword::ErrorCode::OVERSIZE);
592 
593     /**
594      * @tc.steps: step8. call import interface with password f1 and get the value of k1.
595      * @tc.expected: step8. call import interface successfully and the value of k1 is v1
596      */
597     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, g_filePasswd1), OK);
598     valueGot.clear();
599     valueGot = DistributedTestTools::Get(*g_kvBackupDelegate, KEY_1);
600     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueGot, VALUE_1));
601     RemoveDir(importPath);
602 }
603 
604 /*
605  * @tc.name: ImportTest 002
606  * @tc.desc: Verify that can't import when the file is not exist or the file path is wrong.
607  * @tc.type: FUNC
608  * @tc.require: SR000D4878
609  * @tc.author: fengxiaoyun
610  */
611 HWTEST_F(DistributeddbKvBackupTest, ImportTest002, TestSize.Level1)
612 {
613     std::string importPath1 = DIRECTOR + "export";
614     SetDir(importPath1);
615     std::string filePath = importPath1 + "/bkpDB1.bin";
616     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
617 
618     /**
619      * @tc.steps: step1. import the backup file 1 in the noexsit path.
620      * @tc.expected: step1. call failed and return INVALID_FILE.
621      */
622     std::string importPath2 = DIRECTOR + "noexsit";
623     filePath = importPath2 + "/bkpDB1.bin";
624     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_ARGS);
625 
626     /**
627      * @tc.steps: step2. import the no exist backup file 2 in the noexsit path.
628      * @tc.expected: step2. call failed and return INVALID_FILE
629      */
630     filePath = importPath1 + "/bkpDB2.bin";
631     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_FILE);
632     RemoveDir(importPath1);
633 }
634 
635 /*
636  * @tc.name: ImportTest 003
637  * @tc.desc: Verify that can't import when the file is not a right DB file or the DB file is damaged.
638  * @tc.type: FUNC
639  * @tc.require: SR000D4878
640  * @tc.author: fengxiaoyun
641  */
642 HWTEST_F(DistributeddbKvBackupTest, ImportTest003, TestSize.Level1)
643 {
644     const std::string importPath = DIRECTOR + "export";
645     SetDir(importPath);
646     std::string filePath = importPath + "/bkpDB.bin";
647     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
648 
649     /**
650      * @tc.steps: step1. import a.txt in the right path.
651      * @tc.expected: step1. call failed and return INVALID_FILE.
652      */
653     filePath = importPath + "/a.txt";
654     ofstream createFile(filePath);
655     if (createFile) {
656         createFile << '1' << endl;
657         createFile.close();
658     }
659     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_FILE);
660 
661     /**
662      * @tc.steps: step2. write some data to DB file1.
663      * @tc.expected: step2. write successfully
664      */
665     filePath = importPath + "/bkpDB.bin";
666     ofstream damageFile(filePath, ios::out | ios::binary);
667     ASSERT_TRUE(damageFile.is_open());
668     damageFile.write(reinterpret_cast<char *>(&filePath), filePath.size());
669     damageFile.close();
670 
671     /**
672      * @tc.steps: step3. import DB file with empty password.
673      * @tc.expected: step3. import failed and returned INVALID_FILE
674      */
675     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), INVALID_FILE);
676     RemoveDir(importPath);
677 }
678 
679 /*
680  * @tc.name: ImportTest 005
681  * @tc.desc: Verify that import will return busy when there are many delegate of the same db.
682  * @tc.type: FUNC
683  * @tc.require: SR000D4878
684  * @tc.author: fengxiaoyun
685  */
686 HWTEST_F(DistributeddbKvBackupTest, ImportTest005, TestSize.Level1)
687 {
688     const std::string importPath = DIRECTOR + "export";
689     SetDir(importPath);
690     std::string filePath = importPath + "/bkpDB1.bin";
691     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, g_filePasswd1), OK);
692 
693     /**
694      * @tc.steps: step1. open the other delegate of the same kvstore.
695      * @tc.expected: step1. open successfully.
696      */
697     KvStoreDelegate *delegate2 = nullptr;
698     KvStoreDelegateManager *manager2 = nullptr;
699     KvOption option = g_kvOption;
700     delegate2 = DistributedTestTools::GetDelegateSuccess(manager2, g_kvdbParameter1, option);
701     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
702     /**
703      * @tc.steps: step2. import the backup file of the same kvstore of g_kvdbParameter1.
704      * @tc.expected: step2. import failed and returned BUSY.
705      */
706     EXPECT_EQ(delegate2->Import(filePath, g_filePasswd1), BUSY);
707 
708     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
709     delegate2 = nullptr;
710     delete manager2;
711     manager2 = nullptr;
712     RemoveDir(importPath);
713 }
714 
715 /*
716  * @tc.name: ImportTest 006
717  * @tc.desc: Verify that if the DB register observer or snapshot, it can't import DB backup file.
718  * @tc.type: FUNC
719  * @tc.require: SR000D4878
720  * @tc.author: fengxiaoyun
721  */
722 HWTEST_F(DistributeddbKvBackupTest, ImportTest006, TestSize.Level1)
723 {
724     const std::string importPath = DIRECTOR + "export";
725     SetDir(importPath);
726     std::string filePath = importPath + "/bkpDB1.bin";
727     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, g_filePasswd1), OK);
728 
729     /**
730      * @tc.steps: step1. register the observer of DB of the same kvstore.
731      * @tc.expected: step1. create successfully.
732      */
733     KvStoreObserverImpl observer;
734     DBStatus status = DistributedTestTools::RegisterObserver(g_kvBackupDelegate, &observer);
735     EXPECT_EQ(status, OK);
736     /**
737      * @tc.steps: step2. import the backup file of the DB.
738      * @tc.expected: step2. import failed and returned BUSY.
739      */
740     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
741     /**
742      * @tc.steps: step3. unregister the observer and register the snap shot.
743      * @tc.expected: step3. unregister observer and register the snap shot successfully.
744      */
745     status = DistributedTestTools::UnRegisterObserver(g_kvBackupDelegate, &observer);
746     EXPECT_EQ(status, OK);
747     KvStoreSnapshotDelegate *snapShot = DistributedTestTools::RegisterSnapObserver(g_kvBackupDelegate, &observer);
748     EXPECT_NE(snapShot, nullptr);
749     /**
750      * @tc.steps: step4. import the backup file of the DB second time.
751      * @tc.expected: step4. import failed and returned BUSY.
752      */
753     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, g_filePasswd1), BUSY);
754     EXPECT_EQ(g_kvBackupDelegate->ReleaseKvStoreSnapshot(snapShot), OK);
755 
756     snapShot = nullptr;
757     RemoveDir(importPath);
758 }
759 
760 /*
761  * @tc.name: ImportTest 007
762  * @tc.desc: Verify that it will return busy if execute CRUD during it is importing.
763  * @tc.type: FUNC
764  * @tc.require: SR000D4878
765  * @tc.author: fengxiaoyun
766  */
767 HWTEST_F(DistributeddbKvBackupTest, ImportTest007, TestSize.Level2)
768 {
769     vector<Entry> entries;
770     std::vector<DistributedDB::Key> allKeys;
771     GenerateFixedRecords(entries, allKeys, TEN_RECORDS, KEY_SIX_BYTE, ONE_M_LONG_STRING);
772     for (auto iter = entries.begin(); iter != entries.end(); iter++) {
773         EXPECT_EQ(g_kvBackupDelegate->Put(iter->key, iter->value), OK);
774     }
775 
776     const std::string importPath = DIRECTOR + "export";
777     SetDir(importPath);
778     std::string filePath = importPath + "/bkpDB1.bin";
779     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
780 
781     /**
782      * @tc.steps: step1. start the sub thread to import a very big backup DB file.
783      * @tc.expected: step1. import successfully if step1 running before step2.
784      */
785     bool importFlag = false;
__anonf52ba0670d02() 786     thread subThread([&]() {
787         DBStatus importStatus = g_kvBackupDelegate->Import(filePath, NULL_PASSWD);
788         EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
789         importFlag = true;
790         g_kvBackupVar.notify_one();
791     });
792     subThread.detach();
793     /**
794      * @tc.steps: step2. get kvstore again during the sub thread is importing backup file.
795      * @tc.expected: step2. get failed and return BUSY if step1 is running, else return OK.
796      */
797     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
798     KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(APP_ID_1, USER_ID_1);
799     ASSERT_NE(manager, nullptr);
800     EXPECT_EQ(manager->SetKvStoreConfig(KV_CONFIG), OK);
801     DelegateKvMgrCallback getDelegateCallback;
802     function<void(DBStatus, KvStoreDelegate*)> function
803         = bind(&DelegateKvMgrCallback::Callback, &getDelegateCallback, std::placeholders::_1, std::placeholders::_2);
804     KvStoreDelegate::Option option = DistributedTestTools::TransferKvOptionType(g_kvOption);
805     manager->GetKvStore(g_kvdbParameter1.storeId, option, function);
806     DBStatus status = getDelegateCallback.GetStatus();
807     EXPECT_TRUE(status == BUSY || status == OK);
808     /**
809      * @tc.steps: step3. CRUD on DB during the sub thread is importing backup file.
810      * @tc.expected: step3. put failed and return BUSY.
811      */
812     status = g_kvBackupDelegate->Put(KEY_1, VALUE_1);
813     EXPECT_TRUE(status == BUSY || status == OK);
814     status = g_kvBackupDelegate->Put(KEY_1, VALUE_2);
815     EXPECT_TRUE(status == BUSY || status == OK);
816     status = g_kvBackupDelegate->Delete(KEY_1);
817     EXPECT_TRUE(status == BUSY || status == OK);
818 
819     std::mutex reGetKvStoreMtx;
820     std::unique_lock<std::mutex> lck(reGetKvStoreMtx);
__anonf52ba0670e02null821     g_kvBackupVar.wait(lck, [&]{return importFlag;});
822     delete manager;
823     manager = nullptr;
824     RemoveDir(importPath);
825 }
826 
827 /*
828  * @tc.name: ImportTest 008
829  * @tc.desc: Verify that it will return busy if it rekey during it is importing.
830  * @tc.type: FUNC
831  * @tc.require: SR000D4878
832  * @tc.author: fengxiaoyun
833  */
834 HWTEST_F(DistributeddbKvBackupTest, ImportTest008, TestSize.Level2)
835 {
836     vector<Entry> entriesRekey;
837     std::vector<DistributedDB::Key> allKeys;
838     GenerateFixedRecords(entriesRekey, allKeys, TEN_RECORDS, KEY_SIX_BYTE, ONE_M_LONG_STRING);
839     for (auto iter = entriesRekey.begin(); iter != entriesRekey.end(); iter++) {
840         EXPECT_EQ(g_kvBackupDelegate->Put(iter->key, iter->value), OK);
841     }
842 
843     const std::string importPath = DIRECTOR + "export";
844     SetDir(importPath);
845     std::string filePath = importPath + "/bkpDB.bin";
846     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
847 
848     /**
849      * @tc.steps: step1. start the sub thread to import a very big backup DB file.
850      * @tc.expected: step1. import successfully.
851      */
852     bool importFlag = false;
__anonf52ba0670f02() 853     thread subThread([&]() {
854         EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), OK);
855         importFlag = true;
856         g_kvBackupVar.notify_one();
857     });
858     subThread.detach();
859     /**
860      * @tc.steps: step2. rekey kvstore use p1 during the sub thread is importing backup file.
861      * @tc.expected: step2. rekey failed and return BUSY if step1 hasn't completed, else return OK.
862      */
863     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_TWO_HUNDREDS_MS));
864     DBStatus status = g_kvBackupDelegate->Rekey(g_passwd1);
865     EXPECT_TRUE(status == BUSY || status == OK);
866 
867     std::mutex reGetKvStoreMtx;
868     std::unique_lock<std::mutex> lck(reGetKvStoreMtx);
__anonf52ba0671002null869     g_kvBackupVar.wait(lck, [&]{return importFlag;});
870     RemoveDir(importPath);
871 }
872 
873 /*
874  * @tc.name: ImportTest 009
875  * @tc.desc: Verify that it will return busy if it import during it is rekeying.
876  * @tc.type: FUNC
877  * @tc.require: SR000D4878
878  * @tc.author: fengxiaoyun
879  */
880 HWTEST_F(DistributeddbKvBackupTest, ImportTest009, TestSize.Level2)
881 {
882     KvStoreDelegate *delegate2 = nullptr;
883     KvStoreDelegateManager *manager2 = nullptr;
884     KvOption option = g_createKvDiskUnencrypted;
885     delegate2 = DistributedTestTools::GetDelegateSuccess(manager2, g_kvdbParameter2, option);
886     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
887 
888     vector<Entry> entriesRekey;
889     std::vector<DistributedDB::Key> allKeys;
890     GenerateFixedRecords(entriesRekey, allKeys, TEN_RECORDS, KEY_SIX_BYTE, ONE_M_LONG_STRING);
891     for (auto iter = entriesRekey.begin(); iter != entriesRekey.end(); iter++) {
892         EXPECT_EQ(delegate2->Put(iter->key, iter->value), OK);
893     }
894 
895     const std::string importPath = DIRECTOR + "export";
896     SetDir(importPath);
897     std::string filePath = importPath + "/bkpDB.bin";
898     delegate2->Export(filePath, NULL_PASSWD);
899 
900     /**
901      * @tc.steps: step1. start the sub thread to import a very big backup DB file.
902      * @tc.expected: step1. import successfully.
903      */
904     bool rekeyFlag = false;
__anonf52ba0671102() 905     thread subThread([&]() {
906         EXPECT_EQ(delegate2->Rekey(g_passwd1), OK);
907         rekeyFlag = true;
908         g_kvBackupVar.notify_one();
909     });
910     subThread.detach();
911     /**
912      * @tc.steps: step2. rekey kvstore use p1 during the sub thread is importing backup file.
913      * @tc.expected: step2. rekey failed and return BUSY if step1 hasn't completed, else return OK.
914      */
915     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_TWO_HUNDREDS_MS));
916     DBStatus status = delegate2->Import(filePath, NULL_PASSWD);
917     EXPECT_TRUE(status == BUSY || status == OK);
918 
919     std::mutex rekeyMtx;
920     std::unique_lock<std::mutex> lck(rekeyMtx);
__anonf52ba0671202null921     g_kvBackupVar.wait(lck, [&]{return rekeyFlag;});
922 
923     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
924     delegate2 = nullptr;
925     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
926     delete manager2;
927     manager2 = nullptr;
928     RemoveDir(importPath);
929 }
930 
931 /*
932  * @tc.name: ImportTest 010
933  * @tc.desc: Verify that it will return busy if it import again during it is importing.
934  * @tc.type: FUNC
935  * @tc.require: SR000D4878
936  * @tc.author: fengxiaoyun
937  */
938 HWTEST_F(DistributeddbKvBackupTest, ImportTest010, TestSize.Level2)
939 {
940     vector<Entry> entriesRekey2;
941     std::vector<DistributedDB::Key> allKeys;
942     GenerateFixedRecords(entriesRekey2, allKeys, TEN_RECORDS, KEY_SIX_BYTE, ONE_M_LONG_STRING);
943     for (auto iter = entriesRekey2.begin(); iter != entriesRekey2.end(); iter++) {
944         EXPECT_EQ(g_kvBackupDelegate->Put(iter->key, iter->value), OK);
945     }
946 
947     const std::string importPath = DIRECTOR + "export";
948     SetDir(importPath);
949     std::string filePath = importPath + "/bkpDB.bin";
950     EXPECT_EQ(g_kvBackupDelegate->Export(filePath, NULL_PASSWD), OK);
951 
952     /**
953      * @tc.steps: step1. start the sub thread to import a very big backup DB file.
954      * @tc.expected: step1. import successfully.
955      */
956     bool importFlag = false;
__anonf52ba0671302() 957     thread subThread([&]() {
958         EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), OK);
959         importFlag = true;
960         g_kvBackupVar.notify_one();
961     });
962     subThread.detach();
963     /**
964      * @tc.steps: step2. import the backup file again during the sub thread is importing.
965      * @tc.expected: step2. call import interface failed and return BUSY.
966      */
967     std::this_thread::sleep_for(std::chrono::microseconds(MILLSECONDS_PER_SECOND));
968     EXPECT_EQ(g_kvBackupDelegate->Import(filePath, NULL_PASSWD), OK);
969 
970     std::mutex reImportMtx;
971     std::unique_lock<std::mutex> lck(reImportMtx);
__anonf52ba0671402null972     g_kvBackupVar.wait(lck, [&]{return importFlag;});
973     RemoveDir(importPath);
974 }
975 
KvSubImportThread(int index,std::string importPath)976 void KvSubImportThread(int index, std::string importPath)
977 {
978     vector<Entry> tenEntries;
979     std::vector<DistributedDB::Key> allKeys;
980     GenerateFixedRecords(tenEntries, allKeys, TEN_RECORDS, KEY_SIX_BYTE, FOUR_M_LONG_STRING);
981     /**
982      * @tc.steps: step1. every thread create one DB put 10 entries into the DB.
983      * @tc.expected: step1. put successfully.
984      */
985     KvStoreDelegate *delegate2 = nullptr;
986     KvStoreDelegateManager *manager2 = nullptr;
987     KvOption option[] = {g_createKvDiskUnencrypted, g_createKvDiskUnencrypted, g_createKvDiskUnencrypted,
988         g_createKvDiskEncrypted, g_createKvDiskEncrypted};
989     KvDBParameters parameter[] = {g_kvdbParameter2, g_kvdbParameter3, g_kvdbParameter4,
990         g_kvdbParameter5, g_kvdbParameter6};
991     delegate2 = DistributedTestTools::GetDelegateSuccess(manager2, parameter[index], option[index]);
992     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr);
993     for (auto iter = tenEntries.begin(); iter != tenEntries.end(); iter++) {
994         EXPECT_EQ(delegate2->Put(iter->key, iter->value), OK);
995     }
996 
997     /**
998      * @tc.steps: step2. every thread export DB to backup file.
999      * @tc.expected: step2. export successfully.
1000      */
1001     DistributedDB::CipherPassword passwd[] = {NULL_PASSWD, NULL_PASSWD, NULL_PASSWD, g_filePasswd1, g_filePasswd2};
1002     const std::string backupFile[] = {"/bkpDB1.bin", "/bkpDB2.bin", "/bkpDB3.bin", "/bkpDB4.bin", "/bkpDB5.bin"};
1003     std::string filePath[] = {(importPath + backupFile[INDEX_ZEROTH]), (importPath + backupFile[INDEX_FIRST]),
1004         (importPath + backupFile[INDEX_SECOND]), (importPath + backupFile[INDEX_THIRD]),
1005         (importPath + backupFile[INDEX_FORTH])};
1006     delegate2->Export(filePath[index], passwd[index]);
1007 
1008     /**
1009      * @tc.steps: step3. every thread import backup file to DB.
1010      * @tc.expected: step3. import successfully.
1011      */
1012     EXPECT_EQ(delegate2->Import(filePath[index], passwd[index]), OK);
1013     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
1014     delegate2 = nullptr;
1015     std::string storeId[] = {STORE_ID_2, STORE_ID_3, STORE_ID_4, STORE_ID_5, STORE_ID_6};
1016     EXPECT_EQ(manager2->DeleteKvStore(storeId[index]), OK);
1017     delete manager2;
1018     manager2 = nullptr;
1019 }
1020 
1021 /*
1022  * @tc.name: ImportTest 011
1023  * @tc.desc: Verify that different DB export and import in the same time don't affect each other.
1024  * @tc.type: FUNC
1025  * @tc.require: SR000D4878
1026  * @tc.author: fengxiaoyun
1027  */
1028 HWTEST_F(DistributeddbKvBackupTest, ImportTest011, TestSize.Level3)
1029 {
1030     std::vector<std::thread> threads;
1031     const std::string importPath = DIRECTOR + "export";
1032     SetDir(importPath);
1033     for (int index = 0; index < FIVE_TIMES; ++index) {
1034         threads.push_back(std::thread(KvSubImportThread, index, std::ref(importPath)));
1035     }
1036 
1037     for (auto& th : threads) {
1038         th.join();
1039     }
1040     RemoveDir(importPath);
1041 }
1042 
1043 /*
1044  * @tc.name: Exchange 001
1045  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1046  * @tc.type: FUNC
1047  * @tc.require: SR000D4878
1048  * @tc.author: fengxiaoyun
1049  */
1050 HWTEST_F(DistributeddbKvBackupTest, Exchange001, TestSize.Level2)
1051 {
1052     const std::string exportPath = DIRECTOR + "export";
1053     SetDir(exportPath);
1054     std::string filePath1 = exportPath + "/bkpDB1.bin";
1055     std::string filePath2 = exportPath + "/bkpDB2.bin";
1056     /**
1057      * @tc.steps: step1. export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1058      * @tc.expected: step1. call successfully.
1059      */
1060     EXPECT_EQ(g_kvBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1061     EXPECT_EQ(g_kvBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1062     /**
1063      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1064      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1065      */
1066     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1067     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1068     /**
1069      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1070      * @tc.expected: step3. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1071      */
1072     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1073     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1074     /**
1075      * @tc.steps: step4. rekey db1 with g_passwd1, and then import "bkpDB1.bin" and "bkpDB2.bin" with p1.
1076      * @tc.expected: step4. rekey succeeded and import failed.
1077      */
1078     EXPECT_EQ(g_kvBackupDelegate->Rekey(g_passwd1), OK);
1079     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1080     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1081     /**
1082      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1083      * @tc.expected: step5. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1084      */
1085     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1086     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1087     /**
1088      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1089      * @tc.expected: step6. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1090      */
1091     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1092     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1093     RemoveDir(exportPath);
1094 }
1095 
1096 /*
1097  * @tc.name: Exchange 002
1098  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1099  * @tc.type: FUNC
1100  * @tc.require: SR000D4878
1101  * @tc.author: fengxiaoyun
1102  */
1103 HWTEST_F(DistributeddbKvBackupTest, Exchange002, TestSize.Level2)
1104 {
1105     const std::string exportPath = DIRECTOR + "export";
1106     SetDir(exportPath);
1107     std::string filePath1 = exportPath + "/bkpDB1.bin";
1108     std::string filePath2 = exportPath + "/bkpDB2.bin";
1109     /**
1110      * @tc.steps: step1. rekey db1 with g_passwd1,
1111      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1112      * @tc.expected: step1. call successfully.
1113      */
1114     EXPECT_EQ(g_kvBackupDelegate->Rekey(g_passwd1), OK);
1115     EXPECT_EQ(g_kvBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1116     EXPECT_EQ(g_kvBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1117     /**
1118      * @tc.steps: step2. import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1119      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1120      */
1121     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1122     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1123     /**
1124      * @tc.steps: step3. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1125      * @tc.expected: step3. rekey succeeded and import failed.
1126      */
1127     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1128     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1129     /**
1130      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1131      * @tc.expected: step4. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1132      */
1133     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1134     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1135     /**
1136      * @tc.steps: step5. rekey db1 with NULL_PASSWD,
1137      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1138      * @tc.expected: step5. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1139      */
1140     EXPECT_EQ(g_kvBackupDelegate->Rekey(NULL_PASSWD), OK);
1141     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1142     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1143     /**
1144      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1145      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1146      */
1147     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1148     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1149     RemoveDir(exportPath);
1150 }
1151 
1152 /*
1153  * @tc.name: Exchange 003
1154  * @tc.desc: whether current db is encrypted or not, import file need to use exported password(or NULL_PASSWD).
1155  * @tc.type: FUNC
1156  * @tc.require: SR000D4878
1157  * @tc.author: fengxiaoyun
1158  */
1159 HWTEST_F(DistributeddbKvBackupTest, Exchange003, TestSize.Level2)
1160 {
1161     const std::string exportPath = DIRECTOR + "export";
1162     SetDir(exportPath);
1163     std::string filePath1 = exportPath + "/bkpDB1.bin";
1164     std::string filePath2 = exportPath + "/bkpDB2.bin";
1165     /**
1166      * @tc.steps: step1. rekey db1 with g_passwd1,
1167      *  export data as "bkpDB1.bin" with passwd g_filePasswd1 and "bkpDB2.bin" with NULL_PASSWD.
1168      * @tc.expected: step1. call successfully.
1169      */
1170     EXPECT_EQ(g_kvBackupDelegate->Rekey(g_passwd1), OK);
1171     EXPECT_EQ(g_kvBackupDelegate->Export(filePath1, g_filePasswd1), OK);
1172     EXPECT_EQ(g_kvBackupDelegate->Export(filePath2, NULL_PASSWD), OK);
1173     /**
1174      * @tc.steps: step2. rekey db1 with g_passwd2,
1175      *  import "bkpDB1.bin" and "bkpDB2.bin" with NULL_PASSWD.
1176      * @tc.expected: step2. import "bkpDB1.bin" failed and import "bkpDB2.bin" succeeded.
1177      */
1178     EXPECT_EQ(g_kvBackupDelegate->Rekey(g_passwd2), OK);
1179     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, NULL_PASSWD), INVALID_FILE);
1180     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, NULL_PASSWD), OK);
1181     /**
1182      * @tc.steps: step3. Put (k1,v1), close db, open db with g_passwd2 and delete (k1,v1)
1183      * @tc.expected: step3. operate successfully.
1184      */
1185     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_1, VALUE_1), OK);
1186     EXPECT_EQ((g_manager->CloseKvStore(g_kvBackupDelegate)), OK);
1187     g_kvBackupDelegate = nullptr;
1188     delete g_manager;
1189     g_manager = nullptr;
1190     KvOption kvEncrypted(true, false, true, DistributedDB::CipherType::DEFAULT,
1191         DistributedDBDataGenerator::PASSWD_VECTOR_2);
1192     g_kvBackupDelegate = DistributedTestTools::GetDelegateSuccess(g_manager, g_kvdbParameter1, kvEncrypted);
1193     ASSERT_TRUE(g_manager != nullptr && g_kvBackupDelegate != nullptr);
1194     EXPECT_EQ(g_kvBackupDelegate->Delete(KEY_1), OK);
1195     /**
1196      * @tc.steps: step4. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd1.
1197      * @tc.expected: step4. import failed.
1198      */
1199     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_passwd1), INVALID_FILE);
1200     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_passwd1), INVALID_FILE);
1201     /**
1202      * @tc.steps: step5. import "bkpDB1.bin" and "bkpDB2.bin" with g_passwd2.
1203      * @tc.expected: step5. import failed.
1204      */
1205     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_passwd2), INVALID_FILE);
1206     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_passwd2), INVALID_FILE);
1207     /**
1208      * @tc.steps: step6. import "bkpDB1.bin" and "bkpDB2.bin" with g_filePasswd1.
1209      * @tc.expected: step6. import "bkpDB1.bin" succeeded and import "bkpDB2.bin" failed.
1210      */
1211     EXPECT_EQ(g_kvBackupDelegate->Import(filePath1, g_filePasswd1), OK);
1212     EXPECT_EQ(g_kvBackupDelegate->Import(filePath2, g_filePasswd1), INVALID_FILE);
1213     /**
1214      * @tc.steps: step7. Put (k2,v2), close db, open db with g_passwd2 and delete (k2,v2)
1215      * @tc.expected: step7. operate successfully.
1216      */
1217     EXPECT_EQ(g_kvBackupDelegate->Put(KEY_2, VALUE_2), OK);
1218     EXPECT_EQ((g_manager->CloseKvStore(g_kvBackupDelegate)), OK);
1219     g_kvBackupDelegate = nullptr;
1220     delete g_manager;
1221     g_manager = nullptr;
1222     g_kvBackupDelegate = DistributedTestTools::GetDelegateSuccess(g_manager, g_kvdbParameter1, kvEncrypted);
1223     ASSERT_TRUE(g_manager != nullptr && g_kvBackupDelegate != nullptr);
1224     EXPECT_EQ(g_kvBackupDelegate->Delete(KEY_2), OK);
1225     RemoveDir(exportPath);
1226 }
1227 }
1228 #endif // OMIT_MULTI_VER