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