• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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