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: AR000GK58F
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,
__anonf1fa0da10302(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: AR000GK58F
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,
__anonf1fa0da10402(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: AR000GK58F
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,
__anonf1fa0da10502(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: AR000GK58F
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,
__anonf1fa0da10602(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: AR000GK58F
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,
__anonf1fa0da10702(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: AR000GK58F
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,
__anonf1fa0da10802(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: AR000GK58F
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,
__anonf1fa0da10902(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: AR000GK58F
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,
__anonf1fa0da10a02(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,
__anonf1fa0da10b02(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: AR000GK58F
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,
__anonf1fa0da10c02(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,
__anonf1fa0da10d02(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,
__anonf1fa0da10e02(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: AR000GK58F
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,
__anonf1fa0da10f02(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,
__anonf1fa0da11002(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,
__anonf1fa0da11102(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: AR000GK58F
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, DBConstant::RELATIONAL_PREFIX + "student_1" + "_log");
509 EXPECT_EQ(cnt, 2);
510 }
511
512 /**
513 * @tc.name: UpgradeTriggerTest001
514 * @tc.desc: Test upgrade from old version
515 * @tc.type: FUNC
516 * @tc.require: AR000GK58F
517 * @tc.author: lianhuix
518 */
519 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, UpgradeTriggerTest001, TestSize.Level1)
520 {
521 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
522 RelationalTestUtils::CreateDeviceTable(db, "student_1", DEVICE_A);
523
524 DBStatus status = delegate->CreateDistributedTable("student_1");
525 EXPECT_EQ(status, OK);
526
527 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
528 delegate = nullptr;
529
530 FakeOldVersionDB(db);
531
532 status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, {}, delegate);
533 EXPECT_EQ(status, OK);
534 ASSERT_NE(delegate, nullptr);
535
536 // checkTrigger
537 std::string resultTrigger;
538 int errCode = RelationalTestUtils::ExecSql(db, "SELECT sql FROM sqlite_master WHERE type = ? AND name = ?",
__anonf1fa0da11202(sqlite3_stmt *stmt) 539 [](sqlite3_stmt *stmt) {
540 (void)SQLiteUtils::BindTextToStatement(stmt, 1, "trigger"); // 1: bind index
541 (void)SQLiteUtils::BindTextToStatement(stmt, 2, "naturalbase_rdb_student_1_ON_UPDATE"); // 2: bind index
542 return E_OK;
543 }, [&resultTrigger](sqlite3_stmt *stmt) {
544 (void)SQLiteUtils::GetColumnTextValue(stmt, 0, resultTrigger);
545 return E_OK;
546 });
547 EXPECT_EQ(errCode, E_OK);
548 LOGD("result trigger: %s", resultTrigger.c_str());
549 std::string expectTrigger = "CREATE TRIGGER naturalbase_rdb_student_1_ON_UPDATE AFTER UPDATE \n"
550 "ON 'student_1'\n"
551 "BEGIN\n"
552 "\t UPDATE naturalbase_rdb_aux_student_1_log SET data_key=-1,timestamp=get_sys_time(0), device='',"
553 " flag=0x03 WHERE hash_key=calc_hash(OLD.'id', 0) AND flag&0x02=0x02;\n"
554 "\t INSERT OR REPLACE INTO naturalbase_rdb_aux_student_1_log VALUES (NEW._rowid_, '', '', get_sys_time(0), "
555 "get_last_time(), CASE WHEN (calc_hash(NEW.'id', 0) != calc_hash(NEW.'id', 0)) " \
556 "THEN 0x02 ELSE 0x22 END, calc_hash(NEW.'id', 0), '', '', '', '', '', 0);\n"
557 "END";
558 EXPECT_TRUE(resultTrigger == expectTrigger);
559 }
560
561
562 namespace {
PrepareSyncData(sqlite3 * db,int dataSize)563 void PrepareSyncData(sqlite3 *db, int dataSize)
564 {
565 int i = 1;
566 std::string insertSql = "INSERT INTO sync_data VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
567 int ret = RelationalTestUtils::ExecSql(db, insertSql, [&i, dataSize] (sqlite3_stmt *stmt) {
568 SQLiteUtils::BindTextToStatement(stmt, 1, "KEY_" + std::to_string(i));
569 SQLiteUtils::BindTextToStatement(stmt, 2, "VAL_" + std::to_string(i));
570 sqlite3_bind_int64(stmt, 3, 1000000 - (1000 + i));
571 sqlite3_bind_int64(stmt, 4, i % 4);
572 SQLiteUtils::BindTextToStatement(stmt, 5, "DEV_" + std::to_string(i));
573 SQLiteUtils::BindTextToStatement(stmt, 6, "KEY_" + std::to_string(i));
574 SQLiteUtils::BindTextToStatement(stmt, 7, "HASHKEY_" + std::to_string(i));
575 sqlite3_bind_int64(stmt, 8, 1000 + i);
576 return (i++ == dataSize) ? E_OK : -E_UNFINISHED;
577 }, nullptr);
578 EXPECT_EQ(ret, E_OK);
579 }
580
GetKey(VirtualRowData rowData)581 std::string GetKey(VirtualRowData rowData)
582 {
583 DataValue dataVal;
584 rowData.objectData.GetDataValue("key", dataVal);
585 EXPECT_EQ(dataVal.GetType(), StorageType::STORAGE_TYPE_TEXT);
586 std::string dataStr;
587 EXPECT_EQ(dataVal.GetText(dataStr), E_OK);
588 return dataStr;
589 }
590
CheckSyncData(sqlite3 * db,const std::string & checkSql,const std::vector<VirtualRowData> & resultData)591 void CheckSyncData(sqlite3 *db, const std::string &checkSql, const std::vector<VirtualRowData> &resultData)
592 {
593 std::set<std::string> keySet;
594 keySet.clear();
595 for (size_t i = 0; i < resultData.size(); i++) {
596 std::string ss = GetKey(resultData[i]);
597 keySet.insert(ss);
598 }
599 EXPECT_EQ(keySet.size(), resultData.size());
600
601 RelationalTestUtils::ExecSql(db, checkSql, nullptr, [keySet](sqlite3_stmt *stmt) {
602 std::string val;
603 SQLiteUtils::GetColumnTextValue(stmt, 0, val);
604 EXPECT_NE(keySet.find(val), keySet.end());
605 return E_OK;
606 });
607 }
608 }
609
610 /**
611 * @tc.name: SyncLimitTest001
612 * @tc.desc: Sync device with limit query
613 * @tc.type: FUNC
614 * @tc.require:
615 * @tc.author: lianhuix
616 */
617 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest001, TestSize.Level3)
618 {
619 PrepareSyncData(db, 5000);
620 std::vector<std::string> devices = {DEVICE_B};
621 Query query = Query::Select("sync_data").Limit(4500, 100);
622 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11702(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 623 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
624 EXPECT_EQ(devicesMap.size(), devices.size());
625 }, true);
626 EXPECT_EQ(errCode, OK);
627
628 std::vector<VirtualRowData> data;
629 g_deviceB->GetAllSyncData("sync_data", data);
630 EXPECT_EQ(data.size(), static_cast<size_t>(4500));
631 std::string checkSql = "select * from sync_data limit 4500 offset 100;";
632 CheckSyncData(db, checkSql, data);
633 }
634
635 /**
636 * @tc.name: SyncLimitTest002
637 * @tc.desc: Sync device with limit query
638 * @tc.type: FUNC
639 * @tc.require:
640 * @tc.author: lianhuix
641 */
642 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest002, TestSize.Level3)
643 {
644 PrepareSyncData(db, 5000);
645
646 std::vector<std::string> devices = {DEVICE_B};
647 Query query = Query::Select("sync_data").Limit(5000, 2000);
648 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 649 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
650 EXPECT_EQ(devicesMap.size(), devices.size());
651 }, true);
652 EXPECT_EQ(errCode, OK);
653
654 std::vector<VirtualRowData> data;
655 g_deviceB->GetAllSyncData("sync_data", data);
656 EXPECT_EQ(data.size(), static_cast<size_t>(3000));
657 std::string checkSql = "select * from sync_data limit 5000 offset 2000;";
658 CheckSyncData(db, checkSql, data);
659 }
660
661 /**
662 * @tc.name: SyncLimitTest003
663 * @tc.desc: Sync device with limit query
664 * @tc.type: FUNC
665 * @tc.require:
666 * @tc.author: lianhuix
667 */
668 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncLimitTest003, TestSize.Level3)
669 {
670 PrepareSyncData(db, 5000);
671
672 std::vector<std::string> devices = {DEVICE_B};
673 Query query = Query::Select("sync_data").OrderBy("timestamp").Limit(4500, 1500);
674 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11902(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 675 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
676 EXPECT_EQ(devicesMap.size(), devices.size());
677 }, true);
678 EXPECT_EQ(errCode, OK);
679
680 std::vector<VirtualRowData> data;
681 g_deviceB->GetAllSyncData("sync_data", data);
682 EXPECT_EQ(data.size(), static_cast<size_t>(3500));
683 std::string checkSql = "select * from sync_data order by timestamp limit 4500 offset 1500;";
684 CheckSyncData(db, checkSql, data);
685 }
686
687 /**
688 * @tc.name: SyncOrderByTest001
689 * @tc.desc: Sync device with limit query
690 * @tc.type: FUNC
691 * @tc.require:
692 * @tc.author: lianhuix
693 */
694 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncOrderByTest001, TestSize.Level3)
695 {
696 PrepareSyncData(db, 5000);
697
698 std::vector<std::string> devices = {DEVICE_B};
699 Query query = Query::Select("sync_data").OrderBy("timestamp");
700 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11a02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 701 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
702 EXPECT_EQ(devicesMap.size(), devices.size());
703 }, true);
704 EXPECT_EQ(errCode, OK);
705
706 std::vector<VirtualRowData> data;
707 g_deviceB->GetAllSyncData("sync_data", data);
708 EXPECT_EQ(data.size(), static_cast<size_t>(5000));
709 std::string checkSql = "select * from sync_data order by timestamp";
710 CheckSyncData(db, checkSql, data);
711 }
712
713 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest001, TestSize.Level1)
714 {
715 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
716 AddDeviceSchema(g_deviceB, db, "student_1");
717
718 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
719 EXPECT_EQ(status, OK);
720
721 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
722 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
723
724 std::vector<std::string> devices = {DEVICE_B};
725 Query query = Query::Select("sTudENT_1");
726 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da11b02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 727 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
728 EXPECT_EQ(devicesMap.size(), devices.size());
729 }, true);
730 EXPECT_EQ(status, OK);
731
732 std::vector<VirtualRowData> data;
733 g_deviceB->GetAllSyncData("student_1", data);
734 EXPECT_EQ(data.size(), 1u);
735 }
736
737 namespace {
738 struct StudentInOrder {
739 int id_;
740 std::string name_;
741 int level_;
742 int score_;
743
operator ()__anonf1fa0da11c10::StudentInOrder744 VirtualRowData operator() () const
745 {
746 VirtualRowData virtualRowData;
747 DataValue d1;
748 d1 = (int64_t)id_;
749 virtualRowData.objectData.PutDataValue("id", d1);
750 DataValue d2;
751 d2.SetText(name_);
752 virtualRowData.objectData.PutDataValue("name", d2);
753 DataValue d3;
754 d3 = (int64_t)level_;
755 virtualRowData.objectData.PutDataValue("level", d3);
756 DataValue d4;
757 d4 = (int64_t)score_;
758 virtualRowData.objectData.PutDataValue("score", d4);
759 virtualRowData.logInfo.dataKey = 3; // 3 fake datakey
760 virtualRowData.logInfo.device = DEVICE_B;
761 virtualRowData.logInfo.originDev = DEVICE_B;
762 virtualRowData.logInfo.timestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
763 virtualRowData.logInfo.wTimestamp = 3170194300890338180; // 3170194300890338180 fake timestamp
764 virtualRowData.logInfo.flag = 2; // 2 fake flag
765
766 std::vector<uint8_t> hashKey;
767 DBCommon::CalcValueHash({}, hashKey);
768 virtualRowData.logInfo.hashKey = hashKey;
769 return virtualRowData;
770 }
771 };
772 }
773
774 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableNameCaseInsensitiveTest002, TestSize.Level1)
775 {
776 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
777 AddDeviceSchema(g_deviceB, db, "student_1");
778
779 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
780 EXPECT_EQ(status, OK);
781
782 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
783
784 std::vector<std::string> devices = {DEVICE_B};
785 Query query = Query::Select("sTudENT_1");
786 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da11d02(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 787 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
788 EXPECT_EQ(devicesMap.size(), devices.size());
789 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
790 }, true);
791 EXPECT_EQ(status, OK);
792
793 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonf1fa0da11e02(sqlite3_stmt *stmt) 794 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
795 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1);
796 return OK;
797 });
798
799 status = delegate->RemoveDeviceData(DEVICE_B, "sTudENT_1");
800 EXPECT_EQ(status, OK);
801
__anonf1fa0da11f02(sqlite3_stmt *stmt) 802 RelationalTestUtils::ExecSql(db, "select count(*) from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
803 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 0);
804 return OK;
805 });
806 }
807
808 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest001, TestSize.Level1)
809 {
810 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
811 AddDeviceSchema(g_deviceB, db, "student_1");
812 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
813
814 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
815 AddDeviceSchema(g_deviceB, db, "student_1");
816
817 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
818 EXPECT_EQ(status, OK);
819
820 std::string insertSql = "insert into student_1 (id, name, level, score) values (1001, 'xue', 4, 95);";
821 EXPECT_EQ(RelationalTestUtils::ExecSql(db, insertSql), SQLITE_OK);
822
823 std::vector<std::string> devices = {DEVICE_B};
824 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 : id
825 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12002(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 826 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
827 EXPECT_EQ(devicesMap.size(), devices.size());
828 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
829 }, true);
830 EXPECT_EQ(status, OK);
831
832 std::vector<VirtualRowData> data;
833 g_deviceB->GetAllSyncData("student_1", data);
834 EXPECT_EQ(data.size(), 1u);
835 DataValue value;
836 data[0].objectData.GetDataValue("id", value);
837 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
838 int64_t intVal;
839 value.GetInt64(intVal);
840 EXPECT_EQ(intVal, (int64_t)1001); // 1001 : id
841
842 data[0].objectData.GetDataValue("name", value);
843 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_TEXT);
844 std::string strVal;
845 value.GetText(strVal);
846 EXPECT_EQ(strVal, "xue");
847
848 data[0].objectData.GetDataValue("level", value);
849 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
850 value.GetInt64(intVal);
851 EXPECT_EQ(intVal, (int64_t)4); // 4 level
852
853 data[0].objectData.GetDataValue("score", value);
854 EXPECT_EQ(value.GetType(), StorageType::STORAGE_TYPE_INTEGER);
855 value.GetInt64(intVal);
856 EXPECT_EQ(intVal, (int64_t)95); // 95 score
857 }
858
859 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, TableFieldsOrderTest002, TestSize.Level1)
860 {
861 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT_IN_ORDER), SQLITE_OK);
862 AddDeviceSchema(g_deviceB, db, "student_1");
863 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "DROP TABLE IF EXISTS student_1;"), SQLITE_OK);
864
865 g_deviceB->PutDeviceData("student_1", std::vector<StudentInOrder> {{1001, "xue", 4, 91}}); // 4, 91 fake data
866
867 EXPECT_EQ(RelationalTestUtils::ExecSql(db, NORMAL_CREATE_TABLE_SQL_STUDENT), SQLITE_OK);
868
869 DBStatus status = delegate->CreateDistributedTable("StUDent_1");
870 EXPECT_EQ(status, OK);
871
872 std::vector<std::string> devices = {DEVICE_B};
873 Query query = Query::Select("sTudENT_1").EqualTo("ID", 1001); // 1001 id
874 status = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da12102(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 875 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
876 EXPECT_EQ(devicesMap.size(), devices.size());
877 EXPECT_EQ(devicesMap.at(DEVICE_B)[0].status, OK);
878 }, true);
879 EXPECT_EQ(status, OK);
880
881 std::string deviceTableName = g_mgr.GetDistributedTableName(DEVICE_B, "student_1");
__anonf1fa0da12202(sqlite3_stmt *stmt) 882 RelationalTestUtils::ExecSql(db, "select * from " + deviceTableName + ";", nullptr, [] (sqlite3_stmt *stmt) {
883 EXPECT_EQ(sqlite3_column_int64(stmt, 0), 1001); // 1001 id
884 std::string value;
885 EXPECT_EQ(SQLiteUtils::GetColumnTextValue(stmt, 1, value), E_OK);
886 EXPECT_EQ(value, "xue");
887 EXPECT_EQ(sqlite3_column_int64(stmt, 2), 4); // 4 level
888 EXPECT_EQ(sqlite3_column_int64(stmt, 3), 91); // 91 score
889 return OK;
890 });
891 }
892
893 /**
894 * @tc.name: SyncZeroBlobTest001
895 * @tc.desc: Sync device with zero blob
896 * @tc.type: FUNC
897 * @tc.require:
898 * @tc.author: lianhuix
899 */
900 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest001, TestSize.Level1)
901 {
902 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
903 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
904 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
905
906 // prepare with zero blob data
907 std::string insertSql = "INSERT INTO tbl_all_type VALUES(?, ?, ?, ?, ?, ?)";
__anonf1fa0da12302(sqlite3_stmt *stmt) 908 int ret = RelationalTestUtils::ExecSql(db, insertSql, [] (sqlite3_stmt *stmt) {
909 sqlite3_bind_int64(stmt, 1, 1001); // 1, 1001 bind index, bind value
910 sqlite3_bind_int64(stmt, 2, 12344); // 2, 12344 bind index, bind value
911 sqlite3_bind_double(stmt, 3, 1.234); // 3, 1.234 bind index, bind value
912 SQLiteUtils::BindTextToStatement(stmt, 4, ""); // 4, bind index
913 SQLiteUtils::BindBlobToStatement(stmt, 5, {}); // 5,bind index
914 return E_OK;
915 }, nullptr);
916 EXPECT_EQ(ret, E_OK);
917
918 std::vector<std::string> devices = {DEVICE_B};
919 Query query = Query::Select("tbl_all_type");
920 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12402(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 921 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
922 EXPECT_EQ(devicesMap.size(), devices.size());
923 for (const auto &itDev : devicesMap) {
924 for (const auto &itTbl : itDev.second) {
925 EXPECT_EQ(itTbl.status, OK);
926 }
927 }
928 }, true);
929 EXPECT_EQ(errCode, OK);
930
931 std::vector<VirtualRowData> data;
932 g_deviceB->GetAllSyncData("tbl_all_type", data);
933 EXPECT_EQ(data.size(), 1U);
934 for (const auto &it : data) {
935 DataValue val;
936 it.objectData.GetDataValue("id", val);
937 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
938 it.objectData.GetDataValue("f_int", val);
939 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_INTEGER);
940 it.objectData.GetDataValue("f_real", val);
941 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_REAL);
942 it.objectData.GetDataValue("f_text", val);
943 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_TEXT);
944 it.objectData.GetDataValue("f_blob", val);
945 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_BLOB);
946 it.objectData.GetDataValue("f_none", val);
947 EXPECT_EQ(val.GetType(), StorageType::STORAGE_TYPE_NULL);
948 }
949 }
950
951 namespace {
952 struct TblAllType {
953 DataValue id_;
954 DataValue fInt_;
955 DataValue fReal_;
956 DataValue fText_;
957 DataValue fBlob_;
958 DataValue fNone_;
959
TblAllType__anonf1fa0da12510::TblAllType960 TblAllType(int64_t id, int64_t fInt, double fReal, const std::string &fText, const Blob &fBlob)
961 {
962 id_ = id;
963 fInt_ = fInt;
964 fReal_ = fReal;
965 fText_ = fText;
966 fBlob_ = fBlob;
967 }
968
operator ()__anonf1fa0da12510::TblAllType969 VirtualRowData operator() () const
970 {
971 VirtualRowData virtualRowData;
972 virtualRowData.objectData.PutDataValue("id", id_);
973 virtualRowData.objectData.PutDataValue("f_int", fInt_);
974 virtualRowData.objectData.PutDataValue("f_real", fReal_);
975 virtualRowData.objectData.PutDataValue("f_text", fText_);
976 virtualRowData.objectData.PutDataValue("f_blob", fBlob_);
977 virtualRowData.objectData.PutDataValue("f_none", fNone_);
978
979 virtualRowData.logInfo.dataKey = 4; // 4 fake datakey
980 virtualRowData.logInfo.device = DEVICE_B;
981 virtualRowData.logInfo.originDev = DEVICE_B;
982 virtualRowData.logInfo.timestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
983 virtualRowData.logInfo.wTimestamp = 3170194300891338180; // 3170194300891338180 fake timestamp
984 virtualRowData.logInfo.flag = 2; // 2 fake flag
985
986 std::vector<uint8_t> hashKey;
987 DBCommon::CalcValueHash({}, hashKey);
988 virtualRowData.logInfo.hashKey = hashKey;
989 return virtualRowData;
990 }
991 };
992 }
993
994 /**
995 * @tc.name: SyncZeroBlobTest002
996 * @tc.desc: Sync device with zero blob
997 * @tc.type: FUNC
998 * @tc.require:
999 * @tc.author: lianhuix
1000 */
1001 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, SyncZeroBlobTest002, TestSize.Level1)
1002 {
1003 EXPECT_EQ(RelationalTestUtils::ExecSql(db, ALL_FIELD_TYPE_TABLE_SQL), SQLITE_OK);
1004 EXPECT_EQ(delegate->CreateDistributedTable("tbl_all_type"), OK);
1005 AddDeviceSchema(g_deviceB, db, "tbl_all_type");
1006
1007 std::vector<VirtualRowData> dataList;
1008 g_deviceB->PutDeviceData("tbl_all_type",
1009 std::vector<TblAllType> {{1001, 12344, 1.234, "", {}}}); // 1001, 12344, 1.234 : fake data
1010
1011 std::vector<std::string> devices = {DEVICE_B};
1012 Query query = Query::Select("tbl_all_type");
1013 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query,
__anonf1fa0da12602(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1014 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1015 EXPECT_EQ(devicesMap.size(), devices.size());
1016 for (const auto &itDev : devicesMap) {
1017 for (const auto &itTbl : itDev.second) {
1018 EXPECT_EQ(itTbl.status, OK);
1019 }
1020 }
1021 }, true);
1022 EXPECT_EQ(errCode, OK);
1023
1024 std::string devictTbl = RelationalStoreManager::GetDistributedTableName(DEVICE_B, "tbl_all_type");
1025 std::string insertSql = "SELECT * FROM " + devictTbl;
1026 int resCnt = 0;
__anonf1fa0da12702(sqlite3_stmt *stmt) 1027 int ret = RelationalTestUtils::ExecSql(db, insertSql, nullptr, [&resCnt](sqlite3_stmt *stmt) {
1028 EXPECT_EQ(sqlite3_column_type(stmt, 0), SQLITE_INTEGER);
1029 EXPECT_EQ(sqlite3_column_int(stmt, 0), 1001); // 1001: fake data
1030
1031 EXPECT_EQ(sqlite3_column_type(stmt, 1), SQLITE_INTEGER); // 1: column index
1032 EXPECT_EQ(sqlite3_column_int(stmt, 1), 12344); // 1: column index; 12344: fake data
1033
1034 EXPECT_EQ(sqlite3_column_type(stmt, 2), SQLITE_FLOAT); // 2: column index
1035 EXPECT_EQ(sqlite3_column_double(stmt, 2), 1.234); // 2: column index; 1.234: fake data
1036
1037 EXPECT_EQ(sqlite3_column_type(stmt, 3), SQLITE_TEXT); // 3: column index
1038 std::string strVal;
1039 SQLiteUtils::GetColumnTextValue(stmt, 3, strVal); // 3: column index
1040 EXPECT_EQ(strVal, "");
1041
1042 EXPECT_EQ(sqlite3_column_type(stmt, 4), SQLITE_BLOB); // 4: column index
1043 std::vector<uint8_t> blobVal;
1044 SQLiteUtils::GetColumnBlobValue(stmt, 4, blobVal); // 4: column index
1045 EXPECT_EQ(blobVal, std::vector<uint8_t> {});
1046
1047 EXPECT_EQ(sqlite3_column_type(stmt, 5), SQLITE_NULL); // 5: column index
1048 resCnt++;
1049 return E_OK;
1050 });
1051 EXPECT_EQ(resCnt, 1);
1052 EXPECT_EQ(ret, E_OK);
1053 }
1054
1055 /**
1056 * @tc.name: RuntimeConfig001
1057 * @tc.desc: Runtime config api
1058 * @tc.type: FUNC
1059 * @tc.require:
1060 * @tc.author: zhangqiquan
1061 */
1062 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RuntimeConfig001, TestSize.Level1)
1063 {
1064 DBStatus status = RuntimeConfig::SetProcessLabel("", "");
1065 EXPECT_EQ(status, INVALID_ARGS);
1066 status = RuntimeConfig::SetProcessLabel("DistributedDBInterfacesRelationalSyncTest", "RuntimeConfig001");
1067 EXPECT_EQ(status, OK);
1068 status = RuntimeConfig::SetProcessCommunicator(nullptr);
1069 if (!RuntimeContext::GetInstance()->IsCommunicatorAggregatorValid()) {
1070 EXPECT_EQ(status, OK);
1071 }
1072 EXPECT_EQ(RuntimeConfig::IsProcessSystemApiAdapterValid(),
1073 RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid());
1074 }
1075
1076 /**
1077 * @tc.name: RelationalSyncRangeTest001
1078 * @tc.desc: Test with sync interface, range query is not support
1079 * @tc.type: FUNC
1080 * @tc.require: DTS2023112110763
1081 * @tc.author: mazhao
1082 */
1083 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncRangeTest001, TestSize.Level1)
1084 {
1085 std::vector<std::string> devices = {DEVICE_A};
1086 Query query = Query::Select("sync_data").Range({}, {});
1087 int errCode = delegate->Sync(devices, SyncMode::SYNC_MODE_PUSH_ONLY, query,
__anonf1fa0da12802(const std::map<std::string, std::vector<TableStatus>> &devicesMap) 1088 [&devices](const std::map<std::string, std::vector<TableStatus>> &devicesMap) {
1089 EXPECT_EQ(devicesMap.size(), devices.size());
1090 }, true);
1091
1092 EXPECT_EQ(errCode, NOT_SUPPORT);
1093 }
1094
1095 /**
1096 * @tc.name: RelationalSyncTest011
1097 * @tc.desc: Test sync with invalid parm
1098 * @tc.type: FUNC
1099 * @tc.require:
1100 * @tc.author: caihaoting
1101 */
1102 HWTEST_F(DistributedDBInterfacesRelationalSyncTest, RelationalSyncTest011, TestSize.Level1)
1103 {
1104 sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX);
1105 ASSERT_NE(db, nullptr);
1106 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK);
1107 EXPECT_EQ(RelationalTestUtils::ExecSql(db, "CREATE TABLE IF NOT EXISTS t2(a INT, b TEXT)"), SQLITE_OK);
1108 AddDeviceSchema(g_deviceB, db, "t2");
1109 RelationalStoreDelegate *delegate = nullptr;
1110 auto observer = new (std::nothrow) RelationalStoreObserverUnitTest();
1111 DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID,
1112 { .observer = observer }, delegate);
1113 EXPECT_EQ(status, OK);
1114 ASSERT_NE(delegate, nullptr);
1115 EXPECT_EQ(delegate->CreateDistributedTable("t2"), OK);
1116
1117 std::vector<std::string> devices = {DEVICE_B};
1118 Query query = Query::Select("t2");
1119 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, query, nullptr, true), NOT_SUPPORT);
1120
1121 auto relationalStoreImpl = static_cast<RelationalStoreDelegateImpl *>(delegate);
1122 EXPECT_EQ(relationalStoreImpl->Close(), OK);
1123 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, nullptr, true), DB_ERROR);
1124
1125 std::mutex dataMutex;
1126 std::condition_variable cv;
1127 bool finish = false;
__anonf1fa0da12902(const std::map<std::string, SyncProcess> &process) 1128 auto callback = [&cv, &dataMutex, &finish, &status](const std::map<std::string, SyncProcess> &process) {
1129 for (const auto &item: process) {
1130 if (item.second.process == DistributedDB::FINISHED) {
1131 {
1132 EXPECT_EQ(item.second.errCode, status);
1133 std::lock_guard<std::mutex> autoLock(dataMutex);
1134 finish = true;
1135 }
1136 cv.notify_one();
1137 }
1138 }
1139 };
1140 int64_t syncWaitTime = 60;
1141 EXPECT_EQ(delegate->Sync(devices, SyncMode::SYNC_MODE_PULL_ONLY, query, callback, syncWaitTime), DB_ERROR);
1142
1143 CloudSyncOption option;
1144 option.devices = devices;
1145 option.mode = SyncMode::SYNC_MODE_PULL_ONLY;
1146 option.query = query;
1147 option.waitTime = syncWaitTime;
1148 EXPECT_EQ(delegate->Sync(option, callback), DB_ERROR);
1149
1150 EXPECT_EQ(g_mgr.CloseStore(delegate), OK);
1151 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
1152 delete observer;
1153 }
1154