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,
__anon1830fae20202(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,
__anon1830fae20302(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,
__anon1830fae20602(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
__anon1830fae20702(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
__anon1830fae20802(const std::string &identifier, AutoLaunchParam ¶m) 262 const AutoLaunchRequestCallback g_callback2 = [](const std::string &identifier, AutoLaunchParam ¶m) {
263 if (g_identifier != identifier) {
264 LOGD("g_identifier(%s) != identifier(%s)", g_identifier.c_str(), identifier.c_str());
265 return false;
266 }
267 param.subUser = SUB_USER_1;
268 param.path = g_testDir + "/test2.db";
269 param.appId = APP_ID;
270 param.storeId = STORE_ID;
271 CipherPassword passwd;
272 param.option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr,
273 0, nullptr};
274 param.notifier = g_notifier;
275 param.option.syncDualTupleMode = false;
276 return true;
277 };
278
DoRemoteQuery()279 void DoRemoteQuery()
280 {
281 RemoteCondition condition;
282 condition.sql = "SELECT * FROM " + g_tableName;
283 std::shared_ptr<ResultSet> result = std::make_shared<RelationalResultSetImpl>();
284 EXPECT_EQ(g_rdbDelegatePtr1->RemoteQuery(g_deviceB->GetDeviceId(), condition,
285 DBConstant::MAX_TIMEOUT, result), USER_CHANGED);
286 EXPECT_EQ(result, nullptr);
287 g_communicatorAggregator->RegOnDispatch(nullptr);
288 CloseStore();
289 }
290
CheckSyncResult(bool wait,bool isRemoteQuery)291 void CheckSyncResult(bool wait, bool isRemoteQuery)
292 {
293 std::mutex syncLock_{};
294 std::condition_variable syncCondVar_{};
295 std::map<std::string, std::vector<TableStatus>> statusMap;
296 SyncStatusCallback callBack = [&statusMap, &syncLock_, &syncCondVar_, wait](
297 const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
298 statusMap = devicesMap;
299 if (!wait) {
300 std::unique_lock<std::mutex> innerlock(syncLock_);
301 syncCondVar_.notify_one();
302 }
303 };
304 Query query = Query::Select(g_tableName);
305 std::vector<std::string> devices;
306 devices.push_back(g_deviceB->GetDeviceId());
307 std::vector<RelationalVirtualDevice *> remoteDev;
308 remoteDev.push_back(g_deviceB);
309 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
310
311 DBStatus status = DB_ERROR;
312 if (isRemoteQuery) {
313 DoRemoteQuery();
314 return;
315 }
316
317 status = g_rdbDelegatePtr1->Sync(devices, SYNC_MODE_PUSH_ONLY, query, callBack, wait);
318 EXPECT_EQ(status, OK);
319
320 if (!wait) {
321 std::unique_lock<std::mutex> lock(syncLock_);
322 syncCondVar_.wait(lock, [status, &statusMap]() {
323 if (status != OK) {
324 return true;
325 }
326 return !statusMap.empty();
327 });
328 }
329
330 g_communicatorAggregator->RegOnDispatch(nullptr);
331 EXPECT_EQ(statusMap.size(), devices.size());
332 for (const auto &pair : statusMap) {
333 for (const auto &tableStatus : pair.second) {
334 EXPECT_TRUE(tableStatus.status == USER_CHANGED);
335 }
336 }
337 CloseStore();
338 }
339
TestSyncWithUserChange(bool wait,bool isRemoteQuery)340 void TestSyncWithUserChange(bool wait, bool isRemoteQuery)
341 {
342 /**
343 * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
344 */
345 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
346 /**
347 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
348 * @tc.expected: step2. only user2 sync mode is active
349 */
350 OpenStore1(true);
351 OpenStore2(true);
352
353 /**
354 * @tc.steps: step3. prepare environment
355 */
356 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
357 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
358
359 /**
360 * @tc.steps: step4. prepare data
361 */
362 PrepareData(g_tableName, g_storePath1);
363 PrepareData(g_tableName, g_storePath2);
364
365 /**
366 * @tc.steps: step5. set SyncActivationCheckCallback and only userId2 can active
367 */
368 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
369
370 /**
371 * @tc.steps: step6. call NotifyUserChanged and block sync db concurrently
372 * @tc.expected: step6. return OK
373 */
374 CipherPassword passwd;
375 bool startSync = false;
376 std::condition_variable cv;
377 thread subThread([&]() {
378 std::mutex notifyLock;
379 std::unique_lock<std::mutex> lck(notifyLock);
380 cv.wait(lck, [&startSync]() { return startSync; });
381 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
382 });
383 subThread.detach();
384 g_communicatorAggregator->RegOnDispatch([&](const std::string&, Message *inMsg) {
385 if (!startSync) {
386 startSync = true;
387 cv.notify_all();
388 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); // wait for notify user change
389 }
390 });
391
392 /**
393 * @tc.steps: step7. deviceA call sync and wait
394 * @tc.expected: step7. sync should return OK.
395 */
396 CheckSyncResult(wait, isRemoteQuery);
397 }
398
PrepareSelect(sqlite3 * db,sqlite3_stmt * & statement,const std::string & table)399 int PrepareSelect(sqlite3 *db, sqlite3_stmt *&statement, const std::string &table)
400 {
401 std::string dis_tableName = RelationalStoreManager::GetDistributedTableName(DEVICE_B, table);
402 const std::string sql = "SELECT * FROM " + dis_tableName;
403 LOGD("exec sql: %s", sql.c_str());
404 return sqlite3_prepare_v2(db, sql.c_str(), -1, &statement, nullptr);
405 }
406
CheckDataInRealDevice()407 void CheckDataInRealDevice()
408 {
409 sqlite3 *db = nullptr;
410 EXPECT_EQ(GetDB(db, g_storePath2), SQLITE_OK);
411
412 sqlite3_stmt *statement = nullptr;
413 EXPECT_EQ(PrepareSelect(db, statement, g_tableName), SQLITE_OK);
414 int rowCount = 0;
415 while (true) {
416 int rc = sqlite3_step(statement);
417 if (rc != SQLITE_ROW) {
418 LOGD("GetSyncData Exist by code[%d]", rc);
419 break;
420 }
421 int columnCount = sqlite3_column_count(statement);
422 EXPECT_EQ(columnCount, 2); // 2: result index
423 rowCount++;
424 }
425 EXPECT_EQ(rowCount, 1);
426 sqlite3_finalize(statement);
427 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
428 }
429
RegOnDispatchWithoutDataPacket(std::atomic<int> & messageCount,bool checkVirtual=true)430 void RegOnDispatchWithoutDataPacket(std::atomic<int> &messageCount, bool checkVirtual = true)
431 {
432 g_communicatorAggregator->RegOnDispatch([&messageCount, checkVirtual](const std::string &dev, Message *msg) {
433 if (msg->GetMessageId() != TIME_SYNC_MESSAGE && msg->GetMessageId() != ABILITY_SYNC_MESSAGE) {
434 return;
435 }
436 if (((checkVirtual && dev != DEVICE_B) || (!checkVirtual && dev != "real_device")) ||
437 msg->GetMessageType() != TYPE_REQUEST) {
438 return;
439 }
440 messageCount++;
441 });
442 }
443
InsertBatchValue(const std::string & tableName,const std::string & dbPath,int totalNum)444 void InsertBatchValue(const std::string &tableName, const std::string &dbPath, int totalNum)
445 {
446 sqlite3 *db = nullptr;
447 EXPECT_EQ(GetDB(db, dbPath), SQLITE_OK);
448 for (int i = 0; i < totalNum; i++) {
449 std::string sql = "insert into " + tableName
450 + " values(" + std::to_string(i) + ", 'aaa');";
451 EXPECT_EQ(sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr), SQLITE_OK);
452 }
453 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
454 }
455 }
456
457 class DistributedDBRelationalMultiUserTest : public testing::Test {
458 public:
459 static void SetUpTestCase(void);
460 static void TearDownTestCase(void);
461 void SetUp();
462 void TearDown();
463 };
464
SetUpTestCase(void)465 void DistributedDBRelationalMultiUserTest::SetUpTestCase(void)
466 {
467 /**
468 * @tc.setup: Init datadir and Virtual Communicator.
469 */
470 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
471 g_storePath1 = g_testDir + "/test1.db";
472 g_storePath2 = g_testDir + "/test2.db";
473 sqlite3 *db1 = nullptr;
474 ASSERT_EQ(GetDB(db1, g_storePath1), SQLITE_OK);
475 sqlite3_close(db1);
476
477 sqlite3 *db2 = nullptr;
478 ASSERT_EQ(GetDB(db2, g_storePath2), SQLITE_OK);
479 sqlite3_close(db2);
480
481 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
482 ASSERT_TRUE(g_communicatorAggregator != nullptr);
483 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
484 }
485
TearDownTestCase(void)486 void DistributedDBRelationalMultiUserTest::TearDownTestCase(void)
487 {
488 /**
489 * @tc.teardown: Release virtual Communicator and clear data dir.
490 */
491 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
492 LOGE("rm test db files error!");
493 }
494 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
495 }
496
SetUp(void)497 void DistributedDBRelationalMultiUserTest::SetUp(void)
498 {
499 DistributedDBToolsUnitTest::PrintTestCaseInfo();
500 /**
501 * @tc.setup: create virtual device B
502 */
503 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
504 ASSERT_TRUE(g_deviceB != nullptr);
505 VirtualRelationalVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
506 ASSERT_TRUE(syncInterfaceB != nullptr);
507 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
508 g_deviceC = new (std::nothrow) RelationalVirtualDevice(DEVICE_C);
509 ASSERT_TRUE(g_deviceC != nullptr);
510 VirtualRelationalVerSyncDBInterface *syncInterfaceC = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
511 ASSERT_TRUE(syncInterfaceC != nullptr);
512 ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
513 }
514
TearDown(void)515 void DistributedDBRelationalMultiUserTest::TearDown(void)
516 {
517 /**
518 * @tc.teardown: Release device A, B, C
519 */
520 if (g_deviceB != nullptr) {
521 delete g_deviceB;
522 g_deviceB = nullptr;
523 }
524 if (g_deviceC != nullptr) {
525 delete g_deviceC;
526 g_deviceC = nullptr;
527 }
528 SyncActivationCheckCallback callback = nullptr;
529 RuntimeConfig::SetSyncActivationCheckCallback(callback);
530 RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
531 }
532
533 /**
534 * @tc.name: multi user 001
535 * @tc.desc: Test multi user change for rdb
536 * @tc.type: FUNC
537 * @tc.require: AR000GK58G
538 * @tc.author: zhangshijie
539 */
540 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser001, TestSize.Level0)
541 {
542 /**
543 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
544 */
545 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
546
547 /**
548 * @tc.steps: step2. openstore1 and openstore2
549 * @tc.expected: step2. only user2 sync mode is active
550 */
551 OpenStore1();
552 OpenStore2();
553
554 /**
555 * @tc.steps: step3. prepare environment
556 */
557 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
558 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
559
560 /**
561 * @tc.steps: step4. prepare data
562 */
563 PrepareData(g_tableName, g_storePath1);
564 PrepareData(g_tableName, g_storePath2);
565
566 /**
567 * @tc.steps: step5. g_rdbDelegatePtr1 and g_rdbDelegatePtr2 call sync
568 * @tc.expected: step5. g_rdbDelegatePtr2 call success
569 */
570 std::vector<std::string> devices;
571 devices.push_back(g_deviceB->GetDeviceId());
572 std::vector<RelationalVirtualDevice *> remoteDev;
573 remoteDev.push_back(g_deviceB);
574 remoteDev.push_back(g_deviceC);
575 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
576 CheckSyncTest(NOT_ACTIVE, OK, devices);
577
578 /**
579 * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
580 */
581 std::vector<VirtualRowData> targetData;
582 g_deviceB->GetAllSyncData(g_tableName, targetData);
583 EXPECT_EQ(targetData.size(), 1u);
584
585 /**
586 * @tc.expected: step7. user change
587 */
588 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
589 RuntimeConfig::NotifyUserChanged();
590 /**
591 * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
592 * @tc.expected: step8. g_kvDelegatePtr1 call success
593 */
594 devices.clear();
595 devices.push_back(g_deviceC->GetDeviceId());
596 CheckSyncTest(OK, NOT_ACTIVE, devices);
597 /**
598 * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1}
599 */
600 targetData.clear();
601 g_deviceC->GetAllSyncData(g_tableName, targetData);
602 EXPECT_EQ(targetData.size(), 1u);
603 CloseStore();
604 }
605
606 /**
607 * @tc.name: multi user 002
608 * @tc.desc: Test multi user not change for rdb
609 * @tc.type: FUNC
610 * @tc.require: AR000GK58G
611 * @tc.author: zhangshijie
612 */
613 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser002, TestSize.Level0)
614 {
615 /**
616 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
617 */
618 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
619 /**
620 * @tc.steps: step2. openstore1 and openstore2
621 * @tc.expected: step2. only user2 sync mode is active
622 */
623 OpenStore1();
624 OpenStore2();
625
626 /**
627 * @tc.steps: step3. prepare environment
628 */
629 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
630 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
631
632 /**
633 * @tc.steps: step4. prepare data
634 */
635 PrepareData(g_tableName, g_storePath1);
636 PrepareData(g_tableName, g_storePath2);
637
638 /**
639 * @tc.steps: step4. GetRelationalStoreIdentifier success when userId is invalid
640 */
641 std::string userId;
642 EXPECT_TRUE(g_mgr1.GetRelationalStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
643 userId.resize(130);
644 EXPECT_TRUE(g_mgr1.GetRelationalStoreIdentifier(userId, APP_ID, USER_ID_2, true) != "");
645
646 /**
647 * @tc.steps: step5. g_rdbDelegatePtr1 and g_rdbDelegatePtr2 call sync
648 * @tc.expected: step5. g_rdbDelegatePtr2 call success
649 */
650 std::vector<std::string> devices;
651 devices.push_back(g_deviceB->GetDeviceId());
652 std::vector<RelationalVirtualDevice *> remoteDev;
653 remoteDev.push_back(g_deviceB);
654 remoteDev.push_back(g_deviceC);
655 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
656 CheckSyncTest(NOT_ACTIVE, OK, devices);
657
658 /**
659 * @tc.expected: step6. onComplete should be called, DeviceB have {k1,v1}
660 */
661 std::vector<VirtualRowData> targetData;
662 g_deviceB->GetAllSyncData(g_tableName, targetData);
663 EXPECT_EQ(targetData.size(), 1u);
664
665 /**
666 * @tc.expected: step7. user not change
667 */
668 RuntimeConfig::NotifyUserChanged();
669
670 /**
671 * @tc.steps: step8. g_kvDelegatePtr1 and g_kvDelegatePtr2 call sync
672 * @tc.expected: step8. g_kvDelegatePtr1 call success
673 */
674 CheckSyncTest(NOT_ACTIVE, OK, devices);
675
676 /**
677 * @tc.expected: step9. onComplete should be called, DeviceC have {k1,v1}
678 */
679 targetData.clear();
680 g_deviceB->GetAllSyncData(g_tableName, targetData);
681 EXPECT_EQ(targetData.size(), 1u);
682 CloseStore();
683 }
684
685 /**
686 * @tc.name: multi user 003
687 * @tc.desc: enhancement callback return true in multiuser mode for rdb
688 * @tc.type: FUNC
689 * @tc.require: AR000GK58G
690 * @tc.author: zhangshijie
691 */
692 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser003, TestSize.Level3)
693 {
694 /**
695 * @tc.steps: step1. prepare environment
696 */
697 OpenStore1();
698 OpenStore2();
699 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
700 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
701 CloseStore();
702
703 /**
704 * @tc.steps: step2. set SyncActivationCheckCallback and only userId2 can active
705 */
706 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
707
708 /**
709 * @tc.steps: step3. SetAutoLaunchRequestCallback
710 * @tc.expected: step3. success.
711 */
712 g_mgr1.SetAutoLaunchRequestCallback(g_callback);
713
714 /**
715 * @tc.steps: step4. RunCommunicatorLackCallback
716 * @tc.expected: step4. success.
717 */
718 g_identifier = g_mgr1.GetRelationalStoreIdentifier(USER_ID_2, APP_ID, STORE_ID, true);
719 EXPECT_TRUE(g_identifier == g_mgr1.GetRelationalStoreIdentifier(USER_ID_1, APP_ID, STORE_ID, true));
720 std::vector<uint8_t> label(g_identifier.begin(), g_identifier.end());
721 g_communicatorAggregator->SetCurrentUserId(USER_ID_2);
722 g_communicatorAggregator->RunCommunicatorLackCallback(label);
723 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
724
725 /**
726 * @tc.steps: step5. device B put one data
727 * @tc.expected: step5. success.
728 */
729 VirtualRowData virtualRowData;
730 DataValue d1;
731 d1 = (int64_t)1;
732 virtualRowData.objectData.PutDataValue("id", d1);
733 DataValue d2;
734 d2.SetText("hello");
735 virtualRowData.objectData.PutDataValue("name", d2);
736 virtualRowData.logInfo.timestamp = 1;
737 g_deviceB->PutData(g_tableName, {virtualRowData});
738
739 std::vector<RelationalVirtualDevice *> remoteDev;
740 remoteDev.push_back(g_deviceB);
741 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
742
743 /**
744 * @tc.steps: step6. device B push sync to A
745 * @tc.expected: step6. success.
746 */
747 Query query = Query::Select(g_tableName);
748 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
749
750 /**
751 * @tc.steps: step7. deviceA have {k1,v1}
752 * @tc.expected: step7. success.
753 */
754 CheckDataInRealDevice();
755
756 RuntimeConfig::SetAutoLaunchRequestCallback(nullptr, DBType::DB_RELATION);
757 RuntimeConfig::ReleaseAutoLaunch(USER_ID_2, APP_ID, STORE_ID, DBType::DB_RELATION);
758 RuntimeConfig::ReleaseAutoLaunch(USER_ID_2, APP_ID, STORE_ID, DBType::DB_RELATION);
759 g_currentStatus = 0;
760 CloseStore();
761 }
762
763 /**
764 * @tc.name: multi user 004
765 * @tc.desc: test NotifyUserChanged func when all db in normal sync mode for rdb
766 * @tc.type: FUNC
767 * @tc.require: AR000GK58G
768 * @tc.author: zhangshijie
769 */
770 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser004, TestSize.Level0)
771 {
772 /**
773 * @tc.steps: step1. openstore1 and openstore2 in normal sync mode
774 * @tc.expected: step1. only user2 sync mode is active
775 */
776 OpenStore1(false);
777 OpenStore2(false);
778
779 /**
780 * @tc.steps: step2. call NotifyUserChanged
781 * @tc.expected: step2. return OK
782 */
783 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
784 CloseStore();
785
786 /**
787 * @tc.steps: step3. openstore1 open normal sync mode and and openstore2 in dual tuple
788 * @tc.expected: step3. only user2 sync mode is active
789 */
790 OpenStore1(false);
791 OpenStore2();
792
793 /**
794 * @tc.steps: step4. call NotifyUserChanged
795 * @tc.expected: step4. return OK
796 */
797 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
798 CloseStore();
799 }
800
801 /**
802 * @tc.name: multi user 005
803 * @tc.desc: test NotifyUserChanged and close db concurrently for rdb
804 * @tc.type: FUNC
805 * @tc.require: AR000GK58G
806 * @tc.author: zhangshijie
807 */
808 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser005, TestSize.Level0)
809 {
810 /**
811 * @tc.steps: step1. set SyncActivationCheckCallback and only userId1 can active
812 */
813 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
814
815 /**
816 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
817 * @tc.expected: step2. only user2 sync mode is active
818 */
819 OpenStore1(true);
820 OpenStore2(false);
821
822 /**
823 * @tc.steps: step3. set SyncActivationCheckCallback and only userId2 can active
824 */
825 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
826
827 /**
828 * @tc.steps: step4. call NotifyUserChanged and close db concurrently
829 * @tc.expected: step4. return OK
830 */
__anon1830fae20f02() 831 thread subThread([&]() {
832 EXPECT_TRUE(RuntimeConfig::NotifyUserChanged() == OK);
833 });
834 subThread.detach();
835 EXPECT_EQ(g_mgr1.CloseStore(g_rdbDelegatePtr1), OK);
836 g_rdbDelegatePtr1 = nullptr;
837 CloseStore();
838 }
839
840 /**
841 * @tc.name: multi user 006
842 * @tc.desc: test NotifyUserChanged and block sync concurrently for rdb
843 * @tc.type: FUNC
844 * @tc.require: AR000GK58G
845 * @tc.author: zhangshijie
846 */
847 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser006, TestSize.Level0)
848 {
849 TestSyncWithUserChange(true, false);
850 }
851
852 /**
853 * @tc.name: multi user 007
854 * @tc.desc: test NotifyUserChanged and non-block sync concurrently for rdb
855 * @tc.type: FUNC
856 * @tc.require: AR000GK58G
857 * @tc.author: zhangshijie
858 */
859 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser007, TestSize.Level0)
860 {
861 TestSyncWithUserChange(false, false);
862 }
863
864 /**
865 * @tc.name: multi user 008
866 * @tc.desc: test NotifyUserChanged and remote query concurrently for rdb
867 * @tc.type: FUNC
868 * @tc.require: AR000GK58G
869 * @tc.author: zhangshijie
870 */
871 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser008, TestSize.Level1)
872 {
873 /**
874 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
875 */
876 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback1);
877
878 /**
879 * @tc.steps: step2. openstore1 in dual tuple sync mode and openstore2 in normal sync mode
880 * @tc.expected: step2. only user2 sync mode is active
881 */
882 OpenStore1(true);
883 OpenStore2(true);
884 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
885
886 /**
887 * @tc.steps: step3. user1 call remote query
888 * @tc.expected: step3. sync should return NOT_ACTIVE.
889 */
890 std::vector<RelationalVirtualDevice *> remoteDev;
891 remoteDev.push_back(g_deviceB);
892 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
893 RemoteCondition condition;
894 condition.sql = "SELECT * FROM " + g_tableName;
895 std::shared_ptr<ResultSet> result = std::make_shared<RelationalResultSetImpl>();
896 DBStatus status = g_rdbDelegatePtr1->RemoteQuery(g_deviceB->GetDeviceId(), condition,
897 DBConstant::MAX_TIMEOUT, result);
898 EXPECT_EQ(status, NOT_ACTIVE);
899 EXPECT_EQ(result, nullptr);
900 CloseStore();
901 }
902
903 /**
904 * @tc.name: multi user 009
905 * @tc.desc: test user change and remote query concurrently for rdb
906 * @tc.type: FUNC
907 * @tc.require: AR000GK58G
908 * @tc.author: zhangshijie
909 */
910 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser009, TestSize.Level0)
911 {
912 TestSyncWithUserChange(false, true);
913 }
914
915 /**
916 * @tc.name: multi user 010
917 * @tc.desc: test check sync active twice when open store
918 * @tc.type: FUNC
919 * @tc.require: AR000GK58G
920 * @tc.author: zhangqiquan
921 */
922 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser010, TestSize.Level1)
923 {
924 uint32_t callCount = 0u;
925 /**
926 * @tc.steps: step1. set SyncActivationCheckCallback and record call count, only first call return not active
927 */
928 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon1830fae21002(const std::string &userId, const std::string &appId, const std::string &storeId) 929 const std::string &storeId) -> bool {
930 callCount++;
931 return callCount != 1;
932 });
933 /**
934 * @tc.steps: step2. openstore1 in dual tuple sync mode
935 * @tc.expected: step2. it should be activated finally
936 */
937 OpenStore1(true);
938 /**
939 * @tc.steps: step3. prepare environment
940 */
941 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
942 /**
943 * @tc.steps: step4. call sync to DEVICES_B
944 * @tc.expected: step4. should return OK, not NOT_ACTIVE
945 */
946 Query query = Query::Select(g_tableName);
947 SyncStatusCallback callback = nullptr;
948 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
949 CloseStore();
950 }
951
952 /**
953 * @tc.name: multi user 011
954 * @tc.desc: test use different option to open store for rdb
955 * @tc.type: FUNC
956 * @tc.require: AR000GK58G
957 * @tc.author: zhangshijie
958 */
959 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser011, TestSize.Level1)
960 {
961 for (int i = 0; i < 2; i++) {
962 bool syncDualTupleMode = i / 2;
963 OpenStore1(syncDualTupleMode);
964 RelationalStoreDelegate::Option option = { g_observer };
965 option.syncDualTupleMode = !syncDualTupleMode;
966 RelationalStoreDelegate *rdbDeletegatePtr = nullptr;
967 EXPECT_EQ(g_mgr1.OpenStore(g_storePath1, STORE_ID_1, option, rdbDeletegatePtr), MODE_MISMATCH);
968 EXPECT_EQ(rdbDeletegatePtr, nullptr);
969 CloseStore();
970 }
971 }
972
973 /**
974 * @tc.name: multi user 012
975 * @tc.desc: test dont check sync active when open store with normal store
976 * @tc.type: FUNC
977 * @tc.require: AR000GK58G
978 * @tc.author: zhangqiquan
979 */
980 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser012, TestSize.Level1)
981 {
982 uint32_t callCount = 0u;
983 /**
984 * @tc.steps: step1. set SyncActivationCheckCallback and record call count
985 */
986 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon1830fae21102(const std::string &userId, const std::string &appId, const std::string &storeId) 987 const std::string &storeId) -> bool {
988 callCount++;
989 return true;
990 });
991 /**
992 * @tc.steps: step2. openStore in no dual tuple sync mode
993 * @tc.expected: step2. it should be activated finally, and callCount should be zero
994 */
995 OpenStore1(false);
996 EXPECT_EQ(callCount, 0u);
997 CloseStore();
998 }
999
1000 /**
1001 * @tc.name: multi user 013
1002 * @tc.desc: test dont check sync active when open store with normal store
1003 * @tc.type: FUNC
1004 * @tc.require: AR000GK58G
1005 * @tc.author: zhangqiquan
1006 */
1007 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser013, TestSize.Level1)
1008 {
1009 uint32_t callCount = 0u;
1010 /**
1011 * @tc.steps: step1. set SyncActivationCheckCallback and record call count
1012 */
1013 RuntimeConfig::SetSyncActivationCheckCallback([&callCount] (const std::string &userId, const std::string &appId,
__anon1830fae21202(const std::string &userId, const std::string &appId, const std::string &storeId) 1014 const std::string &storeId) -> bool {
1015 callCount++;
1016 return true;
1017 });
1018 /**
1019 * @tc.steps: step2. openStore in dual tuple sync mode
1020 * @tc.expected: step2. it should not be activated finally, and callCount should be 2
1021 */
1022 OpenStore1(true);
1023 EXPECT_EQ(callCount, 2u);
1024 callCount = 0u;
1025 EXPECT_EQ(g_rdbDelegatePtr1->RemoveDeviceData("DEVICE"), OK);
1026 EXPECT_EQ(callCount, 0u);
1027 CloseStore();
1028 }
1029
1030 /**
1031 * @tc.name: multi user 014
1032 * @tc.desc: test remote query with multi user
1033 * @tc.type: FUNC
1034 * @tc.require:
1035 * @tc.author: zhangqiquan
1036 */
1037 HWTEST_F(DistributedDBRelationalMultiUserTest, RdbMultiUser014, TestSize.Level0)
1038 {
1039 /**
1040 * @tc.steps: step1. set SyncActivationCheckCallback and only userId2 can active
1041 */
1042 RuntimeConfig::SetSyncActivationCheckCallback(g_syncActivationCheckCallback2);
1043 /**
1044 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1045 */
1046 OpenStore1(true);
1047 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1048 /**
1049 * @tc.steps: step3. disable communicator and call remote query
1050 * @tc.expected: step3. failed by communicator
1051 */
1052 g_communicatorAggregator->DisableCommunicator();
1053 RemoteCondition condition;
1054 condition.sql = "SELECT * FROM RdbMultiUser014";
1055 std::shared_ptr<ResultSet> resultSet;
1056 DBStatus status = g_rdbDelegatePtr1->RemoteQuery("DEVICE", condition, DBConstant::MAX_TIMEOUT, resultSet);
1057 EXPECT_EQ(status, COMM_FAILURE);
1058 EXPECT_EQ(resultSet, nullptr);
1059 CloseStore();
1060 g_communicatorAggregator->EnableCommunicator();
1061 SyncActivationCheckCallbackV2 callbackV2 = nullptr;
1062 RuntimeConfig::SetSyncActivationCheckCallback(callbackV2);
1063 OS::RemoveFile(g_storePath1);
1064 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1065 }
1066
1067 /**
1068 * @tc.name: RDBSyncOpt001
1069 * @tc.desc: check time sync and ability sync once
1070 * @tc.type: FUNC
1071 * @tc.require:
1072 * @tc.author: zhangqiquan
1073 */
1074 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt001, TestSize.Level0)
1075 {
1076 /**
1077 * @tc.steps: step1. record packet which send to B
1078 */
1079 std::atomic<int> messageCount = 0;
1080 RegOnDispatchWithoutDataPacket(messageCount);
1081 /**
1082 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1083 */
1084 OpenStore1(true);
1085 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1086 PrepareVirtualDeviceBEnv(g_tableName);
1087 /**
1088 * @tc.steps: step3. call sync to DEVICES_B
1089 * @tc.expected: step3. should return OK
1090 */
1091 Query query = Query::Select(g_tableName);
1092 SyncStatusCallback callback = nullptr;
1093 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1094 CloseStore();
1095 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1096 /**
1097 * @tc.steps: step4. re open store and sync again
1098 * @tc.expected: step4. reopen OK and sync success, no negotiation packet
1099 */
1100 OpenStore1(true);
1101 messageCount = 0;
1102 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1103 EXPECT_EQ(messageCount, 0);
1104 CloseStore();
1105 OS::RemoveFile(g_storePath1);
1106 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1107 g_communicatorAggregator->RegOnDispatch(nullptr);
1108 }
1109
1110 /**
1111 * @tc.name: RDBSyncOpt002
1112 * @tc.desc: check re ability sync after create distributed table
1113 * @tc.type: FUNC
1114 * @tc.require:
1115 * @tc.author: zhangqiquan
1116 */
1117 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt002, TestSize.Level0)
1118 {
1119 /**
1120 * @tc.steps: step1. record packet which send to B
1121 */
1122 std::atomic<int> messageCount = 0;
1123 RegOnDispatchWithoutDataPacket(messageCount);
1124 /**
1125 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1126 */
1127 OpenStore1(true);
1128 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1129 PrepareVirtualDeviceBEnv(g_tableName);
1130 /**
1131 * @tc.steps: step3. call sync to DEVICES_B
1132 * @tc.expected: step3. should return OK
1133 */
1134 Query query = Query::Select(g_tableName);
1135 SyncStatusCallback callback = nullptr;
1136 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1137 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1138 /**
1139 * @tc.steps: step4. create distributed table and sync again
1140 * @tc.expected: step4. reopen OK and sync success, only ability packet
1141 */
1142 PrepareEnvironment("table2", g_storePath1, g_rdbDelegatePtr1);
1143 messageCount = 0;
1144 EXPECT_EQ(g_rdbDelegatePtr1->Sync({DEVICE_B}, SYNC_MODE_PUSH_ONLY, query, callback, true), OK);
1145 EXPECT_EQ(messageCount, 1);
1146 CloseStore();
1147 OS::RemoveFile(g_storePath1);
1148 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1149 g_communicatorAggregator->RegOnDispatch(nullptr);
1150 }
1151
1152 /**
1153 * @tc.name: RDBSyncOpt003
1154 * @tc.desc: check re ability sync after create distributed table
1155 * @tc.type: FUNC
1156 * @tc.require:
1157 * @tc.author: zhangqiquan
1158 */
1159 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt003, TestSize.Level0)
1160 {
1161 /**
1162 * @tc.steps: step1. record packet which send to B
1163 */
1164 std::atomic<int> messageCount = 0;
1165 RegOnDispatchWithoutDataPacket(messageCount, false);
1166 /**
1167 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1168 */
1169 OpenStore1(true);
1170 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1171 PrepareVirtualDeviceBEnv(g_tableName);
1172 /**
1173 * @tc.steps: step3. call sync to DEVICES_B
1174 * @tc.expected: step3. should return OK
1175 */
1176 Query query = Query::Select(g_tableName);
1177 SyncStatusCallback callback = nullptr;
1178 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1179 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1180 /**
1181 * @tc.steps: step4. create distributed table and sync again
1182 * @tc.expected: step4. reopen OK and sync success, only ability packet
1183 */
1184 PrepareEnvironment("table2", g_storePath1, g_rdbDelegatePtr1);
1185 messageCount = 0;
1186 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1187 EXPECT_EQ(messageCount, 1);
1188 CloseStore();
1189 OS::RemoveFile(g_storePath1);
1190 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1191 g_communicatorAggregator->RegOnDispatch(nullptr);
1192 }
1193
1194 /**
1195 * @tc.name: RDBSyncOpt004
1196 * @tc.desc: check ability sync once after reopen
1197 * @tc.type: FUNC
1198 * @tc.require:
1199 * @tc.author: zhangqiquan
1200 */
1201 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt004, TestSize.Level0)
1202 {
1203 /**
1204 * @tc.steps: step1. record packet which send to B
1205 */
1206 std::atomic<int> messageCount = 0;
1207 RegOnDispatchWithoutDataPacket(messageCount, false);
1208 /**
1209 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1210 */
1211 OpenStore1(true);
1212 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1213 PrepareVirtualDeviceBEnv(g_tableName);
1214 /**
1215 * @tc.steps: step3. call sync to DEVICES_B
1216 * @tc.expected: step3. should return OK
1217 */
1218 Query query = Query::Select(g_tableName);
1219 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PUSH_ONLY, query, true);
1220 CloseStore();
1221 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1222 /**
1223 * @tc.steps: step4. re open store and sync again
1224 * @tc.expected: step4. reopen OK and sync success, no negotiation packet
1225 */
1226 OpenStore1(true);
1227 messageCount = 0;
1228 g_deviceB->GenericVirtualDevice::Sync(DistributedDB::SYNC_MODE_PUSH_ONLY, query, true);
1229 EXPECT_EQ(messageCount, 0);
1230 CloseStore();
1231 OS::RemoveFile(g_storePath1);
1232 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1233 g_communicatorAggregator->RegOnDispatch(nullptr);
1234 }
1235
1236 /**
1237 * @tc.name: RDBSyncOpt005
1238 * @tc.desc: check re time sync after time change
1239 * @tc.type: FUNC
1240 * @tc.require:
1241 * @tc.author: zhangqiquan
1242 */
1243 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt005, TestSize.Level0)
1244 {
1245 /**
1246 * @tc.steps: step1. record packet which send to B
1247 */
1248 std::atomic<int> messageCount = 0;
1249 RegOnDispatchWithoutDataPacket(messageCount, false);
1250 /**
1251 * @tc.steps: step2. openStore in dual tuple sync mode and call remote query
1252 */
1253 OpenStore1(true);
1254 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1255 PrepareVirtualDeviceBEnv(g_tableName);
1256 /**
1257 * @tc.steps: step3. call sync to DEVICES_B
1258 * @tc.expected: step3. should return OK
1259 */
1260 Query query = Query::Select(g_tableName);
1261 SyncStatusCallback callback = nullptr;
1262 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1263 EXPECT_EQ(messageCount, 2); // 2 contain time sync request packet and ability sync packet
1264 /**
1265 * @tc.steps: step4. notify time change and sync again
1266 * @tc.expected: step4. sync success, only time sync packet
1267 */
1268 RuntimeContext::GetInstance()->NotifyTimestampChanged(100);
1269 RuntimeContext::GetInstance()->RecordAllTimeChange();
1270 RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
1271 messageCount = 0;
1272 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1273 EXPECT_EQ(messageCount, 1);
1274 CloseStore();
1275 OS::RemoveFile(g_storePath1);
1276 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1277 g_communicatorAggregator->RegOnDispatch(nullptr);
1278 }
1279
1280 /**
1281 * @tc.name: RDBSyncOpt006
1282 * @tc.desc: check sync when time change.
1283 * @tc.type: FUNC
1284 * @tc.require:
1285 * @tc.author: suyue
1286 */
1287 HWTEST_F(DistributedDBRelationalMultiUserTest, RDBSyncOpt006, TestSize.Level0)
1288 {
1289 /**
1290 * @tc.steps: step1. openStore and insert data
1291 * @tc.expected: step1. return ok
1292 */
1293 OpenStore1(true);
1294 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1295 PrepareVirtualDeviceBEnv(g_tableName);
1296 InsertBatchValue(g_tableName, g_storePath1, 10000);
1297
1298 /**
1299 * @tc.steps: step2. device B set delay send time
1300 * * @tc.expected: step2. return ok
1301 */
1302 std::set<std::string> delayDevice = {DEVICE_B};
1303 g_communicatorAggregator->SetSendDelayInfo(3000u, TIME_SYNC_MESSAGE, 1u, 0u, delayDevice); // send delay 3000ms
1304
1305 /**
1306 * @tc.steps: step3. notify time change when sync
1307 * @tc.expected: step3. sync success
1308 */
1309 Query query = Query::Select(g_tableName);
1310 SyncStatusCallback callback = nullptr;
__anon1830fae21302() 1311 thread thd1 = thread([&]() {
1312 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PULL_ONLY, query, true), E_OK);
1313 });
1314 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
__anon1830fae21402() 1315 thread thd2 = thread([]() {
1316 RuntimeContext::GetInstance()->NotifyTimestampChanged(100);
1317 RuntimeContext::GetInstance()->RecordAllTimeChange();
1318 RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
1319 });
1320 thd1.join();
1321 thd2.join();
1322
1323 CloseStore();
1324 OS::RemoveFile(g_storePath1);
1325 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1326 g_communicatorAggregator->ResetSendDelayInfo();
1327 }
1328
1329 /**
1330 * @tc.name: SubUserAutoLaunchTest001
1331 * @tc.desc: Test auto launch with sub user
1332 * @tc.type: FUNC
1333 * @tc.require:
1334 * @tc.author: liaoyonghuang
1335 */
1336 HWTEST_F(DistributedDBRelationalMultiUserTest, SubUserAutoLaunchTest001, TestSize.Level0)
1337 {
1338 /**
1339 * @tc.steps: step1. Prepare db1 and db2 with subUser
1340 * @tc.expected: step1. success.
1341 */
1342 RelationalStoreManager subUserMgr2(APP_ID, USER_ID_1, SUB_USER_1);
1343 RelationalStoreDelegate::Option option;
1344 subUserMgr2.OpenStore(g_storePath2, STORE_ID, option, g_rdbDelegatePtr2);
1345 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
1346 subUserMgr2.SetAutoLaunchRequestCallback(g_callback2);
1347 RelationalStoreManager subUserMgr1(APP_ID, USER_ID_1, SUB_USER_1);
1348 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1349 CloseStore();
1350
1351 /**
1352 * @tc.steps: step2. Prepare data in deviceB
1353 * @tc.expected: step2. success.
1354 */
1355 VirtualRowData virtualRowData;
1356 DataValue d1;
1357 d1 = (int64_t)1;
1358 virtualRowData.objectData.PutDataValue("id", d1);
1359 DataValue d2;
1360 d2.SetText("hello");
1361 virtualRowData.objectData.PutDataValue("name", d2);
1362 virtualRowData.logInfo.timestamp = 1;
1363 g_deviceB->PutData(g_tableName, {virtualRowData});
1364
1365 std::vector<RelationalVirtualDevice *> remoteDev;
1366 remoteDev.push_back(g_deviceB);
1367 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
1368
1369 /**
1370 * @tc.steps: step3. Set label in deviceB and sync
1371 * @tc.expected: step3. success.
1372 */
1373 Query query = Query::Select(g_tableName);
1374 g_identifier = subUserMgr1.GetRelationalStoreIdentifier(USER_ID_1, SUB_USER_1, APP_ID, STORE_ID);
1375 std::vector<uint8_t> label(g_identifier.begin(), g_identifier.end());
1376 g_communicatorAggregator->SetCurrentUserId(USER_ID_1);
1377 g_communicatorAggregator->RunCommunicatorLackCallback(label);
1378 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
1379 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1380
1381 /**
1382 * @tc.steps: step4. Check result
1383 * @tc.expected: step4. deviceA have data from deviceB.
1384 */
1385 CheckDataInRealDevice();
1386
1387 RuntimeConfig::SetAutoLaunchRequestCallback(nullptr, DBType::DB_RELATION);
1388 RuntimeConfig::ReleaseAutoLaunch(USER_ID_1, SUB_USER_1, APP_ID, STORE_ID, DBType::DB_RELATION);
1389 }
1390
1391 /**
1392 * @tc.name: DropDistributedTableTest001
1393 * @tc.desc: Test sync after drop distributed table.
1394 * @tc.type: FUNC
1395 * @tc.require:
1396 * @tc.author: liaoyonghuang
1397 */
1398 HWTEST_F(DistributedDBRelationalMultiUserTest, DropDistributedTableTest001, TestSize.Level0)
1399 {
1400 /**
1401 * @tc.steps: step1. Prepare db1 and db2.
1402 * @tc.expected: step1. success.
1403 */
1404 OpenStore1();
1405 PrepareEnvironment(g_tableName, g_storePath1, g_rdbDelegatePtr1);
1406 CloseStore();
1407 OpenStore2();
1408 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
1409 /**
1410 * @tc.steps: step2. Do 1st sync to create distributed table
1411 * @tc.expected: step2. success.
1412 */
1413 std::vector<RelationalVirtualDevice *> remoteDev;
1414 remoteDev.push_back(g_deviceB);
1415 PrepareVirtualDeviceEnv(g_tableName, g_storePath1, remoteDev);
1416 Query query = Query::Select(g_tableName);
1417 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1418 /**
1419 * @tc.steps: step3. Drop distributed table
1420 * @tc.expected: step3. success.
1421 */
1422 std::string distributedTableName = DBCommon::GetDistributedTableName(DEVICE_B, g_tableName);
1423 sqlite3 *db = nullptr;
1424 EXPECT_EQ(GetDB(db, g_storePath2), SQLITE_OK);
1425 EXPECT_EQ(DropTable(db, distributedTableName), SQLITE_OK);
1426 sqlite3_close(db);
1427 /**
1428 * @tc.steps: step4. Do 2nd sync and check result.
1429 * @tc.expected: step4. success.
1430 */
1431 VirtualRowData virtualRowData;
1432 DataValue d1;
1433 d1 = (int64_t)1;
1434 virtualRowData.objectData.PutDataValue("id", d1);
1435 DataValue d2;
1436 d2.SetText("hello");
1437 virtualRowData.objectData.PutDataValue("name", d2);
1438 virtualRowData.logInfo.timestamp = 1;
1439 g_deviceB->PutData(g_tableName, {virtualRowData});
1440 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1441 CheckDataInRealDevice();
1442 g_currentStatus = 0;
1443 CloseStore();
1444 }
1445
1446 /**
1447 * @tc.name: DeleteTest001
1448 * @tc.desc: Test insert update and delete
1449 * @tc.type: FUNC
1450 * @tc.require:
1451 * @tc.author: zqq
1452 */
1453 HWTEST_F(DistributedDBRelationalMultiUserTest, DeleteTest001, TestSize.Level0)
1454 {
1455 /**
1456 * @tc.steps: step1. Prepare db2.
1457 * @tc.expected: step1. success.
1458 */
1459 OpenStore2();
1460 PrepareEnvironment(g_tableName, g_storePath2, g_rdbDelegatePtr2);
1461 /**
1462 * @tc.steps: step2. Do 1st sync to create distributed table
1463 * @tc.expected: step2. success.
1464 */
1465 std::vector<RelationalVirtualDevice *> remoteDev;
1466 remoteDev.push_back(g_deviceB);
1467 PrepareVirtualDeviceEnv(g_tableName, g_storePath2, remoteDev);
1468 /**
1469 * @tc.steps: step3. Do sync and check result.
1470 * @tc.expected: step3. success.
1471 */
1472 VirtualRowData virtualRowData;
1473 DataValue d1;
1474 d1 = static_cast<int64_t>(1);
1475 virtualRowData.objectData.PutDataValue("id", d1);
1476 DataValue d2;
1477 d2.SetText("hello");
1478 virtualRowData.objectData.PutDataValue("name", d2);
1479 virtualRowData.logInfo.timestamp = 1;
1480 virtualRowData.logInfo.hashKey = {'1'};
1481 g_deviceB->PutData(g_tableName, {virtualRowData});
1482 Query query = Query::Select(g_tableName);
1483 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1484 /**
1485 * @tc.steps: step4. Update data and sync again.
1486 * @tc.expected: step4. success.
1487 */
1488 virtualRowData.logInfo.timestamp++;
1489 g_deviceB->PutData(g_tableName, {virtualRowData});
1490 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1491 /**
1492 * @tc.steps: step5. Delete data and sync again.
1493 * @tc.expected: step5. success.
1494 */
1495 virtualRowData.logInfo.timestamp++;
1496 virtualRowData.logInfo.flag = static_cast<uint64_t>(LogInfoFlag::FLAG_DELETE);
1497 g_deviceB->PutData(g_tableName, {virtualRowData});
1498 EXPECT_EQ(g_deviceB->GenericVirtualDevice::Sync(SYNC_MODE_PUSH_ONLY, query, true), E_OK);
1499 CheckDataInRealDevice();
1500 g_currentStatus = 0;
1501 CloseStore();
1502 }