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 g_store->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 g_schemaStore->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: AR000CRAKO
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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: AR000FN6G9
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 // same object identify is same
630 EXPECT_EQ(querySync.GetIdentify(), querySync.GetIdentify());
631
632 IOption option;
633 option.dataType = IOption::SYNC_DATA;
634 Key key;
635 Value value;
636 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
637 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
638 EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
639 EXPECT_EQ(g_connection->Put(option, KEY_1, VALUE_1), E_OK);
640 EXPECT_EQ(g_connection->Put(option, KEY_2, VALUE_2), E_OK);
641
642 /**
643 * @tc.steps:step2. Get prefix key condition query object, get this object identify
644 * @tc.expected: step2. GetIdentify result not same as other condition query object
645 */
646 Query query2 = Query::Select().PrefixKey(key);
647 QuerySyncObject querySync1(query2);
648 EXPECT_EQ(querySync1.GetIdentify().empty(), false);
649 // same object identify is not same
650 EXPECT_NE(querySync.GetIdentify(), querySync1.GetIdentify());
651
652 /**
653 * @tc.steps:step3. empty condition query object can serialized and deserialized normally
654 * @tc.expected: step3. after deserialized, can get all key value in database
655 */
656 vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
657 Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
658 Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
659 EXPECT_EQ(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
660
661 QuerySyncObject queryObj2;
662 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), E_OK);
663 LOGD("Query obj after serialize!");
664
665 DataSizeSpecInfo specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
666 std::vector<SingleVerKvEntry *> entries;
667 ContinueToken token = nullptr;
668 EXPECT_EQ(g_store->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
669 EXPECT_EQ(entries.size(), 3UL);
670 SingleVerKvEntry::Release(entries);
671 }
672
673 /**
674 * @tc.name: GetQueryID003
675 * @tc.desc: To test the function of generating query identity ignore limit, orderby, suggestion.
676 * @tc.type: FUNC
677 * @tc.require: AR000FN6G9
678 * @tc.author: sunpeng
679 */
680 HWTEST_F(DistributedDBStorageQuerySyncTest, GetQueryID003, TestSize.Level1)
681 {
682 /**
683 * @tc.steps:step1. Get empty condition query object, get this object identify
684 */
685 Query query1 = Query::Select().PrefixKey({});
686 QuerySyncObject querySync1(query1);
687 std::string id1 = querySync1.GetIdentify();
688 EXPECT_EQ(id1.empty(), false);
689
690 /**
691 * @tc.steps:step2. Get limit condition query object, get this object identify
692 * @tc.expected: step2. GetIdentify result same as no contain limit condition
693 */
694 Query query2 = query1.Limit(1, 1);
695 QuerySyncObject querySync2(query2);
696 std::string id2 = querySync2.GetIdentify();
697 EXPECT_EQ(id2, id1);
698
699 /**
700 * @tc.steps:step3. Get orderby condition query object, get this object identify
701 * @tc.expected: step3. GetIdentify result same as no contain orderby condition
702 */
703 Query query3 = query2.OrderBy("$.test");
704 QuerySyncObject querySync3(query3);
705 std::string id3 = querySync3.GetIdentify();
706 EXPECT_EQ(id2, id3);
707 }
708
709 /**
710 * @tc.name: Serialize001
711 * @tc.desc: To test the function of querying the data after serialized and deserialized.
712 * @tc.type: FUNC
713 * @tc.require: AR000FN6G9
714 * @tc.author: sunpeng
715 */
716 HWTEST_F(DistributedDBStorageQuerySyncTest, Serialize001, TestSize.Level1)
717 {
718 /**
719 * @tc.steps:step1. Put K1V1 K2V2 and rand KV for query
720 */
721 IOption option;
722 option.dataType = IOption::SYNC_DATA;
723 Key key;
724 Value value;
725 DistributedDBToolsUnitTest::GetRandomKeyValue(key);
726 DistributedDBToolsUnitTest::GetRandomKeyValue(value);
727 EXPECT_EQ(g_connection->Put(option, key, value), E_OK);
728 EXPECT_EQ(g_connection->Put(option, KEY_1, VALUE_1), E_OK);
729 EXPECT_EQ(g_connection->Put(option, KEY_2, VALUE_2), E_OK);
730
731 /**
732 * @tc.steps:step2. Put K1V1 K2V2 and rand KV for query
733 * @tc.expected: step2. GetIdentify result same as no contain limit condition
734 */
735 Query query = Query::Select().PrefixKey(key);
736 QueryObject queryObj(query);
737 DataSizeSpecInfo specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
738 std::vector<SingleVerKvEntry *> entries;
739 ContinueToken token = nullptr;
740 LOGD("Ori query obj!");
741 EXPECT_EQ(g_store->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
742 EXPECT_EQ(entries.size(), 1UL);
743 SingleVerKvEntry::Release(entries);
744
745 /**
746 * @tc.steps:step3. query result after serialized and deserialized
747 * @tc.expected: step3. Get same result
748 */
749 QuerySyncObject querySync(query);
750 vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
751 Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
752 Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
753 EXPECT_EQ(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
754
755 QuerySyncObject queryObj1;
756 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj1), E_OK);
757
758 LOGD("Query obj after serialize!");
759 EXPECT_EQ(g_store->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), E_OK);
760 EXPECT_EQ(entries.size(), 1UL);
761 SingleVerKvEntry::Release(entries);
762
763 std::string id = querySync.GetIdentify().c_str();
764 EXPECT_EQ(id.size(), 64u);
765 LOGD("query identify [%s] [%zu]", id.c_str(), id.size());
766 }
767
768 /**
769 * @tc.name: Serialize002
770 * @tc.desc: To test the function of serialized illegal query object.
771 * @tc.type: FUNC
772 * @tc.require: AR000FN6G9
773 * @tc.author: sunpeng
774 */
775 HWTEST_F(DistributedDBStorageQuerySyncTest, Serialize002, TestSize.Level1)
776 {
777 /**
778 * @tc.steps:step1. Serialized illegal query object
779 * @tc.expected: step1. return not E_OK
780 */
781 Query query = Query::Select().PrefixKey({}).GreaterThan("$.test", true); // bool can not compare
782 QuerySyncObject querySync(query);
783 vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
784 Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
785 EXPECT_NE(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
786 }
787
788 /**
789 * @tc.name: DeSerialize001
790 * @tc.desc: To test the function of deserialized illegal query object.
791 * @tc.type: FUNC
792 * @tc.require: AR000FN6G9
793 * @tc.author: sunpeng
794 */
795 HWTEST_F(DistributedDBStorageQuerySyncTest, DeSerialize001, TestSize.Level1)
796 {
797 /**
798 * @tc.steps:step1. deserialized empty content query object
799 * @tc.expected: step1. return not E_OK
800 */
801 QuerySyncObject querySync;
802 vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
803 Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
804
805 QuerySyncObject queryObj;
806 EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel, queryObj), E_OK);
807
808 /**
809 * @tc.steps:step2. deserialized empty parcel
810 * @tc.expected: step2. return not E_OK
811 */
812 buffer.resize(0);
813 Parcel readParcel1(buffer.data(), 0);
814 EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel1, queryObj), E_OK);
815
816 /**
817 * @tc.steps:step3. deserialized error size parcel
818 * @tc.expected: step3. return not E_OK
819 */
820 uint8_t simSize = 0;
821 RAND_bytes(&simSize, 1);
822 buffer.resize(simSize);
823 Parcel readParcel2(buffer.data(), simSize);
824 EXPECT_NE(QuerySyncObject::DeSerializeData(readParcel2, queryObj), E_OK);
825 }
826
827 /**
828 * @tc.name: DeSerialize002
829 * @tc.desc: Test deserialize with query node over limit
830 * @tc.type: FUNC
831 * @tc.require:
832 * @tc.author: lianhuixxx
833 */
834 HWTEST_F(DistributedDBStorageQuerySyncTest, DeSerialize002, TestSize.Level1)
835 {
836 Query query = Query::Select().EqualTo("field_0", 0);
837 for (int i = 1; i <= 128; i++) { // 128: query node size
838 query = query.And().EqualTo("field_" + std::to_string(i), i);
839 }
840 EXPECT_TRUE(GetQueryInfo::GetQueryExpression(query).GetErrFlag());
841
842 query = query.OrderBy("field_0");
843 EXPECT_FALSE(GetQueryInfo::GetQueryExpression(query).GetErrFlag());
844
845 // fake query sync object with query node over limit
846 std::list<QueryObjNode> queryObjNodes;
847 for (int i = 0; i <= 258; i++) { // 258: over query node limit
848 queryObjNodes.push_back(QueryObjNode {QueryObjType::EQUALTO, "field_" + std::to_string(i),
849 QueryValueType::VALUE_TYPE_INTEGER, {}});
850 }
851
852 QuerySyncObject querySync(queryObjNodes, {}, {});
853 vector<uint8_t> buffer(querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
854 Parcel writeParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
855 EXPECT_EQ(querySync.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
856
857 QuerySyncObject queryObj;
858 Parcel readParcel(buffer.data(), querySync.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
859 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj), -E_INVALID_ARGS);
860 }
861
862 /**
863 * @tc.name: SameQueryObjectIdInDiffVer001
864 * @tc.desc: Same query object have same id in different version.
865 * @tc.type: FUNC
866 * @tc.require: AR000FN6G9
867 * @tc.author: sunpeng
868 */
869 HWTEST_F(DistributedDBStorageQuerySyncTest, SameQueryObjectIdInDiffVer001, TestSize.Level1)
870 {
871 /**
872 * @tc.steps:step1. Record the fixed id of the query object of the current version,
873 * and keep it unchanged in subsequent versions
874 * @tc.expected: step1. Never change in diff version
875 */
876 Query query1 = Query::Select().PrefixKey({});
877 QuerySyncObject querySync1(query1);
878 EXPECT_EQ(querySync1.GetIdentify(), "A9AB721457C4CA98726EECC7CB16F94E31B9752BEE6D08569CFE797B4A64A304");
879
880 Query query2 = Query::Select();
881 QuerySyncObject querySync2(query2);
882 EXPECT_EQ(querySync2.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
883
884 Query query3 = Query::Select().NotLike("$.test", "testValue");
885 QuerySyncObject querySync3(query3);
886 EXPECT_EQ(querySync3.GetIdentify(), "F2BAC2B53FE81F9928E5F8DCDF502F2419E8CEB5DFC157EEBDDB955A66C0148B");
887
888 vector<int> fieldValues{1, 1, 1};
889 Query query4 = Query::Select().In("$.test", fieldValues);
890 QuerySyncObject querySync4(query4);
891 EXPECT_EQ(querySync4.GetIdentify(), "EEAECCD0E1A7217574ED3092C8DAA39469388FA1B8B7B210185B4257B785FE4D");
892
893 Query query5 = Query::Select().OrderBy("$.test.test_child", false);
894 QuerySyncObject querySync5(query5);
895 EXPECT_EQ(querySync5.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
896
897 Query query6 = Query::Select().Limit(1, 2);
898 QuerySyncObject querySync6(query6);
899 EXPECT_EQ(querySync6.GetIdentify(), "AF5570F5A1810B7AF78CAF4BC70A660F0DF51E42BAF91D4DE5B2328DE0E83DFC");
900
901 Query query7 = Query::Select().IsNull("$.test.test_child");
902 QuerySyncObject querySync7(query7);
903 EXPECT_EQ(querySync7.GetIdentify(), "762AB5FDF9B1433D6F398269D4DDD6DE6444953F515E87C6796654180A7FF422");
904
905 Query query8 = Query::Select().EqualTo("$.test.test_child", true).And().GreaterThan("$.test.test_child", 1);
906 QuerySyncObject querySync8(query8);
907 EXPECT_EQ(querySync8.GetIdentify(), "B97FBFFBC690DAF25031FD4EE8ADC92F4698B9E81FD4877CD54EDEA122F6A6E0");
908
909 Query query9 = Query::Select().GreaterThan("$.test", 1).OrderBy("$.test");
910 QuerySyncObject querySync9(query9);
911 EXPECT_EQ(querySync9.GetIdentify(), "77480E3EE04EB1500BB2F1A31704EE5676DC81F088A7A300F6D30E3FABA7D0A3");
912
913 Query query = Query::Select().GreaterThan("$.test1", 1).OrderBy("$.test1");
914 QuerySyncObject querySync(query);
915 EXPECT_EQ(querySync.GetIdentify(), "170F5137C0BB49011D7415F706BD96B86F5FAFADA356374981362B1E177263B9");
916 }
917
918 /**
919 * @tc.name: querySyncByField
920 * @tc.desc: Test for illegal query conditions, use GetSyncData
921 * @tc.type: FUNC
922 * @tc.require:
923 * @tc.author: sunpeng
924 */
925 HWTEST_F(DistributedDBStorageQuerySyncTest, querySyncByField, TestSize.Level1)
926 {
927 Query queryInvalidField = Query::Select().EqualTo("$.field_name11", 1);
928 Query queryInvalidCombine = Query::Select().EqualTo("$.field_name3", 1).BeginGroup();
929 Query queryAll = Query::Select();
930 Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
931
932 DataSizeSpecInfo specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
933 std::vector<SingleVerKvEntry *> entries;
934 ContinueToken token = nullptr;
935
936 QueryObject queryObj(queryInvalidCombine);
937 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), -E_INVALID_QUERY_FORMAT);
938
939 QueryObject queryObj2(queryAll);
940 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
941 EXPECT_EQ(entries.size(), 1UL);
942 ReleaseKvEntries(entries);
943
944 QueryObject queryObj1(queryInvalidField);
945 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), -E_INVALID_QUERY_FIELD);
946
947 QueryObject queryObj3(queryPrefixKeyLimit);
948 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj3, SyncTimeRange{}, specInfo, token, entries), E_OK);
949 ReleaseKvEntries(entries);
950 }
951
952 /**
953 * @tc.name: IsQueryOnlyByKey
954 * @tc.desc: The test can correctly determine whether the value is used for query
955 * @tc.type: FUNC
956 * @tc.require:
957 * @tc.author: sunpeng
958 */
959 HWTEST_F(DistributedDBStorageQuerySyncTest, IsQueryOnlyByKey, TestSize.Level1)
960 {
961 Query queryAll = Query::Select();
962 Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
963 Query queryPrefix = Query::Select().PrefixKey({});
964 Query queryPrefixKeyLimitIndex = Query::Select().PrefixKey({}).Limit(1, 0).SuggestIndex("$.field_name3");
965 Query queryPrefixKeyLimitEQ = Query::Select().PrefixKey({}).Limit(1, 0).EqualTo("$.field_name3", 1);
966 Query queryEQ = Query::Select().EqualTo("$.field_name3", 1);
967 Query queryLimitEQ = Query::Select().Limit(1, 0).EqualTo("$.field_name3", 1);
968
969 QueryObject queryObj(queryAll);
970 EXPECT_TRUE(queryObj.IsQueryOnlyByKey());
971
972 QueryObject queryObj1(queryPrefixKeyLimit);
973 EXPECT_TRUE(queryObj1.IsQueryOnlyByKey());
974
975 QueryObject queryObj2(queryPrefix);
976 EXPECT_TRUE(queryObj2.IsQueryOnlyByKey());
977
978 QueryObject queryObj3(queryPrefixKeyLimitIndex);
979 EXPECT_FALSE(queryObj3.IsQueryOnlyByKey());
980
981 QueryObject queryObj4(queryPrefixKeyLimitEQ);
982 EXPECT_FALSE(queryObj4.IsQueryOnlyByKey());
983
984 QueryObject queryObj5(queryEQ);
985 EXPECT_FALSE(queryObj5.IsQueryOnlyByKey());
986
987 QueryObject queryObj6(queryLimitEQ);
988 EXPECT_FALSE(queryObj6.IsQueryOnlyByKey());
989 }
990
991 /**
992 * @tc.name: MultiQueryParcel
993 * @tc.desc: Mix multiple conditions for simultaneous query can be serialize
994 * @tc.type: FUNC
995 * @tc.require:
996 * @tc.author: sunpeng
997 */
998 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiQueryParcel, TestSize.Level1)
999 {
1000 Query queryInvalidField = Query::Select().LessThan("$.field_name1", 1);
1001 Query queryInvalidCombine = Query::Select().EqualTo("$.field_name3", 1).BeginGroup();
1002 Query queryPrefixKeyLimit = Query::Select().PrefixKey({}).Limit(1, 0);
1003
1004 DataSizeSpecInfo specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
1005 std::vector<SingleVerKvEntry *> entries;
1006 ContinueToken token = nullptr;
1007
1008 QuerySyncObject querySyncObj(queryInvalidField);
1009 vector<uint8_t> buffer(querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
1010 Parcel writeParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1011 Parcel readParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1012 EXPECT_EQ(querySyncObj.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1013 QuerySyncObject queryObjAfterSer;
1014 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObjAfterSer), E_OK);
1015 EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer, SyncTimeRange{}, specInfo, token, entries),
1016 -E_INVALID_QUERY_FORMAT);
1017
1018 QuerySyncObject querySyncObj1(queryInvalidCombine);
1019 vector<uint8_t> buffer1(querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
1020 Parcel writeParcel1(buffer1.data(), querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1021 Parcel readParcel1(buffer1.data(), querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1022 EXPECT_EQ(querySyncObj1.SerializeData(writeParcel1, SOFTWARE_VERSION_CURRENT), E_OK);
1023 QuerySyncObject queryObjAfterSer1;
1024 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel1, queryObjAfterSer1), E_OK);
1025 EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer1, SyncTimeRange{}, specInfo, token, entries),
1026 -E_INVALID_QUERY_FORMAT);
1027
1028 QuerySyncObject querySyncObj2(queryPrefixKeyLimit);
1029 vector<uint8_t> buffer2(querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
1030 Parcel writeParcel2(buffer2.data(), querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1031 Parcel readParcel2(buffer2.data(), querySyncObj2.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1032 EXPECT_EQ(querySyncObj2.SerializeData(writeParcel2, SOFTWARE_VERSION_CURRENT), E_OK);
1033 QuerySyncObject queryObjAfterSer2;
1034 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel2, queryObjAfterSer2), E_OK);
1035 EXPECT_EQ(g_schemaStore->GetSyncData(queryObjAfterSer2, SyncTimeRange{}, specInfo, token, entries),
1036 E_OK);
1037 EXPECT_FALSE(entries.empty());
1038 ReleaseKvEntries(entries);
1039 }
1040
1041
1042 /**
1043 * @tc.name: QueryParcel001
1044 * @tc.desc: Query object should has same attribute(Limit, OrderBy) after deserialized
1045 * @tc.type: FUNC
1046 * @tc.require:
1047 * @tc.author: xulianhui
1048 */
1049 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryParcel001, TestSize.Level1)
1050 {
1051 Query query = Query::Select().OrderBy("$.field_name1").Limit(10, 5);
1052
1053 QuerySyncObject querySyncObj(query);
1054 vector<uint8_t> buffer(querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT), 0);
1055 Parcel writeParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1056 Parcel readParcel(buffer.data(), querySyncObj.CalculateParcelLen(SOFTWARE_VERSION_CURRENT));
1057 EXPECT_EQ(querySyncObj.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1058 QuerySyncObject queryObjAfterSer;
1059 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObjAfterSer), E_OK);
1060 EXPECT_EQ(queryObjAfterSer.HasLimit(), true);
1061 int limit = 0;
1062 int offset = 0;
1063 queryObjAfterSer.GetLimitVal(limit, offset);
1064 EXPECT_EQ(limit, 10);
1065 EXPECT_EQ(offset, 5);
1066 EXPECT_EQ(queryObjAfterSer.HasOrderBy(), true);
1067 }
1068
1069 /**
1070 * @tc.name: MultiQueryGetSyncData001
1071 * @tc.desc: Mix multiple conditions for simultaneous query
1072 * @tc.type: FUNC
1073 * @tc.require:
1074 * @tc.author: sunpeng
1075 */
1076 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiQueryGetSyncData001, TestSize.Level1)
1077 {
1078 Query query = Query::Select();
1079 Query query1 = Query::Select().EqualTo("$.field_name1", true);
1080 Query query2 = Query::Select().BeginGroup().GreaterThan("$.field_name3", 1).EndGroup();
1081 Query query3 = Query::Select().Like("field_name7", "");
1082 Query query4 = Query::Select().PrefixKey({}).OrderBy("$.field_name6");
1083 Query query5 = Query::Select().PrefixKey({}).IsNull("field_name10");
1084
1085 DataSizeSpecInfo specInfo = {4 * 1024 * 1024, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
1086 std::vector<SingleVerKvEntry *> entries;
1087 ContinueToken token = nullptr;
1088
1089 QueryObject queryObj(query);
1090 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj, SyncTimeRange{}, specInfo, token, entries), E_OK);
1091 ReleaseKvEntries(entries);
1092
1093 QueryObject queryObj1(query1);
1094 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj1, SyncTimeRange{}, specInfo, token, entries), E_OK);
1095 EXPECT_EQ(entries.size(), 1UL);
1096 ReleaseKvEntries(entries);
1097
1098 QueryObject queryObj2(query2);
1099 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj2, SyncTimeRange{}, specInfo, token, entries), E_OK);
1100 ReleaseKvEntries(entries);
1101
1102 QueryObject queryObj3(query3);
1103 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj3, SyncTimeRange{}, specInfo, token, entries), E_OK);
1104 ReleaseKvEntries(entries);
1105
1106 QueryObject queryObj4(query4);
1107 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj4, SyncTimeRange{}, specInfo, token, entries), E_OK);
1108 ReleaseKvEntries(entries);
1109
1110 QueryObject queryObj5(query5);
1111 EXPECT_EQ(g_schemaStore->GetSyncData(queryObj5, SyncTimeRange{}, specInfo, token, entries), E_OK);
1112 ReleaseKvEntries(entries);
1113 }
1114
1115 /**
1116 * @tc.name: QueryPredicateValidation001
1117 * @tc.desc: check query object is query only by key and has orderBy or not
1118 * @tc.type: FUNC
1119 * @tc.require: AR000FN6G9
1120 * @tc.author: xulianhui
1121 */
1122 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryPredicateValidation001, TestSize.Level1)
1123 {
1124 /**
1125 * @tc.steps:step1. Create a query object with prefixKey only, check it's predicate
1126 * @tc.expected: step1. check IsQueryOnlyByKey true; check HasOrderBy false
1127 */
1128 Query query1 = Query::Select().PrefixKey({});
1129 QuerySyncObject querySync1(query1);
1130 EXPECT_EQ(querySync1.IsQueryOnlyByKey(), true);
1131 EXPECT_EQ(querySync1.HasOrderBy(), false);
1132
1133 /**
1134 * @tc.steps:step2. Create a query object with prefixKey and equalTo, check it's predicate
1135 * @tc.expected: step2. check IsQueryOnlyByKey false; check HasOrderBy false
1136 */
1137 Query query2 = Query::Select().PrefixKey({}).EqualTo("$.testField", 0);
1138 QuerySyncObject querySync2(query2);
1139 EXPECT_EQ(querySync2.IsQueryOnlyByKey(), false);
1140 EXPECT_EQ(querySync2.HasOrderBy(), false);
1141
1142 /**
1143 * @tc.steps:step3. Create a query object with orderBy only, check it's predicate
1144 * @tc.expected: step3. check IsQueryOnlyByKey false; check HasOrderBy true
1145 */
1146 Query query3 = Query::Select().OrderBy("$.testField");
1147 QuerySyncObject querySync3(query3);
1148 EXPECT_EQ(querySync3.IsQueryOnlyByKey(), false);
1149 EXPECT_EQ(querySync3.HasOrderBy(), true);
1150 }
1151
1152 /**
1153 * @tc.name: RelationalQuerySyncTest001
1154 * @tc.desc: Test querySyncObject serialize with table name is specified
1155 * @tc.type: FUNC
1156 * @tc.require:
1157 * @tc.author: xulianhui
1158 */
1159 HWTEST_F(DistributedDBStorageQuerySyncTest, RelationalQuerySyncTest001, TestSize.Level1)
1160 {
1161 /**
1162 * @tc.steps:step1. Create a query object with table name is specified
1163 * @tc.expected: ok
1164 */
1165 Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1166 QuerySyncObject obj1(query1);
1167
1168 /**
1169 * @tc.steps:step2. Serialize the object
1170 * @tc.expected: ok
1171 */
1172 uint32_t buffLen = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1173 vector<uint8_t> buffer(buffLen, 0);
1174 Parcel writeParcel(buffer.data(), buffLen);
1175 EXPECT_EQ(obj1.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1176
1177 /**
1178 * @tc.steps:step3. DeSerialize the data
1179 * @tc.expected: ok, And the queryId is same
1180 */
1181 Parcel readParcel(buffer.data(), buffLen);
1182 QuerySyncObject queryObj2;
1183 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), E_OK);
1184 EXPECT_EQ(obj1.GetIdentify(), queryObj2.GetIdentify());
1185 }
1186
1187 /**
1188 * @tc.name: RelationalQuerySyncTest002
1189 * @tc.desc: Test querySyncObject with different table name has different identity
1190 * @tc.type: FUNC
1191 * @tc.require:
1192 * @tc.author: xulianhui
1193 */
1194 HWTEST_F(DistributedDBStorageQuerySyncTest, RelationalQuerySyncTest002, TestSize.Level1)
1195 {
1196 Query query1 = Query::Select("Relational_table1").EqualTo("field1", "abc");
1197 QuerySyncObject obj1(query1);
1198
1199 Query query2 = Query::Select("Relational_table2").EqualTo("field1", "abc");
1200 QuerySyncObject obj2(query2);
1201
1202 /**
1203 * @tc.steps:step1. check object identity
1204 * @tc.expected: identity should be different.
1205 */
1206 EXPECT_NE(obj1.GetIdentify(), obj2.GetIdentify());
1207 }
1208
1209 /**
1210 * @tc.name: SerializeAndDeserializeForVer1
1211 * @tc.desc: Test querySyncObject serialization and deserialization.
1212 * @tc.type: FUNC
1213 * @tc.require: AR000GOHO7
1214 * @tc.author: lidongwei
1215 */
1216 HWTEST_F(DistributedDBStorageQuerySyncTest, SerializeAndDeserializeForVer1, TestSize.Level1)
1217 {
1218 Query qeury1 = Query::Select("table1").EqualTo("field1", "abc").InKeys({KEY_1, KEY_2, KEY_3});
1219 QuerySyncObject obj1(qeury1);
1220
1221 /**
1222 * @tc.steps:step1. Serialize obj1.
1223 * @tc.expected: Serialize successfully.
1224 */
1225 auto len = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1226 std::vector<uint8_t> buffer(len);
1227 Parcel parcel1(buffer.data(), buffer.size());
1228 obj1.SerializeData(parcel1, SOFTWARE_VERSION_CURRENT);
1229 ASSERT_EQ(parcel1.IsError(), false);
1230
1231 /**
1232 * @tc.steps:step2. Deserialize obj1.
1233 * @tc.expected: Deserialize successfully.
1234 */
1235 QuerySyncObject obj2;
1236 Parcel parcel2(buffer.data(), buffer.size());
1237 ASSERT_EQ(parcel2.IsError(), false);
1238
1239 /**
1240 * @tc.steps:step3. check object identity
1241 * @tc.expected: identity should be the same.
1242 */
1243 EXPECT_NE(obj1.GetIdentify(), obj2.GetIdentify());
1244 }
1245
1246 /**
1247 * @tc.name: MultiInkeys1
1248 * @tc.desc: Test the rc when multiple inkeys exists.
1249 * @tc.type: FUNC
1250 * @tc.require: AR000GOHO7
1251 * @tc.author: lidongwei
1252 */
1253 HWTEST_F(DistributedDBStorageQuerySyncTest, MultiInkeys1, TestSize.Level1)
1254 {
1255 /**
1256 * @tc.steps:step1. Create an invalid query, with multiple inkeys.
1257 */
1258 Query query = Query::Select().InKeys({KEY_1, KEY_2}).InKeys({KEY_3});
1259
1260 /**
1261 * @tc.steps:step2. Get data.
1262 * @tc.expected: Return INVALID_QUERY_FORMAT.
1263 */
1264 std::vector<Entry> entries;
1265 IOption option;
1266 option.dataType = IOption::SYNC_DATA;
1267 EXPECT_EQ(g_schemaConnect->GetEntries(option, query, entries), -E_INVALID_QUERY_FORMAT);
1268 }
1269
1270 /**
1271 * @tc.name: QueryObject001
1272 * @tc.desc: Parse query object when node is empty
1273 * @tc.type: FUNC
1274 * @tc.require:
1275 * @tc.author: bty
1276 */
1277 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject001, TestSize.Level1)
1278 {
1279 std::list<QueryObjNode> nodes;
1280 QueryObjNode node;
1281 nodes.push_back(node);
1282 std::vector<uint8_t> key;
1283 std::set<Key> keys;
1284 QueryObject queryObj(nodes, key, keys);
1285 EXPECT_EQ(queryObj.ParseQueryObjNodes(), -E_INVALID_QUERY_FORMAT);
1286 }
1287
1288 /**
1289 * @tc.name: QueryObject002
1290 * @tc.desc: Serialize query sync object when node is empty
1291 * @tc.type: FUNC
1292 * @tc.require:
1293 * @tc.author: bty
1294 */
1295 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject002, TestSize.Level1)
1296 {
1297 /**
1298 * @tc.steps:step1. Create a query object and parcel
1299 * @tc.expected: ok
1300 */
1301 std::list<QueryObjNode> nodes;
1302 QueryObjNode node;
1303 nodes.push_back(node);
1304 std::vector<uint8_t> key;
1305 std::set<Key> keys;
1306 QuerySyncObject querySyncObj1(nodes, key, keys);
1307 uint32_t len = 120; // 120 is the number of serialized prefixes
1308 std::vector<uint8_t> buff(len, 0);
1309 Parcel parcel(buff.data(), len);
1310
1311 /**
1312 * @tc.steps:step2. Serialize data when node is empty
1313 * @tc.expected: -E_INVALID_QUERY_FORMAT
1314 */
1315 EXPECT_EQ(querySyncObj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT - 1), (uint32_t) 0);
1316 EXPECT_EQ(querySyncObj1.SerializeData(parcel, 0), -E_INVALID_QUERY_FORMAT);
1317
1318 /**
1319 * @tc.steps:step2. Serialize data when parcel len is zero
1320 * @tc.expected: -E_INVALID_ARGS
1321 */
1322 Query query = Query::Select("Relational_table");
1323 QuerySyncObject querySyncObj2(query);
1324 Parcel parcel1(buff.data(), 0);
1325 EXPECT_EQ(querySyncObj2.SerializeData(parcel1, 0), -E_INVALID_ARGS);
1326 }
1327
1328 /**
1329 * @tc.name: QueryObject003
1330 * @tc.desc: Test DeSerializeData under error Parcel buffer
1331 * @tc.type: FUNC
1332 * @tc.require:
1333 * @tc.author: bty
1334 */
1335 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject003, TestSize.Level1)
1336 {
1337 /**
1338 * @tc.steps:step1. Create a query object with table name is specified
1339 * @tc.expected: ok
1340 */
1341 Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1342 QuerySyncObject obj1(query1);
1343
1344 /**
1345 * @tc.steps:step2. Serialize the object
1346 * @tc.expected: ok
1347 */
1348 uint32_t buffLen = obj1.CalculateParcelLen(SOFTWARE_VERSION_CURRENT);
1349 vector<uint8_t> buffer(buffLen, 0);
1350 Parcel writeParcel(buffer.data(), buffLen);
1351 EXPECT_EQ(obj1.SerializeData(writeParcel, SOFTWARE_VERSION_CURRENT), E_OK);
1352
1353 /**
1354 * @tc.steps:step3. Deserialize data when the version number is abnormal
1355 * @tc.expected: -E_VERSION_NOT_SUPPORT, then correct the version number
1356 */
1357 EXPECT_EQ(buffLen, 120u); // 120 is the max buffer len
1358 uint8_t oldValue = *(buffer.data() + VERSION_BIT);
1359 uint8_t newValue = 2;
1360 ASSERT_EQ(memcpy_s(buffer.data() + VERSION_BIT, sizeof(newValue), &newValue, sizeof(newValue)), 0);
1361 Parcel readParcel(buffer.data(), buffLen);
1362 QuerySyncObject queryObj2;
1363 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel, queryObj2), -E_VERSION_NOT_SUPPORT);
1364 ASSERT_EQ(memcpy_s(buffer.data() + VERSION_BIT, sizeof(oldValue), &oldValue, sizeof(oldValue)), 0);
1365
1366 /**
1367 * @tc.steps:step4. Deserialize data when the key size is abnormal
1368 * @tc.expected: -E_PARSE_FAIL
1369 */
1370 Parcel writeParcel2(buffer.data() + 116, buffLen); // 116 is the starting bit of key
1371 writeParcel2.WriteUInt32(DBConstant::MAX_INKEYS_SIZE + 1);
1372 Parcel readParcel2(buffer.data(), buffLen);
1373 EXPECT_EQ(QuerySyncObject::DeSerializeData(readParcel2, queryObj2), -E_PARSE_FAIL);
1374 }
1375
1376 /**
1377 * @tc.name: QueryObject004
1378 * @tc.desc: Put sync data under error condition
1379 * @tc.type: FUNC
1380 * @tc.require:
1381 * @tc.author: bty
1382 */
1383 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject004, TestSize.Level1)
1384 {
1385 /**
1386 * @tc.steps:step1. Put in error store
1387 * @tc.expected: -E_INVALID_DB
1388 */
1389 Query query1 = Query::Select("Relational_table").EqualTo("field1", "abc");
1390 QuerySyncObject obj1(query1);
1391 std::vector<SingleVerKvEntry *> entry;
1392 std::string deviceName = "";
1393 std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
1394 EXPECT_EQ(errStore->PutSyncDataWithQuery(obj1, entry, deviceName), -E_INVALID_DB);
1395
1396 /**
1397 * @tc.steps:step2. Put in correct store but device name is null
1398 * @tc.expected: -E_NOT_SUPPORT
1399 */
1400 EXPECT_EQ(g_store->PutSyncDataWithQuery(obj1, entry, deviceName), -E_NOT_SUPPORT);
1401
1402 /**
1403 * @tc.steps:step3. Put in correct store but device name is over size
1404 * @tc.expected: -E_INVALID_ARGS
1405 */
1406 vector<uint8_t> buffer(129, 1); // 129 is greater than 128
1407 deviceName.assign(buffer.begin(), buffer.end());
1408 EXPECT_EQ(g_store->PutSyncDataWithQuery(obj1, entry, deviceName), -E_INVALID_ARGS);
1409 }
1410
1411 /**
1412 * @tc.name: QueryObject005
1413 * @tc.desc: Set engine state to cache and then put sync data
1414 * @tc.type: FUNC
1415 * @tc.require:
1416 * @tc.author: bty
1417 */
1418 HWTEST_F(DistributedDBStorageQuerySyncTest, QueryObject005, TestSize.Level1)
1419 {
1420 KvDBProperties property;
1421 property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
1422 property.SetStringProp(KvDBProperties::STORE_ID, "31");
1423 property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, "TestQuerySync");
1424 property.SetBoolProp(KvDBProperties::MEMORY_MODE, false);
1425 property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
1426 property.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, ConflictResolvePolicy::DEVICE_COLLABORATION);
1427 int errCode = E_OK;
1428 SQLiteSingleVerStorageEngine *storageEngine =
1429 static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(property, errCode));
1430 ASSERT_EQ(errCode, E_OK);
1431 ASSERT_NE(storageEngine, nullptr);
1432 storageEngine->SetEngineState(EngineState::CACHEDB);
1433 DataItem data1{KEY1, VALUE1, 0, DataItem::LOCAL_FLAG, REMOTE_DEVICE_ID};
1434 EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(g_store, vector{data1}, REMOTE_DEVICE_ID), -1);
1435 storageEngine->Release();
1436 }