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(triggerTableData_.begin()->second.isCloudSyncDataChange, properties.isCloudSyncDataChange);
89 EXPECT_EQ(triggeredCount_, triggerCount);
90 }
91
WaitAndResetNotify()92 void WaitAndResetNotify()
93 {
94 std::unique_lock<std::mutex> lock(g_mutex);
95 WaitAndResetNotifyWithLock(lock);
96 }
97
WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> & lock)98 void WaitAndResetNotifyWithLock(std::unique_lock<std::mutex> &lock)
99 {
100 g_cv.wait(lock, []() {
101 return g_alreadyNotify;
102 });
103 g_alreadyNotify = false;
104 }
105
106 std::set<std::string> triggerTableNames_;
107 std::map<std::string, ChangeProperties> triggerTableData_;
108 int triggeredCount_ = 0;
109 int triggeredCount2_ = 0;
110 };
111
SetUpTestCase(void)112 void DistributedDBCloudInterfacesRelationalExtTest::SetUpTestCase(void)
113 {
114 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
115 LOGD("Test dir is %s", g_testDir.c_str());
116 g_dbDir = g_testDir + "/";
117 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
118 }
119
TearDownTestCase(void)120 void DistributedDBCloudInterfacesRelationalExtTest::TearDownTestCase(void)
121 {
122 }
123
SetUp()124 void DistributedDBCloudInterfacesRelationalExtTest::SetUp()
125 {
126 }
127
TearDown()128 void DistributedDBCloudInterfacesRelationalExtTest::TearDown()
129 {
130 g_alreadyNotify = false;
131 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
132 }
133
CheckTriggerObserverTest002(const std::string & tableName,std::atomic<int> & count)134 void DistributedDBCloudInterfacesRelationalExtTest::CheckTriggerObserverTest002(const std::string &tableName,
135 std::atomic<int> &count)
136 {
137 count++;
138 ASSERT_EQ(triggerTableData_.size(), 1u);
139 EXPECT_EQ(triggerTableData_.begin()->first, tableName);
140 EXPECT_EQ(triggerTableData_.begin()->second.isTrackedDataChange, false);
141 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
142 EXPECT_EQ(triggeredCount_, count);
143 }
144
GetCurrentSysTimeIn100Ns(uint64_t & outTime)145 static int GetCurrentSysTimeIn100Ns(uint64_t &outTime)
146 {
147 struct timeval rawTime;
148 int errCode = gettimeofday(&rawTime, nullptr);
149 if (errCode < 0) {
150 return -E_ERROR;
151 }
152 outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
153 static_cast<uint64_t>(rawTime.tv_usec);
154 outTime *= TO_100_NS;
155 return E_OK;
156 }
157
SetTracerSchemaTest001(const std::string & tableName)158 static void SetTracerSchemaTest001(const std::string &tableName)
159 {
160 TrackerSchema schema;
161 schema.tableName = tableName;
162 schema.extendColNames = {"id"};
163 schema.trackerColNames = {"name"};
164 RelationalStoreDelegate *delegate = nullptr;
165 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
166 EXPECT_EQ(status, OK);
167 ASSERT_NE(delegate, nullptr);
168 EXPECT_EQ(delegate->SetTrackerTable(schema), OK);
169 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
170 }
171
ExecSqlAndWaitForObserver(sqlite3 * db,const std::string & sql,std::unique_lock<std::mutex> & lock)172 static void ExecSqlAndWaitForObserver(sqlite3 *db, const std::string &sql, std::unique_lock<std::mutex> &lock)
173 {
174 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
175 g_cv.wait(lock, []() {
176 return g_alreadyNotify;
177 });
178 g_alreadyNotify = false;
179 }
180
181 /**
182 * @tc.name: GetRawSysTimeTest001
183 * @tc.desc: Test get_raw_sys_time has been registered in sqlite
184 * @tc.type: FUNC
185 * @tc.require:
186 * @tc.author: zhangshijie
187 */
188 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, GetRawSysTimeTest001, TestSize.Level0)
189 {
190 const std::string sql = "select get_raw_sys_time();";
191 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
192 EXPECT_NE(db, nullptr);
193 uint64_t curTime = 0;
194 int errCode = GetCurrentSysTimeIn100Ns(curTime);
195 EXPECT_EQ(errCode, E_OK);
__anonf66911750402(sqlite3_stmt *stmt) 196 errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime] (sqlite3_stmt *stmt) {
197 EXPECT_GT(static_cast<uint64_t>(sqlite3_column_int64(stmt, 0)), curTime);
198 return E_OK;
199 });
200 EXPECT_EQ(errCode, SQLITE_OK);
201 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
202 }
203
PrepareData(const std::vector<std::string> & tableNames,bool primaryKeyIsRowId,DistributedDB::TableSyncType tableSyncType,bool userDefineRowid=true,bool createDistributeTable=true)204 void PrepareData(const std::vector<std::string> &tableNames, bool primaryKeyIsRowId,
205 DistributedDB::TableSyncType tableSyncType, bool userDefineRowid = true, bool createDistributeTable = true)
206 {
207 /**
208 * @tc.steps:step1. create db, create table.
209 * @tc.expected: step1. return ok.
210 */
211 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
212 EXPECT_NE(db, nullptr);
213 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
214 std::string sql;
215 for (const auto &tableName : tableNames) {
216 if (primaryKeyIsRowId) {
217 sql = "create table " + tableName + "(rowid INTEGER primary key, id int, name TEXT);";
218 } else {
219 if (userDefineRowid) {
220 sql = "create table " + tableName + "(rowid int, id int, name TEXT, PRIMARY KEY(id));";
221 } else {
222 sql = "create table " + tableName + "(id int, name TEXT, PRIMARY KEY(id));";
223 }
224 }
225 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
226 }
227 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
228
229 /**
230 * @tc.steps:step2. create distributed table.
231 * @tc.expected: step2. return ok.
232 */
233 RelationalStoreDelegate *delegate = nullptr;
234 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
235 EXPECT_EQ(status, OK);
236 ASSERT_NE(delegate, nullptr);
237 if (createDistributeTable) {
238 for (const auto &tableName : tableNames) {
239 EXPECT_EQ(delegate->CreateDistributedTable(tableName, tableSyncType), OK);
240 }
241 }
242 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
243 delegate = nullptr;
244 }
245
InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)246 void InsertTriggerTest(DistributedDB::TableSyncType tableSyncType)
247 {
248 /**
249 * @tc.steps:step1. prepare data.
250 * @tc.expected: step1. return ok.
251 */
252 const std::string tableName = "sync_data";
253 PrepareData({tableName}, false, tableSyncType);
254
255 /**
256 * @tc.steps:step2. insert data into sync_data.
257 * @tc.expected: step2. return ok.
258 */
259 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
260 EXPECT_NE(db, nullptr);
261 std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
262 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
263
264 /**
265 * @tc.steps:step3. select data from log table.
266 * @tc.expected: step3. return ok.
267 */
268 sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
269 uint64_t curTime = 0;
270 int errCode = GetCurrentSysTimeIn100Ns(curTime);
271 EXPECT_EQ(errCode, E_OK);
272
273 int resultCount = 0;
274 errCode = RelationalTestUtils::ExecSql(db, sql, nullptr,
275 [tableSyncType, curTime, &resultCount] (sqlite3_stmt *stmt) {
276 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
277 std::string device = "";
278 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
279 EXPECT_EQ(device, "");
280 std::string oriDevice = "";
281 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
282 EXPECT_EQ(oriDevice, "");
283
284 int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
285 int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
286 int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
287 EXPECT_TRUE(wtimestamp - timestamp < diff);
288 EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
289 if (tableSyncType == DistributedDB::CLOUD_COOPERATION) {
290 EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index flag == 0x02|0x20
291 } else {
292 EXPECT_EQ(sqlite3_column_int(stmt, 5), 2); // 5 is column index flag == 2
293 }
294 resultCount++;
295 return E_OK;
296 });
297 EXPECT_EQ(errCode, SQLITE_OK);
298 EXPECT_EQ(resultCount, 1);
299 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
300 }
301
302 /**
303 * @tc.name: InsertTriggerTest001
304 * @tc.desc: Test insert trigger in sqlite in CLOUD_COOPERATION mode
305 * @tc.type: FUNC
306 * @tc.require:
307 * @tc.author: zhangshijie
308 */
309 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest001, TestSize.Level0)
310 {
311 InsertTriggerTest(DistributedDB::CLOUD_COOPERATION);
312 }
313
314 /**
315 * @tc.name: InsertTriggerTest002
316 * @tc.desc: Test insert trigger in sqlite in DEVICE_COOPERATION mode
317 * @tc.type: FUNC
318 * @tc.require:
319 * @tc.author: zhangshijie
320 */
321 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest002, TestSize.Level0)
322 {
323 InsertTriggerTest(DistributedDB::DEVICE_COOPERATION);
324 }
325
326 /**
327 * @tc.name: InsertTriggerTest003
328 * @tc.desc: Test insert trigger in sqlite when use "insert or replace"
329 * @tc.type: FUNC
330 * @tc.require:
331 * @tc.author: zhangshijie
332 */
333 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, InsertTriggerTest003, TestSize.Level1)
334 {
335 /**
336 * @tc.steps:step1. prepare data.
337 * @tc.expected: step1. return ok.
338 */
339 const std::string tableName = "sync_data";
340 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION);
341
342 /**
343 * @tc.steps:step2. insert data into sync_data.
344 * @tc.expected: step2. return ok.
345 */
346 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
347 EXPECT_NE(db, nullptr);
348 std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan1');";
349 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
350
351 // update cloud_gid in log table
352 std::string gid = "test_gid";
353 sql = "update " + DBCommon::GetLogTableName(tableName) + " set cloud_gid = '" + gid + "'";
354 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
355 // use insert or replace to update data
356 sql = "insert or replace into " + tableName + " VALUES(3, 1, 'zhangsan1');";
357 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
358
359 /**
360 * @tc.steps:step3. select data from log table.
361 * @tc.expected: step3. return ok.
362 */
363 sql = "select data_key, device, ori_device, flag, cloud_gid from " + DBCommon::GetLogTableName(tableName);
364 int resultCount = 0;
__anonf66911750602(sqlite3_stmt *stmt) 365 int errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [&resultCount, gid] (sqlite3_stmt *stmt) {
366 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
367 std::string device = "";
368 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
369 EXPECT_EQ(device, "");
370 std::string oriDevice = "";
371 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
372 EXPECT_EQ(oriDevice, "");
373
374 EXPECT_EQ(sqlite3_column_int(stmt, 3), 0x02|0x20); // 3 is column index flag == 0x02|0x20
375 std::string gidStr;
376 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 4, gidStr), E_OK); // 4 is column index
377 EXPECT_EQ(gid, gidStr);
378 resultCount++;
379 return E_OK;
380 });
381 EXPECT_EQ(errCode, SQLITE_OK);
382 EXPECT_EQ(resultCount, 1);
383 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
384 }
385
UpdateTriggerTest(bool primaryKeyIsRowId)386 void UpdateTriggerTest(bool primaryKeyIsRowId)
387 {
388 /**
389 * @tc.steps:step1. prepare data.
390 * @tc.expected: step1. return ok.
391 */
392 const std::string tableName = "sync_data";
393 PrepareData({tableName}, primaryKeyIsRowId, DistributedDB::CLOUD_COOPERATION);
394
395 /**
396 * @tc.steps:step2. insert data into sync_data_tmp.
397 * @tc.expected: step2. return ok.
398 */
399 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
400 EXPECT_NE(db, nullptr);
401 std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
402 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
403
404 /**
405 * @tc.steps:step3. update data.
406 * @tc.expected: step3. return ok.
407 */
408 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
409 sql = "update " + tableName + " set name = 'lisi';";
410 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
411
412 /**
413 * @tc.steps:step4. select data from log table.
414 * @tc.expected: step4. return ok.
415 */
416 sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
417 uint64_t curTime = 0;
418 int errCode = GetCurrentSysTimeIn100Ns(curTime);
419 EXPECT_EQ(errCode, E_OK);
420
421 int resultCount = 0;
422 errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount, primaryKeyIsRowId] (
423 sqlite3_stmt *stmt) {
424 if (primaryKeyIsRowId) {
425 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 2); // 2 is row id
426 } else {
427 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1); // 1 is row id
428 }
429
430 EXPECT_EQ(sqlite3_column_int(stmt, 5), 0x02|0x20); // 5 is column index, flag == 0x02|0x20
431
432 std::string device = "";
433 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
434 EXPECT_EQ(device, "");
435 std::string oriDevice = "";
436 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
437 EXPECT_EQ(oriDevice, "");
438
439 int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
440 int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
441 int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
442 EXPECT_TRUE(timestamp - wtimestamp > diff);
443 EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
444
445 resultCount++;
446 return E_OK;
447 });
448 EXPECT_EQ(errCode, SQLITE_OK);
449 EXPECT_EQ(resultCount, 1);
450 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
451 }
452
453 /**
454 * @tc.name: UpdateTriggerTest001
455 * @tc.desc: Test update trigger in sqlite for primary key is not row id
456 * @tc.type: FUNC
457 * @tc.require:
458 * @tc.author: zhangshijie
459 */
460 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest001, TestSize.Level1)
461 {
462 UpdateTriggerTest(false);
463 }
464
465 /**
466 * @tc.name: UpdateTriggerTest002
467 * @tc.desc: Test update trigger in sqlite for primary key is row id
468 * @tc.type: FUNC
469 * @tc.require:
470 * @tc.author: zhangshijie
471 */
472 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, UpdateTriggerTest002, TestSize.Level1)
473 {
474 UpdateTriggerTest(true);
475 }
476
477 /**
478 * @tc.name: DeleteTriggerTest001
479 * @tc.desc: Test delete trigger in sqlite
480 * @tc.type: FUNC
481 * @tc.require:
482 * @tc.author: zhangshijie
483 */
484 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DeleteTriggerTest001, TestSize.Level1)
485 {
486 /**
487 * @tc.steps:step1. prepare data.
488 * @tc.expected: step1. return ok.
489 */
490 const std::string tableName = "sync_data";
491 PrepareData({tableName}, true, DistributedDB::CLOUD_COOPERATION);
492
493 /**
494 * @tc.steps:step2. insert data into sync_data.
495 * @tc.expected: step2. return ok.
496 */
497 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
498 EXPECT_NE(db, nullptr);
499 std::string sql = "insert into " + tableName + " VALUES(2, 1, 'zhangsan');";
500 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
501
502 /**
503 * @tc.steps:step3. delete data.
504 * @tc.expected: step3. return ok.
505 */
506 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
507 sql = "delete from " + tableName + " where name = 'zhangsan';";
508 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
509
510 /**
511 * @tc.steps:step4. select data from log table.
512 * @tc.expected: step4. return ok.
513 */
514 sql = "select * from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log;";
515 uint64_t curTime = 0;
516 int errCode = GetCurrentSysTimeIn100Ns(curTime);
517 EXPECT_EQ(errCode, E_OK);
518
519 int resultCount = 0;
__anonf66911750802(sqlite3_stmt *stmt) 520 errCode = RelationalTestUtils::ExecSql(db, sql, nullptr, [curTime, &resultCount] (sqlite3_stmt *stmt) {
521 EXPECT_EQ(sqlite3_column_int64(stmt, 0), -1);
522 EXPECT_EQ(sqlite3_column_int(stmt, 5), 3); // 5 is column index, flag == 3
523
524 std::string device = "de";
525 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, device), E_OK);
526 EXPECT_EQ(device, "");
527 std::string oriDevice = "de";
528 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 2, oriDevice), E_OK); // 2 is column index
529 EXPECT_EQ(oriDevice, "");
530
531 int64_t timestamp = sqlite3_column_int64(stmt, 3); // 3 is column index
532 int64_t wtimestamp = sqlite3_column_int64(stmt, 4); // 4 is column index
533 int64_t diff = MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS * TO_100_NS;
534 EXPECT_TRUE(timestamp - wtimestamp > diff);
535 EXPECT_TRUE(static_cast<int64_t>(curTime - timestamp) < diff);
536
537 resultCount++;
538 return E_OK;
539 });
540 EXPECT_EQ(errCode, SQLITE_OK);
541 EXPECT_EQ(resultCount, 1);
542 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
543 }
544
545 /**
546 * @tc.name: TriggerObserverTest001
547 * @tc.desc: Test invalid args for RegisterClientObserver and UnRegisterClientObserver
548 * @tc.type: FUNC
549 * @tc.require:
550 * @tc.author: zhangshijie
551 */
552 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest001, TestSize.Level0)
553 {
554 /**
555 * @tc.steps:step1. call RegisterClientObserver and UnRegisterClientObserver with db = nullptr.
556 * @tc.expected: step1. return INVALID_ARGS.
557 */
558 ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
559 this, std::placeholders::_1);
560 EXPECT_EQ(RegisterClientObserver(nullptr, clientObserver), INVALID_ARGS);
561 EXPECT_EQ(UnRegisterClientObserver(nullptr), INVALID_ARGS);
562
563 /**
564 * @tc.steps:step2. call RegisterClientObserver with nullptr clientObserver.
565 * @tc.expected: step2. return INVALID_ARGS.
566 */
567 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
568 EXPECT_NE(db, nullptr);
569 EXPECT_EQ(RegisterClientObserver(db, nullptr), INVALID_ARGS);
570
571 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
572 }
573
574 /**
575 * @tc.name: TriggerObserverTest002
576 * @tc.desc: Test trigger client observer in sqlite
577 * @tc.type: FUNC
578 * @tc.require:
579 * @tc.author: zhangshijie
580 */
581 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest002, TestSize.Level0)
582 {
583 /**
584 * @tc.steps:step1. prepare data.
585 * @tc.expected: step1. return ok.
586 */
587 const std::string tableName = "sync_data";
588 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
589
590 /**
591 * @tc.steps:step2. register client observer.
592 * @tc.expected: step2. return ok.
593 */
594 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
595 EXPECT_NE(db, nullptr);
596 ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
597 this, std::placeholders::_1);
598 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
599 RegisterDbHook(db);
600
601 /**
602 * @tc.steps:step3. insert data into sync_data, check observer.
603 * @tc.expected: step3. check observer ok.
604 */
605 std::string sql = "insert into " + tableName + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
606 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
607 WaitAndResetNotify();
608 std::atomic<int> count = 0; // 0 is observer triggered counts
609 CheckTriggerObserverTest002(tableName, count);
610
611 /**
612 * @tc.steps:step4. update data, check observer.
613 * @tc.expected: step4. check observer ok.
614 */
615 sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
616 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
617 WaitAndResetNotify();
618 CheckTriggerObserverTest002(tableName, count);
619
620 /**
621 * @tc.steps:step4. delete data, check observer.
622 * @tc.expected: step4. check observer ok.
623 */
624 sql = "delete from " + tableName + " where id = 3;";
625 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
626 WaitAndResetNotify();
627 CheckTriggerObserverTest002(tableName, count);
628
629 /**
630 * @tc.steps:step5. register another observer, update data, check observer.
631 * @tc.expected: step5. check observer ok.
632 */
633 triggeredCount_ = 0;
634 ClientObserver clientObserver2 = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2,
635 this, std::placeholders::_1);
636 EXPECT_EQ(RegisterClientObserver(db, clientObserver2), OK);
637 RegisterDbHook(db);
638 sql = "update " + tableName + " set name = 'lisi2' where id = 2;";
639 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
640 WaitAndResetNotify();
641 EXPECT_EQ(triggeredCount_, 0);
642 EXPECT_EQ(triggeredCount2_, 1);
643
644 /**
645 * @tc.steps:step6. UnRegisterClientObserver, update data, check observer.
646 * @tc.expected: step6. check observer ok.
647 */
648 triggeredCount2_ = 0;
649 EXPECT_EQ(UnRegisterClientObserver(db), OK);
650 sql = "update " + tableName + " set name = 'lisi3' where id = 2;";
651 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
652 EXPECT_EQ(triggeredCount2_, 0); // observer2 will not be triggered
653 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
654 }
655
656 /**
657 * @tc.name: TriggerObserverTest003
658 * @tc.desc: Test RegisterClientObserver and UnRegisterClientObserver concurrently
659 * @tc.type: FUNC
660 * @tc.require:
661 * @tc.author: zhangshijie
662 */
663 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest003, TestSize.Level1)
664 {
665 for (int i = 0; i < 1000; i++) { // 1000 is loop times
__anonf66911750902() 666 std::thread t1 ([this]() {
667 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
668 EXPECT_NE(db, nullptr);
669 ClientObserver clientObserver = std::bind(
670 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc, this, std::placeholders::_1);
671 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
672 EXPECT_EQ(UnRegisterClientObserver(db), OK);
673 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
674 });
675
__anonf66911750a02() 676 std::thread t2 ([this]() {
677 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
678 EXPECT_NE(db, nullptr);
679 ClientObserver clientObserver = std::bind(
680 &DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc2, this, std::placeholders::_1);
681 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
682 EXPECT_EQ(UnRegisterClientObserver(db), OK);
683 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
684 });
685
686 t1.join();
687 t2.join();
688 }
689 }
690
691 /**
692 * @tc.name: TriggerObserverTest004
693 * @tc.desc: Test batch insert/update/delete data then trigger client observer
694 * @tc.type: FUNC
695 * @tc.require:
696 * @tc.author: zhangshijie
697 */
698 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest004, TestSize.Level1)
699 {
700 /**
701 * @tc.steps:step1. prepare data.
702 * @tc.expected: step1. return ok.
703 */
704 const std::string tableName = "sync_data";
705 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
706
707 /**
708 * @tc.steps:step2. register client observer.
709 * @tc.expected: step2. return ok.
710 */
711 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
712 EXPECT_NE(db, nullptr);
713 ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
714 this, std::placeholders::_1);
715 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
716 RegisterDbHook(db);
717
718 /**
719 * @tc.steps:step3. insert data into sync_data, check observer.
720 * @tc.expected: step3. check observer ok.
721 */
722 std::string sql;
723 int dataCounts = 1000; // 1000 is count of insert options.
724 for (int i = 1; i <= dataCounts; i++) {
725 sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
726 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
727 }
728 std::unique_lock<std::mutex> lock(g_mutex);
__anonf66911750b02() 729 bool isEqual = g_cv.wait_for(lock, std::chrono::seconds(1), [this, dataCounts]() { // 1 is wait time
730 return triggeredCount_ == dataCounts;
731 });
732 EXPECT_EQ(isEqual, true);
733 WaitAndResetNotifyWithLock(lock);
734 ASSERT_EQ(triggerTableData_.size(), 1u);
735 EXPECT_EQ(triggerTableData_.begin()->first, tableName);
736 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
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);
__anonf66911750c02() 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 RegisterDbHook(db);
782
783 /**
784 * @tc.steps:step3. begin transaction and commit.
785 * @tc.expected: step3. check observer ok.
786 */
787 std::string sql = "begin;";
788 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
789 int dataCounts = 1000; // 1000 is count of insert options.
790 for (int i = 1; i <= dataCounts; i++) {
791 sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
792 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
793 }
794 sql = "commit;";
795 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
796 WaitAndResetNotify();
797 ASSERT_EQ(triggerTableData_.size(), 1u);
798 EXPECT_EQ(triggerTableData_.begin()->first, tableName);
799 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
800 EXPECT_EQ(triggeredCount_, 1);
801
802 /**
803 * @tc.steps:step4. begin transaction and rollback.
804 * @tc.expected: step3. check observer ok.
805 */
806 triggerTableData_.clear();
807 triggeredCount_ = 0;
808 sql = "begin;";
809 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
810 for (int i = dataCounts + 1; i <= 2 * dataCounts; i++) { // 2 is double dataCounts
811 sql = "insert into " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" + std::to_string(i) + "');";
812 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
813 }
814 sql = "rollback;";
815 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
816 EXPECT_TRUE(triggerTableData_.empty());
817 EXPECT_EQ(triggeredCount_, 0);
818
819 /**
820 * @tc.steps:step5. insert or replace, check observer.
821 * @tc.expected: step5. check observer ok.
822 */
823 triggeredCount_ = 0;
824 sql = "insert or replace into " + tableName + " VALUES(1000, 'lisi');";
825 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
826 WaitAndResetNotify();
827 EXPECT_EQ(triggeredCount_, 1); // 1 is trigger times, first delete then insert
828 EXPECT_EQ(UnRegisterClientObserver(db), OK);
829 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
830 }
831
832 /**
833 * @tc.name: TriggerObserverTest006
834 * @tc.desc: Test commit and rollback for multi-table then trigger client observer
835 * @tc.type: FUNC
836 * @tc.require:
837 * @tc.author: chenchaohao
838 */
839 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest006, TestSize.Level1)
840 {
841 /**
842 * @tc.steps:step1. prepare data.
843 * @tc.expected: step1. return ok.
844 */
845 const std::string tableName1 = "sync_data1";
846 const std::string tableName2 = "sync_data2";
847 PrepareData({tableName1, tableName2}, false, DistributedDB::CLOUD_COOPERATION, false);
848
849 /**
850 * @tc.steps:step2. register client observer.
851 * @tc.expected: step2. return ok.
852 */
853 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
854 EXPECT_NE(db, nullptr);
855 ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
856 this, std::placeholders::_1);
857 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
858 RegisterDbHook(db);
859
860 /**
861 * @tc.steps:step3. begin transaction and commit.
862 * @tc.expected: step3. check observer ok.
863 */
864 std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
865 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
866 WaitAndResetNotify();
867 ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
868 EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
869 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
870 EXPECT_EQ(triggeredCount_, 1); // 1 is trigger count
871
872 /**
873 * @tc.steps:step4. UnRegisterClientObserver and insert table2.
874 * @tc.expected: step3. check observer ok.
875 */
876 triggerTableData_.clear();
877 triggeredCount_ = 0;
878 EXPECT_EQ(UnRegisterClientObserver(db), OK);
879 sql = "insert into " + tableName2 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
880 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
881 EXPECT_TRUE(triggerTableData_.empty());
882 EXPECT_EQ(triggeredCount_, 0);
883
884 /**
885 * @tc.steps:step5. RegisterClientObserver again and insert table1, check observer.
886 * @tc.expected: step5. check observer ok.
887 */
888 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
889 RegisterDbHook(db);
890 sql = "insert into " + tableName1 + " VALUES(7, 'zhangjiu');";
891 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
892 WaitAndResetNotify();
893 ASSERT_EQ(triggerTableData_.size(), 1u); // 1 is table size
894 EXPECT_EQ(triggerTableData_.begin()->first, tableName1);
895 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
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 properties.isCloudSyncDataChange = false;
939 int triggerCount = 1;
940 CheckTriggerTableData(1u, tableName, properties, triggerCount);
941
942 /**
943 * @tc.steps:step4. update data, check observer.
944 * @tc.expected: step4. check observer ok.
945 */
946 sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
947 ExecSqlAndWaitForObserver(db, sql, lock);
948 CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
949
950 /**
951 * @tc.steps:step5. update to the same data again, check observer.
952 * @tc.expected: step5. check observer ok.
953 */
954 sql = "update " + tableName + " set name = 'lisi1' where id = 2;";
955 ExecSqlAndWaitForObserver(db, sql, lock);
956 properties.isTrackedDataChange = false;
957 CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
958
959 /**
960 * @tc.steps:step6. update to the same data again, set name is NULL, check observer.
961 * @tc.expected: step6. check observer ok.
962 */
963 sql = "update " + tableName + " set name = NULL where id = 2;";
964 ExecSqlAndWaitForObserver(db, sql, lock);
965 properties.isTrackedDataChange = true;
966 CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
967
968 /**
969 * @tc.steps:step7. update to the same data again, set name is empty, check observer.
970 * @tc.expected: step7. check observer ok.
971 */
972 sql = "update " + tableName + " set name = '' where id = 2;";
973 ExecSqlAndWaitForObserver(db, sql, lock);
974 CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
975
976 /**
977 * @tc.steps:step8. delete data, check observer.
978 * @tc.expected: step8. check observer ok.
979 */
980 sql = "delete from " + tableName + " where id = 2;";
981 ExecSqlAndWaitForObserver(db, sql, lock);
982 CheckTriggerTableData(1u, tableName, properties, ++triggerCount);
983 EXPECT_EQ(UnRegisterClientObserver(db), OK);
984 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
985 }
986
987 /**
988 * @tc.name: TriggerObserverTest008
989 * @tc.desc: Test trigger client observer
990 * @tc.type: FUNC
991 * @tc.require:
992 * @tc.author: liaoyonghuang
993 */
994 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, TriggerObserverTest008, TestSize.Level0)
995 {
996 /**
997 * @tc.steps:step1. prepare data
998 * @tc.expected: step1. return ok.
999 */
1000 const std::string tableName1 = "table1";
1001 PrepareData({tableName1}, false, DistributedDB::CLOUD_COOPERATION, false, true);
1002 const std::string tableName2 = "table2";
1003 PrepareData({tableName2}, false, DistributedDB::CLOUD_COOPERATION, false, true);
1004
1005 /**
1006 * @tc.steps:step2. register client observer.
1007 * @tc.expected: step2. return ok.
1008 */
1009 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1010 EXPECT_NE(db, nullptr);
1011 ClientObserver clientObserver = std::bind(&DistributedDBCloudInterfacesRelationalExtTest::ClientObserverFunc,
1012 this, std::placeholders::_1);
1013 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
1014
1015 /**
1016 * @tc.steps:step3. insert data into sync_data, check observer.
1017 * @tc.expected: step3. check observer ok.
1018 */
1019 std::string sql = "insert into " + tableName1 + " VALUES(1, 'zhangsan'), (2, 'lisi'), (3, 'wangwu');";
1020 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1021 EXPECT_EQ(triggerTableData_.size(), 0u);
1022
1023 /**
1024 * @tc.steps:step4. re-register client observer and register hook
1025 * @tc.expected: step4. return ok.
1026 */
1027 EXPECT_EQ(UnRegisterClientObserver(db), OK);
1028 EXPECT_EQ(RegisterClientObserver(db, clientObserver), OK);
1029 RegisterDbHook(db);
1030
1031 /**
1032 * @tc.steps:step5. insert data into sync_data, check observer.
1033 * @tc.expected: step5. check observer ok.
1034 */
1035 sql = "insert into " + tableName2 + " VALUES(4, 'aaa');";
1036 std::unique_lock<std::mutex> lock(g_mutex);
1037 ExecSqlAndWaitForObserver(db, sql, lock);
1038 EXPECT_EQ(triggerTableData_.size(), 1u);
1039 EXPECT_TRUE(triggerTableData_.begin()->second.isCloudSyncDataChange);
1040 EXPECT_EQ(UnRegisterClientObserver(db), OK);
1041 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1042 }
1043
InitLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t num)1044 void InitLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t num)
1045 {
1046 for (size_t i = 0; i < num; ++i) {
1047 std::string sql = "insert or replace into " + tableName + " VALUES('" + std::to_string(i) + "', 'zhangsan');";
1048 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1049 }
1050 std::string sql = "update " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log" +
1051 " SET flag = flag | 0x08";
1052 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1053 }
1054
CheckLogicDeleteData(sqlite3 * & db,const std::string & tableName,uint64_t expectNum)1055 void CheckLogicDeleteData(sqlite3 *&db, const std::string &tableName, uint64_t expectNum)
1056 {
1057 std::string sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + tableName + "_log"
1058 " where flag&0x08=0x08 and flag&0x01=0";
1059 sqlite3_stmt *stmt = nullptr;
1060 EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1061 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1062 uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1063 EXPECT_EQ(count, expectNum);
1064 }
1065 int errCode;
1066 SQLiteUtils::ResetStatement(stmt, true, errCode);
1067 stmt = nullptr;
1068 sql = "select count(*) from " + tableName;
1069 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1070 uint64_t count = static_cast<uint64_t>(sqlite3_column_int64(stmt, 0));
1071 EXPECT_EQ(count, expectNum);
1072 }
1073 SQLiteUtils::ResetStatement(stmt, true, errCode);
1074 }
1075
1076 /**
1077 * @tc.name: DropDeleteData001
1078 * @tc.desc: Test trigger client observer in tracker table
1079 * @tc.type: FUNC
1080 * @tc.require:
1081 * @tc.author:
1082 */
1083 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, DropDeleteData001, TestSize.Level0)
1084 {
1085 /**
1086 * @tc.steps:step1. prepare data.
1087 * @tc.expected: step1. return ok.
1088 */
1089 const std::string tableName = "sync_data";
1090 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1091 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1092 EXPECT_NE(db, nullptr);
1093 uint64_t num = 10;
1094 InitLogicDeleteData(db, tableName, num);
1095
1096 /**
1097 * @tc.steps:step2. db handle is nullptr
1098 * @tc.expected: step2. return INVALID_ARGS.
1099 */
1100 EXPECT_EQ(DropLogicDeletedData(nullptr, tableName, 0u), INVALID_ARGS);
1101
1102 /**
1103 * @tc.steps:step3. tableName is empty
1104 * @tc.expected: step3. return INVALID_ARGS.
1105 */
1106 EXPECT_EQ(DropLogicDeletedData(db, "", 0u), INVALID_ARGS);
1107
1108 /**
1109 * @tc.steps:step4. tableName is no exist
1110 * @tc.expected: step4. return INVALID_ARGS.
1111 */
1112 EXPECT_EQ(DropLogicDeletedData(db, tableName + "_", 0u), DB_ERROR);
1113
1114 /**
1115 * @tc.steps:step5. cursor is 0
1116 * @tc.expected: step5. return OK.
1117 */
1118 EXPECT_EQ(DropLogicDeletedData(db, tableName, 0u), OK);
1119 CheckLogicDeleteData(db, tableName, 0u);
1120
1121 /**
1122 * @tc.steps:step6. init data again, and cursor is 15
1123 * @tc.expected: step6. return OK.
1124 */
1125 uint64_t cursor = 15;
1126 InitLogicDeleteData(db, tableName, num);
1127 EXPECT_EQ(DropLogicDeletedData(db, tableName, cursor), OK);
1128 CheckLogicDeleteData(db, tableName, cursor - num);
1129 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1130 }
1131
1132 /**
1133 * @tc.name: FfrtTest001
1134 * @tc.desc: Test ffrt concurrency
1135 * @tc.type: FUNC
1136 * @tc.require:
1137 * @tc.author:
1138 */
1139 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest001, TestSize.Level1)
1140 {
1141 std::map<int, int> ans;
1142 #ifdef USE_FFRT
1143 ffrt::mutex mutex;
1144 #else
1145 std::mutex mutex;
1146 #endif
1147 size_t num = 1000;
1148
1149 /**
1150 * @tc.steps:step1. submit insert map task
1151 * @tc.expected: step1. return ok.
1152 */
__anonf66911750d02() 1153 TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1154 for (size_t j = 0; j < num; j++) {
1155 ConcurrentAdapter::AdapterAutoLock(mutex);
1156 for (size_t i = 0; i < num; i++) {
1157 ans.insert_or_assign(i, i);
1158 }
1159 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1160 }
1161 }, nullptr, &ans);
1162
1163 /**
1164 * @tc.steps:step2. submit erase map task
1165 * @tc.expected: step2. return ok.
1166 */
__anonf66911750e02() 1167 TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1168 for (size_t i = 0; i < num; i++) {
1169 ConcurrentAdapter::AdapterAutoLock(mutex);
1170 for (auto it = ans.begin(); it != ans.end();) {
1171 it = ans.erase(it);
1172 }
1173 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1174 }
1175 }, nullptr, &ans);
1176
1177 /**
1178 * @tc.steps:step3. submit get from map task
1179 * @tc.expected: step3. return ok.
1180 */
__anonf66911750f02() 1181 TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1182 for (size_t i = 0; i < num; i++) {
1183 ConcurrentAdapter::AdapterAutoLock(mutex);
1184 for (auto it = ans.begin(); it != ans.end(); it++) {
1185 int j = it->first;
1186 EXPECT_GE(j, 0);
1187 }
1188 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1189 }
1190 }, &ans, nullptr);
1191 ADAPTER_WAIT(h1);
1192 ADAPTER_WAIT(h2);
1193 ADAPTER_WAIT(h3);
1194 ASSERT_TRUE(ans.empty());
1195 }
1196
1197 /**
1198 * @tc.name: FfrtTest002
1199 * @tc.desc: Test ffrt concurrency
1200 * @tc.type: FUNC
1201 * @tc.require:
1202 * @tc.author:
1203 */
1204 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest002, TestSize.Level1)
1205 {
1206 std::map<int, int> ans;
1207 #ifdef USE_FFRT
1208 ffrt::mutex mutex;
1209 #else
1210 std::mutex mutex;
1211 #endif
1212 size_t num = 1000;
1213
1214 /**
1215 * @tc.steps:step1. subtask submit insert map task
1216 * @tc.expected: step1. return ok.
1217 */
__anonf66911751002() 1218 TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1219 TaskHandle hh1 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1220 for (size_t j = 0; j < num; j++) {
1221 ConcurrentAdapter::AdapterAutoLock(mutex);
1222 for (size_t i = 0; i < num; i++) {
1223 ans.insert_or_assign(i, i);
1224 }
1225 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1226 }
1227 }, nullptr, &ans);
1228 ADAPTER_WAIT(hh1);
1229 });
1230
1231 /**
1232 * @tc.steps:step2. subtask submit erase map task
1233 * @tc.expected: step2. return ok.
1234 */
__anonf66911751202() 1235 TaskHandle h2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1236 TaskHandle hh2 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1237 for (size_t i = 0; i < num; i++) {
1238 ConcurrentAdapter::AdapterAutoLock(mutex);
1239 for (auto it = ans.begin(); it != ans.end();) {
1240 it = ans.erase(it);
1241 }
1242 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1243 }
1244 }, nullptr, &ans);
1245 ADAPTER_WAIT(hh2);
1246 });
1247
1248 /**
1249 * @tc.steps:step3. subtask submit get from map task
1250 * @tc.expected: step3. return ok.
1251 */
__anonf66911751402() 1252 TaskHandle h3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1253 TaskHandle hh3 = ConcurrentAdapter::ScheduleTaskH([this, &ans, &mutex, num]() {
1254 for (size_t i = 0; i < num; i++) {
1255 ConcurrentAdapter::AdapterAutoLock(mutex);
1256 for (auto it = ans.begin(); it != ans.end(); it++) {
1257 int j = it->first;
1258 EXPECT_GE(j, 0);
1259 }
1260 ConcurrentAdapter::AdapterAutoUnLock(mutex);
1261 }
1262 }, &ans, nullptr);
1263 ADAPTER_WAIT(hh3);
1264 });
1265 ADAPTER_WAIT(h1);
1266 ADAPTER_WAIT(h2);
1267 ADAPTER_WAIT(h3);
1268 }
1269
1270 /**
1271 * @tc.name: FfrtTest003
1272 * @tc.desc: Test ffrt concurrency
1273 * @tc.type: FUNC
1274 * @tc.require:
1275 * @tc.author:
1276 */
1277 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FfrtTest003, TestSize.Level1)
1278 {
1279 size_t count = 0;
1280 size_t num = 3000;
1281 std::vector<TaskHandle> waitVec;
1282
1283 /**
1284 * @tc.steps:step1. submit increase task
1285 * @tc.expected: step1. return ok.
1286 */
1287 for (size_t j = 0; j < num; j++) {
__anonf66911751602() 1288 TaskHandle h1 = ConcurrentAdapter::ScheduleTaskH([this, &count, num]() {
1289 for (size_t i = 0; i < num; i++) {
1290 count++;
1291 }
1292 }, nullptr, nullptr);
1293 waitVec.push_back(std::move(h1));
1294 }
1295 for (const auto &item : waitVec) {
1296 ADAPTER_WAIT(item);
1297 }
1298
1299 /**
1300 * @tc.steps:step2. check count
1301 * @tc.expected: step2. return ok.
1302 */
1303 #ifdef USE_FFRT
1304 EXPECT_LE(count, num * num);
1305 #else
1306 EXPECT_EQ(count, num * num);
1307 #endif
1308 }
1309
1310 /**
1311 * @tc.name: AbnormalDelegateTest001
1312 * @tc.desc: Test delegate interface after delegate is closed
1313 * @tc.type: FUNC
1314 * @tc.require:
1315 * @tc.author: chenchaohao
1316 */
1317 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateTest001, TestSize.Level0)
1318 {
1319 /**
1320 * @tc.steps:step1. create db and open store
1321 * @tc.expected: step1. return ok.
1322 */
1323 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1324 ASSERT_NE(db, nullptr);
1325 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1326 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1327 RelationalStoreDelegate *delegate = nullptr;
1328 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1329 EXPECT_EQ(status, OK);
1330 ASSERT_NE(delegate, nullptr);
1331
1332 /**
1333 * @tc.steps:step2. close delegate
1334 * @tc.expected: step2. return ok.
1335 */
1336 auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1337 ClearMetaDataOption option;
1338 EXPECT_EQ(delegateImpl->ClearMetaData(option), OK);
1339 option.tableNameList.insert("asdad");
1340 EXPECT_EQ(delegateImpl->ClearMetaData(option), NOT_SUPPORT);
1341 status = delegateImpl->Close();
1342 EXPECT_EQ(status, OK);
1343
1344 /**
1345 * @tc.steps:step3. test interface after delegate is closed
1346 * @tc.expected: step3. return ok.
1347 */
1348 const std::string tableName = "sync_data";
1349 EXPECT_EQ(delegateImpl->RemoveDeviceData("", tableName), DB_ERROR);
1350 EXPECT_EQ(delegate->RemoveDeviceData("", FLAG_AND_DATA), DB_ERROR);
1351 EXPECT_EQ(delegate->GetCloudSyncTaskCount(), -1); // -1 is error count
1352 EXPECT_EQ(delegate->CreateDistributedTable(tableName, CLOUD_COOPERATION), DB_ERROR);
1353 EXPECT_EQ(delegate->UnRegisterObserver(), DB_ERROR);
1354 DataBaseSchema dataBaseSchema;
1355 EXPECT_EQ(delegate->SetCloudDbSchema(dataBaseSchema), DB_ERROR);
1356 EXPECT_EQ(delegate->SetReference({}), DB_ERROR);
1357 TrackerSchema trackerSchema;
1358 EXPECT_EQ(delegate->SetTrackerTable(trackerSchema), DB_ERROR);
1359 EXPECT_EQ(delegate->CleanTrackerData(tableName, 0), DB_ERROR);
1360 bool logicDelete = true;
1361 auto data = static_cast<PragmaData>(&logicDelete);
1362 EXPECT_EQ(delegate->Pragma(LOGIC_DELETE_SYNC_DATA, data), DB_ERROR);
1363 std::vector<VBucket> records;
1364 RecordStatus recordStatus = RecordStatus::WAIT_COMPENSATED_SYNC;
1365 EXPECT_EQ(delegate->UpsertData(tableName, records, recordStatus), DB_ERROR);
1366
1367 /**
1368 * @tc.steps:step4. close store
1369 * @tc.expected: step4. return ok.
1370 */
1371 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1372 delegate = nullptr;
1373 }
1374
InitDataStatus(const std::string & tableName,int count,sqlite3 * db)1375 void InitDataStatus(const std::string &tableName, int count, sqlite3 *db)
1376 {
1377 int type = 4; // the num of different status
1378 for (int i = 1; i <= type * count; i++) {
1379 std::string sql = "INSERT INTO " + tableName + " VALUES(" + std::to_string(i) + ", 'zhangsan" +
1380 std::to_string(i) + "');";
1381 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1382 }
1383 std::string countStr = std::to_string(count);
1384 std::string sql = "UPDATE " + DBCommon::GetLogTableName(tableName) + " SET status=(CASE WHEN data_key<=" +
1385 countStr + " THEN 0 WHEN data_key>" + countStr + " AND data_key<=2*" + countStr + " THEN 1 WHEN data_key>2*" +
1386 countStr + " AND data_key<=3*" + countStr + " THEN 2 ELSE 3 END)";
1387 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1388 }
1389
CheckDataStatus(const std::string & tableName,const std::string & condition,sqlite3 * db,int64_t expect)1390 void CheckDataStatus(const std::string &tableName, const std::string &condition, sqlite3 *db, int64_t expect)
1391 {
1392 std::string sql = "SELECT count(1) FROM " + DBCommon::GetLogTableName(tableName) + " WHERE " + condition;
1393 sqlite3_stmt *stmt = nullptr;
1394 EXPECT_EQ(SQLiteUtils::GetStatement(db, sql, stmt), E_OK);
1395 while (SQLiteUtils::StepWithRetry(stmt) == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1396 int64_t count = static_cast<int64_t>(sqlite3_column_int64(stmt, 0));
1397 EXPECT_EQ(count, expect);
1398 }
1399 int errCode;
1400 SQLiteUtils::ResetStatement(stmt, true, errCode);
1401 }
1402
1403 /**
1404 * @tc.name: LockDataTest001
1405 * @tc.desc: Test status after lock
1406 * @tc.type: FUNC
1407 * @tc.require:
1408 * @tc.author: bty
1409 */
1410 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest001, TestSize.Level1)
1411 {
1412 /**
1413 * @tc.steps:step1. init data and lock, hashKey has no matching data
1414 * @tc.expected: step1. return NOT_FOUND.
1415 */
1416 const std::string tableName = "sync_data";
1417 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1418 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1419 EXPECT_NE(db, nullptr);
1420 int count = 10;
1421 InitDataStatus(tableName, count, db);
1422 std::vector<std::vector<uint8_t>> hashKey;
1423 hashKey.push_back({'1'});
1424 EXPECT_EQ(Lock(tableName, hashKey, db), NOT_FOUND);
1425
1426 /**
1427 * @tc.steps:step2. init data and lock, hashKey has matching data
1428 * @tc.expected: step2. return OK.
1429 */
1430 hashKey.clear();
1431 CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1432 EXPECT_EQ(Lock(tableName, hashKey, db), OK);
1433
1434 /**
1435 * @tc.steps:step3. check status
1436 * @tc.expected: step3. return OK.
1437 */
1438 CheckDataStatus(tableName, " status = 2 and data_key <= 10 ", db, count);
1439 CheckDataStatus(tableName, " status = 3 and data_key <= 20 ", db, count);
1440 CheckDataStatus(tableName, " status = 2 ", db, count + count);
1441 CheckDataStatus(tableName, " status = 3 ", db, count + count);
1442 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1443 }
1444
1445 /**
1446 * @tc.name: LockDataTest002
1447 * @tc.desc: Test status after unLock
1448 * @tc.type: FUNC
1449 * @tc.require:
1450 * @tc.author: bty
1451 */
1452 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest002, TestSize.Level1)
1453 {
1454 /**
1455 * @tc.steps:step1. init data and unLock, there is data to be compensated for
1456 * @tc.expected: step1. return WAIT_COMPENSATED_SYNC.
1457 */
1458 const std::string tableName = "sync_data";
1459 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1460 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1461 EXPECT_NE(db, nullptr);
1462 int count = 10;
1463 InitDataStatus(tableName, count, db);
1464 std::vector<std::vector<uint8_t>> hashKey;
1465 CloudDBSyncUtilsTest::GetHashKey(tableName, " 1=1 ", db, hashKey);
1466 EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1467
1468 /**
1469 * @tc.steps:step2. check status
1470 * @tc.expected: step2. return OK.
1471 */
1472 CheckDataStatus(tableName, " status = 0 and data_key <= 10 ", db, count);
1473 CheckDataStatus(tableName, " status = 1 and data_key <= 20 ", db, count);
1474 CheckDataStatus(tableName, " status = 0 ", db, count + count);
1475 CheckDataStatus(tableName, " status = 1 ", db, count + count);
1476
1477 /**
1478 * @tc.steps:step3. unLock again, there is data to be compensated for
1479 * @tc.expected: step3. return WAIT_COMPENSATED_SYNC.
1480 */
1481 EXPECT_EQ(UnLock(tableName, hashKey, db), WAIT_COMPENSATED_SYNC);
1482
1483 /**
1484 * @tc.steps:step4. unLock again, there is no data to be compensated for
1485 * @tc.expected: step4. return OK.
1486 */
1487 std::string sql = "update " + DBCommon::GetLogTableName(tableName) + " SET status=0";
1488 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1489 EXPECT_EQ(UnLock(tableName, hashKey, db), OK);
1490
1491 /**
1492 * @tc.steps:step5. unLock again, hashKey has matching data
1493 * @tc.expected: step5. return NOT_FOUND.
1494 */
1495 hashKey.clear();
1496 hashKey.push_back({'1'});
1497 EXPECT_EQ(UnLock(tableName, hashKey, db), NOT_FOUND);
1498 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1499 }
1500
1501 /**
1502 * @tc.name: LockDataTest003
1503 * @tc.desc: Test status after local change
1504 * @tc.type: FUNC
1505 * @tc.require:
1506 * @tc.author: bty
1507 */
1508 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, LockDataTest003, TestSize.Level0)
1509 {
1510 /**
1511 * @tc.steps:step1. update data and check
1512 * @tc.expected: step1. return E_OK.
1513 */
1514 const std::string tableName = "sync_data";
1515 PrepareData({tableName}, false, DistributedDB::CLOUD_COOPERATION, false);
1516 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1517 EXPECT_NE(db, nullptr);
1518 int count = 10;
1519 InitDataStatus(tableName, count, db);
1520 std::string sql = "update " + tableName + " SET name='1' where id in (1,11,21,31)";
1521 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1522 CheckDataStatus(tableName, " status = 3 and data_key in (1,11,21,31) ", db, 2); // 2 is changed count
1523
1524 /**
1525 * @tc.steps:step1. delete data and check
1526 * @tc.expected: step1. return E_OK.
1527 */
1528 sql = "delete from " + tableName + " where id in (2,12,22,32)";
1529 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1530 CheckDataStatus(tableName, " status = 1 and data_key = -1 ", db, 3); // 3 is changed count
1531 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1532 }
1533
1534 DistributedDB::StoreObserver::StoreChangedInfo g_changedData;
1535
1536 class MockStoreObserver : public StoreObserver {
1537 public:
~MockStoreObserver()1538 virtual ~MockStoreObserver() {};
OnChange(StoreChangedInfo && data)1539 void OnChange(StoreChangedInfo &&data) override
1540 {
1541 g_changedData = data;
1542 std::unique_lock<std::mutex> lock(g_mutex);
1543 g_cv.notify_one();
1544 g_alreadyNotify = true;
1545 };
1546 };
1547
CreateTableForStoreObserver(sqlite3 * db,const std::string tableName)1548 void CreateTableForStoreObserver(sqlite3 *db, const std::string tableName)
1549 {
1550 std::string sql = "create table " + tableName + "(id INTEGER primary key, name TEXT);";
1551 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1552 sql = "create table no_" + tableName + "(id INTEGER, name TEXT);";
1553 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1554 sql = "create table mult_" + tableName + "(id INTEGER, name TEXT, age int, ";
1555 sql += "PRIMARY KEY (id, name));";
1556 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1557 }
1558
PrepareDataForStoreObserver(sqlite3 * db,const std::string & tableName,int begin,int dataCounts)1559 void PrepareDataForStoreObserver(sqlite3 *db, const std::string &tableName, int begin, int dataCounts)
1560 {
1561 std::string sql = "begin;";
1562 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1563 for (int i = begin; i < begin + dataCounts; i++) {
1564 sql = "insert into " + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1565 std::to_string(i + 1) + "');";
1566 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1567 sql = "insert into no_" + tableName +" VALUES(" + std::to_string(i + 1) + ", 'zhangsan" +
1568 std::to_string(i + 1) + "');";
1569 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1570 sql = "insert into mult_" + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan";
1571 sql += std::to_string(i + 1) + "', 18);";
1572 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1573 }
1574 for (int i = begin; i < dataCounts / 2 + begin; i++) { // 2 is half
1575 sql = "update " + tableName + " set name = 'lisi' where id = " + std::to_string(i + 1) + ";";
1576 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1577 sql = "update no_" + tableName + " set name = 'lisi' where _rowid_ = " + std::to_string(i + 1) + ";";
1578 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1579 sql = "update mult_" + tableName + " set age = 20 where id = " + std::to_string(i + 1);
1580 sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1581 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1582 }
1583 for (int i = dataCounts / 2 + begin; i < dataCounts + begin; i++) { // 2 is half
1584 sql = "delete from " + tableName + " where id = " + std::to_string(i + 1) + ";";
1585 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1586 sql = "delete from no_" + tableName + " where _rowid_ = " + std::to_string(i + 1) + ";";
1587 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1588 sql = "delete from mult_" + tableName + " where id = " + std::to_string(i + 1);
1589 sql += " and name = 'zhangsan" + std::to_string(i + 1) + "';";
1590 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1591 }
1592 sql = "commit;";
1593 EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK);
1594 }
1595
CheckChangedData(int num,int times=0,int offset=0)1596 void CheckChangedData(int num, int times = 0, int offset = 0)
1597 {
1598 if (num == 1) {
1599 for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1600 EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1601 static_cast<int64_t>(i + offset - times * 5)); // 5 is rowid times
1602 }
1603 for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1604 EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1605 static_cast<int64_t>(i + offset + 5)); // 5 is offset
1606 }
1607 return;
1608 }
1609 for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_INSERT].size(); i++) {
1610 EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_INSERT][i - 1][0]),
1611 static_cast<int64_t>(i + offset));
1612 }
1613 for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_UPDATE].size(); i++) {
1614 EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_UPDATE][i - 1][0]),
1615 static_cast<int64_t>(i + offset));
1616 }
1617 for (size_t i = 1; i <= g_changedData[num].primaryData[ChangeType::OP_DELETE].size(); i++) {
1618 EXPECT_EQ(std::get<int64_t>(g_changedData[num].primaryData[ChangeType::OP_DELETE][i - 1][0]),
1619 static_cast<int64_t>(i + offset + 5)); // 5 is offset
1620 }
1621 }
1622
1623 /**
1624 * @tc.name: RegisterStoreObserverTest001
1625 * @tc.desc: Test commit for three table then trigger store observer
1626 * @tc.type: FUNC
1627 * @tc.require:
1628 * @tc.author: chenchaohao
1629 */
1630 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest001, TestSize.Level1)
1631 {
1632 /**
1633 * @tc.steps:step1. prepare db and create table.
1634 * @tc.expected: step1. return ok.
1635 */
1636 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1637 EXPECT_NE(db, nullptr);
1638 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1639 std::string tableName = "primary_test";
1640 CreateTableForStoreObserver(db, tableName);
1641
1642 /**
1643 * @tc.steps:step2. register store observer and check onchange.
1644 * @tc.expected: step2. return ok.
1645 */
1646 auto storeObserver = std::make_shared<MockStoreObserver>();
1647 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1648 RegisterDbHook(db);
1649 EXPECT_TRUE(g_changedData.empty());
1650 int dataCounts = 10; // 10 is count of insert options.
1651 int begin = 0;
1652 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1653 {
1654 std::unique_lock<std::mutex> lock(g_mutex);
__anonf66911751702() 1655 g_cv.wait(lock, []() {
1656 return g_alreadyNotify;
1657 });
1658 g_alreadyNotify = false;
1659 }
1660 EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1661 CheckChangedData(0);
1662 EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1663 CheckChangedData(1);
1664 EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1665 CheckChangedData(2); // 2 is mult primary table
1666 g_changedData.clear();
1667
1668 /**
1669 * @tc.steps:step3. unregister store observer and update data check onchange.
1670 * @tc.expected: step3. return ok.
1671 */
1672 EXPECT_EQ(UnregisterStoreObserver(db), OK);
1673 begin = 10; // 10 is begin id
1674 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1675 EXPECT_TRUE(g_changedData.empty());
1676 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1677 }
1678
1679 /**
1680 * @tc.name: RegisterStoreObserverTest002
1681 * @tc.desc: Test commit for three table then trigger client observer when register then create table
1682 * @tc.type: FUNC
1683 * @tc.require:
1684 * @tc.author: chenchaohao
1685 */
1686 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest002, TestSize.Level1)
1687 {
1688 /**
1689 * @tc.steps:step1. prepare db and register store observer then create table.
1690 * @tc.expected: step1. return ok.
1691 */
1692 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1693 EXPECT_NE(db, nullptr);
1694 auto storeObserver = std::make_shared<MockStoreObserver>();
1695 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1696 RegisterDbHook(db);
1697 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1698 std::string tableName = "primary_test";
1699 CreateTableForStoreObserver(db, tableName);
1700
1701 /**
1702 * @tc.steps:step2. update data and check onchange.
1703 * @tc.expected: step2. return ok.
1704 */
1705 EXPECT_TRUE(g_changedData.empty());
1706 int dataCounts = 10; // 10 is count of insert options.
1707 int begin = 0;
1708 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1709 WaitAndResetNotify();
1710 EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1711 CheckChangedData(0);
1712 EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1713 CheckChangedData(1);
1714 EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1715 CheckChangedData(2); // 2 is mult primary table
1716 g_changedData.clear();
1717
1718 /**
1719 * @tc.steps:step3. unregister store observer and update data check onchange.
1720 * @tc.expected: step3. return ok.
1721 */
1722 EXPECT_EQ(UnregisterStoreObserver(db), OK);
1723 begin = 10; // 11 is begin id
1724 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1725 EXPECT_TRUE(g_changedData.empty());
1726 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1727 }
1728
1729 /**
1730 * @tc.name: RegisterStoreObserverTest003
1731 * @tc.desc: Test commit for three table then trigger client observer when register two observer
1732 * @tc.type: FUNC
1733 * @tc.require:
1734 * @tc.author: chenchaohao
1735 */
1736 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest003, TestSize.Level1)
1737 {
1738 /**
1739 * @tc.steps:step1. prepare db and register store observer then create table.
1740 * @tc.expected: step1. return ok.
1741 */
1742 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1743 EXPECT_NE(db, nullptr);
1744 auto storeObserver1 = std::make_shared<MockStoreObserver>();
1745 auto storeObserver2 = std::make_shared<MockStoreObserver>();
1746 EXPECT_EQ(RegisterStoreObserver(db, storeObserver1), OK);
1747 EXPECT_EQ(RegisterStoreObserver(db, storeObserver2), OK);
1748 RegisterDbHook(db);
1749 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1750 std::string tableName = "primary_test";
1751 CreateTableForStoreObserver(db, tableName);
1752
1753 /**
1754 * @tc.steps:step2. update data and check onchange.
1755 * @tc.expected: step2. return ok.
1756 */
1757 EXPECT_TRUE(g_changedData.empty());
1758 int dataCounts = 10; // 10 is count of insert options.
1759 int begin = 0;
1760 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1761 WaitAndResetNotify();
1762 EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1763 CheckChangedData(0);
1764 EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1765 CheckChangedData(1);
1766 EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1767 CheckChangedData(2); // 2 is mult primary table
1768 g_changedData.clear();
1769
1770 /**
1771 * @tc.steps:step3. unregister store observer and update data check onchange.
1772 * @tc.expected: step3. return ok.
1773 */
1774 EXPECT_EQ(UnregisterStoreObserver(db, storeObserver1), OK);
1775 begin = 10; // 11 is begin id
1776 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1777 EXPECT_EQ(g_changedData[0].tableName, "primary_test");
1778 CheckChangedData(0, 1, dataCounts);
1779 EXPECT_EQ(g_changedData[1].tableName, "no_primary_test");
1780 CheckChangedData(1, 1, dataCounts);
1781 EXPECT_EQ(g_changedData[2].tableName, "mult_primary_test"); // 2 is mult primary table
1782 CheckChangedData(2, 1, dataCounts); // 2 is mult primary table
1783 g_changedData.clear();
1784
1785 EXPECT_EQ(UnregisterStoreObserver(db, storeObserver2), OK);
1786 begin = 20; // 21 is begin id
1787 PrepareDataForStoreObserver(db, tableName, begin, dataCounts);
1788 EXPECT_TRUE(g_changedData.empty());
1789 UnregisterDbHook(db);
1790 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1791 }
1792
1793 /**
1794 * @tc.name: RegisterStoreObserverTest004
1795 * @tc.desc: Test register two same observer
1796 * @tc.type: FUNC
1797 * @tc.require:
1798 * @tc.author: chenchaohao
1799 */
1800 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest004, TestSize.Level1)
1801 {
1802 /**
1803 * @tc.steps:step1. prepare db and register store observer then create table.
1804 * @tc.expected: step1. return ok.
1805 */
1806 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1807 EXPECT_NE(db, nullptr);
1808 auto storeObserver = std::make_shared<MockStoreObserver>();
1809 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1810 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
1811 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1812 }
1813
1814 /**
1815 * @tc.name: AbnormalDelegateImplTest001
1816 * @tc.desc: Test delegateImpl interface after delegate is closed
1817 * @tc.type: FUNC
1818 * @tc.require:
1819 * @tc.author: suyue
1820 */
1821 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest001, TestSize.Level0)
1822 {
1823 /**
1824 * @tc.steps: step1. create db and open store.
1825 * @tc.expected: step1. return ok.
1826 */
1827 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1828 ASSERT_NE(db, nullptr);
1829 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1830 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1831 RelationalStoreDelegate *delegate = nullptr;
1832 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1833 EXPECT_EQ(status, OK);
1834 ASSERT_NE(delegate, nullptr);
1835
1836 /**
1837 * @tc.steps: step2. close delegate.
1838 * @tc.expected: step2. return ok.
1839 */
1840 auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1841 status = delegateImpl->Close();
1842 EXPECT_EQ(status, OK);
1843
1844 /**
1845 * @tc.steps: step3. test DelegateImpl interface after delegate is closed.
1846 * @tc.expected: step3. return DB_ERROR.
1847 */
1848 const RemoteCondition condition;
1849 std::shared_ptr<ResultSet> result = nullptr;
1850 DBStatus ret = delegateImpl->RemoteQuery("", condition, 0, result);
1851 EXPECT_EQ(ret, DB_ERROR);
1852 EXPECT_EQ(delegateImpl->RemoveDeviceData(), DB_ERROR);
1853
1854 StoreObserver observer;
1855 EXPECT_EQ(delegateImpl->RegisterObserver(&observer), DB_ERROR);
1856 EXPECT_EQ(delegateImpl->UnRegisterObserver(&observer), DB_ERROR);
1857 DistributedDB::SqlCondition sqlCondition;
1858 std::vector<VBucket> records = {};
1859 EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), DB_ERROR);
1860 EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), DB_ERROR);
1861 const CloudSyncConfig config;
1862 EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), DB_ERROR);
1863
1864 /**
1865 * @tc.steps: step4. close store.
1866 * @tc.expected: step4. return ok.
1867 */
1868 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1869 delegate = nullptr;
1870 }
1871
1872 /**
1873 * @tc.name: AbnormalDelegateImplTest002
1874 * @tc.desc: Test delegate interface after delegate is closed
1875 * @tc.type: FUNC
1876 * @tc.require:
1877 * @tc.author: suyue
1878 */
1879 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, AbnormalDelegateImplTest002, TestSize.Level0)
1880 {
1881 /**
1882 * @tc.steps: step1. create db and open store.
1883 * @tc.expected: step1. return ok.
1884 */
1885 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1886 ASSERT_NE(db, nullptr);
1887 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1888 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
1889 RelationalStoreDelegate *delegate = nullptr;
1890 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
1891 EXPECT_EQ(status, OK);
1892 ASSERT_NE(delegate, nullptr);
1893
1894 /**
1895 * @tc.steps: step2. test DelegateImpl interface when para is err.
1896 * @tc.expected: step2. return INVALID_ARGS or NOT_FOUND.
1897 */
1898 auto delegateImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1899 const CloudSyncConfig config;
1900 EXPECT_EQ(delegateImpl->SetCloudSyncConfig(config), OK);
1901 DistributedDB::SqlCondition sqlCondition;
1902 std::vector<VBucket> records = {};
1903 EXPECT_EQ(delegateImpl->ExecuteSql(sqlCondition, records), INVALID_ARGS);
1904 EXPECT_EQ(delegateImpl->UpsertData("", records, RecordStatus::WAIT_COMPENSATED_SYNC), INVALID_ARGS);
1905 EXPECT_EQ(delegateImpl->CleanTrackerData("", 0), INVALID_ARGS);
1906 TrackerSchema schema;
1907 EXPECT_EQ(delegateImpl->SetTrackerTable(schema), INVALID_ARGS);
1908 schema = {.tableName = "test", .extendColNames = {}, .trackerColNames = {}};
1909 EXPECT_EQ(delegateImpl->SetTrackerTable(schema), NOT_FOUND);
1910
1911 /**
1912 * @tc.steps: step3. close store.
1913 * @tc.expected: step3. return ok.
1914 */
1915 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1916 delegate = nullptr;
1917 }
1918
1919 /**
1920 * @tc.name: FuncExceptionTest001
1921 * @tc.desc: Test the interception expection of the interface
1922 * @tc.type: FUNC
1923 * @tc.require:
1924 * @tc.author: bty
1925 */
1926 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, FuncExceptionTest001, TestSize.Level1)
1927 {
1928 std::shared_ptr<StoreObserver> iStoreObserver = nullptr;
1929 EXPECT_EQ(RegisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1930 EXPECT_EQ(UnregisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1931 iStoreObserver = std::make_shared<StoreObserver>();
1932 EXPECT_EQ(RegisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1933 EXPECT_EQ(UnregisterStoreObserver(nullptr, iStoreObserver), INVALID_ARGS);
1934
1935 EXPECT_EQ(RelationalStoreManager::CalcPrimaryKeyHash({}, {}).size(), 0u);
1936 std::map<std::string, Type> pkMap1 = {{"fielddInt", 0L}};
1937 std::map<std::string, CollateType> ctMap1 = {{"fielddInt", CollateType::COLLATE_BUTT}};
1938 std::vector<uint8_t> result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap1, ctMap1);
1939 EXPECT_TRUE(result.empty());
1940
1941 std::map<std::string, Type> pkMap2 = {{"FIELDINT", 0L}, {"FIELDSTR", std::string("FIELDSTR")}};
1942 std::map<std::string, CollateType> ctMap2;
1943 ctMap2.insert_or_assign("fieldint", CollateType::COLLATE_BUTT);
1944 ctMap2.insert_or_assign("fieldstr", CollateType::COLLATE_BUTT);
1945 result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1946 EXPECT_TRUE(result.empty());
1947
1948 ctMap2.insert_or_assign("fieldint", CollateType::COLLATE_NOCASE);
1949 ctMap2.insert_or_assign("fieldstr", CollateType::COLLATE_NOCASE);
1950 result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1951 EXPECT_FALSE(result.empty());
1952
1953 std::map<std::string, std::string> entries2;
1954 pkMap2.insert_or_assign("FIELDINT", entries2);
1955 result = RelationalStoreManager::CalcPrimaryKeyHash(pkMap2, ctMap2);
1956 EXPECT_TRUE(result.empty());
1957 }
1958
1959 /**
1960 * @tc.name: CleanTest001
1961 * @tc.desc: Test calling the Clean interface twice
1962 * @tc.type: FUNC
1963 * @tc.require:
1964 * @tc.author: suyue
1965 */
1966 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CleanTest001, TestSize.Level0)
1967 {
1968 Logger *loggerInstance = Logger::GetInstance();
1969 ASSERT_NE(loggerInstance, nullptr);
1970 Clean(true);
1971 Clean(false);
1972 loggerInstance = nullptr;
1973 Logger *newLoggerInstance = Logger::GetInstance();
1974 ASSERT_NE(newLoggerInstance, nullptr);
1975 }
1976
1977 /**
1978 * @tc.name: CreateTempTriggerTest001
1979 * @tc.desc: Test create data change temp trigger.
1980 * @tc.type: FUNC
1981 * @tc.require:
1982 * @tc.author: liaoyonghuang
1983 */
1984 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest001, TestSize.Level0)
1985 {
1986 /**
1987 * @tc.steps: step1. create db and fts table.
1988 * @tc.expected: step1. return ok.
1989 */
1990 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1991 EXPECT_NE(db, nullptr);
1992 std::string tableName = "table1";
1993 std::string sql = "CREATE VIRTUAL TABLE IF NOT EXISTS " + tableName + " USING fts4(content);";
1994 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
1995 /**
1996 * @tc.steps: step2. create temp trigger on table.
1997 * @tc.expected: step2. return ok.
1998 */
1999 EXPECT_EQ(CreateDataChangeTempTrigger(db), OK);
2000 Clean(false);
2001 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2002 }
2003
2004 /**
2005 * @tc.name: CreateTempTriggerTest002
2006 * @tc.desc: Test create data change temp trigger
2007 * @tc.type: FUNC
2008 * @tc.require:
2009 * @tc.author: liaoyonghuang
2010 */
2011 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest002, TestSize.Level0)
2012 {
2013 /**
2014 * @tc.steps: step1. create db and fts table.
2015 * @tc.expected: step1. return ok.
2016 */
2017 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
2018 EXPECT_NE(db, nullptr);
2019 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
2020 std::string tableName = "table1";
2021 std::string sql = "create virtual table if not exists " + tableName + " using fts4(content);";
2022 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2023 /**
2024 * @tc.steps: step2. create temp trigger on table.
2025 * @tc.expected: step2. return ok.
2026 */
2027 auto storeObserver = std::make_shared<MockStoreObserver>();
2028 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
2029 RegisterDbHook(db);
2030 g_changedData.clear();
2031 /**
2032 * @tc.steps: step3. insert data and check changed data.
2033 * @tc.expected: step3. return ok.
2034 */
2035 sql = "insert into " + tableName + "_content values(1, '123456');";
2036 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2037 ASSERT_EQ(g_changedData.size(), 1u);
2038 EXPECT_EQ(g_changedData.front().tableName, tableName + "_content");
2039 ASSERT_EQ(g_changedData.front().primaryData[OP_INSERT].size(), 1u);
2040 EXPECT_EQ(UnregisterStoreObserver(db, storeObserver), OK);
2041 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2042 }
2043
2044 /**
2045 * @tc.name: CreateTempTriggerTest003
2046 * @tc.desc: Test monitoring of virtual table data
2047 * @tc.type: FUNC
2048 * @tc.require:
2049 * @tc.author: liaoyonghuang
2050 */
2051 HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, CreateTempTriggerTest003, TestSize.Level0)
2052 {
2053 /**
2054 * @tc.steps: step1. create db and fts table.
2055 * @tc.expected: step1. return ok.
2056 */
2057 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
2058 EXPECT_NE(db, nullptr);
2059 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
2060 std::string tableName = "table1";
2061 std::string sql = "create virtual table if not exists " + tableName + " using fts4(content);";
2062 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2063 /**
2064 * @tc.steps: step2. create temp trigger on table.
2065 * @tc.expected: step2. return ok.
2066 */
2067 auto storeObserver = std::make_shared<MockStoreObserver>();
2068 EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK);
2069 RegisterDbHook(db);
2070 g_changedData.clear();
2071 /**
2072 * @tc.steps: step3. insert data and check changed data.
2073 * @tc.expected: step3. return ok.
2074 */
2075 sql = "insert into " + tableName + " values(12345);";
2076 EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, sql), E_OK);
2077 ASSERT_FALSE(g_changedData.empty());
2078 EXPECT_EQ(g_changedData.front().tableName, tableName + "_content");
2079 ASSERT_EQ(g_changedData.front().primaryData[OP_INSERT].size(), 1u);
2080 EXPECT_EQ(UnregisterStoreObserver(db, storeObserver), OK);
2081 EXPECT_EQ(sqlite3_close_v2(db), E_OK);
2082 }
2083 }
2084