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