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