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 }