• 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 #include <gtest/gtest.h>
16 #include <openssl/rand.h>
17 
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "generic_single_ver_kv_entry.h"
23 #include "kvdb_manager.h"
24 #include "query_sync_object.h"
25 #include "sqlite_single_ver_continue_token.h"
26 #include "sqlite_single_ver_natural_store.h"
27 #include "sqlite_single_ver_natural_store_connection.h"
28 #include "storage_engine_manager.h"
29 
30 using namespace testing::ext;
31 using namespace DistributedDB;
32 using namespace DistributedDBUnitTest;
33 using namespace std;
34 
35 namespace {
36     DistributedDB::KvStoreConfig g_config;
37     std::string g_testDir;
38     DistributedDB::SQLiteSingleVerNaturalStore *g_store = nullptr;
39     DistributedDB::SQLiteSingleVerNaturalStore *g_schemaStore = nullptr;
40     DistributedDB::SQLiteSingleVerNaturalStoreConnection *g_connection = nullptr;
41     DistributedDB::SQLiteSingleVerNaturalStoreConnection *g_schemaConnect = nullptr;
42 
43     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
44     // define the g_kvDelegateCallback, used to get some information when open a kv store.
45     DBStatus g_kvDelegateStatus = INVALID_ARGS;
46     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
47     auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
48         placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
49 
50     const std::string REMOTE_DEVICE_ID = "remote_device_id";
51     const Key PREFIX_KEY = { 'k' };
52     const Key KEY1 = { 'k', '1' };
53     const Key KEY2 = { 'k', '2' };
54     const Key KEY3 = { 'k', '3' };
55     const Value VALUE1 = { 'v', '1' };
56     const Value VALUE2 = { 'v', '2' };
57     const Value VALUE3 = { 'v', '3' };
58     const int VERSION_BIT = 19;
59 
ReleaseKvEntries(std::vector<SingleVerKvEntry * > & entries)60     void ReleaseKvEntries(std::vector<SingleVerKvEntry *> &entries)
61     {
62         for (auto &itemEntry : entries) {
63             delete itemEntry;
64             itemEntry = nullptr;
65         }
66         entries.clear();
67     }
68 
69     const string SCHEMA_STRING =
70     "{\"SCHEMA_VERSION\":\"1.0\","
71     "\"SCHEMA_MODE\":\"STRICT\","
72     "\"SCHEMA_DEFINE\":{"
73     "\"field_name1\":\"BOOL\","
74     "\"field_name2\":\"BOOL\","
75     "\"field_name3\":\"INTEGER, NOT NULL\","
76     "\"field_name4\":\"LONG, DEFAULT 100\","
77     "\"field_name5\":\"DOUBLE, NOT NULL, DEFAULT 3.14\","
78     "\"field_name6\":\"STRING, NOT NULL, DEFAULT '3.1415'\","
79     "\"field_name7\":\"LONG, DEFAULT 100\","
80     "\"field_name8\":\"LONG, DEFAULT 100\","
81     "\"field_name9\":\"LONG, DEFAULT 100\","
82     "\"field_name10\":\"LONG, DEFAULT 100\""
83     "},"
84     "\"SCHEMA_INDEXES\":[\"$.field_name1\", \"$.field_name2\"]}";
85 
86     const std::string SCHEMA_VALUE1 =
87     "{\"field_name1\":true,"
88     "\"field_name2\":false,"
89     "\"field_name3\":10,"
90     "\"field_name4\":20,"
91     "\"field_name5\":3.14,"
92     "\"field_name6\":\"3.1415\","
93     "\"field_name7\":100,"
94     "\"field_name8\":100,"
95     "\"field_name9\":100,"
96     "\"field_name10\":100}";
97 }
98 
99 class DistributedDBStorageQuerySyncTest : public testing::Test {
100 public:
101     static void SetUpTestCase(void);
102     static void TearDownTestCase(void);
103     void SetUp();
104     void TearDown();
105 };
106 
SetUpTestCase(void)107 void DistributedDBStorageQuerySyncTest::SetUpTestCase(void)
108 {
109     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
110     LOGD("Test dir is %s", g_testDir.c_str());
111     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir + "/TestQuerySync/" + DBConstant::SINGLE_SUB_DIR);
112 
113     g_config.dataDir = g_testDir;
114     g_mgr.SetKvStoreConfig(g_config);
115     // Create schema database
116     KvStoreNbDelegate::Option option = {true, false, false};
117     option.schema = SCHEMA_STRING;
118     g_mgr.GetKvStore("QuerySyncSchema", option, g_kvNbDelegateCallback);
119     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
120     EXPECT_TRUE(g_kvDelegateStatus == OK);
121     Value value(SCHEMA_VALUE1.begin(), SCHEMA_VALUE1.end());
122     g_kvNbDelegatePtr->Put(KEY_1, value);
123 
124     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
125 }
126 
TearDownTestCase(void)127 void DistributedDBStorageQuerySyncTest::TearDownTestCase(void)
128 {
129     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir);
130 }
131 
SetUp(void)132 void DistributedDBStorageQuerySyncTest::SetUp(void)
133 {
134     DistributedDBToolsUnitTest::PrintTestCaseInfo();
135     KvDBProperties property;
136     property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
137     property.SetStringProp(KvDBProperties::STORE_ID, "31");
138     property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, "TestQuerySync");
139     property.SetBoolProp(KvDBProperties::MEMORY_MODE, false);
140     property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE);
141     property.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, ConflictResolvePolicy::DEVICE_COLLABORATION);
142     g_store = new (std::nothrow) SQLiteSingleVerNaturalStore;
143     ASSERT_NE(g_store, nullptr);
144     ASSERT_EQ(g_store->Open(property), E_OK);
145 
146     int erroCode = E_OK;
147     g_connection = static_cast<SQLiteSingleVerNaturalStoreConnection *>(g_store->GetDBConnection(erroCode));
148     ASSERT_NE(g_connection, nullptr);
149     g_store->DecObjRef(g_store);
150     EXPECT_EQ(erroCode, E_OK);
151 
152     std::string oriIdentifier = USER_ID + "-" + APP_ID + "-" + "QuerySyncSchema";
153     std::string identifier = DBCommon::TransferHashString(oriIdentifier);
154     property.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier);
155     std::string identifierHex = DBCommon::TransferStringToHex(identifier);
156     property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
157     property.SetStringProp(KvDBProperties::STORE_ID, "QuerySyncSchema");
158     property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, identifierHex);
159 
160     g_schemaStore = new (std::nothrow) SQLiteSingleVerNaturalStore;
161     ASSERT_NE(g_schemaStore, nullptr);
162     ASSERT_EQ(g_schemaStore->Open(property), E_OK);
163     g_schemaConnect = static_cast<SQLiteSingleVerNaturalStoreConnection *>(g_schemaStore->GetDBConnection(erroCode));
164     ASSERT_NE(g_schemaConnect, nullptr);
165 
166     std::vector<Entry> entries;
167     IOption option;
168     option.dataType = IOption::SYNC_DATA;
169     g_schemaConnect->GetEntries(option, Query::Select(), entries);
170     ASSERT_FALSE(entries.empty());
171 
172     g_schemaStore->DecObjRef(g_schemaStore);
173 }
174 
TearDown(void)175 void DistributedDBStorageQuerySyncTest::TearDown(void)
176 {
177     if (g_connection != nullptr) {
178         g_connection->Close();
179     }
180 
181     if (g_schemaConnect != nullptr) {
182         g_schemaConnect->Close();
183     }
184 
185     g_store = nullptr;
186     DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir + "/TestQuerySync/" + DBConstant::SINGLE_SUB_DIR);
187 }
188 
189 /**
190   * @tc.name: GetSyncData001
191   * @tc.desc: To test the function of querying the data in the time stamp range in the database.
192   * @tc.type: FUNC
193   * @tc.require: AR000CRAKO
194   * @tc.author: wangbingquan
195   */
196 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData001, TestSize.Level1)
197 {
198     /**
199      * @tc.steps:step1. Obtain the data within the time stamp range
200      *  through the GetSyncData(A, C) interface of the NaturalStore, where A<B<C.
201      * @tc.expected: step1. GetSyncData The number of output parameter
202      *  in the output parameter OK, dataItems is 1.
203      */
204     IOption option;
205     option.dataType = IOption::SYNC_DATA;
206     Key key;
207     Value value;
208     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
209     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
210     EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
211 
212     Query query = Query::Select().PrefixKey(key);
213     QueryObject queryObj(query);
214     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
215     std::vector<SingleVerKvEntry *> entries;
216     ContinueToken token = nullptr;
217     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
218     EXPECT_EQ(entries.size(), 1UL);
219     ReleaseKvEntries(entries);
220 
221     Key keyOther = key;
222     keyOther.push_back('1');
223     g_store->ReleaseContinueToken(token);
224     EXPECT_EQ(g_connection->Put(option, keyOther, value), E_OK);
225     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
226     EXPECT_EQ(entries.size(), 2UL);
227     ReleaseKvEntries(entries);
228     g_store->ReleaseContinueToken(token);
229 }
230 
231 /**
232  * @tc.name: GetQuerySyncData002
233  * @tc.desc: To test GetSyncData function is available and check the boundary value.
234  * @tc.type: FUNC
235  * @tc.require: AR000FN6G9
236  * @tc.author: lidongwei
237  */
238 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData002, TestSize.Level1)
239 {
240     /**
241      * @tc.steps: step1. Put k1 k2. k1's timestamp is 0 and k2's timestamp is INT64_MAX-1.
242      * @tc.expected: step1. Put k1 k2 successfully.
243      */
244     DataItem data1{KEY1, VALUE1, 0, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
245     DataItem data2{KEY2, VALUE2, INT64_MAX - 1, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
246     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data1, data2}, REMOTE_DEVICE_ID), E_OK);
247 
248     /**
249      * @tc.steps: step2. Get k1 k2. SyncTimeRange is default(all time range).
250      * @tc.expected: step2. Get k1 k2 successfully.
251      */
252     Query query = Query::Select().PrefixKey(PREFIX_KEY);
253     QueryObject queryObj(query);
254     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
255     std::vector<SingleVerKvEntry *> entries;
256     ContinueToken token = nullptr;
257     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
258     EXPECT_EQ(entries.size(), 2UL);
259     ReleaseKvEntries(entries);
260     g_store->ReleaseContinueToken(token);
261 
262     /**
263      * @tc.steps: step3. Put k3. k3's timestamp t3 is random.
264      * @tc.expected: step3. Put k3.
265      */
266     auto time3 = static_cast<Timestamp>(DistributedDBToolsUnitTest::GetRandInt64(0, g_store->GetCurrentTimestamp()));
267     DataItem data3{KEY3, VALUE3, time3, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
268     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data3}, REMOTE_DEVICE_ID), E_OK);
269 
270     /**
271      * @tc.steps: step4. Get k3. SyncTimeRange is between t3 and t3 + 1.
272      * @tc.expected: step4. Get k3 successfully.
273      */
274     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{time3, 0, time3 + 1, 0},
275         specInfo, token, entries), E_OK);
276     EXPECT_EQ(entries.size(), 1UL);
277     ReleaseKvEntries(entries);
278     g_store->ReleaseContinueToken(token);
279 
280     /**
281      * @tc.steps: step5. Delete k1 k3.
282      * @tc.expected: step5. Delete k1 k3 successfully.
283      */
284     IOption option{ IOption::SYNC_DATA };
285     Timestamp deleteBeginTime = g_store->GetCurrentTimestamp();
286     g_connection->DeleteBatch(option, vector{KEY1, KEY3});
287 
288     /**
289      * @tc.steps: step6. Get deleted data.
290      * @tc.expected: step6. Get k1 k3.
291      */
292     Timestamp deleteEndTime = g_store->GetCurrentTimestamp();
293     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{0, deleteBeginTime, 0, deleteEndTime}, specInfo, token,
294         entries), E_OK);
295     EXPECT_EQ(entries.size(), 2UL);
296     ReleaseKvEntries(entries);
297     g_store->ReleaseContinueToken(token);
298 }
299 
300 /**
301  * @tc.name: GetQuerySyncData004
302  * @tc.desc: To test GetSyncDataNext function is available and check the boundary value.
303  * @tc.type: FUNC
304  * @tc.require: AR000FN6G9
305  * @tc.author: lidongwei
306  */
307 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData004, TestSize.Level1)
308 {
309     /**
310      * @tc.steps: step1. Put k1 k2. k1's timestamp is 0 and k2's timestamp is INT64_MAX-1.
311      * @tc.expected: step1. Put k1 k2 successfully.
312      */
313     DataItem data1{KEY1, VALUE1, 0, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
314     DataItem data2{KEY2, VALUE2, INT64_MAX - 1, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
315     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data1, data2}, REMOTE_DEVICE_ID), E_OK);
316 
317     /**
318      * @tc.steps: step2. Get k1 k2. SyncTimeRange is default(all time range).
319      * @tc.expected: step2. Get k1 k2 successfully.
320      */
321     Query query = Query::Select().PrefixKey(PREFIX_KEY);
322     QueryObject queryObj(query);
323     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
324     std::vector<SingleVerKvEntry *> entries;
325     ContinueToken token = new (std::nothrow) SQLiteSingleVerContinueToken{SyncTimeRange{}, queryObj};
326     EXPECT_EQ(g_store->GetSyncDataNext(entries, token, specInfo), E_OK);
327     EXPECT_EQ(entries.size(), 2UL);
328     ReleaseKvEntries(entries);
329     g_store->ReleaseContinueToken(token);
330 
331     /**
332      * @tc.steps: step3. Put k3. k3's timestamp t3 is random.
333      * @tc.expected: step3. Put k3.
334      */
335     auto time3 = static_cast<Timestamp>(DistributedDBToolsUnitTest::GetRandInt64(0, g_store->GetCurrentTimestamp()));
336     DataItem data3{KEY3, VALUE3, time3, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
337     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data3}, REMOTE_DEVICE_ID), E_OK);
338 
339     /**
340      * @tc.steps: step4. Get k3. SyncTimeRange is between t3 and t3 + 1.
341      * @tc.expected: step4. Get k3 successfully.
342      */
343     token = new (std::nothrow) SQLiteSingleVerContinueToken{SyncTimeRange{time3, 0, time3 + 1}, queryObj};
344     EXPECT_EQ(g_store->GetSyncDataNext(entries, token, specInfo), E_OK);
345     EXPECT_EQ(entries.size(), 1UL);
346     ReleaseKvEntries(entries);
347     g_store->ReleaseContinueToken(token);
348 
349     /**
350      * @tc.steps: step5. Delete k1 k3.
351      * @tc.expected: step5. Delete k1 k3 successfully.
352      */
353     IOption option{ IOption::SYNC_DATA };
354     Timestamp deleteBeginTime = g_store->GetCurrentTimestamp();
355     g_connection->DeleteBatch(option, vector{KEY1, KEY3});
356 
357     /**
358      * @tc.steps: step6. Get deleted data.
359      * @tc.expected: step6. Get k1 k3.
360      */
361     Timestamp deleteEndTime = g_store->GetCurrentTimestamp();
362     token = new (std::nothrow) SQLiteSingleVerContinueToken{SyncTimeRange{0, deleteBeginTime, 0, deleteEndTime},
363         queryObj};
364     EXPECT_EQ(g_store->GetSyncDataNext(entries, token, specInfo), E_OK);
365     EXPECT_EQ(entries.size(), 2UL);
366     ReleaseKvEntries(entries);
367     g_store->ReleaseContinueToken(token);
368 }
369 
370 /**
371  * @tc.name: GetQuerySyncData006
372  * @tc.desc: To test if parameter is invalid, GetSyncData function return an E_INVALID_ARGS code. If no data found,
373     GetSyncData will return E_OK but entries will be empty.
374  * @tc.type: FUNC
375  * @tc.require: AR000FN6G9
376  * @tc.author: lidongwei
377  */
378 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData006, TestSize.Level1)
379 {
380     /**
381      * @tc.steps: step1. Get sync data when no data exists in DB.
382      * @tc.expected: step1. GetSyncData return E_OK and entries is empty.
383      */
384     Query query = Query::Select().PrefixKey(PREFIX_KEY);
385     QueryObject queryObj(query);
386     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
387     std::vector<SingleVerKvEntry *> entries;
388     ContinueToken token = nullptr;
389     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
390     EXPECT_TRUE(entries.empty());
391     ReleaseKvEntries(entries);
392     g_store->ReleaseContinueToken(token);
393 
394     /**
395      * @tc.steps: step2. Get sync data with invalid SyncTimeRange(beginTime is greater than endTime).
396      * @tc.expected: step2. GetSyncData return E_INVALID_ARGS.
397      */
398     auto time = static_cast<Timestamp>(DistributedDBToolsUnitTest::GetRandInt64(0, INT64_MAX));
399     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{time, 0, 0}, specInfo, token, entries),
400         -E_INVALID_ARGS);
401 }
402 
403 /**
404  * @tc.name: GetQuerySyncData006
405  * @tc.desc: To test QUERY_SYNC_THRESHOLD works. When all query data is found in one get sync data operation,
406     if the size of query data is greater than QUERY_SYNC_THRESHOLD*MAX_ITEM_SIZE , will not get deleted data next.
407     Otherwise, will get deleted data next.
408  * @tc.type: FUNC
409  * @tc.require: AR000FN6G9
410  * @tc.author: lidongwei
411  */
412 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData008, TestSize.Level1)
413 {
414     const size_t maxItemSize = 200;
415     const float querySyncThreshold = 0.50;
416 
417     Key key;
418     Value value;
419     string str;
420     IOption option{ IOption::SYNC_DATA };
421 
422     /**
423      * @tc.steps: step1. Put MAX_ITEM_SIZE / 2 + 1 entries from k0 to k100.
424      * @tc.expected: step1. Put data successfully.
425      */
426     for (unsigned i = 0; i <= maxItemSize * querySyncThreshold; i++) {
427         str = "k" + to_string(i);
428         key = Key(str.begin(), str.end());
429         str[0] = 'v';
430         value = Value(str.begin(), str.end());
431         EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
432     }
433 
434     DataItem item{key, value};
435     auto oneBlockSize = SQLiteSingleVerStorageExecutor::GetDataItemSerialSize(item, Parcel::GetAppendedLen());
436 
437     /**
438      * @tc.steps: step2. Delete k0.
439      * @tc.expected: step2. Delete k0 successfully.
440      */
441     str = "k0";
442     g_connection->Delete(option, Key(str.begin(), str.end()));
443 
444     /**
445      * @tc.steps: step3. Get sync data when 100 query data and 1 deleted data exists in DB.
446      * @tc.expected: step3. Get 100 query data and no deleted data.
447      */
448     Query query = Query::Select().PrefixKey(PREFIX_KEY);
449     QueryObject queryObj(query);
450 
451     DataSizeSpecInfo  specInfo = {static_cast<uint32_t>((maxItemSize) * oneBlockSize), maxItemSize};
452     std::vector<SingleVerKvEntry *> entries;
453     ContinueToken token = nullptr;
454     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), -E_UNFINISHED);
455     EXPECT_EQ(entries.size(), 100UL);
456     ReleaseKvEntries(entries);
457     g_store->ReleaseContinueToken(token);
458 
459     /**
460      * @tc.steps: step4. Delete k1.
461      * @tc.expected: step4. Delete k1 successfully.
462      */
463     str = "k1";
464     g_connection->Delete(option, Key(str.begin(), str.end()));
465 
466     /**
467      * @tc.steps: step5. Get sync data when 99 query data and 2 deleted data exists in DB.
468      * @tc.expected: step5. Get 99 query data and 2 deleted data.
469      */
470     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
471     EXPECT_EQ(entries.size(), 101UL);
472     ReleaseKvEntries(entries);
473     g_store->ReleaseContinueToken(token);
474 }
475 
476 /**
477  * @tc.name: GetQuerySyncData009
478  * @tc.desc: To test GetSyncData and GetSyncDataNext function works with large amounts of data.
479  * @tc.type: FUNC
480  * @tc.require: AR000FN6G9
481  * @tc.author: lidongwei
482  */
483 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData009, TestSize.Level2)
484 {
485     /**
486      * @tc.steps: step1. Put 500 entries from k0 to k499.
487      * @tc.expected: step1. Put data successfully.
488      */
489     Key key;
490     Value value;
491     string str;
492     IOption option{ IOption::SYNC_DATA };
493     const uint64_t totalSize = 500; // 500 data in DB.
494     for (unsigned i = 0; i < totalSize; i++) {
495         str = "k" + to_string(i);
496         key = Key(str.begin(), str.end());
497         str[0] = 'v';
498         value = Value(str.begin(), str.end());
499         EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
500     }
501 
502     /**
503      * @tc.steps: step2. Delete 150 entries from k150 to k299.
504      * @tc.expected: step2. Delete data successfully.
505      */
506     for (unsigned i = 150; i < 300; i++) {
507         str = "k" + to_string(i);
508         g_connection->Delete(option, Key(str.begin(), str.end()));
509     }
510 
511     /**
512      * @tc.steps: step3. Get all sync data;
513      * @tc.expected: step3. Get 500 data.
514      */
515     Query query = Query::Select().PrefixKey(PREFIX_KEY);
516     QueryObject queryObj(query);
517 
518     uint64_t getSize = 0;
519     std::vector<SingleVerKvEntry *> entries;
520     const size_t maxItemSize = 100; // Get 100 data at most in one GetSyncData operation.
521     DataSizeSpecInfo  specInfo = {MTU_SIZE, maxItemSize};
522     ContinueToken token = nullptr;
523     g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries);
524     getSize += entries.size();
525     ReleaseKvEntries(entries);
526 
527     while (token != nullptr) {
528         g_store->GetSyncDataNext(entries, token, specInfo);
529         getSize += entries.size();
530         ReleaseKvEntries(entries);
531     }
532 
533     EXPECT_EQ(getSize, totalSize);
534 }
535 
536 /**
537  * @tc.name: GetQuerySyncData010
538  * @tc.desc: To test GetSyncData when Query with limit.
539  * @tc.type: FUNC
540  * @tc.require: AR000FN6G9
541  * @tc.author: lidongwei
542  */
543 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQuerySyncData010, TestSize.Level1)
544 {
545     /**
546      * @tc.steps: step1. Put 100 entries from k100 to k1.
547      * @tc.expected: step1. Put data successfully.
548      */
549     IOption option{ IOption::SYNC_DATA };
550     const uint64_t totalSize = 100; // 100 data in DB.
551     for (unsigned i = totalSize; i > 0; i--) {
552         string str = "k" + to_string(i);
553         Key key = Key(str.begin(), str.end());
554         str[0] = 'v';
555         Value value = Value(str.begin(), str.end());
556         EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
557     }
558 
559     /**
560      * @tc.steps: step3. Get half of sync data;
561      * @tc.expected: step3. Get half of sync data successfully.
562      */
563     Query query = Query::Select().PrefixKey(PREFIX_KEY).Limit(totalSize / 2);
564     QueryObject queryObj(query);
565 
566     uint64_t getSize = 0;
567     std::vector<SingleVerKvEntry *> entries;
568     const size_t maxItemSize = 10; // Get 10 data at most in one GetSyncData operation.
569     DataSizeSpecInfo  specInfo = {MTU_SIZE, maxItemSize};
570     ContinueToken token = nullptr;
571     g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries);
572     getSize += entries.size();
573     ReleaseKvEntries(entries);
574 
575     while (token != nullptr) {
576         g_store->GetSyncDataNext(entries, token, specInfo);
577         getSize += entries.size();
578         ReleaseKvEntries(entries);
579     }
580 
581     EXPECT_EQ(getSize, totalSize / 2);
582 }
583 
584 /**
585   * @tc.name: GetQueryID001
586   * @tc.desc: To test the function of generating query identity.
587   * @tc.type: FUNC
588   * @tc.require: AR000FN6G9
589   * @tc.author: sunpeng
590   */
591 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQueryID001, TestSize.Level1)
592 {
593     /**
594      * @tc.steps:step1. Get illegal query object, get this object identify
595      * @tc.expected: step1. GetIdentify will get empty string
596      */
597     Query errQuery = Query::Select().GreaterThan("$.test", true);
598     QuerySyncObject querySync(errQuery);
599     EXPECT_EQ(querySync.GetIdentify().empty(), true);
600 
601     /**
602      * @tc.steps:step2. use illegal query object to serialized
603      * @tc.expected: step2. SerializeData will not return E_OK
604      */
605     vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
606     Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
607     Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
608     EXPECT_NE(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
609 }
610 
611 /**
612   * @tc.name: GetQueryID002
613   * @tc.desc: To test the function of generating query identity.
614   * @tc.type: FUNC
615   * @tc.require: AR000FN6G9
616   * @tc.author: sunpeng
617   */
618 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQueryID002, TestSize.Level1)
619 {
620     /**
621      * @tc.steps:step1. Get empty condition query object, get this object identify
622      * @tc.expected: step1. GetIdentify result not change
623      */
624     Query query1 = Query::Select();
625 
626     QuerySyncObject querySync(query1);
627     EXPECT_EQ(querySync.GetIdentify().empty(), false);
628     // same object identify is same
629     EXPECT_EQ(querySync.GetIdentify(), querySync.GetIdentify());
630 
631     IOption option;
632     option.dataType = IOption::SYNC_DATA;
633     Key key;
634     Value value;
635     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
636     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
637     EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
638     EXPECT_EQ(g_connection->Put(option, KEY_1, VALUE_1), E_OK);
639     EXPECT_EQ(g_connection->Put(option, KEY_2, VALUE_2), E_OK);
640 
641     /**
642      * @tc.steps:step2. Get prefix key condition query object, get this object identify
643      * @tc.expected: step2. GetIdentify result not same as other condition query object
644      */
645     Query query2 = Query::Select().PrefixKey(key);
646     QuerySyncObject querySync1(query2);
647     EXPECT_EQ(querySync1.GetIdentify().empty(), false);
648     // same object identify is not same
649     EXPECT_NE(querySync.GetIdentify(), querySync1.GetIdentify());
650 
651     /**
652      * @tc.steps:step3. empty condition query object can serialized and deserialized normally
653      * @tc.expected: step3. after deserialized, can get all key value in database
654      */
655     vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
656     Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
657     Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
658     EXPECT_EQ(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
659 
660     QuerySyncObject queryObj2;
661     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), E_OK);
662     LOGD("Query obj after serialize!");
663 
664     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
665     std::vector<SingleVerKvEntry *> entries;
666     ContinueToken token = nullptr;
667     EXPECT_EQ(g_store->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
668     EXPECT_EQ(entries.size(), 3UL);
669     SingleVerKvEntry::Release(entries);
670 }
671 
672 /**
673   * @tc.name: GetQueryID003
674   * @tc.desc: To test the function of generating query identity ignore limit, orderby, suggestion.
675   * @tc.type: FUNC
676   * @tc.require: AR000FN6G9
677   * @tc.author: sunpeng
678   */
679 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQueryID003, TestSize.Level1)
680 {
681     /**
682      * @tc.steps:step1. Get empty condition query object, get this object identify
683      */
684     Query query1 = Query::Select().PrefixKey({});
685     QuerySyncObject querySync1(query1);
686     std::string id1 = querySync1.GetIdentify();
687     EXPECT_EQ(id1.empty(), false);
688 
689     /**
690      * @tc.steps:step2. Get limit condition query object, get this object identify
691      * @tc.expected: step2. GetIdentify result same as no contain limit condition
692      */
693     Query query2 = query1.Limit(1, 1);
694     QuerySyncObject querySync2(query2);
695     std::string id2 = querySync2.GetIdentify();
696     EXPECT_EQ(id2, id1);
697 
698     /**
699      * @tc.steps:step3. Get orderby condition query object, get this object identify
700      * @tc.expected: step3. GetIdentify result same as no contain orderby condition
701      */
702     Query query3 = query2.OrderBy("$.test");
703     QuerySyncObject querySync3(query3);
704     std::string id3 = querySync3.GetIdentify();
705     EXPECT_EQ(id2, id3);
706 }
707 
708 /**
709   * @tc.name: Serialize001
710   * @tc.desc: To test the function of querying the data after serialized and deserialized.
711   * @tc.type: FUNC
712   * @tc.require: AR000FN6G9
713   * @tc.author: sunpeng
714   */
715 HWTEST_F(DistributedDBStorageQuerySyncTest, Serialize001, TestSize.Level1)
716 {
717     /**
718      * @tc.steps:step1. Put K1V1 K2V2 and rand KV for query
719      */
720     IOption option;
721     option.dataType = IOption::SYNC_DATA;
722     Key key;
723     Value value;
724     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
725     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
726     EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
727     EXPECT_EQ(g_connection->Put(option, KEY_1, VALUE_1), E_OK);
728     EXPECT_EQ(g_connection->Put(option, KEY_2, VALUE_2), E_OK);
729 
730     /**
731      * @tc.steps:step2. Put K1V1 K2V2 and rand KV for query
732      * @tc.expected: step2. GetIdentify result same as no contain limit condition
733      */
734     Query query = Query::Select().PrefixKey(key);
735     QueryObject queryObj(query);
736     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
737     std::vector<SingleVerKvEntry *> entries;
738     ContinueToken token = nullptr;
739     LOGD("Ori query obj!");
740     EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
741     EXPECT_EQ(entries.size(), 1UL);
742     SingleVerKvEntry::Release(entries);
743 
744     /**
745      * @tc.steps:step3. query result after serialized and deserialized
746      * @tc.expected: step3. Get same result
747      */
748     QuerySyncObject querySync(query);
749     vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
750     Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
751     Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
752     EXPECT_EQ(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
753 
754     QuerySyncObject queryObj1;
755     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj1), E_OK);
756 
757     LOGD("Query obj after serialize!");
758     EXPECT_EQ(g_store->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), E_OK);
759     EXPECT_EQ(entries.size(), 1UL);
760     SingleVerKvEntry::Release(entries);
761 
762     std::string id = querySync.GetIdentify().c_str();
763     EXPECT_EQ(id.size(), 64u);
764     LOGD("query identify [%s] [%zu]", id.c_str(), id.size());
765 }
766 
767 /**
768   * @tc.name: Serialize002
769   * @tc.desc: To test the function of serialized illegal query object.
770   * @tc.type: FUNC
771   * @tc.require: AR000FN6G9
772   * @tc.author: sunpeng
773   */
774 HWTEST_F(DistributedDBStorageQuerySyncTest, Serialize002, TestSize.Level1)
775 {
776     /**
777      * @tc.steps:step1. Serialized illegal query object
778      * @tc.expected: step1. return not E_OK
779      */
780     Query query = Query::Select().PrefixKey({}).GreaterThan("$.test", true); // bool can not compare
781     QuerySyncObject querySync(query);
782     vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
783     Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
784     EXPECT_NE(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
785 }
786 
787 /**
788   * @tc.name: DeSerialize001
789   * @tc.desc: To test the function of deserialized  illegal query object.
790   * @tc.type: FUNC
791   * @tc.require: AR000FN6G9
792   * @tc.author: sunpeng
793   */
794 HWTEST_F(DistributedDBStorageQuerySyncTest, DeSerialize001, TestSize.Level1)
795 {
796     /**
797      * @tc.steps:step1. deserialized empty content query object
798      * @tc.expected: step1. return not E_OK
799      */
800     QuerySyncObject querySync;
801     vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
802     Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
803 
804     QuerySyncObject queryObj;
805     EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel, queryObj), E_OK);
806 
807     /**
808      * @tc.steps:step2. deserialized empty parcel
809      * @tc.expected: step2. return not E_OK
810      */
811     buffer.resize(0);
812     Parcel readParcel1(buffer.data(), 0);
813     EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel1, queryObj), E_OK);
814 
815     /**
816      * @tc.steps:step3. deserialized error size parcel
817      * @tc.expected: step3. return not E_OK
818      */
819     uint8_t simSize = 0;
820     RAND_bytes(&simSize, 1);
821     buffer.resize(simSize);
822     Parcel readParcel2(buffer.data(), simSize);
823     EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel2, queryObj), E_OK);
824 }
825 
826 /**
827   * @tc.name: SameQueryObjectIdInDiffVer001
828   * @tc.desc: Same query object have same id in different version.
829   * @tc.type: FUNC
830   * @tc.require: AR000FN6G9
831   * @tc.author: sunpeng
832   */
833 HWTEST_F(DistributedDBStorageQuerySyncTest, SameQueryObjectIdInDiffVer001, TestSize.Level1)
834 {
835     /**
836      * @tc.steps:step1. Record the fixed id of the query object of the current version,
837      * and keep it unchanged in subsequent versions
838      * @tc.expected: step1. Never change in diff version
839      */
840     Query query1 = Query::Select().PrefixKey({});
841     QuerySyncObject querySync1(query1);
842     EXPECT_EQ(querySync1.GetIdentify(), "A9AB721457C4CA98726EECC7CB16F94E31B9752BEE6D08569CFE797B4A64A304");
843 
844     Query query2 = Query::Select();
845     QuerySyncObject querySync2(query2);
846     EXPECT_EQ(querySync2.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
847 
848     Query query3 = Query::Select().NotLike("$.test", "testValue");
849     QuerySyncObject querySync3(query3);
850     EXPECT_EQ(querySync3.GetIdentify(), "F2BAC2B53FE81F9928E5F8DCDF502F2419E8CEB5DFC157EEBDDB955A66C0148B");
851 
852     vector<int> fieldValues{1, 1, 1};
853     Query query4 = Query::Select().In("$.test", fieldValues);
854     QuerySyncObject querySync4(query4);
855     EXPECT_EQ(querySync4.GetIdentify(), "EEAECCD0E1A7217574ED3092C8DAA39469388FA1B8B7B210185B4257B785FE4D");
856 
857     Query query5 = Query::Select().OrderBy("$.test.test_child", false);
858     QuerySyncObject querySync5(query5);
859     EXPECT_EQ(querySync5.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
860 
861     Query query6 = Query::Select().Limit(1, 2);
862     QuerySyncObject querySync6(query6);
863     EXPECT_EQ(querySync6.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
864 
865     Query query7 = Query::Select().IsNull("$.test.test_child");
866     QuerySyncObject querySync7(query7);
867     EXPECT_EQ(querySync7.GetIdentify(), "762AB5FDF9B1433D6F398269D4DDD6DE6444953F515E87C6796654180A7FF422");
868 
869     Query query8 = Query::Select().EqualTo("$.test.test_child", true).And().GreaterThan("$.test.test_child", 1);
870     QuerySyncObject querySync8(query8);
871     EXPECT_EQ(querySync8.GetIdentify(), "B97FBFFBC690DAF25031FD4EE8ADC92F4698B9E81FD4877CD54EDEA122F6A6E0");
872 
873     Query query9 = Query::Select().GreaterThan("$.test", 1).OrderBy("$.test");
874     QuerySyncObject querySync9(query9);
875     EXPECT_EQ(querySync9.GetIdentify(), "77480E3EE04EB1500BB2F1A31704EE5676DC81F088A7A300F6D30E3FABA7D0A3");
876 
877     Query query = Query::Select().GreaterThan("$.test1", 1).OrderBy("$.test1");
878     QuerySyncObject querySync(query);
879     EXPECT_EQ(querySync.GetIdentify(), "170F5137C0BB49011D7415F706BD96B86F5FAFADA356374981362B1E177263B9");
880 }
881 
882 /**
883   * @tc.name: querySyncByField
884   * @tc.desc: Test for illegal query conditions, use GetSyncData
885   * @tc.type: FUNC
886   * @tc.require:
887   * @tc.author: sunpeng
888   */
889 HWTEST_F(DistributedDBStorageQuerySyncTest, querySyncByField, TestSize.Level1)
890 {
891     Query queryInvalidField = Query::Select().EqualTo("$.field_name11", 1);
892     Query queryInvalidCombine = Query::Select().EqualTo("$.field_name3", 1).BeginGroup();
893     Query queryAll = Query::Select();
894     Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
895 
896     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
897     std::vector<SingleVerKvEntry *> entries;
898     ContinueToken token = nullptr;
899 
900     QueryObject queryObj(queryInvalidCombine);
901     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), -E_INVALID_QUERY_FORMAT);
902 
903     QueryObject queryObj2(queryAll);
904     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
905     EXPECT_EQ(entries.size(), 1UL);
906     ReleaseKvEntries(entries);
907 
908     QueryObject queryObj1(queryInvalidField);
909     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), -E_INVALID_QUERY_FIELD);
910 
911     QueryObject queryObj3(queryPrefixKeyLimit);
912     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj3, SyncTimeRange{}, specInfo, token, entries), E_OK);
913     ReleaseKvEntries(entries);
914 }
915 
916 /**
917   * @tc.name: IsQueryOnlyByKey
918   * @tc.desc: The test can correctly determine whether the value is used for query
919   * @tc.type: FUNC
920   * @tc.require:
921   * @tc.author: sunpeng
922   */
923 HWTEST_F(DistributedDBStorageQuerySyncTest, IsQueryOnlyByKey, TestSize.Level1)
924 {
925     Query queryAll = Query::Select();
926     Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
927     Query queryPrefix = Query::Select().PrefixKey({});
928     Query queryPrefixKeyLimitIndex = Query::Select().PrefixKey({}).Limit(1, 0).SuggestIndex("$.field_name3");
929     Query queryPrefixKeyLimitEQ = Query::Select().PrefixKey({}).Limit(1, 0).EqualTo("$.field_name3", 1);
930     Query queryEQ = Query::Select().EqualTo("$.field_name3", 1);
931     Query queryLimitEQ = Query::Select().Limit(1, 0).EqualTo("$.field_name3", 1);
932 
933     QueryObject queryObj(queryAll);
934     EXPECT_TRUE(queryObj.IsQueryOnlyByKey());
935 
936     QueryObject queryObj1(queryPrefixKeyLimit);
937     EXPECT_TRUE(queryObj1.IsQueryOnlyByKey());
938 
939     QueryObject queryObj2(queryPrefix);
940     EXPECT_TRUE(queryObj2.IsQueryOnlyByKey());
941 
942     QueryObject queryObj3(queryPrefixKeyLimitIndex);
943     EXPECT_FALSE(queryObj3.IsQueryOnlyByKey());
944 
945     QueryObject queryObj4(queryPrefixKeyLimitEQ);
946     EXPECT_FALSE(queryObj4.IsQueryOnlyByKey());
947 
948     QueryObject queryObj5(queryEQ);
949     EXPECT_FALSE(queryObj5.IsQueryOnlyByKey());
950 
951     QueryObject queryObj6(queryLimitEQ);
952     EXPECT_FALSE(queryObj6.IsQueryOnlyByKey());
953 }
954 
955 /**
956   * @tc.name: MultiQueryParcel
957   * @tc.desc: Mix multiple conditions for simultaneous query can be serialize
958   * @tc.type: FUNC
959   * @tc.require:
960   * @tc.author: sunpeng
961   */
962 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiQueryParcel, TestSize.Level1)
963 {
964     Query queryInvalidField = Query::Select().LessThan("$.field_name1", 1);
965     Query queryInvalidCombine = Query::Select().EqualTo("$.field_name3", 1).BeginGroup();
966     Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
967 
968     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
969     std::vector<SingleVerKvEntry *> entries;
970     ContinueToken token = nullptr;
971 
972     QuerySyncObject querySyncObj(queryInvalidField);
973     vector<uint8_t> buffer(querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
974     Parcel writeParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
975     Parcel readParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
976     EXPECT_EQ(querySyncObj.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
977     QuerySyncObject queryObjAfterSer;
978     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObjAfterSer), E_OK);
979     EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer, SyncTimeRange{}, specInfo, token, entries),
980         -E_INVALID_QUERY_FORMAT);
981 
982     QuerySyncObject querySyncObj1(queryInvalidCombine);
983     vector<uint8_t> buffer1(querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
984     Parcel writeParcel1(buffer1.data(), querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
985     Parcel readParcel1(buffer1.data(), querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
986     EXPECT_EQ(querySyncObj1.SerializeData(writeParcel1, SOFTWARE_VERSION_CURRENT), E_OK);
987     QuerySyncObject queryObjAfterSer1;
988     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel1, queryObjAfterSer1), E_OK);
989     EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer1, SyncTimeRange{}, specInfo, token, entries),
990         -E_INVALID_QUERY_FORMAT);
991 
992     QuerySyncObject querySyncObj2(queryPrefixKeyLimit);
993     vector<uint8_t> buffer2(querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
994     Parcel writeParcel2(buffer2.data(), querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
995     Parcel readParcel2(buffer2.data(), querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
996     EXPECT_EQ(querySyncObj2.SerializeData(writeParcel2, SOFTWARE_VERSION_CURRENT), E_OK);
997     QuerySyncObject queryObjAfterSer2;
998     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel2, queryObjAfterSer2), E_OK);
999     EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer2, SyncTimeRange{}, specInfo, token, entries),
1000         E_OK);
1001     EXPECT_FALSE(entries.empty());
1002     ReleaseKvEntries(entries);
1003 }
1004 
1005 
1006 /**
1007   * @tc.name: QueryParcel001
1008   * @tc.desc: Query object should has same attribute(Limit, OrderBy) after deserialized
1009   * @tc.type: FUNC
1010   * @tc.require:
1011   * @tc.author: xulianhui
1012   */
1013 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryParcel001, TestSize.Level1)
1014 {
1015     Query query = Query::Select().OrderBy("$.field_name1").Limit(10, 5);
1016 
1017     QuerySyncObject querySyncObj(query);
1018     vector<uint8_t> buffer(querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
1019     Parcel writeParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1020     Parcel readParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1021     EXPECT_EQ(querySyncObj.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1022     QuerySyncObject queryObjAfterSer;
1023     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObjAfterSer), E_OK);
1024     EXPECT_EQ(queryObjAfterSer.HasLimit(), true);
1025     int limit = 0;
1026     int offset = 0;
1027     queryObjAfterSer.GetLimitVal(limit, offset);
1028     EXPECT_EQ(limit, 10);
1029     EXPECT_EQ(offset, 5);
1030     EXPECT_EQ(queryObjAfterSer.HasOrderBy(), true);
1031 }
1032 
1033 /**
1034   * @tc.name: MultiQueryGetSyncData001
1035   * @tc.desc: Mix multiple conditions for simultaneous query
1036   * @tc.type: FUNC
1037   * @tc.require:
1038   * @tc.author: sunpeng
1039   */
1040 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiQueryGetSyncData001, TestSize.Level1)
1041 {
1042     Query query = Query::Select();
1043     Query query1 = Query::Select().EqualTo("$.field_name1", true);
1044     Query query2 = Query::Select().BeginGroup().GreaterThan("$.field_name3", 1).EndGroup();
1045     Query query3 = Query::Select().Like("field_name7", "");
1046     Query query4 = Query::Select().PrefixKey({}).OrderBy("$.field_name6");
1047     Query query5 = Query::Select().PrefixKey({}).IsNull("field_name10");
1048 
1049     DataSizeSpecInfo  specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
1050     std::vector<SingleVerKvEntry *> entries;
1051     ContinueToken token = nullptr;
1052 
1053     QueryObject queryObj(query);
1054     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
1055     ReleaseKvEntries(entries);
1056 
1057     QueryObject queryObj1(query1);
1058     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), E_OK);
1059     EXPECT_EQ(entries.size(), 1UL);
1060     ReleaseKvEntries(entries);
1061 
1062     QueryObject queryObj2(query2);
1063     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
1064     ReleaseKvEntries(entries);
1065 
1066     QueryObject queryObj3(query3);
1067     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj3, SyncTimeRange{}, specInfo, token, entries), E_OK);
1068     ReleaseKvEntries(entries);
1069 
1070     QueryObject queryObj4(query4);
1071     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj4, SyncTimeRange{}, specInfo, token, entries), E_OK);
1072     ReleaseKvEntries(entries);
1073 
1074     QueryObject queryObj5(query5);
1075     EXPECT_EQ(g_schemaStore->GetSyncData(queryObj5, SyncTimeRange{}, specInfo, token, entries), E_OK);
1076     ReleaseKvEntries(entries);
1077 }
1078 
1079 /**
1080   * @tc.name: QueryPredicateValidation001
1081   * @tc.desc: check query object is query only by key and has orderBy or not
1082   * @tc.type: FUNC
1083   * @tc.require: AR000FN6G9
1084   * @tc.author: xulianhui
1085   */
1086 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryPredicateValidation001, TestSize.Level1)
1087 {
1088     /**
1089      * @tc.steps:step1. Create a query object with prefixKey only, check it's predicate
1090      * @tc.expected: step1. check IsQueryOnlyByKey true; check HasOrderBy false
1091      */
1092     Query query1 = Query::Select().PrefixKey({});
1093     QuerySyncObject querySync1(query1);
1094     EXPECT_EQ(querySync1.IsQueryOnlyByKey(), true);
1095     EXPECT_EQ(querySync1.HasOrderBy(), false);
1096 
1097     /**
1098      * @tc.steps:step2. Create a query object with prefixKey and equalTo, check it's predicate
1099      * @tc.expected: step2. check IsQueryOnlyByKey false; check HasOrderBy false
1100      */
1101     Query query2 = Query::Select().PrefixKey({}).EqualTo("$.testField", 0);
1102     QuerySyncObject querySync2(query2);
1103     EXPECT_EQ(querySync2.IsQueryOnlyByKey(), false);
1104     EXPECT_EQ(querySync2.HasOrderBy(), false);
1105 
1106     /**
1107      * @tc.steps:step3. Create a query object with orderBy only, check it's predicate
1108      * @tc.expected: step3. check IsQueryOnlyByKey false; check HasOrderBy true
1109      */
1110     Query query3 = Query::Select().OrderBy("$.testField");
1111     QuerySyncObject querySync3(query3);
1112     EXPECT_EQ(querySync3.IsQueryOnlyByKey(), false);
1113     EXPECT_EQ(querySync3.HasOrderBy(), true);
1114 }
1115 
1116 /**
1117   * @tc.name: RelationalQuerySyncTest001
1118   * @tc.desc: Test querySyncObject serialize with table name is specified
1119   * @tc.type: FUNC
1120   * @tc.require:
1121   * @tc.author: xulianhui
1122   */
1123 HWTEST_F(DistributedDBStorageQuerySyncTest, RelationalQuerySyncTest001, TestSize.Level1)
1124 {
1125     /**
1126      * @tc.steps:step1. Create a query object with table name is specified
1127      * @tc.expected: ok
1128      */
1129     Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1130     QuerySyncObject obj1(query1);
1131 
1132     /**
1133      * @tc.steps:step2. Serialize the object
1134      * @tc.expected: ok
1135      */
1136     uint32_t buffLen = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1137     vector<uint8_t> buffer(buffLen, 0);
1138     Parcel writeParcel(buffer.data(), buffLen);
1139     EXPECT_EQ(obj1.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1140 
1141     /**
1142      * @tc.steps:step3. DeSerialize the data
1143      * @tc.expected: ok, And the queryId is same
1144      */
1145     Parcel readParcel(buffer.data(), buffLen);
1146     QuerySyncObject queryObj2;
1147     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), E_OK);
1148     EXPECT_EQ(obj1.GetIdentify(), queryObj2.GetIdentify());
1149 }
1150 
1151 /**
1152   * @tc.name: RelationalQuerySyncTest002
1153   * @tc.desc: Test querySyncObject with different table name has different identity
1154   * @tc.type: FUNC
1155   * @tc.require:
1156   * @tc.author: xulianhui
1157   */
1158 HWTEST_F(DistributedDBStorageQuerySyncTest, RelationalQuerySyncTest002, TestSize.Level1)
1159 {
1160     Query query1 = Query::Select("Relational_table1").EqualTo("field1", "abc");
1161     QuerySyncObject obj1(query1);
1162 
1163     Query query2 = Query::Select("Relational_table2").EqualTo("field1", "abc");
1164     QuerySyncObject obj2(query2);
1165 
1166     /**
1167      * @tc.steps:step1. check object identity
1168      * @tc.expected: identity should be different.
1169      */
1170     EXPECT_NE(obj1.GetIdentify(), obj2.GetIdentify());
1171 }
1172 
1173 /**
1174  * @tc.name: SerializeAndDeserializeForVer1
1175  * @tc.desc: Test querySyncObject serialization and deserialization.
1176  * @tc.type: FUNC
1177  * @tc.require: AR000GOHO7
1178  * @tc.author: lidongwei
1179  */
1180 HWTEST_F(DistributedDBStorageQuerySyncTest, SerializeAndDeserializeForVer1, TestSize.Level1)
1181 {
1182     Query qeury1 = Query::Select("table1").EqualTo("field1", "abc").InKeys({KEY_1, KEY_2, KEY_3});
1183     QuerySyncObject obj1(qeury1);
1184 
1185     /**
1186      * @tc.steps:step1. Serialize obj1.
1187      * @tc.expected: Serialize successfully.
1188      */
1189     auto len = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1190     std::vector<uint8_t> buffer(len);
1191     Parcel parcel1(buffer.data(), buffer.size());
1192     obj1.SerializeData(parcel1, SOFTWARE_VERSION_CURRENT);
1193     ASSERT_EQ(parcel1.IsError(), false);
1194 
1195     /**
1196      * @tc.steps:step2. Deserialize obj1.
1197      * @tc.expected: Deserialize successfully.
1198      */
1199     QuerySyncObject obj2;
1200     Parcel parcel2(buffer.data(), buffer.size());
1201     ASSERT_EQ(parcel2.IsError(), false);
1202 
1203     /**
1204      * @tc.steps:step3. check object identity
1205      * @tc.expected: identity should be the same.
1206      */
1207     EXPECT_NE(obj1.GetIdentify(), obj2.GetIdentify());
1208 }
1209 
1210 /**
1211  * @tc.name: MultiInkeys1
1212  * @tc.desc: Test the rc when multiple inkeys exists.
1213  * @tc.type: FUNC
1214  * @tc.require: AR000GOHO7
1215  * @tc.author: lidongwei
1216  */
1217 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiInkeys1, TestSize.Level1)
1218 {
1219     /**
1220      * @tc.steps:step1. Create an invalid query, with multiple inkeys.
1221      */
1222     Query query = Query::Select().InKeys({KEY_1, KEY_2}).InKeys({KEY_3});
1223 
1224     /**
1225      * @tc.steps:step2. Get data.
1226      * @tc.expected: Return INVALID_QUERY_FORMAT.
1227      */
1228     std::vector<Entry> entries;
1229     IOption option;
1230     option.dataType = IOption::SYNC_DATA;
1231     EXPECT_EQ(g_schemaConnect->GetEntries(option, query, entries), -E_INVALID_QUERY_FORMAT);
1232 }
1233 
1234 /**
1235   * @tc.name: QueryObject001
1236   * @tc.desc: Parse query object when node is empty
1237   * @tc.type: FUNC
1238   * @tc.require:
1239   * @tc.author: bty
1240   */
1241 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject001, TestSize.Level1)
1242 {
1243     std::list<QueryObjNode> nodes;
1244     QueryObjNode node;
1245     nodes.push_back(node);
1246     std::vector<uint8_t> key;
1247     std::set<Key> keys;
1248     QueryObject queryObj(nodes, key, keys);
1249     EXPECT_EQ(queryObj.ParseQueryObjNodes(), -E_INVALID_QUERY_FORMAT);
1250 }
1251 
1252 /**
1253   * @tc.name: QueryObject002
1254   * @tc.desc: Serialize query sync object when node is empty
1255   * @tc.type: FUNC
1256   * @tc.require:
1257   * @tc.author: bty
1258   */
1259 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject002, TestSize.Level1)
1260 {
1261     /**
1262      * @tc.steps:step1. Create a query object and parcel
1263      * @tc.expected: ok
1264      */
1265     std::list<QueryObjNode> nodes;
1266     QueryObjNode node;
1267     nodes.push_back(node);
1268     std::vector<uint8_t> key;
1269     std::set<Key> keys;
1270     QuerySyncObject querySyncObj1(nodes, key, keys);
1271     uint32_t len = 120; // 120 is the number of serialized prefixes
1272     std::vector<uint8_t> buff(len, 0);
1273     Parcel parcel(buff.data(), len);
1274 
1275     /**
1276      * @tc.steps:step2. Serialize data when node is empty
1277      * @tc.expected: -E_INVALID_QUERY_FORMAT
1278      */
1279     EXPECT_EQ(querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT - 1), (uint32_t) 0);
1280     EXPECT_EQ(querySyncObj1.SerializeData(parcel, 0), -E_INVALID_QUERY_FORMAT);
1281 
1282     /**
1283      * @tc.steps:step2. Serialize data when parcel len is zero
1284      * @tc.expected: -E_INVALID_ARGS
1285      */
1286     Query query = Query::Select("Relational_table");
1287     QuerySyncObject querySyncObj2(query);
1288     Parcel parcel1(buff.data(), 0);
1289     EXPECT_EQ(querySyncObj2.SerializeData(parcel1, 0), -E_INVALID_ARGS);
1290 }
1291 
1292 /**
1293   * @tc.name: QueryObject003
1294   * @tc.desc: Test DeSerializeData under error Parcel buffer
1295   * @tc.type: FUNC
1296   * @tc.require:
1297   * @tc.author: bty
1298   */
1299 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject003, TestSize.Level1)
1300 {
1301     /**
1302      * @tc.steps:step1. Create a query object with table name is specified
1303      * @tc.expected: ok
1304      */
1305     Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1306     QuerySyncObject obj1(query1);
1307 
1308     /**
1309      * @tc.steps:step2. Serialize the object
1310      * @tc.expected: ok
1311      */
1312     uint32_t buffLen = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1313     vector<uint8_t> buffer(buffLen, 0);
1314     Parcel writeParcel(buffer.data(), buffLen);
1315     EXPECT_EQ(obj1.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1316 
1317     /**
1318      * @tc.steps:step3. Deserialize data when the version number is abnormal
1319      * @tc.expected: -E_VERSION_NOT_SUPPORT,then correct the version number
1320      */
1321     EXPECT_EQ(buffLen, 120u); // 120 is the max buffer len
1322     uint8_t oldValue = *(buffer.data() + VERSION_BIT);
1323     uint8_t newValue = 2;
1324     ASSERT_EQ(memcpy_s(buffer.data() + VERSION_BIT, sizeof(newValue), &newValue, sizeof(newValue)), 0);
1325     Parcel readParcel(buffer.data(), buffLen);
1326     QuerySyncObject queryObj2;
1327     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), -E_VERSION_NOT_SUPPORT);
1328     ASSERT_EQ(memcpy_s(buffer.data() + VERSION_BIT, sizeof(oldValue), &oldValue, sizeof(oldValue)), 0);
1329 
1330     /**
1331      * @tc.steps:step4. Deserialize data when the key size is abnormal
1332      * @tc.expected: -E_PARSE_FAIL
1333      */
1334     Parcel writeParcel2(buffer.data() + 116, buffLen); // 116 is the starting bit of key
1335     writeParcel2.WriteUInt32(DBConstant::MAX_INKEYS_SIZE + 1);
1336     Parcel readParcel2(buffer.data(), buffLen);
1337     EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel2, queryObj2), -E_PARSE_FAIL);
1338 }
1339 
1340 /**
1341   * @tc.name: QueryObject004
1342   * @tc.desc: Put sync data under error condition
1343   * @tc.type: FUNC
1344   * @tc.require:
1345   * @tc.author: bty
1346   */
1347 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject004, TestSize.Level1)
1348 {
1349     /**
1350      * @tc.steps:step1. Put in error store
1351      * @tc.expected: -E_INVALID_DB
1352      */
1353     Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1354     QuerySyncObject obj1(query1);
1355     std::vector<SingleVerKvEntry *> entry;
1356     std::string deviceName = "";
1357     std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
1358     EXPECT_EQ(errStore->PutSyncDataWithQuery(obj1, entry, deviceName), -E_INVALID_DB);
1359 
1360     /**
1361      * @tc.steps:step2. Put in correct store but device name is null
1362      * @tc.expected: -E_NOT_SUPPORT
1363      */
1364     EXPECT_EQ(g_store->PutSyncDataWithQuery(obj1, entry, deviceName), -E_NOT_SUPPORT);
1365 
1366     /**
1367      * @tc.steps:step3. Put in correct store but device name is over size
1368      * @tc.expected: -E_INVALID_ARGS
1369      */
1370     vector<uint8_t> buffer(129, 1); // 129 is greater than 128
1371     deviceName.assign(buffer.begin(), buffer.end());
1372     EXPECT_EQ(g_store->PutSyncDataWithQuery(obj1, entry, deviceName), -E_INVALID_ARGS);
1373 }
1374 
1375 /**
1376   * @tc.name: QueryObject005
1377   * @tc.desc: Set engine state to cache and then put sync data
1378   * @tc.type: FUNC
1379   * @tc.require:
1380   * @tc.author: bty
1381   */
1382 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject005, TestSize.Level1)
1383 {
1384     KvDBProperties property;
1385     property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
1386     property.SetStringProp(KvDBProperties::STORE_ID, "31");
1387     property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, "TestQuerySync");
1388     property.SetBoolProp(KvDBProperties::MEMORY_MODE, false);
1389     property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE);
1390     property.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, ConflictResolvePolicy::DEVICE_COLLABORATION);
1391     int errCode = E_OK;
1392     SQLiteSingleVerStorageEngine *storageEngine =
1393         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(property, errCode));
1394     ASSERT_EQ(errCode, E_OK);
1395     ASSERT_NE(storageEngine, nullptr);
1396     storageEngine->SetEngineState(CACHEDB);
1397     DataItem data1{KEY1, VALUE1, 0, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
1398     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data1}, REMOTE_DEVICE_ID), -1);
1399     storageEngine->Release();
1400 }