• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <gtest/gtest.h>
16 #include <string>
17 
18 #include "distributeddb_nb_test_tools.h"
19 #include "distributeddb_data_generator.h"
20 #include "process_communicator_test_stub.h"
21 #include "distributeddb_schema_test_tools.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 DistributeddbNbLocalBatchCrud {
32 KvStoreNbDelegate *g_nbLocalBatchDelegate = nullptr;
33 KvStoreDelegateManager *g_manager = nullptr;
34 
35 class DistributeddbNbLocalBatchCrudTest : public testing::Test {
36 public:
37     static void SetUpTestCase(void);
38     static void TearDownTestCase(void);
39     void SetUp();
40     void TearDown();
41 private:
42 };
43 
SetUpTestCase(void)44 void DistributeddbNbLocalBatchCrudTest::SetUpTestCase(void)
45 {
46     KvStoreDelegateManager manager(APP_ID_1, USER_ID_1);
47     manager.SetProcessLabel("MST", "GetDevicesID");
48     manager.SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
49 }
50 
TearDownTestCase(void)51 void DistributeddbNbLocalBatchCrudTest::TearDownTestCase(void)
52 {
53 }
54 
SetUp(void)55 void DistributeddbNbLocalBatchCrudTest::SetUp(void)
56 {
57     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
58 
59     UnitTest *test = UnitTest::GetInstance();
60     ASSERT_NE(test, nullptr);
61     const TestInfo *testinfo = test->current_test_info();
62     ASSERT_NE(testinfo, nullptr);
63     string testCaseName = string(testinfo->name());
64     MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
65 
66     g_nbLocalBatchDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
67     ASSERT_TRUE(g_nbLocalBatchDelegate != nullptr);
68     ASSERT_TRUE(g_manager != nullptr);
69 }
70 
TearDown(void)71 void DistributeddbNbLocalBatchCrudTest::TearDown(void)
72 {
73     MST_LOG("TearDownTestCase after case.");
74     ASSERT_NE(g_manager, nullptr);
75     EXPECT_TRUE(EndCaseDeleteDB(g_manager, g_nbLocalBatchDelegate, STORE_ID_1, g_option.isMemoryDb));
76     RemoveDir(DistributedDBConstant::NB_DIRECTOR);
77 }
78 
79 /**
80  * @tc.name: SimpleData 001
81  * @tc.desc: Verify that single-ver db can support PutLocalBatch to insert <keys,values> and update records db file,
82  *    and DeleteLocalBatch from db.
83  * @tc.type: FUNC
84  * @tc.require: SR000EPA24
85  * @tc.author: fengxiaoyun
86  */
87 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData001, TestSize.Level1)
88 {
89     vector<Entry> entries1, entries2, gotValues;
90     entries1.push_back(ENTRY_1);
91     entries1.push_back(ENTRY_2);
92     entries1.push_back(ENTRY_3);
93     entries1.push_back(ENTRY_4);
94     entries2.push_back(ENTRY_1_2);
95     entries2.push_back(ENTRY_3_4);
96 
97     /**
98      * @tc.steps: step1. call PutLocalBatch interface to Put (k1, v1), (k2, v2), (k3, v3), (k4, v4) to DB
99      *    and check the data in DB.
100      * @tc.expected: step1. PutLocalBatch successfully and there are (k1, v1), (k2, v2), (k3, v3), (k4, v4) in DB.
101      */
102     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
103     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
104     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
105 
106     /**
107      * @tc.steps: step2. call PutLocalBatch interface to update (k1, v1), (k3, v3) to (k1, v2), (k3, v4)
108      *    and check the data in DB.
109      * @tc.expected: step2. PutLocalBatch successfully and there are (k1, v2), (k2, v2), (k3, v4), (k4, v4) in DB.
110      */
111     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
112     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
113     entries1[0] = ENTRY_1_2;
114     entries1[2] = ENTRY_3_4;
115     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
116 
117     /**
118      * @tc.steps: step3. call DeleteLocalBatch interface to delete (k3, v4), (k4, v4) from db and check the data in DB.
119      * @tc.expected: step3. DeleteLocalBatch successfully and there are only (k1, v2), (k2, v2) in DB.
120      */
121     vector<Key> keys;
122     keys.push_back(ENTRY_3.key);
123     keys.push_back(ENTRY_4.key);
124     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
125     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
126     entries1.pop_back();
127     entries1.pop_back();
128     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
129 }
130 
131 /**
132  * @tc.name: SimpleData 002
133  * @tc.desc: Verify that single-ver db can support PutLocalBatch records that value of which is null, but can't support
134  *    the value of which bigger than 4M.
135  * @tc.type: FUNC
136  * @tc.require: SR000EPA24
137  * @tc.author: fengxiaoyun
138  */
139 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData002, TestSize.Level1)
140 {
141     vector<Entry> entries1, entries2, gotValues;
142     entries1.push_back(ENTRY_1);
143     entries1.push_back({.key = KEY_2, .value = {}});
144 
145     /**
146      * @tc.steps: step1. call PutLocalBatch interface to Put (k1, v1), (k2, null) to DB and check the data in DB.
147      * @tc.expected: step1. PutLocalBatch successfully and there are (k1, v1), (k2, null) in DB.
148      */
149     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
150     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
151     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
152 
153     /**
154      * @tc.steps: step2. call PutLocalBatch interface put (k3, v3), (k3, v4) to db, size of v4 is 4M + 1
155      *    and then check the data in DB.
156      * @tc.expected: step2. PutLocalBatch failed and there are only (k1, v1), (k2, null) in DB.
157      */
158     entries2.push_back(ENTRY_3);
159     Entry entry;
160     EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING + 1};
161     unsigned long keyNo = 1;
162     GenerateRandRecord(entry, entrySize, keyNo);
163     entries2.push_back(entry);
164     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), INVALID_ARGS);
165 
166     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
167     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
168 }
169 
170 /**
171  * @tc.name: SimpleData 003
172  * @tc.desc: Verify that PutLocalBatch can't operate records key of which is null or key is bigger than 1k.
173  * @tc.type: FUNC
174  * @tc.require: SR000EPA24
175  * @tc.author: fengxiaoyun
176  */
177 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData003, TestSize.Level1)
178 {
179     vector<Entry> entries1, entries2, gotValues;
180     entries1.push_back(ENTRY_1);
181     entries1.push_back({.key = {}, .value = VALUE_2});
182 
183     /**
184      * @tc.steps: step1. call PutLocalBatch interface to Put (k1, v1), (null, v2) to DB.
185      * @tc.expected: step1. PutLocalBatch failed.
186      */
187     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), INVALID_ARGS);
188 
189     /**
190      * @tc.steps: step2. call PutLocalBatch interface put (k3, v3), (k4, v4) to db, size of k4 is 1K + 1
191      *    and then check the data in DB.
192      * @tc.expected: step2. PutLocalBatch failed and there are only (k1, v1), (k2, null) in DB.
193      */
194     entries2.push_back(ENTRY_3);
195     Entry entry;
196     EntrySize entrySize = {KEY_ONE_K_BYTE + 1, FOUR_M_LONG_STRING};
197     unsigned long keyNo = 1;
198     GenerateRandRecord(entry, entrySize, keyNo);
199     entries2.push_back(entry);
200     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), INVALID_ARGS);
201 
202     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
203 }
204 
205 /**
206  * @tc.name: SimpleData 004
207  * @tc.desc: Verify that DeleteLocalBatch can't operate records key of which is null or key is bigger than 1k.
208  * @tc.type: FUNC
209  * @tc.require: SR000EPA24
210  * @tc.author: fengxiaoyun
211  */
212 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData004, TestSize.Level1)
213 {
214     /**
215      * @tc.steps: step1. call PutLocalBatch interface to Put (k1, v1), (k2, v2), (k3, v3), (k4, v4) to DB, and check
216      *    the data from.
217      * @tc.expected: step1. PutLocalBatch succeed and can find (k1, v1), (k2, v2), (k3, v3), (k4, v4) from db.
218      */
219     vector<Entry> entries1, entries2, gotValues;
220     entries1.push_back(ENTRY_1);
221     entries1.push_back(ENTRY_2);
222     entries1.push_back(ENTRY_3);
223     entries1.push_back(ENTRY_4);
224     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
225     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
226     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
227 
228     vector<Key> keys1, keys2;
229     keys1.push_back(ENTRY_1.key);
230     Key key(KEY_ONE_K_BYTE + 1, 'k');
231     keys1.push_back(key);
232 
233     /**
234      * @tc.steps: step2. call DeleteLocalBatch interface to Delete k1, k5 from DB, size of k5 is 1K + 1.
235      * @tc.expected: step2. DeleteLocalBatch failed and all the data is still in db.
236      */
237     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys1), INVALID_ARGS);
238     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
239     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
240 
241     /**
242      * @tc.steps: step3. call DeleteLocalBatch interface delete k2, k6 from db, size of k6 is null
243      *    and then check the data in DB.
244      * @tc.expected: step3. DeleteLocalBatch failed and all the data is still in db.
245      */
246     keys2.push_back(ENTRY_2.key);
247     keys2.push_back({});
248     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys2), INVALID_ARGS);
249     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
250     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
251 }
252 
253 /**
254  * @tc.name: SimpleData 005
255  * @tc.desc: Verify that DeleteLocalBatch can delete records that is not exist.
256  * @tc.type: FUNC
257  * @tc.require: SR000EPA24
258  * @tc.author: fengxiaoyun
259  */
260 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData005, TestSize.Level1)
261 {
262     /**
263      * @tc.steps: step1. call PutLocalBatch interface to Put (k1, v1), (k2, v2) to DB, and check the data in db.
264      * @tc.expected: step1. PutLocalBatch succeed and can find (k1, v1), (k2, v2) from db.
265      */
266     vector<Entry> entries1, entries2, gotValues;
267     entries1.push_back(ENTRY_1);
268     entries1.push_back(ENTRY_2);
269     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
270     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
271     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
272 
273     vector<Key> keys;
274     keys.push_back(KEY_1);
275     keys.push_back(KEY_2);
276     keys.push_back(KEY_3);
277 
278     /**
279      * @tc.steps: step2. call DeleteLocalBatch interface to Delete k1, k2, k3 from DB.
280      * @tc.expected: step2. DeleteLocalBatch succeed and can't find data in db.
281      */
282     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
283     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
284 
285     /**
286      * @tc.steps: step3. call DeleteLocalBatch interface again to Delete k1, k2, k3 from DB.
287      * @tc.expected: step3. DeleteLocalBatch succeed and can't find data in db.
288      */
289     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
290     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
291 }
292 
293 /**
294  * @tc.name: SimpleData 006
295  * @tc.desc: Verify that PutLocalBatch and DeleteLocalBatch can't operate 129 records one time.
296  * @tc.type: FUNC
297  * @tc.require: SR000EPA24
298  * @tc.author: fengxiaoyun
299  */
300 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData006, TestSize.Level1)
301 {
302     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_1, VALUE_1), OK);
303     /**
304      * @tc.steps: step1. call PutLocalBatch interface to insert 128 records to DB, and check the data from DB.
305      * @tc.expected: step1. PutLocalBatch succeed and can find 129 records in DB.
306      */
307     vector<Entry> entries1, entries2, gotValues;
308     vector<Key> allKeys1, allKeys2;
309     GenerateFixedRecords(entries1, allKeys1, BATCH_RECORDS, KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE);
310 
311     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
312     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
313     EXPECT_EQ(entries1.size() + 1, gotValues.size());
314 
315     /**
316      * @tc.steps: step2. call PutLocalBatch interface to insert 129 records to DB, and check the data from DB.
317      * @tc.expected: step2. PutLocalBatch failed and can only find 129 records in DB.
318      */
319     GenerateFixedRecords(entries2, allKeys2, BATCH_RECORDS + 1, KEY_EIGHT_BYTE, VALUE_ONE_HUNDRED_BYTE);
320     EXPECT_EQ(g_nbLocalBatchDelegate->PutLocalBatch(entries2), INVALID_ARGS);
321     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
322     EXPECT_EQ(entries1.size() + 1, gotValues.size());
323 
324     /**
325      * @tc.steps: step3. call DeleteLocalBatch interface to Delete 129 records from DB which is already in DB.
326      * @tc.expected: step3. DeleteLocalBatch failed and can still find the 129 records which was find upstairs in db.
327      */
328     allKeys1.push_back(KEY_1);
329     EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocalBatch(allKeys1), INVALID_ARGS);
330     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
331     EXPECT_EQ(entries1.size() + 1, gotValues.size());
332 }
333 
334 #ifndef LOW_LEVEL_MEM_DEV
335 /**
336  * @tc.name: SimpleData 007
337  * @tc.desc: Verify that rekey will return busy when it is PutLocalBatch-ing.
338  * @tc.type: FUNC
339  * @tc.require: SR000EPA24
340  * @tc.author: fengxiaoyun
341  */
342 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData007, TestSize.Level3)
343 {
344     /**
345      * @tc.steps: step1. start one new thread to use PutLocalBatch interface to insert 128 (1k, 4M) records to DB.
346      * @tc.expected: step1. PutLocalBatch succeed.
347      */
348     vector<Entry> entries;
349     EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING};
350     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
351 
352     std::condition_variable batchCondition;
353     std::mutex batchMtx;
354     bool putBatchFinish = false;
__anon9a11829b0102() 355     thread subThread([&]() {
356         DBStatus inserStatus = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries);
357         EXPECT_TRUE(inserStatus == OK || inserStatus == BUSY);
358         {
359             std::lock_guard<std::mutex> lock(batchMtx);
360             putBatchFinish = true;
361         }
362         batchCondition.notify_one();
363     });
364     subThread.detach();
365 
366     /**
367      * @tc.steps: step2. rekey the DB when it is PutLocalBatch-ing.
368      * @tc.expected: step2. rekey failed and it will return busy.
369      */
370     DistributedDB::CipherPassword passwd;
371     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_FIFTY_MS));
372     DBStatus rekeyStatus = g_nbLocalBatchDelegate->Rekey(passwd);
373     EXPECT_TRUE(rekeyStatus == BUSY || rekeyStatus == OK);
374 
375     std::unique_lock<std::mutex> lck(batchMtx);
__anon9a11829b0202null376     batchCondition.wait(lck, [&] { return putBatchFinish; });
377 }
378 
379 /**
380  * @tc.name: SimpleData 008
381  * @tc.desc: Verify that import will return busy when it is PutLocalBatch-ing.
382  * @tc.type: FUNC
383  * @tc.require: SR000EPA24
384  * @tc.author: fengxiaoyun
385  */
386 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData008, TestSize.Level3)
387 {
388     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_1), OK);
389 
390     std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
391     SetDir(exportPath);
392     std::string filePath = exportPath + "/bkpDB.bin";
393     EXPECT_TRUE(g_nbLocalBatchDelegate->Export(filePath, NULL_PASSWD) == OK);
394     /**
395      * @tc.steps: step1. call PutLocalBatch interface to insert 128 records to DB.
396      * @tc.expected: step1. PutLocalBatch succeed.
397      */
398     vector<Entry> entries;
399     EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING};
400     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
401 
402     std::condition_variable batchCondition;
403     std::mutex batchMtx;
404     bool putBatchFinish = false;
__anon9a11829b0302() 405     thread subThread([&]() {
406         DBStatus insertStatus = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries);
407         EXPECT_TRUE(insertStatus == OK || insertStatus == BUSY);
408         {
409             std::lock_guard<std::mutex> lock(batchMtx);
410             putBatchFinish = true;
411         }
412         batchCondition.notify_one();
413     });
414     subThread.detach();
415 
416     /**
417      * @tc.steps: step2. import the backup file of the db.
418      * @tc.expected: step2. import failed and return busy.
419      */
420     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_FIFTY_MS));
421     DBStatus importStatus = g_nbLocalBatchDelegate->Import(filePath, NULL_PASSWD);
422     EXPECT_TRUE(importStatus == BUSY || importStatus == OK);
423 
424     std::unique_lock<std::mutex> lck(batchMtx);
__anon9a11829b0402null425     batchCondition.wait(lck, [&] { return putBatchFinish; });
426 }
427 #endif
428 #ifndef OMIT_JSON
429 /**
430  * @tc.name: SimpleData 009
431  * @tc.desc: Verify that open the schema db use non-schema mode, it can open success on readOnly mode and can be CRUD.
432  * @tc.type: FUNC
433  * @tc.require: SR000EPA24
434  * @tc.author: fengxiaoyun
435  */
436 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData009, TestSize.Level1)
437 {
438     KvStoreNbDelegate *delegate = nullptr;
439     KvStoreDelegateManager *manager = nullptr;
440     Option option1 = g_option;
441     string schemaDefine = "{\"field0\":\"INTEGER,NOT NULL,DEFAULT 10\",\"field1\":[]}";
442     option1.schema = SpliceToSchema(VALID_VERSION_1, VALID_MODE_2, schemaDefine, VALID_INDEX_1);
443     option1.isMemoryDb = false;
444     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, option1);
445     ASSERT_NE(delegate, nullptr);
446     EXPECT_EQ(manager->CloseKvStore(delegate), OK);
447     delete manager;
448     manager = nullptr;
449 
450     /**
451      * @tc.steps: step1. open the schema db with non-schema mode, and then do PutLocal, GetLocal, DeleteLocal.
452      * @tc.expected: step1. open successfully and all operate successfully.
453      */
454     Option option2 = g_option;
455     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, option2);
456     ASSERT_NE(delegate, nullptr);
457 
458     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*delegate, KEY_1, VALUE_1), OK);
459     Value gotValue;
460     EXPECT_EQ(delegate->GetLocal(KEY_1, gotValue), OK);
461     EXPECT_TRUE(CompareVector(gotValue, VALUE_1));
462     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*delegate, KEY_1, VALUE_2), OK);
463     EXPECT_EQ(delegate->DeleteLocal(KEY_1), OK);
464     /**
465      * @tc.steps: step2. PutLocalBatch 128 records, GetLocalEntries PutLocalBatch to update it
466      *    and then DeleteLocalBatch them.
467      * @tc.expected: step2. operate successfully.
468      */
469     vector<Entry> entries1, entries2, gotEntries;
470     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
471     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, BATCH_RECORDS);
472     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*delegate, entries1), OK);
473     EXPECT_EQ(delegate->GetLocalEntries(KEY_EMPTY, gotEntries), OK);
474     EXPECT_TRUE(CompareEntriesVector(entries1, gotEntries));
475 
476     GenerateAppointPrefixAndSizeRecords(entries2, entrySize, BATCH_RECORDS, {'k'}, {'w'});
477     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*delegate, entries2), OK);
478 
479     vector<Key> keys;
480     for (auto iter : entries2) {
481         keys.push_back(iter.key);
482     }
483     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*delegate, keys), OK);
484 
485     EXPECT_TRUE(EndCaseDeleteDB(manager, delegate, STORE_ID_2, option2.isMemoryDb));
486 }
487 #endif
488 /**
489  * @tc.name: ComplexData 001
490  * @tc.desc: Verify that it can continuously insert update and delete
491  * @tc.type: FUNC
492  * @tc.require: SR000EPA24
493  * @tc.author: fengxiaoyun
494  */
495 HWTEST_F(DistributeddbNbLocalBatchCrudTest, ComplexData001, TestSize.Level1)
496 {
497     vector<Entry> entries1, entries2, gotValues;
498     entries1.push_back(ENTRY_1);
499     entries1.push_back(ENTRY_2);
500     entries2.push_back(ENTRY_1_2);
501     entries2.push_back(ENTRY_2_3);
502     vector<Key> keys;
503     keys.push_back(KEY_1);
504     keys.push_back(KEY_2);
505 
506     for (int index = 0; index < HUNDRED_TIMES; index++) {
507         /**
508          * @tc.steps: step1. call PutLocalBatch interface to insert entries1 to DB.
509          * @tc.expected: step1. PutLocalBatch succeed.
510          */
511         EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
512         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
513         EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
514 
515         /**
516          * @tc.steps: step2. call PutLocalBatch interface to update entries1 to entries2.
517          * @tc.expected: step2. update successfully.
518          */
519         EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
520         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
521         EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
522 
523         /**
524          * @tc.steps: step3. call DeleteLocalBatch interface to delete the records.
525          * @tc.expected: step3. delete successfully.
526          */
527         EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
528         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
529     }
530 }
531 
532 /**
533  * @tc.name: ComplexData 002
534  * @tc.desc: Verify that it can continuously insert update and delete
535  * @tc.type: FUNC
536  * @tc.require: SR000EPA24
537  * @tc.author: fengxiaoyun
538  */
539 HWTEST_F(DistributeddbNbLocalBatchCrudTest, ComplexData002, TestSize.Level1)
540 {
541     vector<Entry> entries1, entries2, gotValues;
542     entries1.push_back(ENTRY_1);
543     entries1.push_back(ENTRY_2);
544     entries2.push_back(ENTRY_1_3);
545     entries2.push_back(ENTRY_2_4);
546     entries2.push_back(ENTRY_3);
547     vector<Key> keys;
548     keys.push_back(KEY_2);
549     keys.push_back(KEY_3);
550 
551     /**
552      * @tc.steps: step1. call PutLocalBatch interface to insert entries1 to DB.
553      * @tc.expected: step1. PutLocalBatch succeed.
554      */
555     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
556     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
557     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
558 
559     /**
560      * @tc.steps: step2. call PutLocalBatch interface to update entries1 to entries2.
561      * @tc.expected: step2. update successfully.
562      */
563     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
564     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
565     EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
566 
567     /**
568      * @tc.steps: step3. call DeleteLocalBatch interface to delete the records.
569      * @tc.expected: step3. delete successfully.
570      */
571     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
572     entries2.pop_back();
573     entries2.pop_back();
574     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
575     EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
576 }
577 
578 /**
579  * @tc.name: Exception 001
580  * @tc.desc: Verify that local operate will calculate the total items in transantion.
581  * @tc.type: EXCEPTION
582  * @tc.require: SR000EPA24
583  * @tc.author: fengxiaoyun
584  */
585 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Exception001, TestSize.Level1)
586 {
587     /**
588      * @tc.steps: step1. start the transantion.
589      * @tc.expected: step1. start success
590      */
591     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
592     /**
593      * @tc.steps: step2. call PutBatch interface to insert 128 records to sync DB, and call PutLocalBatch interface to
594      *    insert (k1, v1) (k2, v2) to local DB.
595      * @tc.expected: step2. PutBatch succeed but PutLocalBatch will return OVER_MAX_LIMITS.
596      */
597     vector<Entry> entries1, entries2, gotValues;
598     EntrySize entrySize = {KEY_SIX_BYTE, ONE_K_LONG_STRING};
599     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, BATCH_RECORDS);
600     entries2.push_back(ENTRY_1);
601     entries2.push_back(ENTRY_2);
602     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbLocalBatchDelegate, entries1), OK);
603     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OVER_MAX_LIMITS);
604 
605     /**
606      * @tc.steps: step3. call DeleteLocalBatch interface to Delete the 128 records from local DB.
607      * @tc.expected: step3. DeleteLocalBatch failed and returned OVER_MAX_LIMITS.
608      */
609     vector<Key> keys1, keys2;
610     for (vector<Entry>::iterator it = entries1.begin(); it != entries1.end(); it++) {
611         keys1.push_back(it->key);
612     }
613     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys1), OVER_MAX_LIMITS);
614 
615     /**
616      * @tc.steps: step4. call Delete interface to Delete the (k1, v1) from local DB.
617      * @tc.expected: step4. Delete failed and returned OVER_MAX_LIMITS.
618      */
619     EXPECT_EQ(g_nbLocalBatchDelegate->Delete(KEY_1), OVER_MAX_LIMITS);
620 
621     /**
622      * @tc.steps: step5. call DeleteLocalBatch interface to Delete (k1, v1)(k2, v2) from sync DB
623      *     and then commit the transantion.
624      * @tc.expected: step5. Delete failed and returned OVER_MAX_LIMITS and the transantion commit success.
625      */
626     keys2.push_back(KEY_1);
627     keys2.push_back(KEY_2);
628     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys2), OVER_MAX_LIMITS);
629     EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
630 
631     /**
632      * @tc.steps: step6. call GetEntries and GetLocalEntries interface to check the data on sync and local DB.
633      * @tc.expected: step6. there are 128 records in sync DB but local DB is empty.
634      */
635     EXPECT_EQ(g_nbLocalBatchDelegate->GetEntries(KEY_EMPTY, gotValues), OK);
636     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
637     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
638 }
639 
640 /**
641  * @tc.name: Observer 001
642  * @tc.desc: Verify that different observer for different key will be triggered when PutLocalBatch.
643  * @tc.type: FUNC
644  * @tc.require: SR000EPA24
645  * @tc.author: fengxiaoyun
646  */
647 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer001, TestSize.Level1)
648 {
649     KvStoreObserverImpl observer1, observer2, observer3;
650     /**
651      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
652      * @tc.expected: step1. register success.
653      */
654     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
655     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
656     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
657 
658     /**
659      * @tc.steps: step2. PutLocalBatch (k1, v1), (k2, v2) to DB and check the 3 observers.
660      * @tc.expected: step2. PutLocalBatch and observer1, and observer2 was triggered but observer3 was not triggered.
661      */
662     vector<Entry> entries1, entries2;
663     entries1.push_back(ENTRY_1);
664     entries1.push_back(ENTRY_2);
665     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
666     list<DistributedDB::Entry> changeList;
667     changeList.push_back(ENTRY_1);
668     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, changeList));
669     changeList.clear();
670     changeList.push_back(ENTRY_2);
671     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, INSERT_LIST, changeList));
672     changeList.clear();
673     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
674     /**
675      * @tc.steps: step3. PutLocalBatch (k2, v3) (k3, v3) to insert (k3, v3) and update (k2, v3) and check the observers
676      * @tc.expected: step3. PutLocalBatch success and observer1 was not triggered, observer2 was triggered update mode,
677      *    and observer3 was triggered by insert mode.
678      */
679     observer1.Clear();
680     observer2.Clear();
681     entries2.push_back(ENTRY_2_3);
682     entries2.push_back(ENTRY_3);
683     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
684     changeList.clear();
685     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
686     changeList.clear();
687     changeList.push_back(ENTRY_2_3);
688     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
689     changeList.clear();
690     changeList.push_back(ENTRY_3);
691     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, changeList));
692 }
693 
694 /**
695  * @tc.name: Observer 002
696  * @tc.desc: Verify that different observer for different key will be triggered when DeleteLocalBatch.
697  * @tc.type: FUNC
698  * @tc.require: SR000EPA24
699  * @tc.author: fengxiaoyun
700  */
701 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer002, TestSize.Level1)
702 {
703     KvStoreObserverImpl observer1, observer2, observer3;
704     vector<Entry> entries, gotEntries;
705     entries.push_back(ENTRY_1);
706     entries.push_back(ENTRY_2);
707     entries.push_back(ENTRY_3);
708     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
709     /**
710      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
711      * @tc.expected: step1. register success.
712      */
713     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
714     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
715     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
716 
717     /**
718      * @tc.steps: step2. DeleteLocalBatch (k1, v1), (k2, v2) from DB and check the 3 observers.
719      * @tc.expected: step2. DeleteLocalBatch success and observer1, and observer2 was triggered by delete mode,
720      *    but observer3 was not triggered.
721      */
722     vector<Key> keys;
723     keys.push_back(KEY_1);
724     keys.push_back(KEY_2);
725     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
726     list<DistributedDB::Entry> changeList;
727     changeList.push_back(ENTRY_1);
728     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, changeList));
729     changeList.clear();
730     changeList.push_back(ENTRY_2);
731     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, DELETE_LIST, changeList));
732     changeList.clear();
733     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, DELETE_LIST, changeList));
734 
735     /**
736      * @tc.steps: step3. use GetLocalEntries to check the data in DB.
737      * @tc.expected: step3. there is only (k3, v3) in DB.
738      */
739     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotEntries), OK);
740     entries.erase(entries.begin(), entries.begin() + 2);
741     EXPECT_TRUE(CompareEntriesVector(entries, gotEntries));
742 }
743 
744 /**
745  * @tc.name: Observer 003
746  * @tc.desc: Verify that PutLocalBatch operator one key many times, the observer can still be triggered but will be
747  *    triggered one time.
748  * @tc.type: FUNC
749  * @tc.require: SR000EPA24
750  * @tc.author: fengxiaoyun
751  */
752 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer003, TestSize.Level1)
753 {
754     KvStoreObserverImpl observer1, observer2, observer3;
755     /**
756      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
757      * @tc.expected: step1. register success.
758      */
759     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
760     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
761     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
762 
763     /**
764      * @tc.steps: step2. PutLocalBatch (k1, v1), (k1, v2), (k2, v2) to DB and check the 3 observers.
765      * @tc.expected: step2. PutLocalBatch success and observer1 was triggered once time by insert mode,
766      *    and observer2 was triggered by insert mode, but observer3 was not triggered.
767      */
768     vector<Entry> entries1, entries2;
769     entries1.push_back(ENTRY_1);
770     entries1.push_back(ENTRY_1_2);
771     entries1.push_back(ENTRY_2);
772     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
773 
774     list<DistributedDB::Entry> changeList;
775     changeList.push_back(ENTRY_1_2);
776     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, changeList));
777     changeList.clear();
778     changeList.push_back(ENTRY_2);
779     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, INSERT_LIST, changeList));
780     changeList.clear();
781     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
782 
783     /**
784      * @tc.steps: step3. PutLocalBatch (k2, v3), (k2, v4), (k3, v3) to DB and check the 3 observers.
785      * @tc.expected: step3. PutLocalBatch success and observer1 was not triggered, and observer2 was triggered by
786      *    update mode, and observer3 was triggered once by insert mode.
787      */
788     observer1.Clear();
789     observer2.Clear();
790     entries2.push_back(ENTRY_2_3);
791     entries2.push_back(ENTRY_2_4);
792     entries2.push_back(ENTRY_3);
793     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
794 
795     changeList.clear();
796     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, UPDATE_LIST, changeList));
797     changeList.clear();
798     changeList.push_back(ENTRY_2_4);
799     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
800     changeList.clear();
801     changeList.push_back(ENTRY_3);
802     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, changeList));
803 }
804 
805 /**
806  * @tc.name: Observer 004
807  * @tc.desc: Verify that DeleteLocalBatch operator one key many times, the observer can still be triggered but will be
808  *    triggered one time.
809  * @tc.type: FUNC
810  * @tc.require: SR000EPA24
811  * @tc.author: fengxiaoyun
812  */
813 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer004, TestSize.Level1)
814 {
815     KvStoreObserverImpl observer1, observer2, observer3;
816     vector<Entry> entries1, entries2;
817     entries1.push_back(ENTRY_1);
818     entries1.push_back(ENTRY_2);
819     entries1.push_back(ENTRY_3);
820     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
821     /**
822      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
823      * @tc.expected: step1. register success.
824      */
825     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
826     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
827     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
828 
829     /**
830      * @tc.steps: step2. DeleteLocalBatch (k1, k2, k1) from DB and check the 3 observers.
831      * @tc.expected: step2. DeleteLocalBatch success and observer1 and observer2 was triggered once time by delete mode,
832      *    but observer3 was not triggered.
833      */
834     vector<Key> keys;
835     keys.push_back(KEY_1);
836     keys.push_back(KEY_2);
837     keys.push_back(KEY_1);
838     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
839     list<DistributedDB::Entry> changeList;
840     changeList.push_back(ENTRY_1);
841     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, changeList));
842     changeList.clear();
843     changeList.push_back(ENTRY_2);
844     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, DELETE_LIST, changeList));
845     changeList.clear();
846     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, DELETE_LIST, changeList));
847 }
848 
849 /**
850  * @tc.name: Observer 005
851  * @tc.desc: Verify that different observers of the same key will be triggered when the key is changed
852  * @tc.type: FUNC
853  * @tc.require: SR000EPA24
854  * @tc.author: fengxiaoyun
855  */
856 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer005, TestSize.Level1)
857 {
858     vector<KvStoreObserverImpl> observer(OBSERVER_CNT_END);
859     /**
860      * @tc.steps: step1. register observer all the 8 observers of OBSERVER_CHANGES_LOCAL_ONLY mode.
861      * @tc.expected: step1. register success.
862      */
863     for (unsigned long index = 0; index < OBSERVER_CNT_END; index++) {
864         EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY,
865             &observer[index]), OK);
866     }
867 
868     /**
869      * @tc.steps: step2. PutLocalBatch  10 data to DB and check the 8 observers.
870      * @tc.expected: step2. PutLocalBatch success and all the observers were triggered one insert callback and the
871      *    callback list contains 10 data.
872      */
873     vector<Entry> entries;
874     vector<Key> keys;
875     GenerateFixedRecords(entries, keys, TEN_RECORDS, KEY_SIX_BYTE, ONE_K_LONG_STRING);
876     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
877     list<DistributedDB::Entry> changeList;
878     for (auto it = entries.begin(); it != entries.end(); it++) {
879         changeList.push_back(*it);
880     }
881     for (auto it = observer.begin(); it != observer.end(); it++) {
882         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, INSERT_LIST, changeList));
883         it->Clear();
884     }
885     /**
886      * @tc.steps: step3. use PutLocalBatch to update the 10 data to DB and check the 8 observers.
887      * @tc.expected: step3. update success and all the observers were triggered one update callback and the
888      *    callback list contains 10 data.
889      */
890     for (auto it = entries.begin(); it != entries.end(); it++) {
891         it->value = {'v', 'v', 'v', 'v', 'v'};
892     }
893     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
894     changeList.clear();
895     for (auto it = entries.begin(); it != entries.end(); it++) {
896         it->value = {'v', 'v', 'v', 'v', 'v'};
897         changeList.push_back(*it);
898     }
899     for (auto it = observer.begin(); it != observer.end(); it++) {
900         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
901         it->Clear();
902     }
903     /**
904      * @tc.steps: step4. use DeleteLocalBatch to delete the 10 data from DB and check the 8 observers.
905      * @tc.expected: step4. delete success and all the observers were triggered one delete callback and the
906      *    callback list contains 10 data.
907      */
908     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
909     for (auto it = observer.begin(); it != observer.end(); it++) {
910         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, DELETE_LIST, changeList));
911     }
912 }
913 
914 /**
915  * @tc.name: Observer 006
916  * @tc.desc: Operation data committed in a transaction will trigger batch callback in registered observer
917  * @tc.type: FUNC
918  * @tc.require: SR000EPA24
919  * @tc.author: fengxiaoyun
920  */
921 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer006, TestSize.Level1)
922 {
923     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_1), OK);
924     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_2, VALUE_2), OK);
925     vector<Entry> insertEntries;
926     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
927     GenerateAppointPrefixAndSizeRecords(insertEntries, entrySize, TEN_RECORDS, {'k'}, {'v', 'm'});
928     DBStatus status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, insertEntries);
929     EXPECT_EQ(status, OK);
930     /**
931      * @tc.steps: step1. register a local and a native observer separately, then start a transaction.
932      * @tc.expected: step1. operate successfully.
933      */
934     KvStoreObserverImpl observerLocal;
935     KvStoreObserverImpl observerNative;
936     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY, &observerLocal), OK);
937     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observerNative), OK);
938     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
939     /**
940      * @tc.steps: step2. PutBatch 10 records, Put (k1,v1), Delete (k2).
941      * @tc.expected: step2. operate successfully.
942      */
943     status = DistributedDBNbTestTools::PutBatch(*g_nbLocalBatchDelegate, insertEntries);
944     EXPECT_EQ(status, OK);
945     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_2), OK);
946     EXPECT_EQ(g_nbLocalBatchDelegate->Delete(KEY_2), OK);
947     /**
948      * @tc.steps: step3. PutLocal (k1,v1), (k2,v2), DeleteLocal (k1,v1),
949      *  use PutLocalBatch to update records from k1 to k5, use DeleteLocalBatch to delete keys from k6 to k10.
950      * @tc.expected: step3. operate successfully.
951      */
952     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_1, VALUE_1), OK);
953     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_2, VALUE_2), OK);
954     EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocal(KEY_1), OK);
955     vector<Entry> localUpdateEntries;
956     GenerateAppointPrefixAndSizeRecords(localUpdateEntries, entrySize, FIVE_RECORDS, {'k'}, {'v', 'n'});
957     status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, localUpdateEntries);
958     EXPECT_EQ(status, OK);
959 
960     vector<Key> localDeleteKeys;
961     vector<Entry> localDeleteEntries;
962     for (size_t index = INDEX_FIFTH; index < insertEntries.size(); index++) {
963         localDeleteKeys.push_back(insertEntries[index].key);
964         localDeleteEntries.push_back(insertEntries[index]);
965     }
966     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, localDeleteKeys), OK);
967     /**
968      * @tc.steps: step4. commit the transaction and verify corresponding data.
969      * @tc.expected: step4. delete success and all the observers were triggered one delete callback and the
970      *    callback list contains 10 data.
971      */
972     EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
973     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
974     vector<Entry> updateEntries = { ENTRY_1_2 };
975     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, UPDATE_LIST, updateEntries));
976     vector<Entry> deleteEntries = { ENTRY_2 };
977     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, DELETE_LIST, deleteEntries));
978 
979     vector<Entry> localInsertEntries = { ENTRY_2 };
980     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, localInsertEntries));
981     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, UPDATE_LIST, localUpdateEntries));
982     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, DELETE_LIST, localDeleteEntries));
983 
984     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerLocal), OK);
985     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerNative), OK);
986 }
987 
988 /**
989  * @tc.name: Observer 007
990  * @tc.desc: observer callback data only can be received after a transaction committed
991  *  in multi-thread environment using the same delegate and observer.
992  * @tc.type: FUNC
993  * @tc.require: SR000EPA24
994  * @tc.author: fengxiaoyun
995  */
996 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer007, TestSize.Level1)
997 {
998     /**
999      * @tc.steps: step1. register a local observer.
1000      * @tc.expected: step1. operate successfully.
1001      */
1002     KvStoreObserverImpl observerLocal;
1003     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY, &observerLocal), OK);
1004     /**
1005      * @tc.steps: step2. start a transaction, then PutBatch 10 records, PutLocal (k10,v10),
1006      *  and PutLocalBatch from k1 to k5.
1007      * @tc.expected: step2. operate successfully.
1008      */
1009     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
1010     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_10, VALUE_10), OK);
1011     vector<Entry> insertEntries = { ENTRY_1, ENTRY_2, ENTRY_3, ENTRY_4, ENTRY_5 };
1012     DBStatus status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, insertEntries);
1013     EXPECT_EQ(status, OK);
1014     /**
1015      * @tc.steps: step3. launch a thread to verify observer callback data, commit the transaction
1016      *  and then verify the data again.
1017      * @tc.expected: step3. there is no data before committing the transaction
1018      *  and there are 6 records in insert list of the local observer after committing.
1019      */
1020     insertEntries.push_back(ENTRY_10);
__anon9a11829b0502() 1021     thread subThread([&]() {
1022         vector<Entry> emptyInsertEntries;
1023         EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ZERO_TIME, INSERT_LIST, emptyInsertEntries));
1024         EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
1025         EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
1026     });
1027     subThread.join();
1028     /**
1029      * @tc.steps: step4. verify the data in main thread after the transaction committed in sub thread.
1030      * @tc.expected: step4. there are 6 records in insert list of the local observer.
1031      */
1032     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
1033     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerLocal), OK);
1034 }
1035 } // end of namespace DistributeddbNbLocalBatchCrud