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