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