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