1 /*
2  * Copyright (c) 2023 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 <sys/time.h>
17 #include <gtest/gtest.h>
18 
19 #include "concurrent_adapter.h"
20 #include "db_common.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "relational_store_client.h"
24 #include "relational_store_delegate_impl.h"
25 #include "relational_store_manager.h"
26 #include "cloud_db_sync_utils_test.h"
27 #include "store_observer.h"
28 
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33 
34 namespace {
35 constexpr const char *DB_SUFFIX = ".db";
36 constexpr const char *STORE_ID = "Relational_Store_ID";
37 std::string g_dbDir;
38 std::string g_testDir;
39 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
40 
41 constexpr int E_OK = 0;
42 constexpr int E_ERROR = 1;
43 const int WAIT_TIME = 1000; // 1000ms
44 constexpr static uint64_t TO_100_NS = 10; // 1us to 100ns
45 const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000;
46 std::mutex g_mutex;
47 std::condition_variable g_cv;
48 bool g_alreadyNotify = false;
49 
50 class DistributedDBCloudInterfacesRelationalExtTest : public testing::Test {
51 public:
52     static void SetUpTestCase(void);
53     static void TearDownTestCase(void);
54     void SetUp() override;
55     void TearDown() override;
56     void CheckTriggerObserverTest002(const std::string &tableName, std::atomic<int> &count);
57 
ClientObserverFunc(ClientChangedData & clientChangedData)58     void ClientObserverFunc(ClientChangedData &clientChangedData)
59     {
60         for (const auto &tableEntry : clientChangedData.tableData) {
61             LOGD("client observer fired, table: %s", tableEntry.first.c_str());
62             triggerTableData_.insert_or_assign(tableEntry.first, tableEntry.second);
63         }
64         triggeredCount_++;
65         {
66             std::unique_lock<std::mutex> lock(g_mutex);
67             g_alreadyNotify = true;
68         }
69         g_cv.notify_one();
70     }
71 
ClientObserverFunc2(ClientChangedData & clientChangedData)72     void ClientObserverFunc2(ClientChangedData &clientChangedData)
73     {
74         triggeredCount2_++;
75         {
76             std::unique_lock<std::mutex> lock(g_mutex);
77             g_alreadyNotify = true;
78         }
79         g_cv.notify_one();
80     }
81 
CheckTriggerTableData(size_t dataSize,const std::string & tableName,ChangeProperties & properties,int triggerCount)82     void CheckTriggerTableData(size_t dataSize, const std::string &tableName, ChangeProperties &properties,
83         int triggerCount)
84     {
85         ASSERT_EQ(triggerTableData_.size(), dataSize);
86         EXPECT_EQ(triggerTableData_.begin()->first, tableName);
87         EXPECT_EQ(triggerTableData_.begin()->second.isTrackedDataChange, properties.isTrackedDataChange);
88         EXPECT_EQ(triggeredCount_, triggerCount);
89     }
90 
WaitAndResetNotify()91     void WaitAndResetNotify()
92     {
93         std::unique_lock<std::mutex> lock(g_mutex);
94         WaitAndResetNotifyWithLock(lock);
95     }
96 
WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> & lock)97     void WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> &lock)
98     {
99         g_cv.wait(lock, []() {
100             return g_alreadyNotify;
101         });
102         g_alreadyNotify = false;
103     }
104 
105     std::set<std::string> triggerTableNames_;
106     std::map<std::string, ChangeProperties> triggerTableData_;
107     int triggeredCount_ = 0;
108     int triggeredCount2_ = 0;
109 };
110 
SetUpTestCase(void)111 void DistributedDBCloudInterfacesRelationalExtTest::SetUpTestCase(void)
112 {
113     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
114     LOGD("Test dir is %s", g_testDir.c_str());
115     g_dbDir = g_testDir + "/";
116     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
117 }
118 
TearDownTestCase(void)119 void DistributedDBCloudInterfacesRelationalExtTest::TearDownTestCase(void)
120 {
121 }
122 
SetUp()123 void DistributedDBCloudInterfacesRelationalExtTest::SetUp()
124 {
125 }
126 
TearDown()127 void DistributedDBCloudInterfacesRelationalExtTest::TearDown()
128 {
129     g_alreadyNotify = false;
130     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
131 }
132 
CheckTriggerObserverTest002(const std::string & tableName,std::atomic<int> & count)133 void DistributedDBCloudInterfacesRelationalExtTest::CheckTriggerObserverTest002(const std::string &tableName,
134     std::atomic<int> &count)
135 {
136     count++;
137     ASSERT_EQ(triggerTableData_.size(), 1u);
138     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
139     EXPECT_EQ(triggerTableData_.begin()->second.isTrackedDataChange, false);
140     EXPECT_EQ(triggeredCount_, count);
141 }
142 
GetCurrentSysTimeIn100Ns(uint64_t & outTime)143 static int GetCurrentSysTimeIn100Ns(uint64_t &outTime)
144 {
145     struct timeval rawTime;
146     int errCode = gettimeofday(&rawTime, nullptr);
147     if (errCode < 0) {
148         return -E_ERROR;
149     }
150     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
151         static_cast<uint64_t>(rawTime.tv_usec);
152     outTime *= TO_100_NS;
153     return E_OK;
154 }
155 
SetTracerSchemaTest001(const std::string & tableName)156 static void SetTracerSchemaTest001(const std::string &tableName)
157 {
158     TrackerSchema schema;
159     schema.tableName = tableName;
160     schema.extendColName = "id";
161     schema.trackerColNames = {"name"};
162     RelationalStoreDelegate *delegate = nullptr;
163     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
164     EXPECT_EQ(status, OK);
165     ASSERT_NE(delegate, nullptr);
166     EXPECT_EQ(delegate->SetTrackerTable(schema), OK);
167     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
168 }
169 
ExecSqlAndWaitForObserver(sqlite3 * db,const std::string & sql,std::unique_lock<std::mutex> & lock)170 static void ExecSqlAndWaitForObserver(sqlite3 *db, const std::string &sql, std::unique_lock<std::mutex> &lock)
171 {
172     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
173     g_cv.wait(lock, []() {
174         return g_alreadyNotify;
175     });
176     g_alreadyNotify = false;
177 }
178 
179 /**
180  * @tc.name: GetRawSysTimeTest001
181  * @tc.desc: Test get_raw_sys_time has been registered in sqlite
182  * @tc.type: FUNC
183  * @tc.require:
184  * @tc.author: zhangshijie
185  */
186 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, GetRawSysTimeTest001, TestSize.Level0)
187 {
188     const std::string sql = "select get_raw_sys_time();";
189     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
190     EXPECT_NE(db, nullptr);
191     uint64_t curTime = 0;
192     int errCode = GetCurrentSysTimeIn100Ns(curTime);
193     EXPECT_EQ(errCode, E_OK);
__anon41da56cb0402(sqlite3_stmt *stmt) 194     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime] (sqlite3_stmt *stmt) {
195         EXPECT_GT(static_cast<uint64_t>(sqlite3_column_int64(stmt, 0)), curTime);
196         return E_OK;
197     });
198     EXPECT_EQ(errCode, SQLITE_OK);
199     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
200 }
201 
PrepareData(const std::vector<std::string> & tableNames,bool primaryKeyIsRowId,DistributedDB::TableSyncType tableSyncType,bool userDefineRowid=true,bool createDistributeTable=true)202 void PrepareData(const std::vector<std::string> &tableNames, bool primaryKeyIsRowId,
203     DistributedDB::TableSyncType tableSyncType, bool userDefineRowid = true, bool createDistributeTable = true)
204 {
205     /**
206      * @tc.steps:step1. create db, create table.
207      * @tc.expected: step1. return ok.
208      */
209     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
210     EXPECT_NE(db, nullptr);
211     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
212     std::string sql;
213     for (const auto &tableName : tableNames) {
214         if (primaryKeyIsRowId) {
215             sql = "create table " + tableName + "(rowid INTEGER primary key, id int, name TEXT);";
216         } else {
217             if (userDefineRowid) {
218                 sql = "create table " + tableName + "(rowid int, id int, name TEXT, PRIMARY KEY(id));";
219             } else {
220                 sql = "create table " + tableName + "(id int, name TEXT, PRIMARY KEY(id));";
221             }
222         }
223         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
224     }
225     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
226 
227     /**
228      * @tc.steps:step2. create distributed table.
229      * @tc.expected: step2. return ok.
230      */
231     RelationalStoreDelegate *delegate = nullptr;
232     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
233     EXPECT_EQ(status, OK);
234     ASSERT_NE(delegate, nullptr);
235     if (createDistributeTable) {
236         for (const auto &tableName : tableNames) {
237             EXPECT_EQ(delegate->CreateDistributedTable(tableName, tableSyncType), OK);
238         }
239     }
240     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
241     delegate = nullptr;
242 }
243 
InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)244 void InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)
245 {
246     /**
247      * @tc.steps:step1. prepare data.
248      * @tc.expected: step1. return ok.
249      */
250     const std::string tableName = "sync_data";
251     PrepareData({tableName}, false, tableSyncType);
252 
253     /**
254      * @tc.steps:step2. insert data into sync_data.
255      * @tc.expected: step2. return ok.
256      */
257     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
258     EXPECT_NE(db, nullptr);
259     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
260     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
261 
262     /**
263      * @tc.steps:step3. select data from log table.
264      * @tc.expected: step3. return ok.
265      */
266     sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;";
267     uint64_t curTime = 0;
268     int errCode = GetCurrentSysTimeIn100Ns(curTime);
269     EXPECT_EQ(errCode, E_OK);
270 
271     int resultCount = 0;
272     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr,
273         [tableSyncType, curTime, &resultCount] (sqlite3_stmt *stmt) {
274         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
275         std::string device = "";
276         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
277         EXPECT_EQ(device, "");
278         std::string oriDevice = "";
279         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
280         EXPECT_EQ(oriDevice, "");
281 
282         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
283         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
284         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
285         EXPECT_TRUE(wtimestamp - timestamp < diff);
286         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
287         if (tableSyncType == DistributedDB::CLOUD_COOPERATION) {
288             EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index flag == 0x02|0x20
289         } else {
290             EXPECT_EQ(sqlite3_column_int(stmt, 5), 2); // 5 is column index flag == 2
291         }
292         resultCount++;
293         return E_OK;
294     });
295     EXPECT_EQ(errCode, SQLITE_OK);
296     EXPECT_EQ(resultCount, 1);
297     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
298 }
299 
300 /**
301  * @tc.name: InsertTriggerTest001
302  * @tc.desc: Test insert trigger in sqlite in CLOUD_COOPERATION mode
303  * @tc.type: FUNC
304  * @tc.require:
305  * @tc.author: zhangshijie
306  */
307 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, TestSize.Level0)
308 {
309     InsertTriggerTest(DistributedDB::CLOUD_COOPERATION);
310 }
311 
312 /**
313  * @tc.name: InsertTriggerTest002
314  * @tc.desc: Test insert trigger in sqlite in DEVICE_COOPERATION mode
315  * @tc.type: FUNC
316  * @tc.require:
317  * @tc.author: zhangshijie
318  */
319 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, TestSize.Level0)
320 {
321     InsertTriggerTest(DistributedDB::DEVICE_COOPERATION);
322 }
323 
324 /**
325  * @tc.name: InsertTriggerTest003
326  * @tc.desc: Test insert trigger in sqlite when use "insert or replace"
327  * @tc.type: FUNC
328  * @tc.require:
329  * @tc.author: zhangshijie
330  */
331 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest003, TestSize.Level1)
332 {
333     /**
334     * @tc.steps:step1. prepare data.
335     * @tc.expected: step1. return ok.
336     */
337     const std::string tableName = "sync_data";
338     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION);
339 
340     /**
341      * @tc.steps:step2. insert data into sync_data.
342      * @tc.expected: step2. return ok.
343      */
344     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
345     EXPECT_NE(db, nullptr);
346     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan1');";
347     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
348 
349     // update cloud_gid in log table
350     std::string gid = "test_gid";
351     sql = "update " + DBCommon::GetLogTableName(tableName) + " set cloud_gid = '" + gid + "'";
352     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
353     // use insert or replace to update data
354     sql = "insert or replace into " + tableName + " VALUES(3, 1, 'zhangsan1');";
355     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
356 
357     /**
358      * @tc.steps:step3. select data from log table.
359      * @tc.expected: step3. return ok.
360      */
361     sql = "select data_key, device, ori_device, flag, cloud_gid from " + DBCommon::GetLogTableName(tableName);
362     int resultCount = 0;
__anon41da56cb0602(sqlite3_stmt *stmt) 363     int errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [&resultCount, gid] (sqlite3_stmt *stmt) {
364         EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
365         std::string device = "";
366         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
367         EXPECT_EQ(device, "");
368         std::string oriDevice = "";
369         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
370         EXPECT_EQ(oriDevice, "");
371 
372         EXPECT_EQ(sqlite3_column_int(stmt, 3), 0x02|0x20); // 3 is column index flag == 0x02|0x20
373         std::string gidStr;
374         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 4, gidStr), E_OK); // 4 is column index
375         EXPECT_EQ(gid, gidStr);
376         resultCount++;
377         return E_OK;
378     });
379     EXPECT_EQ(errCode, SQLITE_OK);
380     EXPECT_EQ(resultCount, 1);
381     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
382 }
383 
UpdateTriggerTest(bool primaryKeyIsRowId)384 void UpdateTriggerTest(bool primaryKeyIsRowId)
385 {
386     /**
387      * @tc.steps:step1. prepare data.
388      * @tc.expected: step1. return ok.
389      */
390     const std::string tableName = "sync_data";
391     PrepareData({tableName}, primaryKeyIsRowId, DistributedDB::CLOUD_COOPERATION);
392 
393     /**
394      * @tc.steps:step2. insert data into sync_data_tmp.
395      * @tc.expected: step2. return ok.
396      */
397     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
398     EXPECT_NE(db, nullptr);
399     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
400     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
401 
402     /**
403      * @tc.steps:step3. update data.
404      * @tc.expected: step3. return ok.
405      */
406     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
407     sql = "update " + tableName + " set name = 'lisi';";
408     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
409 
410     /**
411      * @tc.steps:step4. select data from log table.
412      * @tc.expected: step4. return ok.
413      */
414     sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;";
415     uint64_t curTime = 0;
416     int errCode = GetCurrentSysTimeIn100Ns(curTime);
417     EXPECT_EQ(errCode, E_OK);
418 
419     int resultCount = 0;
420     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount, primaryKeyIsRowId] (
421         sqlite3_stmt *stmt) {
422         if (primaryKeyIsRowId) {
423             EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
424         } else {
425             EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
426         }
427 
428         EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index, flag == 0x02|0x20
429 
430         std::string device = "";
431         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
432         EXPECT_EQ(device, "");
433         std::string oriDevice = "";
434         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
435         EXPECT_EQ(oriDevice, "");
436 
437         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
438         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
439         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
440         EXPECT_TRUE(timestamp - wtimestamp > diff);
441         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
442 
443         resultCount++;
444         return E_OK;
445     });
446     EXPECT_EQ(errCode, SQLITE_OK);
447     EXPECT_EQ(resultCount, 1);
448     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
449 }
450 
451 /**
452  * @tc.name: UpdateTriggerTest001
453  * @tc.desc: Test update trigger in sqlite for primary key is not row id
454  * @tc.type: FUNC
455  * @tc.require:
456  * @tc.author: zhangshijie
457  */
458 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest001, TestSize.Level0)
459 {
460     UpdateTriggerTest(false);
461 }
462 
463 /**
464  * @tc.name: UpdateTriggerTest002
465  * @tc.desc: Test update trigger in sqlite for primary key is row id
466  * @tc.type: FUNC
467  * @tc.require:
468  * @tc.author: zhangshijie
469  */
470 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest002, TestSize.Level0)
471 {
472     UpdateTriggerTest(true);
473 }
474 
475 /**
476  * @tc.name: DeleteTriggerTest001
477  * @tc.desc: Test delete trigger in sqlite
478  * @tc.type: FUNC
479  * @tc.require:
480  * @tc.author: zhangshijie
481  */
482 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DeleteTriggerTest001, TestSize.Level0)
483 {
484     /**
485      * @tc.steps:step1. prepare data.
486      * @tc.expected: step1. return ok.
487      */
488     const std::string tableName = "sync_data";
489     PrepareData({tableName}, true, DistributedDB::CLOUD_COOPERATION);
490 
491     /**
492      * @tc.steps:step2. insert data into sync_data.
493      * @tc.expected: step2. return ok.
494      */
495     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
496     EXPECT_NE(db, nullptr);
497     std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
498     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
499 
500     /**
501      * @tc.steps:step3. delete data.
502      * @tc.expected: step3. return ok.
503      */
504     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
505     sql = "delete from " + tableName + " where name = 'zhangsan';";
506     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
507 
508     /**
509      * @tc.steps:step4. select data from log table.
510      * @tc.expected: step4. return ok.
511      */
512     sql = "select * from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log;";
513     uint64_t curTime = 0;
514     int errCode = GetCurrentSysTimeIn100Ns(curTime);
515     EXPECT_EQ(errCode, E_OK);
516 
517     int resultCount = 0;
__anon41da56cb0802(sqlite3_stmt *stmt) 518     errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount] (sqlite3_stmt *stmt) {
519         EXPECT_EQ(sqlite3_column_int64(stmt, 0), -1);
520         EXPECT_EQ(sqlite3_column_int(stmt, 5), 3); // 5 is column index, flag == 3
521 
522         std::string device = "de";
523         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
524         EXPECT_EQ(device, "");
525         std::string oriDevice = "de";
526         EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
527         EXPECT_EQ(oriDevice, "");
528 
529         int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
530         int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
531         int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
532         EXPECT_TRUE(timestamp - wtimestamp > diff);
533         EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
534 
535         resultCount++;
536         return E_OK;
537     });
538     EXPECT_EQ(errCode, SQLITE_OK);
539     EXPECT_EQ(resultCount, 1);
540     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
541 }
542 
543 /**
544  * @tc.name: TriggerObserverTest001
545  * @tc.desc: Test invalid args for RegisterClientObserver and UnRegisterClientObserver
546  * @tc.type: FUNC
547  * @tc.require:
548  * @tc.author: zhangshijie
549  */
550 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest001, TestSize.Level0)
551 {
552     /**
553      * @tc.steps:step1. call RegisterClientObserver and UnRegisterClientObserver with db = nullptr.
554      * @tc.expected: step1. return INVALID_ARGS.
555      */
556     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
557         this, std::placeholders::_1);
558     EXPECT_EQ(RegisterClientObserver(nullptr, clientObserver), INVALID_ARGS);
559     EXPECT_EQ(UnRegisterClientObserver(nullptr), INVALID_ARGS);
560 
561     /**
562      * @tc.steps:step2. call RegisterClientObserver with nullptr clientObserver.
563      * @tc.expected: step2. return INVALID_ARGS.
564      */
565     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
566     EXPECT_NE(db, nullptr);
567     EXPECT_EQ(RegisterClientObserver(db, nullptr), INVALID_ARGS);
568 
569     /**
570      * @tc.steps:step3. call RegisterClientObserver and UnRegisterClientObserver with closed db handle.
571      * @tc.expected: step3. return INVALID_ARGS.
572      */
573     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
574     EXPECT_EQ(RegisterClientObserver(db, clientObserver), INVALID_ARGS);
575     EXPECT_EQ(UnRegisterClientObserver(db), INVALID_ARGS);
576 }
577 
578 /**
579  * @tc.name: TriggerObserverTest002
580  * @tc.desc: Test trigger client observer in sqlite
581  * @tc.type: FUNC
582  * @tc.require:
583  * @tc.author: zhangshijie
584  */
585 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, TestSize.Level0)
586 {
587     /**
588      * @tc.steps:step1. prepare data.
589      * @tc.expected: step1. return ok.
590      */
591     const std::string tableName = "sync_data";
592     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
593 
594     /**
595     * @tc.steps:step2. register client observer.
596     * @tc.expected: step2. return ok.
597     */
598     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
599     EXPECT_NE(db, nullptr);
600     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
601         this, std::placeholders::_1);
602     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
603 
604     /**
605      * @tc.steps:step3. insert data into sync_data, check observer.
606      * @tc.expected: step3. check observer ok.
607      */
608     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
609     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
610     WaitAndResetNotify();
611     std::atomic<int> count = 0; // 0 is observer triggered counts
612     CheckTriggerObserverTest002(tableName, count);
613 
614     /**
615      * @tc.steps:step4. update data, check observer.
616      * @tc.expected: step4. check observer ok.
617      */
618     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
619     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
620     WaitAndResetNotify();
621     CheckTriggerObserverTest002(tableName, count);
622 
623     /**
624      * @tc.steps:step4. delete data, check observer.
625      * @tc.expected: step4. check observer ok.
626      */
627     sql = "delete from " + tableName + " where id = 3;";
628     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
629     WaitAndResetNotify();
630     CheckTriggerObserverTest002(tableName, count);
631 
632     /**
633      * @tc.steps:step5. register another observer, update data, check observer.
634      * @tc.expected: step5. check observer ok.
635      */
636     triggeredCount_ = 0;
637     ClientObserver clientObserver2 = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2,
638         this, std::placeholders::_1);
639     EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK);
640     sql = "update " + tableName + " set name = 'lisi2' where id = 2;";
641     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
642     WaitAndResetNotify();
643     EXPECT_EQ(triggeredCount_, 0);
644     EXPECT_EQ(triggeredCount2_, 1);
645 
646     /**
647      * @tc.steps:step6. UnRegisterClientObserver, update data, check observer.
648      * @tc.expected: step6. check observer ok.
649      */
650     triggeredCount2_ = 0;
651     EXPECT_EQ(UnRegisterClientObserver(db), OK);
652     sql = "update " + tableName + " set name = 'lisi3' where id = 2;";
653     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
654     EXPECT_EQ(triggeredCount2_, 0); // observer2 will not be triggered
655     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
656 }
657 
658 /**
659  * @tc.name: TriggerObserverTest003
660  * @tc.desc: Test RegisterClientObserver and UnRegisterClientObserver concurrently
661  * @tc.type: FUNC
662  * @tc.require:
663  * @tc.author: zhangshijie
664  */
665 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest003, TestSize.Level1)
666 {
667     for (int i = 0; i < 1000; i++) { // 1000 is loop times
__anon41da56cb0902() 668         std::thread t1 ([this]() {
669             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
670             EXPECT_NE(db, nullptr);
671             ClientObserver clientObserver = std::bind(
672                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, this, std::placeholders::_1);
673             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
674             EXPECT_EQ(UnRegisterClientObserver(db), OK);
675             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
676         });
677 
__anon41da56cb0a02() 678         std::thread t2 ([this]() {
679             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
680             EXPECT_NE(db, nullptr);
681             ClientObserver clientObserver = std::bind(
682                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2, this, std::placeholders::_1);
683             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
684             EXPECT_EQ(UnRegisterClientObserver(db), OK);
685             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
686         });
687 
688         t1.join();
689         t2.join();
690     }
691 }
692 
693 /**
694  * @tc.name: TriggerObserverTest004
695  * @tc.desc: Test batch insert/update/delete data then trigger client observer
696  * @tc.type: FUNC
697  * @tc.require:
698  * @tc.author: zhangshijie
699  */
700 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, TestSize.Level1)
701 {
702     /**
703      * @tc.steps:step1. prepare data.
704      * @tc.expected: step1. return ok.
705      */
706     const std::string tableName = "sync_data";
707     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
708 
709     /**
710     * @tc.steps:step2. register client observer.
711     * @tc.expected: step2. return ok.
712     */
713     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
714     EXPECT_NE(db, nullptr);
715     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
716         this, std::placeholders::_1);
717     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
718 
719     /**
720      * @tc.steps:step3. insert data into sync_data, check observer.
721      * @tc.expected: step3. check observer ok.
722      */
723     std::string sql;
724     int dataCounts = 1000; // 1000 is count of insert options.
725     for (int i = 1; i <= dataCounts; i++) {
726         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
727         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
728     }
729     std::unique_lock<std::mutex> lock(g_mutex);
__anon41da56cb0b02() 730     bool isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this, dataCounts]() { // 1 is wait time
731         return triggeredCount_ == dataCounts;
732     });
733     EXPECT_EQ(isEqual, true);
734     WaitAndResetNotifyWithLock(lock);
735     ASSERT_EQ(triggerTableData_.size(), 1u);
736     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
737     EXPECT_EQ(triggeredCount_, dataCounts);
738 
739     /**
740      * @tc.steps:step4. insert or replace, check observer.
741      * @tc.expected: step5. check observer ok.
742      */
743     triggeredCount_ = 0;
744     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
745     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
__anon41da56cb0c02() 746     isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this]() { // 1 is wait time
747         return triggeredCount_ == 1;
748     });
749     EXPECT_EQ(isEqual, true);
750     WaitAndResetNotifyWithLock(lock);
751     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
752     EXPECT_EQ(UnRegisterClientObserver(db), OK);
753     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
754 }
755 
756 /**
757  * @tc.name: TriggerObserverTest005
758  * @tc.desc: Test commit and rollback for one table then trigger client observer
759  * @tc.type: FUNC
760  * @tc.require:
761  * @tc.author: chenchaohao
762  */
763 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, TestSize.Level1)
764 {
765     /**
766      * @tc.steps:step1. prepare data.
767      * @tc.expected: step1. return ok.
768      */
769     const std::string tableName = "sync_data";
770     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
771 
772     /**
773     * @tc.steps:step2. register client observer.
774     * @tc.expected: step2. return ok.
775     */
776     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
777     EXPECT_NE(db, nullptr);
778     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
779         this, std::placeholders::_1);
780     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
781 
782     /**
783      * @tc.steps:step3. begin transaction and commit.
784      * @tc.expected: step3. check observer ok.
785      */
786     std::string sql = "begin;";
787     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
788     int dataCounts = 1000; // 1000 is count of insert options.
789     for (int i = 1; i <= dataCounts; i++) {
790         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
791         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
792     }
793     sql = "commit;";
794     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
795     WaitAndResetNotify();
796     ASSERT_EQ(triggerTableData_.size(), 1u);
797     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
798     EXPECT_EQ(triggeredCount_, 1);
799 
800     /**
801      * @tc.steps:step4. begin transaction and rollback.
802      * @tc.expected: step3. check observer ok.
803      */
804     triggerTableData_.clear();
805     triggeredCount_ = 0;
806     sql = "begin;";
807     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
808     for (int i = dataCounts + 1; i <= 2 * dataCounts; i++) { // 2 is double dataCounts
809         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
810         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
811     }
812     sql = "rollback;";
813     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
814     EXPECT_TRUE(triggerTableData_.empty());
815     EXPECT_EQ(triggeredCount_, 0);
816 
817     /**
818      * @tc.steps:step5. insert or replace, check observer.
819      * @tc.expected: step5. check observer ok.
820      */
821     triggeredCount_ = 0;
822     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
823     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
824     WaitAndResetNotify();
825     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
826     EXPECT_EQ(UnRegisterClientObserver(db), OK);
827     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
828 }
829 
830 /**
831  * @tc.name: TriggerObserverTest006
832  * @tc.desc: Test commit and rollback for multi-table then trigger client observer
833  * @tc.type: FUNC
834  * @tc.require:
835  * @tc.author: chenchaohao
836  */
837 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, TestSize.Level1)
838 {
839     /**
840      * @tc.steps:step1. prepare data.
841      * @tc.expected: step1. return ok.
842      */
843     const std::string tableName1 = "sync_data1";
844     const std::string tableName2 = "sync_data2";
845     PrepareData({tableName1, tableName2}, false, DistributedDB::CLOUD_COOPERATION, false);
846 
847     /**
848     * @tc.steps:step2. register client observer.
849     * @tc.expected: step2. return ok.
850     */
851     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
852     EXPECT_NE(db, nullptr);
853     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
854         this, std::placeholders::_1);
855     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
856 
857     /**
858      * @tc.steps:step3. begin transaction and commit.
859      * @tc.expected: step3. check observer ok.
860      */
861     std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
862     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
863     WaitAndResetNotify();
864     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
865     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
866     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
867 
868     /**
869      * @tc.steps:step4. UnRegisterClientObserver and insert table2.
870      * @tc.expected: step3. check observer ok.
871      */
872     triggerTableData_.clear();
873     triggeredCount_ = 0;
874     EXPECT_EQ(UnRegisterClientObserver(db), OK);
875     sql = "insert into " + tableName2 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
876     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
877     EXPECT_TRUE(triggerTableData_.empty());
878     EXPECT_EQ(triggeredCount_, 0);
879 
880     /**
881      * @tc.steps:step5. RegisterClientObserver again and insert table1, check observer.
882      * @tc.expected: step5. check observer ok.
883      */
884     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
885     sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');";
886     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
887     WaitAndResetNotify();
888     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
889     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
890     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
891     EXPECT_EQ(UnRegisterClientObserver(db), OK);
892     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
893 }
894 
895 /**
896  * @tc.name: TriggerObserverTest007
897  * @tc.desc: Test trigger client observer in tracker table
898  * @tc.type: FUNC
899  * @tc.require:
900  * @tc.author: zhangshijie
901  */
902 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest007, TestSize.Level0)
903 {
904     /**
905      * @tc.steps:step1. prepare data and set trackerTable
906      * @tc.expected: step1. return ok.
907      */
908     const std::string tableName = "sync_data";
909     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false, false);
910     SetTracerSchemaTest001(tableName);
911 
912     /**
913     * @tc.steps:step2. register client observer.
914     * @tc.expected: step2. return ok.
915     */
916     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
917     EXPECT_NE(db, nullptr);
918     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
919         this, std::placeholders::_1);
920     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
921 
922     /**
923      * @tc.steps:step3. insert data into sync_data, check observer.
924      * @tc.expected: step3. check observer ok.
925      */
926     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
927     std::unique_lock<std::mutex> lock(g_mutex);
928     ExecSqlAndWaitForObserver(db, sql, lock);
929     ChangeProperties properties;
930     properties.isTrackedDataChange = true;
931     int triggerCount = 1;
932     CheckTriggerTableData(1u, tableName, properties, triggerCount);
933 
934     /**
935      * @tc.steps:step4. update data, check observer.
936      * @tc.expected: step4. check observer ok.
937      */
938     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
939     ExecSqlAndWaitForObserver(db, sql, lock);
940     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
941 
942     /**
943      * @tc.steps:step5. update to the same data again, check observer.
944      * @tc.expected: step5. check observer ok.
945      */
946     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
947     ExecSqlAndWaitForObserver(db, sql, lock);
948     properties.isTrackedDataChange = false;
949     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
950 
951     /**
952      * @tc.steps:step6. update to the same data again, set name is NULL, check observer.
953      * @tc.expected: step6. check observer ok.
954      */
955     sql = "update " + tableName + " set name = NULL where id = 2;";
956     ExecSqlAndWaitForObserver(db, sql, lock);
957     properties.isTrackedDataChange = true;
958     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
959 
960     /**
961      * @tc.steps:step7. update to the same data again, set name is empty, check observer.
962      * @tc.expected: step7. check observer ok.
963      */
964     sql = "update " + tableName + " set name = '' where id = 2;";
965     ExecSqlAndWaitForObserver(db, sql, lock);
966     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
967 
968     /**
969      * @tc.steps:step8. delete data, check observer.
970      * @tc.expected: step8. check observer ok.
971      */
972     sql = "delete from " + tableName + " where id = 2;";
973     ExecSqlAndWaitForObserver(db, sql, lock);
974     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
975     EXPECT_EQ(UnRegisterClientObserver(db), OK);
976     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
977 }
978 
InitLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t num)979 void InitLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t num)
980 {
981     for (size_t i = 0; i < num; ++i) {
982         std::string sql = "insert or replace into " + tableName + " VALUES('" + std::to_string(i) + "', 'zhangsan');";
983         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
984     }
985     std::string sql = "update " + DBConstant::RELATIONAL_PREFIX + tableName + "_log" + " SET flag = flag | 0x08";
986     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
987 }
988 
CheckLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t expectNum)989 void CheckLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t expectNum)
990 {
991     std::string sql = "select count(*) from " + DBConstant::RELATIONAL_PREFIX + tableName + "_log"
992         " where flag&0x08=0x08 and flag&0x01=0";
993     sqlite3_stmt *stmt = nullptr;
994     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
995     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
996         uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
997         EXPECT_EQ(count, expectNum);
998     }
999     int errCode;
1000     SQLiteUtils::ResetStatement(stmt, true, errCode);
1001     stmt = nullptr;
1002     sql = "select count(*) from " + tableName;
1003     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1004         uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1005         EXPECT_EQ(count, expectNum);
1006     }
1007     SQLiteUtils::ResetStatement(stmt, true, errCode);
1008 }
1009 
1010 /**
1011  * @tc.name: DropDeleteData001
1012  * @tc.desc: Test trigger client observer in tracker table
1013  * @tc.type: FUNC
1014  * @tc.require:
1015  * @tc.author:
1016  */
1017 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DropDeleteData001, TestSize.Level0)
1018 {
1019     /**
1020      * @tc.steps:step1. prepare data.
1021      * @tc.expected: step1. return ok.
1022      */
1023     const std::string tableName = "sync_data";
1024     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1025     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1026     EXPECT_NE(db, nullptr);
1027     uint64_t num = 10;
1028     InitLogicDeleteData(db, tableName, num);
1029 
1030     /**
1031      * @tc.steps:step2. db handle is nullptr
1032      * @tc.expected: step2. return INVALID_ARGS.
1033      */
1034     EXPECT_EQ(DropLogicDeletedData(nullptr, tableName, 0u), INVALID_ARGS);
1035 
1036     /**
1037      * @tc.steps:step3. tableName is empty
1038      * @tc.expected: step3. return INVALID_ARGS.
1039      */
1040     EXPECT_EQ(DropLogicDeletedData(db, "", 0u), INVALID_ARGS);
1041 
1042     /**
1043      * @tc.steps:step4. tableName is no exist
1044      * @tc.expected: step4. return INVALID_ARGS.
1045      */
1046     EXPECT_EQ(DropLogicDeletedData(db, tableName + "_", 0u), DB_ERROR);
1047 
1048     /**
1049      * @tc.steps:step5. cursor is 0
1050      * @tc.expected: step5. return OK.
1051      */
1052     EXPECT_EQ(DropLogicDeletedData(db, tableName, 0u), OK);
1053     CheckLogicDeleteData(db, tableName, 0u);
1054 
1055     /**
1056      * @tc.steps:step6. init data again, and cursor is 15
1057      * @tc.expected: step6. return OK.
1058      */
1059     uint64_t cursor = 15;
1060     InitLogicDeleteData(db, tableName, num);
1061     EXPECT_EQ(DropLogicDeletedData(db, tableName, cursor), OK);
1062     CheckLogicDeleteData(db, tableName, cursor - num);
1063     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1064 }
1065 
1066 /**
1067  * @tc.name: FfrtTest001
1068  * @tc.desc: Test ffrt concurrency
1069  * @tc.type: FUNC
1070  * @tc.require:
1071  * @tc.author:
1072  */
1073 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest001, TestSize.Level0)
1074 {
1075     std::map<int, int> ans;
1076     std::mutex mutex;
1077     size_t num = 1000;
1078 
1079     /**
1080      * @tc.steps:step1. submit insert map task
1081      * @tc.expected: step1. return ok.
1082      */
__anon41da56cb0d02() 1083     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1084         for (size_t j = 0; j < num; j++) {
1085             ADAPTER_AUTO_LOCK(lock, mutex);
1086             for (size_t i = 0; i < num; i++) {
1087                 ans.insert_or_assign(i, i);
1088             }
1089         }
1090     }, nullptr, &ans);
1091 
1092     /**
1093      * @tc.steps:step2. submit erase map task
1094      * @tc.expected: step2. return ok.
1095      */
__anon41da56cb0e02() 1096     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1097         for (size_t i = 0; i < num; i++) {
1098             ADAPTER_AUTO_LOCK(lock, mutex);
1099             for (auto it = ans.begin(); it != ans.end();) {
1100                 it = ans.erase(it);
1101             }
1102         }
1103     }, nullptr, &ans);
1104 
1105     /**
1106      * @tc.steps:step3. submit get from map task
1107      * @tc.expected: step3. return ok.
1108      */
__anon41da56cb0f02() 1109     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1110         for (size_t i = 0; i < num; i++) {
1111             ADAPTER_AUTO_LOCK(lock, mutex);
1112             for (auto it = ans.begin(); it != ans.end(); it++) {
1113                 int j = it->first;
1114                 EXPECT_GE(j, 0);
1115             }
1116         }
1117     }, &ans, nullptr);
1118     ADAPTER_WAIT(h1);
1119     ADAPTER_WAIT(h2);
1120     ADAPTER_WAIT(h3);
1121     ASSERT_TRUE(ans.empty());
1122 }
1123 
1124 /**
1125  * @tc.name: FfrtTest002
1126  * @tc.desc: Test ffrt concurrency
1127  * @tc.type: FUNC
1128  * @tc.require:
1129  * @tc.author:
1130  */
1131 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Level0)
1132 {
1133     std::map<int, int> ans;
1134     std::mutex mutex;
1135     size_t num = 1000;
1136 
1137     /**
1138      * @tc.steps:step1. subtask submit insert map task
1139      * @tc.expected: step1. return ok.
1140      */
__anon41da56cb1002() 1141     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1142         TaskHandle hh1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1143             for (size_t j = 0; j < num; j++) {
1144                 ADAPTER_AUTO_LOCK(lock, mutex);
1145                 for (size_t i = 0; i < num; i++) {
1146                     ans.insert_or_assign(i, i);
1147                 }
1148             }
1149         }, nullptr, &ans);
1150         ADAPTER_WAIT(hh1);
1151     });
1152 
1153     /**
1154      * @tc.steps:step2. subtask submit erase map task
1155      * @tc.expected: step2. return ok.
1156      */
__anon41da56cb1202() 1157     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1158         TaskHandle hh2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1159             for (size_t i = 0; i < num; i++) {
1160                 ADAPTER_AUTO_LOCK(lock, mutex);
1161                 for (auto it = ans.begin(); it != ans.end();) {
1162                     it = ans.erase(it);
1163                 }
1164             }
1165         }, nullptr, &ans);
1166         ADAPTER_WAIT(hh2);
1167     });
1168 
1169     /**
1170      * @tc.steps:step3. subtask submit get from map task
1171      * @tc.expected: step3. return ok.
1172      */
__anon41da56cb1402() 1173     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1174         TaskHandle hh3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1175             for (size_t i = 0; i < num; i++) {
1176                 ADAPTER_AUTO_LOCK(lock, mutex);
1177                 for (auto it = ans.begin(); it != ans.end(); it++) {
1178                     int j = it->first;
1179                     EXPECT_GE(j, 0);
1180                 }
1181             }
1182         }, &ans, nullptr);
1183         ADAPTER_WAIT(hh3);
1184     });
1185     ADAPTER_WAIT(h1);
1186     ADAPTER_WAIT(h2);
1187     ADAPTER_WAIT(h3);
1188 }
1189 
1190 /**
1191  * @tc.name: FfrtTest003
1192  * @tc.desc: Test ffrt concurrency
1193  * @tc.type: FUNC
1194  * @tc.require:
1195  * @tc.author:
1196  */
1197 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest003, TestSize.Level0)
1198 {
1199     size_t count = 0;
1200     size_t num = 3000;
1201     std::vector<TaskHandle> waitVec;
1202 
1203     /**
1204      * @tc.steps:step1. submit increase task
1205      * @tc.expected: step1. return ok.
1206      */
1207     for (size_t j = 0; j < num; j++) {
__anon41da56cb1602() 1208         TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &count, num]() {
1209             for (size_t i = 0; i < num; i++) {
1210                 count++;
1211             }
1212         }, nullptr, nullptr);
1213         waitVec.push_back(std::move(h1));
1214     }
1215     for (const auto &item : waitVec) {
1216         ADAPTER_WAIT(item);
1217     }
1218 
1219     /**
1220      * @tc.steps:step2. check count
1221      * @tc.expected: step2. return ok.
1222      */
1223 #ifdef USE_FFRT
1224     EXPECT_NE(count, num * num);
1225 #else
1226     EXPECT_EQ(count, num * num);
1227 #endif
1228 }
1229 
1230 /**
1231  * @tc.name: AbnormalDelegateTest001
1232  * @tc.desc: Test delegate interface after delegate is closed
1233  * @tc.type: FUNC
1234  * @tc.require:
1235  * @tc.author: chenchaohao
1236  */
1237 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateTest001, TestSize.Level0)
1238 {
1239     /**
1240      * @tc.steps:step1. create db and open store
1241      * @tc.expected: step1. return ok.
1242      */
1243     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1244     ASSERT_NE(db, nullptr);
1245     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1246     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1247     RelationalStoreDelegate *delegate = nullptr;
1248     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1249     EXPECT_EQ(status, OK);
1250     ASSERT_NE(delegate, nullptr);
1251 
1252     /**
1253      * @tc.steps:step2. close delegate
1254      * @tc.expected: step2. return ok.
1255      */
1256     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1257     status = delegateImpl->Close();
1258     EXPECT_EQ(status, OK);
1259 
1260     /**
1261      * @tc.steps:step3. test interface after delegate is closed
1262      * @tc.expected: step3. return ok.
1263      */
1264     const std::string tableName = "sync_data";
1265     EXPECT_EQ(delegateImpl->RemoveDeviceData("", tableName), DB_ERROR);
1266     EXPECT_EQ(delegate->RemoveDeviceData("", FLAG_AND_DATA), DB_ERROR);
1267     EXPECT_EQ(delegate->GetCloudSyncTaskCount(), -1); // -1 is error count
1268     EXPECT_EQ(delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DB_ERROR);
1269     EXPECT_EQ(delegate->UnRegisterObserver(), DB_ERROR);
1270     DataBaseSchema dataBaseSchema;
1271     EXPECT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DB_ERROR);
1272     EXPECT_EQ(delegate->SetReference({}), DB_ERROR);
1273     TrackerSchema trackerSchema;
1274     EXPECT_EQ(delegate->SetTrackerTable(trackerSchema), DB_ERROR);
1275     EXPECT_EQ(delegate->CleanTrackerData(tableName, 0), DB_ERROR);
1276     bool logicDelete = true;
1277     auto data = static_cast<PragmaData>(&logicDelete);
1278     EXPECT_EQ(delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), DB_ERROR);
1279     std::vector<VBucket> records;
1280     RecordStatus recordStatus = RecordStatus::WAIT_COMPENSATED_SYNC;
1281     EXPECT_EQ(delegate->UpsertData(tableName, records, recordStatus), DB_ERROR);
1282 
1283     /**
1284      * @tc.steps:step4. close store
1285      * @tc.expected: step4. return ok.
1286      */
1287     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1288     delegate = nullptr;
1289 }
1290 
InitDataStatus(const std::string & tableName,int count,sqlite3 * db)1291 void InitDataStatus(const std::string &tableName, int count, sqlite3 *db)
1292 {
1293     int type = 4; // the num of different status
1294     for (int i = 1; i <= type * count; i++) {
1295         std::string sql = "INSERT INTO " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" +
1296             std::to_string(i) + "');";
1297         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1298     }
1299     std::string countStr = std::to_string(count);
1300     std::string sql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET status=(CASE WHEN data_key<=" +
1301         countStr + " THEN 0 WHEN data_key>" + countStr + " AND data_key<=2*" + countStr + " THEN 1 WHEN data_key>2*" +
1302         countStr + " AND data_key<=3*" + countStr + " THEN 2 ELSE 3 END)";
1303     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1304 }
1305 
CheckDataStatus(const std::string & tableName,const std::string & condition,sqlite3 * db,int64_t expect)1306 void CheckDataStatus(const std::string &tableName, const std::string &condition, sqlite3 *db, int64_t expect)
1307 {
1308     std::string sql = "SELECT count(1) FROM " + DBCommon::GetLogTableName(tableName) + " WHERE " + condition;
1309     sqlite3_stmt *stmt = nullptr;
1310     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1311     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1312         int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
1313         EXPECT_EQ(count, expect);
1314     }
1315     int errCode;
1316     SQLiteUtils::ResetStatement(stmt, true, errCode);
1317 }
1318 
1319 /**
1320  * @tc.name: LockDataTest001
1321  * @tc.desc: Test status after lock
1322  * @tc.type: FUNC
1323  * @tc.require:
1324  * @tc.author: bty
1325  */
1326 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest001, TestSize.Level0)
1327 {
1328     /**
1329      * @tc.steps:step1. init data and lock, hashKey has no matching data
1330      * @tc.expected: step1. return NOT_FOUND.
1331      */
1332     const std::string tableName = "sync_data";
1333     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1334     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1335     EXPECT_NE(db, nullptr);
1336     int count = 10;
1337     InitDataStatus(tableName, count, db);
1338     std::vector<std::vector<uint8_t>> hashKey;
1339     hashKey.push_back({'1'});
1340     EXPECT_EQ(Lock(tableName, hashKey, db), NOT_FOUND);
1341 
1342     /**
1343      * @tc.steps:step2. init data and lock, hashKey has matching data
1344      * @tc.expected: step2. return OK.
1345      */
1346     hashKey.clear();
1347     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1348     EXPECT_EQ(Lock(tableName, hashKey, db), OK);
1349 
1350     /**
1351      * @tc.steps:step3. check status
1352      * @tc.expected: step3. return OK.
1353      */
1354     CheckDataStatus(tableName, " status = 2 and data_key <= 10 ", db, count);
1355     CheckDataStatus(tableName, " status = 3 and data_key <= 20 ", db, count);
1356     CheckDataStatus(tableName, " status = 2 ", db, count + count);
1357     CheckDataStatus(tableName, " status = 3 ", db, count + count);
1358     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1359 }
1360 
1361 /**
1362  * @tc.name: LockDataTest002
1363  * @tc.desc: Test status after unLock
1364  * @tc.type: FUNC
1365  * @tc.require:
1366  * @tc.author: bty
1367  */
1368 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest002, TestSize.Level0)
1369 {
1370     /**
1371      * @tc.steps:step1. init data and unLock, there is data to be compensated for
1372      * @tc.expected: step1. return WAIT_COMPENSATED_SYNC.
1373      */
1374     const std::string tableName = "sync_data";
1375     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1376     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1377     EXPECT_NE(db, nullptr);
1378     int count = 10;
1379     InitDataStatus(tableName, count, db);
1380     std::vector<std::vector<uint8_t>> hashKey;
1381     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1382     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1383 
1384     /**
1385      * @tc.steps:step2. check status
1386      * @tc.expected: step2. return OK.
1387      */
1388     CheckDataStatus(tableName, " status = 0 and data_key <= 10 ", db, count);
1389     CheckDataStatus(tableName, " status = 1 and data_key <= 20 ", db, count);
1390     CheckDataStatus(tableName, " status = 0 ", db, count + count);
1391     CheckDataStatus(tableName, " status = 1 ", db, count + count);
1392 
1393     /**
1394      * @tc.steps:step3. unLock again, there is data to be compensated for
1395      * @tc.expected: step3. return WAIT_COMPENSATED_SYNC.
1396      */
1397     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1398 
1399     /**
1400      * @tc.steps:step4. unLock again, there is no data to be compensated for
1401      * @tc.expected: step4. return OK.
1402      */
1403     std::string sql = "update " + DBCommon::GetLogTableName(tableName) + " SET status=0";
1404     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1405     EXPECT_EQ(UnLock(tableName, hashKey, db), OK);
1406 
1407     /**
1408      * @tc.steps:step5. unLock again, hashKey has matching data
1409      * @tc.expected: step5. return NOT_FOUND.
1410      */
1411     hashKey.clear();
1412     hashKey.push_back({'1'});
1413     EXPECT_EQ(UnLock(tableName, hashKey, db), NOT_FOUND);
1414     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1415 }
1416 
1417 /**
1418  * @tc.name: LockDataTest003
1419  * @tc.desc: Test status after local change
1420  * @tc.type: FUNC
1421  * @tc.require:
1422  * @tc.author: bty
1423  */
1424 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest003, TestSize.Level0)
1425 {
1426     /**
1427      * @tc.steps:step1. update data and check
1428      * @tc.expected: step1. return E_OK.
1429      */
1430     const std::string tableName = "sync_data";
1431     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1432     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1433     EXPECT_NE(db, nullptr);
1434     int count = 10;
1435     InitDataStatus(tableName, count, db);
1436     std::string sql = "update " + tableName + " SET name='1' where id in (1,11,21,31)";
1437     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1438     CheckDataStatus(tableName, " status = 3 and data_key in (1,11,21,31) ", db, 2); // 2 is changed count
1439 
1440     /**
1441      * @tc.steps:step1. delete data and check
1442      * @tc.expected: step1. return E_OK.
1443      */
1444     sql = "delete from " + tableName + " where id in (2,12,22,32)";
1445     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1446     CheckDataStatus(tableName, " status = 1 and data_key = -1 ", db, 3); // 3 is changed count
1447 }
1448 
1449 DistributedDB::StoreObserver::StoreChangedInfo g_changedData;
1450 
1451 class MockStoreObserver : public StoreObserver {
1452 public:
~MockStoreObserver()1453     virtual ~MockStoreObserver() {};
OnChange(StoreChangedInfo && data)1454     void OnChange(StoreChangedInfo &&data) override
1455     {
1456         g_changedData = data;
1457         std::unique_lock<std::mutex> lock(g_mutex);
1458         g_cv.notify_one();
1459         g_alreadyNotify = true;
1460     };
1461 };
1462 
CreateTableForStoreObserver(sqlite3 * db,const std::string tableName)1463 void CreateTableForStoreObserver(sqlite3 *db, const std::string tableName)
1464 {
1465     std::string sql = "create table " + tableName + "(id INTEGER primary key, name TEXT);";
1466     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1467     sql = "create table no_" + tableName + "(id INTEGER, name TEXT);";
1468     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1469     sql = "create table mult_" + tableName + "(id INTEGER, name TEXT, age int, ";
1470     sql += "PRIMARY KEY (id, name));";
1471     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1472 }
1473 
PrepareDataForStoreObserver(sqlite3 * db,const std::string & tableName,int begin,int dataCounts)1474 void PrepareDataForStoreObserver(sqlite3 *db, const std::string &tableName, int begin, int dataCounts)
1475 {
1476     std::string sql = "begin;";
1477     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1478     for (int i = begin; i < begin + dataCounts; i++) {
1479         sql = "insert into " + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1480             std::to_string(i + 1) + "');";
1481         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1482         sql = "insert into no_" + tableName +" VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1483             std::to_string(i + 1) + "');";
1484         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1485         sql = "insert into mult_" + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan";
1486         sql += std::to_string(i + 1) + "', 18);";
1487         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1488     }
1489     for (int i = begin; i < dataCounts / 2 + begin; i++) { // 2 is half
1490         sql = "update " + tableName + " set name = 'lisi' where id = " + std::to_string(i + 1) + ";";
1491         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1492         sql = "update no_" + tableName + " set name = 'lisi' where _rowid_ = " + std::to_string(i + 1) + ";";
1493         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1494         sql = "update mult_" + tableName + " set age = 20 where id = " + std::to_string(i + 1);
1495         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1496         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1497     }
1498     for (int i = dataCounts / 2 + begin; i < dataCounts + begin; i++) { // 2 is half
1499         sql = "delete from " + tableName + " where id = " + std::to_string(i + 1) + ";";
1500         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1501         sql = "delete from no_" + tableName + " where _rowid_ = " + std::to_string(i + 1) + ";";
1502         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1503         sql = "delete from mult_" + tableName + " where id = " + std::to_string(i + 1);
1504         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1505         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1506     }
1507     sql = "commit;";
1508     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1509 }
1510 
CheckChangedData(int num,int times=0,int offset=0)1511 void CheckChangedData(int num, int times = 0, int offset = 0)
1512 {
1513     if (num == 1) {
1514         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1515             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1516                 static_cast<int64_t>(i + offset - times * 5)); // 5 is rowid times
1517         }
1518         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1519             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1520                 static_cast<int64_t>(i + offset + 5)); // 5 is offset
1521         }
1522         return;
1523     }
1524     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1525         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1526             static_cast<int64_t>(i + offset));
1527     }
1528     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_UPDATE].size(); i++) {
1529         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_UPDATE][i - 1][0]),
1530             static_cast<int64_t>(i + offset));
1531     }
1532     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1533         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1534             static_cast<int64_t>(i + offset + 5)); // 5 is offset
1535     }
1536 }
1537 
1538 /**
1539  * @tc.name: RegisterStoreObserverTest001
1540  * @tc.desc: Test commit for three table then trigger store observer
1541  * @tc.type: FUNC
1542  * @tc.require:
1543  * @tc.author: chenchaohao
1544  */
1545 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest001, TestSize.Level1)
1546 {
1547     /**
1548      * @tc.steps:step1. prepare db and create table.
1549      * @tc.expected: step1. return ok.
1550      */
1551     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1552     EXPECT_NE(db, nullptr);
1553     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1554     std::string tableName = "primary_test";
1555     CreateTableForStoreObserver(db, tableName);
1556 
1557     /**
1558     * @tc.steps:step2. register store observer and check onchange.
1559     * @tc.expected: step2. return ok.
1560     */
1561     auto storeObserver = std::make_shared<MockStoreObserver>();
1562     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1563     EXPECT_TRUE(g_changedData.empty());
1564     int dataCounts = 10; // 10 is count of insert options.
1565     int begin = 0;
1566     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1567     {
1568         std::unique_lock<std::mutex> lock(g_mutex);
__anon41da56cb1702() 1569         g_cv.wait(lock, []() {
1570             return g_alreadyNotify;
1571         });
1572         g_alreadyNotify = false;
1573     }
1574     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1575     CheckChangedData(0);
1576     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1577     CheckChangedData(1);
1578     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1579     CheckChangedData(2); // 2 is mult primary table
1580     g_changedData.clear();
1581 
1582     /**
1583     * @tc.steps:step3. unregister store observer and update data check onchange.
1584     * @tc.expected: step3. return ok.
1585     */
1586     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1587     begin = 10; // 10 is begin id
1588     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1589     EXPECT_TRUE(g_changedData.empty());
1590     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1591 }
1592 
1593 /**
1594  * @tc.name: RegisterStoreObserverTest002
1595  * @tc.desc: Test commit for three table then trigger client observer when register then create table
1596  * @tc.type: FUNC
1597  * @tc.require:
1598  * @tc.author: chenchaohao
1599  */
1600 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest002, TestSize.Level1)
1601 {
1602     /**
1603      * @tc.steps:step1. prepare db and register store observer then create table.
1604      * @tc.expected: step1. return ok.
1605      */
1606     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1607     EXPECT_NE(db, nullptr);
1608     auto storeObserver = std::make_shared<MockStoreObserver>();
1609     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1610     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1611     std::string tableName = "primary_test";
1612     CreateTableForStoreObserver(db, tableName);
1613 
1614     /**
1615     * @tc.steps:step2. update data and check onchange.
1616     * @tc.expected: step2. return ok.
1617     */
1618     EXPECT_TRUE(g_changedData.empty());
1619     int dataCounts = 10; // 10 is count of insert options.
1620     int begin = 0;
1621     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1622     WaitAndResetNotify();
1623     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1624     CheckChangedData(0);
1625     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1626     CheckChangedData(1);
1627     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1628     CheckChangedData(2); // 2 is mult primary table
1629     g_changedData.clear();
1630 
1631     /**
1632     * @tc.steps:step3. unregister store observer and update data check onchange.
1633     * @tc.expected: step3. return ok.
1634     */
1635     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1636     begin = 10; // 11 is begin id
1637     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1638     EXPECT_TRUE(g_changedData.empty());
1639     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1640 }
1641 
1642 /**
1643  * @tc.name: RegisterStoreObserverTest003
1644  * @tc.desc: Test commit for three table then trigger client observer when register two observer
1645  * @tc.type: FUNC
1646  * @tc.require:
1647  * @tc.author: chenchaohao
1648  */
1649 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest003, TestSize.Level1)
1650 {
1651     /**
1652      * @tc.steps:step1. prepare db and register store observer then create table.
1653      * @tc.expected: step1. return ok.
1654      */
1655     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1656     EXPECT_NE(db, nullptr);
1657     auto storeObserver1 = std::make_shared<MockStoreObserver>();
1658     auto storeObserver2 = std::make_shared<MockStoreObserver>();
1659     EXPECT_EQ(RegisterStoreObserver(db, storeObserver1), OK);
1660     EXPECT_EQ(RegisterStoreObserver(db, storeObserver2), OK);
1661     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1662     std::string tableName = "primary_test";
1663     CreateTableForStoreObserver(db, tableName);
1664 
1665     /**
1666     * @tc.steps:step2. update data and check onchange.
1667     * @tc.expected: step2. return ok.
1668     */
1669     EXPECT_TRUE(g_changedData.empty());
1670     int dataCounts = 10; // 10 is count of insert options.
1671     int begin = 0;
1672     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1673     WaitAndResetNotify();
1674     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1675     CheckChangedData(0);
1676     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1677     CheckChangedData(1);
1678     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1679     CheckChangedData(2); // 2 is mult primary table
1680     g_changedData.clear();
1681 
1682     /**
1683     * @tc.steps:step3. unregister store observer and update data check onchange.
1684     * @tc.expected: step3. return ok.
1685     */
1686     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver1), OK);
1687     begin = 10; // 11 is begin id
1688     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1689     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1690     CheckChangedData(0, 1, dataCounts);
1691     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1692     CheckChangedData(1, 1, dataCounts);
1693     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1694     CheckChangedData(2, 1, dataCounts); // 2 is mult primary table
1695     g_changedData.clear();
1696 
1697     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver2), OK);
1698     begin = 20; // 21 is begin id
1699     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1700     EXPECT_TRUE(g_changedData.empty());
1701     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1702 }
1703 
1704 /**
1705  * @tc.name: RegisterStoreObserverTest004
1706  * @tc.desc: Test register two same observer
1707  * @tc.type: FUNC
1708  * @tc.require:
1709  * @tc.author: chenchaohao
1710  */
1711 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest004, TestSize.Level1)
1712 {
1713     /**
1714      * @tc.steps:step1. prepare db and register store observer then create table.
1715      * @tc.expected: step1. return ok.
1716      */
1717     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1718     EXPECT_NE(db, nullptr);
1719     auto storeObserver = std::make_shared<MockStoreObserver>();
1720     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1721     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), INVALID_ARGS);
1722 }
1723 
1724 /**
1725  * @tc.name: AbnormalDelegateImplTest001
1726  * @tc.desc: Test delegateImpl interface after delegate is closed
1727  * @tc.type: FUNC
1728  * @tc.require: DTS2024073106613
1729  * @tc.author: suyue
1730  */
1731 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest001, TestSize.Level0)
1732 {
1733     /**
1734      * @tc.steps:step1. create db and open store.
1735      * @tc.expected: step1. return ok.
1736      */
1737     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1738     ASSERT_NE(db, nullptr);
1739     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1740     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1741     RelationalStoreDelegate *delegate = nullptr;
1742     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1743     EXPECT_EQ(status, OK);
1744     ASSERT_NE(delegate, nullptr);
1745 
1746     /**
1747      * @tc.steps:step2. close delegate.
1748      * @tc.expected: step2. return ok.
1749      */
1750     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1751     status = delegateImpl->Close();
1752     EXPECT_EQ(status, OK);
1753 
1754     /**
1755      * @tc.steps:step3. test DelegateImpl interface after delegate is closed.
1756      * @tc.expected: step3. return DB_ERROR.
1757      */
1758     const RemoteCondition condition;
1759     std::shared_ptr<ResultSet> result = nullptr;
1760     DBStatus ret = delegateImpl->RemoteQuery("", condition, 0, result);
1761     EXPECT_EQ(ret, DB_ERROR);
1762     EXPECT_EQ(delegateImpl->RemoveDeviceData(), DB_ERROR);
1763 
1764     StoreObserver observer;
1765     EXPECT_EQ(delegateImpl->RegisterObserver(&observer), DB_ERROR);
1766     EXPECT_EQ(delegateImpl->UnRegisterObserver(&observer), DB_ERROR);
1767     DistributedDB::SqlCondition sqlCondition;
1768     std::vector<VBucket> records = {};
1769     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), DB_ERROR);
1770     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), DB_ERROR);
1771     const CloudSyncConfig config;
1772     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), DB_ERROR);
1773 
1774     /**
1775      * @tc.steps:step4. close store.
1776      * @tc.expected: step4. return ok.
1777      */
1778     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1779     delegate = nullptr;
1780 }
1781 
1782 /**
1783  * @tc.name: AbnormalDelegateImplTest002
1784  * @tc.desc: Test delegate interface after delegate is closed
1785  * @tc.type: FUNC
1786  * @tc.require: DTS2024073106613
1787  * @tc.author: suyue
1788  */
1789 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest002, TestSize.Level0)
1790 {
1791     /**
1792      * @tc.steps:step1. create db and open store.
1793      * @tc.expected: step1. return ok.
1794      */
1795     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1796     ASSERT_NE(db, nullptr);
1797     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1798     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1799     RelationalStoreDelegate *delegate = nullptr;
1800     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1801     EXPECT_EQ(status, OK);
1802     ASSERT_NE(delegate, nullptr);
1803 
1804     /**
1805      * @tc.steps:step2. test DelegateImpl interface when para is err.
1806      * @tc.expected: step2. return INVALID_ARGS or NOT_FOUND.
1807      */
1808     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1809     const CloudSyncConfig config;
1810     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), OK);
1811     DistributedDB::SqlCondition sqlCondition;
1812     std::vector<VBucket> records = {};
1813     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), INVALID_ARGS);
1814     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), INVALID_ARGS);
1815     EXPECT_EQ(delegateImpl->CleanTrackerData("", 0), INVALID_ARGS);
1816     TrackerSchema schema;
1817     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), INVALID_ARGS);
1818     schema = {.tableName = "test", .extendColName = "", .trackerColNames = {}};
1819     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), NOT_FOUND);
1820 
1821     /**
1822      * @tc.steps:step3. close store.
1823      * @tc.expected: step3. return ok.
1824      */
1825     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1826     delegate = nullptr;
1827 }
1828 }
1829