1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <gtest/gtest.h>
16 #include <string>
17 #include <thread>
18 #include <vector>
19
20 #include "distributeddb_nb_test_tools.h"
21 #include "process_communicator_test_stub.h"
22
23 using namespace std;
24 using namespace testing;
25 #if defined TESTCASES_USING_GTEST_EXT
26 using namespace testing::ext;
27 #endif
28 using namespace DistributedDB;
29 using namespace DistributedDBDataGenerator;
30
31 namespace DistributeddbNbBatchCrud {
32 static std::condition_variable g_conditionNbBatchVar;
33 const int TWENTY_RECORDS = 20;
34 const int TWENTYFIVE_RECORDS = 25;
35 const int OBSERVER_COUNT = 8;
36 enum BatchTag {
37 PUTBATCH = 0,
38 DELETEBATCH = 1,
39 GETENTRIES = 2,
40 };
41 KvStoreNbDelegate *g_nbBatchCrudDelegate = nullptr;
42 KvStoreDelegateManager *g_manager = nullptr;
43
44 DistributedDB::CipherPassword g_passwd1;
45
46 class DistributeddbNbBatchCrudTest : public testing::Test {
47 public:
48 static void SetUpTestCase(void);
49 static void TearDownTestCase(void);
50 void SetUp();
51 void TearDown();
52 private:
53 };
54
SetUpTestCase(void)55 void DistributeddbNbBatchCrudTest::SetUpTestCase(void)
56 {
57 KvStoreDelegateManager *manager = new (std::nothrow) KvStoreDelegateManager(APP_ID_1, USER_ID_1);
58 ASSERT_NE(manager, nullptr);
59 manager->SetProcessLabel("MST", "GetDevicesID");
60 manager->SetProcessCommunicator(std::make_shared<ProcessCommunicatorTestStub>());
61 delete manager;
62 manager = nullptr;
63 (void)g_passwd1.SetValue(PASSWD_VECTOR_1.data(), PASSWD_VECTOR_1.size());
64 }
65
TearDownTestCase(void)66 void DistributeddbNbBatchCrudTest::TearDownTestCase(void)
67 {
68 }
69
SetUp(void)70 void DistributeddbNbBatchCrudTest::SetUp(void)
71 {
72 RemoveDir(DistributedDBConstant::NB_DIRECTOR);
73
74 UnitTest *test = UnitTest::GetInstance();
75 ASSERT_NE(test, nullptr);
76 const TestInfo *testinfo = test->current_test_info();
77 ASSERT_NE(testinfo, nullptr);
78 string testCaseName = string(testinfo->name());
79 MST_LOG("[SetUp] test case %s is start to run", testCaseName.c_str());
80
81 g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
82 ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr);
83 }
84
TearDown(void)85 void DistributeddbNbBatchCrudTest::TearDown(void)
86 {
87 MST_LOG("TearDownTestCase after case.");
88 ASSERT_NE(g_manager, nullptr);
89 EXPECT_TRUE(EndCaseDeleteDB(g_manager, g_nbBatchCrudDelegate, STORE_ID_1, g_option.isMemoryDb));
90 RemoveDir(DistributedDBConstant::NB_DIRECTOR);
91 }
92
93 /**
94 * @tc.name: SimpleData 001
95 * @tc.desc: Verify that single-ver db can support putbatch<keys,values> to db file.
96 * @tc.type: FUNC
97 * @tc.require: SR000DORPP
98 * @tc.author: fengxiaoyun
99 */
100 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData001, TestSize.Level1)
101 {
102 vector<Entry> entries1, entries2;
103 entries1.push_back(ENTRY_1);
104 entries1.push_back(ENTRY_2);
105 entries2.push_back(ENTRY_3);
106 entries2.push_back(ENTRY_4);
107
108 /**
109 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB and check the data in DB.
110 * @tc.expected: step1. PutBatch successfully and the (k1, v1), (k2, v2) is in DB.
111 */
112 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
113 Value valueResult;
114 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
115 EXPECT_EQ(valueResult, VALUE_1);
116 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
117 EXPECT_EQ(valueResult, VALUE_2);
118
119 /**
120 * @tc.steps: step2. call PutBatch interface to Put (k3, v3), (k4, v4) to DB and check the data in DB.
121 * @tc.expected: step2. PutBatch successfully and (k3, v3), (k4, v4) is in DB.
122 */
123 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
124 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), OK);
125 EXPECT_EQ(valueResult, VALUE_3);
126 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_4, valueResult), OK);
127 EXPECT_EQ(valueResult, VALUE_4);
128 }
129
130 /**
131 * @tc.name: SimpleData 002
132 * @tc.desc: Verify that single-ver db can support update entries in batches.
133 * @tc.type: FUNC
134 * @tc.require: SR000DORPP
135 * @tc.author: fengxiaoyun
136 */
137 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData002, TestSize.Level1)
138 {
139 vector<Entry> entries1, entries2, entriesGot;
140 entries1.push_back(ENTRY_1);
141 entries1.push_back(ENTRY_2);
142 entries2.push_back(ENTRY_1_2);
143 entries2.push_back(ENTRY_2_3);
144
145 /**
146 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB and check the data in DB.
147 * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2) in DB.
148 */
149 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
150 Value valueResult;
151 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
152 EXPECT_EQ(valueResult, VALUE_1);
153 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
154 EXPECT_EQ(valueResult, VALUE_2);
155 /**
156 * @tc.steps: step2. call PutBatch interface to update (k1, v1), (k2, v2) to (k1, v2), (k2, v3)
157 * and check the data in DB.
158 * @tc.expected: step2. PutBatch successfully and the value of k1 is v2, the value of k2 is v3.
159 */
160 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
161 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
162 EXPECT_EQ(valueResult, VALUE_2);
163 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
164 EXPECT_EQ(valueResult, VALUE_3);
165 }
166
167 /**
168 * @tc.name: SimpleData 003
169 * @tc.desc: Verify that single-ver db can support DeleteBatch<keys> from db file.
170 * @tc.type: FUNC
171 * @tc.require: SR000DORPP
172 * @tc.author: fengxiaoyun
173 */
174 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData003, TestSize.Level1)
175 {
176 vector<Entry> entries, entryResults;
177 entries.push_back(ENTRY_1);
178 entries.push_back(ENTRY_2);
179 entries.push_back(ENTRY_3);
180 entries.push_back(ENTRY_4);
181 std::vector<DistributedDB::Key> keys;
182 keys.push_back(KEY_1);
183 keys.push_back(KEY_2);
184 keys.push_back(KEY_3);
185 keys.push_back(KEY_4);
186 /**
187 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2), (k3, v3), (k4, v4) to DB
188 * and check the data in DB.
189 * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2), (k3, v3), (k4, v4) in DB.
190 */
191 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
192 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
193 EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
194
195 /**
196 * @tc.steps: step2. call DeleteBatch interface to delete (k1, v1), (k2, v2), (k3, v3), (k4, v4) from DB
197 * and check the data in DB.
198 * @tc.expected: step2. DeleteBatch successfully and the DB is empty.
199 */
200 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
201 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
202 }
203
204 /**
205 * @tc.name: SimpleData 004
206 * @tc.desc: Verify that single-ver db can putbatch <keys,values> value of which is null, but can't putBatch
207 * <keys,values> value of which is bigger than 4M.
208 * @tc.type: FUNC
209 * @tc.require: SR000DORPP
210 * @tc.author: fengxiaoyun
211 */
212 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData004, TestSize.Level1)
213 {
214 vector<Entry> entries1, entries2, entryResults;
215 entries1.push_back(ENTRY_1);
216 entries1.push_back(ENTRY_2_NULL);
217 entries2.push_back(ENTRY_3);
218 DistributedDB::Entry entry;
219 entry.key = KEY_4;
220 entry.value.assign(FOUR_M_LONG_STRING + 1, 'v'); // the size of value is 4M + 1
221 entries2.push_back(entry);
222
223 /**
224 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, NULL) to DB and check the data in DB.
225 * @tc.expected: step1. PutBatch successfully and the value of k1 is v1, and the value of k2 is null.
226 */
227 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
228 Value valueResult;
229 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
230 EXPECT_EQ(valueResult, VALUE_1);
231 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
232 EXPECT_EQ(valueResult, VALUE_EMPTY);
233
234 /**
235 * @tc.steps: step2. call PutBatch interface to Put (k3, v3), entry value of which is supper bigger than 4M
236 * and check the data in DB.
237 * @tc.expected: step2. PutBatch failed and returned INVALID_ARGS.
238 */
239 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), INVALID_ARGS);
240 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
241 EXPECT_EQ(entryResults.size(), entries1.size());
242 }
243
244 /**
245 * @tc.name: SimpleData 005
246 * @tc.desc: Verify that single-ver db can't putbatch <keys,values> key of which is null bigger than 1k.
247 * @tc.type: FUNC
248 * @tc.require: SR000DORPP
249 * @tc.author: fengxiaoyun
250 */
251 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData005, TestSize.Level1)
252 {
253 vector<Entry> entries1, entries2, entryResults;
254 DistributedDB::Entry entry1, entry2;
255 entries1.push_back(ENTRY_1);
256 entry1.key = KEY_EMPTY;
257 entry1.value = VALUE_2;
258 entries1.push_back(entry1);
259 entries2.push_back(ENTRY_3);
260 entry2.key.assign(ONE_K_LONG_STRING + 1, 'k'); // the size of key is 1k + 1
261 entry2.value = VALUE_4;
262 entries2.push_back(entry2);
263
264 /**
265 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (NULL, v2) to DB and check the data in DB.
266 * @tc.expected: step1. PutBatch failed and return INVALID_ARGS.
267 */
268 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), INVALID_ARGS);
269
270 /**
271 * @tc.steps: step2. call PutBatch interface to Put (k3, v3), entry value of which is supper bigger than 4M
272 * and check the data in DB.
273 * @tc.expected: step2. PutBatch failed and returned INVALID_ARGS.
274 */
275 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), INVALID_ARGS);
276 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
277 }
278
279 /**
280 * @tc.name: SimpleData 006
281 * @tc.desc: Verify that single-ver db can't putbatch <keys,values> key of which is null bigger than 1k.
282 * @tc.type: FUNC
283 * @tc.require: SR000DORPP
284 * @tc.author: fengxiaoyun
285 */
286 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData006, TestSize.Level1)
287 {
288 vector<Entry> entries, entryResults;
289 entries.push_back(ENTRY_1);
290 entries.push_back(ENTRY_2);
291 entries.push_back(ENTRY_3);
292 entries.push_back(ENTRY_4);
293
294 vector<Key> keys1, keys2;
295 keys1.push_back(KEY_1);
296 DistributedDB::Key supperKey;
297 supperKey.assign(ONE_K_LONG_STRING + 1, 'k'); // the size of key is 1k + 1
298 keys1.push_back(supperKey);
299 keys2.push_back(KEY_2);
300 keys2.push_back(KEY_EMPTY);
301
302 /**
303 * @tc.steps: step1. PutBatch (k1,v1)(k2,v2)(k3,v3)(k4,v4) to db.
304 * @tc.expected: step1. PutBatch successfully.
305 */
306 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
307 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
308 EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
309
310 /**
311 * @tc.steps: step2. call DeleteBatch interface to delete k1, supperKey from DB and check the data in DB.
312 * @tc.expected: step2. DeleteBatch failed and the data in DB is not changed.
313 */
314 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1), INVALID_ARGS);
315 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
316 EXPECT_EQ(entryResults.size(), entries.size());
317 /**
318 * @tc.steps: step3. call DeleteBatch interface to delete k2 which is KEY_EMPTY from DB and check the data in DB.
319 * @tc.expected: step3. DeleteBatch failed and the data in DB is not changed.
320 */
321 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys2), INVALID_ARGS);
322 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
323 EXPECT_EQ(entryResults.size(), entries.size());
324 }
325
326 /**
327 * @tc.name: SimpleData 007
328 * @tc.desc: Verify that single-ver db deletebatch the data that are noexist party will return OK, but will
329 * return NOT_FOUND when the keys are all noexist.
330 * @tc.type: FUNC
331 * @tc.require: SR000DORPP
332 * @tc.author: fengxiaoyun
333 */
334 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData007, TestSize.Level1)
335 {
336 vector<Entry> entries, entryResults;
337 entries.push_back(ENTRY_1);
338 entries.push_back(ENTRY_2);
339 std::vector<DistributedDB::Key> keys;
340 keys.push_back(KEY_1);
341 keys.push_back(KEY_2);
342 keys.push_back(KEY_3);
343
344 /**
345 * @tc.steps: step1. call PutBatch interface to Put (k1, v1), (k2, v2) to DB
346 * and check the data in DB.
347 * @tc.expected: step1. PutBatch successfully and can find (k1, v1), (k2, v2) in DB.
348 */
349 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
350 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
351 EXPECT_TRUE(CompareEntriesVector(entryResults, entries));
352
353 /**
354 * @tc.steps: step2. call DeleteBatch interface to delete (k1,k2,k3) from DB
355 * and check the data in DB.
356 * @tc.expected: step2. DeleteBatch successfully and the DB is empty.
357 */
358 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
359 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
360
361 /**
362 * @tc.steps: step3. call DeleteBatch interface to delete (k1,k2,k3) from DB
363 * and check the data in DB.
364 * @tc.expected: step3. DeleteBatch return OK and the DB is empty.
365 */
366 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
367 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
368 }
369
370 /**
371 * @tc.name: SimpleData 008
372 * @tc.desc: Verify that when the items of batch operation over 128, the interface will return INVALID_ARGS.
373 * @tc.type: FUNC
374 * @tc.require: SR000DORPP
375 * @tc.author: fengxiaoyun
376 */
377 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData008, TestSize.Level1)
378 {
379 vector<Entry> entriesBatch, entryResults;
380 vector<Key> allKeys;
381 GenerateFixedRecords(entriesBatch, allKeys, BATCH_RECORDS + 1, FOUR_M_LONG_STRING, ONE_M_LONG_STRING);
382
383 /**
384 * @tc.steps: step1. PutBatch 129 items to DB and GetEntries().
385 * @tc.expected: step1. PutBatch failed and GetEntries return NOT_FOUND.
386 */
387 EXPECT_EQ(g_nbBatchCrudDelegate->PutBatch(entriesBatch), INVALID_ARGS);
388 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
389
390 /**
391 * @tc.steps: step2. DeleteBatch 129 items to DB and GetEntries().
392 * @tc.expected: step2. DeleteBatch failed and GetEntries return NOT_FOUND.
393 */
394 EXPECT_EQ(g_nbBatchCrudDelegate->DeleteBatch(allKeys), INVALID_ARGS);
395 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
396 }
397
398 /**
399 * @tc.name: SimpleData 009
400 * @tc.desc: Verify that rekey will return busy when do batch operation.
401 * @tc.type: FUNC
402 * @tc.require: SR000DORPP
403 * @tc.author: fengxiaoyun
404 */
405 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData009, TestSize.Level2)
406 {
407 vector<Entry> entriesBatch, entryResults;
408 vector<Key> allKeys;
409 GenerateFixedRecords(entriesBatch, allKeys, TEN_RECORDS, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
410 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
411
412 /**
413 * @tc.steps: step1. PutBatch <keys,values> to db.
414 * @tc.expected: step1. PutBatch successfully.
415 */
416 bool subPutBatchFlag = false;
__anon306584110102() 417 thread subThread([&entriesBatch, &subPutBatchFlag]() {
418 DBStatus status = g_nbBatchCrudDelegate->PutBatch(entriesBatch);
419 EXPECT_TRUE(status == OK || status == BUSY);
420 subPutBatchFlag = true;
421 g_conditionNbBatchVar.notify_all();
422 });
423 subThread.detach();
424
425 /**
426 * @tc.steps: step2. call Rekey when step1 is running.
427 * @tc.expected: step2. rekey return BUSY.
428 */
429 std::this_thread::sleep_for(std::chrono::microseconds(WAIT_FOR_LONG_TIME));
430 DBStatus rekeyStatus = g_nbBatchCrudDelegate->Rekey(g_passwd1);
431 EXPECT_TRUE(rekeyStatus == OK || rekeyStatus == BUSY);
432
433 /**
434 * @tc.steps: step3. GetEntries() from db.
435 * @tc.expected: step3. GetEntries the data that step1 putbatch.
436 */
437 std::mutex count;
438 std::unique_lock<std::mutex> lck(count);
__anon306584110202null439 g_conditionNbBatchVar.wait(lck, [&]{return subPutBatchFlag;});
440 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
441 EXPECT_EQ(entryResults.size(), entriesBatch.size());
442 }
443
444 /**
445 * @tc.name: SimpleData 010
446 * @tc.desc: Verify that import will return busy when do batch operation.
447 * @tc.type: FUNC
448 * @tc.require: SR000DORPP
449 * @tc.author: fengxiaoyun
450 */
451 HWTEST_F(DistributeddbNbBatchCrudTest, SimpleData010, TestSize.Level2)
452 {
453 const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "export";
454 SetDir(importPath);
455 std::string filePath = importPath + "/bkpDB.bin";
456 EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), OK);
457 vector<Entry> entriesBatch, entryResults;
458 vector<Key> allKeys;
459 GenerateFixedRecords(entriesBatch, allKeys, NB_PREDATA_NUM, ONE_K_LONG_STRING, ONE_M_LONG_STRING);
460 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
461
462 /**
463 * @tc.steps: step1. DeleteBatch data.
464 * @tc.expected: step1. operation successfully.
465 */
466 bool subDeleteBatchFlag = false;
__anon306584110302() 467 thread subThread([&subDeleteBatchFlag, &allKeys]() {
468 DBStatus deleteStatus = g_nbBatchCrudDelegate->DeleteBatch(allKeys);
469 EXPECT_TRUE(deleteStatus == OK || deleteStatus == BUSY);
470 subDeleteBatchFlag = true;
471 g_conditionNbBatchVar.notify_all();
472 });
473 subThread.detach();
474
475 /**
476 * @tc.steps: step2. call import interface when step1 is running.
477 * @tc.expected: step2. import return BUSY.
478 */
479 std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
480 DBStatus importStatus = g_nbBatchCrudDelegate->Import(filePath, NULL_PASSWD);
481 EXPECT_TRUE(importStatus == OK || importStatus == BUSY);
482
483 /**
484 * @tc.steps: step3. GetEntries() from db.
485 * @tc.expected: step3. GetEntries return NOT_FOUND.
486 */
487 std::mutex count;
488 std::unique_lock<std::mutex> lck(count);
__anon306584110402null489 g_conditionNbBatchVar.wait(lck, [&]{return subDeleteBatchFlag;});
490 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), NOT_FOUND);
491 }
492
TestBatchComplexAction(vector<Entry> & entries1,vector<Entry> & entries12)493 void TestBatchComplexAction(vector<Entry> &entries1, vector<Entry> &entries12)
494 {
495 /**
496 * @tc.steps: step3. PutBatch (k1,v1)(k2,v2) and then get.
497 * @tc.expected: step3. PutBatch successfully get null of k1,k2.
498 */
499 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
500 EXPECT_EQ(status, OK);
501 Value valueResult;
502 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
503 EXPECT_EQ(valueResult, VALUE_1);
504 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
505 EXPECT_EQ(valueResult, VALUE_2);
506
507 /**
508 * @tc.steps: step4. PutBatch (k1,v2)(k2,v3) and then get.
509 * @tc.expected: step4. PutBatch successfully get v2 of k1,v3 of k2.
510 */
511 status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries12);
512 EXPECT_EQ(status, OK);
513 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
514 EXPECT_EQ(valueResult, VALUE_2);
515 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
516 EXPECT_EQ(valueResult, VALUE_3);
517 }
518
519 /**
520 * @tc.name: ComplexData 001
521 * @tc.desc: Verify that single-ver db can support batch CRUD for the same keys continuously.
522 * @tc.type: FUNC
523 * @tc.require: SR000DORPP
524 * @tc.author: fengxiaoyun
525 */
526 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData001, TestSize.Level1)
527 {
528 vector<Entry> entries1;
529 entries1.push_back(ENTRY_1);
530 entries1.push_back(ENTRY_2);
531 vector<Entry> entries12;
532 entries12.push_back(ENTRY_1_2);
533 entries12.push_back(ENTRY_2_3);
534
535 vector<Key> keys1;
536 keys1.push_back(ENTRY_1.key);
537 keys1.push_back(ENTRY_2.key);
538
539 /**
540 * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
541 * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
542 */
543 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
544 EXPECT_EQ(status, OK);
545 Value valueResult;
546 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
547 EXPECT_EQ(valueResult, VALUE_1);
548 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
549 EXPECT_EQ(valueResult, VALUE_2);
550
551 /**
552 * @tc.steps: step2. DeleteBatch (k1)(k2) and then get.
553 * @tc.expected: step2. DeleteBatch successfully get return NOT_FOUND.
554 */
555 status = DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1);
556 EXPECT_EQ(status, OK);
557 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
558 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
559
560 TestBatchComplexAction(entries1, entries12);
561
562 /**
563 * @tc.steps: step5. DeleteBatch (k1)(k2) and then get.
564 * @tc.expected: step5. DeleteBatch successfully get return NOT_FOUND.
565 */
566 status = DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys1);
567 EXPECT_EQ(status, OK);
568 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
569 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
570 }
571
572 /**
573 * @tc.name: ComplexData 002
574 * @tc.desc: Verify that single-ver db can support batch CRUD for the different keys continuously.
575 * @tc.type: FUNC
576 * @tc.require: SR000DORPP
577 * @tc.author: fengxiaoyun
578 */
579 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData002, TestSize.Level2)
580 {
581 vector<Entry> entriesBatch, entriesRes;
582 vector<Key> allKeys;
583 /**
584 * @tc.steps: step1-2. PutBatch 100 items of (keys,values) then query and deletebatch for 100 times.
585 * @tc.expected: step1-2. operate successfully.
586 */
587 GenerateFixedLenRandRecords(entriesBatch, allKeys, ONE_HUNDRED_RECORDS, KEY_SIX_BYTE, KEY_ONE_HUNDRED_BYTE);
588 for (int count = 0; count < ONE_HUNDRED_RECORDS; count++) {
589 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
590 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
591 EXPECT_EQ(entriesRes.size(), entriesBatch.size());
592 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys), OK);
593 entriesRes.clear();
594 }
595
596 /**
597 * @tc.steps: step3. PutBatch 20 items of (keys,values) and then query.
598 * @tc.expected: step3. PutBatch successfully GetEntries is right.
599 */
600 entriesBatch.clear();
601 GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys, entriesBatch);
602 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch);
603 EXPECT_EQ(status, OK);
604 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
605 EXPECT_EQ(entriesRes.size(), entriesBatch.size());
606 }
607
CheckBatchCrud(vector<Entry> entries,vector<Key> keys)608 void CheckBatchCrud(vector<Entry> entries, vector<Key> keys)
609 {
610 /**
611 * @tc.steps: step3. Put(k1,v3) Put(k2,v4) Put(k3,v3) and then get.
612 * @tc.expected: step3. Put successfully get v3 of k1,v4 of k2,v3 of k3.
613 */
614 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_1_3.key, ENTRY_1_3.value), OK);
615 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_2_4.key, ENTRY_2_4.value), OK);
616 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, ENTRY_3.key, ENTRY_3.value), OK);
617 vector<Entry> entriesRes;
618 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesRes), OK);
619 EXPECT_TRUE(CompareEntriesVector(entriesRes, entries));
620 /**
621 * @tc.steps: step4. DeleteBatch (k2)(k3) and then get.
622 * @tc.expected: step4. DeleteBatch successfully get v3 of k1,get return NOT_FOUND of k2,k3.
623 */
624 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
625 Value valueResult;
626 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
627 EXPECT_EQ(valueResult, VALUE_3);
628 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), NOT_FOUND);
629 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), NOT_FOUND);
630 /**
631 * @tc.steps: step5. PutBatch(k1,v2)(k2,v3)(k3,v4) then get.
632 * @tc.expected: step5. Putbatch successfully, get v2 of k1, v3 of k2, v4 of k3.
633 */
634 vector<Entry> entries123;
635 entries123.push_back(ENTRY_1_2);
636 entries123.push_back(ENTRY_2_3);
637 entries123.push_back(ENTRY_3_4);
638 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries123);
639 EXPECT_EQ(status, OK);
640 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
641 EXPECT_EQ(valueResult, VALUE_2);
642 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
643 EXPECT_EQ(valueResult, VALUE_3);
644 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, valueResult), OK);
645 EXPECT_EQ(valueResult, VALUE_4);
646 }
647
648 /**
649 * @tc.name: ComplexData 003
650 * @tc.desc: Verify that can batch and single crud continuously.
651 * @tc.type: FUN
652 * @tc.require: SR000DORPP
653 * @tc.author: fengxiaoyun
654 */
655 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData003, TestSize.Level1)
656 {
657 vector<Entry> entries1;
658 entries1.push_back(ENTRY_1);
659 entries1.push_back(ENTRY_2);
660 vector<Entry> entries123;
661 entries123.push_back(ENTRY_1_3);
662 entries123.push_back(ENTRY_2_4);
663 entries123.push_back(ENTRY_3);
664 vector<Key> keys23;
665 keys23.push_back(ENTRY_2.key);
666 keys23.push_back(ENTRY_3.key);
667
668 /**
669 * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
670 * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
671 */
672 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1);
673 EXPECT_EQ(status, OK);
674 Value valueResult;
675 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), OK);
676 EXPECT_EQ(valueResult, VALUE_1);
677 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
678 EXPECT_EQ(valueResult, VALUE_2);
679
680 /**
681 * @tc.steps: step2. delete k1 and then get.
682 * @tc.expected: step2. delete successfully get return NOT_FOUND of k1, get v2 of k2.
683 */
684 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
685 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, valueResult), NOT_FOUND);
686 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, valueResult), OK);
687 EXPECT_EQ(valueResult, VALUE_2);
688
689 CheckBatchCrud(entries123, keys23);
690 }
691
NbBatchCRUDThread(BatchTag tag)692 void NbBatchCRUDThread(BatchTag tag)
693 {
694 vector<Entry> entriesBatch;
695 vector<Key> allKeys;
696 GenerateFixedLenRandRecords(entriesBatch, allKeys, TWENTY_RECORDS,
697 KEY_SIX_BYTE, KEY_ONE_HUNDRED_BYTE);
698 if (tag == PUTBATCH) {
699 DBStatus status = DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch);
700 EXPECT_EQ(status, OK);
701 } else if (tag == DELETEBATCH) {
702 DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys);
703 } else if (tag == GETENTRIES) {
704 vector<Entry> entryResults;
705 DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, {'k'}, entryResults);
706 }
707 }
708
709 /**
710 * @tc.name: ComplexData 005
711 * @tc.desc: test that it won't be crash when there are 20 threads to batch operation.
712 * @tc.type: Pressure
713 * @tc.require: SR000DORPP
714 * @tc.author: fengxiaoyun
715 */
716 HWTEST_F(DistributeddbNbBatchCrudTest, ComplexData005, TestSize.Level2)
717 {
718 /**
719 * @tc.steps: step1. start 20 threads to do batch operation.
720 * @tc.expected: step1. process is normal and no crash.
721 */
722 std::vector<std::thread> threads;
723 for (int threadId = 0; threadId < TWENTY_RECORDS; ++threadId) {
724 int indexOption = GetRandInt(MODE_RAND_MIN, MODE_RAND_MAX);
725 threads.push_back(std::thread(NbBatchCRUDThread, BatchTag(indexOption)));
726 }
727 for (auto& th : threads) {
728 th.join();
729 }
730 std::this_thread::sleep_for(std::chrono::seconds(UNIQUE_SECOND));
731 }
732
733 /**
734 * @tc.name: Observer 001
735 * @tc.desc: Verify that putbatch will trigger callback after register observer for specific key.
736 * @tc.type: FUNC
737 * @tc.require: SR000DORPP
738 * @tc.author: fengxiaoyun
739 */
740 HWTEST_F(DistributeddbNbBatchCrudTest, Observer001, TestSize.Level1)
741 {
742 KvStoreObserverImpl observer1, observer2, observer3;
743 vector<Entry> entries1, entries2;
744 entries1.push_back(ENTRY_1);
745 entries1.push_back(ENTRY_2);
746 entries2.push_back(ENTRY_2_3);
747 entries2.push_back(ENTRY_3);
748 vector<DistributedDB::Entry> observerCallbackEntries;
749
750 /**
751 * @tc.steps: step1. register observer1,observer2,observer3 for k1,k2,k3 with
752 * mode = OBSERVER_CHANGES_NATIVE.
753 * @tc.expected: step1. register successfully.
754 */
755 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
756 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
757 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
758
759 /**
760 * @tc.steps: step2. putbatch (k1,v1)(k2,v2) to db and check observer callback.
761 * @tc.expected: step2. putbatch successfully and the callback of observer1 and observer2
762 * are all once INSERT_LIST.
763 */
764 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
765 observerCallbackEntries.push_back(ENTRY_1);
766 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
767 observerCallbackEntries.clear();
768 observerCallbackEntries.push_back(ENTRY_2);
769 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
770 observer1.Clear();
771 observer2.Clear();
772 observer3.Clear();
773
774 /**
775 * @tc.steps: step3. putbatch (k2,v3)(k3,v3) to db and check observer callback.
776 * @tc.expected: step3. putbatch successfully and the callback of observer2 is once UPDATE_LIST,
777 * the callback of observer3 is once INSERT_LIST, there is no callback of observer1.
778 */
779 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
780 observerCallbackEntries.clear();
781 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
782 observerCallbackEntries.push_back(ENTRY_2_3);
783 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
784 observerCallbackEntries.clear();
785 observerCallbackEntries.push_back(ENTRY_3);
786 EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
787 }
788
789 /**
790 * @tc.name: Observer 002
791 * @tc.desc: Verify that deletebatch will trigger callback after register observer for specific key.
792 * @tc.type: FUNC
793 * @tc.require: SR000DORPP
794 * @tc.author: fengxiaoyun
795 */
796 HWTEST_F(DistributeddbNbBatchCrudTest, Observer002, TestSize.Level1)
797 {
798 KvStoreObserverImpl observer1, observer2, observer3;
799 vector<Entry> entries1, entryResults;
800 entries1.push_back(ENTRY_1);
801 entries1.push_back(ENTRY_2);
802 std::vector<DistributedDB::Key> keys;
803 keys.push_back(KEY_3);
804 keys.push_back(KEY_2);
805 keys.push_back(KEY_1);
806 vector<DistributedDB::Entry> observerCallbackEntries;
807
808 /**
809 * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
810 * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
811 */
812 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
813 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
814 EXPECT_TRUE(CompareEntriesVector(entryResults, entries1));
815
816 /**
817 * @tc.steps: step2. register observer1,observer2,observer3 for k1,k2,k3 with
818 * mode = OBSERVER_CHANGES_NATIVE.
819 * @tc.expected: step2. register successfully.
820 */
821 DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
822 EXPECT_EQ(status, OK);
823 status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
824 EXPECT_EQ(status, OK);
825 status = g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3);
826 EXPECT_EQ(status, OK);
827
828 /**
829 * @tc.steps: step3. deletebatch (k1,k2,k3) and check observer callback.
830 * @tc.expected: step3. deletebatch successfully and the callback of observer1 and observer2
831 * are all once DELETE_LIST, the observer3 won't receive callback.
832 */
833 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
834 observerCallbackEntries.push_back(ENTRY_1);
835 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
836 observerCallbackEntries.clear();
837 observerCallbackEntries.push_back(ENTRY_2);
838 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
839 observerCallbackEntries.clear();
840 EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ZERO_TIME, ListType::DELETE_LIST, observerCallbackEntries));
841 }
842
843 /**
844 * @tc.name: Observer 003
845 * @tc.desc: Verify that putbatch will trigger callback after register observer for specific key.
846 * @tc.type: FUNC
847 * @tc.require: SR000DORPP
848 * @tc.author: fengxiaoyun
849 */
850 HWTEST_F(DistributeddbNbBatchCrudTest, Observer003, TestSize.Level1)
851 {
852 KvStoreObserverImpl observer1, observer2, observer3;
853 vector<Entry> entries1, entries2;
854 entries1.push_back(ENTRY_1);
855 entries1.push_back(ENTRY_1_2);
856 entries1.push_back(ENTRY_2);
857 entries2.push_back(ENTRY_2_3);
858 entries2.push_back(ENTRY_2_4);
859 entries2.push_back(ENTRY_3);
860 vector<DistributedDB::Entry> observerCallbackEntries;
861
862 /**
863 * @tc.steps: step1. register observer1,observer2,observer3 for k1,k2,k3 with
864 * mode = OBSERVER_CHANGES_NATIVE.
865 * @tc.expected: step1. register successfully.
866 */
867 DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
868 EXPECT_EQ(status, OK);
869 status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
870 EXPECT_EQ(status, OK);
871 status = g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3);
872 EXPECT_EQ(status, OK);
873
874 /**
875 * @tc.steps: step2. putbatch (k1,v1)(k2,v2) to db and check observer callback.
876 * @tc.expected: step2. putbatch successfully and the callback of observer1 and observer2
877 * are all once INSERT_LIST.
878 */
879 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
880 observerCallbackEntries.push_back(ENTRY_1_2);
881 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
882 observerCallbackEntries.clear();
883 observerCallbackEntries.push_back(ENTRY_2);
884 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
885 observer1.Clear();
886 observer2.Clear();
887 observer3.Clear();
888
889 /**
890 * @tc.steps: step3. putbatch (k2,v3)(k3,v3) to db and check observer callback.
891 * @tc.expected: step3. putbatch successfully and the callback of observer2 is once UPDATE_LIST,
892 * the callback of observer3 is once INSERT_LIST, there is no callback of observer1.
893 */
894 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
895 observerCallbackEntries.clear();
896 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
897 observerCallbackEntries.push_back(ENTRY_2_4);
898 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::UPDATE_LIST, observerCallbackEntries));
899 observerCallbackEntries.clear();
900 observerCallbackEntries.push_back(ENTRY_3);
901 EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, ListType::INSERT_LIST, observerCallbackEntries));
902 }
903
904 /**
905 * @tc.name: Observer 004
906 * @tc.desc: Verify that deletebatch will trigger callback after register observer for specific key.
907 * @tc.type: FUNC
908 * @tc.require: SR000DORPP
909 * @tc.author: fengxiaoyun
910 */
911 HWTEST_F(DistributeddbNbBatchCrudTest, Observer004, TestSize.Level1)
912 {
913 KvStoreObserverImpl observer1, observer2;
914 vector<Entry> entries1, entryResults;
915 entries1.push_back(ENTRY_1);
916 entries1.push_back(ENTRY_2);
917 std::vector<DistributedDB::Key> keys;
918 keys.push_back(KEY_1);
919 keys.push_back(KEY_2);
920 keys.push_back(KEY_1);
921 vector<DistributedDB::Entry> observerCallbackEntries;
922
923 /**
924 * @tc.steps: step1. PutBatch (k1,v1)(k2,v2) and then get.
925 * @tc.expected: step1. PutBatch successfully get v1 of k1,v2 of k2.
926 */
927 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
928 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entryResults), OK);
929 EXPECT_TRUE(CompareEntriesVector(entryResults, entries1));
930
931 /**
932 * @tc.steps: step2. register observer1,observer2 for k1, k2 with mode = OBSERVER_CHANGES_NATIVE.
933 * @tc.expected: step2. register successfully.
934 */
935 DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1);
936 EXPECT_EQ(status, OK);
937 status = g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2);
938 EXPECT_EQ(status, OK);
939
940 /**
941 * @tc.steps: step3. deletebatch (k1,k2,k1) and check observer callback.
942 * @tc.expected: step3. deletebatch successfully and observer1 and observer2 are both triggered once.
943 */
944 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
945 observerCallbackEntries.push_back(ENTRY_1);
946 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
947 observerCallbackEntries.clear();
948 observerCallbackEntries.push_back(ENTRY_2);
949 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, ListType::DELETE_LIST, observerCallbackEntries));
950 }
951
952 /**
953 * @tc.name: Observer 005
954 * @tc.desc: Verify that deletebatch will trigger once callback after register observer for all key.
955 * @tc.type: FUNC
956 * @tc.require: SR000DORPP
957 * @tc.author: fengxiaoyun
958 */
959 HWTEST_F(DistributeddbNbBatchCrudTest, Observer005, TestSize.Level1)
960 {
961 vector<Entry> entriesBatch;
962 vector<Key> allKeys;
963 GenerateRecords(TEN_RECORDS, DEFAULT_START, allKeys, entriesBatch);
964
965 /**
966 * @tc.steps: step1. register 8 observers for all key.
967 * @tc.expected: step1. register successfully.
968 */
969 KvStoreObserverImpl observerNative[OBSERVER_COUNT];
970 for (int obsCnt = 0; obsCnt < OBSERVER_COUNT; obsCnt++) {
971 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE,
972 &observerNative[obsCnt]), OK);
973 }
974
975 /**
976 * @tc.steps: step2. putbatch 10 items of <keys,values> to db and check observer callback.
977 * @tc.expected: step2. putbatch successfully and the callback of all observers are once
978 * INSERT_LIST with 10 items data.
979 */
980 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
981 for (int index = 0; index < OBSERVER_COUNT; index++) {
982 EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::INSERT_LIST, entriesBatch));
983 }
984 for (int index = 0; index < OBSERVER_COUNT; index++) {
985 observerNative[index].Clear();
986 }
987
988 /**
989 * @tc.steps: step3. putbatch 10 items of <keys,values> to db and check observer callback.
990 * @tc.expected: step3. putbatch successfully and the callback of all observers are once
991 * UPDATE_LIST with 10 items data.
992 */
993 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entriesBatch), OK);
994 for (int index = 0; index < OBSERVER_COUNT; index++) {
995 EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::UPDATE_LIST, entriesBatch));
996 }
997 for (int index = 0; index < OBSERVER_COUNT; index++) {
998 observerNative[index].Clear();
999 }
1000
1001 /**
1002 * @tc.steps: step4. deletebatch 10 items of <keys> from db and check observer callback.
1003 * @tc.expected: step4. putbatch successfully and the callback of all observers are once
1004 * DELETE_LIST with 10 items data.
1005 */
1006 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, allKeys), OK);
1007 for (int index = 0; index < OBSERVER_COUNT; index++) {
1008 EXPECT_TRUE(VerifyObserverResult(observerNative[index], CHANGED_ONE_TIME, ListType::DELETE_LIST, entriesBatch));
1009 }
1010 }
1011
1012 /**
1013 * @tc.name: Transaction 001
1014 * @tc.desc: start transaction success and can only native DB support to put and local DB not.
1015 * @tc.type: FUNC
1016 * @tc.require: SR000DORPP
1017 * @tc.author: fengxiaoyun
1018 */
1019 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction001, TestSize.Level1)
1020 {
1021 /**
1022 * @tc.steps: step1. start transaction.
1023 * @tc.expected: step1. start successfully.
1024 */
1025 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1026
1027 /**
1028 * @tc.steps: step2. use Put interface to put (k1, v1) and Get the value of k1;
1029 * @tc.expected: step2. put successfully but can't find data in db
1030 */
1031 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1032 Value value;
1033 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1034 EXPECT_EQ(value, VALUE_1);
1035 /**
1036 * @tc.steps: step3. use PutLocal interface to put (k2, v2) and Get the value of k2;
1037 * @tc.expected: step3. PutLocal failed and returned NOT_SUPPORT and can't find data in db
1038 */
1039 EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
1040 EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1041 EXPECT_EQ(value, VALUE_2);
1042
1043 /**
1044 * @tc.steps: step4. commit the transaction and check the data in db again.
1045 * @tc.expected: step4. commit successfully.
1046 */
1047 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1048 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1049 EXPECT_EQ(value, VALUE_1);
1050 EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1051 EXPECT_EQ(value, VALUE_2);
1052 }
1053
1054 /**
1055 * @tc.name: Transaction 002
1056 * @tc.desc: verify that the db support Rollback but can't Rollback repeatedly.
1057 * @tc.type: FUNC
1058 * @tc.require: SR000DORPP
1059 * @tc.author: fengxiaoyun
1060 */
1061 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction002, TestSize.Level1)
1062 {
1063 /**
1064 * @tc.steps: step1. start transaction.
1065 * @tc.expected: step1. start successfully.
1066 */
1067 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1068
1069 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1070 Value value;
1071 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1072 EXPECT_EQ(value, VALUE_1);
1073 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
1074 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
1075 EXPECT_EQ(value, VALUE_2);
1076
1077 /**
1078 * @tc.steps: step2. use Delete interface to delete (k1, v1) and Get the value of k1.
1079 * @tc.expected: step2. delete successfully and can't find k1 in db.
1080 */
1081 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1082 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1083
1084 /**
1085 * @tc.steps: step3. Rollback and check the data in db again.
1086 * @tc.expected: step3. Rollback successfully and can't find (k1, v1) and (k2, v2) in db.
1087 */
1088 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1089 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1090 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), NOT_FOUND);
1091
1092 /**
1093 * @tc.steps: step4. Rollback again.
1094 * @tc.expected: step4. returned error.
1095 */
1096 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1097 }
1098
1099 /**
1100 * @tc.name: Transaction 003
1101 * @tc.desc: verify that it can't start transaction repeatedly.
1102 * @tc.type: FUNC
1103 * @tc.require: SR000DORPP
1104 * @tc.author: fengxiaoyun
1105 */
1106 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction003, TestSize.Level1)
1107 {
1108 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1109 /**
1110 * @tc.steps: step1. start transaction and update (k1, v1) to (k1, v2).
1111 * @tc.expected: step1. start and put successfully but the value of k1 is still v1.
1112 */
1113 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1114
1115 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1116 Value value;
1117 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1118 EXPECT_EQ(value, VALUE_2);
1119 /**
1120 * @tc.steps: step2. start the transaction again.
1121 * @tc.expected: step2. returned error.
1122 */
1123 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), DB_ERROR);
1124
1125 /**
1126 * @tc.steps: step3. commit and check the records in db.
1127 * @tc.expected: step3. commit successfully and the value of k1 is v2.
1128 */
1129 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1130 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1131 EXPECT_EQ(value, VALUE_2);
1132 }
1133
1134 /**
1135 * @tc.name: Transaction 004
1136 * @tc.desc: verify that can't commit without start transaction and can putBatch when start transaction.
1137 * @tc.type: FUNC
1138 * @tc.require: SR000DORPP
1139 * @tc.author: fengxiaoyun
1140 */
1141 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction004, TestSize.Level1)
1142 {
1143 /**
1144 * @tc.steps: step1. commit the transaction without start it.
1145 * @tc.expected: step1. commit failed.
1146 */
1147 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1148 /**
1149 * @tc.steps: step2. start the transaction and putBatch 128 records and check the data with GetEntries.
1150 * @tc.expected: step2. start success and GetEntries returns no entry.
1151 */
1152 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1153
1154 std::vector<DistributedDB::Entry> entries, entriesGot;
1155 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1156 GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
1157 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1158 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1159 EXPECT_EQ(entriesGot.size(), BATCH_RECORDS);
1160
1161 /**
1162 * @tc.steps: step3. commit and GetEntries in db.
1163 * @tc.expected: step3. commit successfully and can find the entries in db.
1164 */
1165 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1166 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1167 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1168 }
1169
1170 /**
1171 * @tc.name: Transaction 005
1172 * @tc.desc: verify that can't Rollback without start transaction and can updateBatch when start transaction.
1173 * @tc.type: FUNC
1174 * @tc.require: SR000DORPP
1175 * @tc.author: fengxiaoyun
1176 */
1177 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction005, TestSize.Level1)
1178 {
1179 /**
1180 * @tc.steps: step1. Rollback the transaction without start it and PutBatch 10 records to DB.
1181 * @tc.expected: step1. Rollback failed and PutBatch success.
1182 */
1183 std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1184 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1185 GenerateAppointPrefixAndSizeRecords(entries1, entrySize, TEN_RECORDS, {'k'}, {'a'});
1186 GenerateAppointPrefixAndSizeRecords(entries2, entrySize, TEN_RECORDS, {'k'}, {'b'});
1187 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1188
1189 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1190 /**
1191 * @tc.steps: step2. start the transaction and update the 10 records Batchly and check the data with GetEntries.
1192 * @tc.expected: step2. start success and GetEntries return the entries is equal to entres1.
1193 */
1194 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1195
1196 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1197 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1198 EXPECT_TRUE(CompareEntriesVector(entries2, entriesGot));
1199
1200 /**
1201 * @tc.steps: step3. commit and GetEntries in db.
1202 * @tc.expected: step3. commit successfully and the entriesGot is equal to entries2.
1203 */
1204 entriesGot.clear();
1205 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1206 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1207 EXPECT_TRUE(CompareEntriesVector(entries2, entriesGot));
1208 }
1209
1210 /**
1211 * @tc.name: Transaction 006
1212 * @tc.desc: verify that can DeleteBatch when start transaction.
1213 * @tc.type: FUNC
1214 * @tc.require: SR000DORPP
1215 * @tc.author: fengxiaoyun
1216 */
1217 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction006, TestSize.Level1)
1218 {
1219 std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1220 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1221 GenerateAppointPrefixAndSizeRecords(entries1, entrySize, TEN_RECORDS, {'k'}, {'a'});
1222 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1223
1224 for (unsigned int index = 0; index < (entries1.size() / 2); index++) {
1225 entries2.push_back(entries1[index]);
1226 }
1227 std::vector<DistributedDB::Key> keys;
1228 for (auto const &entry : entries2) {
1229 keys.push_back(entry.key);
1230 }
1231
1232 /**
1233 * @tc.steps: step1. start the transaction and Deleted Batchly 5 of the 10 records inserted to db.
1234 * @tc.expected: step1. start and delete success and GetEntries return the entries is equal to entres1.
1235 */
1236 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1237
1238 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1239 entries1.erase(entries1.begin(), entries1.begin() + FIVE_RECORDS);
1240 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1241 EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1242
1243 /**
1244 * @tc.steps: step2. commit and GetEntries in db.
1245 * @tc.expected: step2. commit successfully and the entriesGot is equal to (entries1 - entries2).
1246 */
1247 entriesGot.clear();
1248 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1249 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1250 EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1251
1252 /**
1253 * @tc.steps: step3. commit again.
1254 * @tc.expected: step3. commit failed and returned error.
1255 */
1256 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1257 }
1258
1259 /**
1260 * @tc.name: Transaction 007
1261 * @tc.desc: verify that transaction support native db insert or delete records
1262 * but don't support local db to operate db.
1263 * @tc.type: FUNC
1264 * @tc.require: SR000DORPP
1265 * @tc.author: fengxiaoyun
1266 */
1267 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction007, TestSize.Level1)
1268 {
1269 /**
1270 * @tc.steps: step1. PutLocal (k1, v1) to Local DB and start transaction
1271 * @tc.expected: step1. putLocal and start success.
1272 */
1273 EXPECT_EQ(DistributedDBNbTestTools::PutLocal(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1274
1275 /**
1276 * @tc.steps: step2. start the transaction and Put and update and deleteLocal on DB and commit the transaction.
1277 * @tc.expected: step2. start and Put and commit success,
1278 * but can't find records on native db, and deletelocal returned failed.
1279 */
1280 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1281
1282 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1283 Value value;
1284 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1285 EXPECT_EQ(value, VALUE_1);
1286
1287 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1288 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1289 EXPECT_EQ(value, VALUE_2);
1290
1291 EXPECT_EQ(DistributedDBNbTestTools::DeleteLocal(*g_nbBatchCrudDelegate, KEY_1), OK);
1292
1293 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1294
1295 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1296 EXPECT_EQ(value, VALUE_2);
1297 EXPECT_EQ(DistributedDBNbTestTools::GetLocal(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
1298
1299 /**
1300 * @tc.steps: step3. Rollback after commit.
1301 * @tc.expected: step3. Rollback failed and returned error.
1302 */
1303 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
1304 }
1305
1306 /**
1307 * @tc.name: Transaction 008
1308 * @tc.desc: verify that it can't commit after it was Rollbacked
1309 * @tc.type: FUNC
1310 * @tc.require: SR000DORPP
1311 * @tc.author: fengxiaoyun
1312 */
1313 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction008, TestSize.Level1)
1314 {
1315 /**
1316 * @tc.steps: step1. Put (k1, v1) to DB and start transaction
1317 * @tc.expected: step1. put and start success.
1318 */
1319 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
1320 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1321 /**
1322 * @tc.steps: step2. update (k1, v1) and Rollback.
1323 * @tc.expected: step2. update and Rollback successfully
1324 */
1325 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1326
1327 Value value;
1328 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1329 EXPECT_EQ(value, VALUE_2);
1330
1331 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1332 /**
1333 * @tc.steps: step3. commit after Rollback and check the records in db.
1334 * @tc.expected: step3. commit failed and returned error and the value of k1 is v1.
1335 */
1336 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), DB_ERROR);
1337
1338 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
1339 EXPECT_EQ(value, VALUE_1);
1340 }
1341
1342 /**
1343 * @tc.name: Transaction 009
1344 * @tc.desc: verify that start transaction and commit or rollback repeatedly
1345 * @tc.type: FUNC
1346 * @tc.require: SR000DORPP
1347 * @tc.author: fengxiaoyun
1348 */
1349 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction009, TestSize.Level1)
1350 {
1351 /**
1352 * @tc.steps: step1. repeat 5 times
1353 * @tc.expected: step1. start loop success.
1354 */
1355 for (int index = 0; index < FIVE_TIMES; index++) {
1356 /**
1357 * @tc.steps: step2. start transaction and commit.
1358 * @tc.expected: step2. start and commit successfully
1359 */
1360 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1361
1362 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1363 /**
1364 * @tc.steps: step3. start transaction and rollback.
1365 * @tc.expected: step3. start and Rollback successfully
1366 */
1367 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1368
1369 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1370 }
1371 }
1372
1373 /**
1374 * @tc.name: Transaction 010
1375 * @tc.desc: verify that can Batchly operate on transaction
1376 * @tc.type: FUNC
1377 * @tc.require: SR000DORPP
1378 * @tc.author: fengxiaoyun
1379 */
1380 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction010, TestSize.Level1)
1381 {
1382 /**
1383 * @tc.steps: step1. start transaction
1384 * @tc.expected: step1. start success.
1385 */
1386 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1387
1388 std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1389 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
1390 GenerateAppointPrefixAndSizeRecords(entries1, entrySize, SIXTY_RECORDS, {'a'}, {'m'});
1391 GenerateAppointPrefixAndSizeRecords(entries2, entrySize, THIRTYTWO_RECORDS, {'b'}, {'n'});
1392 /**
1393 * @tc.steps: step2. PutBatch 60 records entries1 to DB.
1394 * @tc.expected: step2. PutBatch successfully
1395 */
1396 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1397 /**
1398 * @tc.steps: step3. PutBatch 32 records entries2 to DB.
1399 * @tc.expected: step3. PutBatch successfully
1400 */
1401 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1402
1403 std::vector<DistributedDB::Key> keys;
1404 for (auto const &entry : entries2) {
1405 keys.push_back(entry.key);
1406 }
1407 /**
1408 * @tc.steps: step4. DeleteBatch entries2 from DB.
1409 * @tc.expected: step4. DeleteBatch successfully
1410 */
1411 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1412
1413 /**
1414 * @tc.steps: step5. Delete entries1[1] and entries1[2] from DB solely.
1415 * @tc.expected: step5. Delete successfully
1416 */
1417 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[1].key), OK);
1418 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[2].key), OK);
1419 /**
1420 * @tc.steps: step6. insert entries1[1] to DB solely.
1421 * @tc.expected: step6. insert successfully
1422 */
1423 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, entries1[1].value), OK);
1424 /**
1425 * @tc.steps: step7. update value of entries1[1] to v2.
1426 * @tc.expected: step7. update successfully
1427 */
1428 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, VALUE_2), OK);
1429 /**
1430 * @tc.steps: step8. commit and check the records in DB.
1431 * @tc.expected: step8. commit success and can only find entries1 in db can't find entries2
1432 * and the value of entries1[1] is v2, and also can't find entries[2].
1433 */
1434 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1435
1436 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1437 for (auto const & entry : entries2) {
__anon306584110502(const DistributedDB::Entry &entry_) 1438 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1439 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1440 });
1441 EXPECT_EQ(it, entriesGot.end());
1442 }
1443 for (auto const & entry : entries1) {
1444 if (!CompareVector(entry.key, entries1[1].key) && !CompareVector(entry.key, entries1[2].key)) {
__anon306584110602(const DistributedDB::Entry &entry_) 1445 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1446 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1447 });
1448 EXPECT_NE(it, entriesGot.end());
1449 } else if (CompareVector(entry.key, entries1[1].key)) {
__anon306584110702(const DistributedDB::Entry &entry_) 1450 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1451 return (CompareVector(entry.key, entry_.key) && CompareVector(VALUE_2, entry_.value));
1452 });
1453 EXPECT_NE(it, entriesGot.end());
1454 } else {
__anon306584110802(const DistributedDB::Entry &entry_) 1455 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1456 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1457 });
1458 EXPECT_EQ(it, entriesGot.end());
1459 }
1460 }
1461 }
1462
1463 /**
1464 * @tc.name: Transaction 011
1465 * @tc.desc: verify that when rollback after logs of CRUD operate, the operate will not be effective.
1466 * @tc.type: FUNC
1467 * @tc.require: SR000DORPP
1468 * @tc.author: fengxiaoyun
1469 */
1470 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction011, TestSize.Level1)
1471 {
1472 std::vector<DistributedDB::Entry> entries1, entries2, entriesGot;
1473 entries1 = {ENTRY_1, ENTRY_2, ENTRY_3};
1474 entries2 = {ENTRY_4, ENTRY_5};
1475 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1476 /**
1477 * @tc.steps: step1. start transaction
1478 * @tc.expected: step1. start success.
1479 */
1480 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1481
1482 entries1[0] = {KEY_1, VALUE_EMPTY};
1483 entries1[1] = {KEY_2, VALUE_EMPTY};
1484 entries1[2] = {KEY_3, VALUE_EMPTY};
1485 /**
1486 * @tc.steps: step2. PutBatch entries1 to DB.
1487 * @tc.expected: step2. PutBatch successfully
1488 */
1489 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1490 /**
1491 * @tc.steps: step3. PutBatch entries2 to DB.
1492 * @tc.expected: step3. PutBatch successfully
1493 */
1494 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1495
1496 std::vector<DistributedDB::Key> keys = {KEY_4, KEY_5};
1497 /**
1498 * @tc.steps: step4. DeleteBatch entries2 from DB.
1499 * @tc.expected: step4. DeleteBatch successfully
1500 */
1501 EXPECT_EQ(DistributedDBNbTestTools::DeleteBatch(*g_nbBatchCrudDelegate, keys), OK);
1502
1503 /**
1504 * @tc.steps: step5. Delete entries1[1] and entries1[2] from DB solely.
1505 * @tc.expected: step5. Delete successfully
1506 */
1507 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[1].key), OK);
1508 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, entries1[2].key), OK);
1509 /**
1510 * @tc.steps: step6. insert entries1[1] to DB solely.
1511 * @tc.expected: step6. insert successfully
1512 */
1513 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, entries1[1].value), OK);
1514 /**
1515 * @tc.steps: step7. update value of entries1[1] to v2.
1516 * @tc.expected: step7. update successfully
1517 */
1518 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, entries1[1].key, VALUE_2), OK);
1519 /**
1520 * @tc.steps: step8. insert the records that key = null.
1521 * @tc.expected: step8. insert failed and returned DB_ERROR
1522 */
1523 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_EMPTY, VALUE_9), INVALID_ARGS);
1524
1525 /**
1526 * @tc.steps: step9. rollback and use GetEntries interface to check.
1527 * @tc.expected: step9. rollback success and the data in db is entries1
1528 */
1529 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1530 entries1 = {ENTRY_1, ENTRY_2, ENTRY_3};
1531 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1532 EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1533 }
1534
1535 /**
1536 * @tc.name: Transaction 012
1537 * @tc.desc: verify that exception operate can't effect transaction and commit.
1538 * @tc.type: FUNC
1539 * @tc.require: SR000DORPP
1540 * @tc.author: fengxiaoyun
1541 */
1542 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction012, TestSize.Level1)
1543 {
1544 std::vector<DistributedDB::Entry> entries, entriesGot;
1545 entries = {ENTRY_1, ENTRY_2};
1546 /**
1547 * @tc.steps: step1. start transaction
1548 * @tc.expected: step1. start success.
1549 */
1550 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1551 /**
1552 * @tc.steps: step2. PutBatch entries to DB.
1553 * @tc.expected: step2. PutBatch successfully
1554 */
1555 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1556 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1557 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1558 /**
1559 * @tc.steps: step3. Put the record that key = empty to DB.
1560 * @tc.expected: step3. Put failed and returned error
1561 */
1562 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_EMPTY, VALUE_10), INVALID_ARGS);
1563
1564 /**
1565 * @tc.steps: step4. commit and use GetEntries interface to check.
1566 * @tc.expected: step4. commit success and the data in db is entries1
1567 */
1568 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1569
1570 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1571 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1572 }
1573
1574 /**
1575 * @tc.name: Transaction 013
1576 * @tc.desc: verify that one transaction can only operate less than MAX_BATCH_SIZE records, or it will return
1577 * OVER_MAX_LIMITS.
1578 * @tc.type: FUNC
1579 * @tc.require: SR000DORPP
1580 * @tc.author: fengxiaoyun
1581 */
1582 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction013, TestSize.Level1)
1583 {
1584 std::vector<DistributedDB::Entry> entries, entriesGot;
1585 EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE};
1586 GenerateAppointPrefixAndSizeRecords(entries, entrySize, BATCH_RECORDS);
1587 /**
1588 * @tc.steps: step1. start transaction
1589 * @tc.expected: step1. start success.
1590 */
1591 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1592 /**
1593 * @tc.steps: step2. PutBatch entries which contains 128 records to DB.
1594 * @tc.expected: step2. PutBatch successfully
1595 */
1596 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
1597 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1598 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1599 /**
1600 * @tc.steps: step3. Put (k1, v1) to DB.
1601 * @tc.expected: step3. Put failed and returned OVER_MAX_LIMITS
1602 */
1603 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OVER_MAX_LIMITS);
1604 /**
1605 * @tc.steps: step3. Delete (k1, v1) from DB.
1606 * @tc.expected: step3. Delete failed and returned OVER_MAX_LIMITS
1607 */
1608 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OVER_MAX_LIMITS);
1609
1610 /**
1611 * @tc.steps: step4. commit and use GetEntries interface to check.
1612 * @tc.expected: step4. commit success and the data in db is entries1
1613 */
1614 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1615
1616 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1617 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
1618 }
1619
1620 /**
1621 * @tc.name: Transaction 014
1622 * @tc.desc: verify that one transaction can only operate less than MAX_BATCH_SIZE records, or it will return
1623 * OVER_MAX_LIMITS and if one operate return OVER_MAX_LIMITS, only this operate is invalid.
1624 * @tc.type: FUNC
1625 * @tc.require: SR000DORPP
1626 * @tc.author: fengxiaoyun
1627 */
1628 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction014, TestSize.Level1)
1629 {
1630 std::vector<DistributedDB::Entry> entries1, entries2, entries3, entries4, entriesGot;
1631 EntrySize entrySize = {KEY_SIX_BYTE, FOUR_M_LONG_STRING - KEY_SIX_BYTE};
1632 GenerateAppointPrefixAndSizeRecords(entries1, entrySize, ONE_HUNDRED_RECORDS, {'a'}, {'m'});
1633 GenerateAppointPrefixAndSizeRecords(entries2, entrySize, RECORDS_SMALL_CNT, {'b'}, {'n'});
1634 GenerateAppointPrefixAndSizeRecords(entries3, entrySize, THIRTYTWO_RECORDS, {'c'}, {'o'});
1635 GenerateAppointPrefixAndSizeRecords(entries4, entrySize, TWENTYFIVE_RECORDS, {'d'}, {'p'});
1636 /**
1637 * @tc.steps: step1. start transaction
1638 * @tc.expected: step1. start success.
1639 */
1640 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1641 /**
1642 * @tc.steps: step2. PutBatch 100 records to DB.
1643 * @tc.expected: step2. PutBatch successfully
1644 */
1645 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1646 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1647 EXPECT_TRUE(CompareEntriesVector(entries1, entriesGot));
1648 /**
1649 * @tc.steps: step3. PutBatch 2 records to DB.
1650 * @tc.expected: step3. PutBatch successfully
1651 */
1652 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1653 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1654 EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1655 /**
1656 * @tc.steps: step4. Delete nonexistent key1 from DB.
1657 * @tc.expected: step4. Delete return OK, and the number of records is still counted in the transaction.
1658 */
1659 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1660 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1661 EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1662 const int nonexistentRecordNum = 1;
1663 /**
1664 * @tc.steps: step5. PutBatch 32 records to DB.
1665 * @tc.expected: step5. PutBatch failed and OVER_MAX_LIMITS
1666 */
1667 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries3), OVER_MAX_LIMITS);
1668 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1669 EXPECT_TRUE(entriesGot.size() == ONE_HUNDRED_RECORDS + RECORDS_SMALL_CNT);
1670 /**
1671 * @tc.steps: step5. PutBatch 26 records to DB.
1672 * @tc.expected: step5. PutBatch succeed.
1673 */
1674 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries4), OK);
1675 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1676 EXPECT_TRUE(entriesGot.size() == (BATCH_RECORDS - nonexistentRecordNum));
1677
1678 /**
1679 * @tc.steps: step4. commit and use GetEntries interface to check.
1680 * @tc.expected: step4. commit success and the data in db is entries1
1681 */
1682 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
1683
1684 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
1685 for (auto const & entry : entries4) {
__anon306584110902(const DistributedDB::Entry &entry_) 1686 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1687 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1688 });
1689 EXPECT_NE(it, entriesGot.end());
1690 }
1691 for (auto const & entry : entries1) {
__anon306584110a02(const DistributedDB::Entry &entry_) 1692 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1693 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1694 });
1695 EXPECT_NE(it, entriesGot.end());
1696 }
1697 for (auto const & entry : entries2) {
__anon306584110b02(const DistributedDB::Entry &entry_) 1698 auto it = std::find_if(entriesGot.begin(), entriesGot.end(), [entry](const DistributedDB::Entry &entry_) {
1699 return (CompareVector(entry.key, entry_.key) && CompareVector(entry.value, entry_.value));
1700 });
1701 EXPECT_NE(it, entriesGot.end());
1702 }
1703 }
1704
1705 int g_threadComplete = 0;
1706 bool g_threadSuccessFlag = true;
ConsistencyCheck()1707 void ConsistencyCheck()
1708 {
1709 KvStoreNbDelegate *delegate = nullptr;
1710 KvStoreDelegateManager *delegateManager = nullptr;
1711 delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1712 ASSERT_TRUE(delegateManager != nullptr && delegate != nullptr) << "ConsistencyCheck get delegate failed.";
1713
1714 while (g_threadComplete < static_cast<int>(SINGLE_THREAD_NUM)) {
1715 std::vector<DistributedDB::Entry> entriesGot;
1716 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate, KEY_EMPTY, entriesGot), OK);
1717 if (GetIntValue(entriesGot[0].value) + GetIntValue(entriesGot[1].value) != VALUE_SUM) {
1718 g_threadSuccessFlag = false;
1719 MST_LOG("ConsistencyCheck get sum %d,%d.", GetIntValue(entriesGot[0].value),
1720 GetIntValue(entriesGot[1].value));
1721 break;
1722 }
1723 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1724 }
1725
1726 EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1727 delegate = nullptr;
1728 delete delegateManager;
1729 delegateManager = nullptr;
1730 }
1731
ConsistencyChange(Key keyLeft,Value valueLeft,Key keyRight,Value valueRight)1732 void ConsistencyChange(Key keyLeft, Value valueLeft, Key keyRight, Value valueRight)
1733 {
1734 // wait 100 ms, let ConsistencyCheck begin
1735 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(HUNDRED_MILLI_SECONDS));
1736 KvStoreNbDelegate *delegate = nullptr;
1737 KvStoreDelegateManager *delegateManager = nullptr;
1738 delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1739 if (delegate == nullptr) {
1740 MST_LOG("ConsistencyChange get delegate failed.");
1741 g_threadComplete++;
1742 g_threadSuccessFlag = false;
1743 return;
1744 }
1745
1746 MST_LOG("ConsistencyChange put %d,%d.", GetIntValue(valueLeft), GetIntValue(valueRight));
1747 DBStatus statusStart = delegate->StartTransaction();
1748 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1749
1750 DBStatus statusPutLeft = delegate->Put(keyLeft, valueLeft);
1751 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1752
1753 DBStatus statusPutRight = delegate->Put(keyRight, valueRight);
1754 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1755
1756 DBStatus statusCommit = delegate->Commit();
1757 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(FIFTY_MILI_SECONDS));
1758 g_threadComplete++;
1759
1760 if (statusStart != DBStatus::OK || statusPutLeft != DBStatus::OK ||
1761 statusPutRight != DBStatus::OK || statusCommit != DBStatus::OK) {
1762 MST_LOG("ConsistencyChange put failed.");
1763 g_threadComplete++;
1764 g_threadSuccessFlag = false;
1765 return;
1766 }
1767 ConsistencyCheck();
1768
1769 EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1770 delegate = nullptr;
1771 delete delegateManager;
1772 delegateManager = nullptr;
1773 }
1774
1775 /**
1776 * @tc.name: Transaction 015
1777 * @tc.desc: Verify that transaction singlely action's consistency.
1778 * @tc.type: FUNC
1779 * @tc.require: SR000DORPP
1780 * @tc.author: fengxiaoyun
1781 */
1782 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction015, TestSize.Level2)
1783 {
1784 int baseNumer = VALUE_FIVE_HUNDRED;
1785 Value base = GetValueWithInt(baseNumer);
1786
1787 Entry entry1, entry2;
1788 vector<Entry> entries1;
1789 entry1 = {KEY_CONS_1, base};
1790 entry2 = {KEY_CONS_2, base};
1791 entries1.push_back(entry1);
1792 entries1.push_back(entry2);
1793 /**
1794 * @tc.steps: step1. putBatch (k1=cons1,v1=500) (k2=cons2,v2=500) to construct exist v1+v2=1000.
1795 * @tc.expected: step1. putBatch successfully.
1796 */
1797 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1798 Value value;
1799 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, entry1.key, value), OK);
1800 EXPECT_EQ(value, base);
1801 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, entry2.key, value), OK);
1802 EXPECT_EQ(value, base);
1803
1804 /**
1805 * @tc.steps: step2. start a thread to update k1=cons1's value to 400, update k2=cons2's value to 600.
1806 * @tc.expected: step2. run thread successfully and k1+k2=1000 is true in sub thread.
1807 */
1808 std::vector<std::thread> suThreads;
1809 suThreads.push_back(std::thread(ConsistencyChange, KEY_CONS_1, GetValueWithInt(VALUE_CHANGE1_FIRST),
1810 KEY_CONS_2, GetValueWithInt(VALUE_CHANGE1_SECOND)));
1811 /**
1812 * @tc.steps: step3. start another thread to update k1=cons1's value to 700, update k2=cons2's value to 300.
1813 * @tc.expected: step3. run thread successfully and k1+k2=1000 is true in sub thread.
1814 */
1815 suThreads.push_back(std::thread(ConsistencyChange, KEY_CONS_1, GetValueWithInt(VALUE_CHANGE2_FIRST),
1816 KEY_CONS_2, GetValueWithInt(VALUE_CHANGE2_SECOND)));
1817 for (auto& th : suThreads) {
1818 th.detach();
1819 }
1820
1821 ConsistencyCheck();
1822 std::this_thread::sleep_for(std::chrono::seconds(FIVE_SECONDS));
1823 ASSERT_TRUE(g_threadSuccessFlag);
1824 }
1825
1826 bool g_batchThreadSuccess = true;
1827 bool g_batchThreadComplete = false;
ConsistencyBatchCheck(vector<Key> * keyLeft,vector<Key> * keyRight,int times)1828 void ConsistencyBatchCheck(vector<Key> *keyLeft, vector<Key> *keyRight, int times)
1829 {
1830 std::this_thread::sleep_for(std::chrono::seconds(TWO_SECONDS));
1831 KvStoreNbDelegate *delegate = nullptr;
1832 KvStoreDelegateManager *delegateManager = nullptr;
1833 delegate = DistributedDBNbTestTools::GetNbDelegateSuccess(delegateManager, g_dbParameter1, g_option);
1834 ASSERT_TRUE(delegateManager != nullptr && delegate != nullptr) << "ConsistencyBatchCheck get delegate failed.";
1835
1836 Value leftValue;
1837 Value rightValue;
1838 while (!g_batchThreadComplete) {
1839 for (int i = 0; i < times; ++i) {
1840 leftValue.clear();
1841 rightValue.clear();
1842 EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyLeft->at(i), leftValue), OK);
1843 EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyRight->at(i), rightValue), OK);
1844
1845 if (GetIntValue(leftValue) + GetIntValue(rightValue) != (times + 1)) {
1846 g_batchThreadSuccess = false;
1847 MST_LOG("ConsistencyBatchCheck get leftvalue: %d, rightvalue: %d, failed.",
1848 GetIntValue(leftValue), GetIntValue(rightValue));
1849 break;
1850 }
1851 }
1852 }
1853
1854 MST_LOG("g_batchThreadComplete.");
1855 EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1856 delegate = nullptr;
1857 delete delegateManager;
1858 delegateManager = nullptr;
1859 }
1860
ConsistencyCheckTransaction(vector<Entry> & entries1,vector<Entry> & entries2)1861 void ConsistencyCheckTransaction(vector<Entry> &entries1, vector<Entry> &entries2)
1862 {
1863 Key query1 = {'k', 'a'};
1864 Key query2 = {'k', 'b'};
1865 /**
1866 * @tc.steps: step1. putBatch 20 items of (keys1,values1)(key2,values2).
1867 * @tc.expected: step1. putBatch successfully to construct exist data in db.
1868 */
1869 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1870 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1871
1872 /**
1873 * @tc.steps: step3. start transaction.
1874 * @tc.expected: step3. start transaction successfully.
1875 */
1876 EXPECT_TRUE(g_nbBatchCrudDelegate->StartTransaction() == DBStatus::OK);
1877 /**
1878 * @tc.steps: step4. getEntries with keyprefix before updateBatch.
1879 * @tc.expected: step4. getEntries successfully that the size of them is 20.
1880 */
1881 vector<Entry> values1;
1882 vector<Entry> values2;
1883 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query1, values1), OK);
1884 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query2, values2), OK);
1885 EXPECT_EQ(static_cast<int>(values1.size()), TWENTY_RECORDS);
1886 EXPECT_EQ(static_cast<int>(values2.size()), TWENTY_RECORDS);
1887 /**
1888 * @tc.steps: step5. updateBatch values1+1 of keys1, values2-1 of keys2.
1889 * @tc.expected: step5. updateBatch successfully.
1890 */
1891 for (int i = 0; i != TWENTY_RECORDS; ++i) {
1892 entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + 1);
1893 entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - 1);
1894 }
1895 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1896 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1897 /**
1898 * @tc.steps: step6. updateBatch values1+2 of keys1, values2-2 of keys2.
1899 * @tc.expected: step6. updateBatch successfully.
1900 */
1901 for (int i = 0; i != TWENTY_RECORDS; ++i) {
1902 entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + EVEN_NUMBER);
1903 entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - EVEN_NUMBER);
1904 }
1905 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1906 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1907 /**
1908 * @tc.steps: step7. commit transaction and stop child thread.
1909 * @tc.expected: step7. operate successfully.
1910 */
1911 EXPECT_TRUE(g_nbBatchCrudDelegate->Commit() == DBStatus::OK);
1912 MST_LOG("commit over!");
1913 }
1914
1915 /**
1916 * @tc.name: Transaction 016
1917 * @tc.desc: Verify that transaction batch action's consistency.
1918 * @tc.type: FUNC
1919 * @tc.require: SR000DORPP
1920 * @tc.author: fengxiaoyun
1921 */
1922 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction016, TestSize.Level2)
1923 {
1924 uint8_t left = 'a';
1925 uint8_t right = 'b';
1926 vector<Entry> entries1;
1927 vector<Key> allKeys1;
1928 GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys1, entries1);
1929 vector<Entry> entries2;
1930 vector<Key> allKeys2;
1931 GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys2, entries2);
1932 for (int i = 0; i < TWENTY_RECORDS; ++i) {
1933 entries1[i].key.insert(entries1[i].key.begin() + 1, left);
1934 entries2[i].key.insert(entries2[i].key.begin() + 1, right);
1935 allKeys1[i].insert(allKeys1[i].begin() + 1, left);
1936 allKeys2[i].insert(allKeys2[i].begin() + 1, right);
1937 entries1[i].value = GetValueWithInt(i);
1938 entries2[i].value = GetValueWithInt(TWENTY_RECORDS - i);
1939 }
1940
1941 /**
1942 * @tc.steps: step2. start child thread to query keys1 and keys2 continuously.
1943 * @tc.expected: step2. if keys1.size()+keys2.size()!=20 print info.
1944 */
1945 thread readThread = thread(ConsistencyBatchCheck, &allKeys1, &allKeys2, TWENTY_RECORDS);
1946 readThread.detach();
1947 ConsistencyCheckTransaction(entries1, entries2);
1948 g_batchThreadComplete = true;
1949
1950 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1951 ASSERT_TRUE(g_batchThreadSuccess);
1952 }
1953
TransactionSubThread1()1954 void TransactionSubThread1()
1955 {
1956 /**
1957 * @tc.steps: step2. start transanction and update v1 of k1 to v2, and put (k3, v3) to STORE_ID_1.
1958 * @tc.expected: step2. start and put successfully.
1959 */
1960 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1961 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1962 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
1963 }
TransactionSubThread2()1964 void TransactionSubThread2()
1965 {
1966 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1967
1968 /**
1969 * @tc.steps: step3. update v2 of k2 to v3, and delete k1, and Get (k3, v3) from DB
1970 * @tc.expected: step3. put and delete successfully, but can't find (k3, v3) in DB.
1971 */
1972 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
1973 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1974 Value value;
1975 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), OK);
1976 EXPECT_EQ(value, VALUE_3);
1977 }
TransactionSubThread3()1978 void TransactionSubThread3()
1979 {
1980 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1981
1982 /**
1983 * @tc.steps: step4. rollback
1984 * @tc.expected: step4. rollback successfully.
1985 */
1986 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1987 }
1988 /**
1989 * @tc.name: Transaction 017
1990 * @tc.desc: Verify that one delegate start transaction, and then the different delegate of the same storeid are
1991 * already in the same transaction.
1992 * @tc.type: FUNC
1993 * @tc.require: SR000DORPP
1994 * @tc.author: fengxiaoyun
1995 */
1996 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction017, TestSize.Level2)
1997 {
1998 /**
1999 * @tc.steps: step1. put (k1, v1), (k2, v2) to STORE_ID_1.
2000 * @tc.expected: step1. put successfully.
2001 */
2002 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2003 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2004
2005 std::thread thread1, thread2, thread3;
2006 thread1 = std::thread(TransactionSubThread1);
2007 thread1.join();
2008 thread2 = std::thread(TransactionSubThread2);
2009 thread2.join();
2010 thread3 = std::thread(TransactionSubThread3);
2011 thread3.join();
2012
2013 /**
2014 * @tc.steps: step5. check the records in db
2015 * @tc.expected: step5. the value of k1 is v1, the value of k2 is v2, but (k3, v3) is not in db.
2016 */
2017 Value value;
2018 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2019 EXPECT_EQ(value, VALUE_1);
2020 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
2021 EXPECT_EQ(value, VALUE_2);
2022 value.clear();
2023 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), NOT_FOUND);
2024 EXPECT_TRUE(value.empty());
2025 }
2026
2027 /**
2028 * @tc.name: Transaction 018
2029 * @tc.desc: Verify that transaction has persistence.
2030 * @tc.type: FUNC
2031 * @tc.require: SR000DORPP
2032 * @tc.author: fengxiaoyun
2033 */
2034 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction018, TestSize.Level1)
2035 {
2036 KvStoreNbDelegate *delegate1 = nullptr;
2037 KvStoreDelegateManager *manager1 = nullptr;
2038 delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2039 ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2040 /**
2041 * @tc.steps: step1. start transaction.
2042 * @tc.expected: step1. start transactionsuccessfully.
2043 */
2044 EXPECT_EQ(delegate1->StartTransaction(), OK);
2045 /**
2046 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2047 * @tc.expected: step2. putBatch successfully.
2048 */
2049 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2050 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2051
2052 /**
2053 * @tc.steps: step3. commit the transaction.
2054 * @tc.expected: step3. commit successfully.
2055 */
2056 EXPECT_EQ(delegate1->Commit(), OK);
2057 /**
2058 * @tc.steps: step4. close the db but don't delete the STORE, and then create a new delegate of the same STORE
2059 * @tc.expected: step4. close and create successfully.
2060 */
2061 EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2062 delegate1 = nullptr;
2063 delete manager1;
2064 manager1 = nullptr;
2065
2066 KvStoreNbDelegate *delegate2 = nullptr;
2067 KvStoreDelegateManager *manager2 = nullptr;
2068 delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2069 ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2070 /**
2071 * @tc.steps: step5. check the data in db STORE.
2072 * @tc.expected: step5. the entries is still in the db.
2073 */
2074 std::vector<DistributedDB::Entry> entriesGot;
2075 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), OK);
2076 EXPECT_TRUE(CompareEntriesVector(entriesGot, entries));
2077
2078 EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2079 delegate2 = nullptr;
2080 EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2081 delete manager2;
2082 manager2 = nullptr;
2083 }
2084
2085 /**
2086 * @tc.name: Transaction 019
2087 * @tc.desc: Verify that close the delegate before transaction commit, and it will cause the transaction rollback.
2088 * @tc.type: FUNC
2089 * @tc.require: SR000DORPP
2090 * @tc.author: fengxiaoyun
2091 */
2092 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction019, TestSize.Level1)
2093 {
2094 KvStoreNbDelegate *delegate1 = nullptr;
2095 KvStoreDelegateManager *manager1 = nullptr;
2096 delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2097 ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2098 /**
2099 * @tc.steps: step1. start transaction.
2100 * @tc.expected: step1. start transactionsuccessfully.
2101 */
2102 EXPECT_EQ(delegate1->StartTransaction(), OK);
2103 /**
2104 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2105 * @tc.expected: step2. putBatch successfully.
2106 */
2107 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2108 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2109
2110 /**
2111 * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2112 * @tc.expected: step3. close successfully.
2113 */
2114 EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2115 delegate1 = nullptr;
2116 delete manager1;
2117 manager1 = nullptr;
2118
2119 /**
2120 * @tc.steps: step4. create a new delegate of the same STORE
2121 * @tc.expected: step4. start successfully.
2122 */
2123 KvStoreNbDelegate *delegate2 = nullptr;
2124 KvStoreDelegateManager *manager2 = nullptr;
2125 delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2126 ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2127 /**
2128 * @tc.steps: step5. commit the transaction on the new deleate, and check the data in db STORE.
2129 * @tc.expected: step5. commit failed and the entries is NULL.
2130 */
2131 EXPECT_EQ(delegate2->Commit(), DB_ERROR);
2132 std::vector<DistributedDB::Entry> entriesGot;
2133 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), NOT_FOUND);
2134 EXPECT_TRUE(entriesGot.empty());
2135
2136 EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2137 delegate2 = nullptr;
2138 EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2139 delete manager2;
2140 manager2 = nullptr;
2141 }
2142
2143 /**
2144 * @tc.name: Transaction 020
2145 * @tc.desc: Verify that close the delegate before transaction rollback, and it will cause the transaction rollback.
2146 * @tc.type: FUNC
2147 * @tc.require: SR000DORPP
2148 * @tc.author: fengxiaoyun
2149 */
2150 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction020, TestSize.Level1)
2151 {
2152 /**
2153 * @tc.steps: step1. start transaction.
2154 * @tc.expected: step1. start transactionsuccessfully.
2155 */
2156 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2157 /**
2158 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2159 * @tc.expected: step2. putBatch successfully.
2160 */
2161 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2162 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2163
2164 /**
2165 * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2166 * @tc.expected: step3. close successfully.
2167 */
2168 EXPECT_EQ(g_manager->CloseKvStore(g_nbBatchCrudDelegate), OK);
2169 g_nbBatchCrudDelegate = nullptr;
2170 delete g_manager;
2171 g_manager = nullptr;
2172
2173 /**
2174 * @tc.steps: step4. create a new delegate of the same STORE
2175 * @tc.expected: step4. start successfully.
2176 */
2177 g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
2178 ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr) << "get g_nbBatchCrudDelegate failed.";
2179 /**
2180 * @tc.steps: step5. Rollback the transaction on the new deleate, and check the data in db STORE.
2181 * @tc.expected: step5. Rollback failed and the entries is NULL.
2182 */
2183 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
2184 std::vector<DistributedDB::Entry> entriesGot;
2185 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), NOT_FOUND);
2186 EXPECT_TRUE(entriesGot.empty());
2187 }
2188
2189 /**
2190 * @tc.name: Transaction 021
2191 * @tc.desc: Verify that it will failed to delete the store before transaction rollback.
2192 * @tc.type: FUNC
2193 * @tc.require: SR000DORPP
2194 * @tc.author: fengxiaoyun
2195 */
2196 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction021, TestSize.Level1)
2197 {
2198 /**
2199 * @tc.steps: step1. start transaction.
2200 * @tc.expected: step1. start transactionsuccessfully.
2201 */
2202 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2203 /**
2204 * @tc.steps: step2. put (k1, v1) to STORE_ID_1.
2205 * @tc.expected: step2. put successfully.
2206 */
2207 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2208 DistributedDB::Value value;
2209 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2210 EXPECT_EQ(value, VALUE_1);
2211
2212 /**
2213 * @tc.steps: step3. delete the STORE without committing or rollback
2214 * the transaction
2215 * @tc.expected: step3. delete failed and returned BUSY.
2216 */
2217 EXPECT_EQ(g_manager->DeleteKvStore(STORE_ID_1), BUSY);
2218
2219 /**
2220 * @tc.steps: step4. Rollback and check the db
2221 * @tc.expected: step4. Rollback failed.
2222 */
2223 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
2224
2225 /**
2226 * @tc.steps: step5. check the data in db STORE.
2227 * @tc.expected: step5. the DB is empty.
2228 */
2229 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
2230 }
2231
2232 /**
2233 * @tc.name: Transaction 022
2234 * @tc.desc: Verify transaction can't support resultSet, rekey, Import, Export, RegisterObserver interface.
2235 * @tc.type: FUNC
2236 * @tc.require: SR000DORPP
2237 * @tc.author: fengxiaoyun
2238 */
2239 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction022, TestSize.Level3)
2240 {
2241 KvStoreResultSet *resultSet1 = nullptr;
2242 KvStoreResultSet *resultSet2 = nullptr;
2243 EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet1), OK);
2244 KvStoreObserverImpl observer1, observer2;
2245 vector<Entry> entries, entriesGot;
2246 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
2247 GenerateAppointPrefixAndSizeRecords(entries, entrySize, TEN_RECORDS);
2248
2249 DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer1);
2250 EXPECT_EQ(status, OK);
2251
2252 const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "import";
2253 const std::string importFilePath = importPath + "/importbkpDB.bin";
2254 SetDir(importPath);
2255 EXPECT_EQ(g_nbBatchCrudDelegate->Export(importFilePath, NULL_PASSWD), OK);
2256
2257 /**
2258 * @tc.steps: step1. start transaction.
2259 * @tc.expected: step1. start transaction successfully.
2260 */
2261 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2262 /**
2263 * @tc.steps: step2. putBatch entries to db.
2264 * @tc.expected: step2. putBatch successfully.
2265 */
2266 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2267 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2268 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2269
2270 vector<DistributedDB::Entry> observerCheckEntry;
2271 observerCheckEntry.clear();
2272 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::INSERT_LIST, observerCheckEntry));
2273
2274 /**
2275 * @tc.steps: step3. call rekey, import, export interface
2276 * @tc.expected: step3. all call failed and returned BUSY.
2277 */
2278 EXPECT_EQ(g_nbBatchCrudDelegate->Rekey(g_passwd1), BUSY);
2279
2280 const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
2281 const std::string filePath = exportPath + "/bkpDB.bin";
2282 SetDir(exportPath);
2283 EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), BUSY);
2284 EXPECT_EQ(g_nbBatchCrudDelegate->Import(importFilePath, NULL_PASSWD), BUSY);
2285 /**
2286 * @tc.steps: step4. call GetEntries to obtain resultSet2, and register observer2.
2287 * @tc.expected: step4. all call failed and returned BUSY.
2288 */
2289 EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet2), BUSY);
2290 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer2), BUSY);
2291
2292 /**
2293 * @tc.steps: step5. close resultSet1 and resultSet2, UnRegister observer1 and observer2.
2294 * @tc.expected: step5. close resultSet1 succeed and resultSet2 failed,
2295 * UnRegister observer1 succeed and observer2 failed.
2296 */
2297 EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet1), OK);
2298 EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet2), INVALID_ARGS);
2299 EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer1), OK);
2300 EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer2), NOT_FOUND);
2301 /**
2302 * @tc.steps: step6. commit the transaction and check the data in db.
2303 * @tc.expected: step6. commit succeed and can find entries in DB.
2304 */
2305 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2306 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2307 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2308 }
2309
2310 /**
2311 * @tc.name: TransactionObserver 001
2312 * @tc.desc: Verify transaction can and only trigger observer one time.
2313 * @tc.type: FUNC
2314 * @tc.require: SR000DORPP
2315 * @tc.author: fengxiaoyun
2316 */
2317 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver001, TestSize.Level1)
2318 {
2319 /**
2320 * @tc.steps: step1. Register observer1 and observer2 of k1 and k2 separately and start the transaction.
2321 * @tc.expected: step1. Register start transaction successfully.
2322 */
2323 KvStoreObserverImpl observer1, observer2;
2324 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2325 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2326 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2327
2328 /**
2329 * @tc.steps: step2. put (k1, v1), (k3, v3) and check the callback of the observer.
2330 * @tc.expected: step2. put successfully and both of the observers can't receive the callback.
2331 */
2332 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2333 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2334 vector<DistributedDB::Entry> observerCheckList;
2335 observerCheckList.clear();
2336 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2337 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2338 /**
2339 * @tc.steps: step3. update (k1, v1) to (k1, v2) and delete (k3, v3) and check the observers.
2340 * @tc.expected: step3. update and delete successfully both of the observers can't receive the callback either.
2341 */
2342 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
2343 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2344 observerCheckList.clear();
2345 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2346 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2347
2348 /**
2349 * @tc.steps: step4. commit the transaction and check the observers.
2350 * @tc.expected: step4. commit succeed and observer1 was triggered one time and observer2 wasn't triggered.
2351 */
2352 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2353 observerCheckList.clear();
2354 observerCheckList.push_back(ENTRY_1_2);
2355 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2356 observerCheckList.clear();
2357 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2358 }
2359
2360 /**
2361 * @tc.name: TransactionObserver 002
2362 * @tc.desc: Verify transaction can and only trigger observer one time.
2363 * @tc.type: FUNC
2364 * @tc.require: SR000DORPP
2365 * @tc.author: fengxiaoyun
2366 */
2367 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver002, TestSize.Level1)
2368 {
2369 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2370 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2371 /**
2372 * @tc.steps: step1. Register observer1, observer2, observer3, observer4 of k1, k2, k3
2373 * and k4 separately and start the transaction.
2374 * @tc.expected: step1. Register and start transaction successfully.
2375 */
2376 KvStoreObserverImpl observer1, observer2, observer3, observer4;
2377 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2378 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2379 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
2380 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_4, OBSERVER_CHANGES_NATIVE, &observer4), OK);
2381 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2382
2383 /**
2384 * @tc.steps: step2. put (k1, v1), (k2, v2), (k3, v3) and (k4, v4) and then delete (k1, v1) and (k4, v4).
2385 * @tc.expected: step2. put and delete successfully.
2386 */
2387 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2388 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2389 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_4, VALUE_4), OK);
2390
2391 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2392 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_4), OK);
2393
2394 /**
2395 * @tc.steps: step3. commit the transaction and check the observers.
2396 * @tc.expected: step3. commit succeed and observer1 received one delete notify, observer2 received one update
2397 * notify, observer3 received one insert notify, and observer4 didn't receive any notify.
2398 */
2399 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2400 vector<DistributedDB::Entry> observerCheckList;
2401 observerCheckList.clear();
2402 observerCheckList.push_back(ENTRY_1);
2403 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2404 observerCheckList.clear();
2405 observerCheckList.push_back(ENTRY_2_3);
2406 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2407 observerCheckList.clear();
2408 observerCheckList.push_back(ENTRY_3);
2409 EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2410 observerCheckList.clear();
2411 EXPECT_TRUE(VerifyObserverResult(observer4, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2412 }
2413
2414 /**
2415 * @tc.name: TransactionObserver 003
2416 * @tc.desc: Verify the different observer of same key will all be triggered after transaction
2417 * and will only be trigger once.
2418 * @tc.type: FUNC
2419 * @tc.require: SR000DORPP
2420 * @tc.author: fengxiaoyun
2421 */
2422 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver003, TestSize.Level1)
2423 {
2424 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2425 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2426 /**
2427 * @tc.steps: step1. Register 8 observers of all keys.
2428 * @tc.expected: step1. Register successfully.
2429 */
2430 std::vector<KvStoreObserverImpl> observers(OBSERVER_NUM);
2431 for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2432 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observers[cnt]), OK);
2433 }
2434
2435 /**
2436 * @tc.steps: step2. start the transaction and putBatch (ENTRY_3), (ENTRY_4), ..., (ENTRY_8) to db.
2437 * @tc.expected: step2. start transaction and putBatch successfully.
2438 */
2439 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2440 std::vector<DistributedDB::Entry> entries = {ENTRY_3, ENTRY_4, ENTRY_5, ENTRY_6, ENTRY_7, ENTRY_8, ENTRY_9};
2441 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2442
2443 /**
2444 * @tc.steps: step3. delete (k1, v1), (k3, v3) and (k9, v9), update (k2, v2) to (k2, v3).
2445 * @tc.expected: step3. operate succeed.
2446 */
2447 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2448 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2449 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2450 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_9), OK);
2451
2452 /**
2453 * @tc.steps: step3. commit the transaction and check the observers.
2454 * @tc.expected: step3. commit succeed and all of the observers received one insert notify, callbacklist of which
2455 * contains (ENTRY_4), ..., (ENTRY_8), all observer received one update notify, callbacklist of which contains
2456 * (k2, v3), all observers received one insert notify, callback of which contains (k1, v1), (k3, v3), (k9, v9).
2457 */
2458 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2459 vector<DistributedDB::Entry> observerCheckList;
2460 for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2461 observerCheckList.clear();
2462 observerCheckList.push_back(ENTRY_4);
2463 observerCheckList.push_back(ENTRY_5);
2464 observerCheckList.push_back(ENTRY_6);
2465 observerCheckList.push_back(ENTRY_7);
2466 observerCheckList.push_back(ENTRY_8);
2467 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2468 observerCheckList.clear();
2469 observerCheckList.push_back(ENTRY_2_3);
2470 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2471 observerCheckList.clear();
2472 observerCheckList.push_back(ENTRY_1);
2473 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2474 }
2475 }
2476
2477 /**
2478 * @tc.name: GetKeysPressure 001
2479 * @tc.desc: Concurrent GetEntries and GetKeys.
2480 * @tc.type: FUNC
2481 * @tc.require: SR000DORPP
2482 * @tc.author: xuhongkang
2483 */
2484 #ifdef GETKEYS_PRESSURE001
2485 HWTEST_F(DistributeddbNbBatchCrudTest, GetKeysPressure001, TestSize.Level3)
2486 {
2487 DBStatus status, status1, status2;
2488 std::vector<Key> allKeysKA, allKeysKB, expectKeyResult;
2489 std::vector<Entry> entriesA, entriesB, entriesBatch;
2490 DistributedDB::Value longValue1;
2491 DistributedDB::Key ka = {'k', 'a'};
2492 DistributedDB::Key kb = {'k', 'b'};
2493 longValue1.assign(ONE_K_LONG_STRING, (uint8_t)'v');
2494 GenerateRecords(TEN_THOUSAND_RECORDS, DEFAULT_START, allKeysKA, entriesA, ka);
2495 GenerateRecords(FIVE_THOUSANDS_RECORDS, DEFAULT_START, allKeysKB, entriesB, kb);
2496
2497 entriesBatch.insert(entriesBatch.end(), entriesA.begin(), entriesA.end());
2498 entriesBatch.insert(entriesBatch.end(), entriesB.begin(), entriesB.end());
2499 for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++)
2500 {
2501 if (index < TEN_THOUSAND_RECORDS) {
2502 entriesA[index].value = longValue1;
2503 }
2504 entriesBatch[index].value = longValue1;
2505 status = g_nbBatchCrudDelegate->Put(entriesBatch[index].key, entriesBatch[index].value);
2506 EXPECT_EQ(status, OK);
2507 }
2508 std::vector<Key> keyResult;
2509 std::vector<Entry> valueResult;
__anon306584110c02() 2510 std::thread sub = std::thread([&status1, &ka, &valueResult]() {
2511 status1 = DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, ka, valueResult);
2512 });
2513 status2 = DistributedDBNbTestTools::GetKeys(*g_nbBatchCrudDelegate, KEY_EMPTY, keyResult);
2514 sub.join();
2515 EXPECT_EQ(status1, OK);
2516 EXPECT_EQ(status2, OK);
2517 expectKeyResult.insert(expectKeyResult.end(), allKeysKA.begin(), allKeysKA.end());
2518 expectKeyResult.insert(expectKeyResult.end(), allKeysKB.begin(), allKeysKB.end());
2519 sort(keyResult.begin(), keyResult.end());
2520 sort(expectKeyResult.begin(), expectKeyResult.end());
2521 for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++) {
2522 string actResult(keyResult[index].begin(), keyResult[index].end());
2523 string expectResult(expectKeyResult[index].begin(), expectKeyResult[index].end());
2524 bool result = (actResult == expectResult);
2525 EXPECT_EQ(result, true);
2526 }
2527 EXPECT_TRUE(CompareEntriesVector(valueResult, entriesA));
2528 }
2529 #endif // GETKEYS_PRESSURE001
2530 }
2531