• 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     GenerateRecords(BATCH_RECORDS + 1, DEFAULT_START, allKeys, entriesBatch);
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;
__anon07ddae6e0102() 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);
__anon07ddae6e0202null439     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;
__anon07ddae6e0302() 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);
__anon07ddae6e0402null489     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) {
__anon07ddae6e0502(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)) {
__anon07ddae6e0602(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)) {
__anon07ddae6e0702(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 {
__anon07ddae6e0802(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, VALUE_ONE_HUNDRED_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, VALUE_ONE_HUNDRED_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) {
__anon07ddae6e0902(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) {
__anon07ddae6e0a02(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) {
__anon07ddae6e0b02(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, rightValue;
1837     while (!g_batchThreadComplete) {
1838         for (int i = 0; i < times; ++i) {
1839             leftValue.clear();
1840             rightValue.clear();
1841             EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyLeft->at(i), leftValue), OK);
1842             EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyRight->at(i), rightValue), OK);
1843 
1844             if (GetIntValue(leftValue) + GetIntValue(rightValue) != (times + 1)) {
1845                 g_batchThreadSuccess = false;
1846                 MST_LOG("ConsistencyBatchCheck get leftvalue: %d, rightvalue: %d, failed.",
1847                     GetIntValue(leftValue), GetIntValue(rightValue));
1848                 break;
1849             }
1850         }
1851     }
1852 
1853     MST_LOG("g_batchThreadComplete.");
1854     EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1855     delegate = nullptr;
1856     delete delegateManager;
1857     delegateManager = nullptr;
1858 }
1859 
ConsistencyCheckTransaction(vector<Entry> & entries1,vector<Entry> & entries2)1860 void ConsistencyCheckTransaction(vector<Entry> &entries1, vector<Entry> &entries2)
1861 {
1862     Key query1 = {'k', 'a'};
1863     Key query2 = {'k', 'b'};
1864     /**
1865      * @tc.steps: step1. putBatch 20 items of (keys1,values1)(key2,values2).
1866      * @tc.expected: step1. putBatch successfully to construct exist data in db.
1867      */
1868     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1869     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1870 
1871     /**
1872      * @tc.steps: step3. start transaction.
1873      * @tc.expected: step3. start transaction successfully.
1874      */
1875     EXPECT_TRUE(g_nbBatchCrudDelegate->StartTransaction() == DBStatus::OK);
1876     /**
1877      * @tc.steps: step4. getEntries with keyprefix before updateBatch.
1878      * @tc.expected: step4. getEntries successfully that the size of them is 20.
1879      */
1880     vector<Entry> values1, values2;
1881     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query1, values1), OK);
1882     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query2, values2), OK);
1883     EXPECT_EQ(static_cast<int>(values1.size()), TWENTY_RECORDS);
1884     EXPECT_EQ(static_cast<int>(values2.size()), TWENTY_RECORDS);
1885     /**
1886      * @tc.steps: step5. updateBatch values1+1 of keys1, values2-1 of keys2.
1887      * @tc.expected: step5. updateBatch successfully.
1888      */
1889     for (int i = 0; i != TWENTY_RECORDS; ++i) {
1890         entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + 1);
1891         entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - 1);
1892     }
1893     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1894     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1895     /**
1896      * @tc.steps: step6. updateBatch values1+2 of keys1, values2-2 of keys2.
1897      * @tc.expected: step6. updateBatch successfully.
1898      */
1899     for (int i = 0; i != TWENTY_RECORDS; ++i) {
1900         entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + EVEN_NUMBER);
1901         entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - EVEN_NUMBER);
1902     }
1903     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1904     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1905     /**
1906      * @tc.steps: step7. commit transaction and stop child thread.
1907      * @tc.expected: step7. operate successfully.
1908      */
1909     EXPECT_TRUE(g_nbBatchCrudDelegate->Commit() == DBStatus::OK);
1910     MST_LOG("commit over!");
1911 }
1912 
1913 /**
1914  * @tc.name: Transaction 016
1915  * @tc.desc: Verify that transaction batch action's consistency.
1916  * @tc.type: FUNC
1917  * @tc.require: SR000DORPP
1918  * @tc.author: fengxiaoyun
1919  */
1920 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction016, TestSize.Level2)
1921 {
1922     uint8_t left = 'a';
1923     uint8_t right = 'b';
1924     vector<Entry> entries1;
1925     vector<Key> allKeys1;
1926     GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys1, entries1);
1927     vector<Entry> entries2;
1928     vector<Key> allKeys2;
1929     GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys2, entries2);
1930     for (int i = 0; i < TWENTY_RECORDS; ++i) {
1931         entries1[i].key.insert(entries1[i].key.begin() + 1, left);
1932         entries2[i].key.insert(entries2[i].key.begin() + 1, right);
1933         allKeys1[i].insert(allKeys1[i].begin() + 1, left);
1934         allKeys2[i].insert(allKeys2[i].begin() + 1, right);
1935         entries1[i].value = GetValueWithInt(i);
1936         entries2[i].value = GetValueWithInt(TWENTY_RECORDS - i);
1937     }
1938 
1939     /**
1940      * @tc.steps: step2. start child thread to query keys1 and keys2 continuously.
1941      * @tc.expected: step2. if keys1.size()+keys2.size()!=20 print info.
1942      */
1943     thread readThread = thread(ConsistencyBatchCheck, &allKeys1, &allKeys2, TWENTY_RECORDS);
1944     readThread.detach();
1945     ConsistencyCheckTransaction(entries1, entries2);
1946     g_batchThreadComplete = true;
1947 
1948     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1949     ASSERT_TRUE(g_batchThreadSuccess);
1950 }
1951 
TransactionSubThread1()1952 void TransactionSubThread1()
1953 {
1954     /**
1955      * @tc.steps: step2. start transanction and update v1 of k1 to v2, and put (k3, v3) to STORE_ID_1.
1956      * @tc.expected: step2. start and put successfully.
1957      */
1958     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1959     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1960     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
1961 }
TransactionSubThread2()1962 void TransactionSubThread2()
1963 {
1964     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1965 
1966     /**
1967      * @tc.steps: step3. update v2 of k2 to v3, and delete k1, and Get (k3, v3) from DB
1968      * @tc.expected: step3. put and delete successfully, but can't find (k3, v3) in DB.
1969      */
1970     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
1971     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1972     Value value;
1973     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), OK);
1974     EXPECT_EQ(value, VALUE_3);
1975 }
TransactionSubThread3()1976 void TransactionSubThread3()
1977 {
1978     std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1979 
1980     /**
1981      * @tc.steps: step4. rollback
1982      * @tc.expected: step4. rollback successfully.
1983      */
1984     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1985 }
1986 /**
1987  * @tc.name: Transaction 017
1988  * @tc.desc: Verify that one delegate start transaction, and then the different delegate of the same storeid are
1989  *     already in the same transaction.
1990  * @tc.type: FUNC
1991  * @tc.require: SR000DORPP
1992  * @tc.author: fengxiaoyun
1993  */
1994 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction017, TestSize.Level2)
1995 {
1996     /**
1997      * @tc.steps: step1. put (k1, v1), (k2, v2) to STORE_ID_1.
1998      * @tc.expected: step1. put successfully.
1999      */
2000     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2001     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2002 
2003     std::thread thread1, thread2, thread3;
2004     thread1 = std::thread(TransactionSubThread1);
2005     thread1.join();
2006     thread2 = std::thread(TransactionSubThread2);
2007     thread2.join();
2008     thread3 = std::thread(TransactionSubThread3);
2009     thread3.join();
2010 
2011     /**
2012      * @tc.steps: step5. check the records in db
2013      * @tc.expected: step5. the value of k1 is v1, the value of k2 is v2, but (k3, v3) is not in db.
2014      */
2015     Value value;
2016     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2017     EXPECT_EQ(value, VALUE_1);
2018     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
2019     EXPECT_EQ(value, VALUE_2);
2020     value.clear();
2021     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), NOT_FOUND);
2022     EXPECT_TRUE(value.empty());
2023 }
2024 
2025 /**
2026  * @tc.name: Transaction 018
2027  * @tc.desc: Verify that transaction has persistence.
2028  * @tc.type: FUNC
2029  * @tc.require: SR000DORPP
2030  * @tc.author: fengxiaoyun
2031  */
2032 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction018, TestSize.Level1)
2033 {
2034     KvStoreNbDelegate *delegate1 = nullptr;
2035     KvStoreDelegateManager *manager1 = nullptr;
2036     delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2037     ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2038     /**
2039      * @tc.steps: step1. start transaction.
2040      * @tc.expected: step1. start transactionsuccessfully.
2041      */
2042     EXPECT_EQ(delegate1->StartTransaction(), OK);
2043     /**
2044      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2045      * @tc.expected: step2. putBatch successfully.
2046      */
2047     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2048     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2049 
2050     /**
2051      * @tc.steps: step3. commit the transaction.
2052      * @tc.expected: step3. commit successfully.
2053      */
2054     EXPECT_EQ(delegate1->Commit(), OK);
2055     /**
2056      * @tc.steps: step4. close the db but don't delete the STORE, and then create a new delegate of the same STORE
2057      * @tc.expected: step4. close and create successfully.
2058      */
2059     EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2060     delegate1 = nullptr;
2061     delete manager1;
2062     manager1 = nullptr;
2063 
2064     KvStoreNbDelegate *delegate2 = nullptr;
2065     KvStoreDelegateManager *manager2 = nullptr;
2066     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2067     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2068     /**
2069      * @tc.steps: step5. check the data in db STORE.
2070      * @tc.expected: step5. the entries is still in the db.
2071      */
2072     std::vector<DistributedDB::Entry> entriesGot;
2073     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), OK);
2074     EXPECT_TRUE(CompareEntriesVector(entriesGot, entries));
2075 
2076     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2077     delegate2 = nullptr;
2078     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2079     delete manager2;
2080     manager2 = nullptr;
2081 }
2082 
2083 /**
2084  * @tc.name: Transaction 019
2085  * @tc.desc: Verify that close the delegate before transaction commit, and it will cause the transaction rollback.
2086  * @tc.type: FUNC
2087  * @tc.require: SR000DORPP
2088  * @tc.author: fengxiaoyun
2089  */
2090 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction019, TestSize.Level1)
2091 {
2092     KvStoreNbDelegate *delegate1 = nullptr;
2093     KvStoreDelegateManager *manager1 = nullptr;
2094     delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2095     ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2096     /**
2097      * @tc.steps: step1. start transaction.
2098      * @tc.expected: step1. start transactionsuccessfully.
2099      */
2100     EXPECT_EQ(delegate1->StartTransaction(), OK);
2101     /**
2102      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2103      * @tc.expected: step2. putBatch successfully.
2104      */
2105     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2106     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2107 
2108     /**
2109      * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2110      * @tc.expected: step3. close successfully.
2111      */
2112     EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2113     delegate1 = nullptr;
2114     delete manager1;
2115     manager1 = nullptr;
2116 
2117     /**
2118      * @tc.steps: step4. create a new delegate of the same STORE
2119      * @tc.expected: step4. start successfully.
2120      */
2121     KvStoreNbDelegate *delegate2 = nullptr;
2122     KvStoreDelegateManager *manager2 = nullptr;
2123     delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2124     ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2125     /**
2126      * @tc.steps: step5. commit the transaction on the new deleate, and check the data in db STORE.
2127      * @tc.expected: step5. commit failed and the entries is NULL.
2128      */
2129     EXPECT_EQ(delegate2->Commit(), DB_ERROR);
2130     std::vector<DistributedDB::Entry> entriesGot;
2131     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), NOT_FOUND);
2132     EXPECT_TRUE(entriesGot.empty());
2133 
2134     EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2135     delegate2 = nullptr;
2136     EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2137     delete manager2;
2138     manager2 = nullptr;
2139 }
2140 
2141 /**
2142  * @tc.name: Transaction 020
2143  * @tc.desc: Verify that close the delegate before transaction rollback, and it will cause the transaction rollback.
2144  * @tc.type: FUNC
2145  * @tc.require: SR000DORPP
2146  * @tc.author: fengxiaoyun
2147  */
2148 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction020, TestSize.Level1)
2149 {
2150     /**
2151      * @tc.steps: step1. start transaction.
2152      * @tc.expected: step1. start transactionsuccessfully.
2153      */
2154     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2155     /**
2156      * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2157      * @tc.expected: step2. putBatch successfully.
2158      */
2159     std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2160     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2161 
2162     /**
2163      * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2164      * @tc.expected: step3. close successfully.
2165      */
2166     EXPECT_EQ(g_manager->CloseKvStore(g_nbBatchCrudDelegate), OK);
2167     g_nbBatchCrudDelegate = nullptr;
2168     delete g_manager;
2169     g_manager = nullptr;
2170 
2171     /**
2172      * @tc.steps: step4. create a new delegate of the same STORE
2173      * @tc.expected: step4. start successfully.
2174      */
2175     g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
2176     ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr) << "get g_nbBatchCrudDelegate failed.";
2177     /**
2178      * @tc.steps: step5. Rollback the transaction on the new deleate, and check the data in db STORE.
2179      * @tc.expected: step5. Rollback failed and the entries is NULL.
2180      */
2181     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
2182     std::vector<DistributedDB::Entry> entriesGot;
2183     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), NOT_FOUND);
2184     EXPECT_TRUE(entriesGot.empty());
2185 }
2186 
2187 /**
2188  * @tc.name: Transaction 021
2189  * @tc.desc: Verify that it will failed to delete the store before transaction rollback.
2190  * @tc.type: FUNC
2191  * @tc.require: SR000DORPP
2192  * @tc.author: fengxiaoyun
2193  */
2194 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction021, TestSize.Level1)
2195 {
2196     /**
2197      * @tc.steps: step1. start transaction.
2198      * @tc.expected: step1. start transactionsuccessfully.
2199      */
2200     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2201     /**
2202      * @tc.steps: step2. put (k1, v1) to STORE_ID_1.
2203      * @tc.expected: step2. put successfully.
2204      */
2205     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2206     DistributedDB::Value value;
2207     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2208     EXPECT_EQ(value, VALUE_1);
2209 
2210     /**
2211      * @tc.steps: step3. delete the STORE without committing or rollback
2212      *     the transaction
2213      * @tc.expected: step3. delete failed and returned BUSY.
2214      */
2215     EXPECT_EQ(g_manager->DeleteKvStore(STORE_ID_1), BUSY);
2216 
2217     /**
2218      * @tc.steps: step4. Rollback and check the db
2219      * @tc.expected: step4. Rollback failed.
2220      */
2221     EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
2222 
2223     /**
2224      * @tc.steps: step5. check the data in db STORE.
2225      * @tc.expected: step5. the DB is empty.
2226      */
2227     EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
2228 }
2229 
2230 /**
2231  * @tc.name: Transaction 022
2232  * @tc.desc: Verify transaction can't support resultSet, rekey, Import, Export, RegisterObserver interface.
2233  * @tc.type: FUNC
2234  * @tc.require: SR000DORPP
2235  * @tc.author: fengxiaoyun
2236  */
2237 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction022, TestSize.Level3)
2238 {
2239     KvStoreResultSet *resultSet1 = nullptr;
2240     KvStoreResultSet *resultSet2 = nullptr;
2241     EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet1), OK);
2242     KvStoreObserverImpl observer1, observer2;
2243     vector<Entry> entries, entriesGot;
2244     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
2245     GenerateAppointPrefixAndSizeRecords(entries, entrySize, TEN_RECORDS);
2246 
2247     DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer1);
2248     EXPECT_EQ(status, OK);
2249 
2250     const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "import";
2251     const std::string importFilePath = importPath + "/importbkpDB.bin";
2252     SetDir(importPath);
2253     EXPECT_EQ(g_nbBatchCrudDelegate->Export(importFilePath, NULL_PASSWD), OK);
2254 
2255     /**
2256      * @tc.steps: step1. start transaction.
2257      * @tc.expected: step1. start transaction successfully.
2258      */
2259     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2260     /**
2261      * @tc.steps: step2. putBatch entries to db.
2262      * @tc.expected: step2. putBatch successfully.
2263      */
2264     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2265     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2266     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2267 
2268     vector<DistributedDB::Entry> observerCheckEntry;
2269     observerCheckEntry.clear();
2270     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::INSERT_LIST, observerCheckEntry));
2271 
2272     /**
2273      * @tc.steps: step3. call rekey, import, export interface
2274      * @tc.expected: step3. all call failed and returned BUSY.
2275      */
2276     EXPECT_EQ(g_nbBatchCrudDelegate->Rekey(g_passwd1), BUSY);
2277 
2278     const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
2279     const std::string filePath = exportPath + "/bkpDB.bin";
2280     SetDir(exportPath);
2281     EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), BUSY);
2282     EXPECT_EQ(g_nbBatchCrudDelegate->Import(importFilePath, NULL_PASSWD), BUSY);
2283     /**
2284      * @tc.steps: step4. call GetEntries to obtain resultSet2, and register observer2.
2285      * @tc.expected: step4. all call failed and returned BUSY.
2286      */
2287     EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet2), BUSY);
2288     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer2), BUSY);
2289 
2290     /**
2291      * @tc.steps: step5. close resultSet1 and resultSet2, UnRegister observer1 and observer2.
2292      * @tc.expected: step5. close resultSet1 succeed and resultSet2 failed,
2293      *     UnRegister observer1 succeed and observer2 failed.
2294      */
2295     EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet1), OK);
2296     EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet2), INVALID_ARGS);
2297     EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer1), OK);
2298     EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer2), NOT_FOUND);
2299     /**
2300      * @tc.steps: step6. commit the transaction and check the data in db.
2301      * @tc.expected: step6. commit succeed and can find entries in DB.
2302      */
2303     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2304     EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2305     EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2306 }
2307 
2308 /**
2309  * @tc.name: TransactionObserver 001
2310  * @tc.desc: Verify transaction can and only trigger observer one time.
2311  * @tc.type: FUNC
2312  * @tc.require: SR000DORPP
2313  * @tc.author: fengxiaoyun
2314  */
2315 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver001, TestSize.Level1)
2316 {
2317     /**
2318      * @tc.steps: step1. Register observer1 and observer2 of k1 and k2 separately and start the transaction.
2319      * @tc.expected: step1. Register start transaction successfully.
2320      */
2321     KvStoreObserverImpl observer1, observer2;
2322     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2323     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2324     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2325 
2326     /**
2327      * @tc.steps: step2. put (k1, v1), (k3, v3) and check the callback of the observer.
2328      * @tc.expected: step2. put successfully and both of the observers can't receive the callback.
2329      */
2330     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2331     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2332     vector<DistributedDB::Entry> observerCheckList;
2333     observerCheckList.clear();
2334     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2335     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2336     /**
2337      * @tc.steps: step3. update (k1, v1) to (k1, v2) and delete (k3, v3) and check the observers.
2338      * @tc.expected: step3. update and delete successfully both of the observers can't receive the callback either.
2339      */
2340     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
2341     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2342     observerCheckList.clear();
2343     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2344     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2345 
2346     /**
2347      * @tc.steps: step4. commit the transaction and check the observers.
2348      * @tc.expected: step4. commit succeed and observer1 was triggered one time and observer2 wasn't triggered.
2349      */
2350     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2351     observerCheckList.clear();
2352     observerCheckList.push_back(ENTRY_1_2);
2353     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2354     observerCheckList.clear();
2355     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2356 }
2357 
2358 /**
2359  * @tc.name: TransactionObserver 002
2360  * @tc.desc: Verify transaction can and only trigger observer one time.
2361  * @tc.type: FUNC
2362  * @tc.require: SR000DORPP
2363  * @tc.author: fengxiaoyun
2364  */
2365 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver002, TestSize.Level1)
2366 {
2367     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2368     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2369     /**
2370      * @tc.steps: step1. Register observer1, observer2, observer3, observer4 of k1, k2, k3
2371      *     and k4 separately and start the transaction.
2372      * @tc.expected: step1. Register and start transaction successfully.
2373      */
2374     KvStoreObserverImpl observer1, observer2, observer3, observer4;
2375     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2376     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2377     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
2378     EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_4, OBSERVER_CHANGES_NATIVE, &observer4), OK);
2379     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2380 
2381     /**
2382      * @tc.steps: step2. put (k1, v1), (k2, v2), (k3, v3) and (k4, v4) and then delete (k1, v1) and (k4, v4).
2383      * @tc.expected: step2. put and delete successfully.
2384      */
2385     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2386     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2387     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_4, VALUE_4), OK);
2388 
2389     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2390     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_4), OK);
2391 
2392     /**
2393      * @tc.steps: step3. commit the transaction and check the observers.
2394      * @tc.expected: step3. commit succeed and observer1 received one delete notify, observer2 received one update
2395      *     notify, observer3 received one insert notify, and observer4 didn't receive any notify.
2396      */
2397     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2398     vector<DistributedDB::Entry> observerCheckList;
2399     observerCheckList.clear();
2400     observerCheckList.push_back(ENTRY_1);
2401     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2402     observerCheckList.clear();
2403     observerCheckList.push_back(ENTRY_2_3);
2404     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2405     observerCheckList.clear();
2406     observerCheckList.push_back(ENTRY_3);
2407     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2408     observerCheckList.clear();
2409     EXPECT_TRUE(VerifyObserverResult(observer4, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2410 }
2411 
2412 /**
2413  * @tc.name: TransactionObserver 003
2414  * @tc.desc: Verify the different observer of same key will all be triggered after transaction
2415  *     and will only be trigger once.
2416  * @tc.type: FUNC
2417  * @tc.require: SR000DORPP
2418  * @tc.author: fengxiaoyun
2419  */
2420 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver003, TestSize.Level1)
2421 {
2422     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2423     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2424     /**
2425      * @tc.steps: step1. Register 8 observers of all keys.
2426      * @tc.expected: step1. Register successfully.
2427      */
2428     std::vector<KvStoreObserverImpl> observers(OBSERVER_NUM);
2429     for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2430         EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observers[cnt]), OK);
2431     }
2432 
2433     /**
2434      * @tc.steps: step2. start the transaction and putBatch (ENTRY_3), (ENTRY_4), ..., (ENTRY_8) to db.
2435      * @tc.expected: step2. start transaction and putBatch successfully.
2436      */
2437     EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2438     std::vector<DistributedDB::Entry> entries = {ENTRY_3, ENTRY_4, ENTRY_5, ENTRY_6, ENTRY_7, ENTRY_8, ENTRY_9};
2439     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2440 
2441     /**
2442      * @tc.steps: step3. delete (k1, v1), (k3, v3) and (k9, v9), update (k2, v2) to (k2, v3).
2443      * @tc.expected: step3. operate succeed.
2444      */
2445     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2446     EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2447     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2448     EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_9), OK);
2449 
2450     /**
2451      * @tc.steps: step3. commit the transaction and check the observers.
2452      * @tc.expected: step3. commit succeed and all of the observers received one insert notify, callbacklist of which
2453      *    contains (ENTRY_4), ..., (ENTRY_8), all observer received one update notify, callbacklist of which contains
2454      *    (k2, v3), all observers received one insert notify, callback of which contains (k1, v1), (k3, v3), (k9, v9).
2455      */
2456     EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2457     vector<DistributedDB::Entry> observerCheckList;
2458     for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2459         observerCheckList.clear();
2460         observerCheckList.push_back(ENTRY_4);
2461         observerCheckList.push_back(ENTRY_5);
2462         observerCheckList.push_back(ENTRY_6);
2463         observerCheckList.push_back(ENTRY_7);
2464         observerCheckList.push_back(ENTRY_8);
2465         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2466         observerCheckList.clear();
2467         observerCheckList.push_back(ENTRY_2_3);
2468         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2469         observerCheckList.clear();
2470         observerCheckList.push_back(ENTRY_1);
2471         EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2472     }
2473 }
2474 
2475 /**
2476  * @tc.name: GetKeysPressure 001
2477  * @tc.desc: Concurrent GetEntries and GetKeys.
2478  * @tc.type: FUNC
2479  * @tc.require: SR000DORPP
2480  * @tc.author: xuhongkang
2481  */
2482 #ifdef GETKEYS_PRESSURE001
2483 HWTEST_F(DistributeddbNbBatchCrudTest, GetKeysPressure001, TestSize.Level3)
2484 {
2485     DBStatus status, status1, status2;
2486     std::vector<Key> allKeysKA, allKeysKB, expectKeyResult;
2487     std::vector<Entry> entriesA, entriesB, entriesBatch;
2488     DistributedDB::Value longValue1;
2489     DistributedDB::Key ka = {'k', 'a'};
2490     DistributedDB::Key kb = {'k', 'b'};
2491     longValue1.assign(ONE_K_LONG_STRING, (uint8_t)'v');
2492     GenerateRecords(TEN_THOUSAND_RECORDS, DEFAULT_START, allKeysKA, entriesA, ka);
2493     GenerateRecords(FIVE_THOUSANDS_RECORDS, DEFAULT_START, allKeysKB, entriesB, kb);
2494 
2495     entriesBatch.insert(entriesBatch.end(), entriesA.begin(), entriesA.end());
2496     entriesBatch.insert(entriesBatch.end(), entriesB.begin(), entriesB.end());
2497     for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++)
2498     {
2499         if (index < TEN_THOUSAND_RECORDS) {
2500             entriesA[index].value = longValue1;
2501         }
2502         entriesBatch[index].value = longValue1;
2503         status = g_nbBatchCrudDelegate->Put(entriesBatch[index].key, entriesBatch[index].value);
2504         EXPECT_EQ(status, OK);
2505     }
2506     std::vector<Key> keyResult;
2507     std::vector<Entry> valueResult;
__anon07ddae6e0c02() 2508     std::thread sub = std::thread([&status1, &ka, &valueResult]() {
2509         status1 = DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, ka, valueResult);
2510     });
2511     status2 = DistributedDBNbTestTools::GetKeys(*g_nbBatchCrudDelegate, KEY_EMPTY, keyResult);
2512     sub.join();
2513     EXPECT_EQ(status1, OK);
2514     EXPECT_EQ(status2, OK);
2515     expectKeyResult.insert(expectKeyResult.end(), allKeysKA.begin(), allKeysKA.end());
2516     expectKeyResult.insert(expectKeyResult.end(), allKeysKB.begin(), allKeysKB.end());
2517     sort(keyResult.begin(), keyResult.end());
2518     sort(expectKeyResult.begin(), expectKeyResult.end());
2519     for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++) {
2520         string actResult(keyResult[index].begin(), keyResult[index].end());
2521         string expectResult(expectKeyResult[index].begin(), expectKeyResult[index].end());
2522         bool result = (actResult == expectResult);
2523         EXPECT_EQ(result, true);
2524     }
2525     EXPECT_TRUE(CompareEntriesVector(valueResult, entriesA));
2526 }
2527 #endif // GETKEYS_PRESSURE001
2528 }
2529