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 ¶m, 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 }