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