• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include <condition_variable>
17 #include <gtest/gtest.h>
18 #include <thread>
19 
20 #include "db_constant.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "kv_store_nb_delegate.h"
24 #include "kv_virtual_device.h"
25 #include "platform_specific.h"
26 
27 using namespace testing::ext;
28 using namespace DistributedDB;
29 using namespace DistributedDBUnitTest;
30 using namespace std;
31 
32 namespace {
33     string g_testDir;
34     const string STORE_ID = "kv_stroe_sync_test";
35     const string USER_ID_1 = "userId1";
36     const string USER_ID_2 = "userId2";
37     const std::string DEVICE_B = "deviceB";
38     const std::string DEVICE_C = "deviceC";
39     const int WAIT_TIME = 1000; // 1000ms
40     const int WAIT_3_SECONDS = 3000;
41 
42     KvStoreDelegateManager g_mgr1(APP_ID, USER_ID_1);
43     KvStoreDelegateManager g_mgr2(APP_ID, USER_ID_2);
44     KvStoreConfig g_config;
45     DistributedDBToolsUnitTest g_tool;
46     KvStoreNbDelegate* g_kvDelegatePtr1 = nullptr;
47     KvStoreNbDelegate* g_kvDelegatePtr2 = nullptr;
48     VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
49     KvVirtualDevice *g_deviceB = nullptr;
50     KvVirtualDevice *g_deviceC = nullptr;
51     DBStatus g_kvDelegateStatus1 = INVALID_ARGS;
52     DBStatus g_kvDelegateStatus2 = INVALID_ARGS;
53     std::string g_identifier;
54 
55     // the type of g_kvDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
56     auto g_kvDelegateCallback1 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
57         placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus1), std::ref(g_kvDelegatePtr1));
58     auto g_kvDelegateCallback2 = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
59         placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus2), std::ref(g_kvDelegatePtr2));
60     auto g_syncActivationCheckCallback1 = [] (const std::string &userId, const std::string &appId,
__anonb535fe850202(const std::string &userId, const std::string &appId, const std::string &storeId)61         const std::string &storeId)-> bool {
62         if (userId == USER_ID_2) {
63             return true;
64         } else {
65             return false;
66         }
67         return true;
68     };
69     auto g_syncActivationCheckCallback2 = [] (const std::string &userId, const std::string &appId,
__anonb535fe850302(const std::string &userId, const std::string &appId, const std::string &storeId)70         const std::string &storeId)-> bool {
71         if (userId == USER_ID_1) {
72             return true;
73         } else {
74             return false;
75         }
76         return true;
77     };
78 }
79 
80 class DistributedDBSingleVerMultiUserTest : public testing::Test {
81 public:
82     static void SetUpTestCase(void);
83     static void TearDownTestCase(void);
84     void SetUp();
85     void TearDown();
86 };
87 
SetUpTestCase(void)88 void DistributedDBSingleVerMultiUserTest::SetUpTestCase(void)
89 {
90     /**
91      * @tc.setup: Init datadir and Virtual Communicator.
92      */
93     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
94     g_config.dataDir = g_testDir;
95     g_mgr1.SetKvStoreConfig(g_config);
96     g_mgr2.SetKvStoreConfig(g_config);
97 
98     string dir = g_testDir + "/single_ver";
99     DIR* dirTmp = opendir(dir.c_str());
100     if (dirTmp == nullptr) {
101         OS::MakeDBDirectory(dir);
102     } else {
103         closedir(dirTmp);
104     }
105 
106     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
107     ASSERT_TRUE(g_communicatorAggregator != nullptr);
108     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
109 }
110 
TearDownTestCase(void)111 void DistributedDBSingleVerMultiUserTest::TearDownTestCase(void)
112 {
113     /**
114      * @tc.teardown: Release virtual Communicator and clear data dir.
115      */
116     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
117         LOGE("rm test db files error!");
118     }
119     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
120 }
121 
SetUp(void)122 void DistributedDBSingleVerMultiUserTest::SetUp(void)
123 {
124     DistributedDBToolsUnitTest::PrintTestCaseInfo();
125     /**
126      * @tc.setup: create virtual device B
127      */
128     g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
129     ASSERT_TRUE(g_deviceB != nullptr);
130     VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
131     ASSERT_TRUE(syncInterfaceB != nullptr);
132     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
133     g_deviceC = new (std::nothrow) KvVirtualDevice(DEVICE_C);
134     ASSERT_TRUE(g_deviceC != nullptr);
135     VirtualSingleVerSyncDBInterface *syncInterfaceC = new (std::nothrow) VirtualSingleVerSyncDBInterface();
136     ASSERT_TRUE(syncInterfaceC != nullptr);
137     ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
138 }
139 
TearDown(void)140 void DistributedDBSingleVerMultiUserTest::TearDown(void)
141 {
142     /**
143      * @tc.teardown: Release device A, B, C
144      */
145     if (g_deviceB != nullptr) {
146         delete g_deviceB;
147         g_deviceB = nullptr;
148     }
149     if (g_deviceC != nullptr) {
150         delete g_deviceC;
151         g_deviceC = nullptr;
152     }
153     SyncActivationCheckCallback callback = nullptr;
154     g_mgr1.SetSyncActivationCheckCallback(callback);
155 }
156 
157 namespace {
OpenStore1(bool syncDualTupleMode=true)158 void OpenStore1(bool syncDualTupleMode = true)
159 {
160     KvStoreNbDelegate::Option option;
161     option.syncDualTupleMode = syncDualTupleMode;
162     g_mgr1.GetKvStore(STORE_ID, option, g_kvDelegateCallback1);
163     ASSERT_TRUE(g_kvDelegateStatus1 == OK);
164     ASSERT_TRUE(g_kvDelegatePtr1 != nullptr);
165 }
166 
OpenStore2(bool syncDualTupleMode=true)167 void OpenStore2(bool syncDualTupleMode = true)
168 {
169     KvStoreNbDelegate::Option option;
170     option.syncDualTupleMode = syncDualTupleMode;
171     g_mgr2.GetKvStore(STORE_ID, option, g_kvDelegateCallback2);
172     ASSERT_TRUE(g_kvDelegateStatus2 == OK);
173     ASSERT_TRUE(g_kvDelegatePtr2 != nullptr);
174 }
175 
CloseStore()176 void CloseStore()
177 {
178     if (g_kvDelegatePtr1 != nullptr) {
179         ASSERT_EQ(g_mgr1.CloseKvStore(g_kvDelegatePtr1), OK);
180         g_kvDelegatePtr1 = nullptr;
181         DBStatus status = g_mgr1.DeleteKvStore(STORE_ID);
182         LOGD("delete kv store status %d", status);
183         ASSERT_TRUE(status == OK);
184     }
185     if (g_kvDelegatePtr2 != nullptr) {
186         ASSERT_EQ(g_mgr2.CloseKvStore(g_kvDelegatePtr2), OK);
187         g_kvDelegatePtr2 = nullptr;
188         DBStatus status = g_mgr2.DeleteKvStore(STORE_ID);
189         LOGD("delete kv store status %d", status);
190         ASSERT_TRUE(status == OK);
191     }
192 }
193 
CheckSyncTest(DBStatus status1,DBStatus status2,std::vector<std::string> & devices)194 void CheckSyncTest(DBStatus status1, DBStatus status2, std::vector<std::string> &devices)
195 {
196     std::map<std::string, DBStatus> result;
197     DBStatus status = g_tool.SyncTest(g_kvDelegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result);
198     ASSERT_TRUE(status == status1);
199     if (status == OK) {
200         for (const auto &pair : result) {
201             LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
202             EXPECT_TRUE(pair.second == OK);
203         }
204     }
205     result.clear();
206     status = g_tool.SyncTest(g_kvDelegatePtr2, devices, SYNC_MODE_PUSH_ONLY, result);
207     ASSERT_TRUE(status == status2);
208     if (status == OK) {
209         ASSERT_TRUE(result.size() == devices.size());
210         for (const auto &pair : result) {
211             LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
212             EXPECT_TRUE(pair.second == OK);
213         }
214     }
215 }
216 
AutoLaunchCallBack(const std::string & identifier,AutoLaunchParam & param,KvStoreObserverUnitTest * observer,bool ret)217 bool AutoLaunchCallBack(const std::string &identifier, AutoLaunchParam &param, KvStoreObserverUnitTest *observer,
218     bool ret)
219 {
220     LOGD("int AutoLaunchCallBack");
221     EXPECT_TRUE(identifier == g_identifier);
222     param.appId = APP_ID;
223     param.storeId = STORE_ID;
224     CipherPassword passwd;
225     param.option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer,
226         0, nullptr};
227     param.notifier = nullptr;
228     param.option.syncDualTupleMode = true;
229     return ret;
230 }
231 
TestSyncWithUserChange(bool wait)232 void TestSyncWithUserChange(bool wait)
233 {
234     /**
235      * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
236      */
237     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
238     /**
239      * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
240      * @tc.expected: step2. only user2 sync mode is active
241      */
242     OpenStore1(true);
243     OpenStore2(true);
244     /**
245      * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
246      */
247     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
248 
249     /**
250      * @tc.steps: step4. call NotifyUserChanged and block sync db concurrently
251      * @tc.expected: step4. return OK
252      */
253     CipherPassword passwd;
254     bool startSync = false;
255     std::condition_variable cv;
256     thread subThread([&startSync, &cv]() {
257         std::mutex notifyLock;
258         std::unique_lock<std::mutex> lck(notifyLock);
259         cv.wait(lck, [&startSync]() { return startSync; });
260         EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
261     });
262     subThread.detach();
263     g_communicatorAggregator->RegOnDispatch([&startSync, &cv](const std::string&, Message *inMsg) {
264         if (!startSync) {
265             startSync = true;
266             cv.notify_all();
267         }
268     });
269 
270     /**
271      * @tc.steps: step5. deviceA call sync and wait
272      * @tc.expected: step5. sync should return OK.
273      */
274     std::map<std::string, DBStatus> result;
275     std::vector<std::string> devices;
276     devices.push_back(g_deviceB->GetDeviceId());
277     DBStatus status = g_tool.SyncTest(g_kvDelegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result, wait);
278     EXPECT_EQ(status, OK);
279     g_communicatorAggregator->RegOnDispatch(nullptr);
280     /**
281      * @tc.expected: step6. onComplete should be called, and status is USER_CHANGED
282      */
283     EXPECT_EQ(result.size(), devices.size());
284     for (const auto &pair : result) {
285         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
286         EXPECT_EQ(pair.second, USER_CHANGED);
287     }
288     CloseStore();
289 }
290 }
291 
292 /**
293  * @tc.name: multi user 001
294  * @tc.desc: Test multi user change
295  * @tc.type: FUNC
296  * @tc.require: AR000CQS3S SR000CQE0B
297  * @tc.author: zhuwentao
298  */
299 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser001, TestSize.Level0)
300 {
301     /**
302      * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
303      */
304     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
305     /**
306      * @tc.steps: step2. openstore1 and openstore2
307      * @tc.expected: step2. only user2 sync mode is active
308      */
309     OpenStore1();
310     OpenStore2();
311     /**
312      * @tc.steps: step3. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k1, v1}
313      */
314     Key key = {'1'};
315     Value value = {'1'};
316     Value value2 = {'2'};
317     EXPECT_TRUE(g_kvDelegatePtr1->Put(key, value2) == OK);
318     EXPECT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK);
319     /**
320      * @tc.steps: step4. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
321      * @tc.expected: step4. g_kvDelegatePtr2 call success
322      */
323     std::vector<std::string> devices;
324     devices.push_back(g_deviceB->GetDeviceId());
325     CheckSyncTest(NOT_ACTIVE, OK, devices);
326     /**
327      * @tc.steps: step5. g_kvDelegatePtr1 support some pragma cmd call
328      * @tc.expected: step5. Pragma call success
329      */
330     int pragmaData = 1;
331     PragmaData input = static_cast<PragmaData>(&pragmaData);
332     EXPECT_TRUE(g_kvDelegatePtr1->Pragma(AUTO_SYNC, input) == OK);
333     pragmaData = 100;
334     input = static_cast<PragmaData>(&pragmaData);
335     EXPECT_TRUE(g_kvDelegatePtr1->Pragma(SET_QUEUED_SYNC_LIMIT, input) == OK);
336     EXPECT_TRUE(g_kvDelegatePtr1->Pragma(GET_QUEUED_SYNC_LIMIT, input) == OK);
337     EXPECT_TRUE(input == static_cast<PragmaData>(&pragmaData));
338     pragmaData = 1;
339     input = static_cast<PragmaData>(&pragmaData);
340     EXPECT_TRUE(g_kvDelegatePtr1->Pragma(SET_WIPE_POLICY, input) == OK);
341     EXPECT_TRUE(g_kvDelegatePtr1->Pragma(SET_SYNC_RETRY, input) == OK);
342     /**
343      * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
344      */
345     VirtualDataItem item;
346     g_deviceB->GetData(key, item);
347     EXPECT_TRUE(item.value == value);
348     /**
349      * @tc.expected: step7. user change
350      */
351     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
352     KvStoreDelegateManager::NotifyUserChanged();
353     /**
354      * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
355      * @tc.expected: step8. g_kvDelegatePtr1 call success
356      */
357     devices.clear();
358     devices.push_back(g_deviceC->GetDeviceId());
359     CheckSyncTest(OK, NOT_ACTIVE, devices);
360     /**
361      * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1}
362      */
363     g_deviceC->GetData(key, item);
364     EXPECT_TRUE(item.value == value2);
365     CloseStore();
366 }
367 
368 /**
369  * @tc.name: multi user 002
370  * @tc.desc: Test multi user not change
371  * @tc.type: FUNC
372  * @tc.require: AR000CQS3S SR000CQE0B
373  * @tc.author: zhuwentao
374  */
375 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser002, TestSize.Level0)
376 {
377     /**
378      * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
379      */
380     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
381     /**
382      * @tc.steps: step2. openstore1 and openstore2
383      * @tc.expected: step2. only user2 sync mode is active
384      */
385     OpenStore1();
386     OpenStore2();
387     /**
388      * @tc.steps: step3. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k1, v1}
389      */
390     Key key = {'1'};
391     Value value = {'1'};
392     EXPECT_TRUE(g_kvDelegatePtr1->Put(key, value) == OK);
393     EXPECT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK);
394     /**
395      * @tc.steps: step4. GetKvStoreIdentifier success when userId is invalid
396      */
397     std::string userId;
398     EXPECT_TRUE(g_mgr1.GetKvStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
399     userId.resize(130);
400     EXPECT_TRUE(g_mgr1.GetKvStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
401     /**
402      * @tc.steps: step5. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
403      * @tc.expected: step5. g_kvDelegatePtr2 call success
404      */
405     std::vector<std::string> devices;
406     devices.push_back(g_deviceB->GetDeviceId());
407     CheckSyncTest(NOT_ACTIVE, OK, devices);
408     /**
409      * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
410      */
411     VirtualDataItem item;
412     g_deviceB->GetData(key, item);
413     EXPECT_TRUE(item.value == value);
414     /**
415      * @tc.expected: step7. user not change
416      */
417     KvStoreDelegateManager::NotifyUserChanged();
418     /**
419      * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 put {k2, v2}
420      */
421     key = {'2'};
422     value = {'2'};
423     EXPECT_TRUE(g_kvDelegatePtr1->Put(key, value) == OK);
424     EXPECT_TRUE(g_kvDelegatePtr2->Put(key, value) == OK);
425     /**
426      * @tc.steps: step9. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
427      * @tc.expected: step9. g_kvDelegatePtr2 call success
428      */
429     devices.clear();
430     devices.push_back(g_deviceB->GetDeviceId());
431     CheckSyncTest(NOT_ACTIVE, OK, devices);
432     /**
433      * @tc.expected: step10. onComplete should be called, DeviceB have {k2,v2}
434      */
435     g_deviceB->GetData(key, item);
436     EXPECT_TRUE(item.value == value);
437     CloseStore();
438 }
439 
440 /**
441  * @tc.name: multi user 003
442  * @tc.desc: enhancement callback return true in multiuser mode
443  * @tc.type: FUNC
444  * @tc.require: AR000EPARJ
445  * @tc.author: zhuwentao
446  */
447 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser003, TestSize.Level3)
448 {
449     /**
450      * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
451      */
452     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
453 
454     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
455     EXPECT_TRUE(observer != nullptr);
456     /**
457      * @tc.steps: step2. SetAutoLaunchRequestCallback
458      * @tc.expected: step2. success.
459      */
460     g_mgr1.SetAutoLaunchRequestCallback(
461         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true));
462 
463     /**
464      * @tc.steps: step2. RunCommunicatorLackCallback
465      * @tc.expected: step2. success.
466      */
467     g_identifier = g_mgr1.GetKvStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true);
468     EXPECT_TRUE(g_identifier == g_mgr1.GetKvStoreIdentifier(USER_ID_1, APP_ID, STORE_ID, true));
469     std::vector<uint8_t> label(g_identifier.begin(), g_identifier.end());
470     g_communicatorAggregator->SetCurrentUserId(USER_ID_2);
471     g_communicatorAggregator->RunCommunicatorLackCallback(label);
472     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
473     /**
474      * @tc.steps: step3. device B put {k1, v1}
475      * @tc.expected: step3. success.
476      */
477     Key key = {'1'};
478     Value value = {'1'};
479     Timestamp currentTime;
480     (void)OS::GetCurrentSysTimeInMicrosecond(currentTime);
481     EXPECT_TRUE(g_deviceB->PutData(key, value, currentTime, 0) == OK);
482     /**
483      * @tc.steps: step4. device B push sync to A
484      * @tc.expected: step4. success.
485      */
486     EXPECT_TRUE(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true) == OK);
487     EXPECT_TRUE(observer->GetCallCount() == 1); // only A
488     /**
489      * @tc.steps: step5. deviceA have {k1,v1}
490      * @tc.expected: step5. success.
491      */
492     OpenStore2();
493     Value actualValue;
494     g_kvDelegatePtr2->Get(key, actualValue);
495     EXPECT_EQ(actualValue, value);
496     std::this_thread::sleep_for(std::chrono::seconds(70));
497     g_mgr1.SetAutoLaunchRequestCallback(nullptr);
498     CloseStore();
499     delete observer;
500 }
501 
502 /**
503  * @tc.name: MultiUser004
504  * @tc.desc: CommunicatorLackCallback in multi user mode
505  * @tc.type: FUNC
506  * @tc.require: AR000E8S2T
507  * @tc.author: zhuwentao
508  */
509 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser004, TestSize.Level0)
510 {
511     /**
512      * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
513      */
514     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
515 
516     /**
517      * @tc.steps: step2. right param A B enable
518      * @tc.expected: step2. success.
519      */
520     AutoLaunchNotifier notifier = nullptr;
521     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
522     EXPECT_TRUE(observer != nullptr);
523     AutoLaunchOption option;
524     CipherPassword passwd;
525     option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer,
526         0, nullptr};
527     option.notifier = nullptr;
528     option.observer = observer;
529     option.syncDualTupleMode = true;
530     EXPECT_TRUE(g_mgr1.EnableKvStoreAutoLaunch(USER_ID_2, APP_ID, STORE_ID, option, notifier) == OK);
531     EXPECT_TRUE(g_mgr1.EnableKvStoreAutoLaunch(USER_ID_1, APP_ID, STORE_ID, option, notifier) == OK);
532 
533     /**
534      * @tc.steps: step3. RunCommunicatorLackCallback
535      * @tc.expected: step3. userId2 open db successfully.
536      */
537     g_identifier = g_mgr1.GetKvStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true);
538     std::vector<uint8_t> label(g_identifier.begin(), g_identifier.end());
539     g_communicatorAggregator->SetCurrentUserId(USER_ID_2);
540     g_communicatorAggregator->RunCommunicatorLackCallback(label);
541     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
542     /**
543      * @tc.steps: step5. device B put {k1, v1}
544      * @tc.expected: step5. success.
545      */
546     Key key = {'1'};
547     Value value = {'1'};
548     Timestamp currentTime;
549     (void)OS::GetCurrentSysTimeInMicrosecond(currentTime);
550     EXPECT_TRUE(g_deviceB->PutData(key, value, currentTime, 0) == OK);
551     /**
552      * @tc.steps: step6. device B push sync to A
553      * @tc.expected: step6. success.
554      */
555     EXPECT_TRUE(g_deviceB->Sync(SYNC_MODE_PUSH_ONLY, true) == OK);
556     EXPECT_TRUE(observer->GetCallCount() == 1); // only A
557     /**
558      * @tc.steps: step7. deviceA have {k1,v1}
559      * @tc.expected: step7. success.
560      */
561     OpenStore2();
562     Value actualValue;
563     g_kvDelegatePtr2->Get(key, actualValue);
564     EXPECT_EQ(actualValue, value);
565     /**
566      * @tc.steps: step8. param A B disable
567      * @tc.expected: step8. notifier WRITE_CLOSED
568      */
569     EXPECT_TRUE(g_mgr1.DisableKvStoreAutoLaunch(USER_ID_2, APP_ID, STORE_ID) == OK);
570     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
571     EXPECT_TRUE(g_mgr1.DisableKvStoreAutoLaunch(USER_ID_1, APP_ID, STORE_ID) == OK);
572     CloseStore();
573     delete observer;
574 }
575 
576 /**
577  * @tc.name: MultiUser005
578  * @tc.desc: test NotifyUserChanged func when all db in normal sync mode
579  * @tc.type: FUNC
580  * @tc.require: AR000E8S2T
581  * @tc.author: zhuwentao
582  */
583 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser005, TestSize.Level0)
584 {
585     /**
586      * @tc.steps: step1. openstore1 and openstore2 in normal sync mode
587      * @tc.expected: step1. only user2 sync mode is active
588      */
589     OpenStore1(false);
590     OpenStore2(false);
591     /**
592      * @tc.steps: step2. call NotifyUserChanged
593      * @tc.expected: step2. return OK
594      */
595     EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
596     CloseStore();
597     /**
598      * @tc.steps: step3. openstore1 open normal sync mode and and openstore2 in dual tuple
599      * @tc.expected: step3. only user2 sync mode is active
600      */
601     OpenStore1(false);
602     OpenStore2();
603     /**
604      * @tc.steps: step4. call NotifyUserChanged
605      * @tc.expected: step4. return OK
606      */
607     EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
608     CloseStore();
609 }
610 
611 /**
612  * @tc.name: MultiUser006
613  * @tc.desc: test NotifyUserChanged and close db concurrently
614  * @tc.type: FUNC
615  * @tc.require: AR000E8S2T
616  * @tc.author: zhuwentao
617  */
618 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser006, TestSize.Level0)
619 {
620     /**
621      * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
622      */
623     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
624     /**
625      * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
626      * @tc.expected: step2. only user2 sync mode is active
627      */
628     OpenStore1(true);
629     OpenStore2(false);
630     /**
631      * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
632      */
633     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
634     /**
635      * @tc.steps: step4. call NotifyUserChanged and close db concurrently
636      * @tc.expected: step4. return OK
637      */
__anonb535fe850802() 638     thread subThread([]() {
639         EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
640     });
641     subThread.detach();
642     EXPECT_EQ(g_mgr1.CloseKvStore(g_kvDelegatePtr1), OK);
643     g_kvDelegatePtr1 = nullptr;
644     CloseStore();
645 }
646 
647 /**
648  * @tc.name: MultiUser007
649  * @tc.desc: test NotifyUserChanged and rekey db concurrently
650  * @tc.type: FUNC
651  * @tc.require: AR000E8S2T
652  * @tc.author: zhuwentao
653  */
654 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser007, TestSize.Level0)
655 {
656     /**
657      * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
658      */
659     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
660     /**
661      * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
662      * @tc.expected: step2. only user2 sync mode is active
663      */
664     OpenStore1(true);
665     OpenStore2(false);
666     /**
667      * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
668      */
669     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
670     /**
671      * @tc.steps: step2. call NotifyUserChanged and close db concurrently
672      * @tc.expected: step2. return OK
673      */
674     CipherPassword passwd;
__anonb535fe850902() 675     thread subThread([]() {
676         EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
677     });
678     subThread.detach();
679     std::this_thread::sleep_for(std::chrono::milliseconds(1));
680     EXPECT_TRUE(g_kvDelegatePtr1->Rekey(passwd) == OK);
681     CloseStore();
682 }
683 
684 /**
685  * @tc.name: MultiUser008
686  * @tc.desc: test NotifyUserChanged and block sync concurrently
687  * @tc.type: FUNC
688  * @tc.require: AR000E8S2T
689  * @tc.author: zhuwentao
690  */
691 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser008, TestSize.Level0)
692 {
693     TestSyncWithUserChange(true);
694 }
695 
696 /**
697  * @tc.name: MultiUser009
698  * @tc.desc: test NotifyUserChanged and non-block sync concurrently
699  * @tc.type: FUNC
700  * @tc.require: AR000E8S2T
701  * @tc.author: zhuwentao
702  */
703 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser009, TestSize.Level0)
704 {
705     TestSyncWithUserChange(false);
706 }
707 
708 /**
709  * @tc.name: MultiUser010
710  * @tc.desc: test NotifyUserChanged and non-block sync with multi devices concurrently
711  * @tc.type: FUNC
712  * @tc.require: AR000E8S2T
713  * @tc.author: zhuwentao
714  */
715 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser010, TestSize.Level3)
716 {
717     /**
718      * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
719      */
720     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
721     /**
722      * @tc.steps: step2. openstore1 and openstore2 in dual tuple sync mode
723      * @tc.expected: step2. only userId1 sync mode is active
724      */
725     OpenStore1(true);
726     OpenStore2(true);
727     /**
728      * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
729      */
730     g_mgr1.SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
731     /**
732      * @tc.steps: step4. deviceA put {k1, v1}
733      */
734     Key key = {'1'};
735     Value value = {'1'};
736     EXPECT_TRUE(g_kvDelegatePtr1->Put(key, value) == OK);
737 
738     /**
739      * @tc.steps: step5. deviceB set sava data dely 5s
740      */
741     g_deviceC->SetSaveDataDelayTime(WAIT_3_SECONDS);
742     /**
743      * @tc.steps: step6. call NotifyUserChanged and block sync db concurrently
744      * @tc.expected: step6. return OK
745      */
746     CipherPassword passwd;
__anonb535fe850a02() 747     thread subThread([]() {
748         std::this_thread::sleep_for(std::chrono::milliseconds(1000));
749         EXPECT_TRUE(KvStoreDelegateManager::NotifyUserChanged() == OK);
750     });
751     subThread.detach();
752     /**
753      * @tc.steps: step7. deviceA call sync and wait
754      * @tc.expected: step7. sync should return OK.
755      */
756     std::map<std::string, DBStatus> result;
757     std::vector<std::string> devices = {g_deviceB->GetDeviceId(), g_deviceC->GetDeviceId()};
758     DBStatus status = g_tool.SyncTest(g_kvDelegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result, false);
759     EXPECT_TRUE(status == OK);
760 
761     /**
762      * @tc.expected: step8. onComplete should be called, and status is USER_CHANGED
763      */
764     EXPECT_TRUE(result.size() == devices.size());
765     for (const auto &pair : result) {
766         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
767         if (pair.first == g_deviceB->GetDeviceId()) {
768             EXPECT_TRUE(pair.second == OK);
769         } else {
770             EXPECT_TRUE(pair.second == USER_CHANGED);
771         }
772     }
773     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_3_SECONDS));
774     CloseStore();
775 }
776 
777 /**
778  * @tc.name: MultiUser011
779  * @tc.desc: test check sync active twice when open store
780  * @tc.type: FUNC
781  * @tc.require: AR000E8S2T
782  * @tc.author: zhangqiquan
783  */
784 HWTEST_F(DistributedDBSingleVerMultiUserTest, MultiUser011, TestSize.Level1)
785 {
786     uint32_t callCount = 0u;
787     /**
788      * @tc.steps: step1. set SyncActivationCheckCallback and record call count, only first call return not active
789      */
790     g_mgr1.SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anonb535fe850b02(const std::string &userId, const std::string &appId, const std::string &storeId) 791         const std::string &storeId) -> bool {
792         callCount++;
793         return callCount != 1;
794     });
795     /**
796      * @tc.steps: step2. openstore1 in dual tuple sync mode
797      * @tc.expected: step2. it should be activity finally
798      */
799     OpenStore1(true);
800     /**
801      * @tc.steps: step3. call sync to DEVICES_B
802      * @tc.expected: step3. should return OK, not NOT_ACTIVE
803      */
804     std::map<std::string, DBStatus> result;
805     std::vector<std::string> devices = {g_deviceB->GetDeviceId()};
806     EXPECT_EQ(g_tool.SyncTest(g_kvDelegatePtr1, devices, SYNC_MODE_PUSH_ONLY, result, true), OK);
807     CloseStore();
808 }