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