• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <gtest/gtest.h>
16 #include <ctime>
17 #include <string>
18 
19 #include "delegate_callback.h"
20 #include "distributeddb_data_generator.h"
21 #include "distributed_test_tools.h"
22 #include "kv_store_delegate.h"
23 #include "kv_store_delegate_manager.h"
24 #include "kv_store_snapshot_callback.h"
25 
26 using namespace std;
27 using namespace testing;
28 #if defined TESTCASES_USING_GTEST_EXT
29 using namespace testing::ext;
30 #endif
31 using namespace DistributedDB;
32 using namespace std::placeholders;
33 using namespace DistributedDBDataGenerator;
34 
35 namespace DistributeddbKvBatchCrud {
36 class DistributeddbKvBatchCrudTest : public testing::Test {
37 public:
38     static void SetUpTestCase(void);
39     static void TearDownTestCase(void);
40     void SetUp();
41     void TearDown();
42 private:
43 };
44 
45 const bool IS_LOCAL = false;
46 KvStoreDelegate *g_kvStoreBatchDelegate = nullptr; // the delegate used in this suit.
47 KvStoreDelegateManager *g_batchManager = nullptr;
SetUpTestCase(void)48 void DistributeddbKvBatchCrudTest::SetUpTestCase(void)
49 {
50     MST_LOG("SetUpTestCase before all cases local[%d].", IS_LOCAL);
51     RemoveDir(DIRECTOR);
52     KvOption option = g_kvOption;
53     option.localOnly = IS_LOCAL;
54     g_kvStoreBatchDelegate = DistributedTestTools::GetDelegateSuccess(g_batchManager,
55         g_kvdbParameter1, option);
56     ASSERT_TRUE(g_batchManager != nullptr && g_kvStoreBatchDelegate != nullptr);
57 }
58 
TearDownTestCase(void)59 void DistributeddbKvBatchCrudTest::TearDownTestCase(void)
60 {
61     MST_LOG("TearDownTestCase after all cases.");
62     EXPECT_EQ(g_batchManager->CloseKvStore(g_kvStoreBatchDelegate), OK);
63     g_kvStoreBatchDelegate = nullptr;
64     DBStatus status = g_batchManager->DeleteKvStore(STORE_ID_1);
65     EXPECT_EQ(status, OK) << "fail to delete exist kvdb";
66     delete g_batchManager;
67     g_batchManager = nullptr;
68     RemoveDir(DIRECTOR);
69 }
70 
SetUp(void)71 void DistributeddbKvBatchCrudTest::SetUp(void)
72 {
73     ASSERT_TRUE(g_kvStoreBatchDelegate != nullptr);
74     UnitTest *test = UnitTest::GetInstance();
75     ASSERT_NE(test, nullptr);
76     const TestInfo *testinfo = test->current_test_info();
77     ASSERT_NE(testinfo, nullptr);
78     string testCaseName = string(testinfo->name());
79     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
80 }
81 
TearDown(void)82 void DistributeddbKvBatchCrudTest::TearDown(void)
83 {
84 }
85 
86 class KvStoreObserverSnapImpl final : public KvStoreObserver {
87 public:
OnChange(const KvStoreChangedData & data)88     void OnChange(const KvStoreChangedData &data)
89     {
90         changed_++;
91         onChangeTime_ = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
92         MST_LOG("comes a change,changed[%ld]!!!", changed_);
93         MST_LOG("GetEntriesInserted().size() = %zu, GetEntriesUpdated() = %zu, GetEntriesDeleted() = %zu",
94             data.GetEntriesInserted().size(), data.GetEntriesUpdated().size(), data.GetEntriesDeleted().size());
95         insertCrudList_.assign(data.GetEntriesInserted().begin(), data.GetEntriesInserted().end());
96         updateCrudList_.assign(data.GetEntriesUpdated().begin(), data.GetEntriesUpdated().end());
97         deleteCrudList_.assign(data.GetEntriesDeleted().begin(), data.GetEntriesDeleted().end());
98     }
99 
KvStoreObserverSnapImpl()100     KvStoreObserverSnapImpl()
101     {
102         insertCrudList_.clear();
103         updateCrudList_.clear();
104         deleteCrudList_.clear();
105         changed_ = 0;
106         onChangeTime_ = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
107     }
108 
~KvStoreObserverSnapImpl()109     ~KvStoreObserverSnapImpl()
110     {
111         changed_ = 0;
112     }
113 
GetChanged()114     long GetChanged()
115     {
116         return changed_;
117     }
118 
GetInsertList()119     const list<Entry> GetInsertList()
120     {
121         return insertCrudList_;
122     }
123 
GetDeleteList()124     const list<Entry> GetDeleteList()
125     {
126         return deleteCrudList_;
127     }
128 
GetUpdateList()129     const list<Entry> GetUpdateList()
130     {
131         return updateCrudList_;
132     }
133 
GetOnChangeTime()134     microClock_type GetOnChangeTime()
135     {
136         return onChangeTime_;
137     }
138 
Clear()139     void Clear()
140     {
141         insertCrudList_.clear();
142         deleteCrudList_.clear();
143         updateCrudList_.clear();
144         changed_ = 0;
145     }
146 
147 private:
148     list<Entry> insertCrudList_ = {};
149     list<Entry> deleteCrudList_ = {};
150     list<Entry> updateCrudList_ = {};
151     long changed_ = 0;
152     microClock_type onChangeTime_
153         = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::steady_clock::now());
154 };
155 
156 /*
157  * @tc.name: SimpleData 001
158  * @tc.desc: Verify that can PutBatch(keys,values) and get.
159  * @tc.type: FUN
160  * @tc.require: SR000BUH3J
161  * @tc.author: luqianfu
162  */
163 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData001, TestSize.Level1)
164 {
165     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
166 
167     vector<Entry> entries1;
168     entries1.push_back(ENTRY_1);
169     entries1.push_back(ENTRY_2);
170     vector<Entry> entries2;
171     entries2.push_back(ENTRY_3);
172 
173     /**
174      * @tc.steps: step1. create kv db and PutBatch (k1,v1)(k2,v2) then get.
175      * @tc.expected: step1. PutBatch successfully and get the value of k1 is v1,get the value of k2 is v2.
176      */
177     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
178     EXPECT_EQ(status, OK);
179     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
180     EXPECT_NE(valueResult.size(), size_t(0));
181     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_1));
182     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
183     EXPECT_NE(valueResult.size(), size_t(0));
184     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_2));
185 
186     /**
187      * @tc.steps: step2. create kv db and PutBatch (k3,v3) then get.
188      * @tc.expected: step2. PutBatch successfully and get the value of k3 is v3.
189      */
190     DBStatus status2 = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries2);
191     EXPECT_EQ(status2, OK);
192     Value valueResult2 = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_3);
193     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult2, VALUE_3));
194 
195     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
196 }
197 
198 /*
199  * @tc.name: SimpleData 002
200  * @tc.desc: Verify that can PutBatch(keys,values) and update them.
201  * @tc.type: FUN
202  * @tc.require: SR000BUH3J
203  * @tc.author: luqianfu
204  */
205 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData002, TestSize.Level1)
206 {
207     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
208 
209     vector<Entry> entries1;
210     entries1.push_back(ENTRY_1);
211     entries1.push_back(ENTRY_2);
212     vector<Entry> entries1Up;
213     entries1Up.push_back(ENTRY_1_2);
214     entries1Up.push_back(ENTRY_2_3);
215 
216     /**
217      * @tc.steps: step1. create kv db and PutBatch (k1,v1)(k2,v2) then get.
218      * @tc.expected: step1. PutBatch successfully and get the value of k1 is v1,get the value of k2 is v2.
219      */
220     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
221     EXPECT_EQ(status, OK);
222 
223     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
224     EXPECT_NE(valueResult.size(), size_t(0));
225     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_1));
226 
227     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
228     EXPECT_NE(valueResult.size(), size_t(0));
229     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_2));
230 
231     /**
232      * @tc.steps: step2. update (k1,v1)(k2,v2) to (k1,v2)(k2,v3).
233      * @tc.expected: step2. update successfully and get the value of k1 is v2,get the value of k2 is v3.
234      */
235     status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1Up);
236     EXPECT_EQ(status, DBStatus::OK);
237 
238     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
239     EXPECT_NE(valueResult.size(), size_t(0));
240     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_2));
241 
242     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
243     EXPECT_NE(valueResult.size(), size_t(0));
244     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_3));
245 
246     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
247 }
248 
249 /*
250  * @tc.name: SimpleData 003
251  * @tc.desc: Verify that can deletebatch list.
252  * @tc.type: FUN
253  * @tc.require: SR000BUH3J
254  * @tc.author: luqianfu
255  */
256 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData003, TestSize.Level1)
257 {
258     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
259     vector<Entry> entries1;
260     entries1.push_back(ENTRY_1);
261     entries1.push_back(ENTRY_2);
262     /**
263      * @tc.steps: step1. create kv db and PutBatch (k1,v1)(k2,v2) then get.
264      * @tc.expected: step1. PutBatch successfully and get the value of k1 is v1,get the value of k2 is v2.
265      */
266     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
267     ASSERT_EQ(status, DBStatus::OK);
268     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
269     EXPECT_NE(valueResult.size(), size_t(0));
270     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_1));
271     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
272     EXPECT_NE(valueResult.size(), size_t(0));
273     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_2));
274 
275     /**
276      * @tc.steps: step2. deleteBatch (k1)(k2) then get.
277      * @tc.expected: step2. deleteBatch successfully and get the value of k1 is null,get the value of k2 is null.
278      */
279     vector<Key> keys1;
280     keys1.push_back(ENTRY_1.key);
281     keys1.push_back(ENTRY_2.key);
282 
283     DBStatus status2 = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1);
284 
285     ASSERT_EQ(status2, DBStatus::OK);
286     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
287     EXPECT_EQ(valueResult.size(), size_t(0));
288     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
289     EXPECT_EQ(valueResult.size(), size_t(0));
290 }
291 
292 /*
293  * @tc.name: SimpleData 004
294  * @tc.desc: Verify that can put batch with some null value.
295  * @tc.type: FUN
296  * @tc.require: SR000BUH3J
297  * @tc.author: luqianfu
298  */
299 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData004, TestSize.Level1)
300 {
301     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
302 
303     vector<Entry> entries1;
304     entries1.push_back(ENTRY_1_NULL); // KEY_1 with null value.
305     entries1.push_back(ENTRY_2);
306 
307     /**
308      * @tc.steps: step1. create kv db and PutBatch (k1,v1)(k2,v2) that v1=null.
309      * @tc.expected: step1. PutBatch successfully.
310      */
311     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
312     ASSERT_TRUE(status == DBStatus::OK);
313 
314     /**
315      * @tc.steps: step2. get k1,k2 from db.
316      * @tc.expected: step2. get the value of k1 is null,get the value of k2 is not null.
317      */
318     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
319     EXPECT_EQ(valueResult.size(), size_t(0));
320     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
321     EXPECT_NE(valueResult.size(), size_t(0));
322 }
323 
324 /*
325  * @tc.name: SimpleData 005
326  * @tc.desc: Verify that can not put batch with some null key.
327  * @tc.type: FUN
328  * @tc.require: SR000BUH3J
329  * @tc.author: luqianfu
330  */
331 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData005, TestSize.Level1)
332 {
333     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
334 
335     vector<Entry> entries1;
336     entries1.push_back(ENTRY_NULL_1); // null key with VALUE_1.
337     entries1.push_back(ENTRY_2);
338 
339     /**
340      * @tc.steps: step1. create kv db and PutBatch (k1,v1)(k2,v2) that k1=null.
341      * @tc.expected: step1. PutBatch failed.
342      */
343     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
344     ASSERT_TRUE(status != DBStatus::OK);
345 
346     /**
347      * @tc.steps: step2. get k1,k2 from db.
348      * @tc.expected: step2. get the value of k1 is null,get the value of k2 is null.
349      */
350     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
351     EXPECT_EQ(valueResult.size(), size_t(0));
352     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
353     EXPECT_EQ(valueResult.size(), size_t(0));
354 }
355 
356 /*
357  * @tc.name: SimpleData 006
358  * @tc.desc: Verify that get batch none exist data will get null.
359  * @tc.type: FUN
360  * @tc.require: SR000BUH3J
361  * @tc.author: luqianfu
362  */
363 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData006, TestSize.Level1)
364 {
365     /**
366      * @tc.steps: step1. clear kv db.
367      * @tc.expected: step1. Construct that none exist data.
368      */
369     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
370 
371     /**
372      * @tc.steps: step2. get batch(k1)(k2).
373      * @tc.expected: step2. get null.
374      */
375     vector<Entry> valueResult = DistributedTestTools::GetEntries(*g_kvStoreBatchDelegate, KEY_SEARCH);
376     ASSERT_TRUE(valueResult.size() == 0);
377 }
378 
379 /*
380  * @tc.name: SimpleData 007
381  * @tc.desc: Verify that delete batch none exist data will return OK.
382  * @tc.type: FUN
383  * @tc.require: SR000BUH3J
384  * @tc.author: luqianfu
385  */
386 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData007, TestSize.Level1)
387 {
388     /**
389      * @tc.steps: step1. clear kv db.
390      * @tc.expected: step1. Construct that none exist data.
391      */
392     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
393 
394     vector<Key> keys1;
395     keys1.push_back(ENTRY_1.key);
396     keys1.push_back(ENTRY_2.key);
397 
398     /**
399      * @tc.steps: step2. delete batch none exist data.
400      * @tc.expected: step2. delete failed but return OK.
401      */
402     DBStatus status = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1);
403     ASSERT_TRUE(status == DBStatus::OK);
404 }
405 
406 /*
407  * @tc.name: SimpleData 008
408  * @tc.desc: Verify that can get entries with prefix-key.
409  * @tc.type: FUN
410  * @tc.require: SR000BUH3J
411  * @tc.author: luqianfu
412  */
413 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData008, TestSize.Level1)
414 {
415     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
416     vector<Entry> entries1;
417     entries1.push_back(ENTRY_A_1);
418     entries1.push_back(ENTRY_A_2);
419     entries1.push_back(ENTRY_A_3);
420     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
421     ASSERT_TRUE(status == DBStatus::OK);
422 
423     /**
424      * @tc.steps: step1. get entries that prefix-key="ab".
425      * @tc.expected: step1. get 3 records which are key="abc","abcdasd","abcds".
426      */
427     vector<Entry> valueResult = DistributedTestTools::GetEntries(*g_kvStoreBatchDelegate, KEY_SEARCH);
428     MST_LOG("value size %zu", valueResult.size());
429     EXPECT_EQ(valueResult.size(), THREE_RECORDS);
430     /**
431      * @tc.steps: step2. get entries that prefix-key="abcde".
432      * @tc.expected: step2. get 0 record.
433      */
434     valueResult = DistributedTestTools::GetEntries(*g_kvStoreBatchDelegate, KEY_SEARCH_2);
435     EXPECT_EQ(valueResult.size(), size_t(0));
436 }
437 
438 /*
439  * @tc.name: SimpleData 009
440  * @tc.desc: Verify that get entries with null key will return all records.
441  * @tc.type: FUN
442  * @tc.require: SR000BUH3J
443  * @tc.author: luqianfu
444  */
445 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData009, TestSize.Level1)
446 {
447     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
448     vector<Entry> entries1;
449     entries1.push_back(ENTRY_A_1);
450     entries1.push_back(ENTRY_A_2);
451     entries1.push_back(ENTRY_A_3);
452     /**
453      * @tc.steps: step1. PutBatch (k1=abc,v1=a1)(k2=abcdasd,v2=a2)(k3=abcds,v3=a3).
454      * @tc.expected: step1. PutBatch successfully to construct exist data.
455      */
456     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
457     ASSERT_TRUE(status == DBStatus::OK);
458 
459     /**
460      * @tc.steps: step2. GetEntries with key=null.
461      * @tc.expected: step2. GetEntries successfully and return all records in db.
462      */
463     vector<Entry> valueResult = DistributedTestTools::GetEntries(*g_kvStoreBatchDelegate, KEY_EMPTY);
464     ASSERT_TRUE(valueResult.size() == entries1.size());
465 }
466 
467 /*
468  * @tc.name: SimpleData 010
469  * @tc.desc: Verify that can release snapshot.
470  * @tc.type: FUN
471  * @tc.require: SR000CQDTF
472  * @tc.author: luqianfu
473  */
474 HWTEST_F(DistributeddbKvBatchCrudTest, SimpleData010, TestSize.Level1)
475 {
476     DelegateCallback delegateCallback;
477     function<void(DBStatus, KvStoreSnapshotDelegate *)> function
478         = bind(&DelegateCallback::Callback, &delegateCallback, _1, _2);
479 
480     g_kvStoreBatchDelegate->GetKvStoreSnapshot(nullptr, function);
481     DBStatus status = delegateCallback.GetStatus();
482     EXPECT_EQ(status, DBStatus::OK);
483     KvStoreSnapshotDelegate *snapshot
484         = const_cast<KvStoreSnapshotDelegate *>(delegateCallback.GetKvStoreSnapshot());
485     EXPECT_NE(snapshot, nullptr);
486     /**
487      * @tc.steps: step1. release snapshot.
488      * @tc.expected: step1. release snapshot successfully.
489      */
490     EXPECT_EQ(g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snapshot), OK);
491 }
492 
PutBatchTwoRecords(vector<Entry> & entries)493 bool PutBatchTwoRecords(vector<Entry> &entries)
494 {
495     bool result = true;
496     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries);
497     result = result && (status == DBStatus::OK);
498     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, entries[0].key);
499     result = result && (valueResult.size() != 0);
500     if (!result) {
501         MST_LOG("value.size() of entries[0].key is 0, and failed");
502     }
503     result = result && (DistributedTestTools::IsValueEquals(valueResult, entries[0].value));
504     if (!result) {
505         MST_LOG("value.size() Got of entries[0].key is not equal to the value entries[0].key Expected");
506     }
507     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, entries[1].key);
508     result = result && (valueResult.size() != 0);
509     if (!result) {
510         MST_LOG("value.size() of entries[1].key is 0, and failed");
511     }
512     result = result && (DistributedTestTools::IsValueEquals(valueResult, entries[1].value));
513     if (!result) {
514         MST_LOG("value.size() Got of entries[1].key is not equal to the value entries[1].key Expected");
515     }
516     return result;
517 }
518 
519 /*
520  * @tc.name: ComplexData 001
521  * @tc.desc: Verify that can batch crud for same keys repeatedly.
522  * @tc.type: FUN
523  * @tc.require: SR000CQDTF
524  * @tc.author: luqianfu
525  */
526 HWTEST_F(DistributeddbKvBatchCrudTest, ComplexData001, TestSize.Level1)
527 {
528     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
529 
530     vector<Entry> entries1;
531     entries1.push_back(ENTRY_1);
532     entries1.push_back(ENTRY_2);
533     vector<Entry> entries12;
534     entries12.push_back(ENTRY_1_2);
535     entries12.push_back(ENTRY_2_3);
536 
537     /**
538      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
539      * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
540      */
541     EXPECT_TRUE(PutBatchTwoRecords(entries1));
542 
543     /**
544      * @tc.steps: step2. DeleteBatch (k1)(k2) and then get.
545      * @tc.expected: step2. DeleteBatch successfully get null of k1,k2.
546      */
547     DBStatus status2 = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, KEYS_1);
548     ASSERT_EQ(status2, DBStatus::OK);
549     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
550     EXPECT_EQ(valueResult.size(), size_t(0));
551     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
552     EXPECT_EQ(valueResult.size(), size_t(0));
553 
554     /**
555      * @tc.steps: step3. PutBatch (k1,v1)(k2,v2) and then get.
556      * @tc.expected: step3. PutBatch successfully get v1,v2 of k1,k2.
557      */
558     EXPECT_TRUE(PutBatchTwoRecords(entries1));
559 
560     /**
561      * @tc.steps: step4. PutBatch (k1,v2)(k2,v3) and then get.
562      * @tc.expected: step4. PutBatch successfully get v2 of k1,v3 of k2.
563      */
564     EXPECT_TRUE(PutBatchTwoRecords(entries12));
565 
566     /**
567      * @tc.steps: step5. DeleteBatch (k1)(k2) and then get.
568      * @tc.expected: step5. DeleteBatch successfully get null of k1,k2.
569      */
570     status2 = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, KEYS_1);
571     EXPECT_EQ(status2, DBStatus::OK);
572     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
573     EXPECT_EQ(valueResult.size(), size_t(0));
574     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
575     EXPECT_EQ(valueResult.size(), size_t(0));
576 }
577 
CheckBatchCrud(vector<Key> keys23)578 void CheckBatchCrud(vector<Key> keys23)
579 {
580     /**
581      * @tc.steps: step3. Put(k1,v3) Put(k2,v4) Put(k3,v3) and then get.
582      * @tc.expected: step3. Put successfully get v3 of k1,v4 of k2,v3 of k3.
583      */
584     DBStatus status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, ENTRY_1_3.key, ENTRY_1_3.value);
585     ASSERT_EQ(status, DBStatus::OK);
586     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, ENTRY_2_4.key, ENTRY_2_4.value);
587     ASSERT_EQ(status, DBStatus::OK);
588     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, ENTRY_3.key, ENTRY_3.value);
589     ASSERT_EQ(status, DBStatus::OK);
590     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
591     EXPECT_NE(valueResult.size(), size_t(0));
592     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_3));
593     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
594     EXPECT_NE(valueResult.size(), size_t(0));
595     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_4));
596     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_3);
597     EXPECT_NE(valueResult.size(), size_t(0));
598     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_3));
599     /**
600      * @tc.steps: step4. DeleteBatch (k2)(k3) and then get.
601      * @tc.expected: step4. DeleteBatch successfully get not null of k1,null of k2,k3.
602      */
603     DBStatus status2 = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys23);
604     ASSERT_TRUE(status2 == DBStatus::OK);
605     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
606     EXPECT_NE(valueResult.size(), size_t(0));
607     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_3));
608     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
609     EXPECT_TRUE(valueResult.size() == size_t(0));
610     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_3);
611     EXPECT_TRUE(valueResult.size() == size_t(0));
612     /**
613      * @tc.steps: step5. clear all and then Put(k1,v1) then get.
614      * @tc.expected: step5. clear and Put successfully, get v1 of k1.
615      */
616     status2 = DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
617     ASSERT_TRUE(status2 == DBStatus::OK);
618     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
619     EXPECT_TRUE(valueResult.size() == size_t(0));
620     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, ENTRY_1.key, ENTRY_1.value);
621     ASSERT_TRUE(status == DBStatus::OK);
622     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
623     EXPECT_TRUE(valueResult.size() != size_t(0));
624     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_1));
625 }
626 
627 /*
628  * @tc.name: ComplexData 002
629  * @tc.desc: Verify that can batch and single crud continuously.
630  * @tc.type: FUN
631  * @tc.require: SR000BUH3J
632  * @tc.author: luqianfu
633  */
634 HWTEST_F(DistributeddbKvBatchCrudTest, ComplexData002, TestSize.Level1)
635 {
636     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
637 
638     vector<Entry> entries1;
639     entries1.push_back(ENTRY_1);
640     entries1.push_back(ENTRY_2);
641     vector<Entry> entries12;
642     entries12.push_back(ENTRY_1_2);
643     entries12.push_back(ENTRY_2_3);
644     vector<Entry> entries23;
645     entries23.push_back(ENTRY_2);
646     entries23.push_back(ENTRY_3);
647     vector<Key> keys23;
648     keys23.push_back(ENTRY_2.key);
649     keys23.push_back(ENTRY_3.key);
650 
651     /**
652      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
653      * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
654      */
655     EXPECT_TRUE(PutBatchTwoRecords(entries1));
656 
657     /**
658      * @tc.steps: step2. delete k1 and then get.
659      * @tc.expected: step2. delete successfully get null of k1,v2 of k2.
660      */
661     DBStatus status2 = DistributedTestTools::Delete(*g_kvStoreBatchDelegate, KEY_1);
662     ASSERT_TRUE(status2 == DBStatus::OK);
663     Value valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_1);
664     EXPECT_TRUE(valueResult.size() == 0);
665     valueResult = DistributedTestTools::Get(*g_kvStoreBatchDelegate, KEY_2);
666     EXPECT_TRUE(valueResult.size() != 0);
667     EXPECT_TRUE(DistributedTestTools::IsValueEquals(valueResult, VALUE_2));
668 
669     CheckBatchCrud(keys23);
670 }
671 
MultiSnapCheck1(vector<Entry> & entries1,vector<Entry> & entries2,DistributedDB::Key & keyPrefix,KvStoreObserverSnapImpl & observer3,KvStoreObserverSnapImpl & observer4)672 vector<Entry> MultiSnapCheck1(vector<Entry> &entries1, vector<Entry> &entries2, DistributedDB::Key &keyPrefix,
673     KvStoreObserverSnapImpl &observer3, KvStoreObserverSnapImpl &observer4)
674 {
675     /**
676      * @tc.steps: step3. Register snap2 then getEntries with keyPrefix="k".
677      * @tc.expected: step3. operate successfully and getEntries are null.
678      */
679     KvStoreObserverSnapImpl observer2;
680     KvStoreSnapshotCallback kvStoreSnapshotCallback2;
681     function<void(DBStatus, const std::vector<Entry>&)> function2
682         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback2, _1, _2);
683     KvStoreSnapshotDelegate *snap2 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer2);
684     EXPECT_NE(snap2, nullptr);
685     snap2->GetEntries(keyPrefix, function2);
686     vector<Entry> resultEntries2 = kvStoreSnapshotCallback2.GetEntries();
687     vector<Entry> resultEmptyEntry;
688     EXPECT_TRUE(CompareEntriesVector(resultEntries2, resultEmptyEntry));
689     /**
690      * @tc.steps: step4. putBatch (k1,v1)(k2,v2) again and Register snap3 then getEntries with keyPrefix="k".
691      * @tc.expected: step4. operate successfully and getEntries are (k1,v1)(k2,v2).
692      */
693     vector<Entry> entriesInDB;
694     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
695     EXPECT_TRUE(status == DBStatus::OK);
696     for (auto eachEntry : entries1) {
697         entriesInDB.push_back(eachEntry);
698     }
699     KvStoreSnapshotCallback kvStoreSnapshotCallback3;
700     function<void(DBStatus, const std::vector<Entry>&)> function3
701         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback3, _1, _2);
702     KvStoreSnapshotDelegate *snap3 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer3);
703     EXPECT_NE(snap3, nullptr);
704     snap3->GetEntries(keyPrefix, function3);
705     vector<Entry> resultEntries3 = kvStoreSnapshotCallback3.GetEntries();
706     EXPECT_TRUE(CompareEntriesVector(resultEntries3, entries1));
707     /**
708      * @tc.steps: step5. putBatch (k1,v2)(k2,v3) again, Register snap4 then getEntries with keyPrefix="k".
709      * @tc.expected: step5. operate successfully and getEntries are (k1,v2)(k2,v3).
710      */
711     status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries2);
712     for (auto eachEntry : entries2) {
713         PutUniqueKey(entriesInDB, eachEntry.key, eachEntry.value);
714     }
715     KvStoreSnapshotCallback kvStoreSnapshotCallback4;
716     function<void(DBStatus, const std::vector<Entry>&)> function4
717         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback4, _1, _2);
718     KvStoreSnapshotDelegate *snap4 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer4);
719     EXPECT_NE(snap4, nullptr);
720     snap4->GetEntries(keyPrefix, function4);
721     vector<Entry> resultEntries4 = kvStoreSnapshotCallback4.GetEntries();
722     EXPECT_TRUE(CompareEntriesVector(resultEntries4, entries2));
723     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap2);
724     EXPECT_TRUE(status == DBStatus::OK);
725     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap3);
726     EXPECT_TRUE(status == DBStatus::OK);
727     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap4);
728     EXPECT_TRUE(status == DBStatus::OK);
729     return entriesInDB;
730 }
731 
SnapWithTransactionCheck(vector<Key> keys1,DistributedDB::Key keyPrefix,KvStoreObserverSnapImpl observer5,vector<Entry> entriesInDB)732 void SnapWithTransactionCheck(vector<Key> keys1, DistributedDB::Key keyPrefix,
733     KvStoreObserverSnapImpl observer5, vector<Entry> entriesInDB)
734 {
735     /**
736      * @tc.steps: step6. StartTransaction then deleteBatch (k1,v2)(k2,v3).
737      * @tc.expected: step6. operate successfully to construct there is no data in db.
738      */
739     KvStoreSnapshotCallback kvStoreSnapshotCallback5;
740     function<void(DBStatus, const std::vector<Entry>&)> function5
741         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback5, _1, _2);
742 
743     DBStatus statusStart = g_kvStoreBatchDelegate->StartTransaction();
744     EXPECT_TRUE(statusStart == DBStatus::OK);
745     DBStatus status = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1);
746     ASSERT_TRUE(status == DBStatus::OK);
747     for (unsigned long idxKey = 0; idxKey < keys1.size(); ++idxKey) {
748         for (unsigned long idxEntry = 0; idxEntry < entriesInDB.size(); ++idxEntry) {
749             if (CompareVector(keys1[idxKey], entriesInDB[idxEntry].key)) {
750                 entriesInDB.erase(entriesInDB.begin() + idxEntry);
751             }
752         }
753     }
754     /**
755      * @tc.steps: step7. put(k1,v1)(k2,v3) alone and commit, Register snap5 to getEntries with prefix-key='k'.
756      * @tc.expected: step7. operate successfully and getEntries are (k1,v1)(k2,v3).
757      */
758     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, KEY_1, VALUE_1);
759     ASSERT_TRUE(status == DBStatus::OK);
760     PutUniqueKey(entriesInDB, KEY_1, VALUE_1);
761     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, KEY_2, VALUE_2);
762     ASSERT_TRUE(status == DBStatus::OK);
763     PutUniqueKey(entriesInDB, KEY_2, VALUE_2);
764     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, KEY_3, VALUE_3);
765     ASSERT_TRUE(status == DBStatus::OK);
766     PutUniqueKey(entriesInDB, KEY_3, VALUE_3);
767     status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, KEY_2, VALUE_3);
768     ASSERT_TRUE(status == DBStatus::OK);
769     PutUniqueKey(entriesInDB, KEY_2, VALUE_3);
770     status = DistributedTestTools::Delete(*g_kvStoreBatchDelegate, KEY_3);
771     ASSERT_TRUE(status == DBStatus::OK);
772     for (unsigned long idx = 0; idx < entriesInDB.size(); ++idx) {
773         if (CompareVector(entriesInDB[idx].key, KEY_3)) {
774             entriesInDB.erase(entriesInDB.begin() + idx);
775         }
776     }
777     DBStatus statusCommit = g_kvStoreBatchDelegate->Commit();
778     EXPECT_TRUE(statusCommit == DBStatus::OK);
779     KvStoreSnapshotDelegate *snap5 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer5);
780     EXPECT_NE(snap5, nullptr);
781     snap5->GetEntries(keyPrefix, function5);
782     vector<Entry> resultEntries5 = kvStoreSnapshotCallback5.GetEntries();
783     EXPECT_TRUE(CompareEntriesVector(resultEntries5, entriesInDB));
784     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap5);
785     ASSERT_TRUE(status == DBStatus::OK);
786 }
787 
788 /*
789  * @tc.name: ComplexSnap 001
790  * @tc.desc: Verify that can read multiple snapshots correctly after crud repeatedly.
791  * @tc.type: FUN
792  * @tc.require: SR000BUH3J
793  * @tc.author: luqianfu
794  */
795 HWTEST_F(DistributeddbKvBatchCrudTest, ComplexSnap001, TestSize.Level1)
796 {
797     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
798     vector<Entry> entries1;
799     entries1.push_back(ENTRY_1);
800     entries1.push_back(ENTRY_2);
801     vector<Entry> entries2;
802     entries2.push_back(ENTRY_1_2);
803     entries2.push_back(ENTRY_2_3);
804     KvStoreObserverSnapImpl observer1;
805     KvStoreObserverSnapImpl observer3;
806     KvStoreObserverSnapImpl observer4;
807     KvStoreObserverSnapImpl observer5;
808     /**
809      * @tc.steps: step1. putBatch (k1,v1)(k2,v2) to db.
810      * @tc.expected: step1. putBatch successfully to construct data in db.
811      */
812     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries1);
813     ASSERT_TRUE(status == DBStatus::OK);
814     KvStoreSnapshotCallback kvStoreSnapshotCallback;
815     function<void(DBStatus, const std::vector<Entry>&)> function1
816         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback, _1, _2);
817     /**
818      * @tc.steps: step2. Register snap1 then getEntries with keyPrefix="k" and then delete.
819      * @tc.expected: step2. operate successfully and getEntries are (k1,v1)(k2,v2).
820      */
821     KvStoreSnapshotDelegate *snap1 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer1);
822     EXPECT_NE(snap1, nullptr);
823     vector<Key> keys1;
824     for (unsigned long time = 0; time < entries1.size(); ++time) {
825         keys1.push_back(entries1.at(time).key);
826     }
827     DistributedDB::Key keyPrefix = { 'k' };
828     snap1->GetEntries(keyPrefix, function1);
829     vector<Entry> resultEntries = kvStoreSnapshotCallback.GetEntries();
830     EXPECT_TRUE(CompareEntriesVector(resultEntries, entries1));
831     status = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1);
832     ASSERT_TRUE(status == DBStatus::OK);
833     vector<Entry> entriesInDB = MultiSnapCheck1(entries1, entries2, keyPrefix, observer3, observer4);
834     SnapWithTransactionCheck(keys1, keyPrefix, observer5, entriesInDB);
835 
836     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap1);
837     ASSERT_TRUE(status == DBStatus::OK);
838     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
839 }
840 
RegisterSnapAgainAndCheck1(KvStoreObserverSnapImpl & observer1,KvStoreSnapshotDelegate * & snap1,vector<Entry> & entries,DistributedDB::Key & keyPrefix)841 void RegisterSnapAgainAndCheck1(KvStoreObserverSnapImpl &observer1, KvStoreSnapshotDelegate *&snap1,
842     vector<Entry> &entries, DistributedDB::Key &keyPrefix)
843 {
844     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries);
845     ASSERT_TRUE(status == DBStatus::OK);
846     /**
847      * @tc.steps: step2. ReleaseKvStoreSnapshot then RegisterSnapObserver snap1 and getEntries with keyPrefix="k".
848      * @tc.expected: step2. operate successfully and getEntries are (k1,v1)(k2,v2).
849      */
850     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap1);
851     ASSERT_TRUE(status == DBStatus::OK);
852     snap1 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer1);
853     EXPECT_NE(snap1, nullptr);
854     KvStoreSnapshotCallback kvStoreSnapshotCallback1;
855     function<void(DBStatus, const std::vector<Entry>&)> function1
856         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback1, _1, _2);
857 
858     snap1->GetEntries(keyPrefix, function1);
859     vector<Entry> resultEntries = kvStoreSnapshotCallback1.GetEntries();
860     EXPECT_TRUE(CompareEntriesVector(resultEntries, entries));
861 }
862 
RegisterSnapAgainAndCheck2(KvStoreObserverSnapImpl & observer2,KvStoreSnapshotDelegate * & snap2,vector<Entry> & entries,DistributedDB::Key & keyPrefix)863 vector<Key> RegisterSnapAgainAndCheck2(KvStoreObserverSnapImpl &observer2, KvStoreSnapshotDelegate *&snap2,
864     vector<Entry> &entries, DistributedDB::Key &keyPrefix)
865 {
866     /**
867      * @tc.steps: step3. deleteBatch and RegisterSnapObserver snap2 then getEntries with keyPrefix="k".
868      * @tc.expected: step3. operate successfully and getEntries are null.
869      */
870     vector<Key> keys1;
871     for (unsigned long time = 0; time < entries.size(); ++time) {
872         keys1.push_back(entries.at(time).key);
873     }
874     DBStatus status = DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1);
875     EXPECT_TRUE(status == DBStatus::OK);
876     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap2);
877     EXPECT_TRUE(status == DBStatus::OK);
878     snap2 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer2);
879     EXPECT_NE(snap2, nullptr);
880     KvStoreSnapshotCallback kvStoreSnapshotCallback2;
881     function<void(DBStatus, const std::vector<Entry>&)> function2
882         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback2, _1, _2);
883     snap2->GetEntries(keyPrefix, function2);
884     vector<Entry> resultEntries2 = kvStoreSnapshotCallback2.GetEntries();
885     vector<Entry> resultEmptyEntry;
886     EXPECT_TRUE(CompareEntriesVector(resultEntries2, resultEmptyEntry));
887     return keys1;
888 }
889 
RegisterSnapAgainAndCheck3(KvStoreObserverSnapImpl & observer3,KvStoreSnapshotDelegate * & snap3,vector<Entry> & entries,DistributedDB::Key & keyPrefix)890 vector<Entry> RegisterSnapAgainAndCheck3(KvStoreObserverSnapImpl &observer3, KvStoreSnapshotDelegate *&snap3,
891     vector<Entry> &entries, DistributedDB::Key &keyPrefix)
892 {
893     /**
894      * @tc.steps: step4. putBatch (k1,v1)(k2,v2) again and RegisterSnapObserver snap3 then getEntries with keyPrefix="k"
895      * @tc.expected: step4. operate successfully and getEntries are (k1,v1)(k2,v2).
896      */
897     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries);
898     EXPECT_TRUE(status == DBStatus::OK);
899     vector<Entry> entriesInDB;
900     for (auto eachEntry : entries) {
901         entriesInDB.push_back(eachEntry);
902     }
903     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap3);
904     EXPECT_TRUE(status == DBStatus::OK);
905     snap3 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer3);
906     EXPECT_NE(snap3, nullptr);
907     KvStoreSnapshotCallback kvStoreSnapshotCallback3;
908     function<void(DBStatus, const std::vector<Entry>&)> function3
909         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback3, _1, _2);
910     snap3->GetEntries(keyPrefix, function3);
911     vector<Entry> resultEntries3 = kvStoreSnapshotCallback3.GetEntries();
912     EXPECT_TRUE(CompareEntriesVector(resultEntries3, entries));
913     return entriesInDB;
914 }
915 
RegisterSnapAgainAndCheck4(KvStoreObserverSnapImpl & observer4,KvStoreSnapshotDelegate * & snap4,vector<Entry> & entries,DistributedDB::Key & keyPrefix,vector<Entry> & entriesInDB)916 void RegisterSnapAgainAndCheck4(KvStoreObserverSnapImpl &observer4, KvStoreSnapshotDelegate *&snap4,
917     vector<Entry> &entries, DistributedDB::Key &keyPrefix, vector<Entry> &entriesInDB)
918 {
919     /**
920      * @tc.steps: step5. putBatch (k1,v2)(k2,v3) again and RegisterSnapObserver snap4 then getEntries with keyPrefix="k"
921      * @tc.expected: step5. operate successfully and getEntries are (k1,v2)(k2,v3).
922      */
923     DBStatus status = DistributedTestTools::PutBatch(*g_kvStoreBatchDelegate, entries);
924     ASSERT_TRUE(status == DBStatus::OK);
925     for (auto eachEntry : entries) {
926         PutUniqueKey(entriesInDB, eachEntry.key, eachEntry.value);
927     }
928     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap4);
929     ASSERT_TRUE(status == DBStatus::OK);
930     snap4 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer4);
931     EXPECT_NE(snap4, nullptr);
932     KvStoreSnapshotCallback kvStoreSnapshotCallback4;
933     function<void(DBStatus, const std::vector<Entry>&)> function4
934         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback4, _1, _2);
935     snap4->GetEntries(keyPrefix, function4);
936     vector<Entry> resultEntries4 = kvStoreSnapshotCallback4.GetEntries();
937     EXPECT_TRUE(CompareEntriesVector(resultEntries4, entries));
938 }
939 
PutAndCheck(DistributedDB::Key KEY_1,DistributedDB::Value VALUE_1,vector<Entry> & entriesInDB)940 void PutAndCheck(DistributedDB::Key KEY_1, DistributedDB::Value VALUE_1, vector<Entry> &entriesInDB)
941 {
942     DBStatus status = DistributedTestTools::Put(*g_kvStoreBatchDelegate, KEY_1, VALUE_1);
943     ASSERT_TRUE(status == DBStatus::OK);
944     PutUniqueKey(entriesInDB, KEY_1, VALUE_1);
945 }
946 
RegisterSnapAgainAndCheck5(KvStoreObserverSnapImpl & observer5,KvStoreSnapshotDelegate * & snap5,vector<Entry> & entries1,DistributedDB::Key & keyPrefix,vector<Entry> & entriesInDB)947 void RegisterSnapAgainAndCheck5(KvStoreObserverSnapImpl &observer5, KvStoreSnapshotDelegate *&snap5,
948     vector<Entry> &entries1, DistributedDB::Key &keyPrefix, vector<Entry> &entriesInDB)
949 {
950     vector<Key> keys1;
951     for (unsigned long time = 0; time < entries1.size(); ++time) {
952         keys1.push_back(entries1.at(time).key);
953     }
954     /**
955      * @tc.steps: step6. StartTransaction then deleteBatch (k1,v2)(k2,v3).
956      * @tc.expected: step6. operate successfully to construct there is no data in db.
957      */
958     ASSERT_TRUE((g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap5)) == OK);
959     snap5 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer5);
960     EXPECT_NE(snap5, nullptr);
961     KvStoreSnapshotCallback kvStoreSnapshotCallback5;
962     function<void(DBStatus, const std::vector<Entry>&)> function5
963         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback5, _1, _2);
964     EXPECT_TRUE((g_kvStoreBatchDelegate->StartTransaction()) == OK);
965     ASSERT_TRUE((DistributedTestTools::DeleteBatch(*g_kvStoreBatchDelegate, keys1)) == OK);
966     for (unsigned long idxKey = 0; idxKey < keys1.size(); ++idxKey) {
967         for (unsigned long idxEntry = 0; idxEntry < entriesInDB.size(); ++idxEntry) {
968             if (CompareVector(keys1[idxKey], entriesInDB[idxEntry].key)) {
969                 entriesInDB.erase(entriesInDB.begin() + idxEntry);
970             }
971         }
972     }
973     /**
974      * @tc.steps: step7. put(k1,v1)(k2,v3) alone and commit, Register snap5 to getEntries with prefix-key='k'.
975      * @tc.expected: step7. operate successfully and getEntries are (k1,v1)(k2,v3).
976      */
977     PutAndCheck(KEY_1, VALUE_1, entriesInDB);
978     PutAndCheck(KEY_2, VALUE_2, entriesInDB);
979     PutAndCheck(KEY_3, VALUE_3, entriesInDB);
980     PutAndCheck(KEY_2, VALUE_3, entriesInDB);
981     ASSERT_TRUE((DistributedTestTools::Delete(*g_kvStoreBatchDelegate, KEY_3)) == OK);
982     for (unsigned long idx = 0; idx < entriesInDB.size(); ++idx) {
983         if (CompareVector(entriesInDB[idx].key, KEY_3)) {
984             entriesInDB.erase(entriesInDB.begin() + idx);
985         }
986     }
987     EXPECT_TRUE((g_kvStoreBatchDelegate->Commit()) == OK);
988     ASSERT_TRUE((g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap5)) == OK);
989     snap5 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer5);
990     EXPECT_NE(snap5, nullptr);
991     snap5->GetEntries(keyPrefix, function5);
992     vector<Entry> resultEntries5 = kvStoreSnapshotCallback5.GetEntries();
993     EXPECT_TRUE(CompareEntriesVector(resultEntries5, entriesInDB));
994 }
995 
RegisterSnapAgainAndCheck6(KvStoreSnapshotDelegate * snap6,KvStoreSnapshotDelegate * snap7,KvStoreSnapshotDelegate * snap8,DistributedDB::Key & keyPrefix)996 void RegisterSnapAgainAndCheck6(KvStoreSnapshotDelegate *snap6, KvStoreSnapshotDelegate *snap7,
997     KvStoreSnapshotDelegate *snap8, DistributedDB::Key &keyPrefix)
998 {
999     /**
1000      * @tc.steps: step8. RegisterSnapObserver snap6,snap7,snap8 to getEntries with prefix-key='k'.
1001      * @tc.expected: step8. getEntries are empty.
1002      */
1003     KvStoreSnapshotCallback kvStoreSnapshotCallback6;
1004     function<void(DBStatus, const std::vector<Entry>&)> function6
1005         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback6, _1, _2);
1006     snap6->GetEntries(keyPrefix, function6);
1007     vector<Entry> resultEntries6 = kvStoreSnapshotCallback6.GetEntries();
1008     vector<Entry> resultEmptyEntry;
1009     EXPECT_TRUE(CompareEntriesVector(resultEntries6, resultEmptyEntry));
1010     KvStoreSnapshotCallback kvStoreSnapshotCallback7;
1011     function<void(DBStatus, const std::vector<Entry>&)> function7
1012         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback7, _1, _2);
1013     snap7->GetEntries(keyPrefix, function7);
1014     vector<Entry> resultEntries7 = kvStoreSnapshotCallback7.GetEntries();
1015     EXPECT_TRUE(CompareEntriesVector(resultEntries7, resultEmptyEntry));
1016     KvStoreSnapshotCallback kvStoreSnapshotCallback8;
1017     function<void(DBStatus, const std::vector<Entry>&)> function8
1018         = bind(&KvStoreSnapshotCallback::Callback, &kvStoreSnapshotCallback8, _1, _2);
1019     snap8->GetEntries(keyPrefix, function8);
1020     vector<Entry> resultEntries8 = kvStoreSnapshotCallback8.GetEntries();
1021     EXPECT_TRUE(CompareEntriesVector(resultEntries8, resultEmptyEntry));
1022 }
1023 
ReleaseSnap(KvStoreSnapshotDelegate * & snap1,KvStoreSnapshotDelegate * & snap2,KvStoreSnapshotDelegate * & snap3,KvStoreSnapshotDelegate * & snap4)1024 void ReleaseSnap(KvStoreSnapshotDelegate *&snap1, KvStoreSnapshotDelegate *&snap2,
1025     KvStoreSnapshotDelegate *&snap3, KvStoreSnapshotDelegate *&snap4)
1026 {
1027     DBStatus status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap1);
1028     ASSERT_TRUE(status == DBStatus::OK);
1029     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap2);
1030     ASSERT_TRUE(status == DBStatus::OK);
1031     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap3);
1032     ASSERT_TRUE(status == DBStatus::OK);
1033     status = g_kvStoreBatchDelegate->ReleaseKvStoreSnapshot(snap4);
1034     ASSERT_TRUE(status == DBStatus::OK);
1035 }
1036 
1037 /*
1038  * @tc.name: ComplexSnap 002
1039  * @tc.desc: Verify that release the registered snapshot, register again successfully.
1040  * @tc.type: FUN
1041  * @tc.require: SR000BUH3J
1042  * @tc.author: luqianfu
1043  */
1044 HWTEST_F(DistributeddbKvBatchCrudTest, ComplexSnap002, TestSize.Level1)
1045 {
1046     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
1047     vector<Entry> entries1;
1048     entries1.push_back(ENTRY_1);
1049     entries1.push_back(ENTRY_2);
1050     vector<Entry> entries12;
1051     entries12.push_back(ENTRY_1_2);
1052     entries12.push_back(ENTRY_2_3);
1053     KvStoreObserverSnapImpl observer1, observer2, observer3, observer4, observer5, observer6, observer7, observer8;
1054     KvStoreSnapshotDelegate *snap1 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer1);
1055     EXPECT_NE(snap1, nullptr);
1056     KvStoreSnapshotDelegate *snap2 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer2);
1057     EXPECT_NE(snap2, nullptr);
1058     KvStoreSnapshotDelegate *snap3 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer3);
1059     EXPECT_NE(snap3, nullptr);
1060     KvStoreSnapshotDelegate *snap4 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer4);
1061     EXPECT_NE(snap4, nullptr);
1062     KvStoreSnapshotDelegate *snap5 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer5);
1063     EXPECT_NE(snap5, nullptr);
1064     KvStoreSnapshotDelegate *snap6 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer6);
1065     EXPECT_NE(snap6, nullptr);
1066     KvStoreSnapshotDelegate *snap7 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer7);
1067     EXPECT_NE(snap7, nullptr);
1068     KvStoreSnapshotDelegate *snap8 = DistributedTestTools::RegisterSnapObserver(g_kvStoreBatchDelegate, &observer8);
1069     EXPECT_NE(snap8, nullptr);
1070     /**
1071      * @tc.steps: step1. putBatch (k1,v1)(k2,v2) to db.
1072      * @tc.expected: step1. putBatch successfully to construct data in db.
1073      */
1074     DistributedDB::Key keyPrefix = { 'k' };
1075     RegisterSnapAgainAndCheck1(observer1, snap1, entries1, keyPrefix);
1076     vector<Key> keys1 = RegisterSnapAgainAndCheck2(observer2, snap2, entries1, keyPrefix);
1077     vector<Entry> entriesInDB = RegisterSnapAgainAndCheck3(observer3, snap3, entries1, keyPrefix);
1078     RegisterSnapAgainAndCheck4(observer4, snap4, entries1, keyPrefix, entriesInDB);
1079     RegisterSnapAgainAndCheck5(observer5, snap5, entries1, keyPrefix, entriesInDB);
1080     RegisterSnapAgainAndCheck6(snap6, snap7, snap8, keyPrefix);
1081     ReleaseSnap(snap1, snap2, snap3, snap4);
1082     ReleaseSnap(snap5, snap6, snap7, snap8);
1083     DistributedTestTools::Clear(*g_kvStoreBatchDelegate);
1084 }
1085 }
1086