• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.extendColNames = {"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);
__anona8aa9dd30402(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 " + std::string(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;
__anona8aa9dd30602(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 " + std::string(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 " + std::string(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;
__anona8aa9dd30802(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     RegisterDbHook(db);
604 
605     /**
606      * @tc.steps:step3. insert data into sync_data, check observer.
607      * @tc.expected: step3. check observer ok.
608      */
609     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
610     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
611     WaitAndResetNotify();
612     std::atomic<int> count = 0; // 0 is observer triggered counts
613     CheckTriggerObserverTest002(tableName, count);
614 
615     /**
616      * @tc.steps:step4. update data, check observer.
617      * @tc.expected: step4. check observer ok.
618      */
619     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
620     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
621     WaitAndResetNotify();
622     CheckTriggerObserverTest002(tableName, count);
623 
624     /**
625      * @tc.steps:step4. delete data, check observer.
626      * @tc.expected: step4. check observer ok.
627      */
628     sql = "delete from " + tableName + " where id = 3;";
629     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
630     WaitAndResetNotify();
631     CheckTriggerObserverTest002(tableName, count);
632 
633     /**
634      * @tc.steps:step5. register another observer, update data, check observer.
635      * @tc.expected: step5. check observer ok.
636      */
637     triggeredCount_ = 0;
638     ClientObserver clientObserver2 = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2,
639         this, std::placeholders::_1);
640     EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK);
641     RegisterDbHook(db);
642     sql = "update " + tableName + " set name = 'lisi2' where id = 2;";
643     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
644     WaitAndResetNotify();
645     EXPECT_EQ(triggeredCount_, 0);
646     EXPECT_EQ(triggeredCount2_, 1);
647 
648     /**
649      * @tc.steps:step6. UnRegisterClientObserver, update data, check observer.
650      * @tc.expected: step6. check observer ok.
651      */
652     triggeredCount2_ = 0;
653     EXPECT_EQ(UnRegisterClientObserver(db), OK);
654     sql = "update " + tableName + " set name = 'lisi3' where id = 2;";
655     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
656     EXPECT_EQ(triggeredCount2_, 0); // observer2 will not be triggered
657     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
658 }
659 
660 /**
661  * @tc.name: TriggerObserverTest003
662  * @tc.desc: Test RegisterClientObserver and UnRegisterClientObserver concurrently
663  * @tc.type: FUNC
664  * @tc.require:
665  * @tc.author: zhangshijie
666  */
667 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest003, TestSize.Level1)
668 {
669     for (int i = 0; i < 1000; i++) { // 1000 is loop times
__anona8aa9dd30902() 670         std::thread t1 ([this]() {
671             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
672             EXPECT_NE(db, nullptr);
673             ClientObserver clientObserver = std::bind(
674                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, this, std::placeholders::_1);
675             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
676             EXPECT_EQ(UnRegisterClientObserver(db), OK);
677             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
678         });
679 
__anona8aa9dd30a02() 680         std::thread t2 ([this]() {
681             sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
682             EXPECT_NE(db, nullptr);
683             ClientObserver clientObserver = std::bind(
684                 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2, this, std::placeholders::_1);
685             EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
686             EXPECT_EQ(UnRegisterClientObserver(db), OK);
687             EXPECT_EQ(sqlite3_close_v2(db), E_OK);
688         });
689 
690         t1.join();
691         t2.join();
692     }
693 }
694 
695 /**
696  * @tc.name: TriggerObserverTest004
697  * @tc.desc: Test batch insert/update/delete data then trigger client observer
698  * @tc.type: FUNC
699  * @tc.require:
700  * @tc.author: zhangshijie
701  */
702 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, TestSize.Level1)
703 {
704     /**
705      * @tc.steps:step1. prepare data.
706      * @tc.expected: step1. return ok.
707      */
708     const std::string tableName = "sync_data";
709     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
710 
711     /**
712     * @tc.steps:step2. register client observer.
713     * @tc.expected: step2. return ok.
714     */
715     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
716     EXPECT_NE(db, nullptr);
717     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
718         this, std::placeholders::_1);
719     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
720     RegisterDbHook(db);
721 
722     /**
723      * @tc.steps:step3. insert data into sync_data, check observer.
724      * @tc.expected: step3. check observer ok.
725      */
726     std::string sql;
727     int dataCounts = 1000; // 1000 is count of insert options.
728     for (int i = 1; i <= dataCounts; i++) {
729         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
730         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
731     }
732     std::unique_lock<std::mutex> lock(g_mutex);
__anona8aa9dd30b02() 733     bool isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this, dataCounts]() { // 1 is wait time
734         return triggeredCount_ == dataCounts;
735     });
736     EXPECT_EQ(isEqual, true);
737     WaitAndResetNotifyWithLock(lock);
738     ASSERT_EQ(triggerTableData_.size(), 1u);
739     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
740     EXPECT_EQ(triggeredCount_, dataCounts);
741 
742     /**
743      * @tc.steps:step4. insert or replace, check observer.
744      * @tc.expected: step5. check observer ok.
745      */
746     triggeredCount_ = 0;
747     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
748     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
__anona8aa9dd30c02() 749     isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this]() { // 1 is wait time
750         return triggeredCount_ == 1;
751     });
752     EXPECT_EQ(isEqual, true);
753     WaitAndResetNotifyWithLock(lock);
754     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
755     EXPECT_EQ(UnRegisterClientObserver(db), OK);
756     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
757 }
758 
759 /**
760  * @tc.name: TriggerObserverTest005
761  * @tc.desc: Test commit and rollback for one table then trigger client observer
762  * @tc.type: FUNC
763  * @tc.require:
764  * @tc.author: chenchaohao
765  */
766 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest005, TestSize.Level1)
767 {
768     /**
769      * @tc.steps:step1. prepare data.
770      * @tc.expected: step1. return ok.
771      */
772     const std::string tableName = "sync_data";
773     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
774 
775     /**
776     * @tc.steps:step2. register client observer.
777     * @tc.expected: step2. return ok.
778     */
779     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
780     EXPECT_NE(db, nullptr);
781     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
782         this, std::placeholders::_1);
783     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
784     RegisterDbHook(db);
785 
786     /**
787      * @tc.steps:step3. begin transaction and commit.
788      * @tc.expected: step3. check observer ok.
789      */
790     std::string sql = "begin;";
791     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
792     int dataCounts = 1000; // 1000 is count of insert options.
793     for (int i = 1; i <= dataCounts; i++) {
794         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
795         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
796     }
797     sql = "commit;";
798     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
799     WaitAndResetNotify();
800     ASSERT_EQ(triggerTableData_.size(), 1u);
801     EXPECT_EQ(triggerTableData_.begin()->first, tableName);
802     EXPECT_EQ(triggeredCount_, 1);
803 
804     /**
805      * @tc.steps:step4. begin transaction and rollback.
806      * @tc.expected: step3. check observer ok.
807      */
808     triggerTableData_.clear();
809     triggeredCount_ = 0;
810     sql = "begin;";
811     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
812     for (int i = dataCounts + 1; i <= 2 * dataCounts; i++) { // 2 is double dataCounts
813         sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
814         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
815     }
816     sql = "rollback;";
817     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
818     EXPECT_TRUE(triggerTableData_.empty());
819     EXPECT_EQ(triggeredCount_, 0);
820 
821     /**
822      * @tc.steps:step5. insert or replace, check observer.
823      * @tc.expected: step5. check observer ok.
824      */
825     triggeredCount_ = 0;
826     sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
827     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
828     WaitAndResetNotify();
829     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
830     EXPECT_EQ(UnRegisterClientObserver(db), OK);
831     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
832 }
833 
834 /**
835  * @tc.name: TriggerObserverTest006
836  * @tc.desc: Test commit and rollback for multi-table then trigger client observer
837  * @tc.type: FUNC
838  * @tc.require:
839  * @tc.author: chenchaohao
840  */
841 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, TestSize.Level1)
842 {
843     /**
844      * @tc.steps:step1. prepare data.
845      * @tc.expected: step1. return ok.
846      */
847     const std::string tableName1 = "sync_data1";
848     const std::string tableName2 = "sync_data2";
849     PrepareData({tableName1, tableName2}, false, DistributedDB::CLOUD_COOPERATION, false);
850 
851     /**
852     * @tc.steps:step2. register client observer.
853     * @tc.expected: step2. return ok.
854     */
855     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
856     EXPECT_NE(db, nullptr);
857     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
858         this, std::placeholders::_1);
859     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
860     RegisterDbHook(db);
861 
862     /**
863      * @tc.steps:step3. begin transaction and commit.
864      * @tc.expected: step3. check observer ok.
865      */
866     std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
867     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
868     WaitAndResetNotify();
869     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
870     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
871     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
872 
873     /**
874      * @tc.steps:step4. UnRegisterClientObserver and insert table2.
875      * @tc.expected: step3. check observer ok.
876      */
877     triggerTableData_.clear();
878     triggeredCount_ = 0;
879     EXPECT_EQ(UnRegisterClientObserver(db), OK);
880     sql = "insert into " + tableName2 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
881     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
882     EXPECT_TRUE(triggerTableData_.empty());
883     EXPECT_EQ(triggeredCount_, 0);
884 
885     /**
886      * @tc.steps:step5. RegisterClientObserver again and insert table1, check observer.
887      * @tc.expected: step5. check observer ok.
888      */
889     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
890     RegisterDbHook(db);
891     sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');";
892     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
893     WaitAndResetNotify();
894     ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
895     EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
896     EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
897     EXPECT_EQ(UnRegisterClientObserver(db), OK);
898     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
899 }
900 
901 /**
902  * @tc.name: TriggerObserverTest007
903  * @tc.desc: Test trigger client observer in tracker table
904  * @tc.type: FUNC
905  * @tc.require:
906  * @tc.author: zhangshijie
907  */
908 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest007, TestSize.Level0)
909 {
910     /**
911      * @tc.steps:step1. prepare data and set trackerTable
912      * @tc.expected: step1. return ok.
913      */
914     const std::string tableName = "sync_data";
915     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false, false);
916     SetTracerSchemaTest001(tableName);
917 
918     /**
919     * @tc.steps:step2. register client observer.
920     * @tc.expected: step2. return ok.
921     */
922     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
923     EXPECT_NE(db, nullptr);
924     ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
925         this, std::placeholders::_1);
926     EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
927     RegisterDbHook(db);
928 
929     /**
930      * @tc.steps:step3. insert data into sync_data, check observer.
931      * @tc.expected: step3. check observer ok.
932      */
933     std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
934     std::unique_lock<std::mutex> lock(g_mutex);
935     ExecSqlAndWaitForObserver(db, sql, lock);
936     ChangeProperties properties;
937     properties.isTrackedDataChange = true;
938     int triggerCount = 1;
939     CheckTriggerTableData(1u, tableName, properties, triggerCount);
940 
941     /**
942      * @tc.steps:step4. update data, check observer.
943      * @tc.expected: step4. check observer ok.
944      */
945     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
946     ExecSqlAndWaitForObserver(db, sql, lock);
947     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
948 
949     /**
950      * @tc.steps:step5. update to the same data again, check observer.
951      * @tc.expected: step5. check observer ok.
952      */
953     sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
954     ExecSqlAndWaitForObserver(db, sql, lock);
955     properties.isTrackedDataChange = false;
956     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
957 
958     /**
959      * @tc.steps:step6. update to the same data again, set name is NULL, check observer.
960      * @tc.expected: step6. check observer ok.
961      */
962     sql = "update " + tableName + " set name = NULL where id = 2;";
963     ExecSqlAndWaitForObserver(db, sql, lock);
964     properties.isTrackedDataChange = true;
965     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
966 
967     /**
968      * @tc.steps:step7. update to the same data again, set name is empty, check observer.
969      * @tc.expected: step7. check observer ok.
970      */
971     sql = "update " + tableName + " set name = '' where id = 2;";
972     ExecSqlAndWaitForObserver(db, sql, lock);
973     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
974 
975     /**
976      * @tc.steps:step8. delete data, check observer.
977      * @tc.expected: step8. check observer ok.
978      */
979     sql = "delete from " + tableName + " where id = 2;";
980     ExecSqlAndWaitForObserver(db, sql, lock);
981     CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
982     EXPECT_EQ(UnRegisterClientObserver(db), OK);
983     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
984 }
985 
InitLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t num)986 void InitLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t num)
987 {
988     for (size_t i = 0; i < num; ++i) {
989         std::string sql = "insert or replace into " + tableName + " VALUES('" + std::to_string(i) + "', 'zhangsan');";
990         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
991     }
992     std::string sql = "update " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log" +
993         " SET flag = flag | 0x08";
994     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
995 }
996 
CheckLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t expectNum)997 void CheckLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t expectNum)
998 {
999     std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log"
1000         " where flag&0x08=0x08 and flag&0x01=0";
1001     sqlite3_stmt *stmt = nullptr;
1002     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
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     int errCode;
1008     SQLiteUtils::ResetStatement(stmt, true, errCode);
1009     stmt = nullptr;
1010     sql = "select count(*) from " + tableName;
1011     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1012         uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1013         EXPECT_EQ(count, expectNum);
1014     }
1015     SQLiteUtils::ResetStatement(stmt, true, errCode);
1016 }
1017 
1018 /**
1019  * @tc.name: DropDeleteData001
1020  * @tc.desc: Test trigger client observer in tracker table
1021  * @tc.type: FUNC
1022  * @tc.require:
1023  * @tc.author:
1024  */
1025 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DropDeleteData001, TestSize.Level0)
1026 {
1027     /**
1028      * @tc.steps:step1. prepare data.
1029      * @tc.expected: step1. return ok.
1030      */
1031     const std::string tableName = "sync_data";
1032     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1033     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1034     EXPECT_NE(db, nullptr);
1035     uint64_t num = 10;
1036     InitLogicDeleteData(db, tableName, num);
1037 
1038     /**
1039      * @tc.steps:step2. db handle is nullptr
1040      * @tc.expected: step2. return INVALID_ARGS.
1041      */
1042     EXPECT_EQ(DropLogicDeletedData(nullptr, tableName, 0u), INVALID_ARGS);
1043 
1044     /**
1045      * @tc.steps:step3. tableName is empty
1046      * @tc.expected: step3. return INVALID_ARGS.
1047      */
1048     EXPECT_EQ(DropLogicDeletedData(db, "", 0u), INVALID_ARGS);
1049 
1050     /**
1051      * @tc.steps:step4. tableName is no exist
1052      * @tc.expected: step4. return INVALID_ARGS.
1053      */
1054     EXPECT_EQ(DropLogicDeletedData(db, tableName + "_", 0u), DB_ERROR);
1055 
1056     /**
1057      * @tc.steps:step5. cursor is 0
1058      * @tc.expected: step5. return OK.
1059      */
1060     EXPECT_EQ(DropLogicDeletedData(db, tableName, 0u), OK);
1061     CheckLogicDeleteData(db, tableName, 0u);
1062 
1063     /**
1064      * @tc.steps:step6. init data again, and cursor is 15
1065      * @tc.expected: step6. return OK.
1066      */
1067     uint64_t cursor = 15;
1068     InitLogicDeleteData(db, tableName, num);
1069     EXPECT_EQ(DropLogicDeletedData(db, tableName, cursor), OK);
1070     CheckLogicDeleteData(db, tableName, cursor - num);
1071     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1072 }
1073 
1074 /**
1075  * @tc.name: FfrtTest001
1076  * @tc.desc: Test ffrt concurrency
1077  * @tc.type: FUNC
1078  * @tc.require:
1079  * @tc.author:
1080  */
1081 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest001, TestSize.Level0)
1082 {
1083     std::map<int, int> ans;
1084 #ifdef USE_FFRT
1085     ffrt::mutex mutex;
1086 #else
1087     std::mutex mutex;
1088 #endif
1089     size_t num = 1000;
1090 
1091     /**
1092      * @tc.steps:step1. submit insert map task
1093      * @tc.expected: step1. return ok.
1094      */
__anona8aa9dd30d02() 1095     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1096         for (size_t j = 0; j < num; j++) {
1097             ConcurrentAdapter::AdapterAutoLock(mutex);
1098             for (size_t i = 0; i < num; i++) {
1099                 ans.insert_or_assign(i, i);
1100             }
1101             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1102         }
1103     }, nullptr, &ans);
1104 
1105     /**
1106      * @tc.steps:step2. submit erase map task
1107      * @tc.expected: step2. return ok.
1108      */
__anona8aa9dd30e02() 1109     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1110         for (size_t i = 0; i < num; i++) {
1111             ConcurrentAdapter::AdapterAutoLock(mutex);
1112             for (auto it = ans.begin(); it != ans.end();) {
1113                 it = ans.erase(it);
1114             }
1115             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1116         }
1117     }, nullptr, &ans);
1118 
1119     /**
1120      * @tc.steps:step3. submit get from map task
1121      * @tc.expected: step3. return ok.
1122      */
__anona8aa9dd30f02() 1123     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1124         for (size_t i = 0; i < num; i++) {
1125             ConcurrentAdapter::AdapterAutoLock(mutex);
1126             for (auto it = ans.begin(); it != ans.end(); it++) {
1127                 int j = it->first;
1128                 EXPECT_GE(j, 0);
1129             }
1130             ConcurrentAdapter::AdapterAutoUnLock(mutex);
1131         }
1132     }, &ans, nullptr);
1133     ADAPTER_WAIT(h1);
1134     ADAPTER_WAIT(h2);
1135     ADAPTER_WAIT(h3);
1136     ASSERT_TRUE(ans.empty());
1137 }
1138 
1139 /**
1140  * @tc.name: FfrtTest002
1141  * @tc.desc: Test ffrt concurrency
1142  * @tc.type: FUNC
1143  * @tc.require:
1144  * @tc.author:
1145  */
1146 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Level0)
1147 {
1148     std::map<int, int> ans;
1149 #ifdef USE_FFRT
1150     ffrt::mutex mutex;
1151 #else
1152     std::mutex mutex;
1153 #endif
1154     size_t num = 1000;
1155 
1156     /**
1157      * @tc.steps:step1. subtask submit insert map task
1158      * @tc.expected: step1. return ok.
1159      */
__anona8aa9dd31002() 1160     TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1161         TaskHandle hh1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1162             for (size_t j = 0; j < num; j++) {
1163                 ConcurrentAdapter::AdapterAutoLock(mutex);
1164                 for (size_t i = 0; i < num; i++) {
1165                     ans.insert_or_assign(i, i);
1166                 }
1167                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1168             }
1169         }, nullptr, &ans);
1170         ADAPTER_WAIT(hh1);
1171     });
1172 
1173     /**
1174      * @tc.steps:step2. subtask submit erase map task
1175      * @tc.expected: step2. return ok.
1176      */
__anona8aa9dd31202() 1177     TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1178         TaskHandle hh2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1179             for (size_t i = 0; i < num; i++) {
1180                 ConcurrentAdapter::AdapterAutoLock(mutex);
1181                 for (auto it = ans.begin(); it != ans.end();) {
1182                     it = ans.erase(it);
1183                 }
1184                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1185             }
1186         }, nullptr, &ans);
1187         ADAPTER_WAIT(hh2);
1188     });
1189 
1190     /**
1191      * @tc.steps:step3. subtask submit get from map task
1192      * @tc.expected: step3. return ok.
1193      */
__anona8aa9dd31402() 1194     TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1195         TaskHandle hh3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1196             for (size_t i = 0; i < num; i++) {
1197                 ConcurrentAdapter::AdapterAutoLock(mutex);
1198                 for (auto it = ans.begin(); it != ans.end(); it++) {
1199                     int j = it->first;
1200                     EXPECT_GE(j, 0);
1201                 }
1202                 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1203             }
1204         }, &ans, nullptr);
1205         ADAPTER_WAIT(hh3);
1206     });
1207     ADAPTER_WAIT(h1);
1208     ADAPTER_WAIT(h2);
1209     ADAPTER_WAIT(h3);
1210 }
1211 
1212 /**
1213  * @tc.name: FfrtTest003
1214  * @tc.desc: Test ffrt concurrency
1215  * @tc.type: FUNC
1216  * @tc.require:
1217  * @tc.author:
1218  */
1219 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest003, TestSize.Level0)
1220 {
1221     size_t count = 0;
1222     size_t num = 3000;
1223     std::vector<TaskHandle> waitVec;
1224 
1225     /**
1226      * @tc.steps:step1. submit increase task
1227      * @tc.expected: step1. return ok.
1228      */
1229     for (size_t j = 0; j < num; j++) {
__anona8aa9dd31602() 1230         TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &count, num]() {
1231             for (size_t i = 0; i < num; i++) {
1232                 count++;
1233             }
1234         }, nullptr, nullptr);
1235         waitVec.push_back(std::move(h1));
1236     }
1237     for (const auto &item : waitVec) {
1238         ADAPTER_WAIT(item);
1239     }
1240 
1241     /**
1242      * @tc.steps:step2. check count
1243      * @tc.expected: step2. return ok.
1244      */
1245 #ifdef USE_FFRT
1246     EXPECT_LE(count, num * num);
1247 #else
1248     EXPECT_EQ(count, num * num);
1249 #endif
1250 }
1251 
1252 /**
1253  * @tc.name: AbnormalDelegateTest001
1254  * @tc.desc: Test delegate interface after delegate is closed
1255  * @tc.type: FUNC
1256  * @tc.require:
1257  * @tc.author: chenchaohao
1258  */
1259 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateTest001, TestSize.Level0)
1260 {
1261     /**
1262      * @tc.steps:step1. create db and open store
1263      * @tc.expected: step1. return ok.
1264      */
1265     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1266     ASSERT_NE(db, nullptr);
1267     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1268     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1269     RelationalStoreDelegate *delegate = nullptr;
1270     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1271     EXPECT_EQ(status, OK);
1272     ASSERT_NE(delegate, nullptr);
1273 
1274     /**
1275      * @tc.steps:step2. close delegate
1276      * @tc.expected: step2. return ok.
1277      */
1278     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1279     status = delegateImpl->Close();
1280     EXPECT_EQ(status, OK);
1281 
1282     /**
1283      * @tc.steps:step3. test interface after delegate is closed
1284      * @tc.expected: step3. return ok.
1285      */
1286     const std::string tableName = "sync_data";
1287     EXPECT_EQ(delegateImpl->RemoveDeviceData("", tableName), DB_ERROR);
1288     EXPECT_EQ(delegate->RemoveDeviceData("", FLAG_AND_DATA), DB_ERROR);
1289     EXPECT_EQ(delegate->GetCloudSyncTaskCount(), -1); // -1 is error count
1290     EXPECT_EQ(delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DB_ERROR);
1291     EXPECT_EQ(delegate->UnRegisterObserver(), DB_ERROR);
1292     DataBaseSchema dataBaseSchema;
1293     EXPECT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DB_ERROR);
1294     EXPECT_EQ(delegate->SetReference({}), DB_ERROR);
1295     TrackerSchema trackerSchema;
1296     EXPECT_EQ(delegate->SetTrackerTable(trackerSchema), DB_ERROR);
1297     EXPECT_EQ(delegate->CleanTrackerData(tableName, 0), DB_ERROR);
1298     bool logicDelete = true;
1299     auto data = static_cast<PragmaData>(&logicDelete);
1300     EXPECT_EQ(delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), DB_ERROR);
1301     std::vector<VBucket> records;
1302     RecordStatus recordStatus = RecordStatus::WAIT_COMPENSATED_SYNC;
1303     EXPECT_EQ(delegate->UpsertData(tableName, records, recordStatus), DB_ERROR);
1304 
1305     /**
1306      * @tc.steps:step4. close store
1307      * @tc.expected: step4. return ok.
1308      */
1309     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1310     delegate = nullptr;
1311 }
1312 
InitDataStatus(const std::string & tableName,int count,sqlite3 * db)1313 void InitDataStatus(const std::string &tableName, int count, sqlite3 *db)
1314 {
1315     int type = 4; // the num of different status
1316     for (int i = 1; i <= type * count; i++) {
1317         std::string sql = "INSERT INTO " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" +
1318             std::to_string(i) + "');";
1319         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1320     }
1321     std::string countStr = std::to_string(count);
1322     std::string sql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET status=(CASE WHEN data_key<=" +
1323         countStr + " THEN 0 WHEN data_key>" + countStr + " AND data_key<=2*" + countStr + " THEN 1 WHEN data_key>2*" +
1324         countStr + " AND data_key<=3*" + countStr + " THEN 2 ELSE 3 END)";
1325     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1326 }
1327 
CheckDataStatus(const std::string & tableName,const std::string & condition,sqlite3 * db,int64_t expect)1328 void CheckDataStatus(const std::string &tableName, const std::string &condition, sqlite3 *db, int64_t expect)
1329 {
1330     std::string sql = "SELECT count(1) FROM " + DBCommon::GetLogTableName(tableName) + " WHERE " + condition;
1331     sqlite3_stmt *stmt = nullptr;
1332     EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1333     while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1334         int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
1335         EXPECT_EQ(count, expect);
1336     }
1337     int errCode;
1338     SQLiteUtils::ResetStatement(stmt, true, errCode);
1339 }
1340 
1341 /**
1342  * @tc.name: LockDataTest001
1343  * @tc.desc: Test status after lock
1344  * @tc.type: FUNC
1345  * @tc.require:
1346  * @tc.author: bty
1347  */
1348 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest001, TestSize.Level0)
1349 {
1350     /**
1351      * @tc.steps:step1. init data and lock, hashKey has no matching data
1352      * @tc.expected: step1. return NOT_FOUND.
1353      */
1354     const std::string tableName = "sync_data";
1355     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1356     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1357     EXPECT_NE(db, nullptr);
1358     int count = 10;
1359     InitDataStatus(tableName, count, db);
1360     std::vector<std::vector<uint8_t>> hashKey;
1361     hashKey.push_back({'1'});
1362     EXPECT_EQ(Lock(tableName, hashKey, db), NOT_FOUND);
1363 
1364     /**
1365      * @tc.steps:step2. init data and lock, hashKey has matching data
1366      * @tc.expected: step2. return OK.
1367      */
1368     hashKey.clear();
1369     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1370     EXPECT_EQ(Lock(tableName, hashKey, db), OK);
1371 
1372     /**
1373      * @tc.steps:step3. check status
1374      * @tc.expected: step3. return OK.
1375      */
1376     CheckDataStatus(tableName, " status = 2 and data_key <= 10 ", db, count);
1377     CheckDataStatus(tableName, " status = 3 and data_key <= 20 ", db, count);
1378     CheckDataStatus(tableName, " status = 2 ", db, count + count);
1379     CheckDataStatus(tableName, " status = 3 ", db, count + count);
1380     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1381 }
1382 
1383 /**
1384  * @tc.name: LockDataTest002
1385  * @tc.desc: Test status after unLock
1386  * @tc.type: FUNC
1387  * @tc.require:
1388  * @tc.author: bty
1389  */
1390 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest002, TestSize.Level0)
1391 {
1392     /**
1393      * @tc.steps:step1. init data and unLock, there is data to be compensated for
1394      * @tc.expected: step1. return WAIT_COMPENSATED_SYNC.
1395      */
1396     const std::string tableName = "sync_data";
1397     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1398     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1399     EXPECT_NE(db, nullptr);
1400     int count = 10;
1401     InitDataStatus(tableName, count, db);
1402     std::vector<std::vector<uint8_t>> hashKey;
1403     CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1404     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1405 
1406     /**
1407      * @tc.steps:step2. check status
1408      * @tc.expected: step2. return OK.
1409      */
1410     CheckDataStatus(tableName, " status = 0 and data_key <= 10 ", db, count);
1411     CheckDataStatus(tableName, " status = 1 and data_key <= 20 ", db, count);
1412     CheckDataStatus(tableName, " status = 0 ", db, count + count);
1413     CheckDataStatus(tableName, " status = 1 ", db, count + count);
1414 
1415     /**
1416      * @tc.steps:step3. unLock again, there is data to be compensated for
1417      * @tc.expected: step3. return WAIT_COMPENSATED_SYNC.
1418      */
1419     EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1420 
1421     /**
1422      * @tc.steps:step4. unLock again, there is no data to be compensated for
1423      * @tc.expected: step4. return OK.
1424      */
1425     std::string sql = "update " + DBCommon::GetLogTableName(tableName) + " SET status=0";
1426     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1427     EXPECT_EQ(UnLock(tableName, hashKey, db), OK);
1428 
1429     /**
1430      * @tc.steps:step5. unLock again, hashKey has matching data
1431      * @tc.expected: step5. return NOT_FOUND.
1432      */
1433     hashKey.clear();
1434     hashKey.push_back({'1'});
1435     EXPECT_EQ(UnLock(tableName, hashKey, db), NOT_FOUND);
1436     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1437 }
1438 
1439 /**
1440  * @tc.name: LockDataTest003
1441  * @tc.desc: Test status after local change
1442  * @tc.type: FUNC
1443  * @tc.require:
1444  * @tc.author: bty
1445  */
1446 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest003, TestSize.Level0)
1447 {
1448     /**
1449      * @tc.steps:step1. update data and check
1450      * @tc.expected: step1. return E_OK.
1451      */
1452     const std::string tableName = "sync_data";
1453     PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1454     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1455     EXPECT_NE(db, nullptr);
1456     int count = 10;
1457     InitDataStatus(tableName, count, db);
1458     std::string sql = "update " + tableName + " SET name='1' where id in (1,11,21,31)";
1459     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1460     CheckDataStatus(tableName, " status = 3 and data_key in (1,11,21,31) ", db, 2); // 2 is changed count
1461 
1462     /**
1463      * @tc.steps:step1. delete data and check
1464      * @tc.expected: step1. return E_OK.
1465      */
1466     sql = "delete from " + tableName + " where id in (2,12,22,32)";
1467     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1468     CheckDataStatus(tableName, " status = 1 and data_key = -1 ", db, 3); // 3 is changed count
1469     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1470 }
1471 
1472 DistributedDB::StoreObserver::StoreChangedInfo g_changedData;
1473 
1474 class MockStoreObserver : public StoreObserver {
1475 public:
~MockStoreObserver()1476     virtual ~MockStoreObserver() {};
OnChange(StoreChangedInfo && data)1477     void OnChange(StoreChangedInfo &&data) override
1478     {
1479         g_changedData = data;
1480         std::unique_lock<std::mutex> lock(g_mutex);
1481         g_cv.notify_one();
1482         g_alreadyNotify = true;
1483     };
1484 };
1485 
CreateTableForStoreObserver(sqlite3 * db,const std::string tableName)1486 void CreateTableForStoreObserver(sqlite3 *db, const std::string tableName)
1487 {
1488     std::string sql = "create table " + tableName + "(id INTEGER primary key, name TEXT);";
1489     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1490     sql = "create table no_" + tableName + "(id INTEGER, name TEXT);";
1491     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1492     sql = "create table mult_" + tableName + "(id INTEGER, name TEXT, age int, ";
1493     sql += "PRIMARY KEY (id, name));";
1494     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1495 }
1496 
PrepareDataForStoreObserver(sqlite3 * db,const std::string & tableName,int begin,int dataCounts)1497 void PrepareDataForStoreObserver(sqlite3 *db, const std::string &tableName, int begin, int dataCounts)
1498 {
1499     std::string sql = "begin;";
1500     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1501     for (int i = begin; i < begin + dataCounts; i++) {
1502         sql = "insert into " + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1503             std::to_string(i + 1) + "');";
1504         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1505         sql = "insert into no_" + tableName +" VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1506             std::to_string(i + 1) + "');";
1507         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1508         sql = "insert into mult_" + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan";
1509         sql += std::to_string(i + 1) + "', 18);";
1510         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1511     }
1512     for (int i = begin; i < dataCounts / 2 + begin; i++) { // 2 is half
1513         sql = "update " + tableName + " set name = 'lisi' where id = " + std::to_string(i + 1) + ";";
1514         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1515         sql = "update no_" + tableName + " set name = 'lisi' where _rowid_ = " + std::to_string(i + 1) + ";";
1516         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1517         sql = "update mult_" + tableName + " set age = 20 where id = " + std::to_string(i + 1);
1518         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1519         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1520     }
1521     for (int i = dataCounts / 2 + begin; i < dataCounts + begin; i++) { // 2 is half
1522         sql = "delete from " + tableName + " where id = " + std::to_string(i + 1) + ";";
1523         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1524         sql = "delete from no_" + tableName + " where _rowid_ = " + std::to_string(i + 1) + ";";
1525         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1526         sql = "delete from mult_" + tableName + " where id = " + std::to_string(i + 1);
1527         sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1528         EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1529     }
1530     sql = "commit;";
1531     EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1532 }
1533 
CheckChangedData(int num,int times=0,int offset=0)1534 void CheckChangedData(int num, int times = 0, int offset = 0)
1535 {
1536     if (num == 1) {
1537         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1538             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1539                 static_cast<int64_t>(i + offset - times * 5)); // 5 is rowid times
1540         }
1541         for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1542             EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1543                 static_cast<int64_t>(i + offset + 5)); // 5 is offset
1544         }
1545         return;
1546     }
1547     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1548         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1549             static_cast<int64_t>(i + offset));
1550     }
1551     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_UPDATE].size(); i++) {
1552         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_UPDATE][i - 1][0]),
1553             static_cast<int64_t>(i + offset));
1554     }
1555     for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1556         EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1557             static_cast<int64_t>(i + offset + 5)); // 5 is offset
1558     }
1559 }
1560 
1561 /**
1562  * @tc.name: RegisterStoreObserverTest001
1563  * @tc.desc: Test commit for three table then trigger store observer
1564  * @tc.type: FUNC
1565  * @tc.require:
1566  * @tc.author: chenchaohao
1567  */
1568 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest001, TestSize.Level1)
1569 {
1570     /**
1571      * @tc.steps:step1. prepare db and create table.
1572      * @tc.expected: step1. return ok.
1573      */
1574     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1575     EXPECT_NE(db, nullptr);
1576     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1577     std::string tableName = "primary_test";
1578     CreateTableForStoreObserver(db, tableName);
1579 
1580     /**
1581     * @tc.steps:step2. register store observer and check onchange.
1582     * @tc.expected: step2. return ok.
1583     */
1584     auto storeObserver = std::make_shared<MockStoreObserver>();
1585     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1586     RegisterDbHook(db);
1587     EXPECT_TRUE(g_changedData.empty());
1588     int dataCounts = 10; // 10 is count of insert options.
1589     int begin = 0;
1590     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1591     {
1592         std::unique_lock<std::mutex> lock(g_mutex);
__anona8aa9dd31702() 1593         g_cv.wait(lock, []() {
1594             return g_alreadyNotify;
1595         });
1596         g_alreadyNotify = false;
1597     }
1598     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1599     CheckChangedData(0);
1600     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1601     CheckChangedData(1);
1602     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1603     CheckChangedData(2); // 2 is mult primary table
1604     g_changedData.clear();
1605 
1606     /**
1607     * @tc.steps:step3. unregister store observer and update data check onchange.
1608     * @tc.expected: step3. return ok.
1609     */
1610     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1611     begin = 10; // 10 is begin id
1612     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1613     EXPECT_TRUE(g_changedData.empty());
1614     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1615 }
1616 
1617 /**
1618  * @tc.name: RegisterStoreObserverTest002
1619  * @tc.desc: Test commit for three table then trigger client observer when register then create table
1620  * @tc.type: FUNC
1621  * @tc.require:
1622  * @tc.author: chenchaohao
1623  */
1624 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest002, TestSize.Level1)
1625 {
1626     /**
1627      * @tc.steps:step1. prepare db and register store observer then create table.
1628      * @tc.expected: step1. return ok.
1629      */
1630     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1631     EXPECT_NE(db, nullptr);
1632     auto storeObserver = std::make_shared<MockStoreObserver>();
1633     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1634     RegisterDbHook(db);
1635     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1636     std::string tableName = "primary_test";
1637     CreateTableForStoreObserver(db, tableName);
1638 
1639     /**
1640     * @tc.steps:step2. update data and check onchange.
1641     * @tc.expected: step2. return ok.
1642     */
1643     EXPECT_TRUE(g_changedData.empty());
1644     int dataCounts = 10; // 10 is count of insert options.
1645     int begin = 0;
1646     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1647     WaitAndResetNotify();
1648     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1649     CheckChangedData(0);
1650     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1651     CheckChangedData(1);
1652     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1653     CheckChangedData(2); // 2 is mult primary table
1654     g_changedData.clear();
1655 
1656     /**
1657     * @tc.steps:step3. unregister store observer and update data check onchange.
1658     * @tc.expected: step3. return ok.
1659     */
1660     EXPECT_EQ(UnregisterStoreObserver(db), OK);
1661     begin = 10; // 11 is begin id
1662     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1663     EXPECT_TRUE(g_changedData.empty());
1664     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1665 }
1666 
1667 /**
1668  * @tc.name: RegisterStoreObserverTest003
1669  * @tc.desc: Test commit for three table then trigger client observer when register two observer
1670  * @tc.type: FUNC
1671  * @tc.require:
1672  * @tc.author: chenchaohao
1673  */
1674 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest003, TestSize.Level1)
1675 {
1676     /**
1677      * @tc.steps:step1. prepare db and register store observer then create table.
1678      * @tc.expected: step1. return ok.
1679      */
1680     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1681     EXPECT_NE(db, nullptr);
1682     auto storeObserver1 = std::make_shared<MockStoreObserver>();
1683     auto storeObserver2 = std::make_shared<MockStoreObserver>();
1684     EXPECT_EQ(RegisterStoreObserver(db, storeObserver1), OK);
1685     EXPECT_EQ(RegisterStoreObserver(db, storeObserver2), OK);
1686     RegisterDbHook(db);
1687     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1688     std::string tableName = "primary_test";
1689     CreateTableForStoreObserver(db, tableName);
1690 
1691     /**
1692     * @tc.steps:step2. update data and check onchange.
1693     * @tc.expected: step2. return ok.
1694     */
1695     EXPECT_TRUE(g_changedData.empty());
1696     int dataCounts = 10; // 10 is count of insert options.
1697     int begin = 0;
1698     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1699     WaitAndResetNotify();
1700     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1701     CheckChangedData(0);
1702     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1703     CheckChangedData(1);
1704     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1705     CheckChangedData(2); // 2 is mult primary table
1706     g_changedData.clear();
1707 
1708     /**
1709     * @tc.steps:step3. unregister store observer and update data check onchange.
1710     * @tc.expected: step3. return ok.
1711     */
1712     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver1), OK);
1713     begin = 10; // 11 is begin id
1714     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1715     EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1716     CheckChangedData(0, 1, dataCounts);
1717     EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1718     CheckChangedData(1, 1, dataCounts);
1719     EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1720     CheckChangedData(2, 1, dataCounts); // 2 is mult primary table
1721     g_changedData.clear();
1722 
1723     EXPECT_EQ(UnregisterStoreObserver(db, storeObserver2), OK);
1724     begin = 20; // 21 is begin id
1725     PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1726     EXPECT_TRUE(g_changedData.empty());
1727     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1728 }
1729 
1730 /**
1731  * @tc.name: RegisterStoreObserverTest004
1732  * @tc.desc: Test register two same observer
1733  * @tc.type: FUNC
1734  * @tc.require:
1735  * @tc.author: chenchaohao
1736  */
1737 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest004, TestSize.Level1)
1738 {
1739     /**
1740      * @tc.steps:step1. prepare db and register store observer then create table.
1741      * @tc.expected: step1. return ok.
1742      */
1743     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1744     EXPECT_NE(db, nullptr);
1745     auto storeObserver = std::make_shared<MockStoreObserver>();
1746     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1747     EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1748     EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1749 }
1750 
1751 /**
1752  * @tc.name: AbnormalDelegateImplTest001
1753  * @tc.desc: Test delegateImpl interface after delegate is closed
1754  * @tc.type: FUNC
1755  * @tc.require:
1756  * @tc.author: suyue
1757  */
1758 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest001, TestSize.Level0)
1759 {
1760     /**
1761      * @tc.steps:step1. create db and open store.
1762      * @tc.expected: step1. return ok.
1763      */
1764     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1765     ASSERT_NE(db, nullptr);
1766     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1767     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1768     RelationalStoreDelegate *delegate = nullptr;
1769     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1770     EXPECT_EQ(status, OK);
1771     ASSERT_NE(delegate, nullptr);
1772 
1773     /**
1774      * @tc.steps: step2. close delegate.
1775      * @tc.expected: step2. return ok.
1776      */
1777     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1778     status = delegateImpl->Close();
1779     EXPECT_EQ(status, OK);
1780 
1781     /**
1782      * @tc.steps:step3. test DelegateImpl interface after delegate is closed.
1783      * @tc.expected: step3. return DB_ERROR.
1784      */
1785     const RemoteCondition condition;
1786     std::shared_ptr<ResultSet> result = nullptr;
1787     DBStatus ret = delegateImpl->RemoteQuery("", condition, 0, result);
1788     EXPECT_EQ(ret, DB_ERROR);
1789     EXPECT_EQ(delegateImpl->RemoveDeviceData(), DB_ERROR);
1790 
1791     StoreObserver observer;
1792     EXPECT_EQ(delegateImpl->RegisterObserver(&observer), DB_ERROR);
1793     EXPECT_EQ(delegateImpl->UnRegisterObserver(&observer), DB_ERROR);
1794     DistributedDB::SqlCondition sqlCondition;
1795     std::vector<VBucket> records = {};
1796     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), DB_ERROR);
1797     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), DB_ERROR);
1798     const CloudSyncConfig config;
1799     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), DB_ERROR);
1800 
1801     /**
1802      * @tc.steps:step4. close store.
1803      * @tc.expected: step4. return ok.
1804      */
1805     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1806     delegate = nullptr;
1807 }
1808 
1809 /**
1810  * @tc.name: AbnormalDelegateImplTest002
1811  * @tc.desc: Test delegate interface after delegate is closed
1812  * @tc.type: FUNC
1813  * @tc.require:
1814  * @tc.author: suyue
1815  */
1816 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest002, TestSize.Level0)
1817 {
1818     /**
1819      * @tc.steps:step1. create db and open store.
1820      * @tc.expected: step1. return ok.
1821      */
1822     sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1823     ASSERT_NE(db, nullptr);
1824     EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1825     EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1826     RelationalStoreDelegate *delegate = nullptr;
1827     DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1828     EXPECT_EQ(status, OK);
1829     ASSERT_NE(delegate, nullptr);
1830 
1831     /**
1832      * @tc.steps:step2. test DelegateImpl interface when para is err.
1833      * @tc.expected: step2. return INVALID_ARGS or NOT_FOUND.
1834      */
1835     auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1836     const CloudSyncConfig config;
1837     EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), OK);
1838     DistributedDB::SqlCondition sqlCondition;
1839     std::vector<VBucket> records = {};
1840     EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), INVALID_ARGS);
1841     EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), INVALID_ARGS);
1842     EXPECT_EQ(delegateImpl->CleanTrackerData("", 0), INVALID_ARGS);
1843     TrackerSchema schema;
1844     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), INVALID_ARGS);
1845     schema = {.tableName = "test", .extendColNames = {}, .trackerColNames = {}};
1846     EXPECT_EQ(delegateImpl->SetTrackerTable(schema), NOT_FOUND);
1847 
1848     /**
1849      * @tc.steps:step3. close store.
1850      * @tc.expected: step3. return ok.
1851      */
1852     EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1853     delegate = nullptr;
1854 }
1855 }
1856