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