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