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_ENCRYPT
16 #include <gtest/gtest.h>
17
18 #include "distributeddb_data_generate_unit_test.h"
19 #include "distributeddb_tools_unit_test.h"
20 #include "platform_specific.h"
21
22 using namespace testing::ext;
23 using namespace DistributedDB;
24 using namespace DistributedDBUnitTest;
25 using namespace std;
26
27 namespace {
28 string g_testDir;
29
30 const string STORE_ID1 = "store1";
31 const string STORE_ID2 = "store2";
32
33 KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
34 KvStoreConfig g_config;
35 }
36
37 class DistributedDBInterfacesEncryptDatabaseTest : public testing::Test {
38 public:
39 static void SetUpTestCase(void);
40 static void TearDownTestCase(void);
41 static void CheckRekeyWithMultiKvStore(bool isLocal);
42 static void CheckRekeyWithExistedSnapshot(bool isLocal);
43 static void CheckRekeyWithExistedObserver(bool isLocal);
44 void SetUp();
45 void TearDown();
46 };
47
SetUpTestCase(void)48 void DistributedDBInterfacesEncryptDatabaseTest::SetUpTestCase(void)
49 {
50 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
51 g_config.dataDir = g_testDir;
52 g_mgr.SetKvStoreConfig(g_config);
53 }
54
TearDownTestCase(void)55 void DistributedDBInterfacesEncryptDatabaseTest::TearDownTestCase(void)
56 {
57 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
58 LOGE("rm test db files error!");
59 }
60 }
61
SetUp(void)62 void DistributedDBInterfacesEncryptDatabaseTest::SetUp(void)
63 {
64 DistributedDBToolsUnitTest::PrintTestCaseInfo();
65 }
66
TearDown(void)67 void DistributedDBInterfacesEncryptDatabaseTest::TearDown(void)
68 {
69 }
70
CheckRekeyWithMultiKvStore(bool isLocal)71 void DistributedDBInterfacesEncryptDatabaseTest::CheckRekeyWithMultiKvStore(bool isLocal)
72 {
73 DBStatus status;
74 KvStoreDelegate *kvStore1 = nullptr;
75 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
76 placeholders::_2, std::ref(status), std::ref(kvStore1));
77 /**
78 * @tc.steps:step1. Get the delegate.
79 */
80 KvStoreDelegate::Option option = {true, isLocal, false};
81 g_mgr.GetKvStore(STORE_ID1, option, delegateCallback);
82 ASSERT_TRUE(kvStore1 != nullptr);
83
84 KvStoreDelegate *kvStore2 = nullptr;
85 auto delegateCallback2 = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
86 placeholders::_2, std::ref(status), std::ref(kvStore2));
87 /**
88 * @tc.steps:step2. Get another delegate.
89 */
90 option.createIfNecessary = false;
91 g_mgr.GetKvStore(STORE_ID1, option, delegateCallback2);
92 ASSERT_TRUE(kvStore2 != nullptr);
93
94 /**
95 * @tc.steps:step3. Execute the rekey operation.
96 * @tc.expected: step3. return BUSY.
97 */
98 CipherPassword passwd; // random password
99 vector<uint8_t> passwdBuffer(10, 45); // 10 and 45 as random password.
100 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
101 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
102 EXPECT_EQ(kvStore1->Rekey(passwd), BUSY);
103 /**
104 * @tc.steps:step4. Close the kv store delegate.
105 */
106 EXPECT_EQ(g_mgr.CloseKvStore(kvStore2), OK);
107 /**
108 * @tc.steps:step5. Execute the rekey operation.
109 * @tc.expected: step5. return OK.
110 */
111 EXPECT_EQ(kvStore1->Rekey(passwd), OK);
112 EXPECT_EQ(g_mgr.CloseKvStore(kvStore1), OK);
113 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID1), OK);
114 }
115
CheckRekeyWithExistedSnapshot(bool isLocal)116 void DistributedDBInterfacesEncryptDatabaseTest::CheckRekeyWithExistedSnapshot(bool isLocal)
117 {
118 DBStatus status;
119 KvStoreDelegate *kvStore = nullptr;
120 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
121 placeholders::_2, std::ref(status), std::ref(kvStore));
122 /**
123 * @tc.steps:step1. Get the delegate.
124 */
125 KvStoreDelegate::Option option = {true, isLocal, false};
126 g_mgr.GetKvStore(STORE_ID1, option, delegateCallback);
127 ASSERT_TRUE(kvStore != nullptr);
128
129 KvStoreSnapshotDelegate *snapshot = nullptr;
130 auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
131 placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshot));
132 /**
133 * @tc.steps:step2. Get the snapshot through the delegate.
134 */
135 kvStore->GetKvStoreSnapshot(nullptr, snapshotDelegateCallback);
136 EXPECT_NE(snapshot, nullptr);
137 /**
138 * @tc.steps:step3. Execute the rekey operation.
139 * @tc.expected: step3. return BUSY.
140 */
141 CipherPassword passwd; // random password
142 vector<uint8_t> passwdBuffer(10, 45); // 10 and 45 as random password.
143 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
144 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
145 EXPECT_EQ(kvStore->Rekey(passwd), BUSY);
146 /**
147 * @tc.steps:step4. Release the snapshot.
148 */
149 EXPECT_EQ(kvStore->ReleaseKvStoreSnapshot(snapshot), OK);
150 /**
151 * @tc.steps:step5. Execute the rekey operation.
152 * @tc.expected: step5. return OK.
153 */
154 EXPECT_EQ(kvStore->Rekey(passwd), OK);
155 EXPECT_EQ(g_mgr.CloseKvStore(kvStore), OK);
156 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID1), OK);
157 }
158
CheckRekeyWithExistedObserver(bool isLocal)159 void DistributedDBInterfacesEncryptDatabaseTest::CheckRekeyWithExistedObserver(bool isLocal)
160 {
161 DBStatus status;
162 KvStoreDelegate *kvStore = nullptr;
163 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
164 placeholders::_2, std::ref(status), std::ref(kvStore));
165 /**
166 * @tc.steps:step1. Get the delegate.
167 */
168 KvStoreDelegate::Option option = {true, isLocal, false};
169 g_mgr.GetKvStore(STORE_ID1, option, delegateCallback);
170 ASSERT_TRUE(kvStore != nullptr);
171 /**
172 * @tc.steps:step2. Register the non-null observer.
173 */
174 auto observer = new (std::nothrow) KvStoreObserverUnitTest;
175 ASSERT_TRUE(observer != nullptr);
176 ASSERT_EQ(kvStore->RegisterObserver(observer), OK);
177 /**
178 * @tc.steps:step3. Execute the rekey operation.
179 * @tc.expected: step3. return BUSY.
180 */
181 CipherPassword passwd; // random password
182 vector<uint8_t> passwdBuffer(10, 45); // 10 and 45 as random password.
183 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
184 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
185 EXPECT_EQ(kvStore->Rekey(passwd), BUSY);
186 /**
187 * @tc.steps:step4. Unregister the observer.
188 */
189 EXPECT_EQ(kvStore->UnRegisterObserver(observer), OK);
190 delete observer;
191 observer = nullptr;
192 /**
193 * @tc.steps:step5. Execute the rekey operation.
194 * @tc.expected: step5. return OK.
195 */
196 EXPECT_EQ(kvStore->Rekey(passwd), OK);
197 EXPECT_EQ(g_mgr.CloseKvStore(kvStore), OK);
198 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID1), OK);
199 }
200
201 /**
202 * @tc.name: LocalDatabaseRekeyCheck001
203 * @tc.desc: Attempt to rekey while another delegate is existed.
204 * @tc.type: FUNC
205 * @tc.require: AR000CQDT7
206 * @tc.author: wumin
207 */
208 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, LocalDatabaseRekeyCheck001, TestSize.Level1)
209 {
210 /**
211 * @tc.steps:step1. Get the local delegate.
212 */
213 /**
214 * @tc.steps:step2. Get another local delegate.
215 */
216 /**
217 * @tc.steps:step3. Execute the rekey operation.
218 * @tc.expected: step3. return BUSY.
219 */
220 /**
221 * @tc.steps:step4. Close the kv store delegate.
222 */
223 /**
224 * @tc.steps:step5. Execute the rekey operation.
225 * @tc.expected: step5. return OK.
226 */
227 CheckRekeyWithMultiKvStore(true);
228 }
229
230 /**
231 * @tc.name: LocalDatabaseRekeyCheck002
232 * @tc.desc: Attempt to rekey while the snapshot is existed.
233 * @tc.type: FUNC
234 * @tc.require: AR000CQDT7
235 * @tc.author: wumin
236 */
237 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, LocalDatabaseRekeyCheck002, TestSize.Level1)
238 {
239 /**
240 * @tc.steps:step1. Get the local delegate.
241 */
242 /**
243 * @tc.steps:step2. Get the snapshot through the delegate.
244 */
245 /**
246 * @tc.steps:step3. Execute the rekey operation.
247 * @tc.expected: step3. return BUSY.
248 */
249 /**
250 * @tc.steps:step4. Release the snapshot.
251 */
252 /**
253 * @tc.steps:step5. Execute the rekey operation.
254 * @tc.expected: step5. return OK.
255 */
256 CheckRekeyWithExistedSnapshot(true);
257 }
258
259 /**
260 * @tc.name: MultiVerRekeyCheck001
261 * @tc.desc: Attempt to rekey while another delegate is existed.
262 * @tc.type: FUNC
263 * @tc.require: AR000CQDT7
264 * @tc.author: wumin
265 */
266 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, MultiVerRekeyCheck001, TestSize.Level1)
267 {
268 /**
269 * @tc.steps:step1. Get the multi version delegate.
270 */
271 /**
272 * @tc.steps:step2. Get another multi version delegate.
273 */
274 /**
275 * @tc.steps:step3. Execute the rekey operation.
276 * @tc.expected: step3. return BUSY.
277 */
278 /**
279 * @tc.steps:step4. Close the kv store delegate.
280 */
281 /**
282 * @tc.steps:step5. Execute the rekey operation.
283 * @tc.expected: step5. return OK.
284 */
285 CheckRekeyWithMultiKvStore(false);
286 }
287
288 /**
289 * @tc.name: MultiVerRekeyCheck002
290 * @tc.desc: Attempt to rekey while the snapshot is existed.
291 * @tc.type: FUNC
292 * @tc.require: AR000CQDT7
293 * @tc.author: wumin
294 */
295 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, MultiVerRekeyCheck002, TestSize.Level1)
296 {
297 /**
298 * @tc.steps:step1. Get the multi version delegate.
299 */
300 /**
301 * @tc.steps:step2. Get the snapshot through the delegate.
302 */
303 /**
304 * @tc.steps:step3. Execute the rekey operation.
305 * @tc.expected: step3. return BUSY.
306 */
307 /**
308 * @tc.steps:step4. Release the snapshot.
309 */
310 /**
311 * @tc.steps:step5. Execute the rekey operation.
312 * @tc.expected: step5. return OK.
313 */
314 CheckRekeyWithExistedSnapshot(false);
315 }
316
317 /**
318 * @tc.name: MultiVerRekeyCheck003
319 * @tc.desc: Attempt to rekey while the observer is existed.
320 * @tc.type: FUNC
321 * @tc.require: AR000CQDT7
322 * @tc.author: wumin
323 */
324 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, MultiVerRekeyCheck003, TestSize.Level1)
325 {
326 /**
327 * @tc.steps:step1. Get the delegate.
328 */
329 /**
330 * @tc.steps:step2. Register the non-null observer.
331 */
332 /**
333 * @tc.steps:step3. Execute the rekey operation.
334 * @tc.expected: step3. return BUSY.
335 */
336 /**
337 * @tc.steps:step4. Unregister the observer.
338 */
339 /**
340 * @tc.steps:step5. Execute the rekey operation.
341 * @tc.expected: step5. return OK.
342 */
343 CheckRekeyWithExistedObserver(false);
344 }
345
346 /**
347 * @tc.name: SingleVerRekeyCheck001
348 * @tc.desc: Attempt to rekey while another delegate is existed.
349 * @tc.type: FUNC
350 * @tc.require: AR000CQDT7
351 * @tc.author: wumin
352 */
353 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, SingleVerRekeyCheck001, TestSize.Level1)
354 {
355 DBStatus status;
356 KvStoreNbDelegate *kvStore1 = nullptr;
357 auto delegateCallback1 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
358 placeholders::_2, std::ref(status), std::ref(kvStore1));
359 /**
360 * @tc.steps:step1. Get the single version delegate.
361 */
362 KvStoreNbDelegate::Option option = {true, false, false};
363 g_mgr.GetKvStore(STORE_ID2, option, delegateCallback1);
364 ASSERT_TRUE(kvStore1 != nullptr);
365
366 KvStoreNbDelegate *kvStore2 = nullptr;
367 auto delegateCallback2 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
368 placeholders::_2, std::ref(status), std::ref(kvStore2));
369 /**
370 * @tc.steps:step2. Get another single version delegate.
371 */
372 option.createIfNecessary = false;
373 g_mgr.GetKvStore(STORE_ID2, option, delegateCallback2);
374 ASSERT_TRUE(kvStore2 != nullptr);
375
376 /**
377 * @tc.steps:step3. Execute the rekey operation.
378 * @tc.expected: step3. return BUSY.
379 */
380 CipherPassword passwd;
381 vector<uint8_t> passwdBuffer(10, 45);
382 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
383 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
384 EXPECT_EQ(kvStore1->Rekey(passwd), BUSY);
385 /**
386 * @tc.steps:step4. Close the kv store delegate.
387 */
388 EXPECT_EQ(g_mgr.CloseKvStore(kvStore2), OK);
389 /**
390 * @tc.steps:step5. Execute the rekey operation.
391 * @tc.expected: step5. return OK.
392 */
393 EXPECT_EQ(kvStore1->Rekey(passwd), OK);
394 EXPECT_EQ(g_mgr.CloseKvStore(kvStore1), OK);
395 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID2), OK);
396 }
397
398 /**
399 * @tc.name: SingleVerRekeyCheck002
400 * @tc.desc: Attempt to rekey when the observer exists.
401 * @tc.type: FUNC
402 * @tc.require: AR000CQDT7
403 * @tc.author: wumin
404 */
405 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, SingleVerRekeyCheck002, TestSize.Level1)
406 {
407 DBStatus status;
408 KvStoreNbDelegate *kvStore = nullptr;
409 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
410 placeholders::_2, std::ref(status), std::ref(kvStore));
411 /**
412 * @tc.steps:step1. Get the single version delegate.
413 */
414 KvStoreNbDelegate::Option option = {true, false, false};
415 g_mgr.GetKvStore(STORE_ID2, option, delegateCallback);
416 ASSERT_TRUE(kvStore != nullptr);
417
418 KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
419 ASSERT_TRUE(observer != nullptr);
420 /**
421 * @tc.steps:step2. Register the non-null observer for the empty key.
422 */
423 Key key;
424 EXPECT_EQ(kvStore->RegisterObserver(key, 4, observer), OK); // Only use the event 4.
425
426 /**
427 * @tc.steps:step3. Execute the rekey operation.
428 * @tc.expected: step3. return BUSY.
429 */
430 CipherPassword passwd;
431 vector<uint8_t> passwdBuffer(10, 45);
432 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
433 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
434 EXPECT_EQ(kvStore->Rekey(passwd), BUSY);
435 /**
436 * @tc.steps:step4. Unregister the observer.
437 */
438 EXPECT_EQ(kvStore->UnRegisterObserver(observer), OK);
439 delete observer;
440 observer = nullptr;
441 /**
442 * @tc.steps:step5. Execute the rekey operation.
443 * @tc.expected: step5. return OK.
444 */
445 EXPECT_EQ(kvStore->Rekey(passwd), OK);
446 EXPECT_EQ(g_mgr.CloseKvStore(kvStore), OK);
447 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID2), OK);
448 }
449
NotifierCallback(const KvStoreNbConflictData & data)450 static void NotifierCallback(const KvStoreNbConflictData &data)
451 {
452 }
453 /**
454 * @tc.name: SingleVerRekeyCheck003
455 * @tc.desc: Attempt to rekey while the conflict notifier is set.
456 * @tc.type: FUNC
457 * @tc.require: AR000CQDT7
458 * @tc.author: wumin
459 */
460 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, SingleVerRekeyCheck003, TestSize.Level1)
461 {
462 DBStatus status;
463 KvStoreNbDelegate *kvStore = nullptr;
464 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
465 placeholders::_2, std::ref(status), std::ref(kvStore));
466 /**
467 * @tc.steps:step1. Get the single version delegate.
468 */
469 KvStoreNbDelegate::Option option = {true, false, false};
470 g_mgr.GetKvStore(STORE_ID2, option, delegateCallback);
471 ASSERT_TRUE(kvStore != nullptr);
472 /**
473 * @tc.steps:step2. Set the non-null conflict notifier.
474 */
475 const int conflictAll = 15;
476 ASSERT_EQ(kvStore->SetConflictNotifier(conflictAll, NotifierCallback), OK);
477 CipherPassword passwd;
478 vector<uint8_t> passwdBuffer(10, 45);
479 int errCode = passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
480 ASSERT_EQ(errCode, CipherPassword::ErrorCode::OK);
481 /**
482 * @tc.steps:step3. Execute the rekey operation.
483 * @tc.expected: step3. return BUSY.
484 */
485 EXPECT_EQ(kvStore->Rekey(passwd), BUSY);
486 /**
487 * @tc.steps:step4. Set the null conflict notifier to unregister the conflict notifier.
488 */
489 EXPECT_EQ(kvStore->SetConflictNotifier(1, nullptr), OK);
490 /**
491 * @tc.steps:step5. Execute the rekey operation.
492 * @tc.expected: step5. return OK.
493 */
494 EXPECT_EQ(kvStore->Rekey(passwd), OK);
495 EXPECT_EQ(g_mgr.CloseKvStore(kvStore), OK);
496 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID2), OK);
497 }
498
499 /**
500 * @tc.name: ExportAndImportCheck001
501 * @tc.desc: Test the EXPORT interface
502 * @tc.type: FUNC
503 * @tc.require:
504 * @tc.author: bty
505 */
506 HWTEST_F(DistributedDBInterfacesEncryptDatabaseTest, ExportAndImportCheck001, TestSize.Level1)
507 {
508 DBStatus status;
509 KvStoreDelegate *kvStore = nullptr;
510 auto delegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
511 placeholders::_2, std::ref(status), std::ref(kvStore));
512 KvStoreDelegate::Option option = {true, true, false};
513 g_mgr.GetKvStore(STORE_ID1, option, delegateCallback);
514 ASSERT_TRUE(kvStore != nullptr);
515
516 string path = g_testDir + "/export.back";
517 CipherPassword passwd;
518 vector<uint8_t> passwdBuffer(10, 45); // 10 and 45 as random password.
519 passwd.SetValue(passwdBuffer.data(), passwdBuffer.size());
520 ASSERT_EQ(kvStore->Export(path, passwd), OK);
521 EXPECT_EQ(g_mgr.CloseKvStore(kvStore), OK);
522 EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID1), OK);
523 }
524 #endif
525