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 <gtest/gtest.h>
17
18 #include "db_constant.h"
19 #include "db_properties.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "platform_specific.h"
23 #include "relational_store_delegate.h"
24 #include "relational_store_manager.h"
25 #include "relational_virtual_device.h"
26 #include "runtime_config.h"
27 #include "virtual_relational_ver_sync_db_interface.h"
28
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33
34 namespace {
35 string g_testDir;
36 const string STORE_ID = "rdb_stroe_sync_test";
37 const string USER_ID_1 = "userId1";
38 const string USER_ID_2 = "userId2";
39 const std::string DEVICE_B = "deviceB";
40 const std::string DEVICE_C = "deviceC";
41 const int WAIT_TIME = 1000; // 1000ms
42 const std::string g_tableName = "TEST_TABLE";
43 std::string g_identifier;
44
45 RelationalStoreManager g_mgr1(APP_ID, USER_ID_1);
46 RelationalStoreManager g_mgr2(APP_ID, USER_ID_2);
47 KvStoreConfig g_config;
48 DistributedDBToolsUnitTest g_tool;
49 RelationalStoreDelegate* g_rdbDelegatePtr1 = nullptr;
50 RelationalStoreDelegate* g_rdbDelegatePtr2 = nullptr;
51 VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
52 RelationalVirtualDevice *g_deviceB = nullptr;
53 RelationalVirtualDevice *g_deviceC = nullptr;
54 std::string g_dbDir;
55 std::string g_storePath1;
56 std::string g_storePath2;
57 RelationalStoreObserverUnitTest *g_observer = nullptr;
58
59 auto g_syncActivationCheckCallback1 = [] (const std::string &userId, const std::string &appId,
__anon3413e1da0202(const std::string &userId, const std::string &appId, const std::string &storeId)60 const std::string &storeId)-> bool {
61 if (userId == USER_ID_2) {
62 LOGE("active call back1, active user2");
63 return true;
64 } else {
65 LOGE("active call back1, no need to active user1");
66 return false;
67 }
68 return true;
69 };
70 auto g_syncActivationCheckCallback2 = [] (const std::string &userId, const std::string &appId,
__anon3413e1da0302(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 LOGE("active call back2, active user1");
74 return true;
75 } else {
76 LOGE("active call back2, no need to active user2");
77 return false;
78 }
79 return true;
80 };
81
DropTable(sqlite3 * db,const std::string & tableName)82 int DropTable(sqlite3 *db, const std::string &tableName)
83 {
84 std::string sql = "DROP TABLE IF EXISTS " + tableName + ";";
85 char *errMsg = nullptr;
86 int rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg);
87 if (rc != 0) {
88 LOGE("failed to drop table: %s, errMsg: %s", tableName.c_str(), errMsg);
89 }
90 return rc;
91 }
92
CreateTable(sqlite3 * db,const std::string & tableName)93 int CreateTable(sqlite3 *db, const std::string &tableName)
94 {
95 std::string sql = "CREATE TABLE " + tableName + "(id int, name text);";
96 int rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
97 return rc;
98 }
99
InsertValue(sqlite3 * db,const std::string & tableName)100 int InsertValue(sqlite3 *db, const std::string &tableName)
101 {
102 std::string sql = "insert into " + tableName + " values(1, 'aaa');";
103 return sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
104 }
105
GetDB(sqlite3 * & db,const std::string & dbPath)106 int GetDB(sqlite3 *&db, const std::string &dbPath)
107 {
108 int flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
109 int rc = sqlite3_open_v2(dbPath.c_str(), &db, flag, nullptr);
110 if (rc != SQLITE_OK) {
111 return rc;
112 }
113 EXPECT_EQ(SQLiteUtils::RegisterCalcHash(db), E_OK);
114 EXPECT_EQ(SQLiteUtils::RegisterGetSysTime(db), E_OK);
115 EXPECT_EQ(sqlite3_exec(db, "PRAGMA journal_mode=WAL;", nullptr, nullptr, nullptr), SQLITE_OK);
116 return rc;
117 }
118
PrepareVirtualDeviceEnv(const std::string & tableName,const std::string & dbPath,std::vector<RelationalVirtualDevice * > & remoteDeviceVec)119 void PrepareVirtualDeviceEnv(const std::string &tableName, const std::string &dbPath,
120 std::vector<RelationalVirtualDevice *> &remoteDeviceVec)
121 {
122 sqlite3 *db = nullptr;
123 EXPECT_EQ(GetDB(db, dbPath), SQLITE_OK);
124 TableInfo tableInfo;
125 SQLiteUtils::AnalysisSchema(db, tableName, tableInfo);
126 for (auto &dev : remoteDeviceVec) {
127 std::vector<FieldInfo> fieldInfoList = tableInfo.GetFieldInfos();
128 dev->SetLocalFieldInfo(fieldInfoList);
129 dev->SetTableInfo(tableInfo);
130 }
131 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
132 }
133
PrepareVirtualDeviceBEnv(const std::string & tableName)134 void PrepareVirtualDeviceBEnv(const std::string &tableName)
135 {
136 std::vector<RelationalVirtualDevice *> remoteDev;
137 remoteDev.push_back(g_deviceB);
138 PrepareVirtualDeviceEnv(tableName, g_storePath1, remoteDev);
139 }
140
PrepareData(const std::string & tableName,const std::string & dbPath)141 void PrepareData(const std::string &tableName, const std::string &dbPath)
142 {
143 sqlite3 *db = nullptr;
144 EXPECT_EQ(GetDB(db, dbPath), SQLITE_OK);
145 EXPECT_EQ(InsertValue(db, tableName), SQLITE_OK);
146 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
147 }
148
OpenStore1(bool syncDualTupleMode=true)149 void OpenStore1(bool syncDualTupleMode = true)
150 {
151 if (g_observer == nullptr) {
152 g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
153 }
154 RelationalStoreDelegate::Option option = {g_observer};
155 option.syncDualTupleMode = syncDualTupleMode;
156 g_mgr1.OpenStore(g_storePath1, STORE_ID_1, option, g_rdbDelegatePtr1);
157 ASSERT_TRUE(g_rdbDelegatePtr1 != nullptr);
158 }
159
OpenStore2(bool syncDualTupleMode=true)160 void OpenStore2(bool syncDualTupleMode = true)
161 {
162 if (g_observer == nullptr) {
163 g_observer = new (std::nothrow) RelationalStoreObserverUnitTest();
164 }
165 RelationalStoreDelegate::Option option = {g_observer};
166 option.syncDualTupleMode = syncDualTupleMode;
167 g_mgr2.OpenStore(g_storePath2, STORE_ID_2, option, g_rdbDelegatePtr2);
168 ASSERT_TRUE(g_rdbDelegatePtr2 != nullptr);
169 }
170
CloseStore()171 void CloseStore()
172 {
173 if (g_rdbDelegatePtr1 != nullptr) {
174 ASSERT_EQ(g_mgr1.CloseStore(g_rdbDelegatePtr1), OK);
175 g_rdbDelegatePtr1 = nullptr;
176 LOGD("delete rdb store");
177 }
178 if (g_rdbDelegatePtr2 != nullptr) {
179 ASSERT_EQ(g_mgr2.CloseStore(g_rdbDelegatePtr2), OK);
180 g_rdbDelegatePtr2 = nullptr;
181 LOGD("delete rdb store");
182 }
183 }
184
PrepareEnvironment(const std::string & tableName,const std::string & dbPath,RelationalStoreDelegate * rdbDelegate)185 void PrepareEnvironment(const std::string &tableName, const std::string &dbPath,
186 RelationalStoreDelegate* rdbDelegate)
187 {
188 sqlite3 *db = nullptr;
189 EXPECT_EQ(GetDB(db, dbPath), SQLITE_OK);
190 EXPECT_EQ(DropTable(db, tableName), SQLITE_OK);
191 EXPECT_EQ(CreateTable(db, tableName), SQLITE_OK);
192 if (rdbDelegate != nullptr) {
193 EXPECT_EQ(rdbDelegate->CreateDistributedTable(tableName), OK);
194 }
195 sqlite3_close(db);
196 }
197
CheckSyncTest(DBStatus status1,DBStatus status2,std::vector<std::string> & devices)198 void CheckSyncTest(DBStatus status1, DBStatus status2, std::vector<std::string> &devices)
199 {
200 std::map<std::string, std::vector<TableStatus>> statusMap;
201 SyncStatusCallback callBack = [&statusMap](
202 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
203 statusMap = devicesMap;
204 };
205 Query query = Query::Select(g_tableName);
206 DBStatus status = g_rdbDelegatePtr1->Sync(devices, SYNC_MODE_PUSH_ONLY, query, callBack, true);
207 LOGE("expect status is: %d, actual is %d", status1, status);
208 ASSERT_TRUE(status == status1);
209 if (status == OK) {
210 for (const auto &pair : statusMap) {
211 for (const auto &tableStatus : pair.second) {
212 LOGD("dev %s, status %d", pair.first.c_str(), tableStatus.status);
213 EXPECT_TRUE(tableStatus.status == OK);
214 }
215 }
216 }
217 statusMap.clear();
218
219 std::map<std::string, std::vector<TableStatus>> statusMap2;
220 SyncStatusCallback callBack2 = [&statusMap2](
221 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
222 LOGE("call back devicesMap.size = %d", devicesMap.size());
223 statusMap2 = devicesMap;
224 };
225 status = g_rdbDelegatePtr2->Sync(devices, SYNC_MODE_PUSH_ONLY, query, callBack2, true);
226 LOGE("expect status2 is: %d, actual is %d, statusMap2.size = %d", status2, status, statusMap2.size());
227 ASSERT_TRUE(status == status2);
228 if (status == OK) {
229 for (const auto &pair : statusMap2) {
230 for (const auto &tableStatus : pair.second) {
231 LOGE("*********** rdb dev %s, status %d", pair.first.c_str(), tableStatus.status);
232 EXPECT_TRUE(tableStatus.status == OK);
233 }
234 }
235 }
236 statusMap.clear();
237 }
238
239 int g_currentStatus = 0;
240 const AutoLaunchNotifier g_notifier = [](const std::string &userId,
__anon3413e1da0602(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 241 const std::string &appId, const std::string &storeId, AutoLaunchStatus status) {
242 LOGD("notifier status = %d", status);
243 g_currentStatus = static_cast<int>(status);
244 };
245
__anon3413e1da0702(const std::string &identifier, AutoLaunchParam ¶m) 246 const AutoLaunchRequestCallback g_callback = [](const std::string &identifier, AutoLaunchParam ¶m) {
247 if (g_identifier != identifier) {
248 LOGD("g_identifier(%s) != identifier(%s)", g_identifier.c_str(), identifier.c_str());
249 return false;
250 }
251 param.path = g_testDir + "/test2.db";
252 param.appId = APP_ID;
253 param.storeId = STORE_ID;
254 CipherPassword passwd;
255 param.option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr,
256 0, nullptr};
257 param.notifier = g_notifier;
258 param.option.syncDualTupleMode = true;
259 return true;
260 };
261
DoRemoteQuery()262 void DoRemoteQuery()
263 {
264 RemoteCondition condition;
265 condition.sql = "SELECT * FROM " + g_tableName;
266 std::shared_ptr<ResultSet> result = std::make_shared<RelationalResultSetImpl>();
267 EXPECT_EQ(g_rdbDelegatePtr1->RemoteQuery(g_deviceB->GetDeviceId(), condition,
268 DBConstant::MAX_TIMEOUT, result), USER_CHANGED);
269 EXPECT_EQ(result, nullptr);
270 g_communicatorAggregator->RegOnDispatch(nullptr);
271 CloseStore();
272 }
273
CheckSyncResult(bool wait,bool isRemoteQuery)274 void CheckSyncResult(bool wait, bool isRemoteQuery)
275 {
276 std::mutex syncLock_{};
277 std::condition_variable syncCondVar_{};
278 std::map<std::string, std::vector<TableStatus>> statusMap;
279 SyncStatusCallback callBack = [&statusMap, &syncLock_, &syncCondVar_, wait](
280 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
281 statusMap = devicesMap;
282 if (!wait) {
283 std::unique_lock<std::mutex> innerlock(syncLock_);
284 syncCondVar_.notify_one();
285 }
286 };
287 Query query = Query::Select(g_tableName);
288 std::vector<std::string> devices;
289 devices.push_back(g_deviceB->GetDeviceId());
290 std::vector<RelationalVirtualDevice *> remoteDev;
291 remoteDev.push_back(g_deviceB);
292 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
293
294 DBStatus status = DB_ERROR;
295 if (isRemoteQuery) {
296 DoRemoteQuery();
297 return;
298 }
299
300 status = g_rdbDelegatePtr1->Sync(devices, SYNC_MODE_PUSH_ONLY, query, callBack, wait);
301 EXPECT_EQ(status, OK);
302
303 if (!wait) {
304 std::unique_lock<std::mutex> lock(syncLock_);
305 syncCondVar_.wait(lock, [status, &statusMap]() {
306 if (status != OK) {
307 return true;
308 }
309 return !statusMap.empty();
310 });
311 }
312
313 g_communicatorAggregator->RegOnDispatch(nullptr);
314 EXPECT_EQ(statusMap.size(), devices.size());
315 for (const auto &pair : statusMap) {
316 for (const auto &tableStatus : pair.second) {
317 EXPECT_TRUE(tableStatus.status == USER_CHANGED);
318 }
319 }
320 CloseStore();
321 }
322
TestSyncWithUserChange(bool wait,bool isRemoteQuery)323 void TestSyncWithUserChange(bool wait, bool isRemoteQuery)
324 {
325 /**
326 * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
327 */
328 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
329 /**
330 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
331 * @tc.expected: step2. only user2 sync mode is active
332 */
333 OpenStore1(true);
334 OpenStore2(true);
335
336 /**
337 * @tc.steps: step3. prepare environment
338 */
339 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
340 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
341
342 /**
343 * @tc.steps: step4. prepare data
344 */
345 PrepareData(g_tableName, g_storePath1);
346 PrepareData(g_tableName, g_storePath2);
347
348 /**
349 * @tc.steps: step5. set SyncActivationCheckCallback and only userId2 can active
350 */
351 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
352
353 /**
354 * @tc.steps: step6. call NotifyUserChanged and block sync db concurrently
355 * @tc.expected: step6. return OK
356 */
357 CipherPassword passwd;
358 bool startSync = false;
359 std::condition_variable cv;
360 thread subThread([&]() {
361 std::mutex notifyLock;
362 std::unique_lock<std::mutex> lck(notifyLock);
363 cv.wait(lck, [&startSync]() { return startSync; });
364 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
365 });
366 subThread.detach();
367 g_communicatorAggregator->RegOnDispatch([&](const std::string&, Message *inMsg) {
368 if (!startSync) {
369 startSync = true;
370 cv.notify_all();
371 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); // wait for notify user change
372 }
373 });
374
375 /**
376 * @tc.steps: step7. deviceA call sync and wait
377 * @tc.expected: step7. sync should return OK.
378 */
379 CheckSyncResult(wait, isRemoteQuery);
380 }
381
PrepareSelect(sqlite3 * db,sqlite3_stmt * & statement,const std::string & table)382 int PrepareSelect(sqlite3 *db, sqlite3_stmt *&statement, const std::string &table)
383 {
384 std::string dis_tableName = RelationalStoreManager::GetDistributedTableName(DEVICE_B, table);
385 const std::string sql = "SELECT * FROM " + dis_tableName;
386 LOGD("exec sql: %s", sql.c_str());
387 return sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr);
388 }
389
CheckDataInRealDevice()390 void CheckDataInRealDevice()
391 {
392 sqlite3 *db = nullptr;
393 EXPECT_EQ(GetDB(db, g_storePath2), SQLITE_OK);
394
395 sqlite3_stmt *statement = nullptr;
396 EXPECT_EQ(PrepareSelect(db, statement, g_tableName), SQLITE_OK);
397 int rowCount = 0;
398 while (true) {
399 int rc = sqlite3_step(statement);
400 if (rc != SQLITE_ROW) {
401 LOGD("GetSyncData Exist by code[%d]", rc);
402 break;
403 }
404 int columnCount = sqlite3_column_count(statement);
405 EXPECT_EQ(columnCount, 2); // 2: result index
406 rowCount++;
407 }
408 EXPECT_EQ(rowCount, 1);
409 sqlite3_finalize(statement);
410 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
411 }
412
RegOnDispatchWithoutDataPacket(std::atomic<int> & messageCount,bool checkVirtual=true)413 void RegOnDispatchWithoutDataPacket(std::atomic<int> &messageCount, bool checkVirtual = true)
414 {
415 g_communicatorAggregator->RegOnDispatch([&messageCount, checkVirtual](const std::string &dev, Message *msg) {
416 if (msg->GetMessageId() != TIME_SYNC_MESSAGE && msg->GetMessageId() != ABILITY_SYNC_MESSAGE) {
417 return;
418 }
419 if (((checkVirtual && dev != DEVICE_B) || (!checkVirtual && dev != "real_device")) ||
420 msg->GetMessageType() != TYPE_REQUEST) {
421 return;
422 }
423 messageCount++;
424 });
425 }
426 }
427
428 class DistributedDBRelationalMultiUserTest : public testing::Test {
429 public:
430 static void SetUpTestCase(void);
431 static void TearDownTestCase(void);
432 void SetUp();
433 void TearDown();
434 };
435
SetUpTestCase(void)436 void DistributedDBRelationalMultiUserTest::SetUpTestCase(void)
437 {
438 /**
439 * @tc.setup: Init datadir and Virtual Communicator.
440 */
441 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
442 g_storePath1 = g_testDir + "/test1.db";
443 g_storePath2 = g_testDir + "/test2.db";
444 sqlite3 *db1 = nullptr;
445 ASSERT_EQ(GetDB(db1, g_storePath1), SQLITE_OK);
446 sqlite3_close(db1);
447
448 sqlite3 *db2 = nullptr;
449 ASSERT_EQ(GetDB(db2, g_storePath2), SQLITE_OK);
450 sqlite3_close(db2);
451
452 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
453 ASSERT_TRUE(g_communicatorAggregator != nullptr);
454 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
455 }
456
TearDownTestCase(void)457 void DistributedDBRelationalMultiUserTest::TearDownTestCase(void)
458 {
459 /**
460 * @tc.teardown: Release virtual Communicator and clear data dir.
461 */
462 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
463 LOGE("rm test db files error!");
464 }
465 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
466 }
467
SetUp(void)468 void DistributedDBRelationalMultiUserTest::SetUp(void)
469 {
470 DistributedDBToolsUnitTest::PrintTestCaseInfo();
471 /**
472 * @tc.setup: create virtual device B
473 */
474 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
475 ASSERT_TRUE(g_deviceB != nullptr);
476 VirtualRelationalVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
477 ASSERT_TRUE(syncInterfaceB != nullptr);
478 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
479 g_deviceC = new (std::nothrow) RelationalVirtualDevice(DEVICE_C);
480 ASSERT_TRUE(g_deviceC != nullptr);
481 VirtualRelationalVerSyncDBInterface *syncInterfaceC = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
482 ASSERT_TRUE(syncInterfaceC != nullptr);
483 ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
484 }
485
TearDown(void)486 void DistributedDBRelationalMultiUserTest::TearDown(void)
487 {
488 /**
489 * @tc.teardown: Release device A, B, C
490 */
491 if (g_deviceB != nullptr) {
492 delete g_deviceB;
493 g_deviceB = nullptr;
494 }
495 if (g_deviceC != nullptr) {
496 delete g_deviceC;
497 g_deviceC = nullptr;
498 }
499 SyncActivationCheckCallback callback = nullptr;
500 RuntimeConfig::SetSyncActivationCheckCallback(callback);
501 RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
502 }
503
504 /**
505 * @tc.name: multi user 001
506 * @tc.desc: Test multi user change for rdb
507 * @tc.type: FUNC
508 * @tc.require: AR000GK58G
509 * @tc.author: zhangshijie
510 */
511 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser001, TestSize.Level0)
512 {
513 /**
514 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
515 */
516 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
517
518 /**
519 * @tc.steps: step2. openstore1 and openstore2
520 * @tc.expected: step2. only user2 sync mode is active
521 */
522 OpenStore1();
523 OpenStore2();
524
525 /**
526 * @tc.steps: step3. prepare environment
527 */
528 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
529 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
530
531 /**
532 * @tc.steps: step4. prepare data
533 */
534 PrepareData(g_tableName, g_storePath1);
535 PrepareData(g_tableName, g_storePath2);
536
537 /**
538 * @tc.steps: step5. g_rdbDelegatePtr1 and g_rdbDelegatePtr2 call sync
539 * @tc.expected: step5. g_rdbDelegatePtr2 call success
540 */
541 std::vector<std::string> devices;
542 devices.push_back(g_deviceB->GetDeviceId());
543 std::vector<RelationalVirtualDevice *> remoteDev;
544 remoteDev.push_back(g_deviceB);
545 remoteDev.push_back(g_deviceC);
546 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
547 CheckSyncTest(NOT_ACTIVE, OK, devices);
548
549 /**
550 * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
551 */
552 std::vector<VirtualRowData> targetData;
553 g_deviceB->GetAllSyncData(g_tableName, targetData);
554 EXPECT_EQ(targetData.size(), 1u);
555
556 /**
557 * @tc.expected: step7. user change
558 */
559 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
560 RuntimeConfig::NotifyUserChanged();
561 /**
562 * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
563 * @tc.expected: step8. g_kvDelegatePtr1 call success
564 */
565 devices.clear();
566 devices.push_back(g_deviceC->GetDeviceId());
567 CheckSyncTest(OK, NOT_ACTIVE, devices);
568 /**
569 * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1}
570 */
571 targetData.clear();
572 g_deviceC->GetAllSyncData(g_tableName, targetData);
573 EXPECT_EQ(targetData.size(), 1u);
574 CloseStore();
575 }
576
577 /**
578 * @tc.name: multi user 002
579 * @tc.desc: Test multi user not change for rdb
580 * @tc.type: FUNC
581 * @tc.require: AR000GK58G
582 * @tc.author: zhangshijie
583 */
584 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser002, TestSize.Level0)
585 {
586 /**
587 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
588 */
589 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
590 /**
591 * @tc.steps: step2. openstore1 and openstore2
592 * @tc.expected: step2. only user2 sync mode is active
593 */
594 OpenStore1();
595 OpenStore2();
596
597 /**
598 * @tc.steps: step3. prepare environment
599 */
600 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
601 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
602
603 /**
604 * @tc.steps: step4. prepare data
605 */
606 PrepareData(g_tableName, g_storePath1);
607 PrepareData(g_tableName, g_storePath2);
608
609 /**
610 * @tc.steps: step4. GetRelationalStoreIdentifier success when userId is invalid
611 */
612 std::string userId;
613 EXPECT_TRUE(g_mgr1.GetRelationalStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
614 userId.resize(130);
615 EXPECT_TRUE(g_mgr1.GetRelationalStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
616
617 /**
618 * @tc.steps: step5. g_rdbDelegatePtr1 and g_rdbDelegatePtr2 call sync
619 * @tc.expected: step5. g_rdbDelegatePtr2 call success
620 */
621 std::vector<std::string> devices;
622 devices.push_back(g_deviceB->GetDeviceId());
623 std::vector<RelationalVirtualDevice *> remoteDev;
624 remoteDev.push_back(g_deviceB);
625 remoteDev.push_back(g_deviceC);
626 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
627 CheckSyncTest(NOT_ACTIVE, OK, devices);
628
629 /**
630 * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
631 */
632 std::vector<VirtualRowData> targetData;
633 g_deviceB->GetAllSyncData(g_tableName, targetData);
634 EXPECT_EQ(targetData.size(), 1u);
635
636 /**
637 * @tc.expected: step7. user not change
638 */
639 RuntimeConfig::NotifyUserChanged();
640
641 /**
642 * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
643 * @tc.expected: step8. g_kvDelegatePtr1 call success
644 */
645 CheckSyncTest(NOT_ACTIVE, OK, devices);
646
647 /**
648 * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1}
649 */
650 targetData.clear();
651 g_deviceB->GetAllSyncData(g_tableName, targetData);
652 EXPECT_EQ(targetData.size(), 1u);
653 CloseStore();
654 }
655
656 /**
657 * @tc.name: multi user 003
658 * @tc.desc: enhancement callback return true in multiuser mode for rdb
659 * @tc.type: FUNC
660 * @tc.require: AR000GK58G
661 * @tc.author: zhangshijie
662 */
663 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser003, TestSize.Level3)
664 {
665 /**
666 * @tc.steps: step1. prepare environment
667 */
668 OpenStore1();
669 OpenStore2();
670 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
671 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
672 CloseStore();
673
674 /**
675 * @tc.steps: step2. set SyncActivationCheckCallback and only userId2 can active
676 */
677 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
678
679 /**
680 * @tc.steps: step3. SetAutoLaunchRequestCallback
681 * @tc.expected: step3. success.
682 */
683 g_mgr1.SetAutoLaunchRequestCallback(g_callback);
684
685 /**
686 * @tc.steps: step4. RunCommunicatorLackCallback
687 * @tc.expected: step4. success.
688 */
689 g_identifier = g_mgr1.GetRelationalStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true);
690 EXPECT_TRUE(g_identifier == g_mgr1.GetRelationalStoreIdentifier(USER_ID_1, APP_ID, STORE_ID, true));
691 std::vector<uint8_t> label(g_identifier.begin(), g_identifier.end());
692 g_communicatorAggregator->SetCurrentUserId(USER_ID_2);
693 g_communicatorAggregator->RunCommunicatorLackCallback(label);
694 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
695
696 /**
697 * @tc.steps: step5. device B put one data
698 * @tc.expected: step5. success.
699 */
700 VirtualRowData virtualRowData;
701 DataValue d1;
702 d1 = (int64_t)1;
703 virtualRowData.objectData.PutDataValue("id", d1);
704 DataValue d2;
705 d2.SetText("hello");
706 virtualRowData.objectData.PutDataValue("name", d2);
707 virtualRowData.logInfo.timestamp = 1;
708 g_deviceB->PutData(g_tableName, {virtualRowData});
709
710 std::vector<RelationalVirtualDevice *> remoteDev;
711 remoteDev.push_back(g_deviceB);
712 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
713
714 /**
715 * @tc.steps: step6. device B push sync to A
716 * @tc.expected: step6. success.
717 */
718 Query query = Query::Select(g_tableName);
719 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), OK);
720
721 /**
722 * @tc.steps: step7. deviceA have {k1,v1}
723 * @tc.expected: step7. success.
724 */
725 CheckDataInRealDevice();
726
727 RuntimeConfig::SetAutoLaunchRequestCallback(nullptr, DBType::DB_RELATION);
728 RuntimeConfig::ReleaseAutoLaunch(USER_ID_2, APP_ID, STORE_ID, DBType::DB_RELATION);
729 RuntimeConfig::ReleaseAutoLaunch(USER_ID_2, APP_ID, STORE_ID, DBType::DB_RELATION);
730 g_currentStatus = 0;
731 CloseStore();
732 }
733
734 /**
735 * @tc.name: multi user 004
736 * @tc.desc: test NotifyUserChanged func when all db in normal sync mode for rdb
737 * @tc.type: FUNC
738 * @tc.require: AR000GK58G
739 * @tc.author: zhangshijie
740 */
741 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser004, TestSize.Level0)
742 {
743 /**
744 * @tc.steps: step1. openstore1 and openstore2 in normal sync mode
745 * @tc.expected: step1. only user2 sync mode is active
746 */
747 OpenStore1(false);
748 OpenStore2(false);
749
750 /**
751 * @tc.steps: step2. call NotifyUserChanged
752 * @tc.expected: step2. return OK
753 */
754 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
755 CloseStore();
756
757 /**
758 * @tc.steps: step3. openstore1 open normal sync mode and and openstore2 in dual tuple
759 * @tc.expected: step3. only user2 sync mode is active
760 */
761 OpenStore1(false);
762 OpenStore2();
763
764 /**
765 * @tc.steps: step4. call NotifyUserChanged
766 * @tc.expected: step4. return OK
767 */
768 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
769 CloseStore();
770 }
771
772 /**
773 * @tc.name: multi user 005
774 * @tc.desc: test NotifyUserChanged and close db concurrently for rdb
775 * @tc.type: FUNC
776 * @tc.require: AR000GK58G
777 * @tc.author: zhangshijie
778 */
779 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser005, TestSize.Level0)
780 {
781 /**
782 * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
783 */
784 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
785
786 /**
787 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
788 * @tc.expected: step2. only user2 sync mode is active
789 */
790 OpenStore1(true);
791 OpenStore2(false);
792
793 /**
794 * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
795 */
796 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
797
798 /**
799 * @tc.steps: step4. call NotifyUserChanged and close db concurrently
800 * @tc.expected: step4. return OK
801 */
__anon3413e1da0e02() 802 thread subThread([&]() {
803 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
804 });
805 subThread.detach();
806 EXPECT_EQ(g_mgr1.CloseStore(g_rdbDelegatePtr1), OK);
807 g_rdbDelegatePtr1 = nullptr;
808 CloseStore();
809 }
810
811 /**
812 * @tc.name: multi user 006
813 * @tc.desc: test NotifyUserChanged and block sync concurrently for rdb
814 * @tc.type: FUNC
815 * @tc.require: AR000GK58G
816 * @tc.author: zhangshijie
817 */
818 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser006, TestSize.Level0)
819 {
820 TestSyncWithUserChange(true, false);
821 }
822
823 /**
824 * @tc.name: multi user 007
825 * @tc.desc: test NotifyUserChanged and non-block sync concurrently for rdb
826 * @tc.type: FUNC
827 * @tc.require: AR000GK58G
828 * @tc.author: zhangshijie
829 */
830 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser007, TestSize.Level0)
831 {
832 TestSyncWithUserChange(false, false);
833 }
834
835 /**
836 * @tc.name: multi user 008
837 * @tc.desc: test NotifyUserChanged and remote query concurrently for rdb
838 * @tc.type: FUNC
839 * @tc.require: AR000GK58G
840 * @tc.author: zhangshijie
841 */
842 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser008, TestSize.Level1)
843 {
844 /**
845 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
846 */
847 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
848
849 /**
850 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
851 * @tc.expected: step2. only user2 sync mode is active
852 */
853 OpenStore1(true);
854 OpenStore2(true);
855 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
856
857 /**
858 * @tc.steps: step3. user1 call remote query
859 * @tc.expected: step3. sync should return NOT_ACTIVE.
860 */
861 std::vector<RelationalVirtualDevice *> remoteDev;
862 remoteDev.push_back(g_deviceB);
863 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
864 RemoteCondition condition;
865 condition.sql = "SELECT * FROM " + g_tableName;
866 std::shared_ptr<ResultSet> result = std::make_shared<RelationalResultSetImpl>();
867 DBStatus status = g_rdbDelegatePtr1->RemoteQuery(g_deviceB->GetDeviceId(), condition,
868 DBConstant::MAX_TIMEOUT, result);
869 EXPECT_EQ(status, NOT_ACTIVE);
870 EXPECT_EQ(result, nullptr);
871 CloseStore();
872 }
873
874 /**
875 * @tc.name: multi user 009
876 * @tc.desc: test user change and remote query concurrently for rdb
877 * @tc.type: FUNC
878 * @tc.require: AR000GK58G
879 * @tc.author: zhangshijie
880 */
881 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser009, TestSize.Level0)
882 {
883 TestSyncWithUserChange(false, true);
884 }
885
886 /**
887 * @tc.name: multi user 010
888 * @tc.desc: test check sync active twice when open store
889 * @tc.type: FUNC
890 * @tc.require: AR000GK58G
891 * @tc.author: zhangqiquan
892 */
893 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser010, TestSize.Level1)
894 {
895 uint32_t callCount = 0u;
896 /**
897 * @tc.steps: step1. set SyncActivationCheckCallback and record call count, only first call return not active
898 */
899 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon3413e1da0f02(const std::string &userId, const std::string &appId, const std::string &storeId) 900 const std::string &storeId) -> bool {
901 callCount++;
902 return callCount != 1;
903 });
904 /**
905 * @tc.steps: step2. openstore1 in dual tuple sync mode
906 * @tc.expected: step2. it should be activated finally
907 */
908 OpenStore1(true);
909 /**
910 * @tc.steps: step3. prepare environment
911 */
912 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
913 /**
914 * @tc.steps: step4. call sync to DEVICES_B
915 * @tc.expected: step4. should return OK, not NOT_ACTIVE
916 */
917 Query query = Query::Select(g_tableName);
918 SyncStatusCallback callback = nullptr;
919 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
920 CloseStore();
921 }
922
923 /**
924 * @tc.name: multi user 011
925 * @tc.desc: test use different option to open store for rdb
926 * @tc.type: FUNC
927 * @tc.require: AR000GK58G
928 * @tc.author: zhangshijie
929 */
930 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser011, TestSize.Level1)
931 {
932 for (int i = 0; i < 2; i++) {
933 bool syncDualTupleMode = i / 2;
934 OpenStore1(syncDualTupleMode);
935 RelationalStoreDelegate::Option option = { g_observer };
936 option.syncDualTupleMode = !syncDualTupleMode;
937 RelationalStoreDelegate *rdbDeletegatePtr = nullptr;
938 EXPECT_EQ(g_mgr1.OpenStore(g_storePath1, STORE_ID_1, option, rdbDeletegatePtr), MODE_MISMATCH);
939 EXPECT_EQ(rdbDeletegatePtr, nullptr);
940 CloseStore();
941 }
942 }
943
944 /**
945 * @tc.name: multi user 012
946 * @tc.desc: test dont check sync active when open store with normal store
947 * @tc.type: FUNC
948 * @tc.require: AR000GK58G
949 * @tc.author: zhangqiquan
950 */
951 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser012, TestSize.Level1)
952 {
953 uint32_t callCount = 0u;
954 /**
955 * @tc.steps: step1. set SyncActivationCheckCallback and record call count
956 */
957 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon3413e1da1002(const std::string &userId, const std::string &appId, const std::string &storeId) 958 const std::string &storeId) -> bool {
959 callCount++;
960 return true;
961 });
962 /**
963 * @tc.steps: step2. openStore in no dual tuple sync mode
964 * @tc.expected: step2. it should be activated finally, and callCount should be zero
965 */
966 OpenStore1(false);
967 EXPECT_EQ(callCount, 0u);
968 CloseStore();
969 }
970
971 /**
972 * @tc.name: multi user 013
973 * @tc.desc: test dont check sync active when open store with normal store
974 * @tc.type: FUNC
975 * @tc.require: AR000GK58G
976 * @tc.author: zhangqiquan
977 */
978 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser013, TestSize.Level1)
979 {
980 uint32_t callCount = 0u;
981 /**
982 * @tc.steps: step1. set SyncActivationCheckCallback and record call count
983 */
984 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon3413e1da1102(const std::string &userId, const std::string &appId, const std::string &storeId) 985 const std::string &storeId) -> bool {
986 callCount++;
987 return true;
988 });
989 /**
990 * @tc.steps: step2. openStore in dual tuple sync mode
991 * @tc.expected: step2. it should not be activated finally, and callCount should be 2
992 */
993 OpenStore1(true);
994 EXPECT_EQ(callCount, 2u);
995 callCount = 0u;
996 EXPECT_EQ(g_rdbDelegatePtr1->RemoveDeviceData("DEVICE"), OK);
997 EXPECT_EQ(callCount, 0u);
998 CloseStore();
999 }
1000
1001 /**
1002 * @tc.name: multi user 014
1003 * @tc.desc: test remote query with multi user
1004 * @tc.type: FUNC
1005 * @tc.require:
1006 * @tc.author: zhangqiquan
1007 */
1008 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser014, TestSize.Level0)
1009 {
1010 /**
1011 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
1012 */
1013 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
1014 /**
1015 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1016 */
1017 OpenStore1(true);
1018 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1019 /**
1020 * @tc.steps: step3. disable communicator and call remote query
1021 * @tc.expected: step3. failed by communicator
1022 */
1023 g_communicatorAggregator->DisableCommunicator();
1024 RemoteCondition condition;
1025 condition.sql = "SELECT * FROM RdbMultiUser014";
1026 std::shared_ptr<ResultSet> resultSet;
1027 DBStatus status = g_rdbDelegatePtr1->RemoteQuery("DEVICE", condition, DBConstant::MAX_TIMEOUT, resultSet);
1028 EXPECT_EQ(status, COMM_FAILURE);
1029 EXPECT_EQ(resultSet, nullptr);
1030 CloseStore();
1031 g_communicatorAggregator->EnableCommunicator();
1032 SyncActivationCheckCallbackV2 callbackV2 = nullptr;
1033 RuntimeConfig::SetSyncActivationCheckCallback(callbackV2);
1034 OS::RemoveFile(g_storePath1);
1035 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1036 }
1037
1038 /**
1039 * @tc.name: RDBSyncOpt001
1040 * @tc.desc: check time sync and ability sync once
1041 * @tc.type: FUNC
1042 * @tc.require:
1043 * @tc.author: zhangqiquan
1044 */
1045 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt001, TestSize.Level0)
1046 {
1047 /**
1048 * @tc.steps: step1. record packet which send to B
1049 */
1050 std::atomic<int> messageCount = 0;
1051 RegOnDispatchWithoutDataPacket(messageCount);
1052 /**
1053 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1054 */
1055 OpenStore1(true);
1056 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1057 PrepareVirtualDeviceBEnv(g_tableName);
1058 /**
1059 * @tc.steps: step3. call sync to DEVICES_B
1060 * @tc.expected: step3. should return OK
1061 */
1062 Query query = Query::Select(g_tableName);
1063 SyncStatusCallback callback = nullptr;
1064 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1065 CloseStore();
1066 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1067 /**
1068 * @tc.steps: step4. re open store and sync again
1069 * @tc.expected: step4. reopen OK and sync success, no negotiation packet
1070 */
1071 OpenStore1(true);
1072 messageCount = 0;
1073 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1074 EXPECT_EQ(messageCount, 0);
1075 CloseStore();
1076 OS::RemoveFile(g_storePath1);
1077 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1078 g_communicatorAggregator->RegOnDispatch(nullptr);
1079 }
1080
1081 /**
1082 * @tc.name: RDBSyncOpt002
1083 * @tc.desc: check re ability sync after create distributed table
1084 * @tc.type: FUNC
1085 * @tc.require:
1086 * @tc.author: zhangqiquan
1087 */
1088 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt002, TestSize.Level0)
1089 {
1090 /**
1091 * @tc.steps: step1. record packet which send to B
1092 */
1093 std::atomic<int> messageCount = 0;
1094 RegOnDispatchWithoutDataPacket(messageCount);
1095 /**
1096 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1097 */
1098 OpenStore1(true);
1099 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1100 PrepareVirtualDeviceBEnv(g_tableName);
1101 /**
1102 * @tc.steps: step3. call sync to DEVICES_B
1103 * @tc.expected: step3. should return OK
1104 */
1105 Query query = Query::Select(g_tableName);
1106 SyncStatusCallback callback = nullptr;
1107 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1108 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1109 /**
1110 * @tc.steps: step4. create distributed table and sync again
1111 * @tc.expected: step4. reopen OK and sync success, only ability packet
1112 */
1113 PrepareEnvironment("table2", g_storePath1, g_rdbDelegatePtr1);
1114 messageCount = 0;
1115 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1116 EXPECT_EQ(messageCount, 1);
1117 CloseStore();
1118 OS::RemoveFile(g_storePath1);
1119 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1120 g_communicatorAggregator->RegOnDispatch(nullptr);
1121 }
1122
1123 /**
1124 * @tc.name: RDBSyncOpt003
1125 * @tc.desc: check re ability sync after create distributed table
1126 * @tc.type: FUNC
1127 * @tc.require:
1128 * @tc.author: zhangqiquan
1129 */
1130 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt003, TestSize.Level0)
1131 {
1132 /**
1133 * @tc.steps: step1. record packet which send to B
1134 */
1135 std::atomic<int> messageCount = 0;
1136 RegOnDispatchWithoutDataPacket(messageCount, false);
1137 /**
1138 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1139 */
1140 OpenStore1(true);
1141 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1142 PrepareVirtualDeviceBEnv(g_tableName);
1143 /**
1144 * @tc.steps: step3. call sync to DEVICES_B
1145 * @tc.expected: step3. should return OK
1146 */
1147 Query query = Query::Select(g_tableName);
1148 SyncStatusCallback callback = nullptr;
1149 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1150 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1151 /**
1152 * @tc.steps: step4. create distributed table and sync again
1153 * @tc.expected: step4. reopen OK and sync success, only ability packet
1154 */
1155 PrepareEnvironment("table2", g_storePath1, g_rdbDelegatePtr1);
1156 messageCount = 0;
1157 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1158 EXPECT_EQ(messageCount, 1);
1159 CloseStore();
1160 OS::RemoveFile(g_storePath1);
1161 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1162 g_communicatorAggregator->RegOnDispatch(nullptr);
1163 }
1164
1165 /**
1166 * @tc.name: RDBSyncOpt004
1167 * @tc.desc: check ability sync once after reopen
1168 * @tc.type: FUNC
1169 * @tc.require:
1170 * @tc.author: zhangqiquan
1171 */
1172 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt004, TestSize.Level0)
1173 {
1174 /**
1175 * @tc.steps: step1. record packet which send to B
1176 */
1177 std::atomic<int> messageCount = 0;
1178 RegOnDispatchWithoutDataPacket(messageCount, false);
1179 /**
1180 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1181 */
1182 OpenStore1(true);
1183 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1184 PrepareVirtualDeviceBEnv(g_tableName);
1185 /**
1186 * @tc.steps: step3. call sync to DEVICES_B
1187 * @tc.expected: step3. should return OK
1188 */
1189 Query query = Query::Select(g_tableName);
1190 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PUSH_ONLY, query, true);
1191 CloseStore();
1192 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1193 /**
1194 * @tc.steps: step4. re open store and sync again
1195 * @tc.expected: step4. reopen OK and sync success, no negotiation packet
1196 */
1197 OpenStore1(true);
1198 messageCount = 0;
1199 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PUSH_ONLY, query, true);
1200 EXPECT_EQ(messageCount, 0);
1201 CloseStore();
1202 OS::RemoveFile(g_storePath1);
1203 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1204 g_communicatorAggregator->RegOnDispatch(nullptr);
1205 }
1206
1207 /**
1208 * @tc.name: RDBSyncOpt005
1209 * @tc.desc: check re time sync after time change
1210 * @tc.type: FUNC
1211 * @tc.require:
1212 * @tc.author: zhangqiquan
1213 */
1214 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt005, TestSize.Level0)
1215 {
1216 /**
1217 * @tc.steps: step1. record packet which send to B
1218 */
1219 std::atomic<int> messageCount = 0;
1220 RegOnDispatchWithoutDataPacket(messageCount, false);
1221 /**
1222 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1223 */
1224 OpenStore1(true);
1225 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1226 PrepareVirtualDeviceBEnv(g_tableName);
1227 /**
1228 * @tc.steps: step3. call sync to DEVICES_B
1229 * @tc.expected: step3. should return OK
1230 */
1231 Query query = Query::Select(g_tableName);
1232 SyncStatusCallback callback = nullptr;
1233 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1234 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1235 /**
1236 * @tc.steps: step4. notify time change and sync again
1237 * @tc.expected: step4. sync success, only time sync packet
1238 */
1239 RuntimeContext::GetInstance()->NotifyTimestampChanged(100);
1240 RuntimeContext::GetInstance()->RecordAllTimeChange();
1241 RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
1242 messageCount = 0;
1243 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1244 EXPECT_EQ(messageCount, 1);
1245 CloseStore();
1246 OS::RemoveFile(g_storePath1);
1247 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1248 g_communicatorAggregator->RegOnDispatch(nullptr);
1249 }