• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param) 246     const AutoLaunchRequestCallback g_callback = [](const std::string &identifier, AutoLaunchParam &param) {
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 &param) 262     const AutoLaunchRequestCallback g_callback2 = [](const std::string &identifier, AutoLaunchParam &param) {
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 }