• 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, entries3, gotValues;
308     vector<Key> allKeys1, allKeys2, allKeys3;
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, FOUR_M_LONG_STRING - KEY_EIGHT_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     GenerateFixedRecords(entries3, allKeys3, BATCH_RECORDS, FOUR_M_LONG_STRING, VALUE_ONE_HUNDRED_BYTE);
329     allKeys3.push_back(KEY_1);
330     EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocalBatch(allKeys3), INVALID_ARGS);
331     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
332     EXPECT_EQ(entries1.size() + 1, gotValues.size());
333 }
334 
335 #ifndef LOW_LEVEL_MEM_DEV
336 /**
337  * @tc.name: SimpleData 007
338  * @tc.desc: Verify that rekey will return busy when it is PutLocalBatch-ing.
339  * @tc.type: FUNC
340  * @tc.require: SR000EPA24
341  * @tc.author: fengxiaoyun
342  */
343 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData007, TestSize.Level3)
344 {
345     /**
346      * @tc.steps: step1. start one new thread to use PutLocalBatch interface to insert 128 (1k, 4M) records to DB.
347      * @tc.expected: step1. PutLocalBatch succeed.
348      */
349     vector<Entry> entries;
350     EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING - KEY_ONE_K_BYTE};
351     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
352 
353     std::condition_variable batchCondition;
354     std::mutex batchMtx;
355     bool putBatchFinish = false;
__anona43db3f90102() 356     thread subThread([&putBatchFinish, &entries, &batchMtx, &batchCondition]() {
357         DBStatus inserStatus = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries);
358         EXPECT_TRUE(inserStatus == OK || inserStatus == BUSY);
359         {
360             std::lock_guard<std::mutex> lock(batchMtx);
361             putBatchFinish = true;
362         }
363         batchCondition.notify_one();
364     });
365     subThread.detach();
366 
367     /**
368      * @tc.steps: step2. rekey the DB when it is PutLocalBatch-ing.
369      * @tc.expected: step2. rekey failed and it will return busy.
370      */
371     DistributedDB::CipherPassword passwd;
372     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_FIFTY_MS));
373     DBStatus rekeyStatus = g_nbLocalBatchDelegate->Rekey(passwd);
374     EXPECT_TRUE(rekeyStatus == BUSY || rekeyStatus == OK);
375 
376     std::unique_lock<std::mutex> lck(batchMtx);
__anona43db3f90202null377     batchCondition.wait(lck, [&] { return putBatchFinish; });
378 }
379 
380 /**
381  * @tc.name: SimpleData 008
382  * @tc.desc: Verify that import will return busy when it is PutLocalBatch-ing.
383  * @tc.type: FUNC
384  * @tc.require: SR000EPA24
385  * @tc.author: fengxiaoyun
386  */
387 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData008, TestSize.Level3)
388 {
389     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_1), OK);
390 
391     std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
392     SetDir(exportPath);
393     std::string filePath = exportPath + "/bkpDB.bin";
394     EXPECT_TRUE(g_nbLocalBatchDelegate->Export(filePath, NULL_PASSWD) == OK);
395     /**
396      * @tc.steps: step1. call PutLocalBatch interface to insert 128 records to DB.
397      * @tc.expected: step1. PutLocalBatch succeed.
398      */
399     vector<Entry> entries;
400     EntrySize entrySize = {KEY_ONE_K_BYTE, FOUR_M_LONG_STRING - KEY_ONE_K_BYTE};
401     GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
402 
403     std::condition_variable batchCondition;
404     std::mutex batchMtx;
405     bool putBatchFinish = false;
__anona43db3f90302() 406     thread subThread([&putBatchFinish, &entries, &batchMtx, &batchCondition]() {
407         DBStatus insertStatus = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries);
408         EXPECT_TRUE(insertStatus == OK || insertStatus == BUSY);
409         {
410             std::lock_guard<std::mutex> lock(batchMtx);
411             putBatchFinish = true;
412         }
413         batchCondition.notify_one();
414     });
415     subThread.detach();
416 
417     /**
418      * @tc.steps: step2. import the backup file of the db.
419      * @tc.expected: step2. import failed and return busy.
420      */
421     std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_FIFTY_MS));
422     DBStatus importStatus = g_nbLocalBatchDelegate->Import(filePath, NULL_PASSWD);
423     EXPECT_TRUE(importStatus == BUSY || importStatus == OK);
424 
425     std::unique_lock<std::mutex> lck(batchMtx);
__anona43db3f90402null426     batchCondition.wait(lck, [&] { return putBatchFinish; });
427 }
428 #endif
429 #ifndef OMIT_JSON
430 /**
431  * @tc.name: SimpleData 009
432  * @tc.desc: Verify that open the schema db use non-schema mode, it can open success on readOnly mode and can be CRUD.
433  * @tc.type: FUNC
434  * @tc.require: SR000EPA24
435  * @tc.author: fengxiaoyun
436  */
437 HWTEST_F(DistributeddbNbLocalBatchCrudTest, SimpleData009, TestSize.Level1)
438 {
439     KvStoreNbDelegate *delegate = nullptr;
440     KvStoreDelegateManager *manager = nullptr;
441     Option option1 = g_option;
442     string schemaDefine = "{\"field0\":\"INTEGER,NOT NULL,DEFAULT 10\",\"field1\":[]}";
443     option1.schema = SpliceToSchema(VALID_VERSION_1, VALID_MODE_2, schemaDefine, VALID_INDEX_1);
444     option1.isMemoryDb = false;
445     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, option1);
446     ASSERT_NE(delegate, nullptr);
447     EXPECT_EQ(manager->CloseKvStore(delegate), OK);
448     delete manager;
449     manager = nullptr;
450 
451     /**
452      * @tc.steps: step1. open the schema db with non-schema mode, and then do PutLocal, GetLocal, DeleteLocal.
453      * @tc.expected: step1. open successfully and all operate successfully.
454      */
455     Option option2 = g_option;
456     delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(manager, g_dbParameter2, option2);
457     ASSERT_NE(delegate, nullptr);
458 
459     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*delegate, KEY_1, VALUE_1), OK);
460     Value gotValue;
461     EXPECT_EQ(delegate->GetLocal(KEY_1, gotValue), OK);
462     EXPECT_TRUE(CompareVector(gotValue, VALUE_1));
463     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*delegate, KEY_1, VALUE_2), OK);
464     EXPECT_EQ(delegate->DeleteLocal(KEY_1), OK);
465     /**
466      * @tc.steps: step2. PutLocalBatch 128 records, GetLocalEntries PutLocalBatch to update it
467      *    and then DeleteLocalBatch them.
468      * @tc.expected: step2. operate successfully.
469      */
470     vector<Entry> entries1, entries2, gotEntries;
471     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
472     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, BATCH_RECORDS);
473     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*delegate, entries1), OK);
474     EXPECT_EQ(delegate->GetLocalEntries(KEY_EMPTY, gotEntries), OK);
475     EXPECT_TRUE(CompareEntriesVector(entries1, gotEntries));
476 
477     GenerateAppointPrefixAndSizeRecords(entries2, entrySize, BATCH_RECORDS, {'k'}, {'w'});
478     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*delegate, entries2), OK);
479 
480     vector<Key> keys;
481     for (auto iter : entries2) {
482         keys.push_back(iter.key);
483     }
484     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*delegate, keys), OK);
485 
486     EXPECT_TRUE(EndCaseDeleteDB(manager, delegate, STORE_ID_2, option2.isMemoryDb));
487 }
488 #endif
489 /**
490  * @tc.name: ComplexData 001
491  * @tc.desc: Verify that it can continuously insert update and delete
492  * @tc.type: FUNC
493  * @tc.require: SR000EPA24
494  * @tc.author: fengxiaoyun
495  */
496 HWTEST_F(DistributeddbNbLocalBatchCrudTest, ComplexData001, TestSize.Level1)
497 {
498     vector<Entry> entries1, entries2, gotValues;
499     entries1.push_back(ENTRY_1);
500     entries1.push_back(ENTRY_2);
501     entries2.push_back(ENTRY_1_2);
502     entries2.push_back(ENTRY_2_3);
503     vector<Key> keys;
504     keys.push_back(KEY_1);
505     keys.push_back(KEY_2);
506 
507     for (int index = 0; index < HUNDRED_TIMES; index++) {
508         /**
509          * @tc.steps: step1. call PutLocalBatch interface to insert entries1 to DB.
510          * @tc.expected: step1. PutLocalBatch succeed.
511          */
512         EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
513         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
514         EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
515 
516         /**
517          * @tc.steps: step2. call PutLocalBatch interface to update entries1 to entries2.
518          * @tc.expected: step2. update successfully.
519          */
520         EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
521         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
522         EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
523 
524         /**
525          * @tc.steps: step3. call DeleteLocalBatch interface to delete the records.
526          * @tc.expected: step3. delete successfully.
527          */
528         EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
529         EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
530     }
531 }
532 
533 /**
534  * @tc.name: ComplexData 002
535  * @tc.desc: Verify that it can continuously insert update and delete
536  * @tc.type: FUNC
537  * @tc.require: SR000EPA24
538  * @tc.author: fengxiaoyun
539  */
540 HWTEST_F(DistributeddbNbLocalBatchCrudTest, ComplexData002, TestSize.Level1)
541 {
542     vector<Entry> entries1, entries2, gotValues;
543     entries1.push_back(ENTRY_1);
544     entries1.push_back(ENTRY_2);
545     entries2.push_back(ENTRY_1_3);
546     entries2.push_back(ENTRY_2_4);
547     entries2.push_back(ENTRY_3);
548     vector<Key> keys;
549     keys.push_back(KEY_2);
550     keys.push_back(KEY_3);
551 
552     /**
553      * @tc.steps: step1. call PutLocalBatch interface to insert entries1 to DB.
554      * @tc.expected: step1. PutLocalBatch succeed.
555      */
556     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
557     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
558     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
559 
560     /**
561      * @tc.steps: step2. call PutLocalBatch interface to update entries1 to entries2.
562      * @tc.expected: step2. update successfully.
563      */
564     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
565     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
566     EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
567 
568     /**
569      * @tc.steps: step3. call DeleteLocalBatch interface to delete the records.
570      * @tc.expected: step3. delete successfully.
571      */
572     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
573     entries2.pop_back();
574     entries2.pop_back();
575     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), OK);
576     EXPECT_TRUE(CompareEntriesVector(entries2, gotValues));
577 }
578 
579 /**
580  * @tc.name: Exception 001
581  * @tc.desc: Verify that local operate will calculate the total items in transantion.
582  * @tc.type: EXCEPTION
583  * @tc.require: SR000EPA24
584  * @tc.author: fengxiaoyun
585  */
586 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Exception001, TestSize.Level1)
587 {
588     /**
589      * @tc.steps: step1. start the transantion.
590      * @tc.expected: step1. start success
591      */
592     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
593     /**
594      * @tc.steps: step2. call PutBatch interface to insert 128 records to sync DB, and call PutLocalBatch interface to
595      *    insert (k1, v1) (k2, v2) to local DB.
596      * @tc.expected: step2. PutBatch succeed but PutLocalBatch will return OVER_MAX_LIMITS.
597      */
598     vector<Entry> entries1, entries2, gotValues;
599     EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE};
600     GenerateAppointPrefixAndSizeRecords(entries1, entrySize, BATCH_RECORDS);
601     entries2.push_back(ENTRY_1);
602     entries2.push_back(ENTRY_2);
603     EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbLocalBatchDelegate, entries1), OK);
604     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OVER_MAX_LIMITS);
605 
606     /**
607      * @tc.steps: step3. call DeleteLocalBatch interface to Delete the 128 records from local DB.
608      * @tc.expected: step3. DeleteLocalBatch failed and returned OVER_MAX_LIMITS.
609      */
610     vector<Key> keys1, keys2;
611     for (vector<Entry>::iterator it = entries1.begin(); it != entries1.end(); it++) {
612         keys1.push_back(it->key);
613     }
614     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys1), OVER_MAX_LIMITS);
615 
616     /**
617      * @tc.steps: step4. call Delete interface to Delete the (k1, v1) from local DB.
618      * @tc.expected: step4. Delete failed and returned OVER_MAX_LIMITS.
619      */
620     EXPECT_EQ(g_nbLocalBatchDelegate->Delete(KEY_1), OVER_MAX_LIMITS);
621 
622     /**
623      * @tc.steps: step5. call DeleteLocalBatch interface to Delete (k1, v1)(k2, v2) from sync DB
624      *     and then commit the transantion.
625      * @tc.expected: step5. Delete failed and returned OVER_MAX_LIMITS and the transantion commit success.
626      */
627     keys2.push_back(KEY_1);
628     keys2.push_back(KEY_2);
629     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys2), OVER_MAX_LIMITS);
630     EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
631 
632     /**
633      * @tc.steps: step6. call GetEntries and GetLocalEntries interface to check the data on sync and local DB.
634      * @tc.expected: step6. there are 128 records in sync DB but local DB is empty.
635      */
636     EXPECT_EQ(g_nbLocalBatchDelegate->GetEntries(KEY_EMPTY, gotValues), OK);
637     EXPECT_TRUE(CompareEntriesVector(entries1, gotValues));
638     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotValues), NOT_FOUND);
639 }
640 
641 /**
642  * @tc.name: Observer 001
643  * @tc.desc: Verify that different observer for different key will be triggered when PutLocalBatch.
644  * @tc.type: FUNC
645  * @tc.require: SR000EPA24
646  * @tc.author: fengxiaoyun
647  */
648 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer001, TestSize.Level1)
649 {
650     KvStoreObserverImpl observer1, observer2, observer3;
651     /**
652      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
653      * @tc.expected: step1. register success.
654      */
655     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
656     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
657     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
658 
659     /**
660      * @tc.steps: step2. PutLocalBatch (k1, v1), (k2, v2) to DB and check the 3 observers.
661      * @tc.expected: step2. PutLocalBatch and observer1, and observer2 was triggered but observer3 was not triggered.
662      */
663     vector<Entry> entries1, entries2;
664     entries1.push_back(ENTRY_1);
665     entries1.push_back(ENTRY_2);
666     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
667     list<DistributedDB::Entry> changeList;
668     changeList.push_back(ENTRY_1);
669     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, changeList));
670     changeList.clear();
671     changeList.push_back(ENTRY_2);
672     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, INSERT_LIST, changeList));
673     changeList.clear();
674     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
675     /**
676      * @tc.steps: step3. PutLocalBatch (k2, v3) (k3, v3) to insert (k3, v3) and update (k2, v3) and check the observers
677      * @tc.expected: step3. PutLocalBatch success and observer1 was not triggered, observer2 was triggered update mode,
678      *    and observer3 was triggered by insert mode.
679      */
680     observer1.Clear();
681     observer2.Clear();
682     entries2.push_back(ENTRY_2_3);
683     entries2.push_back(ENTRY_3);
684     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
685     changeList.clear();
686     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
687     changeList.clear();
688     changeList.push_back(ENTRY_2_3);
689     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
690     changeList.clear();
691     changeList.push_back(ENTRY_3);
692     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, changeList));
693 }
694 
695 /**
696  * @tc.name: Observer 002
697  * @tc.desc: Verify that different observer for different key will be triggered when DeleteLocalBatch.
698  * @tc.type: FUNC
699  * @tc.require: SR000EPA24
700  * @tc.author: fengxiaoyun
701  */
702 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer002, TestSize.Level1)
703 {
704     KvStoreObserverImpl observer1, observer2, observer3;
705     vector<Entry> entries, gotEntries;
706     entries.push_back(ENTRY_1);
707     entries.push_back(ENTRY_2);
708     entries.push_back(ENTRY_3);
709     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
710     /**
711      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
712      * @tc.expected: step1. register success.
713      */
714     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
715     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
716     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
717 
718     /**
719      * @tc.steps: step2. DeleteLocalBatch (k1, v1), (k2, v2) from DB and check the 3 observers.
720      * @tc.expected: step2. DeleteLocalBatch success and observer1, and observer2 was triggered by delete mode,
721      *    but observer3 was not triggered.
722      */
723     vector<Key> keys;
724     keys.push_back(KEY_1);
725     keys.push_back(KEY_2);
726     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
727     list<DistributedDB::Entry> changeList;
728     changeList.push_back(ENTRY_1);
729     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, changeList));
730     changeList.clear();
731     changeList.push_back(ENTRY_2);
732     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, DELETE_LIST, changeList));
733     changeList.clear();
734     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, DELETE_LIST, changeList));
735 
736     /**
737      * @tc.steps: step3. use GetLocalEntries to check the data in DB.
738      * @tc.expected: step3. there is only (k3, v3) in DB.
739      */
740     EXPECT_EQ(g_nbLocalBatchDelegate->GetLocalEntries(KEY_EMPTY, gotEntries), OK);
741     entries.erase(entries.begin(), entries.begin() + 2);
742     EXPECT_TRUE(CompareEntriesVector(entries, gotEntries));
743 }
744 
745 /**
746  * @tc.name: Observer 003
747  * @tc.desc: Verify that PutLocalBatch operator one key many times, the observer can still be triggered but will be
748  *    triggered one time.
749  * @tc.type: FUNC
750  * @tc.require: SR000EPA24
751  * @tc.author: fengxiaoyun
752  */
753 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer003, TestSize.Level1)
754 {
755     KvStoreObserverImpl observer1, observer2, observer3;
756     /**
757      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
758      * @tc.expected: step1. register success.
759      */
760     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
761     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
762     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
763 
764     /**
765      * @tc.steps: step2. PutLocalBatch (k1, v1), (k1, v2), (k2, v2) to DB and check the 3 observers.
766      * @tc.expected: step2. PutLocalBatch success and observer1 was triggered once time by insert mode,
767      *    and observer2 was triggered by insert mode, but observer3 was not triggered.
768      */
769     vector<Entry> entries1, entries2;
770     entries1.push_back(ENTRY_1);
771     entries1.push_back(ENTRY_1_2);
772     entries1.push_back(ENTRY_2);
773     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
774 
775     list<DistributedDB::Entry> changeList;
776     changeList.push_back(ENTRY_1_2);
777     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, changeList));
778     changeList.clear();
779     changeList.push_back(ENTRY_2);
780     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, INSERT_LIST, changeList));
781     changeList.clear();
782     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, INSERT_LIST, changeList));
783 
784     /**
785      * @tc.steps: step3. PutLocalBatch (k2, v3), (k2, v4), (k3, v3) to DB and check the 3 observers.
786      * @tc.expected: step3. PutLocalBatch success and observer1 was not triggered, and observer2 was triggered by
787      *    update mode, and observer3 was triggered once by insert mode.
788      */
789     observer1.Clear();
790     observer2.Clear();
791     entries2.push_back(ENTRY_2_3);
792     entries2.push_back(ENTRY_2_4);
793     entries2.push_back(ENTRY_3);
794     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries2), OK);
795 
796     changeList.clear();
797     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, UPDATE_LIST, changeList));
798     changeList.clear();
799     changeList.push_back(ENTRY_2_4);
800     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
801     changeList.clear();
802     changeList.push_back(ENTRY_3);
803     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, changeList));
804 }
805 
806 /**
807  * @tc.name: Observer 004
808  * @tc.desc: Verify that DeleteLocalBatch operator one key many times, the observer can still be triggered but will be
809  *    triggered one time.
810  * @tc.type: FUNC
811  * @tc.require: SR000EPA24
812  * @tc.author: fengxiaoyun
813  */
814 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer004, TestSize.Level1)
815 {
816     KvStoreObserverImpl observer1, observer2, observer3;
817     vector<Entry> entries1, entries2;
818     entries1.push_back(ENTRY_1);
819     entries1.push_back(ENTRY_2);
820     entries1.push_back(ENTRY_3);
821     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries1), OK);
822     /**
823      * @tc.steps: step1. register observer of k1, k2, k3 of OBSERVER_CHANGES_LOCAL_ONLY mode.
824      * @tc.expected: step1. register success.
825      */
826     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_LOCAL_ONLY, &observer1), OK);
827     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_LOCAL_ONLY, &observer2), OK);
828     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_LOCAL_ONLY, &observer3), OK);
829 
830     /**
831      * @tc.steps: step2. DeleteLocalBatch (k1, k2, k1) from DB and check the 3 observers.
832      * @tc.expected: step2. DeleteLocalBatch success and observer1 and observer2 was triggered once time by delete mode,
833      *    but observer3 was not triggered.
834      */
835     vector<Key> keys;
836     keys.push_back(KEY_1);
837     keys.push_back(KEY_2);
838     keys.push_back(KEY_1);
839     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
840     list<DistributedDB::Entry> changeList;
841     changeList.push_back(ENTRY_1);
842     EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, changeList));
843     changeList.clear();
844     changeList.push_back(ENTRY_2);
845     EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, DELETE_LIST, changeList));
846     changeList.clear();
847     EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, DELETE_LIST, changeList));
848 }
849 
850 /**
851  * @tc.name: Observer 005
852  * @tc.desc: Verify that different observers of the same key will be triggered when the key is changed
853  * @tc.type: FUNC
854  * @tc.require: SR000EPA24
855  * @tc.author: fengxiaoyun
856  */
857 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer005, TestSize.Level1)
858 {
859     vector<KvStoreObserverImpl> observer(OBSERVER_CNT_END);
860     /**
861      * @tc.steps: step1. register observer all the 8 observers of OBSERVER_CHANGES_LOCAL_ONLY mode.
862      * @tc.expected: step1. register success.
863      */
864     for (unsigned long index = 0; index < OBSERVER_CNT_END; index++) {
865         EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY,
866             &observer[index]), OK);
867     }
868 
869     /**
870      * @tc.steps: step2. PutLocalBatch  10 data to DB and check the 8 observers.
871      * @tc.expected: step2. PutLocalBatch success and all the observers were triggered one insert callback and the
872      *    callback list contains 10 data.
873      */
874     vector<Entry> entries;
875     vector<Key> keys;
876     GenerateFixedRecords(entries, keys, TEN_RECORDS, KEY_SIX_BYTE, ONE_K_LONG_STRING);
877     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
878     list<DistributedDB::Entry> changeList;
879     for (auto it = entries.begin(); it != entries.end(); it++) {
880         changeList.push_back(*it);
881     }
882     for (auto it = observer.begin(); it != observer.end(); it++) {
883         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, INSERT_LIST, changeList));
884         it->Clear();
885     }
886     /**
887      * @tc.steps: step3. use PutLocalBatch to update the 10 data to DB and check the 8 observers.
888      * @tc.expected: step3. update success and all the observers were triggered one update callback and the
889      *    callback list contains 10 data.
890      */
891     for (auto it = entries.begin(); it != entries.end(); it++) {
892         it->value = {'v', 'v', 'v', 'v', 'v'};
893     }
894     EXPECT_EQ(DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, entries), OK);
895     changeList.clear();
896     for (auto it = entries.begin(); it != entries.end(); it++) {
897         it->value = {'v', 'v', 'v', 'v', 'v'};
898         changeList.push_back(*it);
899     }
900     for (auto it = observer.begin(); it != observer.end(); it++) {
901         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, UPDATE_LIST, changeList));
902         it->Clear();
903     }
904     /**
905      * @tc.steps: step4. use DeleteLocalBatch to delete the 10 data from DB and check the 8 observers.
906      * @tc.expected: step4. delete success and all the observers were triggered one delete callback and the
907      *    callback list contains 10 data.
908      */
909     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, keys), OK);
910     for (auto it = observer.begin(); it != observer.end(); it++) {
911         EXPECT_TRUE(VerifyObserverResult(*it, CHANGED_ONE_TIME, DELETE_LIST, changeList));
912     }
913 }
914 
915 /**
916  * @tc.name: Observer 006
917  * @tc.desc: Operation data committed in a transaction will trigger batch callback in registered observer
918  * @tc.type: FUNC
919  * @tc.require: SR000EPA24
920  * @tc.author: fengxiaoyun
921  */
922 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer006, TestSize.Level1)
923 {
924     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_1), OK);
925     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_2, VALUE_2), OK);
926     vector<Entry> insertEntries;
927     EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
928     GenerateAppointPrefixAndSizeRecords(insertEntries, entrySize, TEN_RECORDS, {'k'}, {'v', 'm'});
929     DBStatus status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, insertEntries);
930     EXPECT_EQ(status, OK);
931     /**
932      * @tc.steps: step1. register a local and a native observer separately, then start a transaction.
933      * @tc.expected: step1. operate successfully.
934      */
935     KvStoreObserverImpl observerLocal;
936     KvStoreObserverImpl observerNative;
937     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY, &observerLocal), OK);
938     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observerNative), OK);
939     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
940     /**
941      * @tc.steps: step2. PutBatch 10 records, Put (k1,v1), Delete (k2).
942      * @tc.expected: step2. operate successfully.
943      */
944     status = DistributedDBNbTestTools::PutBatch(*g_nbLocalBatchDelegate, insertEntries);
945     EXPECT_EQ(status, OK);
946     EXPECT_EQ(g_nbLocalBatchDelegate->Put(KEY_1, VALUE_2), OK);
947     EXPECT_EQ(g_nbLocalBatchDelegate->Delete(KEY_2), OK);
948     /**
949      * @tc.steps: step3. PutLocal (k1,v1), (k2,v2), DeleteLocal (k1,v1),
950      *  use PutLocalBatch to update records from k1 to k5, use DeleteLocalBatch to delete keys from k6 to k10.
951      * @tc.expected: step3. operate successfully.
952      */
953     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_1, VALUE_1), OK);
954     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_2, VALUE_2), OK);
955     EXPECT_EQ(g_nbLocalBatchDelegate->DeleteLocal(KEY_1), OK);
956     vector<Entry> localUpdateEntries;
957     GenerateAppointPrefixAndSizeRecords(localUpdateEntries, entrySize, FIVE_RECORDS, {'k'}, {'v', 'n'});
958     status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, localUpdateEntries);
959     EXPECT_EQ(status, OK);
960 
961     vector<Key> localDeleteKeys;
962     vector<Entry> localDeleteEntries;
963     for (size_t index = INDEX_FIFTH; index < insertEntries.size(); index++) {
964         localDeleteKeys.push_back(insertEntries[index].key);
965         localDeleteEntries.push_back(insertEntries[index]);
966     }
967     EXPECT_EQ(DistributedDBNbTestTools::DeleteLocalBatch(*g_nbLocalBatchDelegate, localDeleteKeys), OK);
968     /**
969      * @tc.steps: step4. commit the transaction and verify corresponding data.
970      * @tc.expected: step4. delete success and all the observers were triggered one delete callback and the
971      *    callback list contains 10 data.
972      */
973     EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
974     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
975     vector<Entry> updateEntries = { ENTRY_1_2 };
976     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, UPDATE_LIST, updateEntries));
977     vector<Entry> deleteEntries = { ENTRY_2 };
978     EXPECT_TRUE(VerifyObserverResult(observerNative, CHANGED_ONE_TIME, DELETE_LIST, deleteEntries));
979 
980     vector<Entry> localInsertEntries = { ENTRY_2 };
981     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, localInsertEntries));
982     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, UPDATE_LIST, localUpdateEntries));
983     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, DELETE_LIST, localDeleteEntries));
984 
985     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerLocal), OK);
986     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerNative), OK);
987 }
988 
989 /**
990  * @tc.name: Observer 007
991  * @tc.desc: observer callback data only can be received after a transaction committed
992  *  in multi-thread environment using the same delegate and observer.
993  * @tc.type: FUNC
994  * @tc.require: SR000EPA24
995  * @tc.author: fengxiaoyun
996  */
997 HWTEST_F(DistributeddbNbLocalBatchCrudTest, Observer007, TestSize.Level1)
998 {
999     /**
1000      * @tc.steps: step1. register a local observer.
1001      * @tc.expected: step1. operate successfully.
1002      */
1003     KvStoreObserverImpl observerLocal;
1004     EXPECT_EQ(g_nbLocalBatchDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_LOCAL_ONLY, &observerLocal), OK);
1005     /**
1006      * @tc.steps: step2. start a transaction, then PutBatch 10 records, PutLocal (k10,v10),
1007      *  and PutLocalBatch from k1 to k5.
1008      * @tc.expected: step2. operate successfully.
1009      */
1010     EXPECT_EQ(g_nbLocalBatchDelegate->StartTransaction(), OK);
1011     EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbLocalBatchDelegate, KEY_10, VALUE_10), OK);
1012     vector<Entry> insertEntries = { ENTRY_1, ENTRY_2, ENTRY_3, ENTRY_4, ENTRY_5 };
1013     DBStatus status = DistributedDBNbTestTools::PutLocalBatch(*g_nbLocalBatchDelegate, insertEntries);
1014     EXPECT_EQ(status, OK);
1015     /**
1016      * @tc.steps: step3. launch a thread to verify observer callback data, commit the transaction
1017      *  and then verify the data again.
1018      * @tc.expected: step3. there is no data before committing the transaction
1019      *  and there are 6 records in insert list of the local observer after committing.
1020      */
1021     insertEntries.push_back(ENTRY_10);
__anona43db3f90502() 1022     thread subThread([&insertEntries, &observerLocal]() {
1023         vector<Entry> emptyInsertEntries;
1024         EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ZERO_TIME, INSERT_LIST, emptyInsertEntries));
1025         EXPECT_EQ(g_nbLocalBatchDelegate->Commit(), OK);
1026         EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
1027     });
1028     subThread.join();
1029     /**
1030      * @tc.steps: step4. verify the data in main thread after the transaction committed in sub thread.
1031      * @tc.expected: step4. there are 6 records in insert list of the local observer.
1032      */
1033     EXPECT_TRUE(VerifyObserverResult(observerLocal, CHANGED_ONE_TIME, INSERT_LIST, insertEntries));
1034     EXPECT_EQ(g_nbLocalBatchDelegate->UnRegisterObserver(&observerLocal), OK);
1035 }
1036 } // end of namespace DistributeddbNbLocalBatchCrud