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