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;
__anon5fc0a19b0102() 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);
__anon5fc0a19b0202null377 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;
__anon5fc0a19b0302() 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);
__anon5fc0a19b0402null426 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);
__anon5fc0a19b0502() 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