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