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,
__anon100b4fe60202(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,
__anon100b4fe60302(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 ¶m, 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 */
__anon100b4fe60802() 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;
__anon100b4fe60902() 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;
__anon100b4fe60a02() 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,
__anon100b4fe60b02(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 }