• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "db_types.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "kvdb_properties.h"
24 #include "log_print.h"
25 #include "prepared_stmt.h"
26 #include "relational_row_data_set.h"
27 #include "relational_store_delegate.h"
28 #include "relational_store_instance.h"
29 #include "relational_store_manager.h"
30 #include "relational_store_sqlite_ext.h"
31 #include "relational_sync_able_storage.h"
32 #include "sqlite_relational_store.h"
33 #include "sqlite_utils.h"
34 #include "virtual_communicator_aggregator.h"
35 
36 using namespace testing::ext;
37 using namespace DistributedDB;
38 using namespace DistributedDBUnitTest;
39 using namespace std;
40 
41 namespace {
42 string g_testDir;
43 string g_storePath;
44 string g_storeID = "dftStoreID";
45 string g_tableName { "data" };
46 DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID);
47 RelationalStoreDelegate *g_delegate = nullptr;
48 IRelationalStore *g_store = nullptr;
49 
CreateDBAndTable()50 void CreateDBAndTable()
51 {
52     sqlite3 *db = nullptr;
53     int errCode = sqlite3_open(g_storePath.c_str(), &db);
54     if (errCode != SQLITE_OK) {
55         LOGE("open db failed:%d", errCode);
56         sqlite3_close(db);
57         return;
58     }
59 
60     const string sql =
61         "PRAGMA journal_mode=WAL;"
62         "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
63     char *zErrMsg = nullptr;
64     errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
65     if (errCode != SQLITE_OK) {
66         LOGE("sql error:%s", zErrMsg);
67         sqlite3_free(zErrMsg);
68     }
69     sqlite3_close(db);
70 }
71 
InitStoreProp(const std::string & storePath,const std::string & appId,const std::string & userId,RelationalDBProperties & properties)72 void InitStoreProp(const std::string &storePath, const std::string &appId, const std::string &userId,
73     RelationalDBProperties &properties)
74 {
75     properties.SetStringProp(RelationalDBProperties::DATA_DIR, storePath);
76     properties.SetStringProp(RelationalDBProperties::APP_ID, appId);
77     properties.SetStringProp(RelationalDBProperties::USER_ID, userId);
78     properties.SetStringProp(RelationalDBProperties::STORE_ID, g_storeID);
79     std::string identifier = userId + "-" + appId + "-" + g_storeID;
80     std::string hashIdentifier = DBCommon::TransferHashString(identifier);
81     properties.SetStringProp(RelationalDBProperties::IDENTIFIER_DATA, hashIdentifier);
82 }
83 
GetRelationalStore()84 const RelationalSyncAbleStorage *GetRelationalStore()
85 {
86     RelationalDBProperties properties;
87     InitStoreProp(g_storePath, APP_ID, USER_ID, properties);
88     int errCode = E_OK;
89     g_store = RelationalStoreInstance::GetDataBase(properties, errCode);
90     if (g_store == nullptr) {
91         LOGE("Get db failed:%d", errCode);
92         return nullptr;
93     }
94     return static_cast<SQLiteRelationalStore *>(g_store)->GetStorageEngine();
95 }
96 
ExecSql(sqlite3 * db,const std::string & sql)97 int ExecSql(sqlite3 *db, const std::string &sql)
98 {
99     return sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr);
100 }
101 
InsertData(sqlite3 * db,size_t byteSize)102 int InsertData(sqlite3 *db, size_t byteSize)
103 {
104     static const std::string sql = "INSERT OR REPLACE INTO " + g_tableName + " VALUES(?,?);";
105     sqlite3_stmt *stmt = nullptr;
106     int errCode = SQLiteUtils::GetStatement(db, sql, stmt);
107     if (errCode != E_OK) {
108         return errCode;
109     }
110     std::vector<uint8_t> value(byteSize);
111     errCode = SQLiteUtils::BindBlobToStatement(stmt, 2, value, false);  // 2 means value's index.
112     if (errCode != E_OK) {
113         return errCode;
114     }
115     errCode = SQLiteUtils::StepWithRetry(stmt);
116     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
117         errCode = E_OK;
118     }
119     SQLiteUtils::ResetStatement(stmt, true, errCode);
120     return errCode;
121 }
122 }
123 
124 class DistributedDBRelationalRemoteQueryTest : public testing::Test {
125 public:
126     static void SetUpTestCase();
127     static void TearDownTestCase();
128     void SetUp();
129     void TearDown();
130 };
131 
SetUpTestCase(void)132 void DistributedDBRelationalRemoteQueryTest::SetUpTestCase(void)
133 {
134     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
135     g_storePath = g_testDir + "/relationalRemoteQueryTest.db";
136     LOGI("The test db is:%s", g_testDir.c_str());
137 
138     auto communicator = new (std::nothrow) VirtualCommunicatorAggregator();
139     ASSERT_TRUE(communicator != nullptr);
140     RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicator);
141 }
142 
TearDownTestCase(void)143 void DistributedDBRelationalRemoteQueryTest::TearDownTestCase(void)
144 {
145     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
146 }
147 
SetUp(void)148 void DistributedDBRelationalRemoteQueryTest::SetUp(void)
149 {
150     g_tableName = "data";
151     DistributedDBToolsUnitTest::PrintTestCaseInfo();
152     CreateDBAndTable();
153 }
154 
TearDown(void)155 void DistributedDBRelationalRemoteQueryTest::TearDown(void)
156 {
157     if (g_delegate != nullptr) {
158         EXPECT_EQ(g_mgr.CloseStore(g_delegate), DBStatus::OK);
159         g_delegate = nullptr;
160     }
161     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
162         LOGE("rm test db files error.");
163     }
164     return;
165 }
166 
167 /**
168  * @tc.name: NormalQuery1
169  * @tc.desc: Normal query.
170  * @tc.type: FUNC
171  * @tc.require: AR000GK58G
172  * @tc.author: lidongwei
173  */
174 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NormalQuery1, TestSize.Level1)
175 {
176     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
177     ASSERT_NE(g_delegate, nullptr);
178     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
179 
180     /**
181      * @tc.steps: step1. Put data.
182      * @tc.expected: Succeed, return OK.
183      */
184     sqlite3 *db = nullptr;
185     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
186     ASSERT_NE(db, nullptr);
187 
188     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
189     sqlite3_close(db);
190 
191     /**
192      * @tc.steps: step2. Query with QUERY opcode and a select sql.
193      * @tc.expected: Query successfully.
194      */
195     auto store = GetRelationalStore();
196 
197     ASSERT_NE(store, nullptr);
198     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
199     RelationalRowDataSet rowDataSet {};
200     ContinueToken token = nullptr;
201     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
202     EXPECT_EQ(rowDataSet.GetSize(), 1);
203     EXPECT_EQ(token, nullptr);
204     RefObject::DecObjRef(g_store);
205 }
206 
207 /**
208  * @tc.name: BoolQuery1
209  * @tc.desc: Query bool.
210  * @tc.type: FUNC
211  * @tc.require: AR000GK58G
212  * @tc.author: lidongwei
213  */
214 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BoolQuery1, TestSize.Level1)
215 {
216     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
217     ASSERT_NE(g_delegate, nullptr);
218     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
219 
220     /**
221      * @tc.steps: step1. Put data.
222      * @tc.expected: Succeed, return OK.
223      */
224     sqlite3 *db = nullptr;
225     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
226     ASSERT_NE(db, nullptr);
227 
228     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"), 0);
229     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(2, '1');"), 0);
230     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(3, true);"), 0);
231     sqlite3_close(db);
232 
233     /**
234      * @tc.steps: step2. Check bool.
235      * @tc.expected: '1' and 1 and true in sql is OK. 1 in bindArgs is OK.
236      */
237     auto store = GetRelationalStore();
238     ASSERT_NE(store, nullptr);
239 
240     RelationalRowDataSet rowDataSet {};
241     ContinueToken token = nullptr;
242 
243     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"1"});
244     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
245     EXPECT_EQ(rowDataSet.GetSize(), 3);
246 
247     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='1'", {} };
248     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
249     EXPECT_EQ(rowDataSet.GetSize(), 3);
250 
251     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=1", {} };
252     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
253     EXPECT_EQ(rowDataSet.GetSize(), 3);
254 
255     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=true", {} };
256     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
257     EXPECT_EQ(rowDataSet.GetSize(), 3);
258 
259     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"'1'"} };
260     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
261     EXPECT_EQ(rowDataSet.GetSize(), 0);
262 
263     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value='true'", {} };
264     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
265     EXPECT_EQ(rowDataSet.GetSize(), 0);
266 
267     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"true"} };
268     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
269     EXPECT_EQ(rowDataSet.GetSize(), 0);
270 
271     RefObject::DecObjRef(g_store);
272 }
273 
274 /**
275  * @tc.name: BlobQuery1
276  * @tc.desc: Query blob.
277  * @tc.type: FUNC
278  * @tc.require: AR000GK58G
279  * @tc.author: lidongwei
280  */
281 HWTEST_F(DistributedDBRelationalRemoteQueryTest, BlobQuery1, TestSize.Level1)
282 {
283     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
284     ASSERT_NE(g_delegate, nullptr);
285     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
286 
287     /**
288      * @tc.steps: step1. Put data.
289      * @tc.expected: Succeed, return OK.
290      */
291     sqlite3 *db = nullptr;
292     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
293     ASSERT_NE(db, nullptr);
294 
295     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
296     sqlite3_close(db);
297 
298     /**
299      * @tc.steps: step2. Check blob.
300      * @tc.expected: x'xxx' in sql is OK. Not ok in bindArgs.
301      */
302     auto store = GetRelationalStore();
303     ASSERT_NE(store, nullptr);
304 
305     RelationalRowDataSet rowDataSet {};
306     ContinueToken token = nullptr;
307 
308     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000'", {});
309     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
310     EXPECT_EQ(rowDataSet.GetSize(), 1);
311     EXPECT_FALSE(rowDataSet.GetColNames().empty());
312 
313     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=?", {"x'10101010001000'"} };
314     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
315     EXPECT_EQ(rowDataSet.GetSize(), 0);
316     EXPECT_TRUE(rowDataSet.GetColNames().empty());
317 
318     RefObject::DecObjRef(g_store);
319 }
320 
321 /**
322  * @tc.name: InsertQuery1
323  * @tc.desc: Query with insert statement.
324  * @tc.type: FUNC
325  * @tc.require: AR000GK58G
326  * @tc.author: lidongwei
327  */
328 HWTEST_F(DistributedDBRelationalRemoteQueryTest, InsertQuery1, TestSize.Level1)
329 {
330     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
331     ASSERT_NE(g_delegate, nullptr);
332     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
333 
334     /**
335      * @tc.steps: step1. Put data.
336      * @tc.expected: Succeed, return OK.
337      */
338     sqlite3 *db = nullptr;
339     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
340     ASSERT_NE(db, nullptr);
341 
342     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, x'10101010001000');"), 0);
343     sqlite3_close(db);
344 
345     /**
346      * @tc.steps: step2. Query with a insert statement.
347      * @tc.expected: Query failed.
348      */
349     auto store = GetRelationalStore();
350     ASSERT_NE(store, nullptr);
351 
352     RelationalRowDataSet rowDataSet {};
353     ContinueToken token = nullptr;
354 
355     /**
356      * @tc.steps: step3. Query with INSERT opcode.
357      * @tc.expected: Query failed. Return E_INVALID_ARGS.
358      */
359     PreparedStmt prepStmt(PreparedStmt::INSERT, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {});
360     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_INVALID_ARGS);
361     EXPECT_EQ(rowDataSet.GetSize(), 0);
362 
363     /**
364      * @tc.steps: step4. Query with QUERY opcode and a insert sql.
365      * @tc.expected: Query failed. Return E_DENIED_SQL.
366      */
367     prepStmt = { PreparedStmt::QUERY, "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
368     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -E_DENIED_SQL);
369     EXPECT_EQ(rowDataSet.GetSize(), 0);
370 
371     /**
372      * @tc.steps: step5. Query with QUERY opcode and two sql(one select and one insert).
373      * @tc.expected: Query OK. The second sql is ignored.
374      */
375     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE value=x'10101010001000';"
376                                       "INSERT INTO " + g_tableName + " values(2, x'10101010001000');", {} };
377     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
378     EXPECT_EQ(rowDataSet.GetSize(), 1);
379 
380     RefObject::DecObjRef(g_store);
381 }
382 
383 /**
384  * @tc.name: NonexistentTable1
385  * @tc.desc: Nonexistent table or column.
386  * @tc.type: FUNC
387  * @tc.require: AR000GK58G
388  * @tc.author: lidongwei
389  */
390 HWTEST_F(DistributedDBRelationalRemoteQueryTest, NonexistentTable1, TestSize.Level1)
391 {
392     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
393     ASSERT_NE(g_delegate, nullptr);
394     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
395 
396     /**
397      * @tc.steps: step1. Query when nonexistent table or nonexistent column.
398      * @tc.expected: Failed, return SQLITE_ERROR
399      */
400     auto store = GetRelationalStore();
401     ASSERT_NE(store, nullptr);
402 
403     RelationalRowDataSet rowDataSet {};
404     ContinueToken token = nullptr;
405 
406     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM nonexistent_table WHERE value=1;", {});
407     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
408 
409     prepStmt = { PreparedStmt::QUERY, "SELECT * FROM " + g_tableName + " WHERE nonexistent_column=1;", {} };
410     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), -SQLITE_ERROR);
411 
412     RefObject::DecObjRef(g_store);
413 }
414 
415 /**
416  * @tc.name: PreparedStmtSerialize
417  * @tc.desc: Test the serialization and deserialization of PreparedStmt.
418  * @tc.type: FUNC
419  * @tc.require: AR000GK58G
420  * @tc.author: lidongwei
421  */
422 HWTEST_F(DistributedDBRelationalRemoteQueryTest, PreparedStmtSerialize, TestSize.Level1)
423 {
424     /**
425      * @tc.steps: step1. Create a prepared stmt;
426      * @tc.expected: OK.
427      */
428     PreparedStmt prepStmt1(PreparedStmt::QUERY, "SELECT * FROM test WHERE value=? or value=?", {"1", "2"});
429     int len = prepStmt1.CalcLength();
430 
431     /**
432      * @tc.steps: step2. Serialize the prepared stmt;
433      * @tc.expected: Serialize OK.
434      */
435     std::vector<uint8_t> buffer(len);
436     Parcel parcel1(buffer.data(), buffer.size());
437     ASSERT_EQ(prepStmt1.Serialize(parcel1), E_OK);
438     ASSERT_FALSE(parcel1.IsError());
439 
440     /**
441      * @tc.steps: step3. Deserialize the prepared stmt;
442      * @tc.expected: Deserialize OK.
443      */
444     PreparedStmt prepStmt2;
445     Parcel parcel2(buffer.data(), buffer.size());
446     ASSERT_EQ(prepStmt2.DeSerialize(parcel2), E_OK);
447     ASSERT_FALSE(parcel2.IsError());
448 
449     /**
450      * @tc.steps: step4. Compare the deserialized prepared stmt with the original;
451      * @tc.expected: Compare OK. They are the same.
452      */
453     EXPECT_EQ(prepStmt1.GetOpCode(), prepStmt2.GetOpCode());
454     EXPECT_EQ(prepStmt1.GetSql(), prepStmt2.GetSql());
455     EXPECT_EQ(prepStmt1.GetBindArgs(), prepStmt2.GetBindArgs());
456 }
457 
458 /**
459  * @tc.name: ComplexQuery1
460  * @tc.desc: Complex query with join or aggregate func.
461  * @tc.type: FUNC
462  * @tc.require: AR000GK58G
463  * @tc.author: lidongwei
464  */
465 HWTEST_F(DistributedDBRelationalRemoteQueryTest, ComplexQuery1, TestSize.Level1)
466 {
467     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
468     ASSERT_NE(g_delegate, nullptr);
469     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
470 
471     sqlite3 *db = nullptr;
472     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
473     ASSERT_NE(db, nullptr);
474 
475     EXPECT_EQ(ExecSql(db, "INSERT INTO " + g_tableName + " values(1, 1);"
476                           "CREATE TABLE IF NOT EXISTS r(key INTEGER, value INTEGER);"
477                           "INSERT INTO r VALUES(1, 1);"), 0);
478     sqlite3_close(db);
479 
480     /**
481      * @tc.steps: step1. Query with a complex sql.
482      * @tc.expected: Succeed.
483      */
484     auto store = GetRelationalStore();
485     ASSERT_NE(store, nullptr);
486 
487     RelationalRowDataSet rowDataSet {};
488     ContinueToken token = nullptr;
489 
490     PreparedStmt prepStmt(PreparedStmt::QUERY,
491         "SELECT COUNT(*) FROM " + g_tableName + " INNER JOIN r ON " + g_tableName + ".key=r.key "
492         "WHERE r.value IN (1,2,3);", {});
493     EXPECT_EQ(store->ExecuteQuery(prepStmt, DBConstant::MAX_MTU_SIZE, rowDataSet, token), E_OK);
494     EXPECT_EQ(rowDataSet.GetSize(), 1);
495 
496     RefObject::DecObjRef(g_store);
497 }
498 
499 /**
500  * @tc.name: LargeAmountOfData1
501  * @tc.desc: Large Amount Of Data.
502  * @tc.type: FUNC
503  * @tc.require: AR000GK58G
504  * @tc.author: lidongwei
505  */
506 HWTEST_F(DistributedDBRelationalRemoteQueryTest, LargeAmountOfData1, TestSize.Level1)
507 {
508     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
509     ASSERT_NE(g_delegate, nullptr);
510     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
511 
512     sqlite3 *db = nullptr;
513     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
514     ASSERT_NE(db, nullptr);
515 
516     /**
517      * @tc.steps: step1. Insert 20 data.
518      * @tc.expected: Succeed.
519      */
520     int i = 10;  // 10 for test.
521     while (i-- > 0) {
522         ASSERT_EQ(InsertData(db, 500), 0);  // 500 for test.
523         ASSERT_EQ(InsertData(db, 1500), 0); // 1500 for test.
524     }
525     sqlite3_close(db);
526 
527     /**
528      * @tc.steps: step2. Query.
529      * @tc.expected: Get 20 data.
530      */
531     auto store = GetRelationalStore();
532     ASSERT_NE(store, nullptr);
533 
534     ContinueToken token = nullptr;
535     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
536 
537     size_t totalCnt = 0;
538     RelationalRowDataSet allRowDataSet {};
539     do {
540         RelationalRowDataSet rowDataSet {};
541         EXPECT_EQ(store->ExecuteQuery(prepStmt, 1024, rowDataSet, token), E_OK);  // 1024 is min mtu.
542         totalCnt += rowDataSet.GetSize();
543         EXPECT_EQ(allRowDataSet.Merge(std::move(rowDataSet)), E_OK);
544     } while (token != nullptr);
545 
546     EXPECT_EQ(totalCnt, 20u);
547     EXPECT_EQ(allRowDataSet.GetSize(), 20);
548 
549     RefObject::DecObjRef(g_store);
550 }
551 
552 /**
553  * @tc.name: OverSize1
554  * @tc.desc: Over size.
555  * @tc.type: FUNC
556  * @tc.require: AR000GK58G
557  * @tc.author: lidongwei
558  */
559 HWTEST_F(DistributedDBRelationalRemoteQueryTest, OverSize1, TestSize.Level1)
560 {
561     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
562     ASSERT_NE(g_delegate, nullptr);
563     ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName), DBStatus::OK);
564 
565     sqlite3 *db = nullptr;
566     ASSERT_EQ(sqlite3_open(g_storePath.c_str(), &db), SQLITE_OK);
567     ASSERT_NE(db, nullptr);
568 
569     /**
570      * @tc.steps: step1. Insert over 4M data.
571      * @tc.expected: Succeed.
572      */
573     int i = 4;  // 4MB
574     while (i-- > 0) {
575         ASSERT_EQ(InsertData(db, 1024 * 1024), 0);  // 1024*1024 means 1MB.
576     }
577     sqlite3_close(db);
578 
579     /**
580      * @tc.steps: step2. Query.
581      * @tc.expected: Failed, return E_REMOTE_OVER_SIZE.
582      */
583     auto store = GetRelationalStore();
584     ASSERT_NE(store, nullptr);
585 
586     ContinueToken token = nullptr;
587     PreparedStmt prepStmt(PreparedStmt::QUERY, "SELECT * FROM " + g_tableName, {});
588 
589     RelationalRowDataSet rowDataSet {};
590     EXPECT_EQ(store->ExecuteQuery(prepStmt, 1200, rowDataSet, token), -E_REMOTE_OVER_SIZE);
591     RefObject::DecObjRef(g_store);
592 }
593 
594 /**
595  * @tc.name: RemoteQueryForNotDistributedDb
596  * @tc.desc: Not create distributed table, exec remote query.
597  * @tc.type: FUNC
598  * @tc.require: AR000GK58G
599  * @tc.author: lidongwei
600  */
601 HWTEST_F(DistributedDBRelationalRemoteQueryTest, RemoteQueryForNotDistributedDb, TestSize.Level1)
602 {
603     ASSERT_EQ(g_mgr.OpenStore(g_storePath, g_storeID, RelationalStoreDelegate::Option {}, g_delegate), DBStatus::OK);
604     ASSERT_NE(g_delegate, nullptr);
605 
606     std::shared_ptr<ResultSet> result = nullptr;
607     EXPECT_EQ(g_delegate->RemoteQuery("deviceA", RemoteCondition {}, 1000, result), DBStatus::NOT_SUPPORT);
608 }
609 #endif
610