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 #ifndef OMIT_MULTI_VER
16 #include <cstdlib>
17 #include <ctime>
18 #include <gtest/gtest.h>
19 #include <thread>
20 
21 #include "db_common.h"
22 #include "db_errno.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "distributeddb_tools_unit_test.h"
25 #include "sqlite_single_ver_natural_store.h"
26 
27 using namespace testing::ext;
28 using namespace DistributedDB;
29 using namespace DistributedDBUnitTest;
30 using namespace std;
31 
32 namespace {
33     string g_testDir;
34     const bool LOCAL_ONLY = false;
35     const string STORE_ID = STORE_ID_SYNC;
36     const int OBSERVER_SLEEP_TIME = 100;
37 
38     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
39     KvStoreConfig g_config;
40 
41     // define the g_kvDelegateCallback, used to get some information when open a kv store.
42     DBStatus g_kvDelegateStatus = INVALID_ARGS;
43     KvStoreDelegate *g_kvDelegatePtr = nullptr;
44     // the type of g_kvDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
45     auto g_kvDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreDelegateCallback, placeholders::_1,
46         placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvDelegatePtr));
47 
48     // define the g_snapshotDelegateCallback, used to get some information when open a kv snapshot.
49     DBStatus g_snapshotDelegateStatus = INVALID_ARGS;
50     KvStoreSnapshotDelegate *g_snapshotDelegatePtr = nullptr;
51     // the type of g_snapshotDelegateCallback is function<void(DBStatus, KvStoreSnapshotDelegate*)>
52     auto g_snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
53         placeholders::_1, placeholders::_2, std::ref(g_snapshotDelegateStatus), std::ref(g_snapshotDelegatePtr));
54 
55     // define the g_valueCallback, used to query a value object data from the kvdb.
56     DBStatus g_valueStatus = INVALID_ARGS;
57     Value g_value;
58     // the type of g_valueCallback is function<void(DBStatus, Value)>
59     auto g_valueCallback = bind(&DistributedDBToolsUnitTest::ValueCallback,
60         placeholders::_1, placeholders::_2, std::ref(g_valueStatus), std::ref(g_value));
61 
62     // define the g_entryVectorCallback, used to query a vector<Entry> object data from the kvdb.
63     DBStatus g_entryVectorStatus = INVALID_ARGS;
64     unsigned long g_matchSize = 0;
65     std::vector<Entry> g_entriesVector;
66     // the type of g_entryVectorCallback is function<void(DBStatus, vector<Entry>)>
67     auto g_entryVectorCallback = bind(&DistributedDBToolsUnitTest::EntryVectorCallback, placeholders::_1,
68         placeholders::_2, std::ref(g_entryVectorStatus), std::ref(g_matchSize), std::ref(g_entriesVector));
69 
70     const uint32_t MAX_KEY_SIZE = 1024;
71     const uint32_t MAX_VAL_SIZE = 4194304;
72     const uint32_t INVALID_KEY_SIZE = 1025;
73 
74     Entry g_entryA;
75     Entry g_entryB;
76     Entry g_entryC;
77     Entry g_entryD;
78 
GetSnapshotUnitTest()79     void GetSnapshotUnitTest()
80     {
81         g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, g_snapshotDelegateCallback);
82         EXPECT_TRUE(g_snapshotDelegateStatus == OK);
83         ASSERT_TRUE(g_snapshotDelegatePtr != nullptr);
84     }
85 }
86 
87 class DistributedDBInterfacesDataOperationSyncDBTest : public testing::Test {
88 public:
89     static void SetUpTestCase(void);
90     static void TearDownTestCase(void);
91     void SetUp();
92     void TearDown();
93 };
94 
SetUpTestCase(void)95 void DistributedDBInterfacesDataOperationSyncDBTest::SetUpTestCase(void)
96 {
97     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
98     g_config.dataDir = g_testDir;
99     g_mgr.SetKvStoreConfig(g_config);
100 }
101 
TearDownTestCase(void)102 void DistributedDBInterfacesDataOperationSyncDBTest::TearDownTestCase(void)
103 {
104     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
105         LOGE("rm test db files error!");
106     }
107 }
108 
SetUp(void)109 void DistributedDBInterfacesDataOperationSyncDBTest::SetUp(void)
110 {
111     DistributedDBToolsUnitTest::PrintTestCaseInfo();
112     // init values.
113     g_valueStatus = INVALID_ARGS;
114     g_value.clear();
115     g_entryVectorStatus = INVALID_ARGS;
116     g_matchSize = 0;
117 
118     /*
119      * Here, we create STORE_ID.db before test,
120      * and it will be closed in TearDown().
121      */
122     CipherPassword passwd;
123     KvStoreDelegate::Option option = {true, LOCAL_ONLY, false, CipherType::DEFAULT, passwd};
124     g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback);
125     EXPECT_TRUE(g_kvDelegateStatus == OK);
126     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
127 }
128 
TearDown(void)129 void DistributedDBInterfacesDataOperationSyncDBTest::TearDown(void)
130 {
131     if (g_kvDelegatePtr != nullptr && g_snapshotDelegatePtr != nullptr) {
132         EXPECT_TRUE(g_kvDelegatePtr->ReleaseKvStoreSnapshot(g_snapshotDelegatePtr) == OK);
133         g_snapshotDelegatePtr = nullptr;
134     }
135 
136     if (g_kvDelegatePtr != nullptr) {
137         EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
138         g_kvDelegatePtr = nullptr;
139     }
140 
141     EXPECT_EQ(g_mgr.DeleteKvStore(STORE_ID), OK);
142 }
143 
144 /**
145   * @tc.name: Put001
146   * @tc.desc: Put a data(non-empty key, non-empty value) into an exist distributed db
147   * @tc.type: FUNC
148   * @tc.require: AR000CQDTM AR000CQS3R
149   * @tc.author: huangnaigu
150   */
151 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Put001, TestSize.Level1)
152 {
153     /**
154      * @tc.steps: step1. Put the data(non-empty key and non-empty value) into the database.
155      * @tc.expected: step1. Put returns OK.
156      */
157     Key keyTmp;
158     keyTmp.push_back(1);
159     Value valueTmp;
160     valueTmp.push_back('7');
161     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTmp) == OK);
162     /**
163      * @tc.steps: step2. Get the value according the key through the snapshot.
164      * @tc.expected: step2. Get returns OK.
165      */
166     GetSnapshotUnitTest();
167     g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
168     EXPECT_TRUE(g_valueStatus == OK);
169 }
170 
171 /**
172   * @tc.name: Put002
173   * @tc.desc: Put a data(empty key) into an exist distributed db
174   * @tc.type: FUNC
175   * @tc.require: AR000C6TRV AR000CQDTM
176   * @tc.author: huangnaigu
177   */
178 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Put002, TestSize.Level1)
179 {
180     /**
181      * @tc.steps: step1. Put the data(empty key) into the database.
182      * @tc.expected: step1. Put returns INVALID_ARGS.
183      */
184     Key keyTmp;
185     Value valueTmp;
186     valueTmp.push_back('7');
187     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTmp) == INVALID_ARGS);
188 }
189 
190 /**
191   * @tc.name: Put003
192   * @tc.desc: Put a data(non-empty key, empty value) into an exist distributed db
193   * @tc.type: FUNC
194   * @tc.require: AR000C6TRV AR000CQDTM
195   * @tc.author: huangnaigu
196   */
197 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Put003, TestSize.Level1)
198 {
199     /**
200      * @tc.steps: step1. Put the data(empty value) into the database.
201      * @tc.expected: step1. Put returns OK.
202      */
203     Key keyTmp;
204     keyTmp.push_back(1);
205     Value valueTmp;
206 
207     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTmp) == OK);
208 }
209 
210 /**
211   * @tc.name: Put004
212   * @tc.desc: Put data into the multiversion database
213   * @tc.type: FUNC
214   * @tc.require: AR000C6TRV AR000CQDTM
215   * @tc.author: huangnaigu
216   */
217 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Put004, TestSize.Level1)
218 {
219     /**
220      * @tc.steps: step1. clear the database.
221      */
222     EXPECT_TRUE(g_kvDelegatePtr->Clear() == OK);
223 
224     Key keyTmp;
225     keyTmp.push_back(1);
226 
227     Value valueTmp;
228     valueTmp.push_back('7');
229 
230     /**
231      * @tc.steps: step2. Put one data into the database.
232      * @tc.expected: step2. Put returns OK.
233      */
234     Value valueTest;
235     valueTest.push_back('9');
236     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTmp) == OK);
237 
238     /**
239      * @tc.steps: step3. Get the data from the database.
240      * @tc.expected: step3. Get returns OK and the read value is equal to the value put before.
241      */
242     GetSnapshotUnitTest();
243     g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
244     EXPECT_TRUE(g_valueStatus == OK);
245     EXPECT_TRUE(g_value.size() > 0);
246     if (g_value.size() > 0) {
247         EXPECT_TRUE(g_value.front() == '7');
248     }
249 
250     /**
251      * @tc.steps: step4. Change the value, and Put the data into the database.
252      * @tc.expected: step4. Put returns OK.
253      */
254     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTest) == OK);
255 
256     if (g_kvDelegatePtr != nullptr && g_snapshotDelegatePtr != nullptr) {
257         EXPECT_TRUE(g_kvDelegatePtr->ReleaseKvStoreSnapshot(g_snapshotDelegatePtr) == OK);
258         g_snapshotDelegatePtr = nullptr;
259     }
260     GetSnapshotUnitTest();
261     /**
262      * @tc.steps: step5. Get the data from the database.
263      * @tc.expected: step5. Get returns OK and the read value is equal to the new put value.
264      */
265     g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
266     EXPECT_TRUE(g_valueStatus == OK);
267     EXPECT_TRUE(g_value.size() > 0);
268     if (g_value.size() > 0) {
269         EXPECT_TRUE(g_value.front() == '9');
270     }
271 }
272 
273 /**
274   * @tc.name: Clear001
275   * @tc.desc: Clear the data from an exist distributed db
276   * @tc.type: FUNC
277   * @tc.require: AR000CQDTM AR000CQS3R
278   * @tc.author: huangnaigu
279   */
280 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Clear001, TestSize.Level1)
281 {
282     /**
283      * @tc.steps: step1. Put the valid data into the database.
284      */
285     Key keyTmp;
286     DistributedDBToolsUnitTest::GetRandomKeyValue(keyTmp);
287     Value valueTmp;
288     DistributedDBToolsUnitTest::GetRandomKeyValue(valueTmp);
289     EXPECT_TRUE(g_kvDelegatePtr->Put(keyTmp, valueTmp) == OK);
290     /**
291      * @tc.steps: step2. Clear the database.
292      * @tc.expected: step2. Clear returns OK.
293      */
294     EXPECT_TRUE(g_kvDelegatePtr->Clear() == OK);
295     /**
296      * @tc.steps: step3. Get the data from the database according the inserted key before clear.
297      * @tc.expected: step3. Get returns NOT_FOUND.
298      */
299     Key key;
300     GetSnapshotUnitTest();
301     g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
302     EXPECT_EQ(g_valueStatus, NOT_FOUND);
303 }
304 
305 /**
306   * @tc.name: PutBatch001
307   * @tc.desc: Putbatch data into the multiversion database
308   * @tc.type: FUNC
309   * @tc.require: AR000CQDTM AR000CQS3R
310   * @tc.author: huangnaigu
311   */
312 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, PutBatch001, TestSize.Level1)
313 {
314     /**
315      * @tc.steps: step1. Put the prepared data.
316      */
317     vector<Entry> entries;
318     for (int i = 1; i < 10; i++) {
319         Entry entry;
320         entry.key.push_back(i);
321         entry.value.push_back('8');
322         entries.push_back(entry);
323     }
324     /**
325      * @tc.steps: step2. PutBatch the prepared data.
326      * @tc.expected: step2. PutBatch returns OK.
327      */
328     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
329 
330     /**
331      * @tc.steps: step3. Get the data from the database.
332      * @tc.expected: step3. Get returns OK and the get value is equal to the inserted value before.
333      */
334     GetSnapshotUnitTest();
335     for (int i = 1; i < 10; i++) {
336         Key keyTmp;
337         keyTmp.push_back(i);
338 
339         g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
340         EXPECT_TRUE(g_valueStatus == OK);
341         EXPECT_TRUE(g_value.size() > 0);
342         if (g_value.size() > 0) {
343             EXPECT_TRUE(g_value.front() == '8');
344         }
345     }
346 }
347 
348 /**
349   * @tc.name: PutBatch002
350   * @tc.desc: PutBatch modified data into the multiversion database
351   * @tc.type: FUNC
352   * @tc.require: AR000C6TRV AR000CQDTM
353   * @tc.author: huangnaigu
354   */
355 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, PutBatch002, TestSize.Level1)
356 {
357     /**
358      * @tc.steps: step1. prepare the batch data.
359      */
360     vector<Entry> entries;
361     for (int i = 1; i < 10; i++) {
362         Entry entry;
363         entry.key.push_back(i);
364         entry.value.push_back('2');
365         entries.push_back(entry);
366     }
367     /**
368      * @tc.steps: step2. PutBatch the prepared batch data.
369      * @tc.expected: step2. PutBatch returns OK.
370      */
371     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
372     /**
373      * @tc.steps: step3. Get data from the database according the inserted keys.
374      * @tc.expected: step3. Get returns OK and the read value is equal to the inserted value.
375      */
376     GetSnapshotUnitTest();
377     for (int i = 1; i < 10; i++) {
378         Key keyTmp;
379         keyTmp.push_back(i);
380 
381         g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
382         EXPECT_TRUE(g_valueStatus == OK);
383         EXPECT_TRUE(g_value.size() > 0);
384         if (g_value.size() > 0) {
385             EXPECT_TRUE(g_value.front() == '2');
386         }
387     }
388 }
389 
390 /**
391   * @tc.name: Delete001
392   * @tc.desc: Delete existed data from the multiversion database
393   * @tc.type: FUNC
394   * @tc.require: AR000C6TRV AR000CQDTM
395   * @tc.author: huangnaigu
396   */
397 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Delete001, TestSize.Level1)
398 {
399     /**
400      * @tc.steps: step1. Put the prepared data.
401      */
402     Key keyTmp;
403     keyTmp.push_back(1);
404     Value valueTmp;
405     valueTmp.push_back(3);
406     EXPECT_EQ(g_kvDelegatePtr->Put(keyTmp, valueTmp), OK);
407     /**
408      * @tc.steps: step2. Delete the existed data from the database.
409      * @tc.expected: step2. Delete returns OK.
410      */
411     EXPECT_EQ(g_kvDelegatePtr->Delete(keyTmp), OK);
412     /**
413      * @tc.steps: step3. Get the deleted data from the database.
414      * @tc.expected: step3. Get returns NOT_FOUND.
415      */
416     GetSnapshotUnitTest();
417     g_snapshotDelegatePtr->Get(keyTmp, g_valueCallback);
418     EXPECT_TRUE(g_valueStatus == NOT_FOUND);
419 }
420 
421 /**
422   * @tc.name: Delete002
423   * @tc.desc: Delete non-existed data from the multiversion database
424   * @tc.type: FUNC
425   * @tc.require: AR000C6TRV AR000CQDTM
426   * @tc.author: huangnaigu
427   */
428 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, Delete002, TestSize.Level1)
429 {
430     /**
431      * @tc.steps: step1. Clear the database.
432      */
433     EXPECT_TRUE(g_kvDelegatePtr->Clear() == OK);
434 
435     /**
436      * @tc.steps: step2. Delete the non-existed data from the database.
437      * @tc.expected: step2. Delete returns OK.
438      */
439     Key keyTmp;
440     keyTmp.push_back(1);
441     EXPECT_EQ(g_kvDelegatePtr->Delete(keyTmp), OK);
442 }
443 
444 /**
445   * @tc.name: DeleteBatch001
446   * @tc.desc: Delete the existed batch data from the multiversion database
447   * @tc.type: FUNC
448   * @tc.require: AR000C6TRV AR000CQDTM
449   * @tc.author: huangnaigu
450   */
451 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, DeleteBatch001, TestSize.Level1)
452 {
453     /**
454      * @tc.steps: step1. Put the batch data into the database.
455      */
456     vector<Entry> entries;
457     for (int i = 1; i < 4; i++) {
458         Entry entry;
459         entry.key.push_back(i);
460         entry.value.push_back('2');
461         entries.push_back(entry);
462     }
463     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
464 
465     /**
466      * @tc.steps: step2. Delete the batch data from the database.
467      * @tc.steps: step2. DeleteBatch returns OK.
468      */
469     vector<Key> keys;
470     for (int i = 1; i < 4; i++) {
471         Key key;
472         key.push_back(i);
473         keys.push_back(key);
474     }
475     EXPECT_TRUE(g_kvDelegatePtr->DeleteBatch(keys) == OK);
476 
477     /**
478      * @tc.steps: step3. Get all the data from the database.
479      * @tc.steps: step3. GetEntries result NOT_FOUND.
480      */
481     Key keyTmp;
482     GetSnapshotUnitTest();
483     g_snapshotDelegatePtr->GetEntries(keyTmp, g_entryVectorCallback);
484     EXPECT_EQ(g_entryVectorStatus, NOT_FOUND);
485 }
486 
487 /**
488   * @tc.name: DeleteBatch002
489   * @tc.desc: Delete the non-existed batch data from the multiversion database
490   * @tc.type: FUNC
491   * @tc.require: AR000C6TRV AR000CQDTM
492   * @tc.author: huangnaigu
493   */
494 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, DeleteBatch002, TestSize.Level1)
495 {
496     /**
497      * @tc.steps: step1. clear the database.
498      */
499     EXPECT_TRUE(g_kvDelegatePtr->Clear() == OK);
500     /**
501      * @tc.steps: step2. Delete the batch non-existed data from the database.
502      * @tc.expected: step2. DeleteBatch returns OK
503      */
504     vector<Key> keys;
505     for (int i = 1; i < 10; i++) {
506         Key key;
507         key.push_back(i);
508         keys.push_back(key);
509     }
510     EXPECT_TRUE(g_kvDelegatePtr->DeleteBatch(keys) == OK);
511 }
512 
513 /**
514   * @tc.name: GetEntries001
515   * @tc.desc: Get the batch data from the non-empty database by the prefix key.
516   * @tc.type: FUNC
517   * @tc.require: AR000C6TRV AR000CQDTM
518   * @tc.author: huangnaigu
519   */
520 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetEntries001, TestSize.Level1)
521 {
522     /**
523      * @tc.steps: step1. insert batch data into the database.
524      */
525     vector<Entry> entries;
526     for (int i = 1; i <= 10; i++) {
527         Entry entry;
528         for (int j = 1; j <= i; j++) {
529             entry.key.push_back(j);
530         }
531         entry.value.push_back(i);
532         entries.push_back(entry);
533     }
534 
535     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
536 
537     Key keyPrefix;
538     for (int j = 1; j <= 5; j++) {
539         keyPrefix.push_back(j);
540     }
541     /**
542      * @tc.steps: step2. Get batch data from the database using the prefix key.
543      * @tc.expected: step2. GetEntries results OK and the result entries size is the match size.
544      */
545     unsigned long matchSize = 6;
546     GetSnapshotUnitTest();
547     g_snapshotDelegatePtr->GetEntries(keyPrefix, g_entryVectorCallback);
548     ASSERT_TRUE(g_matchSize == matchSize);
549     EXPECT_TRUE(g_entryVectorStatus == OK);
550 }
551 
552 /**
553   * @tc.name: GetEntries002
554   * @tc.desc: Get all the data(empty prefixkey) from the empty database.
555   * @tc.type: FUNC
556   * @tc.require: AR000C6TRV AR000CQDTM
557   * @tc.author: huangnaigu
558   */
559 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetEntries002, TestSize.Level1)
560 {
561     /**
562      * @tc.steps: step1. Get all the data from the empty database.
563      * @tc.expected: step1. GetEntries results NOT_FOUND.
564      */
565     Key keyPrefix;
566     for (int j = 1; j <= 5; j++) {
567         keyPrefix.push_back('a');
568     }
569 
570     unsigned long matchSize = 0;
571     GetSnapshotUnitTest();
572     g_snapshotDelegatePtr->GetEntries(keyPrefix, g_entryVectorCallback);
573     ASSERT_TRUE(g_matchSize == matchSize);
574     EXPECT_TRUE(g_entryVectorStatus == NOT_FOUND);
575 }
576 
577 /**
578   * @tc.name: GetEntries003
579   * @tc.desc: Get all the data(empty prefixkey) from the database.
580   * @tc.type: FUNC
581   * @tc.require: AR000C6TRV AR000CQDTM
582   * @tc.author: huangnaigu
583   */
584 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetEntries003, TestSize.Level1)
585 {
586     /**
587      * @tc.steps: step1. Put batch data into the database.
588      */
589     vector<Entry> entries;
590     const unsigned long entriesSize = 10;
591     for (unsigned long i = 1; i <= entriesSize; i++) {
592         Entry entry;
593         for (unsigned long j = 1; j <= i; j++) {
594             entry.key.push_back(j);
595         }
596         entry.value.push_back(i);
597         entries.push_back(entry);
598     }
599 
600     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
601 
602     /**
603      * @tc.steps: step2. Get all the data from the database using the empty prefix key.
604      * @tc.expected: step2. GetEntries results OK and the entries size is the put batch data size.
605      */
606     Key keyPrefix;
607     GetSnapshotUnitTest();
608     g_snapshotDelegatePtr->GetEntries(keyPrefix, g_entryVectorCallback);
609     ASSERT_EQ(g_matchSize, entriesSize);
610     EXPECT_TRUE(g_entryVectorStatus == OK);
611 }
612 
TestSnapshotCreateAndRelease()613 static void TestSnapshotCreateAndRelease()
614 {
615     DBStatus status;
616     KvStoreSnapshotDelegate *snapshot = nullptr;
617     KvStoreObserver *observer = nullptr;
618     auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
619         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshot));
620 
621     /**
622      * @tc.steps: step1. Obtain the snapshot object snapshot through
623      *  the GetKvStoreSnapshot interface of the delegate.
624      * @tc.expected: step1. Returns a non-empty snapshot.
625      */
626     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallback);
627 
628     EXPECT_TRUE(status == OK);
629     EXPECT_NE(snapshot, nullptr);
630 
631     /**
632      * @tc.steps: step2. Release the obtained snapshot through
633      *  the ReleaseKvStoreSnapshot interface of the delegate.
634      * @tc.expected: step2. Release successfully.
635      */
636     EXPECT_EQ(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshot), OK);
637 }
638 
639 /**
640   * @tc.name: GetSnapshot001
641   * @tc.desc: Get observer is empty, whether you get the snapshot.
642   * @tc.type: FUNC
643   * @tc.require: AR000BVRNF AR000CQDTI
644   * @tc.author: wangbingquan
645   */
646 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshot001, TestSize.Level1)
647 {
648     /**
649      * @tc.steps: step1.Obtain the snapshot object whose observer is null
650      *  by using the GetKvStoreSnapshot interface of the delegate.
651      * @tc.expected: step1. The obtained snapshot is not empty.
652      */
653     TestSnapshotCreateAndRelease();
654 }
655 
656 /**
657   * @tc.name: GetSnapshot002
658   * @tc.desc: Get observer is not empty, whether you get the snapshot.
659   * @tc.type: FUNC
660   * @tc.require: AR000BVRNF AR000CQDTI
661   * @tc.author: wangbingquan
662   */
663 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshot002, TestSize.Level1)
664 {
665     /**
666      * @tc.steps: step1.Obtain the snapshot object whose observer is null
667      *  by using the GetKvStoreSnapshot interface of the delegate.
668      * @tc.expected: step1. The obtained snapshot is not empty.
669      */
670     DBStatus status;
671     KvStoreSnapshotDelegate *snapshot = nullptr;
672     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
673     ASSERT_NE(observer, nullptr);
674     auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
675         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshot));
676     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallback);
677 
678     EXPECT_TRUE(status == OK);
679     EXPECT_NE(snapshot, nullptr);
680 
681     /**
682      * @tc.steps: step2. Release the snapshot get before.
683      * @tc.expected: step2. ReleaseKvStoreSnapshot returns OK.
684      */
685     EXPECT_EQ(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshot), OK);
686     delete observer;
687     observer = nullptr;
688 }
689 
690 /**
691   * @tc.name: ReleaseSnapshot001
692   * @tc.desc: To test the function of releasing an empty snapshot.
693   * @tc.type: FUNC
694   * @tc.require: AR000BVRNF AR000CQDTI
695   * @tc.author: wangbingquan
696   */
697 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, ReleaseSnapshot001, TestSize.Level1)
698 {
699     /**
700      * @tc.steps: step1.Release the null pointer snapshot through
701      *  the ReleaseKvStoreSnapshot interface of the delegate.
702      * @tc.expected: step1. Return ERROR.
703      */
704     KvStoreSnapshotDelegate *snapshot = nullptr;
705     EXPECT_EQ(g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshot), DB_ERROR);
706 }
707 
708 /**
709   * @tc.name: ReleaseSnapshot002
710   * @tc.desc: Release the obtained snapshot object that is not empty.
711   * @tc.type: FUNC
712   * @tc.require: AR000BVRNF AR000CQDTI
713   * @tc.author: wangbingquan
714   */
715 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, ReleaseSnapshot002, TestSize.Level1)
716 {
717     TestSnapshotCreateAndRelease();
718 }
719 
TestSnapshotEntryPut()720 static void TestSnapshotEntryPut()
721 {
722     KvStoreObserverUnitTest *observer = nullptr;
723     DBStatus status;
724     KvStoreSnapshotDelegate *snapshotA = nullptr;
725     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
726         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
727 
728     /**
729      * @tc.steps: step1.Release the null pointer snapshot through
730      *  the ReleaseKvStoreSnapshot interface of the delegate.
731      * @tc.expected: step1. Return not empty snapshot.
732      */
733     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallbackA);
734     ASSERT_NE(snapshotA, nullptr);
735     Key keyA;
736     Value valueA;
737     Value valueB;
738     DistributedDBToolsUnitTest::GetRandomKeyValue(keyA);
739     DistributedDBToolsUnitTest::GetRandomKeyValue(valueA);
740     DistributedDBToolsUnitTest::GetRandomKeyValue(valueB);
741 
742     /**
743      * @tc.steps: step2. Obtain the keyA data through the Get interface of the snapshotA.
744      * @tc.expected: step2. Return NOT_FOUND.
745      */
746     snapshotA->Get(keyA, g_valueCallback);
747     EXPECT_EQ(g_valueStatus, NOT_FOUND);
748 
749     /**
750      * @tc.steps: step3. Insert the data of keyA and valueA through the Put interface of the delegate.
751      */
752     g_kvDelegatePtr->Put(keyA, valueA);
753     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
754 
755     KvStoreSnapshotDelegate *snapshotB = nullptr;
756     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
757         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
758 
759     /**
760      * @tc.steps: step5. Obtain the snapshot object snapshotB through the GetKvStoreSnapshot
761      *  interface of the delegate. Obtain the keyA data through the Get interface of the snapshotB.
762      * @tc.expected: step5. Return a non-empty snapshot. The value of keyA is valueA..
763      */
764     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallbackB);
765     ASSERT_NE(snapshotA, nullptr);
766 
767     /**
768      * @tc.steps: step4. Obtain the keyA data through the Get interface of the snapshotA.
769      * @tc.expected: step4. Return NOT_FOUND.
770      */
771     snapshotA->Get(keyA, g_valueCallback);
772     EXPECT_EQ(g_valueStatus, NOT_FOUND);
773     ASSERT_NE(snapshotB, nullptr);
774     snapshotB->Get(keyA, g_valueCallback);
775     EXPECT_EQ(g_valueStatus, OK);
776     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, valueA), true);
777 
778     /**
779      * @tc.steps: step6. Insert the data of keyA and valueB through the Put interface of the delegate..
780      */
781     g_kvDelegatePtr->Put(keyA, valueB);
782     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
783     KvStoreSnapshotDelegate *snapshotC = nullptr;
784     auto snapshotDelegateCallbackC = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
785         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotC));
786 
787     /**
788      * @tc.steps: step7. Obtain the snapshotC through the GetKvStoreSnapshot interface
789      *  of the delegate and obtain the data of the keyA through the Get interface.
790      * @tc.expected: step7. Return a non-empty snapshot. The value of keyA is valueB.
791      */
792     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallbackC);
793     ASSERT_NE(snapshotC, nullptr);
794 
795     /**
796      * @tc.steps: step8. Obtain the keyA data through the Get interface of the snapshotB.
797      * @tc.expected: step8. Return OK, and the value of keyA is valueA..
798      */
799     snapshotB->Get(keyA, g_valueCallback);
800     EXPECT_EQ(g_valueStatus, OK);
801     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, valueA), true);
802     snapshotC->Get(keyA, g_valueCallback);
803     EXPECT_EQ(g_valueStatus, OK);
804     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, valueB), true);
805 
806     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
807     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
808     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotC);
809 }
810 
TestSnapshotEntryDelete()811 static void TestSnapshotEntryDelete()
812 {
813     KvStoreObserverUnitTest *observer = nullptr;
814     DBStatus status;
815     Key key;
816     Value value;
817     DistributedDBToolsUnitTest::GetRandomKeyValue(key);
818     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
819 
820     g_kvDelegatePtr->Put(key, value);
821     KvStoreSnapshotDelegate *snapshotA = nullptr;
822     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
823         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
824     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallbackA);
825     ASSERT_NE(snapshotA, nullptr);
826     snapshotA->Get(key, g_valueCallback);
827     EXPECT_EQ(g_valueStatus, OK);
828     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, value), true);
829 
830     /**
831      * @tc.steps: step9. Delete the keyA data through
832      *  the Delete interface of the delegate.
833      */
834     g_kvDelegatePtr->Delete(key);
835     KvStoreSnapshotDelegate *snapshotB = nullptr;
836     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
837         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
838 
839     /**
840      * @tc.steps:step10 Obtain the snapshot object snapshotB through the GetKvStoreSnapshot interface of the delegate.
841      */
842     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallbackB);
843     ASSERT_NE(snapshotB, nullptr);
844 
845     /**
846      * @tc.steps: step11. Obtain the value of keyA through the Get interface of snapshotB.
847      * @tc.expected: step11. Return NOT_FOUND.
848      */
849     snapshotB->Get(key, g_valueCallback);
850     EXPECT_EQ(g_valueStatus, NOT_FOUND);
851 
852     /**
853      * @tc.steps: step12. Obtain the value of keyA through the Get interface of snapshotA.
854      * @tc.expected: step12. Return OK, the value of keyA is valueB.
855      */
856     snapshotA->Get(key, g_valueCallback);
857     EXPECT_EQ(g_valueStatus, OK);
858     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, value), true);
859 
860     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
861     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
862 }
863 
864 /**
865   * @tc.name: get_snapshot_entry_001
866   * @tc.desc: Obtain data from the obtained snapshot object and test the impact of the write
867   *  database on the snapshot obtained after the snapshot is obtained.
868   * @tc.type: FUNC
869   * @tc.require: AR000BVRNH AR000CQDTJ
870   * @tc.author: wangbingquan
871   */
872 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshotEntry001, TestSize.Level1)
873 {
874     TestSnapshotEntryPut();
875     TestSnapshotEntryDelete();
876 }
877 
878 /**
879   * @tc.name: get_snapshot_entry_002
880   * @tc.desc: Read the data of the invalid key from the obtained snapshot object.
881   * @tc.type: FUNC
882   * @tc.require: AR000BVRNH AR000CQDTJ
883   * @tc.author: wangbingquan
884   */
885 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshotEntry002, TestSize.Level1)
886 {
887     Key key;
888     Value value;
889     DistributedDBToolsUnitTest::GetRandomKeyValue(key, MAX_KEY_SIZE); // max key size.
890     DistributedDBToolsUnitTest::GetRandomKeyValue(value, MAX_VAL_SIZE); // max valueSize;
891 
892     /**
893      * @tc.steps: step1.Insert [keyA, valueA] data through the Put interface of the delegate.
894      */
895     g_kvDelegatePtr->Put(key, value);
896     KvStoreSnapshotDelegate *snapshot = nullptr;
897     KvStoreObserverUnitTest *observer = nullptr;
898     DBStatus status;
899     auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
900         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshot));
901 
902     /**
903      * @tc.steps: step2. Obtain the snapshot object snapshotA through
904      *  the GetKvStoreSnapshot interface of the delegate.
905      */
906     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallback);
907 
908     ASSERT_NE(snapshot, nullptr);
909     snapshot->Get(key, g_valueCallback);
910     ASSERT_EQ(g_valueStatus, OK);
911     EXPECT_EQ(DistributedDBToolsUnitTest::IsValueEqual(g_value, value), true);
912 
913     /**
914      * @tc.steps: step3. Obtain the empty key data through the Get interface of the snapshotA.
915      * @tc.expected: step3. Return ERROR.
916      */
917     Key keyEmpty;
918     snapshot->Get(keyEmpty, g_valueCallback);
919     ASSERT_EQ(g_valueStatus, INVALID_ARGS);
920 
921     /**
922      * @tc.steps: step4. Obtain the data whose key size exceeds 1024 through the Get interface of the snapshotA.
923      * @tc.expected: step4. Return ERROR.
924      */
925     Key keyMax;
926     DistributedDBToolsUnitTest::GetRandomKeyValue(keyMax, INVALID_KEY_SIZE); // max add one
927     snapshot->Get(keyMax, g_valueCallback);
928     ASSERT_EQ(g_valueStatus, INVALID_ARGS);
929     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshot);
930 }
931 
SnapshotTestPreEntriesPutInner(KvStoreSnapshotDelegate * snapshotA,KvStoreSnapshotDelegate * & snapshotB)932 static void SnapshotTestPreEntriesPutInner(KvStoreSnapshotDelegate *snapshotA, KvStoreSnapshotDelegate *&snapshotB)
933 {
934     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.key);
935     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.value);
936     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryB.value);
937     g_entryB.key = g_entryA.key;
938 
939     g_entryB.key.push_back(std::rand() % 0xFF); // push back random one.
940     g_entryC = g_entryB;
941     uint8_t tmp = (g_entryC.key[0] == 0xFF) ? 0 : 0xFF;
942     g_entryC.key.insert(g_entryC.key.begin(), tmp);
943 
944     /**
945      * @tc.steps: step2. Obtain the data whose keyPrefix is empty through
946      *  the GetEntries interface of the snapshotA.
947      * @tc.expected: step2. Return NOT_FOUND.
948      */
949     snapshotA->GetEntries(g_entryA.key, g_entryVectorCallback);
950     EXPECT_EQ(g_entryVectorStatus, NOT_FOUND);
951 
952     /**
953      * @tc.steps: step3. Obtain the data whose keyPrefix is empty through
954      *  the GetEntries interface of the snapshotA.
955      * @tc.expected: step3. Return NOT_FOUND.
956      */
957     g_kvDelegatePtr->Put(g_entryA.key, g_entryA.value);
958     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
959     g_kvDelegatePtr->Put(g_entryB.key, g_entryB.value);
960     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
961     g_kvDelegatePtr->Put(g_entryC.key, g_entryC.value);
962     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
963 
964     DBStatus status;
965     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
966         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
967     /**
968      * @tc.steps: step5. Obtain the snapshot object snapshotB
969      *  through the GetKvStoreSnapshot interface of the delegate.
970      *  Obtain the data whose keyPrefix is empty through the GetEntries interface of the snapshotB.
971      * @tc.expected: step5. Return a non-empty snapshot. GetEntries Obtain data [keyA, valueA], [keyB, valueB].
972      */
973     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackB);
974     ASSERT_NE(snapshotB, nullptr);
975 }
976 
SnapshotTestPreEntriesPut()977 static void SnapshotTestPreEntriesPut()
978 {
979     DBStatus status;
980     KvStoreSnapshotDelegate *snapshotA = nullptr;
981     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
982         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
983 
984     /**
985      * @tc.steps: step1. Obtain the snapshot object snapshotA through
986      *  the GetKvStoreSnapshot interface of the delegate.
987      * @tc.expected: step1. Returns a non-empty snapsho.
988      */
989     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackA);
990     ASSERT_NE(snapshotA, nullptr);
991 
992     KvStoreSnapshotDelegate *snapshotB = nullptr;
993     SnapshotTestPreEntriesPutInner(snapshotA, snapshotB);
994 
995     snapshotA->GetEntries(g_entryA.key, g_entryVectorCallback);
996     EXPECT_EQ(g_entryVectorStatus, NOT_FOUND);
997     snapshotB->GetEntries(g_entryA.key, g_entryVectorCallback);
998     EXPECT_EQ(g_matchSize, 2UL);
999 
1000     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1001     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1002 
1003     g_entryD = g_entryA;
1004     g_entryD.value.push_back(std::rand() % 0xFF); // random one byte.
1005 
1006     /**
1007      * @tc.steps: step6. Insert [keyA, valueC] data through the Put interface of the delegate.
1008      */
1009     g_kvDelegatePtr->Put(g_entryD.key, g_entryD.value);
1010     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
1011     KvStoreSnapshotDelegate *snapshotC = nullptr;
1012     auto snapshotDelegateCallbackC = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1013         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotC));
1014 
1015     /**
1016      * @tc.steps: step7. Obtain the snapshot object snapshotC
1017      *  through the GetKvStoreSnapshot interface of the delegate. Obtain the data whose
1018      *  keyPrefix is empty through the GetEntries interface of the snapshotC.
1019      * @tc.expected: step5. Return a non-empty snapshot. GetEntries Obtain data [keyA, valueC], [keyB, valueB].
1020      */
1021     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackC);
1022     ASSERT_NE(snapshotC, nullptr);
1023 
1024     /**
1025      * @tc.steps: step8. Obtain the data whose keyPrefix is empty
1026      *  through the GetEntries interface of the snapshotB.
1027      * @tc.expected: step8. Return OK, GetEntries obtains data [keyA, valueA], [keyB, valueB]..
1028      */
1029     snapshotB->GetEntries(g_entryA.key, g_entryVectorCallback);
1030     EXPECT_EQ(g_entryVectorStatus, OK);
1031     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1032     snapshotC->GetEntries(g_entryA.key, g_entryVectorCallback);
1033     EXPECT_EQ(g_entryVectorStatus, OK);
1034     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryD, g_entriesVector), true);
1035 
1036     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
1037     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
1038     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotC);
1039 }
1040 
SnapshotTestPreEntriesDelete()1041 static void SnapshotTestPreEntriesDelete()
1042 {
1043     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.key);
1044     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.value);
1045     g_entryB.key = g_entryA.key;
1046     g_entryB.key.push_back(std::rand() % 0xFF);
1047     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryB.value);
1048 
1049     g_kvDelegatePtr->Put(g_entryA.key, g_entryA.value);
1050     g_kvDelegatePtr->Put(g_entryB.key, g_entryB.value);
1051 
1052     DBStatus status;
1053     KvStoreSnapshotDelegate *snapshotA = nullptr;
1054     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1055         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
1056     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackA);
1057     ASSERT_NE(snapshotA, nullptr);
1058 
1059     snapshotA->GetEntries(g_entryA.key, g_entryVectorCallback);
1060     EXPECT_EQ(g_entryVectorStatus, OK);
1061     EXPECT_EQ(g_matchSize, 2UL); // entryA and entryB
1062     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1063     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1064 
1065     /**
1066      * @tc.steps: step9. Delete the keyA data through the Delete interface of the delegate.
1067      */
1068     g_kvDelegatePtr->Delete(g_entryA.key);
1069 
1070     KvStoreSnapshotDelegate *snapshotB = nullptr;
1071     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1072         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
1073 
1074     /**
1075      * @tc.steps: step10. Obtain the snapshot object snapshotB
1076      *  through the GetKvStoreSnapshot interface of the delegate.
1077      */
1078     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackB);
1079     ASSERT_NE(snapshotB, nullptr);
1080 
1081     /**
1082      * @tc.steps: step11\12. Obtain the value of keyA through the Get interface of snapshotA\B.
1083      */
1084     snapshotA->GetEntries(g_entryA.key, g_entryVectorCallback);
1085     EXPECT_EQ(g_entryVectorStatus, OK);
1086     EXPECT_EQ(g_matchSize, 2UL);
1087     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1088     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1089 
1090     snapshotB->GetEntries(g_entryA.key, g_entryVectorCallback);
1091     EXPECT_EQ(g_matchSize, 1UL);
1092     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), false);
1093     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1094 
1095     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
1096     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
1097 }
1098 
1099 /**
1100   * @tc.name: GetSnapshotEntries001
1101   * @tc.desc: To test the function of obtaining full data when keyPrefix is set to null.
1102   * @tc.type: FUNC
1103   * @tc.require: AR000BVRNI AR000CQDTK
1104   * @tc.author: wangbingquan
1105   */
1106 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshotEntries001, TestSize.Level1)
1107 {
1108     std::srand(std::time(nullptr));
1109     SnapshotTestPreEntriesPut();
1110     SnapshotTestPreEntriesDelete();
1111 }
1112 
SnapshotTestEmptyPreEntriesPut()1113 static void SnapshotTestEmptyPreEntriesPut()
1114 {
1115     DBStatus status;
1116     Key emptyKey;
1117     KvStoreSnapshotDelegate *snapshotA = nullptr;
1118     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1119         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
1120 
1121     /**
1122      * @tc.steps: step1.Obtain the snapshot object snapshotA
1123      *  through the GetKvStoreSnapshot interface of the delegate.
1124      * @tc.expected: step1. Returns a non-empty snapshot.
1125      */
1126     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackA);
1127     ASSERT_NE(snapshotA, nullptr);
1128 
1129     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.key);
1130     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryA.value);
1131     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryB.key, g_entryA.key.size() + 1); // more one
1132     DistributedDBToolsUnitTest::GetRandomKeyValue(g_entryB.value);
1133 
1134     g_kvDelegatePtr->Put(g_entryA.key, g_entryA.value);
1135     g_kvDelegatePtr->Put(g_entryB.key, g_entryB.value);
1136 
1137     /**
1138      * @tc.steps: step2. Obtain the data whose keyPrefix is AB from the GetEntries interface of the snapshotA.
1139      * @tc.expected: step2. Return NOT_FOUND.
1140      */
1141     snapshotA->GetEntries(emptyKey, g_entryVectorCallback);
1142     EXPECT_EQ(g_entryVectorStatus, NOT_FOUND);
1143 
1144     KvStoreSnapshotDelegate *snapshotB = nullptr;
1145     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1146         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
1147     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackB);
1148     ASSERT_NE(snapshotB, nullptr);
1149     snapshotA->GetEntries(emptyKey, g_entryVectorCallback);
1150     EXPECT_EQ(g_entryVectorStatus, NOT_FOUND);
1151     snapshotB->GetEntries(emptyKey, g_entryVectorCallback);
1152     EXPECT_EQ(g_matchSize, 2UL);
1153 
1154     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1155     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1156 
1157     g_entryC = g_entryA;
1158     g_entryC.value.push_back(std::rand() % 0xFF); // random one byte.
1159 
1160     /**
1161      * @tc.steps: step3.Insert the data of ["AB", valueA], ["AE", valueB], ["ABC", valueC],
1162      *  and ["CAB", valueD] through the Put interface of the delegate.
1163      */
1164     g_kvDelegatePtr->Put(g_entryC.key, g_entryC.value);
1165     KvStoreSnapshotDelegate *snapshotC = nullptr;
1166     auto snapshotDelegateCallbackC = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1167         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotC));
1168     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackC);
1169     ASSERT_NE(snapshotC, nullptr);
1170 
1171     /**
1172      * @tc.steps: step5\6\7\8. Obtain the snapshot object snapshot
1173      *  through the GetKvStoreSnapshot interface of the delegate.
1174      *  Obtain the data whose keyPrefix is "AB" through the GetEntries interface of the snapshot.
1175      * @tc.expected: step5\6\7\8. Get Returns a non-empty snapshot and data.
1176      */
1177     snapshotB->GetEntries(emptyKey, g_entryVectorCallback);
1178     EXPECT_EQ(g_entryVectorStatus, OK);
1179     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryA, g_entriesVector), true);
1180     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1181     snapshotC->GetEntries(emptyKey, g_entryVectorCallback);
1182     EXPECT_EQ(g_entryVectorStatus, OK);
1183     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryB, g_entriesVector), true);
1184     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryC, g_entriesVector), true);
1185 
1186     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
1187     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
1188     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotC);
1189 }
1190 
SnapshotTestEmptyPreEntriesDelete()1191 static void SnapshotTestEmptyPreEntriesDelete()
1192 {
1193     DBStatus status;
1194     Key emptyKey;
1195     KvStoreSnapshotDelegate *snapshotA = nullptr;
1196     auto snapshotDelegateCallbackA = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1197         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotA));
1198     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackA);
1199 
1200     ASSERT_NE(snapshotA, nullptr);
1201 
1202     /**
1203      * @tc.steps: step9. Delete the "AB" data through the Delete interface of the delegate.
1204      */
1205     g_kvDelegatePtr->Delete(g_entryC.key);
1206 
1207     /**
1208      * @tc.steps: step11. Obtain the data whose keyPrefix is "AB" through the GetEntries interface of the snapshot.
1209      * @tc.expected: step11. Return OK.get [ABC,valueC].
1210      */
1211     snapshotA->GetEntries(emptyKey, g_entryVectorCallback);
1212     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryC, g_entriesVector), true);
1213 
1214     KvStoreSnapshotDelegate *snapshotB = nullptr;
1215     auto snapshotDelegateCallbackB = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1216         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshotB));
1217 
1218     /**
1219      * @tc.steps: step10.Obtain the snapshot object snapshot through the GetKvStoreSnapshot interface of the delegate.
1220      */
1221     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, snapshotDelegateCallbackB);
1222     ASSERT_NE(snapshotB, nullptr);
1223 
1224     /**
1225      * @tc.steps: step12. Obtain the data whose keyPrefix is "AB" through the GetEntries interface of the snapshot.
1226      * @tc.expected: step12. Return OK.
1227      */
1228     snapshotB->GetEntries(emptyKey, g_entryVectorCallback);
1229     EXPECT_EQ(g_entryVectorStatus, OK);
1230     EXPECT_EQ(DistributedDBToolsUnitTest::IsEntryExist(g_entryC, g_entriesVector), false);
1231 
1232     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotA);
1233     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshotB);
1234 }
1235 
1236 /**
1237   * @tc.name: GetSnapshotEntries002
1238   * @tc.desc: To test the function of obtaining the prefix data when keyPrefix is set to a non-empty value.
1239   * @tc.type: FUNC
1240   * @tc.require: AR000BVRNI AR000CQDTK
1241   * @tc.author: wangbingquan
1242   */
1243 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshotEntries002, TestSize.Level1)
1244 {
1245     std::srand(std::time(nullptr));
1246     SnapshotTestEmptyPreEntriesPut();
1247     SnapshotTestEmptyPreEntriesDelete();
1248 }
1249 
1250 /**
1251   * @tc.name: GetSnapshotEntries003
1252   * @tc.desc: To test whether data can be obtained when keyPrefix is set to an ultra-long key.
1253   * @tc.type: FUNC
1254   * @tc.require: AR000BVRNI AR000CQDTK
1255   * @tc.author: wangbingquan
1256   */
1257 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, GetSnapshotEntries003, TestSize.Level1)
1258 {
1259     Key key;
1260     Value value;
1261     DistributedDBToolsUnitTest::GetRandomKeyValue(key, MAX_KEY_SIZE); // max key size.
1262     DistributedDBToolsUnitTest::GetRandomKeyValue(value, MAX_VAL_SIZE); // max valueSize;
1263 
1264     g_kvDelegatePtr->Put(key, value);
1265     KvStoreSnapshotDelegate *snapshot = nullptr;
1266     KvStoreObserverUnitTest *observer = nullptr;
1267     DBStatus status;
1268     auto snapshotDelegateCallback = bind(&DistributedDBToolsUnitTest::SnapshotDelegateCallback,
1269         placeholders::_1, placeholders::_2, std::ref(status), std::ref(snapshot));
1270 
1271     /**
1272      * @tc.steps: step1. Obtain the snapshot object snapshot through the GetKvStoreSnapshot interface of the delegate.
1273      * @tc.expected: step1. Returns a non-empty snapshot.
1274      */
1275     g_kvDelegatePtr->GetKvStoreSnapshot(observer, snapshotDelegateCallback);
1276 
1277     ASSERT_NE(snapshot, nullptr);
1278     snapshot->GetEntries(key, g_entryVectorCallback);
1279     ASSERT_EQ(g_entryVectorStatus, OK);
1280     EXPECT_EQ(g_matchSize, 1UL);
1281     Entry entry = {key, value};
1282     DistributedDBToolsUnitTest::IsEntryExist(entry, g_entriesVector);
1283 
1284     /**
1285      * @tc.steps: step2.Obtain the data of the key whose keyPrefix exceeds 1024 bytes
1286      *  through the GetEntries interface of the snapshotA.
1287      * @tc.expected: step2. Return ERROR.
1288      */
1289     Key keyMax;
1290     DistributedDBToolsUnitTest::GetRandomKeyValue(keyMax, INVALID_KEY_SIZE); // max add one
1291     snapshot->GetEntries(keyMax, g_entryVectorCallback);
1292     ASSERT_EQ(g_entryVectorStatus, INVALID_ARGS);
1293     g_kvDelegatePtr->ReleaseKvStoreSnapshot(snapshot);
1294 }
1295 
1296 /**
1297   * @tc.name: TestTransactionException001
1298   * @tc.desc: An exception occurred while the test transaction was executing.
1299   * @tc.type: FUNC
1300   * @tc.require: AR000C0F0F AR000CQDTN or SR000BVRNJ
1301   * @tc.author: sunpeng
1302   */
1303 HWTEST_F(DistributedDBInterfacesDataOperationSyncDBTest, TransactionException001, TestSize.Level1)
1304 {
1305     // pre-set: create a db for test.
1306     vector<Entry> entries, entries1;
1307 
1308     /**
1309       * @tc.steps: step1. Start the transaction, insert the data in bulk, end the transaction,
1310       * insert the data of the data of the key1, the value1, the data of the key2, the value2, the transaction.
1311       */
1312     entries.push_back(ENTRY_1);
1313     entries.push_back(ENTRY_2);
1314 
1315     EXPECT_EQ(g_kvDelegatePtr->StartTransaction(), OK);
1316     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries) == OK);
1317     EXPECT_TRUE(g_kvDelegatePtr->Commit() == OK);
1318 
1319     /**
1320      * @tc.steps: step2. Start the transaction, insert the data in bulk, end the transaction,
1321      * insert the data of the data of the key3, the value3, the data of the key4, the value4, the transaction.
1322      */
1323     entries1.push_back(ENTRY_3);
1324     entries1.push_back(ENTRY_4);
1325 
1326     EXPECT_EQ(g_kvDelegatePtr->StartTransaction(), OK);
1327     EXPECT_TRUE(g_kvDelegatePtr->PutBatch(entries1) == OK);
1328     EXPECT_EQ(g_kvDelegatePtr->Commit(), OK);
1329 
1330     /**
1331      * @tc.steps: step2. Close database and Delegate,
1332      */
1333     EXPECT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
1334     g_kvDelegatePtr = nullptr;
1335 
1336     /**
1337      * @tc.steps: step4. Simulated scenes where the log library is not written to complete (power-down):
1338      * read the commit-log database through the sqlite3 interface, delete the latest head node,
1339      * and set the parent node of the header node as the head node.
1340      */
1341     IKvDBFactory *factory = IKvDBFactory::GetCurrent();
1342     ASSERT_NE(factory, nullptr);
1343     if (factory == nullptr) {
1344         LOGE("failed to get DefaultFactory!");
1345         return;
1346     }
1347     int result = E_OK;
1348     IKvDBCommitStorage *commitStorage = factory->CreateMultiVerCommitStorage(result);
1349     ASSERT_EQ(result, E_OK);
1350     ASSERT_NE(commitStorage, nullptr);
1351 
1352     std::string origIdentifier = USER_ID + "-" + APP_ID + "-" + STORE_ID_SYNC;
1353     std::string hashIdentifier = DBCommon::TransferHashString(origIdentifier);
1354     std::string hexDir = DBCommon::TransferStringToHex(hashIdentifier);
1355     IKvDBCommitStorage::Property property = {g_testDir, hexDir, false};
1356 
1357     ASSERT_EQ(commitStorage->Open(property), E_OK);
1358     int errCode = E_OK;
1359     result = commitStorage->RemoveCommit(commitStorage->GetHeader(errCode));
1360     ASSERT_EQ(result, E_OK);
1361     delete commitStorage;
1362     commitStorage = nullptr;
1363 
1364     /**
1365      * @tc.steps: step5. Get delegate with GetKvStore, create snapshot, get data from key3 and key4.
1366      * @tc.expected: step5. Data on key3 and key4 could not be obtained.
1367      */
1368     CipherPassword passwd;
1369     KvStoreDelegate::Option option = {true, false, false, CipherType::DEFAULT, passwd};
1370     g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback);
1371     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
1372     EXPECT_TRUE(g_kvDelegateStatus == OK);
1373 
1374     g_kvDelegatePtr->GetKvStoreSnapshot(nullptr, g_snapshotDelegateCallback);
1375     EXPECT_TRUE(g_snapshotDelegateStatus == OK);
1376     ASSERT_TRUE(g_snapshotDelegatePtr != nullptr);
1377 
1378     g_snapshotDelegatePtr->Get(KEY_3, g_valueCallback);
1379     EXPECT_EQ(g_valueStatus, NOT_FOUND);
1380 
1381     g_valueStatus = INVALID_ARGS;
1382     g_snapshotDelegatePtr->Get(KEY_4, g_valueCallback);
1383     EXPECT_EQ(g_valueStatus, NOT_FOUND);
1384 }
1385 #endif
1386