1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17
18 #include "db_common.h"
19 #include "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "log_print.h"
22 #include "relational_store_delegate_impl.h"
23 #include "relational_store_manager.h"
24 #include "relational_virtual_device.h"
25 #include "runtime_config.h"
26 #include "virtual_communicator_aggregator.h"
27
28 using namespace testing::ext;
29 using namespace DistributedDB;
30 using namespace DistributedDBUnitTest;
31 using namespace std;
32
33 namespace {
34 constexpr const char* DB_SUFFIX = ".db";
35 constexpr const char* STORE_ID = "Relational_Store_ID";
36 const std::string DEVICE_A = "DEVICE_A";
37 const std::string DEVICE_B = "DEVICE_B";
38 std::string g_testDir;
39 std::string g_dbDir;
40 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
41 VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
42 RelationalVirtualDevice *g_deviceB = nullptr;
43
44 const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \
45 "key BLOB NOT NULL UNIQUE," \
46 "value BLOB," \
47 "timestamp INT NOT NULL," \
48 "flag INT NOT NULL," \
49 "device BLOB," \
50 "ori_device BLOB," \
51 "hash_key BLOB PRIMARY KEY NOT NULL," \
52 "w_timestamp INT," \
53 "UNIQUE(device, ori_device));" \
54 "CREATE INDEX key_index ON sync_data (key, flag);";
55
56 const std::string EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS student(" \
57 "id INTEGER NOT NULL UNIQUE," \
58 "name TEXT," \
59 "field_1);";
60
61 const std::string NORMAL_CREATE_TABLE_SQL_STUDENT = R""(create table student_1 (
62 id INTEGER PRIMARY KEY,
63 name STRING,
64 level INTEGER,
65 score INTEGER
66 ))"";
67
68 const std::string NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER = R""(create table student_1 (
69 id INTEGER PRIMARY KEY,
70 name STRING,
71 score INTEGER,
72 level INTEGER
73 ))"";
74
75 const std::string ALL_FIELD_TYPE_TABLE_SQL = R""(CREATE TABLE IF NOT EXISTS tbl_all_type(
76 id INTEGER PRIMARY KEY,
77 f_int INT,
78 f_real REAL,
79 f_text TEXT,
80 f_blob BLOB,
81 f_none
82 ))"";
83
FakeOldVersionDB(sqlite3 * db)84 void FakeOldVersionDB(sqlite3 *db)
85 {
86 std::string dropLogTable = "drop table naturalbase_rdb_aux_student_1_log;";
87 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropLogTable), SQLITE_OK);
88 dropLogTable = "drop table naturalbase_rdb_aux_sync_data_log;";
89 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropLogTable), SQLITE_OK);
90
91 std::string createLogTable = "CREATE TABLE naturalbase_rdb_aux_student_1_log(" \
92 "data_key INT NOT NULL," \
93 "device BLOB," \
94 "ori_device BLOB," \
95 "timestamp INT NOT NULL," \
96 "wtimestamp INT NOT NULL," \
97 "flag INT NOT NULL," \
98 "hash_key BLOB NOT NULL," \
99 "PRIMARY KEY(hash_key));";
100 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createLogTable), SQLITE_OK);
101
102 createLogTable = "CREATE TABLE naturalbase_rdb_aux_sync_data_log(" \
103 "data_key INT NOT NULL," \
104 "device BLOB," \
105 "ori_device BLOB," \
106 "timestamp INT NOT NULL," \
107 "wtimestamp INT NOT NULL," \
108 "flag INT NOT NULL," \
109 "hash_key BLOB NOT NULL," \
110 "PRIMARY KEY(hash_key));";
111 EXPECT_EQ(RelationalTestUtils::ExecSql(db, createLogTable), SQLITE_OK);
112
113 std::string dropTrigger = "DROP TRIGGER IF EXISTS naturalbase_rdb_student_1_ON_UPDATE;";
114 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropTrigger), SQLITE_OK);
115
116 std::string oldTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
117 "ON student_1\n"
118 "BEGIN\n"
119 "\t UPDATE naturalbase_rdb_aux_student_1_log SET timestamp=get_sys_time(0), device='', "
120 "flag=0x22 WHERE hash_key=calc_hash(OLD.id) AND flag&0x02=0x02;\n"
121 "END;";
122 EXPECT_EQ(RelationalTestUtils::ExecSql(db, oldTrigger), SQLITE_OK);
123 Key key;
124 DBCommon::StringToVector("log_table_version", key);
125 Value val;
126 DBCommon::StringToVector("1.0", val);
127 EXPECT_EQ(RelationalTestUtils::SetMetaData(db, key, val), SQLITE_OK);
128 }
129
AddDeviceSchema(RelationalVirtualDevice * device,sqlite3 * db,const std::string & name)130 void AddDeviceSchema(RelationalVirtualDevice *device, sqlite3 *db, const std::string &name)
131 {
132 TableInfo table;
133 SQLiteUtils::AnalysisSchema(db, name, table);
134
135 std::vector<FieldInfo> fieldList;
136 for (const auto &it : table.GetFields()) {
137 fieldList.push_back(it.second);
138 }
139 device->SetLocalFieldInfo(table.GetFieldInfos());
140 device->SetTableInfo(table);
141 }
142 }
143
144 class DistributedDBInterfacesRelationalSyncTest : public testing::Test {
145 public:
146 static void SetUpTestCase(void);
147 static void TearDownTestCase(void);
148 void SetUp() override;
149 void TearDown() override;
150 protected:
151 sqlite3 *db = nullptr;
152 RelationalStoreDelegate *delegate = nullptr;
153 };
154
SetUpTestCase(void)155 void DistributedDBInterfacesRelationalSyncTest::SetUpTestCase(void)
156 {
157 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
158 LOGD("Test dir is %s", g_testDir.c_str());
159 g_dbDir = g_testDir + "/";
160
161 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
162 ASSERT_TRUE(g_communicatorAggregator != nullptr);
163 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
164 }
165
TearDownTestCase(void)166 void DistributedDBInterfacesRelationalSyncTest::TearDownTestCase(void)
167 {
168 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
169 }
170
SetUp()171 void DistributedDBInterfacesRelationalSyncTest::SetUp()
172 {
173 DistributedDBToolsUnitTest::PrintTestCaseInfo();
174
175 g_deviceB = new (std::nothrow) RelationalVirtualDevice(DEVICE_B);
176 ASSERT_TRUE(g_deviceB != nullptr);
177 auto *syncInterfaceB = new (std::nothrow) VirtualRelationalVerSyncDBInterface();
178 ASSERT_TRUE(syncInterfaceB != nullptr);
179 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
180
181 auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
182 const std::string &deviceId, uint8_t flag) -> bool {
183 return true;
184 };
185 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(permissionCheckCallback), OK);
186
187 db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
188 ASSERT_NE(db, nullptr);
189 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
190 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
191 RelationalTestUtils::CreateDeviceTable(db, "sync_data", DEVICE_A);
192 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
193 EXPECT_EQ(status, OK);
194 ASSERT_NE(delegate, nullptr);
195
196 status = delegate->CreateDistributedTable("sync_data");
197 EXPECT_EQ(status, OK);
198
199 AddDeviceSchema(g_deviceB, db, "sync_data");
200 }
201
TearDown()202 void DistributedDBInterfacesRelationalSyncTest::TearDown()
203 {
204 if (g_deviceB != nullptr) {
205 delete g_deviceB;
206 g_deviceB = nullptr;
207 }
208 PermissionCheckCallbackV2 nullCallback;
209 EXPECT_EQ(RuntimeConfig::SetPermissionCheckCallback(nullCallback), OK);
210
211 g_mgr.CloseStore(delegate);
212 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
213 DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
214 }
215
216 /**
217 * @tc.name: RelationalSyncTest001
218 * @tc.desc: Test with sync interface, table is not a distributed table
219 * @tc.type: FUNC
220 * @tc.require:
221 * @tc.author: lianhuix
222 */
223 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest001, TestSize.Level1)
224 {
225 std::vector<std::string> devices = {DEVICE_A};
226 Query query = Query::Select("sync_datb");
227 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90302(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 228 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
229 EXPECT_EQ(devicesMap.size(), devices.size());
230 }, true);
231
232 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_NOT_FOUND);
233 }
234
235 /**
236 * @tc.name: RelationalSyncTest002
237 * @tc.desc: Test with sync interface, query is not support
238 * @tc.type: FUNC
239 * @tc.require:
240 * @tc.author: lianhuix
241 */
242 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest002, TestSize.Level1)
243 {
244 std::vector<std::string> devices = {DEVICE_A};
245 Query query = Query::Select("sync_data").Like("value", "abc");
246 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90402(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 247 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
248 EXPECT_EQ(devicesMap.size(), devices.size());
249 }, true);
250
251 EXPECT_EQ(errCode, NOT_SUPPORT);
252 }
253
254 /**
255 * @tc.name: RelationalSyncTest003
256 * @tc.desc: Test with sync interface, query is invalid format
257 * @tc.type: FUNC
258 * @tc.require:
259 * @tc.author: lianhuix
260 */
261 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest003, TestSize.Level1)
262 {
263 std::vector<std::string> devices = {DEVICE_A};
264 Query query = Query::Select("sync_data").And().Or().EqualTo("flag", 2);
265 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90502(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 266 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
267 EXPECT_EQ(devicesMap.size(), devices.size());
268 }, true);
269
270 EXPECT_EQ(errCode, INVALID_QUERY_FORMAT);
271 }
272
273 /**
274 * @tc.name: RelationalSyncTest004
275 * @tc.desc: Test with sync interface, query use invalid field
276 * @tc.type: FUNC
277 * @tc.require:
278 * @tc.author: lianhuix
279 */
280 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest004, TestSize.Level1)
281 {
282 std::vector<std::string> devices = {DEVICE_A};
283 Query query = Query::Select("sync_data").EqualTo("fleg", 2);
284 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90602(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 285 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
286 EXPECT_EQ(devicesMap.size(), devices.size());
287 }, true);
288
289 EXPECT_EQ(errCode, INVALID_QUERY_FIELD);
290 }
291
292 /**
293 * @tc.name: RelationalSyncTest005
294 * @tc.desc: Test with sync interface, query table has been modified
295 * @tc.type: FUNC
296 * @tc.require:
297 * @tc.author: lianhuix
298 */
299 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest005, TestSize.Level1)
300 {
301 std::string modifySql = "ALTER TABLE sync_data ADD COLUMN add_field INTEGER;";
302 EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
303
304 std::vector<std::string> devices = {DEVICE_A};
305 Query query = Query::Select("sync_data");
306 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 307 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
308 EXPECT_EQ(devicesMap.size(), devices.size());
309 }, true);
310
311 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
312 }
313
314 /**
315 * @tc.name: RelationalSyncTest006
316 * @tc.desc: Test with sync interface, query is not set table name
317 * @tc.type: FUNC
318 * @tc.require:
319 * @tc.author: lianhuix
320 */
321 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest006, TestSize.Level1)
322 {
323 std::vector<std::string> devices = {DEVICE_A};
324 Query query = Query::Select();
325 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 326 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
327 EXPECT_EQ(devicesMap.size(), devices.size());
328 }, true);
329
330 EXPECT_EQ(errCode, NOT_SUPPORT);
331 }
332
333 /**
334 * @tc.name: RelationalSyncTest007
335 * @tc.desc: Test with sync interface, distributed table has empty column type
336 * @tc.type: FUNC
337 * @tc.require:
338 * @tc.author: lianhuix
339 */
340 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest007, TestSize.Level1)
341 {
342 EXPECT_EQ(RelationalTestUtils::ExecSql(db, EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL), SQLITE_OK);
343 RelationalTestUtils::CreateDeviceTable(db, "student", DEVICE_A);
344
345 DBStatus status = delegate->CreateDistributedTable("student");
346 EXPECT_EQ(status, OK);
347
348 std::vector<std::string> devices = {DEVICE_A};
349 Query query = Query::Select("student");
350 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 351 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
352 EXPECT_EQ(devicesMap.size(), devices.size());
353 }, true);
354
355 EXPECT_EQ(errCode, OK);
356 }
357
358 /**
359 * @tc.name: RelationalSyncTest008
360 * @tc.desc: Test sync with rebuilt table
361 * @tc.type: FUNC
362 * @tc.require:
363 * @tc.author: lianhuix
364 */
365 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest008, TestSize.Level1)
366 {
367 /**
368 * @tc.steps:step1. Drop sync_data
369 * @tc.expected: step1. ok
370 */
371 std::string dropSql = "DROP TABLE IF EXISTS sync_data;";
372 EXPECT_EQ(RelationalTestUtils::ExecSql(db, dropSql), SQLITE_OK);
373
374 /**
375 * @tc.steps:step2. sync with sync_data
376 * @tc.expected: step2. return INVALID_QUERY_FORMAT
377 */
378 std::vector<std::string> devices = {DEVICE_A};
379 Query query = Query::Select("sync_data");
380 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 381 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
382 EXPECT_EQ(devicesMap.size(), devices.size());
383 }, true);
384 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
385
386 /**
387 * @tc.steps:step3. recreate sync_data
388 * @tc.expected: step3. ok
389 */
390 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL), SQLITE_OK);
391 DBStatus status = delegate->CreateDistributedTable("sync_data");
392 EXPECT_EQ(status, OK);
393
394 /**
395 * @tc.steps:step4. Check trigger
396 * @tc.expected: step4. trigger exists
397 */
398 bool result = false;
399 std::string checkSql = "select * from sqlite_master where type = 'trigger' and tbl_name = 'sync_data';";
400 EXPECT_EQ(RelationalTestUtils::CheckSqlResult(db, checkSql, result), E_OK);
401 EXPECT_EQ(result, true);
402
403 /**
404 * @tc.steps:step5. sync with sync_data
405 * @tc.expected: step5. ok
406 */
407 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 408 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
409 EXPECT_EQ(devicesMap.size(), devices.size());
410 }, true);
411
412 EXPECT_EQ(errCode, OK);
413 }
414
415 /**
416 * @tc.name: RelationalSyncTest009
417 * @tc.desc: Test sync with invalid query
418 * @tc.type: FUNC
419 * @tc.require:
420 * @tc.author: lianhuix
421 */
422 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest009, TestSize.Level1)
423 {
424 EXPECT_EQ(RelationalTestUtils::ExecSql(db, EMPTY_COLUMN_TYPE_CREATE_TABLE_SQL), SQLITE_OK);
425 RelationalTestUtils::CreateDeviceTable(db, "student", DEVICE_A);
426
427 DBStatus status = delegate->CreateDistributedTable("student");
428 EXPECT_EQ(status, OK);
429
430 std::vector<std::string> devices = {DEVICE_A};
431 Query query = Query::Select("student").EqualTo("$id", 123);
432 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90c02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 433 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
434 EXPECT_EQ(devicesMap.size(), devices.size());
435 }, true);
436 EXPECT_EQ(status, INVALID_QUERY_FORMAT);
437
438 query = Query::Select("student").EqualTo("A$id", 123);
439 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 440 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
441 EXPECT_EQ(devicesMap.size(), devices.size());
442 }, true);
443 EXPECT_EQ(status, INVALID_QUERY_FORMAT);
444
445 query = Query::Select("student").EqualTo("$.id", 123);
446 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90e02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 447 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
448 EXPECT_EQ(devicesMap.size(), devices.size());
449 }, true);
450
451 EXPECT_EQ(status, OK);
452 }
453
454 /**
455 * @tc.name: RelationalSyncTest010
456 * @tc.desc: Test sync with shcema changed
457 * @tc.type: FUNC
458 * @tc.require:
459 * @tc.author: lianhuix
460 */
461 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest010, TestSize.Level1)
462 {
463 std::vector<std::string> devices = {DEVICE_A};
464 Query query = Query::Select("sync_data");
465 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa90f02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 466 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
467 EXPECT_EQ(devicesMap.size(), devices.size());
468 }, true);
469 EXPECT_EQ(errCode, OK);
470
471 std::string modifySql = "DROP TABLE IF EXISTS sync_data;";
472 EXPECT_EQ(RelationalTestUtils::ExecSql(db, modifySql), SQLITE_OK);
473
474 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 475 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
476 EXPECT_EQ(devicesMap.size(), devices.size());
477 }, true);
478 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
479
480 errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 481 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
482 EXPECT_EQ(devicesMap.size(), devices.size());
483 }, true);
484 EXPECT_EQ(errCode, DISTRIBUTED_SCHEMA_CHANGED);
485 }
486
487 /**
488 * @tc.name: UpdatePrimaryKeyTest001
489 * @tc.desc: Test update data's primary key
490 * @tc.type: FUNC
491 * @tc.require:
492 * @tc.author: lianhuix
493 */
494 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpdatePrimaryKeyTest001, TestSize.Level1)
495 {
496 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
497 RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
498
499 DBStatus status = delegate->CreateDistributedTable("student_1");
500 EXPECT_EQ(status, OK);
501
502 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
503 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
504
505 std::string updateSql = "update student_1 set id = 1002 where name = 'xue';";
506 EXPECT_EQ(RelationalTestUtils::ExecSql(db, updateSql), SQLITE_OK);
507
508 int cnt = RelationalTestUtils::CheckTableRecords(db, std::string(DBConstant::RELATIONAL_PREFIX) + "student_1" +
509 "_log");
510 EXPECT_EQ(cnt, 2);
511 }
512
513 /**
514 * @tc.name: UpgradeTriggerTest001
515 * @tc.desc: Test upgrade from old version
516 * @tc.type: FUNC
517 * @tc.require:
518 * @tc.author: lianhuix
519 */
520 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpgradeTriggerTest001, TestSize.Level1)
521 {
522 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
523 RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
524
525 DBStatus status = delegate->CreateDistributedTable("student_1");
526 EXPECT_EQ(status, OK);
527
528 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
529 delegate = nullptr;
530
531 FakeOldVersionDB(db);
532
533 status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
534 EXPECT_EQ(status, OK);
535 ASSERT_NE(delegate, nullptr);
536
537 // checkTrigger
538 std::string resultTrigger;
539 int errCode = RelationalTestUtils::ExecSql(db, "SELECT sql FROM sqlite_master WHERE type = ? AND name = ?",
__anonef37cfa91202(sqlite3_stmt *stmt) 540 [](sqlite3_stmt *stmt) {
541 (void)SQLiteUtils::BindTextToStatement(stmt, 1, "trigger"); // 1: bind index
542 (void)SQLiteUtils::BindTextToStatement(stmt, 2, "naturalbase_rdb_student_1_ON_UPDATE"); // 2: bind index
543 return E_OK;
544 }, [&resultTrigger](sqlite3_stmt *stmt) {
545 (void)SQLiteUtils::GetColumnTextValue(stmt, 0, resultTrigger);
546 return E_OK;
547 });
548 EXPECT_EQ(errCode, E_OK);
549 LOGD("result trigger: %s", resultTrigger.c_str());
550 std::string expectTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
551 "ON 'student_1'\n"
552 "BEGIN\n"
553 "\t UPDATE naturalbase_rdb_aux_student_1_log SET data_key=-1,timestamp=get_sys_time(0), device='',"
554 " flag=0x03 WHERE hash_key=calc_hash(OLD.'id', 0) AND flag&0x02=0x02;\n"
555 "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW._rowid_, '', '', get_sys_time(0), "
556 "get_last_time(), CASE WHEN (calc_hash(NEW.'id', 0) != calc_hash(NEW.'id', 0)) " \
557 "THEN 0x02 ELSE 0x22 END, calc_hash(NEW.'id', 0), '', '', '', '', '', 0);\n"
558 "END";
559 EXPECT_TRUE(resultTrigger == expectTrigger);
560 }
561
562
563 namespace {
PrepareSyncData(sqlite3 * db,int dataSize)564 void PrepareSyncData(sqlite3 *db, int dataSize)
565 {
566 int i = 1;
567 std::string insertSql = "INSERT INTO sync_data VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
568 int ret = RelationalTestUtils::ExecSql(db, insertSql, [&i, dataSize] (sqlite3_stmt *stmt) {
569 SQLiteUtils::BindTextToStatement(stmt, 1, "KEY_" + std::to_string(i));
570 SQLiteUtils::BindTextToStatement(stmt, 2, "VAL_" + std::to_string(i));
571 sqlite3_bind_int64(stmt, 3, 1000000 - (1000 + i));
572 sqlite3_bind_int64(stmt, 4, i % 4);
573 SQLiteUtils::BindTextToStatement(stmt, 5, "DEV_" + std::to_string(i));
574 SQLiteUtils::BindTextToStatement(stmt, 6, "KEY_" + std::to_string(i));
575 SQLiteUtils::BindTextToStatement(stmt, 7, "HASHKEY_" + std::to_string(i));
576 sqlite3_bind_int64(stmt, 8, 1000 + i);
577 return (i++ == dataSize) ? E_OK : -E_UNFINISHED;
578 }, nullptr);
579 EXPECT_EQ(ret, E_OK);
580 }
581
GetKey(VirtualRowData rowData)582 std::string GetKey(VirtualRowData rowData)
583 {
584 DataValue dataVal;
585 rowData.objectData.GetDataValue("key", dataVal);
586 EXPECT_EQ(dataVal.GetType(), StorageType::STORAGE_TYPE_TEXT);
587 std::string dataStr;
588 EXPECT_EQ(dataVal.GetText(dataStr), E_OK);
589 return dataStr;
590 }
591
CheckSyncData(sqlite3 * db,const std::string & checkSql,const std::vector<VirtualRowData> & resultData)592 void CheckSyncData(sqlite3 *db, const std::string &checkSql, const std::vector<VirtualRowData> &resultData)
593 {
594 std::set<std::string> keySet;
595 keySet.clear();
596 for (size_t i = 0; i < resultData.size(); i++) {
597 std::string ss = GetKey(resultData[i]);
598 keySet.insert(ss);
599 }
600 EXPECT_EQ(keySet.size(), resultData.size());
601
602 RelationalTestUtils::ExecSql(db, checkSql, nullptr, [keySet](sqlite3_stmt *stmt) {
603 std::string val;
604 SQLiteUtils::GetColumnTextValue(stmt, 0, val);
605 EXPECT_NE(keySet.find(val), keySet.end());
606 return E_OK;
607 });
608 }
609 }
610
611 /**
612 * @tc.name: SyncLimitTest001
613 * @tc.desc: Sync device with limit query
614 * @tc.type: FUNC
615 * @tc.require:
616 * @tc.author: lianhuix
617 */
618 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest001, TestSize.Level3)
619 {
620 PrepareSyncData(db, 5000);
621 std::vector<std::string> devices = {DEVICE_B};
622 Query query = Query::Select("sync_data").Limit(4500, 100);
623 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 624 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
625 EXPECT_EQ(devicesMap.size(), devices.size());
626 }, true);
627 EXPECT_EQ(errCode, OK);
628
629 std::vector<VirtualRowData> data;
630 g_deviceB->GetAllSyncData("sync_data", data);
631 EXPECT_EQ(data.size(), static_cast<size_t>(4500));
632 std::string checkSql = "select * from sync_data limit 4500 offset 100;";
633 CheckSyncData(db, checkSql, data);
634 }
635
636 /**
637 * @tc.name: SyncLimitTest002
638 * @tc.desc: Sync device with limit query
639 * @tc.type: FUNC
640 * @tc.require:
641 * @tc.author: lianhuix
642 */
643 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest002, TestSize.Level3)
644 {
645 PrepareSyncData(db, 5000);
646
647 std::vector<std::string> devices = {DEVICE_B};
648 Query query = Query::Select("sync_data").Limit(5000, 2000);
649 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 650 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
651 EXPECT_EQ(devicesMap.size(), devices.size());
652 }, true);
653 EXPECT_EQ(errCode, OK);
654
655 std::vector<VirtualRowData> data;
656 g_deviceB->GetAllSyncData("sync_data", data);
657 EXPECT_EQ(data.size(), static_cast<size_t>(3000));
658 std::string checkSql = "select * from sync_data limit 5000 offset 2000;";
659 CheckSyncData(db, checkSql, data);
660 }
661
662 /**
663 * @tc.name: SyncLimitTest003
664 * @tc.desc: Sync device with limit query
665 * @tc.type: FUNC
666 * @tc.require:
667 * @tc.author: lianhuix
668 */
669 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest003, TestSize.Level3)
670 {
671 PrepareSyncData(db, 5000);
672
673 std::vector<std::string> devices = {DEVICE_B};
674 Query query = Query::Select("sync_data").OrderBy("timestamp").Limit(4500, 1500);
675 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 676 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
677 EXPECT_EQ(devicesMap.size(), devices.size());
678 }, true);
679 EXPECT_EQ(errCode, OK);
680
681 std::vector<VirtualRowData> data;
682 g_deviceB->GetAllSyncData("sync_data", data);
683 EXPECT_EQ(data.size(), static_cast<size_t>(3500));
684 std::string checkSql = "select * from sync_data order by timestamp limit 4500 offset 1500;";
685 CheckSyncData(db, checkSql, data);
686 }
687
688 /**
689 * @tc.name: SyncOrderByTest001
690 * @tc.desc: Sync device with limit query
691 * @tc.type: FUNC
692 * @tc.require:
693 * @tc.author: lianhuix
694 */
695 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncOrderByTest001, TestSize.Level3)
696 {
697 PrepareSyncData(db, 5000);
698
699 std::vector<std::string> devices = {DEVICE_B};
700 Query query = Query::Select("sync_data").OrderBy("timestamp");
701 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 702 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
703 EXPECT_EQ(devicesMap.size(), devices.size());
704 }, true);
705 EXPECT_EQ(errCode, OK);
706
707 std::vector<VirtualRowData> data;
708 g_deviceB->GetAllSyncData("sync_data", data);
709 EXPECT_EQ(data.size(), static_cast<size_t>(5000));
710 std::string checkSql = "select * from sync_data order by timestamp";
711 CheckSyncData(db, checkSql, data);
712 }
713
714 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest001, TestSize.Level1)
715 {
716 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
717 AddDeviceSchema(g_deviceB, db, "student_1");
718
719 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
720 EXPECT_EQ(status, OK);
721
722 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
723 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
724
725 std::vector<std::string> devices = {DEVICE_B};
726 Query query = Query::Select("sTudENT_1");
727 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa91b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 728 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
729 EXPECT_EQ(devicesMap.size(), devices.size());
730 }, true);
731 EXPECT_EQ(status, OK);
732
733 std::vector<VirtualRowData> data;
734 g_deviceB->GetAllSyncData("student_1", data);
735 EXPECT_EQ(data.size(), 1u);
736 }
737
738 namespace {
739 struct StudentInOrder {
740 int id_;
741 std::string name_;
742 int level_;
743 int score_;
744
operator ()__anonef37cfa91c11::StudentInOrder745 VirtualRowData operator() () const
746 {
747 VirtualRowData virtualRowData;
748 DataValue d1;
749 d1 = (int64_t)id_;
750 virtualRowData.objectData.PutDataValue("id", d1);
751 DataValue d2;
752 d2.SetText(name_);
753 virtualRowData.objectData.PutDataValue("name", d2);
754 DataValue d3;
755 d3 = (int64_t)level_;
756 virtualRowData.objectData.PutDataValue("level", d3);
757 DataValue d4;
758 d4 = (int64_t)score_;
759 virtualRowData.objectData.PutDataValue("score", d4);
760 virtualRowData.logInfo.dataKey = 3; // 3 fake datakey
761 virtualRowData.logInfo.device = DEVICE_B;
762 virtualRowData.logInfo.originDev = DEVICE_B;
763 virtualRowData.logInfo.timestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
764 virtualRowData.logInfo.wTimestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
765 virtualRowData.logInfo.flag = 2; // 2 fake flag
766
767 std::vector<uint8_t> hashKey;
768 DBCommon::CalcValueHash({}, hashKey);
769 virtualRowData.logInfo.hashKey = hashKey;
770 return virtualRowData;
771 }
772 };
773 }
774
775 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest002, TestSize.Level1)
776 {
777 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
778 AddDeviceSchema(g_deviceB, db, "student_1");
779
780 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
781 EXPECT_EQ(status, OK);
782
783 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
784
785 std::vector<std::string> devices = {DEVICE_B};
786 Query query = Query::Select("sTudENT_1");
787 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonef37cfa91d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 788 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
789 EXPECT_EQ(devicesMap.size(), devices.size());
790 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
791 }, true);
792 EXPECT_EQ(status, OK);
793
794 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonef37cfa91e02(sqlite3_stmt *stmt) 795 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
796 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1);
797 return OK;
798 });
799
800 status = delegate->RemoveDeviceData(DEVICE_B, "sTudENT_1");
801 EXPECT_EQ(status, OK);
802
__anonef37cfa91f02(sqlite3_stmt *stmt) 803 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
804 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 0);
805 return OK;
806 });
807 }
808
809 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest001, TestSize.Level1)
810 {
811 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
812 AddDeviceSchema(g_deviceB, db, "student_1");
813 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
814
815 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
816 AddDeviceSchema(g_deviceB, db, "student_1");
817
818 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
819 EXPECT_EQ(status, OK);
820
821 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 4, 95);";
822 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
823
824 std::vector<std::string> devices = {DEVICE_B};
825 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 : id
826 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa92002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 827 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
828 EXPECT_EQ(devicesMap.size(), devices.size());
829 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
830 }, true);
831 EXPECT_EQ(status, OK);
832
833 std::vector<VirtualRowData> data;
834 g_deviceB->GetAllSyncData("student_1", data);
835 EXPECT_EQ(data.size(), 1u);
836 DataValue value;
837 data[0].objectData.GetDataValue("id", value);
838 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
839 int64_t intVal;
840 value.GetInt64(intVal);
841 EXPECT_EQ(intVal, (int64_t)1001); // 1001 : id
842
843 data[0].objectData.GetDataValue("name", value);
844 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_TEXT);
845 std::string strVal;
846 value.GetText(strVal);
847 EXPECT_EQ(strVal, "xue");
848
849 data[0].objectData.GetDataValue("level", value);
850 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
851 value.GetInt64(intVal);
852 EXPECT_EQ(intVal, (int64_t)4); // 4 level
853
854 data[0].objectData.GetDataValue("score", value);
855 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
856 value.GetInt64(intVal);
857 EXPECT_EQ(intVal, (int64_t)95); // 95 score
858 }
859
860 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest002, TestSize.Level1)
861 {
862 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
863 AddDeviceSchema(g_deviceB, db, "student_1");
864 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
865
866 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
867
868 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
869
870 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
871 EXPECT_EQ(status, OK);
872
873 std::vector<std::string> devices = {DEVICE_B};
874 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 id
875 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonef37cfa92102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 876 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
877 EXPECT_EQ(devicesMap.size(), devices.size());
878 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
879 }, true);
880 EXPECT_EQ(status, OK);
881
882 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonef37cfa92202(sqlite3_stmt *stmt) 883 RelationalTestUtils::ExecSql(db, "select * from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
884 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1001); // 1001 id
885 std::string value;
886 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, value), E_OK);
887 EXPECT_EQ(value, "xue");
888 EXPECT_EQ(sqlite3_column_int64(stmt, 2), 4); // 4 level
889 EXPECT_EQ(sqlite3_column_int64(stmt, 3), 91); // 91 score
890 return OK;
891 });
892 }
893
894 /**
895 * @tc.name: SyncZeroBlobTest001
896 * @tc.desc: Sync device with zero blob
897 * @tc.type: FUNC
898 * @tc.require:
899 * @tc.author: lianhuix
900 */
901 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest001, TestSize.Level1)
902 {
903 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
904 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
905 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
906
907 // prepare with zero blob data
908 std::string insertSql = "INSERT INTO tbl_all_type VALUES(?, ?, ?, ?, ?, ?)";
__anonef37cfa92302(sqlite3_stmt *stmt) 909 int ret = RelationalTestUtils::ExecSql(db, insertSql, [] (sqlite3_stmt *stmt) {
910 sqlite3_bind_int64(stmt, 1, 1001); // 1, 1001 bind index, bind value
911 sqlite3_bind_int64(stmt, 2, 12344); // 2, 12344 bind index, bind value
912 sqlite3_bind_double(stmt, 3, 1.234); // 3, 1.234 bind index, bind value
913 SQLiteUtils::BindTextToStatement(stmt, 4, ""); // 4, bind index
914 SQLiteUtils::BindBlobToStatement(stmt, 5, {}); // 5,bind index
915 return E_OK;
916 }, nullptr);
917 EXPECT_EQ(ret, E_OK);
918
919 std::vector<std::string> devices = {DEVICE_B};
920 Query query = Query::Select("tbl_all_type");
921 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa92402(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 922 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
923 EXPECT_EQ(devicesMap.size(), devices.size());
924 for (const auto &itDev : devicesMap) {
925 for (const auto &itTbl : itDev.second) {
926 EXPECT_EQ(itTbl.status, OK);
927 }
928 }
929 }, true);
930 EXPECT_EQ(errCode, OK);
931
932 std::vector<VirtualRowData> data;
933 g_deviceB->GetAllSyncData("tbl_all_type", data);
934 EXPECT_EQ(data.size(), 1U);
935 for (const auto &it : data) {
936 DataValue val;
937 it.objectData.GetDataValue("id", val);
938 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
939 it.objectData.GetDataValue("f_int", val);
940 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
941 it.objectData.GetDataValue("f_real", val);
942 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_REAL);
943 it.objectData.GetDataValue("f_text", val);
944 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_TEXT);
945 it.objectData.GetDataValue("f_blob", val);
946 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_BLOB);
947 it.objectData.GetDataValue("f_none", val);
948 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_NULL);
949 }
950 }
951
952 namespace {
953 struct TblAllType {
954 DataValue id_;
955 DataValue fInt_;
956 DataValue fReal_;
957 DataValue fText_;
958 DataValue fBlob_;
959 DataValue fNone_;
960
TblAllType__anonef37cfa92511::TblAllType961 TblAllType(int64_t id, int64_t fInt, double fReal, const std::string &fText, const Blob &fBlob)
962 {
963 id_ = id;
964 fInt_ = fInt;
965 fReal_ = fReal;
966 fText_ = fText;
967 fBlob_ = fBlob;
968 }
969
operator ()__anonef37cfa92511::TblAllType970 VirtualRowData operator() () const
971 {
972 VirtualRowData virtualRowData;
973 virtualRowData.objectData.PutDataValue("id", id_);
974 virtualRowData.objectData.PutDataValue("f_int", fInt_);
975 virtualRowData.objectData.PutDataValue("f_real", fReal_);
976 virtualRowData.objectData.PutDataValue("f_text", fText_);
977 virtualRowData.objectData.PutDataValue("f_blob", fBlob_);
978 virtualRowData.objectData.PutDataValue("f_none", fNone_);
979
980 virtualRowData.logInfo.dataKey = 4; // 4 fake datakey
981 virtualRowData.logInfo.device = DEVICE_B;
982 virtualRowData.logInfo.originDev = DEVICE_B;
983 virtualRowData.logInfo.timestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
984 virtualRowData.logInfo.wTimestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
985 virtualRowData.logInfo.flag = 2; // 2 fake flag
986
987 std::vector<uint8_t> hashKey;
988 DBCommon::CalcValueHash({}, hashKey);
989 virtualRowData.logInfo.hashKey = hashKey;
990 return virtualRowData;
991 }
992 };
993 }
994
995 /**
996 * @tc.name: SyncZeroBlobTest002
997 * @tc.desc: Sync device with zero blob
998 * @tc.type: FUNC
999 * @tc.require:
1000 * @tc.author: lianhuix
1001 */
1002 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest002, TestSize.Level1)
1003 {
1004 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
1005 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
1006 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
1007
1008 std::vector<VirtualRowData> dataList;
1009 g_deviceB->PutDeviceData("tbl_all_type",
1010 std::vector<TblAllType> {{1001, 12344, 1.234, "", {}}}); // 1001, 12344, 1.234 : fake data
1011
1012 std::vector<std::string> devices = {DEVICE_B};
1013 Query query = Query::Select("tbl_all_type");
1014 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonef37cfa92602(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1015 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1016 EXPECT_EQ(devicesMap.size(), devices.size());
1017 for (const auto &itDev : devicesMap) {
1018 for (const auto &itTbl : itDev.second) {
1019 EXPECT_EQ(itTbl.status, OK);
1020 }
1021 }
1022 }, true);
1023 EXPECT_EQ(errCode, OK);
1024
1025 std::string devictTbl = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "tbl_all_type");
1026 std::string insertSql = "SELECT * FROM " + devictTbl;
1027 int resCnt = 0;
__anonef37cfa92702(sqlite3_stmt *stmt) 1028 int ret = RelationalTestUtils::ExecSql(db, insertSql, nullptr, [&resCnt](sqlite3_stmt *stmt) {
1029 EXPECT_EQ(sqlite3_column_type(stmt, 0), SQLITE_INTEGER);
1030 EXPECT_EQ(sqlite3_column_int(stmt, 0), 1001); // 1001: fake data
1031
1032 EXPECT_EQ(sqlite3_column_type(stmt, 1), SQLITE_INTEGER); // 1: column index
1033 EXPECT_EQ(sqlite3_column_int(stmt, 1), 12344); // 1: column index; 12344: fake data
1034
1035 EXPECT_EQ(sqlite3_column_type(stmt, 2), SQLITE_FLOAT); // 2: column index
1036 EXPECT_EQ(sqlite3_column_double(stmt, 2), 1.234); // 2: column index; 1.234: fake data
1037
1038 EXPECT_EQ(sqlite3_column_type(stmt, 3), SQLITE_TEXT); // 3: column index
1039 std::string strVal;
1040 SQLiteUtils::GetColumnTextValue(stmt, 3, strVal); // 3: column index
1041 EXPECT_EQ(strVal, "");
1042
1043 EXPECT_EQ(sqlite3_column_type(stmt, 4), SQLITE_BLOB); // 4: column index
1044 std::vector<uint8_t> blobVal;
1045 SQLiteUtils::GetColumnBlobValue(stmt, 4, blobVal); // 4: column index
1046 EXPECT_EQ(blobVal, std::vector<uint8_t> {});
1047
1048 EXPECT_EQ(sqlite3_column_type(stmt, 5), SQLITE_NULL); // 5: column index
1049 resCnt++;
1050 return E_OK;
1051 });
1052 EXPECT_EQ(resCnt, 1);
1053 EXPECT_EQ(ret, E_OK);
1054 }
1055
1056 /**
1057 * @tc.name: RuntimeConfig001
1058 * @tc.desc: Runtime config api
1059 * @tc.type: FUNC
1060 * @tc.require:
1061 * @tc.author: zhangqiquan
1062 */
1063 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RuntimeConfig001, TestSize.Level1)
1064 {
1065 DBStatus status = RuntimeConfig::SetProcessLabel("", "");
1066 EXPECT_EQ(status, INVALID_ARGS);
1067 status = RuntimeConfig::SetProcessLabel("DistributedDBInterfacesRelationalSyncTest", "RuntimeConfig001");
1068 EXPECT_EQ(status, OK);
1069 status = RuntimeConfig::SetProcessCommunicator(nullptr);
1070 if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) {
1071 EXPECT_EQ(status, OK);
1072 }
1073 EXPECT_EQ(RuntimeConfig::IsProcessSystemApiAdapterValid(),
1074 RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid());
1075 }
1076
1077 /**
1078 * @tc.name: RelationalSyncRangeTest001
1079 * @tc.desc: Test with sync interface, range query is not support
1080 * @tc.type: FUNC
1081 * @tc.require:
1082 * @tc.author: mazhao
1083 */
1084 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncRangeTest001, TestSize.Level1)
1085 {
1086 std::vector<std::string> devices = {DEVICE_A};
1087 Query query = Query::Select("sync_data").Range({}, {});
1088 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonef37cfa92802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1089 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1090 EXPECT_EQ(devicesMap.size(), devices.size());
1091 }, true);
1092
1093 EXPECT_EQ(errCode, NOT_SUPPORT);
1094 }
1095
1096 /**
1097 * @tc.name: RelationalSyncTest011
1098 * @tc.desc: Test sync with invalid parm
1099 * @tc.type: FUNC
1100 * @tc.require:
1101 * @tc.author: caihaoting
1102 */
1103 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest011, TestSize.Level1)
1104 {
1105 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1106 ASSERT_NE(db, nullptr);
1107 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1108 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS t2(a INT, b TEXT)"), SQLITE_OK);
1109 AddDeviceSchema(g_deviceB, db, "t2");
1110 RelationalStoreDelegate *delegate = nullptr;
1111 auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1112 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID,
1113 { .observer = observer }, delegate);
1114 EXPECT_EQ(status, OK);
1115 ASSERT_NE(delegate, nullptr);
1116 EXPECT_EQ(delegate->CreateDistributedTable("t2"), OK);
1117
1118 std::vector<std::string> devices = {DEVICE_B};
1119 Query query = Query::Select("t2");
1120 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, query, nullptr, true), NOT_SUPPORT);
1121
1122 auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1123 EXPECT_EQ(relationalStoreImpl->Close(), OK);
1124 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true), DB_ERROR);
1125
1126 std::mutex dataMutex;
1127 std::condition_variable cv;
1128 bool finish = false;
__anonef37cfa92902(const std::map<std::string, SyncProcess> &process) 1129 auto callback = [&cv, &dataMutex, &finish, &status](const std::map<std::string, SyncProcess> &process) {
1130 for (const auto &item: process) {
1131 if (item.second.process == DistributedDB::FINISHED) {
1132 {
1133 EXPECT_EQ(item.second.errCode, status);
1134 std::lock_guard<std::mutex> autoLock(dataMutex);
1135 finish = true;
1136 }
1137 cv.notify_one();
1138 }
1139 }
1140 };
1141 int64_t syncWaitTime = 60;
1142 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, callback, syncWaitTime), DB_ERROR);
1143
1144 CloudSyncOption option;
1145 option.devices = devices;
1146 option.mode = SyncMode::SYNC_MODE_PULL_ONLY;
1147 option.query = query;
1148 option.waitTime = syncWaitTime;
1149 EXPECT_EQ(delegate->Sync(option, callback), DB_ERROR);
1150
1151 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1152 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1153 delete observer;
1154 }
1155