• 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 <string>
17 
18 #include "distributeddb_nb_test_tools.h"
19 #include "process_communicator_test_stub.h"
20 
21 using namespace std;
22 using namespace testing;
23 #if defined TESTCASES_USING_GTEST_EXT
24 using namespace testing::ext;
25 #endif
26 using namespace DistributedDB;
27 using namespace DistributedDBDataGenerator;
28 
29 namespace DistributeddbNbBatchCrud {
30 static std::condition_variable g_conditionNbBatchVar;
31 const int TWENTY_RECORDS = 20;
32 const int TWENTYFIVE_RECORDS = 25;
33 const int OBSERVER_COUNT = 8;
34 enum BatchTag {
35     PUTBATCH = 0,
36     DELETEBATCH = 1,
37     GETENTRIES = 2,
38 };
39 KvStoreNbDelegate *g_nbBatchCrudDelegate = nullptr;
40 KvStoreDelegateManager *g_manager = nullptr;
41 
42 DistributedDB::CipherPassword g_passwd1;
43 
44 class DistributeddbNbBatchCrudTest : public testing::Test {
45 public:
46     static void SetUpTestCase(void);
47     static void TearDownTestCase(void);
48     void SetUp();
49     void TearDown();
50 private:
51 };
52 
SetUpTestCase(void)53 void DistributeddbNbBatchCrudTest::SetUpTestCase(void)
54 {
55     KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(APP_ID_1, USER_ID_1);
56     ASSERT_NE(manager, nullptr);
57     manager->SetProcessLabel("MST", "GetDevicesID");
58     manager->SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
59     delete manager;
60     manager = nullptr;
61     (void)g_passwd1.SetValue(PASSWD_VECTOR_1.data(), PASSWD_VECTOR_1.size());
62 }
63 
TearDownTestCase(void)64 void DistributeddbNbBatchCrudTest::TearDownTestCase(void)
65 {
66 }
67 
SetUp(void)68 void DistributeddbNbBatchCrudTest::SetUp(void)
69 {
70     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
71 
72     UnitTest *test = UnitTest::GetInstance();
73     ASSERT_NE(test, nullptr);
74     const TestInfo *testinfo = test->current_test_info();
75     ASSERT_NE(testinfo, nullptr);
76     string testCaseName = string(testinfo->name());
77     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
78 
79     g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
80     ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr);
81 }
82 
TearDown(void)83 void DistributeddbNbBatchCrudTest::TearDown(void)
84 {
85     MST_LOG("TearDownTestCase after case.");
86     ASSERT_NE(g_manager, nullptr);
87     EXPECT_TRUE(EndCaseDeleteDB(g_manager, g_nbBatchCrudDelegate, STORE_ID_1, g_option.isMemoryDb));
88     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
89 }
90 
91 /**
92  * @tc.name: SimpleData 001
93  * @tc.desc: Verify that single-ver db can support putbatch<keys,values> to db file.
94  * @tc.type: FUNC
95  * @tc.require: SR000DORPP
96  * @tc.author: fengxiaoyun
97  */
98 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData001, TestSize.Level1)
99 {
100     vector<Entry> entries1, entries2;
101     entries1.push_back(ENTRY_1);
102     entries1.push_back(ENTRY_2);
103     entries2.push_back(ENTRY_3);
104     entries2.push_back(ENTRY_4);
105 
106     /**
107      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB and check the data in DB.
108      * @tc.expected: step1. PutBatch successfully and the (k1, v1), (k2, v2) is in DB.
109      */
110     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
111     Value valueResult;
112     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
113     EXPECT_EQ(valueResult, VALUE_1);
114     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
115     EXPECT_EQ(valueResult, VALUE_2);
116 
117     /**
118      * @tc.steps: step2. call PutBatch interface to Put (k3, v3), (k4, v4) to DB and check the data in DB.
119      * @tc.expected: step2. PutBatch successfully and (k3, v3), (k4, v4) is in DB.
120      */
121     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
122     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), OK);
123     EXPECT_EQ(valueResult, VALUE_3);
124     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_4, valueResult), OK);
125     EXPECT_EQ(valueResult, VALUE_4);
126 }
127 
128 /**
129  * @tc.name: SimpleData 002
130  * @tc.desc: Verify that single-ver db can support update entries in batches.
131  * @tc.type: FUNC
132  * @tc.require: SR000DORPP
133  * @tc.author: fengxiaoyun
134  */
135 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData002, TestSize.Level1)
136 {
137     vector<Entry> entries1, entries2, entriesGot;
138     entries1.push_back(ENTRY_1);
139     entries1.push_back(ENTRY_2);
140     entries2.push_back(ENTRY_1_2);
141     entries2.push_back(ENTRY_2_3);
142 
143     /**
144      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB and check the data in DB.
145      * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2) in DB.
146      */
147     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
148     Value valueResult;
149     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
150     EXPECT_EQ(valueResult, VALUE_1);
151     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
152     EXPECT_EQ(valueResult, VALUE_2);
153     /**
154      * @tc.steps: step2. call PutBatch interface to update (k1, v1), (k2, v2) to (k1, v2), (k2, v3)
155      *    and check the data in DB.
156      * @tc.expected: step2. PutBatch successfully and the value of k1 is v2, the value of k2 is v3.
157      */
158     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
159     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
160     EXPECT_EQ(valueResult, VALUE_2);
161     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
162     EXPECT_EQ(valueResult, VALUE_3);
163 }
164 
165 /**
166  * @tc.name: SimpleData 003
167  * @tc.desc: Verify that single-ver db can support DeleteBatch<keys> from db file.
168  * @tc.type: FUNC
169  * @tc.require: SR000DORPP
170  * @tc.author: fengxiaoyun
171  */
172 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData003, TestSize.Level1)
173 {
174     vector<Entry> entries, entryResults;
175     entries.push_back(ENTRY_1);
176     entries.push_back(ENTRY_2);
177     entries.push_back(ENTRY_3);
178     entries.push_back(ENTRY_4);
179     std::vector<DistributedDB::Key> keys;
180     keys.push_back(KEY_1);
181     keys.push_back(KEY_2);
182     keys.push_back(KEY_3);
183     keys.push_back(KEY_4);
184     /**
185      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2), (k3, v3), (k4, v4) to DB
186      *    and check the data in DB.
187      * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2), (k3, v3), (k4, v4) in DB.
188      */
189     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
190     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
191     EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
192 
193     /**
194      * @tc.steps: step2. call DeleteBatch interface to delete  (k1, v1), (k2, v2), (k3, v3), (k4, v4) from DB
195      *    and check the data in DB.
196      * @tc.expected: step2. DeleteBatch successfully and the DB is empty.
197      */
198     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
199     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
200 }
201 
202 /**
203  * @tc.name: SimpleData 004
204  * @tc.desc: Verify that single-ver db can putbatch <keys,values> value of which is null, but can't putBatch
205  *    <keys,values> value of which is bigger than 4M.
206  * @tc.type: FUNC
207  * @tc.require: SR000DORPP
208  * @tc.author: fengxiaoyun
209  */
210 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData004, TestSize.Level1)
211 {
212     vector<Entry> entries1, entries2, entryResults;
213     entries1.push_back(ENTRY_1);
214     entries1.push_back(ENTRY_2_NULL);
215     entries2.push_back(ENTRY_3);
216     DistributedDB::Entry entry;
217     entry.key = KEY_4;
218     entry.value.assign(FOUR_M_LONG_STRING + 1, 'v'); // the size of value is 4M + 1
219     entries2.push_back(entry);
220 
221     /**
222      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, NULL) to DB and check the data in DB.
223      * @tc.expected: step1. PutBatch successfully and the value of k1 is v1, and the value of k2 is null.
224      */
225     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
226     Value valueResult;
227     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
228     EXPECT_EQ(valueResult, VALUE_1);
229     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
230     EXPECT_EQ(valueResult, VALUE_EMPTY);
231 
232     /**
233      * @tc.steps: step2. call PutBatch interface to Put (k3, v3), entry value of which is supper bigger than 4M
234      *    and check the data in DB.
235      * @tc.expected: step2. PutBatch failed and returned INVALID_ARGS.
236      */
237     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), INVALID_ARGS);
238     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
239     EXPECT_EQ(entryResults.size(), entries1.size());
240 }
241 
242 /**
243  * @tc.name: SimpleData 005
244  * @tc.desc: Verify that single-ver db can't putbatch <keys,values> key of which is null bigger than 1k.
245  * @tc.type: FUNC
246  * @tc.require: SR000DORPP
247  * @tc.author: fengxiaoyun
248  */
249 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData005, TestSize.Level1)
250 {
251     vector<Entry> entries1, entries2, entryResults;
252     DistributedDB::Entry entry1, entry2;
253     entries1.push_back(ENTRY_1);
254     entry1.key = KEY_EMPTY;
255     entry1.value = VALUE_2;
256     entries1.push_back(entry1);
257     entries2.push_back(ENTRY_3);
258     entry2.key.assign(ONE_K_LONG_STRING + 1, 'k'); // the size of key is 1k + 1
259     entry2.value = VALUE_4;
260     entries2.push_back(entry2);
261 
262     /**
263      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (NULL, v2) to DB and check the data in DB.
264      * @tc.expected: step1. PutBatch failed and return INVALID_ARGS.
265      */
266     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), INVALID_ARGS);
267 
268     /**
269      * @tc.steps: step2. call PutBatch interface to Put (k3, v3), entry value of which is supper bigger than 4M
270      *    and check the data in DB.
271      * @tc.expected: step2. PutBatch failed and returned INVALID_ARGS.
272      */
273     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), INVALID_ARGS);
274     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
275 }
276 
277 /**
278  * @tc.name: SimpleData 006
279  * @tc.desc: Verify that single-ver db can't putbatch <keys,values> key of which is null bigger than 1k.
280  * @tc.type: FUNC
281  * @tc.require: SR000DORPP
282  * @tc.author: fengxiaoyun
283  */
284 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData006, TestSize.Level1)
285 {
286     vector<Entry> entries, entryResults;
287     entries.push_back(ENTRY_1);
288     entries.push_back(ENTRY_2);
289     entries.push_back(ENTRY_3);
290     entries.push_back(ENTRY_4);
291 
292     vector<Key> keys1, keys2;
293     keys1.push_back(KEY_1);
294     DistributedDB::Key supperKey;
295     supperKey.assign(ONE_K_LONG_STRING + 1, 'k'); // the size of key is 1k + 1
296     keys1.push_back(supperKey);
297     keys2.push_back(KEY_2);
298     keys2.push_back(KEY_EMPTY);
299 
300     /**
301      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2)(k3,v3)(k4,v4) to db.
302      * @tc.expected: step1. PutBatch successfully.
303      */
304     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
305     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
306     EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
307 
308     /**
309      * @tc.steps: step2. call DeleteBatch interface to delete k1, supperKey from DB and check the data in DB.
310      * @tc.expected: step2. DeleteBatch failed and the data in DB is not changed.
311      */
312     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1), INVALID_ARGS);
313     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
314     EXPECT_EQ(entryResults.size(), entries.size());
315     /**
316      * @tc.steps: step3. call DeleteBatch interface to delete k2 which is KEY_EMPTY from DB and check the data in DB.
317      * @tc.expected: step3. DeleteBatch failed and the data in DB is not changed.
318      */
319     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys2), INVALID_ARGS);
320     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
321     EXPECT_EQ(entryResults.size(), entries.size());
322 }
323 
324 /**
325  * @tc.name: SimpleData 007
326  * @tc.desc: Verify that single-ver db deletebatch the data that are noexist party will return OK, but will
327  * return NOT_FOUND when the keys are all noexist.
328  * @tc.type: FUNC
329  * @tc.require: SR000DORPP
330  * @tc.author: fengxiaoyun
331  */
332 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData007, TestSize.Level1)
333 {
334     vector<Entry> entries, entryResults;
335     entries.push_back(ENTRY_1);
336     entries.push_back(ENTRY_2);
337     std::vector<DistributedDB::Key> keys;
338     keys.push_back(KEY_1);
339     keys.push_back(KEY_2);
340     keys.push_back(KEY_3);
341 
342     /**
343      * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB
344      *    and check the data in DB.
345      * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2) in DB.
346      */
347     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
348     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
349     EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
350 
351     /**
352      * @tc.steps: step2. call DeleteBatch interface to delete  (k1,k2,k3) from DB
353      *    and check the data in DB.
354      * @tc.expected: step2. DeleteBatch successfully and the DB is empty.
355      */
356     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
357     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
358 
359     /**
360      * @tc.steps: step3. call DeleteBatch interface to delete  (k1,k2,k3) from DB
361      *    and check the data in DB.
362      * @tc.expected: step3. DeleteBatch return OK and the DB is empty.
363      */
364     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
365     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
366 }
367 
368 /**
369  * @tc.name: SimpleData 008
370  * @tc.desc: Verify that when the items of batch operation over 128, the interface will return INVALID_ARGS.
371  * @tc.type: FUNC
372  * @tc.require: SR000DORPP
373  * @tc.author: fengxiaoyun
374  */
375 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData008, TestSize.Level1)
376 {
377     vector<Entry> entriesBatch, entryResults;
378     vector<Key> allKeys;
379     GenerateRecords(BATCH_RECORDS + 1, DEFAULT_START, allKeys, entriesBatch);
380 
381     /**
382      * @tc.steps: step1. PutBatch 129 items to DB and GetEntries().
383      * @tc.expected: step1. PutBatch failed and GetEntries return NOT_FOUND.
384      */
385     EXPECT_EQ(g_nbBatchCrudDelegate->PutBatch(entriesBatch), INVALID_ARGS);
386     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
387 
388     /**
389      * @tc.steps: step2. DeleteBatch 129 items to DB and GetEntries().
390      * @tc.expected: step2. DeleteBatch failed and GetEntries return NOT_FOUND.
391      */
392     EXPECT_EQ(g_nbBatchCrudDelegate->DeleteBatch(allKeys), INVALID_ARGS);
393     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
394 }
395 
396 /**
397  * @tc.name: SimpleData 009
398  * @tc.desc: Verify that rekey will return busy when do batch operation.
399  * @tc.type: FUNC
400  * @tc.require: SR000DORPP
401  * @tc.author: fengxiaoyun
402  */
403 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData009, TestSize.Level2)
404 {
405     vector<Entry> entriesBatch, entryResults;
406     vector<Key> allKeys;
407     GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
408     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
409 
410     /**
411      * @tc.steps: step1. PutBatch <keys,values> to db.
412      * @tc.expected: step1. PutBatch successfully.
413      */
414     bool subPutBatchFlag = false;
__anon7be1a5110102() 415     thread subThread([&]() {
416         DBStatus status = g_nbBatchCrudDelegate->PutBatch(entriesBatch);
417         EXPECT_TRUE(status == OK || status == BUSY);
418         subPutBatchFlag = true;
419         g_conditionNbBatchVar.notify_all();
420     });
421     subThread.detach();
422 
423     /**
424      * @tc.steps: step2. call Rekey when step1 is running.
425      * @tc.expected: step2. rekey return BUSY.
426      */
427     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
428     DBStatus rekeyStatus = g_nbBatchCrudDelegate->Rekey(g_passwd1);
429     EXPECT_TRUE(rekeyStatus == OK || rekeyStatus == BUSY);
430 
431     /**
432      * @tc.steps: step3. GetEntries() from db.
433      * @tc.expected: step3. GetEntries the data that step1 putbatch.
434      */
435     std::mutex count;
436     std::unique_lock<std::mutex> lck(count);
__anon7be1a5110202null437     g_conditionNbBatchVar.wait(lck, [&]{return subPutBatchFlag;});
438     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
439     EXPECT_EQ(entryResults.size(), entriesBatch.size());
440 }
441 
442 /**
443  * @tc.name: SimpleData 010
444  * @tc.desc: Verify that import will return busy when do batch operation.
445  * @tc.type: FUNC
446  * @tc.require: SR000DORPP
447  * @tc.author: fengxiaoyun
448  */
449 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData010, TestSize.Level2)
450 {
451     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
452     SetDir(importPath);
453     std::string filePath = importPath + "/bkpDB.bin";
454     EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), OK);
455     vector<Entry> entriesBatch, entryResults;
456     vector<Key> allKeys;
457     GenerateFixedRecords(entriesBatch, allKeys, NB_PREDATA_NUM, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
458     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
459 
460     /**
461      * @tc.steps: step1. DeleteBatch data.
462      * @tc.expected: step1. operation successfully.
463      */
464     bool subDeleteBatchFlag = false;
__anon7be1a5110302() 465     thread subThread([&]() {
466         DBStatus deleteStatus = g_nbBatchCrudDelegate->DeleteBatch(allKeys);
467         EXPECT_TRUE(deleteStatus == OK || deleteStatus == BUSY);
468         subDeleteBatchFlag = true;
469         g_conditionNbBatchVar.notify_all();
470     });
471     subThread.detach();
472 
473     /**
474      * @tc.steps: step2. call import interface when step1 is running.
475      * @tc.expected: step2. import return BUSY.
476      */
477     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
478     DBStatus importStatus = g_nbBatchCrudDelegate->Import(filePath, NULL_PASSWD);
479     EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
480 
481     /**
482      * @tc.steps: step3. GetEntries() from db.
483      * @tc.expected: step3. GetEntries return NOT_FOUND.
484      */
485     std::mutex count;
486     std::unique_lock<std::mutex> lck(count);
__anon7be1a5110402null487     g_conditionNbBatchVar.wait(lck, [&]{return subDeleteBatchFlag;});
488     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
489 }
490 
TestBatchComplexAction(vector<Entry> & entries1,vector<Entry> & entries12)491 void TestBatchComplexAction(vector<Entry> &entries1, vector<Entry> &entries12)
492 {
493     /**
494      * @tc.steps: step3. PutBatch (k1,v1)(k2,v2) and then get.
495      * @tc.expected: step3. PutBatch successfully get null of k1,k2.
496      */
497     DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
498     EXPECT_EQ(status, OK);
499     Value valueResult;
500     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
501     EXPECT_EQ(valueResult, VALUE_1);
502     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
503     EXPECT_EQ(valueResult, VALUE_2);
504 
505     /**
506      * @tc.steps: step4. PutBatch (k1,v2)(k2,v3) and then get.
507      * @tc.expected: step4. PutBatch successfully get v2 of k1,v3 of k2.
508      */
509     status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries12);
510     EXPECT_EQ(status, OK);
511     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
512     EXPECT_EQ(valueResult, VALUE_2);
513     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
514     EXPECT_EQ(valueResult, VALUE_3);
515 }
516 
517 /**
518  * @tc.name: ComplexData 001
519  * @tc.desc: Verify that single-ver db can support batch CRUD for the same keys continuously.
520  * @tc.type: FUNC
521  * @tc.require: SR000DORPP
522  * @tc.author: fengxiaoyun
523  */
524 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData001, TestSize.Level1)
525 {
526     vector<Entry> entries1;
527     entries1.push_back(ENTRY_1);
528     entries1.push_back(ENTRY_2);
529     vector<Entry> entries12;
530     entries12.push_back(ENTRY_1_2);
531     entries12.push_back(ENTRY_2_3);
532 
533     vector<Key> keys1;
534     keys1.push_back(ENTRY_1.key);
535     keys1.push_back(ENTRY_2.key);
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     DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
542     EXPECT_EQ(status, OK);
543     Value valueResult;
544     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
545     EXPECT_EQ(valueResult, VALUE_1);
546     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
547     EXPECT_EQ(valueResult, VALUE_2);
548 
549     /**
550      * @tc.steps: step2. DeleteBatch (k1)(k2) and then get.
551      * @tc.expected: step2. DeleteBatch successfully get return NOT_FOUND.
552      */
553     status = DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1);
554     EXPECT_EQ(status, OK);
555     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
556     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
557 
558     TestBatchComplexAction(entries1, entries12);
559 
560     /**
561      * @tc.steps: step5. DeleteBatch (k1)(k2) and then get.
562      * @tc.expected: step5. DeleteBatch successfully get return NOT_FOUND.
563      */
564     status = DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1);
565     EXPECT_EQ(status, OK);
566     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
567     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
568 }
569 
570 /**
571  * @tc.name: ComplexData 002
572  * @tc.desc: Verify that single-ver db can support batch CRUD for the different keys continuously.
573  * @tc.type: FUNC
574  * @tc.require: SR000DORPP
575  * @tc.author: fengxiaoyun
576  */
577 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData002, TestSize.Level2)
578 {
579     vector<Entry> entriesBatch, entriesRes;
580     vector<Key> allKeys;
581     /**
582      * @tc.steps: step1-2. PutBatch 100 items of (keys,values) then query and deletebatch for 100 times.
583      * @tc.expected: step1-2. operate successfully.
584      */
585     GenerateFixedLenRandRecords(entriesBatch, allKeys, ONE_HUNDRED_RECORDS, KEY_SIX_BYTE, KEY_ONE_HUNDRED_BYTE);
586     for (int count = 0; count < ONE_HUNDRED_RECORDS; count++) {
587         EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
588         EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
589         EXPECT_EQ(entriesRes.size(), entriesBatch.size());
590         EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys), OK);
591         entriesRes.clear();
592     }
593 
594     /**
595      * @tc.steps: step3. PutBatch 20 items of (keys,values) and then query.
596      * @tc.expected: step3. PutBatch successfully GetEntries is right.
597      */
598     entriesBatch.clear();
599     GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys, entriesBatch);
600     DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch);
601     EXPECT_EQ(status, OK);
602     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
603     EXPECT_EQ(entriesRes.size(), entriesBatch.size());
604 }
605 
CheckBatchCrud(vector<Entry> entries,vector<Key> keys)606 void CheckBatchCrud(vector<Entry> entries, vector<Key> keys)
607 {
608     /**
609      * @tc.steps: step3. Put(k1,v3) Put(k2,v4) Put(k3,v3) and then get.
610      * @tc.expected: step3. Put successfully get v3 of k1,v4 of k2,v3 of k3.
611      */
612     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_1_3.key, ENTRY_1_3.value), OK);
613     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_2_4.key, ENTRY_2_4.value), OK);
614     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_3.key, ENTRY_3.value), OK);
615     vector<Entry> entriesRes;
616     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
617     EXPECT_TRUE(CompareEntriesVector(entriesRes, entries));
618     /**
619      * @tc.steps: step4. DeleteBatch (k2)(k3) and then get.
620      * @tc.expected: step4. DeleteBatch successfully get v3 of k1,get return NOT_FOUND of k2,k3.
621      */
622     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
623     Value valueResult;
624     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
625     EXPECT_EQ(valueResult, VALUE_3);
626     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
627     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), NOT_FOUND);
628     /**
629      * @tc.steps: step5. PutBatch(k1,v2)(k2,v3)(k3,v4) then get.
630      * @tc.expected: step5. Putbatch successfully, get v2 of k1, v3 of k2, v4 of k3.
631      */
632     vector<Entry> entries123;
633     entries123.push_back(ENTRY_1_2);
634     entries123.push_back(ENTRY_2_3);
635     entries123.push_back(ENTRY_3_4);
636     DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries123);
637     EXPECT_EQ(status, OK);
638     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
639     EXPECT_EQ(valueResult, VALUE_2);
640     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
641     EXPECT_EQ(valueResult, VALUE_3);
642     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), OK);
643     EXPECT_EQ(valueResult, VALUE_4);
644 }
645 
646 /**
647  * @tc.name: ComplexData 003
648  * @tc.desc: Verify that can batch and single crud continuously.
649  * @tc.type: FUN
650  * @tc.require: SR000DORPP
651  * @tc.author: fengxiaoyun
652  */
653 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData003, TestSize.Level1)
654 {
655     vector<Entry> entries1;
656     entries1.push_back(ENTRY_1);
657     entries1.push_back(ENTRY_2);
658     vector<Entry> entries123;
659     entries123.push_back(ENTRY_1_3);
660     entries123.push_back(ENTRY_2_4);
661     entries123.push_back(ENTRY_3);
662     vector<Key> keys23;
663     keys23.push_back(ENTRY_2.key);
664     keys23.push_back(ENTRY_3.key);
665 
666     /**
667      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
668      * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
669      */
670     DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
671     EXPECT_EQ(status, OK);
672     Value valueResult;
673     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
674     EXPECT_EQ(valueResult, VALUE_1);
675     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
676     EXPECT_EQ(valueResult, VALUE_2);
677 
678     /**
679      * @tc.steps: step2. delete k1 and then get.
680      * @tc.expected: step2. delete successfully get return NOT_FOUND of k1, get v2 of k2.
681      */
682     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
683     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
684     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
685     EXPECT_EQ(valueResult, VALUE_2);
686 
687     CheckBatchCrud(entries123, keys23);
688 }
689 
NbBatchCRUDThread(BatchTag tag)690 void NbBatchCRUDThread(BatchTag tag)
691 {
692     vector<Entry> entriesBatch;
693     vector<Key> allKeys;
694     GenerateFixedLenRandRecords(entriesBatch, allKeys, TWENTY_RECORDS,
695         KEY_SIX_BYTE, KEY_ONE_HUNDRED_BYTE);
696     if (tag == PUTBATCH) {
697         DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch);
698         EXPECT_EQ(status, OK);
699     } else if (tag == DELETEBATCH) {
700         DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys);
701     } else if (tag == GETENTRIES) {
702         vector<Entry> entryResults;
703         DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, {'k'}, entryResults);
704     }
705 }
706 
707 /**
708  * @tc.name: ComplexData 005
709  * @tc.desc: test that it won't be crash when there are 20 threads to batch operation.
710  * @tc.type: Pressure
711  * @tc.require: SR000DORPP
712  * @tc.author: fengxiaoyun
713  */
714 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData005, TestSize.Level2)
715 {
716     /**
717      * @tc.steps: step1. start 20 threads to do batch operation.
718      * @tc.expected: step1. process is normal and no crash.
719      */
720     std::vector<std::thread> threads;
721     for (int threadId = 0; threadId < TWENTY_RECORDS; ++threadId) {
722         int indexOption = GetRandInt(MODE_RAND_MIN, MODE_RAND_MAX);
723         threads.push_back(std::thread(NbBatchCRUDThread, BatchTag(indexOption)));
724     }
725     for (auto& th : threads) {
726         th.join();
727     }
728     std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
729 }
730 
731 /**
732  * @tc.name: Observer 001
733  * @tc.desc: Verify that putbatch will trigger callback after register observer for specific key.
734  * @tc.type: FUNC
735  * @tc.require: SR000DORPP
736  * @tc.author: fengxiaoyun
737  */
738 HWTEST_F(DistributeddbNbBatchCrudTest, Observer001, TestSize.Level1)
739 {
740     KvStoreObserverImpl observer1, observer2, observer3;
741     vector<Entry> entries1, entries2;
742     entries1.push_back(ENTRY_1);
743     entries1.push_back(ENTRY_2);
744     entries2.push_back(ENTRY_2_3);
745     entries2.push_back(ENTRY_3);
746     vector<DistributedDB::Entry> observerCallbackEntries;
747 
748     /**
749      * @tc.steps: step1. register observer1,observer2,observer3 for k1,k2,k3 with
750      * mode = OBSERVER_CHANGES_NATIVE.
751      * @tc.expected: step1. register successfully.
752      */
753     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
754     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
755     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
756 
757     /**
758      * @tc.steps: step2. putbatch (k1,v1)(k2,v2) to db and check observer callback.
759      * @tc.expected: step2. putbatch successfully and the callback of observer1 and observer2
760      * are all once INSERT_LIST.
761      */
762     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
763     observerCallbackEntries.push_back(ENTRY_1);
764     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
765     observerCallbackEntries.clear();
766     observerCallbackEntries.push_back(ENTRY_2);
767     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
768     observer1.Clear();
769     observer2.Clear();
770     observer3.Clear();
771 
772     /**
773      * @tc.steps: step3. putbatch (k2,v3)(k3,v3) to db and check observer callback.
774      * @tc.expected: step3. putbatch successfully and the callback of observer2 is once UPDATE_LIST,
775      * the callback of observer3 is once INSERT_LIST, there is no callback of observer1.
776      */
777     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
778     observerCallbackEntries.clear();
779     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
780     observerCallbackEntries.push_back(ENTRY_2_3);
781     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
782     observerCallbackEntries.clear();
783     observerCallbackEntries.push_back(ENTRY_3);
784     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
785 }
786 
787 /**
788  * @tc.name: Observer 002
789  * @tc.desc: Verify that deletebatch will trigger callback after register observer for specific key.
790  * @tc.type: FUNC
791  * @tc.require: SR000DORPP
792  * @tc.author: fengxiaoyun
793  */
794 HWTEST_F(DistributeddbNbBatchCrudTest, Observer002, TestSize.Level1)
795 {
796     KvStoreObserverImpl observer1, observer2, observer3;
797     vector<Entry> entries1, entryResults;
798     entries1.push_back(ENTRY_1);
799     entries1.push_back(ENTRY_2);
800     std::vector<DistributedDB::Key> keys;
801     keys.push_back(KEY_3);
802     keys.push_back(KEY_2);
803     keys.push_back(KEY_1);
804     vector<DistributedDB::Entry> observerCallbackEntries;
805 
806     /**
807      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
808      * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
809      */
810     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
811     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
812     EXPECT_TRUE(CompareEntriesVector(entryResults, entries1));
813 
814     /**
815      * @tc.steps: step2. register observer1,observer2,observer3 for k1,k2,k3 with
816      * mode = OBSERVER_CHANGES_NATIVE.
817      * @tc.expected: step2. register successfully.
818      */
819     DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
820     EXPECT_EQ(status, OK);
821     status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
822     EXPECT_EQ(status, OK);
823     status = g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3);
824     EXPECT_EQ(status, OK);
825 
826     /**
827      * @tc.steps: step3. deletebatch (k1,k2,k3) and check observer callback.
828      * @tc.expected: step3. deletebatch successfully and the callback of observer1 and observer2
829      * are all once DELETE_LIST, the observer3 won't receive callback.
830      */
831     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
832     observerCallbackEntries.push_back(ENTRY_1);
833     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
834     observerCallbackEntries.clear();
835     observerCallbackEntries.push_back(ENTRY_2);
836     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
837     observerCallbackEntries.clear();
838     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, ListType::DELETE_LIST, observerCallbackEntries));
839 }
840 
841 /**
842  * @tc.name: Observer 003
843  * @tc.desc: Verify that putbatch will trigger callback after register observer for specific key.
844  * @tc.type: FUNC
845  * @tc.require: SR000DORPP
846  * @tc.author: fengxiaoyun
847  */
848 HWTEST_F(DistributeddbNbBatchCrudTest, Observer003, TestSize.Level1)
849 {
850     KvStoreObserverImpl observer1, observer2, observer3;
851     vector<Entry> entries1, entries2;
852     entries1.push_back(ENTRY_1);
853     entries1.push_back(ENTRY_1_2);
854     entries1.push_back(ENTRY_2);
855     entries2.push_back(ENTRY_2_3);
856     entries2.push_back(ENTRY_2_4);
857     entries2.push_back(ENTRY_3);
858     vector<DistributedDB::Entry> observerCallbackEntries;
859 
860     /**
861      * @tc.steps: step1. register observer1,observer2,observer3 for k1,k2,k3 with
862      * mode = OBSERVER_CHANGES_NATIVE.
863      * @tc.expected: step1. register successfully.
864      */
865     DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
866     EXPECT_EQ(status, OK);
867     status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
868     EXPECT_EQ(status, OK);
869     status = g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3);
870     EXPECT_EQ(status, OK);
871 
872     /**
873      * @tc.steps: step2. putbatch (k1,v1)(k2,v2) to db and check observer callback.
874      * @tc.expected: step2. putbatch successfully and the callback of observer1 and observer2
875      * are all once INSERT_LIST.
876      */
877     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
878     observerCallbackEntries.push_back(ENTRY_1_2);
879     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
880     observerCallbackEntries.clear();
881     observerCallbackEntries.push_back(ENTRY_2);
882     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
883     observer1.Clear();
884     observer2.Clear();
885     observer3.Clear();
886 
887     /**
888      * @tc.steps: step3. putbatch (k2,v3)(k3,v3) to db and check observer callback.
889      * @tc.expected: step3. putbatch successfully and the callback of observer2 is once UPDATE_LIST,
890      * the callback of observer3 is once INSERT_LIST, there is no callback of observer1.
891      */
892     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
893     observerCallbackEntries.clear();
894     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
895     observerCallbackEntries.push_back(ENTRY_2_4);
896     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
897     observerCallbackEntries.clear();
898     observerCallbackEntries.push_back(ENTRY_3);
899     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
900 }
901 
902 /**
903  * @tc.name: Observer 004
904  * @tc.desc: Verify that deletebatch will trigger callback after register observer for specific key.
905  * @tc.type: FUNC
906  * @tc.require: SR000DORPP
907  * @tc.author: fengxiaoyun
908  */
909 HWTEST_F(DistributeddbNbBatchCrudTest, Observer004, TestSize.Level1)
910 {
911     KvStoreObserverImpl observer1, observer2;
912     vector<Entry> entries1, entryResults;
913     entries1.push_back(ENTRY_1);
914     entries1.push_back(ENTRY_2);
915     std::vector<DistributedDB::Key> keys;
916     keys.push_back(KEY_1);
917     keys.push_back(KEY_2);
918     keys.push_back(KEY_1);
919     vector<DistributedDB::Entry> observerCallbackEntries;
920 
921     /**
922      * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
923      * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
924      */
925     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
926     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
927     EXPECT_TRUE(CompareEntriesVector(entryResults, entries1));
928 
929     /**
930      * @tc.steps: step2. register observer1,observer2 for k1, k2 with mode = OBSERVER_CHANGES_NATIVE.
931      * @tc.expected: step2. register successfully.
932      */
933     DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
934     EXPECT_EQ(status, OK);
935     status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
936     EXPECT_EQ(status, OK);
937 
938     /**
939      * @tc.steps: step3. deletebatch (k1,k2,k1) and check observer callback.
940      * @tc.expected: step3. deletebatch successfully and observer1 and observer2 are both triggered once.
941      */
942     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
943     observerCallbackEntries.push_back(ENTRY_1);
944     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
945     observerCallbackEntries.clear();
946     observerCallbackEntries.push_back(ENTRY_2);
947     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
948 }
949 
950 /**
951  * @tc.name: Observer 005
952  * @tc.desc: Verify that deletebatch will trigger once callback after register observer for all key.
953  * @tc.type: FUNC
954  * @tc.require: SR000DORPP
955  * @tc.author: fengxiaoyun
956  */
957 HWTEST_F(DistributeddbNbBatchCrudTest, Observer005, TestSize.Level1)
958 {
959     vector<Entry> entriesBatch;
960     vector<Key> allKeys;
961     GenerateRecords(TEN_RECORDS, DEFAULT_START, allKeys, entriesBatch);
962 
963     /**
964      * @tc.steps: step1. register 8 observers for all key.
965      * @tc.expected: step1. register successfully.
966      */
967     KvStoreObserverImpl observerNative[OBSERVER_COUNT];
968     for (int obsCnt = 0; obsCnt < OBSERVER_COUNT; obsCnt++) {
969         EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE,
970             &observerNative[obsCnt]), OK);
971     }
972 
973     /**
974      * @tc.steps: step2. putbatch 10 items of <keys,values> to db and check observer callback.
975      * @tc.expected: step2. putbatch successfully and the callback of all observers are once
976      * INSERT_LIST with 10 items data.
977      */
978     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
979     for (int index = 0; index < OBSERVER_COUNT; index++) {
980         EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::INSERT_LIST, entriesBatch));
981     }
982     for (int index = 0; index < OBSERVER_COUNT; index++) {
983         observerNative[index].Clear();
984     }
985 
986     /**
987      * @tc.steps: step3. putbatch 10 items of <keys,values> to db and check observer callback.
988      * @tc.expected: step3. putbatch successfully and the callback of all observers are once
989      * UPDATE_LIST with 10 items data.
990      */
991     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
992     for (int index = 0; index < OBSERVER_COUNT; index++) {
993         EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::UPDATE_LIST, entriesBatch));
994     }
995     for (int index = 0; index < OBSERVER_COUNT; index++) {
996     observerNative[index].Clear();
997     }
998 
999     /**
1000      * @tc.steps: step4. deletebatch 10 items of <keys> from db and check observer callback.
1001      * @tc.expected: step4. putbatch successfully and the callback of all observers are once
1002      * DELETE_LIST with 10 items data.
1003      */
1004     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys), OK);
1005     for (int index = 0; index < OBSERVER_COUNT; index++) {
1006         EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::DELETE_LIST, entriesBatch));
1007     }
1008 }
1009 
1010 /**
1011  * @tc.name: Transaction 001
1012  * @tc.desc: start transaction success and can only native DB support to put and local DB not.
1013  * @tc.type: FUNC
1014  * @tc.require: SR000DORPP
1015  * @tc.author: fengxiaoyun
1016  */
1017 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction001, TestSize.Level1)
1018 {
1019     /**
1020      * @tc.steps: step1. start transaction.
1021      * @tc.expected: step1. start successfully.
1022      */
1023     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1024 
1025     /**
1026      * @tc.steps: step2. use Put interface to put (k1, v1) and Get the value of k1;
1027      * @tc.expected: step2. put successfully but can't find data in db
1028      */
1029     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1030     Value value;
1031     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1032     EXPECT_EQ(value, VALUE_1);
1033     /**
1034      * @tc.steps: step3. use PutLocal interface to put (k2, v2) and Get the value of k2;
1035      * @tc.expected: step3. PutLocal failed and returned NOT_SUPPORT and can't find data in db
1036      */
1037     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
1038     EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1039     EXPECT_EQ(value, VALUE_2);
1040 
1041     /**
1042      * @tc.steps: step4. commit the transaction and check the data in db again.
1043      * @tc.expected: step4. commit successfully.
1044      */
1045     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1046     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1047     EXPECT_EQ(value, VALUE_1);
1048     EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1049     EXPECT_EQ(value, VALUE_2);
1050 }
1051 
1052 /**
1053  * @tc.name: Transaction 002
1054  * @tc.desc: verify that the db support Rollback but can't Rollback repeatedly.
1055  * @tc.type: FUNC
1056  * @tc.require: SR000DORPP
1057  * @tc.author: fengxiaoyun
1058  */
1059 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction002, TestSize.Level1)
1060 {
1061     /**
1062      * @tc.steps: step1. start transaction.
1063      * @tc.expected: step1. start successfully.
1064      */
1065     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1066 
1067     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1068     Value value;
1069     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1070     EXPECT_EQ(value, VALUE_1);
1071     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
1072     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1073     EXPECT_EQ(value, VALUE_2);
1074 
1075     /**
1076      * @tc.steps: step2. use Delete interface to delete (k1, v1) and Get the value of k1.
1077      * @tc.expected: step2. delete successfully and can't find k1 in db.
1078      */
1079     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1080     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1081 
1082     /**
1083      * @tc.steps: step3. Rollback and check the data in db again.
1084      * @tc.expected: step3. Rollback successfully and can't find (k1, v1) and (k2, v2) in db.
1085      */
1086     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1087     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1088     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), NOT_FOUND);
1089 
1090     /**
1091      * @tc.steps: step4. Rollback again.
1092      * @tc.expected: step4. returned error.
1093      */
1094     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1095 }
1096 
1097 /**
1098  * @tc.name: Transaction 003
1099  * @tc.desc: verify that it can't start transaction repeatedly.
1100  * @tc.type: FUNC
1101  * @tc.require: SR000DORPP
1102  * @tc.author: fengxiaoyun
1103  */
1104 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction003, TestSize.Level1)
1105 {
1106     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1107     /**
1108      * @tc.steps: step1. start transaction and update (k1, v1) to (k1, v2).
1109      * @tc.expected: step1. start and put successfully but the value of k1 is still v1.
1110      */
1111     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1112 
1113     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1114     Value value;
1115     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1116     EXPECT_EQ(value, VALUE_2);
1117     /**
1118      * @tc.steps: step2. start the transaction again.
1119      * @tc.expected: step2. returned error.
1120      */
1121     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), DB_ERROR);
1122 
1123     /**
1124      * @tc.steps: step3. commit and check the records in db.
1125      * @tc.expected: step3. commit successfully and the value of k1 is v2.
1126      */
1127     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1128     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1129     EXPECT_EQ(value, VALUE_2);
1130 }
1131 
1132 /**
1133  * @tc.name: Transaction 004
1134  * @tc.desc: verify that can't commit without start transaction and can putBatch when start transaction.
1135  * @tc.type: FUNC
1136  * @tc.require: SR000DORPP
1137  * @tc.author: fengxiaoyun
1138  */
1139 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction004, TestSize.Level1)
1140 {
1141     /**
1142      * @tc.steps: step1. commit the transaction without start it.
1143      * @tc.expected: step1. commit failed.
1144      */
1145     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1146     /**
1147      * @tc.steps: step2. start the transaction and putBatch 128 records and check the data with GetEntries.
1148      * @tc.expected: step2. start success and GetEntries returns no entry.
1149      */
1150     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1151 
1152     std::vector<DistributedDB::Entry> entries, entriesGot;
1153     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1154     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
1155     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1156     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1157     EXPECT_EQ(entriesGot.size(), BATCH_RECORDS);
1158 
1159     /**
1160      * @tc.steps: step3. commit and GetEntries in db.
1161      * @tc.expected: step3. commit successfully and can find the entries in db.
1162      */
1163     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1164     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1165     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1166 }
1167 
1168 /**
1169  * @tc.name: Transaction 005
1170  * @tc.desc: verify that can't Rollback without start transaction and can updateBatch when start transaction.
1171  * @tc.type: FUNC
1172  * @tc.require: SR000DORPP
1173  * @tc.author: fengxiaoyun
1174  */
1175 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction005, TestSize.Level1)
1176 {
1177     /**
1178      * @tc.steps: step1. Rollback the transaction without start it and PutBatch 10 records to DB.
1179      * @tc.expected: step1. Rollback failed and PutBatch success.
1180      */
1181     std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1182     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1183     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, TEN_RECORDS, {'k'}, {'a'});
1184     GenerateAppointPrefixAndSizeRecords(entries2, entrySize, TEN_RECORDS, {'k'}, {'b'});
1185     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1186 
1187     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1188     /**
1189      * @tc.steps: step2. start the transaction and update the 10 records Batchly and check the data with GetEntries.
1190      * @tc.expected: step2. start success and GetEntries return the entries is equal to entres1.
1191      */
1192     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1193 
1194     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1195     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1196     EXPECT_TRUE(CompareEntriesVector(entries2, entriesGot));
1197 
1198     /**
1199      * @tc.steps: step3. commit and GetEntries in db.
1200      * @tc.expected: step3. commit successfully and the entriesGot is equal to entries2.
1201      */
1202     entriesGot.clear();
1203     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1204     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1205     EXPECT_TRUE(CompareEntriesVector(entries2, entriesGot));
1206 }
1207 
1208 /**
1209  * @tc.name: Transaction 006
1210  * @tc.desc: verify that can DeleteBatch when start transaction.
1211  * @tc.type: FUNC
1212  * @tc.require: SR000DORPP
1213  * @tc.author: fengxiaoyun
1214  */
1215 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction006, TestSize.Level1)
1216 {
1217     std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1218     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1219     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, TEN_RECORDS, {'k'}, {'a'});
1220     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1221 
1222     for (unsigned int index = 0; index < (entries1.size() / 2); index++) {
1223         entries2.push_back(entries1[index]);
1224     }
1225     std::vector<DistributedDB::Key> keys;
1226     for (auto const &entry : entries2) {
1227         keys.push_back(entry.key);
1228     }
1229 
1230     /**
1231      * @tc.steps: step1. start the transaction and Deleted Batchly 5 of the 10 records inserted to db.
1232      * @tc.expected: step1. start and delete success and GetEntries return the entries is equal to entres1.
1233      */
1234     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1235 
1236     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1237     entries1.erase(entries1.begin(), entries1.begin() + FIVE_RECORDS);
1238     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1239     EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1240 
1241     /**
1242      * @tc.steps: step2. commit and GetEntries in db.
1243      * @tc.expected: step2. commit successfully and the entriesGot is equal to (entries1 - entries2).
1244      */
1245     entriesGot.clear();
1246     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1247     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1248     EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1249 
1250     /**
1251      * @tc.steps: step3. commit again.
1252      * @tc.expected: step3. commit failed and returned error.
1253      */
1254     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1255 }
1256 
1257 /**
1258  * @tc.name: Transaction 007
1259  * @tc.desc: verify that transaction support native db insert or delete records
1260  *     but don't support local db to operate db.
1261  * @tc.type: FUNC
1262  * @tc.require: SR000DORPP
1263  * @tc.author: fengxiaoyun
1264  */
1265 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction007, TestSize.Level1)
1266 {
1267     /**
1268      * @tc.steps: step1. PutLocal (k1, v1) to Local DB and start transaction
1269      * @tc.expected: step1. putLocal and start success.
1270      */
1271     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1272 
1273     /**
1274      * @tc.steps: step2. start the transaction and Put and update and deleteLocal on DB and commit the transaction.
1275      * @tc.expected: step2. start and Put and commit success,
1276      *    but can't find records on native db, and deletelocal returned failed.
1277      */
1278     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1279 
1280     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1281     Value value;
1282     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1283     EXPECT_EQ(value, VALUE_1);
1284 
1285     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1286     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1287     EXPECT_EQ(value, VALUE_2);
1288 
1289     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocal(*g_nbBatchCrudDelegate, KEY_1), OK);
1290 
1291     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1292 
1293     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1294     EXPECT_EQ(value, VALUE_2);
1295     EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1296 
1297     /**
1298      * @tc.steps: step3. Rollback after commit.
1299      * @tc.expected: step3. Rollback failed and returned error.
1300      */
1301     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1302 }
1303 
1304 /**
1305  * @tc.name: Transaction 008
1306  * @tc.desc: verify that it can't commit after it was Rollbacked
1307  * @tc.type: FUNC
1308  * @tc.require: SR000DORPP
1309  * @tc.author: fengxiaoyun
1310  */
1311 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction008, TestSize.Level1)
1312 {
1313     /**
1314      * @tc.steps: step1. Put (k1, v1) to DB and start transaction
1315      * @tc.expected: step1. put and start success.
1316      */
1317     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1318     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1319     /**
1320      * @tc.steps: step2. update (k1, v1) and Rollback.
1321      * @tc.expected: step2. update and Rollback successfully
1322      */
1323     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1324 
1325     Value value;
1326     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1327     EXPECT_EQ(value, VALUE_2);
1328 
1329     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1330     /**
1331      * @tc.steps: step3. commit after Rollback and check the records in db.
1332      * @tc.expected: step3. commit failed and returned error and the value of k1 is v1.
1333      */
1334     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1335 
1336     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1337     EXPECT_EQ(value, VALUE_1);
1338 }
1339 
1340 /**
1341  * @tc.name: Transaction 009
1342  * @tc.desc: verify that start transaction and commit or rollback repeatedly
1343  * @tc.type: FUNC
1344  * @tc.require: SR000DORPP
1345  * @tc.author: fengxiaoyun
1346  */
1347 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction009, TestSize.Level1)
1348 {
1349     /**
1350      * @tc.steps: step1. repeat 5 times
1351      * @tc.expected: step1. start loop success.
1352      */
1353     for (int index = 0; index < FIVE_TIMES; index++) {
1354         /**
1355          * @tc.steps: step2. start transaction and commit.
1356          * @tc.expected: step2. start and commit successfully
1357          */
1358         EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1359 
1360         EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1361         /**
1362          * @tc.steps: step3. start transaction and rollback.
1363          * @tc.expected: step3. start and Rollback successfully
1364          */
1365         EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1366 
1367         EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1368     }
1369 }
1370 
1371 /**
1372  * @tc.name: Transaction 010
1373  * @tc.desc: verify that can Batchly operate on transaction
1374  * @tc.type: FUNC
1375  * @tc.require: SR000DORPP
1376  * @tc.author: fengxiaoyun
1377  */
1378 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction010, TestSize.Level1)
1379 {
1380     /**
1381      * @tc.steps: step1. start transaction
1382      * @tc.expected: step1. start success.
1383      */
1384     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1385 
1386     std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1387     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1388     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, SIXTY_RECORDS, {'a'}, {'m'});
1389     GenerateAppointPrefixAndSizeRecords(entries2, entrySize, THIRTYTWO_RECORDS, {'b'}, {'n'});
1390     /**
1391      * @tc.steps: step2. PutBatch 60 records entries1 to DB.
1392      * @tc.expected: step2. PutBatch successfully
1393      */
1394     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1395     /**
1396      * @tc.steps: step3. PutBatch 32 records entries2 to DB.
1397      * @tc.expected: step3. PutBatch successfully
1398      */
1399     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1400 
1401     std::vector<DistributedDB::Key> keys;
1402     for (auto const &entry : entries2) {
1403         keys.push_back(entry.key);
1404     }
1405     /**
1406      * @tc.steps: step4. DeleteBatch entries2 from DB.
1407      * @tc.expected: step4. DeleteBatch successfully
1408      */
1409     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1410 
1411     /**
1412      * @tc.steps: step5. Delete entries1[1] and entries1[2] from DB solely.
1413      * @tc.expected: step5. Delete successfully
1414      */
1415     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[1].key), OK);
1416     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[2].key), OK);
1417     /**
1418      * @tc.steps: step6. insert entries1[1] to DB solely.
1419      * @tc.expected: step6. insert successfully
1420      */
1421     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, entries1[1].value), OK);
1422     /**
1423      * @tc.steps: step7. update value of entries1[1] to v2.
1424      * @tc.expected: step7. update successfully
1425      */
1426     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, VALUE_2), OK);
1427     /**
1428      * @tc.steps: step8. commit and check the records in DB.
1429      * @tc.expected: step8. commit success and can only find entries1 in db can't find entries2
1430      *    and the value of entries1[1] is v2, and also can't find entries[2].
1431      */
1432     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1433 
1434     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1435     for (auto const & entry : entries2) {
__anon7be1a5110502(const DistributedDB::Entry &entry_) 1436         auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1437             return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1438         });
1439         EXPECT_EQ(it, entriesGot.end());
1440     }
1441     for (auto const & entry : entries1) {
1442         if (!CompareVector(entry.key, entries1[1].key) && !CompareVector(entry.key, entries1[2].key)) {
__anon7be1a5110602(const DistributedDB::Entry &entry_) 1443             auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1444                 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1445             });
1446             EXPECT_NE(it, entriesGot.end());
1447         } else if (CompareVector(entry.key, entries1[1].key)) {
__anon7be1a5110702(const DistributedDB::Entry &entry_) 1448             auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1449                 return (CompareVector(entry.key, entry_.key) && CompareVector(VALUE_2, entry_.value));
1450             });
1451             EXPECT_NE(it, entriesGot.end());
1452         } else {
__anon7be1a5110802(const DistributedDB::Entry &entry_) 1453             auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1454                 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1455             });
1456             EXPECT_EQ(it, entriesGot.end());
1457         }
1458     }
1459 }
1460 
1461 /**
1462  * @tc.name: Transaction 011
1463  * @tc.desc: verify that when rollback after logs of CRUD operate, the operate will not be effective.
1464  * @tc.type: FUNC
1465  * @tc.require: SR000DORPP
1466  * @tc.author: fengxiaoyun
1467  */
1468 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction011, TestSize.Level1)
1469 {
1470     std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1471     entries1 = {ENTRY_1, ENTRY_2, ENTRY_3};
1472     entries2 = {ENTRY_4, ENTRY_5};
1473     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1474     /**
1475      * @tc.steps: step1. start transaction
1476      * @tc.expected: step1. start success.
1477      */
1478     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1479 
1480     entries1[0] = {KEY_1, VALUE_EMPTY};
1481     entries1[1] = {KEY_2, VALUE_EMPTY};
1482     entries1[2] = {KEY_3, VALUE_EMPTY};
1483     /**
1484      * @tc.steps: step2. PutBatch entries1 to DB.
1485      * @tc.expected: step2. PutBatch successfully
1486      */
1487     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1488     /**
1489      * @tc.steps: step3. PutBatch entries2 to DB.
1490      * @tc.expected: step3. PutBatch successfully
1491      */
1492     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1493 
1494     std::vector<DistributedDB::Key> keys = {KEY_4, KEY_5};
1495     /**
1496      * @tc.steps: step4. DeleteBatch entries2 from DB.
1497      * @tc.expected: step4. DeleteBatch successfully
1498      */
1499     EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1500 
1501     /**
1502      * @tc.steps: step5. Delete entries1[1] and entries1[2] from DB solely.
1503      * @tc.expected: step5. Delete successfully
1504      */
1505     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[1].key), OK);
1506     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[2].key), OK);
1507     /**
1508      * @tc.steps: step6. insert entries1[1] to DB solely.
1509      * @tc.expected: step6. insert successfully
1510      */
1511     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, entries1[1].value), OK);
1512     /**
1513      * @tc.steps: step7. update value of entries1[1] to v2.
1514      * @tc.expected: step7. update successfully
1515      */
1516     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, VALUE_2), OK);
1517     /**
1518      * @tc.steps: step8. insert the records that key = null.
1519      * @tc.expected: step8. insert failed and returned DB_ERROR
1520      */
1521     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_EMPTY, VALUE_9), INVALID_ARGS);
1522 
1523     /**
1524      * @tc.steps: step9. rollback and use GetEntries interface to check.
1525      * @tc.expected: step9. rollback success and the data in db is entries1
1526      */
1527     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1528     entries1 = {ENTRY_1, ENTRY_2, ENTRY_3};
1529     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1530     EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1531 }
1532 
1533 /**
1534  * @tc.name: Transaction 012
1535  * @tc.desc: verify that exception operate can't effect transaction and commit.
1536  * @tc.type: FUNC
1537  * @tc.require: SR000DORPP
1538  * @tc.author: fengxiaoyun
1539  */
1540 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction012, TestSize.Level1)
1541 {
1542     std::vector<DistributedDB::Entry> entries, entriesGot;
1543     entries = {ENTRY_1, ENTRY_2};
1544     /**
1545      * @tc.steps: step1. start transaction
1546      * @tc.expected: step1. start success.
1547      */
1548     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1549     /**
1550      * @tc.steps: step2. PutBatch entries to DB.
1551      * @tc.expected: step2. PutBatch successfully
1552      */
1553     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1554     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1555     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1556     /**
1557      * @tc.steps: step3. Put the record that key = empty to DB.
1558      * @tc.expected: step3. Put failed and returned error
1559      */
1560     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_EMPTY, VALUE_10), INVALID_ARGS);
1561 
1562     /**
1563      * @tc.steps: step4. commit and use GetEntries interface to check.
1564      * @tc.expected: step4. commit success and the data in db is entries1
1565      */
1566     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1567 
1568     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1569     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1570 }
1571 
1572 /**
1573  * @tc.name: Transaction 013
1574  * @tc.desc: verify that one transaction can only operate less than MAX_BATCH_SIZE records, or it will return
1575  *     OVER_MAX_LIMITS.
1576  * @tc.type: FUNC
1577  * @tc.require: SR000DORPP
1578  * @tc.author: fengxiaoyun
1579  */
1580 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction013, TestSize.Level1)
1581 {
1582     std::vector<DistributedDB::Entry> entries, entriesGot;
1583     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1584     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
1585     /**
1586      * @tc.steps: step1. start transaction
1587      * @tc.expected: step1. start success.
1588      */
1589     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1590     /**
1591      * @tc.steps: step2. PutBatch entries which contains 128 records to DB.
1592      * @tc.expected: step2. PutBatch successfully
1593      */
1594     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1595     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1596     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1597     /**
1598      * @tc.steps: step3. Put (k1, v1) to DB.
1599      * @tc.expected: step3. Put failed and returned OVER_MAX_LIMITS
1600      */
1601     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OVER_MAX_LIMITS);
1602     /**
1603      * @tc.steps: step3. Delete (k1, v1) from DB.
1604      * @tc.expected: step3. Delete failed and returned OVER_MAX_LIMITS
1605      */
1606     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OVER_MAX_LIMITS);
1607 
1608     /**
1609      * @tc.steps: step4. commit and use GetEntries interface to check.
1610      * @tc.expected: step4. commit success and the data in db is entries1
1611      */
1612     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1613 
1614     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1615     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1616 }
1617 
1618 /**
1619  * @tc.name: Transaction 014
1620  * @tc.desc: verify that one transaction can only operate less than MAX_BATCH_SIZE records, or it will return
1621  *     OVER_MAX_LIMITS and if one operate return OVER_MAX_LIMITS, only this operate is invalid.
1622  * @tc.type: FUNC
1623  * @tc.require: SR000DORPP
1624  * @tc.author: fengxiaoyun
1625  */
1626 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction014, TestSize.Level1)
1627 {
1628     std::vector<DistributedDB::Entry> entries1, entries2, entries3, entries4, entriesGot;
1629     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1630     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, ONE_HUNDRED_RECORDS, {'a'}, {'m'});
1631     GenerateAppointPrefixAndSizeRecords(entries2, entrySize, RECORDS_SMALL_CNT, {'b'}, {'n'});
1632     GenerateAppointPrefixAndSizeRecords(entries3, entrySize, THIRTYTWO_RECORDS, {'c'}, {'o'});
1633     GenerateAppointPrefixAndSizeRecords(entries4, entrySize, TWENTYFIVE_RECORDS, {'d'}, {'p'});
1634     /**
1635      * @tc.steps: step1. start transaction
1636      * @tc.expected: step1. start success.
1637      */
1638     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1639     /**
1640      * @tc.steps: step2. PutBatch 100 records to DB.
1641      * @tc.expected: step2. PutBatch successfully
1642      */
1643     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1644     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1645     EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1646     /**
1647      * @tc.steps: step3. PutBatch 2 records to DB.
1648      * @tc.expected: step3. PutBatch successfully
1649      */
1650     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1651     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1652     EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1653     /**
1654      * @tc.steps: step4. Delete nonexistent key1 from DB.
1655      * @tc.expected: step4. Delete return OK, and the number of records is still counted in the transaction.
1656      */
1657     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1658     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1659     EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1660     const int nonexistentRecordNum = 1;
1661     /**
1662      * @tc.steps: step5. PutBatch 32 records to DB.
1663      * @tc.expected: step5. PutBatch failed and OVER_MAX_LIMITS
1664      */
1665     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries3), OVER_MAX_LIMITS);
1666     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1667     EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1668     /**
1669      * @tc.steps: step5. PutBatch 26 records to DB.
1670      * @tc.expected: step5. PutBatch succeed.
1671      */
1672     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries4), OK);
1673     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1674     EXPECT_TRUE(entriesGot.size() == (BATCH_RECORDS - nonexistentRecordNum));
1675 
1676     /**
1677      * @tc.steps: step4. commit and use GetEntries interface to check.
1678      * @tc.expected: step4. commit success and the data in db is entries1
1679      */
1680     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1681 
1682     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1683     for (auto const & entry : entries4) {
__anon7be1a5110902(const DistributedDB::Entry &entry_) 1684         auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1685             return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1686         });
1687         EXPECT_NE(it, entriesGot.end());
1688     }
1689     for (auto const & entry : entries1) {
__anon7be1a5110a02(const DistributedDB::Entry &entry_) 1690         auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1691             return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1692         });
1693         EXPECT_NE(it, entriesGot.end());
1694     }
1695     for (auto const & entry : entries2) {
__anon7be1a5110b02(const DistributedDB::Entry &entry_) 1696         auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1697             return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1698         });
1699         EXPECT_NE(it, entriesGot.end());
1700     }
1701 }
1702 
1703 int g_threadComplete = 0;
1704 bool g_threadSuccessFlag = true;
ConsistencyCheck()1705 void ConsistencyCheck()
1706 {
1707     KvStoreNbDelegate *delegate = nullptr;
1708     KvStoreDelegateManager *delegateManager = nullptr;
1709     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1710     ASSERT_TRUE(delegateManager != nullptr && delegate != nullptr) << "ConsistencyCheck get delegate failed.";
1711 
1712     while (g_threadComplete < static_cast<int>(SINGLE_THREAD_NUM)) {
1713         std::vector<DistributedDB::Entry> entriesGot;
1714         EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate, KEY_EMPTY, entriesGot), OK);
1715         if (GetIntValue(entriesGot[0].value) + GetIntValue(entriesGot[1].value) != VALUE_SUM) {
1716             g_threadSuccessFlag = false;
1717             MST_LOG("ConsistencyCheck get sum %d,%d.", GetIntValue(entriesGot[0].value),
1718                 GetIntValue(entriesGot[1].value));
1719             break;
1720         }
1721         std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1722     }
1723 
1724     EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1725     delegate = nullptr;
1726     delete delegateManager;
1727     delegateManager = nullptr;
1728 }
1729 
ConsistencyChange(Key keyLeft,Value valueLeft,Key keyRight,Value valueRight)1730 void ConsistencyChange(Key keyLeft, Value valueLeft, Key keyRight, Value valueRight)
1731 {
1732     // wait 100 ms, let ConsistencyCheck begin
1733     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(HUNDRED_MILLI_SECONDS));
1734     KvStoreNbDelegate *delegate = nullptr;
1735     KvStoreDelegateManager *delegateManager = nullptr;
1736     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1737     if (delegate == nullptr) {
1738         MST_LOG("ConsistencyChange get delegate failed.");
1739         g_threadComplete++;
1740         g_threadSuccessFlag = false;
1741         return;
1742     }
1743 
1744     MST_LOG("ConsistencyChange put %d,%d.", GetIntValue(valueLeft), GetIntValue(valueRight));
1745     DBStatus statusStart = delegate->StartTransaction();
1746     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1747 
1748     DBStatus statusPutLeft = delegate->Put(keyLeft, valueLeft);
1749     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1750 
1751     DBStatus statusPutRight = delegate->Put(keyRight, valueRight);
1752     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1753 
1754     DBStatus statusCommit = delegate->Commit();
1755     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1756     g_threadComplete++;
1757 
1758     if (statusStart != DBStatus::OK || statusPutLeft != DBStatus::OK ||
1759         statusPutRight != DBStatus::OK || statusCommit != DBStatus::OK) {
1760         MST_LOG("ConsistencyChange put failed.");
1761         g_threadComplete++;
1762         g_threadSuccessFlag = false;
1763         return;
1764     }
1765     ConsistencyCheck();
1766 
1767     EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1768     delegate = nullptr;
1769     delete delegateManager;
1770     delegateManager = nullptr;
1771 }
1772 
1773 /**
1774  * @tc.name: Transaction 015
1775  * @tc.desc: Verify that transaction singlely action's consistency.
1776  * @tc.type: FUNC
1777  * @tc.require: SR000DORPP
1778  * @tc.author: fengxiaoyun
1779  */
1780 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction015, TestSize.Level2)
1781 {
1782     int baseNumer = VALUE_FIVE_HUNDRED;
1783     Value base = GetValueWithInt(baseNumer);
1784 
1785     Entry entry1, entry2;
1786     vector<Entry> entries1;
1787     entry1 = {KEY_CONS_1, base};
1788     entry2 = {KEY_CONS_2, base};
1789     entries1.push_back(entry1);
1790     entries1.push_back(entry2);
1791     /**
1792      * @tc.steps: step1. putBatch (k1=cons1,v1=500) (k2=cons2,v2=500) to construct exist v1+v2=1000.
1793      * @tc.expected: step1. putBatch successfully.
1794      */
1795     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1796     Value value;
1797     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, entry1.key, value), OK);
1798     EXPECT_EQ(value, base);
1799     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, entry2.key, value), OK);
1800     EXPECT_EQ(value, base);
1801 
1802     /**
1803      * @tc.steps: step2. start a thread to update k1=cons1's value to 400, update k2=cons2's value to 600.
1804      * @tc.expected: step2. run thread successfully and k1+k2=1000 is true in sub thread.
1805      */
1806     std::vector<std::thread> suThreads;
1807     suThreads.push_back(std::thread(ConsistencyChange, KEY_CONS_1, GetValueWithInt(VALUE_CHANGE1_FIRST),
1808         KEY_CONS_2, GetValueWithInt(VALUE_CHANGE1_SECOND)));
1809     /**
1810      * @tc.steps: step3. start another thread to update k1=cons1's value to 700, update k2=cons2's value to 300.
1811      * @tc.expected: step3. run thread successfully and k1+k2=1000 is true in sub thread.
1812      */
1813     suThreads.push_back(std::thread(ConsistencyChange, KEY_CONS_1, GetValueWithInt(VALUE_CHANGE2_FIRST),
1814         KEY_CONS_2, GetValueWithInt(VALUE_CHANGE2_SECOND)));
1815     for (auto& th : suThreads) {
1816         th.detach();
1817     }
1818 
1819     ConsistencyCheck();
1820     std::this_thread::sleep_for(std::chrono::seconds(FIVE_SECONDS));
1821     ASSERT_TRUE(g_threadSuccessFlag);
1822 }
1823 
1824 bool g_batchThreadSuccess = true;
1825 bool g_batchThreadComplete = false;
ConsistencyBatchCheck(vector<Key> * keyLeft,vector<Key> * keyRight,int times)1826 void ConsistencyBatchCheck(vector<Key> *keyLeft, vector<Key> *keyRight, int times)
1827 {
1828     std::this_thread::sleep_for(std::chrono::seconds(TWO_SECONDS));
1829     KvStoreNbDelegate *delegate = nullptr;
1830     KvStoreDelegateManager *delegateManager = nullptr;
1831     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1832     ASSERT_TRUE(delegateManager != nullptr && delegate != nullptr) << "ConsistencyBatchCheck get delegate failed.";
1833 
1834     Value leftValue, rightValue;
1835     while (!g_batchThreadComplete) {
1836         for (int i = 0; i < times; ++i) {
1837             leftValue.clear();
1838             rightValue.clear();
1839             EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyLeft->at(i), leftValue), OK);
1840             EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyRight->at(i), rightValue), OK);
1841 
1842             if (GetIntValue(leftValue) + GetIntValue(rightValue) != (times + 1)) {
1843                 g_batchThreadSuccess = false;
1844                 MST_LOG("ConsistencyBatchCheck get leftvalue: %d, rightvalue: %d, failed.",
1845                     GetIntValue(leftValue), GetIntValue(rightValue));
1846                 break;
1847             }
1848         }
1849     }
1850 
1851     MST_LOG("g_batchThreadComplete.");
1852     EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1853     delegate = nullptr;
1854     delete delegateManager;
1855     delegateManager = nullptr;
1856 }
1857 
ConsistencyCheckTransaction(vector<Entry> & entries1,vector<Entry> & entries2)1858 void ConsistencyCheckTransaction(vector<Entry> &entries1, vector<Entry> &entries2)
1859 {
1860     Key query1 = {'k', 'a'};
1861     Key query2 = {'k', 'b'};
1862     /**
1863      * @tc.steps: step1. putBatch 20 items of (keys1,values1)(key2,values2).
1864      * @tc.expected: step1. putBatch successfully to construct exist data in db.
1865      */
1866     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1867     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1868 
1869     /**
1870      * @tc.steps: step3. start transaction.
1871      * @tc.expected: step3. start transaction successfully.
1872      */
1873     EXPECT_TRUE(g_nbBatchCrudDelegate->StartTransaction() == DBStatus::OK);
1874     /**
1875      * @tc.steps: step4. getEntries with keyprefix before updateBatch.
1876      * @tc.expected: step4. getEntries successfully that the size of them is 20.
1877      */
1878     vector<Entry> values1, values2;
1879     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query1, values1), OK);
1880     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query2, values2), OK);
1881     EXPECT_EQ(static_cast<int>(values1.size()), TWENTY_RECORDS);
1882     EXPECT_EQ(static_cast<int>(values2.size()), TWENTY_RECORDS);
1883     /**
1884      * @tc.steps: step5. updateBatch values1+1 of keys1, values2-1 of keys2.
1885      * @tc.expected: step5. updateBatch successfully.
1886      */
1887     for (int i = 0; i != TWENTY_RECORDS; ++i) {
1888         entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + 1);
1889         entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - 1);
1890     }
1891     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1892     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1893     /**
1894      * @tc.steps: step6. updateBatch values1+2 of keys1, values2-2 of keys2.
1895      * @tc.expected: step6. updateBatch successfully.
1896      */
1897     for (int i = 0; i != TWENTY_RECORDS; ++i) {
1898         entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + EVEN_NUMBER);
1899         entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - EVEN_NUMBER);
1900     }
1901     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1902     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1903     /**
1904      * @tc.steps: step7. commit transaction and stop child thread.
1905      * @tc.expected: step7. operate successfully.
1906      */
1907     EXPECT_TRUE(g_nbBatchCrudDelegate->Commit() == DBStatus::OK);
1908     MST_LOG("commit over!");
1909 }
1910 
1911 /**
1912  * @tc.name: Transaction 016
1913  * @tc.desc: Verify that transaction batch action's consistency.
1914  * @tc.type: FUNC
1915  * @tc.require: SR000DORPP
1916  * @tc.author: fengxiaoyun
1917  */
1918 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction016, TestSize.Level2)
1919 {
1920     uint8_t left = 'a';
1921     uint8_t right = 'b';
1922     vector<Entry> entries1;
1923     vector<Key> allKeys1;
1924     GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys1, entries1);
1925     vector<Entry> entries2;
1926     vector<Key> allKeys2;
1927     GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys2, entries2);
1928     for (int i = 0; i < TWENTY_RECORDS; ++i) {
1929         entries1[i].key.insert(entries1[i].key.begin() + 1, left);
1930         entries2[i].key.insert(entries2[i].key.begin() + 1, right);
1931         allKeys1[i].insert(allKeys1[i].begin() + 1, left);
1932         allKeys2[i].insert(allKeys2[i].begin() + 1, right);
1933         entries1[i].value = GetValueWithInt(i);
1934         entries2[i].value = GetValueWithInt(TWENTY_RECORDS - i);
1935     }
1936 
1937     /**
1938      * @tc.steps: step2. start child thread to query keys1 and keys2 continuously.
1939      * @tc.expected: step2. if keys1.size()+keys2.size()!=20 print info.
1940      */
1941     thread readThread = thread(ConsistencyBatchCheck, &allKeys1, &allKeys2, TWENTY_RECORDS);
1942     readThread.detach();
1943     ConsistencyCheckTransaction(entries1, entries2);
1944     g_batchThreadComplete = true;
1945 
1946     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1947     ASSERT_TRUE(g_batchThreadSuccess);
1948 }
1949 
TransactionSubThread1()1950 void TransactionSubThread1()
1951 {
1952     /**
1953      * @tc.steps: step2. start transanction and update v1 of k1 to v2, and put (k3, v3) to STORE_ID_1.
1954      * @tc.expected: step2. start and put successfully.
1955      */
1956     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1957     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1958     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
1959 }
TransactionSubThread2()1960 void TransactionSubThread2()
1961 {
1962     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1963 
1964     /**
1965      * @tc.steps: step3. update v2 of k2 to v3, and delete k1, and Get (k3, v3) from DB
1966      * @tc.expected: step3. put and delete successfully, but can't find (k3, v3) in DB.
1967      */
1968     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
1969     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1970     Value value;
1971     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), OK);
1972     EXPECT_EQ(value, VALUE_3);
1973 }
TransactionSubThread3()1974 void TransactionSubThread3()
1975 {
1976     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1977 
1978     /**
1979      * @tc.steps: step4. rollback
1980      * @tc.expected: step4. rollback successfully.
1981      */
1982     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1983 }
1984 /**
1985  * @tc.name: Transaction 017
1986  * @tc.desc: Verify that one delegate start transaction, and then the different delegate of the same storeid are
1987  *     already in the same transaction.
1988  * @tc.type: FUNC
1989  * @tc.require: SR000DORPP
1990  * @tc.author: fengxiaoyun
1991  */
1992 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction017, TestSize.Level2)
1993 {
1994     /**
1995      * @tc.steps: step1. put (k1, v1), (k2, v2) to STORE_ID_1.
1996      * @tc.expected: step1. put successfully.
1997      */
1998     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1999     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2000 
2001     std::thread thread1, thread2, thread3;
2002     thread1 = std::thread(TransactionSubThread1);
2003     thread1.join();
2004     thread2 = std::thread(TransactionSubThread2);
2005     thread2.join();
2006     thread3 = std::thread(TransactionSubThread3);
2007     thread3.join();
2008 
2009     /**
2010      * @tc.steps: step5. check the records in db
2011      * @tc.expected: step5. the value of k1 is v1, the value of k2 is v2, but (k3, v3) is not in db.
2012      */
2013     Value value;
2014     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2015     EXPECT_EQ(value, VALUE_1);
2016     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
2017     EXPECT_EQ(value, VALUE_2);
2018     value.clear();
2019     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), NOT_FOUND);
2020     EXPECT_TRUE(value.empty());
2021 }
2022 
2023 /**
2024  * @tc.name: Transaction 018
2025  * @tc.desc: Verify that transaction has persistence.
2026  * @tc.type: FUNC
2027  * @tc.require: SR000DORPP
2028  * @tc.author: fengxiaoyun
2029  */
2030 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction018, TestSize.Level1)
2031 {
2032     KvStoreNbDelegate *delegate1 = nullptr;
2033     KvStoreDelegateManager *manager1 = nullptr;
2034     delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2035     ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2036     /**
2037      * @tc.steps: step1. start transaction.
2038      * @tc.expected: step1. start transactionsuccessfully.
2039      */
2040     EXPECT_EQ(delegate1->StartTransaction(), OK);
2041     /**
2042      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2043      * @tc.expected: step2. putBatch successfully.
2044      */
2045     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2046     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2047 
2048     /**
2049      * @tc.steps: step3. commit the transaction.
2050      * @tc.expected: step3. commit successfully.
2051      */
2052     EXPECT_EQ(delegate1->Commit(), OK);
2053     /**
2054      * @tc.steps: step4. close the db but don't delete the STORE, and then create a new delegate of the same STORE
2055      * @tc.expected: step4. close and create successfully.
2056      */
2057     EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2058     delegate1 = nullptr;
2059     delete manager1;
2060     manager1 = nullptr;
2061 
2062     KvStoreNbDelegate *delegate2 = nullptr;
2063     KvStoreDelegateManager *manager2 = nullptr;
2064     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2065     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2066     /**
2067      * @tc.steps: step5. check the data in db STORE.
2068      * @tc.expected: step5. the entries is still in the db.
2069      */
2070     std::vector<DistributedDB::Entry> entriesGot;
2071     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), OK);
2072     EXPECT_TRUE(CompareEntriesVector(entriesGot, entries));
2073 
2074     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2075     delegate2 = nullptr;
2076     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2077     delete manager2;
2078     manager2 = nullptr;
2079 }
2080 
2081 /**
2082  * @tc.name: Transaction 019
2083  * @tc.desc: Verify that close the delegate before transaction commit, and it will cause the transaction rollback.
2084  * @tc.type: FUNC
2085  * @tc.require: SR000DORPP
2086  * @tc.author: fengxiaoyun
2087  */
2088 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction019, TestSize.Level1)
2089 {
2090     KvStoreNbDelegate *delegate1 = nullptr;
2091     KvStoreDelegateManager *manager1 = nullptr;
2092     delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2093     ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2094     /**
2095      * @tc.steps: step1. start transaction.
2096      * @tc.expected: step1. start transactionsuccessfully.
2097      */
2098     EXPECT_EQ(delegate1->StartTransaction(), OK);
2099     /**
2100      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2101      * @tc.expected: step2. putBatch successfully.
2102      */
2103     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2104     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2105 
2106     /**
2107      * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2108      * @tc.expected: step3. close successfully.
2109      */
2110     EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2111     delegate1 = nullptr;
2112     delete manager1;
2113     manager1 = nullptr;
2114 
2115     /**
2116      * @tc.steps: step4. create a new delegate of the same STORE
2117      * @tc.expected: step4. start successfully.
2118      */
2119     KvStoreNbDelegate *delegate2 = nullptr;
2120     KvStoreDelegateManager *manager2 = nullptr;
2121     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2122     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2123     /**
2124      * @tc.steps: step5. commit the transaction on the new deleate, and check the data in db STORE.
2125      * @tc.expected: step5. commit failed and the entries is NULL.
2126      */
2127     EXPECT_EQ(delegate2->Commit(), DB_ERROR);
2128     std::vector<DistributedDB::Entry> entriesGot;
2129     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), NOT_FOUND);
2130     EXPECT_TRUE(entriesGot.empty());
2131 
2132     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2133     delegate2 = nullptr;
2134     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2135     delete manager2;
2136     manager2 = nullptr;
2137 }
2138 
2139 /**
2140  * @tc.name: Transaction 020
2141  * @tc.desc: Verify that close the delegate before transaction rollback, and it will cause the transaction rollback.
2142  * @tc.type: FUNC
2143  * @tc.require: SR000DORPP
2144  * @tc.author: fengxiaoyun
2145  */
2146 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction020, TestSize.Level1)
2147 {
2148     /**
2149      * @tc.steps: step1. start transaction.
2150      * @tc.expected: step1. start transactionsuccessfully.
2151      */
2152     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2153     /**
2154      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2155      * @tc.expected: step2. putBatch successfully.
2156      */
2157     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2158     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2159 
2160     /**
2161      * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2162      * @tc.expected: step3. close successfully.
2163      */
2164     EXPECT_EQ(g_manager->CloseKvStore(g_nbBatchCrudDelegate), OK);
2165     g_nbBatchCrudDelegate = nullptr;
2166     delete g_manager;
2167     g_manager = nullptr;
2168 
2169     /**
2170      * @tc.steps: step4. create a new delegate of the same STORE
2171      * @tc.expected: step4. start successfully.
2172      */
2173     g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
2174     ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr) << "get g_nbBatchCrudDelegate failed.";
2175     /**
2176      * @tc.steps: step5. Rollback the transaction on the new deleate, and check the data in db STORE.
2177      * @tc.expected: step5. Rollback failed and the entries is NULL.
2178      */
2179     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
2180     std::vector<DistributedDB::Entry> entriesGot;
2181     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), NOT_FOUND);
2182     EXPECT_TRUE(entriesGot.empty());
2183 }
2184 
2185 /**
2186  * @tc.name: Transaction 021
2187  * @tc.desc: Verify that it will failed to delete the store before transaction rollback.
2188  * @tc.type: FUNC
2189  * @tc.require: SR000DORPP
2190  * @tc.author: fengxiaoyun
2191  */
2192 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction021, TestSize.Level1)
2193 {
2194     /**
2195      * @tc.steps: step1. start transaction.
2196      * @tc.expected: step1. start transactionsuccessfully.
2197      */
2198     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2199     /**
2200      * @tc.steps: step2. put (k1, v1) to STORE_ID_1.
2201      * @tc.expected: step2. put successfully.
2202      */
2203     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2204     DistributedDB::Value value;
2205     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2206     EXPECT_EQ(value, VALUE_1);
2207 
2208     /**
2209      * @tc.steps: step3. delete the STORE without committing or rollback
2210      *     the transaction
2211      * @tc.expected: step3. delete failed and returned BUSY.
2212      */
2213     EXPECT_EQ(g_manager->DeleteKvStore(STORE_ID_1), BUSY);
2214 
2215     /**
2216      * @tc.steps: step4. Rollback and check the db
2217      * @tc.expected: step4. Rollback failed.
2218      */
2219     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
2220 
2221     /**
2222      * @tc.steps: step5. check the data in db STORE.
2223      * @tc.expected: step5. the DB is empty.
2224      */
2225     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
2226 }
2227 
2228 /**
2229  * @tc.name: Transaction 022
2230  * @tc.desc: Verify transaction can't support resultSet, rekey, Import, Export, RegisterObserver interface.
2231  * @tc.type: FUNC
2232  * @tc.require: SR000DORPP
2233  * @tc.author: fengxiaoyun
2234  */
2235 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction022, TestSize.Level3)
2236 {
2237     KvStoreResultSet *resultSet1 = nullptr;
2238     KvStoreResultSet *resultSet2 = nullptr;
2239     EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet1), OK);
2240     KvStoreObserverImpl observer1, observer2;
2241     vector<Entry> entries, entriesGot;
2242     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
2243     GenerateAppointPrefixAndSizeRecords(entries, entrySize, TEN_RECORDS);
2244 
2245     DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer1);
2246     EXPECT_EQ(status, OK);
2247 
2248     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "import";
2249     const std::string importFilePath = importPath + "/importbkpDB.bin";
2250     SetDir(importPath);
2251     EXPECT_EQ(g_nbBatchCrudDelegate->Export(importFilePath, NULL_PASSWD), OK);
2252 
2253     /**
2254      * @tc.steps: step1. start transaction.
2255      * @tc.expected: step1. start transaction successfully.
2256      */
2257     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2258     /**
2259      * @tc.steps: step2. putBatch entries to db.
2260      * @tc.expected: step2. putBatch successfully.
2261      */
2262     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2263     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2264     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2265 
2266     vector<DistributedDB::Entry> observerCheckEntry;
2267     observerCheckEntry.clear();
2268     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::INSERT_LIST, observerCheckEntry));
2269 
2270     /**
2271      * @tc.steps: step3. call rekey, import, export interface
2272      * @tc.expected: step3. all call failed and returned BUSY.
2273      */
2274     EXPECT_EQ(g_nbBatchCrudDelegate->Rekey(g_passwd1), BUSY);
2275 
2276     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
2277     const std::string filePath = exportPath + "/bkpDB.bin";
2278     SetDir(exportPath);
2279     EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), BUSY);
2280     EXPECT_EQ(g_nbBatchCrudDelegate->Import(importFilePath, NULL_PASSWD), BUSY);
2281     /**
2282      * @tc.steps: step4. call GetEntries to obtain resultSet2, and register observer2.
2283      * @tc.expected: step4. all call failed and returned BUSY.
2284      */
2285     EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet2), BUSY);
2286     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer2), BUSY);
2287 
2288     /**
2289      * @tc.steps: step5. close resultSet1 and resultSet2, UnRegister observer1 and observer2.
2290      * @tc.expected: step5. close resultSet1 succeed and resultSet2 failed,
2291      *     UnRegister observer1 succeed and observer2 failed.
2292      */
2293     EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet1), OK);
2294     EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet2), INVALID_ARGS);
2295     EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer1), OK);
2296     EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer2), NOT_FOUND);
2297     /**
2298      * @tc.steps: step6. commit the transaction and check the data in db.
2299      * @tc.expected: step6. commit succeed and can find entries in DB.
2300      */
2301     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2302     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2303     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2304 }
2305 
2306 /**
2307  * @tc.name: TransactionObserver 001
2308  * @tc.desc: Verify transaction can and only trigger observer one time.
2309  * @tc.type: FUNC
2310  * @tc.require: SR000DORPP
2311  * @tc.author: fengxiaoyun
2312  */
2313 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver001, TestSize.Level1)
2314 {
2315     /**
2316      * @tc.steps: step1. Register observer1 and observer2 of k1 and k2 separately and start the transaction.
2317      * @tc.expected: step1. Register start transaction successfully.
2318      */
2319     KvStoreObserverImpl observer1, observer2;
2320     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2321     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2322     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2323 
2324     /**
2325      * @tc.steps: step2. put (k1, v1), (k3, v3) and check the callback of the observer.
2326      * @tc.expected: step2. put successfully and both of the observers can't receive the callback.
2327      */
2328     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2329     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2330     vector<DistributedDB::Entry> observerCheckList;
2331     observerCheckList.clear();
2332     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2333     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2334     /**
2335      * @tc.steps: step3. update (k1, v1) to (k1, v2) and delete (k3, v3) and check the observers.
2336      * @tc.expected: step3. update and delete successfully both of the observers can't receive the callback either.
2337      */
2338     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
2339     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2340     observerCheckList.clear();
2341     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2342     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2343 
2344     /**
2345      * @tc.steps: step4. commit the transaction and check the observers.
2346      * @tc.expected: step4. commit succeed and observer1 was triggered one time and observer2 wasn't triggered.
2347      */
2348     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2349     observerCheckList.clear();
2350     observerCheckList.push_back(ENTRY_1_2);
2351     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2352     observerCheckList.clear();
2353     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2354 }
2355 
2356 /**
2357  * @tc.name: TransactionObserver 002
2358  * @tc.desc: Verify transaction can and only trigger observer one time.
2359  * @tc.type: FUNC
2360  * @tc.require: SR000DORPP
2361  * @tc.author: fengxiaoyun
2362  */
2363 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver002, TestSize.Level1)
2364 {
2365     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2366     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2367     /**
2368      * @tc.steps: step1. Register observer1, observer2, observer3, observer4 of k1, k2, k3
2369      *     and k4 separately and start the transaction.
2370      * @tc.expected: step1. Register and start transaction successfully.
2371      */
2372     KvStoreObserverImpl observer1, observer2, observer3, observer4;
2373     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2374     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2375     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
2376     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_4, OBSERVER_CHANGES_NATIVE, &observer4), OK);
2377     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2378 
2379     /**
2380      * @tc.steps: step2. put (k1, v1), (k2, v2), (k3, v3) and (k4, v4) and then delete (k1, v1) and (k4, v4).
2381      * @tc.expected: step2. put and delete successfully.
2382      */
2383     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2384     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2385     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_4, VALUE_4), OK);
2386 
2387     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2388     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_4), OK);
2389 
2390     /**
2391      * @tc.steps: step3. commit the transaction and check the observers.
2392      * @tc.expected: step3. commit succeed and observer1 received one delete notify, observer2 received one update
2393      *     notify, observer3 received one insert notify, and observer4 didn't receive any notify.
2394      */
2395     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2396     vector<DistributedDB::Entry> observerCheckList;
2397     observerCheckList.clear();
2398     observerCheckList.push_back(ENTRY_1);
2399     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2400     observerCheckList.clear();
2401     observerCheckList.push_back(ENTRY_2_3);
2402     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2403     observerCheckList.clear();
2404     observerCheckList.push_back(ENTRY_3);
2405     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2406     observerCheckList.clear();
2407     EXPECT_TRUE(VerifyObserverResult(observer4, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2408 }
2409 
2410 /**
2411  * @tc.name: TransactionObserver 003
2412  * @tc.desc: Verify the different observer of same key will all be triggered after transaction
2413  *     and will only be trigger once.
2414  * @tc.type: FUNC
2415  * @tc.require: SR000DORPP
2416  * @tc.author: fengxiaoyun
2417  */
2418 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver003, TestSize.Level1)
2419 {
2420     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2421     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2422     /**
2423      * @tc.steps: step1. Register 8 observers of all keys.
2424      * @tc.expected: step1. Register successfully.
2425      */
2426     std::vector<KvStoreObserverImpl> observers(OBSERVER_NUM);
2427     for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2428         EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observers[cnt]), OK);
2429     }
2430 
2431     /**
2432      * @tc.steps: step2. start the transaction and putBatch (k3, v3), (k4, v4), ..., (k8, v8) to db.
2433      * @tc.expected: step2. start transaction and putBatch successfully.
2434      */
2435     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2436     std::vector<DistributedDB::Entry> entries = {ENTRY_3, ENTRY_4, ENTRY_5, ENTRY_6, ENTRY_7, ENTRY_8, ENTRY_9};
2437     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2438 
2439     /**
2440      * @tc.steps: step3. delete (k1, v1), (k3, v3) and (k9, v9), update (k2, v2) to (k2, v3).
2441      * @tc.expected: step3. operate succeed.
2442      */
2443     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2444     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2445     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2446     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_9), OK);
2447 
2448     /**
2449      * @tc.steps: step3. commit the transaction and check the observers.
2450      * @tc.expected: step3. commit succeed and all of the observers received one insert notify, callbacklist of which
2451      *    contains (k4, v4), ..., (k8, v8), all observer received one update notify, callbacklist of which contains
2452      *    (k2, v3), all observers received one insert notify, callback of which contains (k1, v1), (k3, v3), (k9, v9).
2453      */
2454     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2455     vector<DistributedDB::Entry> observerCheckList;
2456     for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2457         observerCheckList.clear();
2458         observerCheckList.push_back(ENTRY_4);
2459         observerCheckList.push_back(ENTRY_5);
2460         observerCheckList.push_back(ENTRY_6);
2461         observerCheckList.push_back(ENTRY_7);
2462         observerCheckList.push_back(ENTRY_8);
2463         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2464         observerCheckList.clear();
2465         observerCheckList.push_back(ENTRY_2_3);
2466         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2467         observerCheckList.clear();
2468         observerCheckList.push_back(ENTRY_1);
2469         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2470     }
2471 }
2472 }
2473