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