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 GenerateRecords(BATCH_RECORDS + 1, DEFAULT_START, allKeys, entriesBatch);
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;
__anon07ddae6e0102() 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);
__anon07ddae6e0202null439 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;
__anon07ddae6e0302() 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);
__anon07ddae6e0402null489 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) {
__anon07ddae6e0502(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)) {
__anon07ddae6e0602(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)) {
__anon07ddae6e0702(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 {
__anon07ddae6e0802(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, VALUE_ONE_HUNDRED_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, VALUE_ONE_HUNDRED_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) {
__anon07ddae6e0902(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) {
__anon07ddae6e0a02(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) {
__anon07ddae6e0b02(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, rightValue;
1837 while (!g_batchThreadComplete) {
1838 for (int i = 0; i < times; ++i) {
1839 leftValue.clear();
1840 rightValue.clear();
1841 EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyLeft->at(i), leftValue), OK);
1842 EXPECT_EQ(DistributedDBNbTestTools::Get(*delegate, keyRight->at(i), rightValue), OK);
1843
1844 if (GetIntValue(leftValue) + GetIntValue(rightValue) != (times + 1)) {
1845 g_batchThreadSuccess = false;
1846 MST_LOG("ConsistencyBatchCheck get leftvalue: %d, rightvalue: %d, failed.",
1847 GetIntValue(leftValue), GetIntValue(rightValue));
1848 break;
1849 }
1850 }
1851 }
1852
1853 MST_LOG("g_batchThreadComplete.");
1854 EXPECT_EQ(delegateManager->CloseKvStore(delegate), OK);
1855 delegate = nullptr;
1856 delete delegateManager;
1857 delegateManager = nullptr;
1858 }
1859
ConsistencyCheckTransaction(vector<Entry> & entries1,vector<Entry> & entries2)1860 void ConsistencyCheckTransaction(vector<Entry> &entries1, vector<Entry> &entries2)
1861 {
1862 Key query1 = {'k', 'a'};
1863 Key query2 = {'k', 'b'};
1864 /**
1865 * @tc.steps: step1. putBatch 20 items of (keys1,values1)(key2,values2).
1866 * @tc.expected: step1. putBatch successfully to construct exist data in db.
1867 */
1868 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1869 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1870
1871 /**
1872 * @tc.steps: step3. start transaction.
1873 * @tc.expected: step3. start transaction successfully.
1874 */
1875 EXPECT_TRUE(g_nbBatchCrudDelegate->StartTransaction() == DBStatus::OK);
1876 /**
1877 * @tc.steps: step4. getEntries with keyprefix before updateBatch.
1878 * @tc.expected: step4. getEntries successfully that the size of them is 20.
1879 */
1880 vector<Entry> values1, values2;
1881 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query1, values1), OK);
1882 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, query2, values2), OK);
1883 EXPECT_EQ(static_cast<int>(values1.size()), TWENTY_RECORDS);
1884 EXPECT_EQ(static_cast<int>(values2.size()), TWENTY_RECORDS);
1885 /**
1886 * @tc.steps: step5. updateBatch values1+1 of keys1, values2-1 of keys2.
1887 * @tc.expected: step5. updateBatch successfully.
1888 */
1889 for (int i = 0; i != TWENTY_RECORDS; ++i) {
1890 entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + 1);
1891 entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - 1);
1892 }
1893 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1894 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1895 /**
1896 * @tc.steps: step6. updateBatch values1+2 of keys1, values2-2 of keys2.
1897 * @tc.expected: step6. updateBatch successfully.
1898 */
1899 for (int i = 0; i != TWENTY_RECORDS; ++i) {
1900 entries1[i].value = GetValueWithInt(GetIntValue(values1[i].value) + EVEN_NUMBER);
1901 entries2[i].value = GetValueWithInt(GetIntValue(values2[i].value) - EVEN_NUMBER);
1902 }
1903 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries1), OK);
1904 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries2), OK);
1905 /**
1906 * @tc.steps: step7. commit transaction and stop child thread.
1907 * @tc.expected: step7. operate successfully.
1908 */
1909 EXPECT_TRUE(g_nbBatchCrudDelegate->Commit() == DBStatus::OK);
1910 MST_LOG("commit over!");
1911 }
1912
1913 /**
1914 * @tc.name: Transaction 016
1915 * @tc.desc: Verify that transaction batch action's consistency.
1916 * @tc.type: FUNC
1917 * @tc.require: SR000DORPP
1918 * @tc.author: fengxiaoyun
1919 */
1920 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction016, TestSize.Level2)
1921 {
1922 uint8_t left = 'a';
1923 uint8_t right = 'b';
1924 vector<Entry> entries1;
1925 vector<Key> allKeys1;
1926 GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys1, entries1);
1927 vector<Entry> entries2;
1928 vector<Key> allKeys2;
1929 GenerateRecords(TWENTY_RECORDS, DEFAULT_START, allKeys2, entries2);
1930 for (int i = 0; i < TWENTY_RECORDS; ++i) {
1931 entries1[i].key.insert(entries1[i].key.begin() + 1, left);
1932 entries2[i].key.insert(entries2[i].key.begin() + 1, right);
1933 allKeys1[i].insert(allKeys1[i].begin() + 1, left);
1934 allKeys2[i].insert(allKeys2[i].begin() + 1, right);
1935 entries1[i].value = GetValueWithInt(i);
1936 entries2[i].value = GetValueWithInt(TWENTY_RECORDS - i);
1937 }
1938
1939 /**
1940 * @tc.steps: step2. start child thread to query keys1 and keys2 continuously.
1941 * @tc.expected: step2. if keys1.size()+keys2.size()!=20 print info.
1942 */
1943 thread readThread = thread(ConsistencyBatchCheck, &allKeys1, &allKeys2, TWENTY_RECORDS);
1944 readThread.detach();
1945 ConsistencyCheckTransaction(entries1, entries2);
1946 g_batchThreadComplete = true;
1947
1948 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1949 ASSERT_TRUE(g_batchThreadSuccess);
1950 }
1951
TransactionSubThread1()1952 void TransactionSubThread1()
1953 {
1954 /**
1955 * @tc.steps: step2. start transanction and update v1 of k1 to v2, and put (k3, v3) to STORE_ID_1.
1956 * @tc.expected: step2. start and put successfully.
1957 */
1958 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
1959 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
1960 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
1961 }
TransactionSubThread2()1962 void TransactionSubThread2()
1963 {
1964 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1965
1966 /**
1967 * @tc.steps: step3. update v2 of k2 to v3, and delete k1, and Get (k3, v3) from DB
1968 * @tc.expected: step3. put and delete successfully, but can't find (k3, v3) in DB.
1969 */
1970 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
1971 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
1972 Value value;
1973 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), OK);
1974 EXPECT_EQ(value, VALUE_3);
1975 }
TransactionSubThread3()1976 void TransactionSubThread3()
1977 {
1978 std::this_thread::sleep_for(std::chrono::duration<float, std::milli>(MILLSECONDS_PER_SECOND));
1979
1980 /**
1981 * @tc.steps: step4. rollback
1982 * @tc.expected: step4. rollback successfully.
1983 */
1984 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
1985 }
1986 /**
1987 * @tc.name: Transaction 017
1988 * @tc.desc: Verify that one delegate start transaction, and then the different delegate of the same storeid are
1989 * already in the same transaction.
1990 * @tc.type: FUNC
1991 * @tc.require: SR000DORPP
1992 * @tc.author: fengxiaoyun
1993 */
1994 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction017, TestSize.Level2)
1995 {
1996 /**
1997 * @tc.steps: step1. put (k1, v1), (k2, v2) to STORE_ID_1.
1998 * @tc.expected: step1. put successfully.
1999 */
2000 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2001 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2002
2003 std::thread thread1, thread2, thread3;
2004 thread1 = std::thread(TransactionSubThread1);
2005 thread1.join();
2006 thread2 = std::thread(TransactionSubThread2);
2007 thread2.join();
2008 thread3 = std::thread(TransactionSubThread3);
2009 thread3.join();
2010
2011 /**
2012 * @tc.steps: step5. check the records in db
2013 * @tc.expected: step5. the value of k1 is v1, the value of k2 is v2, but (k3, v3) is not in db.
2014 */
2015 Value value;
2016 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2017 EXPECT_EQ(value, VALUE_1);
2018 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_2, value), OK);
2019 EXPECT_EQ(value, VALUE_2);
2020 value.clear();
2021 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_3, value), NOT_FOUND);
2022 EXPECT_TRUE(value.empty());
2023 }
2024
2025 /**
2026 * @tc.name: Transaction 018
2027 * @tc.desc: Verify that transaction has persistence.
2028 * @tc.type: FUNC
2029 * @tc.require: SR000DORPP
2030 * @tc.author: fengxiaoyun
2031 */
2032 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction018, TestSize.Level1)
2033 {
2034 KvStoreNbDelegate *delegate1 = nullptr;
2035 KvStoreDelegateManager *manager1 = nullptr;
2036 delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2037 ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2038 /**
2039 * @tc.steps: step1. start transaction.
2040 * @tc.expected: step1. start transactionsuccessfully.
2041 */
2042 EXPECT_EQ(delegate1->StartTransaction(), OK);
2043 /**
2044 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2045 * @tc.expected: step2. putBatch successfully.
2046 */
2047 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2048 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2049
2050 /**
2051 * @tc.steps: step3. commit the transaction.
2052 * @tc.expected: step3. commit successfully.
2053 */
2054 EXPECT_EQ(delegate1->Commit(), OK);
2055 /**
2056 * @tc.steps: step4. close the db but don't delete the STORE, and then create a new delegate of the same STORE
2057 * @tc.expected: step4. close and create successfully.
2058 */
2059 EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2060 delegate1 = nullptr;
2061 delete manager1;
2062 manager1 = nullptr;
2063
2064 KvStoreNbDelegate *delegate2 = nullptr;
2065 KvStoreDelegateManager *manager2 = nullptr;
2066 delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2067 ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2068 /**
2069 * @tc.steps: step5. check the data in db STORE.
2070 * @tc.expected: step5. the entries is still in the db.
2071 */
2072 std::vector<DistributedDB::Entry> entriesGot;
2073 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), OK);
2074 EXPECT_TRUE(CompareEntriesVector(entriesGot, entries));
2075
2076 EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2077 delegate2 = nullptr;
2078 EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2079 delete manager2;
2080 manager2 = nullptr;
2081 }
2082
2083 /**
2084 * @tc.name: Transaction 019
2085 * @tc.desc: Verify that close the delegate before transaction commit, and it will cause the transaction rollback.
2086 * @tc.type: FUNC
2087 * @tc.require: SR000DORPP
2088 * @tc.author: fengxiaoyun
2089 */
2090 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction019, TestSize.Level1)
2091 {
2092 KvStoreNbDelegate *delegate1 = nullptr;
2093 KvStoreDelegateManager *manager1 = nullptr;
2094 delegate1 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager1, g_dbParameter2, g_option);
2095 ASSERT_TRUE(manager1 != nullptr && delegate1 != nullptr) << "get delegate1 failed.";
2096 /**
2097 * @tc.steps: step1. start transaction.
2098 * @tc.expected: step1. start transactionsuccessfully.
2099 */
2100 EXPECT_EQ(delegate1->StartTransaction(), OK);
2101 /**
2102 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2103 * @tc.expected: step2. putBatch successfully.
2104 */
2105 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2106 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*delegate1, entries), OK);
2107
2108 /**
2109 * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2110 * @tc.expected: step3. close successfully.
2111 */
2112 EXPECT_EQ(manager1->CloseKvStore(delegate1), OK);
2113 delegate1 = nullptr;
2114 delete manager1;
2115 manager1 = nullptr;
2116
2117 /**
2118 * @tc.steps: step4. create a new delegate of the same STORE
2119 * @tc.expected: step4. start successfully.
2120 */
2121 KvStoreNbDelegate *delegate2 = nullptr;
2122 KvStoreDelegateManager *manager2 = nullptr;
2123 delegate2 = DistributedDBNbTestTools::GetNbDelegateSuccess(manager2, g_dbParameter2, g_option);
2124 ASSERT_TRUE(manager2 != nullptr && delegate2 != nullptr) << "get delegate2 failed.";
2125 /**
2126 * @tc.steps: step5. commit the transaction on the new deleate, and check the data in db STORE.
2127 * @tc.expected: step5. commit failed and the entries is NULL.
2128 */
2129 EXPECT_EQ(delegate2->Commit(), DB_ERROR);
2130 std::vector<DistributedDB::Entry> entriesGot;
2131 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*delegate2, KEY_EMPTY, entriesGot), NOT_FOUND);
2132 EXPECT_TRUE(entriesGot.empty());
2133
2134 EXPECT_EQ(manager2->CloseKvStore(delegate2), OK);
2135 delegate2 = nullptr;
2136 EXPECT_EQ(manager2->DeleteKvStore(STORE_ID_2), OK);
2137 delete manager2;
2138 manager2 = nullptr;
2139 }
2140
2141 /**
2142 * @tc.name: Transaction 020
2143 * @tc.desc: Verify that close the delegate before transaction rollback, and it will cause the transaction rollback.
2144 * @tc.type: FUNC
2145 * @tc.require: SR000DORPP
2146 * @tc.author: fengxiaoyun
2147 */
2148 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction020, TestSize.Level1)
2149 {
2150 /**
2151 * @tc.steps: step1. start transaction.
2152 * @tc.expected: step1. start transactionsuccessfully.
2153 */
2154 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2155 /**
2156 * @tc.steps: step2. putBatch (k1, v1), (k2, v2) to STORE_ID_1.
2157 * @tc.expected: step2. putBatch successfully.
2158 */
2159 std::vector<DistributedDB::Entry> entries = {ENTRY_1, ENTRY_2};
2160 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2161
2162 /**
2163 * @tc.steps: step3. close the db but don't delete the STORE without committing the transaction
2164 * @tc.expected: step3. close successfully.
2165 */
2166 EXPECT_EQ(g_manager->CloseKvStore(g_nbBatchCrudDelegate), OK);
2167 g_nbBatchCrudDelegate = nullptr;
2168 delete g_manager;
2169 g_manager = nullptr;
2170
2171 /**
2172 * @tc.steps: step4. create a new delegate of the same STORE
2173 * @tc.expected: step4. start successfully.
2174 */
2175 g_nbBatchCrudDelegate = DistributedDBNbTestTools::GetNbDelegateSuccess(g_manager, g_dbParameter1, g_option);
2176 ASSERT_TRUE(g_manager != nullptr && g_nbBatchCrudDelegate != nullptr) << "get g_nbBatchCrudDelegate failed.";
2177 /**
2178 * @tc.steps: step5. Rollback the transaction on the new deleate, and check the data in db STORE.
2179 * @tc.expected: step5. Rollback failed and the entries is NULL.
2180 */
2181 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), DB_ERROR);
2182 std::vector<DistributedDB::Entry> entriesGot;
2183 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), NOT_FOUND);
2184 EXPECT_TRUE(entriesGot.empty());
2185 }
2186
2187 /**
2188 * @tc.name: Transaction 021
2189 * @tc.desc: Verify that it will failed to delete the store before transaction rollback.
2190 * @tc.type: FUNC
2191 * @tc.require: SR000DORPP
2192 * @tc.author: fengxiaoyun
2193 */
2194 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction021, TestSize.Level1)
2195 {
2196 /**
2197 * @tc.steps: step1. start transaction.
2198 * @tc.expected: step1. start transactionsuccessfully.
2199 */
2200 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2201 /**
2202 * @tc.steps: step2. put (k1, v1) to STORE_ID_1.
2203 * @tc.expected: step2. put successfully.
2204 */
2205 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2206 DistributedDB::Value value;
2207 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), OK);
2208 EXPECT_EQ(value, VALUE_1);
2209
2210 /**
2211 * @tc.steps: step3. delete the STORE without committing or rollback
2212 * the transaction
2213 * @tc.expected: step3. delete failed and returned BUSY.
2214 */
2215 EXPECT_EQ(g_manager->DeleteKvStore(STORE_ID_1), BUSY);
2216
2217 /**
2218 * @tc.steps: step4. Rollback and check the db
2219 * @tc.expected: step4. Rollback failed.
2220 */
2221 EXPECT_EQ(g_nbBatchCrudDelegate->Rollback(), OK);
2222
2223 /**
2224 * @tc.steps: step5. check the data in db STORE.
2225 * @tc.expected: step5. the DB is empty.
2226 */
2227 EXPECT_EQ(DistributedDBNbTestTools::Get(*g_nbBatchCrudDelegate, KEY_1, value), NOT_FOUND);
2228 }
2229
2230 /**
2231 * @tc.name: Transaction 022
2232 * @tc.desc: Verify transaction can't support resultSet, rekey, Import, Export, RegisterObserver interface.
2233 * @tc.type: FUNC
2234 * @tc.require: SR000DORPP
2235 * @tc.author: fengxiaoyun
2236 */
2237 HWTEST_F(DistributeddbNbBatchCrudTest, Transaction022, TestSize.Level3)
2238 {
2239 KvStoreResultSet *resultSet1 = nullptr;
2240 KvStoreResultSet *resultSet2 = nullptr;
2241 EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet1), OK);
2242 KvStoreObserverImpl observer1, observer2;
2243 vector<Entry> entries, entriesGot;
2244 EntrySize entrySize = {KEY_SIX_BYTE, VALUE_ONE_HUNDRED_BYTE};
2245 GenerateAppointPrefixAndSizeRecords(entries, entrySize, TEN_RECORDS);
2246
2247 DBStatus status = g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer1);
2248 EXPECT_EQ(status, OK);
2249
2250 const std::string importPath = DistributedDBConstant::NB_DIRECTOR + "import";
2251 const std::string importFilePath = importPath + "/importbkpDB.bin";
2252 SetDir(importPath);
2253 EXPECT_EQ(g_nbBatchCrudDelegate->Export(importFilePath, NULL_PASSWD), OK);
2254
2255 /**
2256 * @tc.steps: step1. start transaction.
2257 * @tc.expected: step1. start transaction successfully.
2258 */
2259 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2260 /**
2261 * @tc.steps: step2. putBatch entries to db.
2262 * @tc.expected: step2. putBatch successfully.
2263 */
2264 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2265 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2266 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2267
2268 vector<DistributedDB::Entry> observerCheckEntry;
2269 observerCheckEntry.clear();
2270 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, ListType::INSERT_LIST, observerCheckEntry));
2271
2272 /**
2273 * @tc.steps: step3. call rekey, import, export interface
2274 * @tc.expected: step3. all call failed and returned BUSY.
2275 */
2276 EXPECT_EQ(g_nbBatchCrudDelegate->Rekey(g_passwd1), BUSY);
2277
2278 const std::string exportPath = DistributedDBConstant::NB_DIRECTOR + "export";
2279 const std::string filePath = exportPath + "/bkpDB.bin";
2280 SetDir(exportPath);
2281 EXPECT_EQ(g_nbBatchCrudDelegate->Export(filePath, NULL_PASSWD), BUSY);
2282 EXPECT_EQ(g_nbBatchCrudDelegate->Import(importFilePath, NULL_PASSWD), BUSY);
2283 /**
2284 * @tc.steps: step4. call GetEntries to obtain resultSet2, and register observer2.
2285 * @tc.expected: step4. all call failed and returned BUSY.
2286 */
2287 EXPECT_EQ(g_nbBatchCrudDelegate->GetEntries(KEY_EMPTY, resultSet2), BUSY);
2288 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_K, OBSERVER_CHANGES_NATIVE, &observer2), BUSY);
2289
2290 /**
2291 * @tc.steps: step5. close resultSet1 and resultSet2, UnRegister observer1 and observer2.
2292 * @tc.expected: step5. close resultSet1 succeed and resultSet2 failed,
2293 * UnRegister observer1 succeed and observer2 failed.
2294 */
2295 EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet1), OK);
2296 EXPECT_EQ(g_nbBatchCrudDelegate->CloseResultSet(resultSet2), INVALID_ARGS);
2297 EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer1), OK);
2298 EXPECT_EQ(g_nbBatchCrudDelegate->UnRegisterObserver(&observer2), NOT_FOUND);
2299 /**
2300 * @tc.steps: step6. commit the transaction and check the data in db.
2301 * @tc.expected: step6. commit succeed and can find entries in DB.
2302 */
2303 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2304 EXPECT_EQ(DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, KEY_EMPTY, entriesGot), OK);
2305 EXPECT_TRUE(CompareEntriesVector(entries, entriesGot));
2306 }
2307
2308 /**
2309 * @tc.name: TransactionObserver 001
2310 * @tc.desc: Verify transaction can and only trigger observer one time.
2311 * @tc.type: FUNC
2312 * @tc.require: SR000DORPP
2313 * @tc.author: fengxiaoyun
2314 */
2315 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver001, TestSize.Level1)
2316 {
2317 /**
2318 * @tc.steps: step1. Register observer1 and observer2 of k1 and k2 separately and start the transaction.
2319 * @tc.expected: step1. Register start transaction successfully.
2320 */
2321 KvStoreObserverImpl observer1, observer2;
2322 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2323 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2324 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2325
2326 /**
2327 * @tc.steps: step2. put (k1, v1), (k3, v3) and check the callback of the observer.
2328 * @tc.expected: step2. put successfully and both of the observers can't receive the callback.
2329 */
2330 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2331 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2332 vector<DistributedDB::Entry> observerCheckList;
2333 observerCheckList.clear();
2334 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2335 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2336 /**
2337 * @tc.steps: step3. update (k1, v1) to (k1, v2) and delete (k3, v3) and check the observers.
2338 * @tc.expected: step3. update and delete successfully both of the observers can't receive the callback either.
2339 */
2340 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_2), OK);
2341 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2342 observerCheckList.clear();
2343 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ZERO_TIME, INSERT_LIST, observerCheckList));
2344 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2345
2346 /**
2347 * @tc.steps: step4. commit the transaction and check the observers.
2348 * @tc.expected: step4. commit succeed and observer1 was triggered one time and observer2 wasn't triggered.
2349 */
2350 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2351 observerCheckList.clear();
2352 observerCheckList.push_back(ENTRY_1_2);
2353 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2354 observerCheckList.clear();
2355 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2356 }
2357
2358 /**
2359 * @tc.name: TransactionObserver 002
2360 * @tc.desc: Verify transaction can and only trigger observer one time.
2361 * @tc.type: FUNC
2362 * @tc.require: SR000DORPP
2363 * @tc.author: fengxiaoyun
2364 */
2365 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver002, TestSize.Level1)
2366 {
2367 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2368 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2369 /**
2370 * @tc.steps: step1. Register observer1, observer2, observer3, observer4 of k1, k2, k3
2371 * and k4 separately and start the transaction.
2372 * @tc.expected: step1. Register and start transaction successfully.
2373 */
2374 KvStoreObserverImpl observer1, observer2, observer3, observer4;
2375 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_1, OBSERVER_CHANGES_NATIVE, &observer1), OK);
2376 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_2, OBSERVER_CHANGES_NATIVE, &observer2), OK);
2377 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, &observer3), OK);
2378 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_4, OBSERVER_CHANGES_NATIVE, &observer4), OK);
2379 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2380
2381 /**
2382 * @tc.steps: step2. put (k1, v1), (k2, v2), (k3, v3) and (k4, v4) and then delete (k1, v1) and (k4, v4).
2383 * @tc.expected: step2. put and delete successfully.
2384 */
2385 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2386 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_3, VALUE_3), OK);
2387 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_4, VALUE_4), OK);
2388
2389 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2390 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_4), OK);
2391
2392 /**
2393 * @tc.steps: step3. commit the transaction and check the observers.
2394 * @tc.expected: step3. commit succeed and observer1 received one delete notify, observer2 received one update
2395 * notify, observer3 received one insert notify, and observer4 didn't receive any notify.
2396 */
2397 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2398 vector<DistributedDB::Entry> observerCheckList;
2399 observerCheckList.clear();
2400 observerCheckList.push_back(ENTRY_1);
2401 EXPECT_TRUE(VerifyObserverResult(observer1, CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2402 observerCheckList.clear();
2403 observerCheckList.push_back(ENTRY_2_3);
2404 EXPECT_TRUE(VerifyObserverResult(observer2, CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2405 observerCheckList.clear();
2406 observerCheckList.push_back(ENTRY_3);
2407 EXPECT_TRUE(VerifyObserverResult(observer3, CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2408 observerCheckList.clear();
2409 EXPECT_TRUE(VerifyObserverResult(observer4, CHANGED_ZERO_TIME, DELETE_LIST, observerCheckList));
2410 }
2411
2412 /**
2413 * @tc.name: TransactionObserver 003
2414 * @tc.desc: Verify the different observer of same key will all be triggered after transaction
2415 * and will only be trigger once.
2416 * @tc.type: FUNC
2417 * @tc.require: SR000DORPP
2418 * @tc.author: fengxiaoyun
2419 */
2420 HWTEST_F(DistributeddbNbBatchCrudTest, TransactionObserver003, TestSize.Level1)
2421 {
2422 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_1, VALUE_1), OK);
2423 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_2), OK);
2424 /**
2425 * @tc.steps: step1. Register 8 observers of all keys.
2426 * @tc.expected: step1. Register successfully.
2427 */
2428 std::vector<KvStoreObserverImpl> observers(OBSERVER_NUM);
2429 for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2430 EXPECT_EQ(g_nbBatchCrudDelegate->RegisterObserver(KEY_EMPTY, OBSERVER_CHANGES_NATIVE, &observers[cnt]), OK);
2431 }
2432
2433 /**
2434 * @tc.steps: step2. start the transaction and putBatch (ENTRY_3), (ENTRY_4), ..., (ENTRY_8) to db.
2435 * @tc.expected: step2. start transaction and putBatch successfully.
2436 */
2437 EXPECT_EQ(g_nbBatchCrudDelegate->StartTransaction(), OK);
2438 std::vector<DistributedDB::Entry> entries = {ENTRY_3, ENTRY_4, ENTRY_5, ENTRY_6, ENTRY_7, ENTRY_8, ENTRY_9};
2439 EXPECT_EQ(DistributedDBNbTestTools::PutBatch(*g_nbBatchCrudDelegate, entries), OK);
2440
2441 /**
2442 * @tc.steps: step3. delete (k1, v1), (k3, v3) and (k9, v9), update (k2, v2) to (k2, v3).
2443 * @tc.expected: step3. operate succeed.
2444 */
2445 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_1), OK);
2446 EXPECT_EQ(DistributedDBNbTestTools::Put(*g_nbBatchCrudDelegate, KEY_2, VALUE_3), OK);
2447 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_3), OK);
2448 EXPECT_EQ(DistributedDBNbTestTools::Delete(*g_nbBatchCrudDelegate, KEY_9), OK);
2449
2450 /**
2451 * @tc.steps: step3. commit the transaction and check the observers.
2452 * @tc.expected: step3. commit succeed and all of the observers received one insert notify, callbacklist of which
2453 * contains (ENTRY_4), ..., (ENTRY_8), all observer received one update notify, callbacklist of which contains
2454 * (k2, v3), all observers received one insert notify, callback of which contains (k1, v1), (k3, v3), (k9, v9).
2455 */
2456 EXPECT_EQ(g_nbBatchCrudDelegate->Commit(), OK);
2457 vector<DistributedDB::Entry> observerCheckList;
2458 for (unsigned long cnt = 0; cnt < OBSERVER_NUM; cnt++) {
2459 observerCheckList.clear();
2460 observerCheckList.push_back(ENTRY_4);
2461 observerCheckList.push_back(ENTRY_5);
2462 observerCheckList.push_back(ENTRY_6);
2463 observerCheckList.push_back(ENTRY_7);
2464 observerCheckList.push_back(ENTRY_8);
2465 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, INSERT_LIST, observerCheckList));
2466 observerCheckList.clear();
2467 observerCheckList.push_back(ENTRY_2_3);
2468 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, UPDATE_LIST, observerCheckList));
2469 observerCheckList.clear();
2470 observerCheckList.push_back(ENTRY_1);
2471 EXPECT_TRUE(VerifyObserverResult(observers[cnt], CHANGED_ONE_TIME, DELETE_LIST, observerCheckList));
2472 }
2473 }
2474
2475 /**
2476 * @tc.name: GetKeysPressure 001
2477 * @tc.desc: Concurrent GetEntries and GetKeys.
2478 * @tc.type: FUNC
2479 * @tc.require: SR000DORPP
2480 * @tc.author: xuhongkang
2481 */
2482 #ifdef GETKEYS_PRESSURE001
2483 HWTEST_F(DistributeddbNbBatchCrudTest, GetKeysPressure001, TestSize.Level3)
2484 {
2485 DBStatus status, status1, status2;
2486 std::vector<Key> allKeysKA, allKeysKB, expectKeyResult;
2487 std::vector<Entry> entriesA, entriesB, entriesBatch;
2488 DistributedDB::Value longValue1;
2489 DistributedDB::Key ka = {'k', 'a'};
2490 DistributedDB::Key kb = {'k', 'b'};
2491 longValue1.assign(ONE_K_LONG_STRING, (uint8_t)'v');
2492 GenerateRecords(TEN_THOUSAND_RECORDS, DEFAULT_START, allKeysKA, entriesA, ka);
2493 GenerateRecords(FIVE_THOUSANDS_RECORDS, DEFAULT_START, allKeysKB, entriesB, kb);
2494
2495 entriesBatch.insert(entriesBatch.end(), entriesA.begin(), entriesA.end());
2496 entriesBatch.insert(entriesBatch.end(), entriesB.begin(), entriesB.end());
2497 for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++)
2498 {
2499 if (index < TEN_THOUSAND_RECORDS) {
2500 entriesA[index].value = longValue1;
2501 }
2502 entriesBatch[index].value = longValue1;
2503 status = g_nbBatchCrudDelegate->Put(entriesBatch[index].key, entriesBatch[index].value);
2504 EXPECT_EQ(status, OK);
2505 }
2506 std::vector<Key> keyResult;
2507 std::vector<Entry> valueResult;
__anon07ddae6e0c02() 2508 std::thread sub = std::thread([&status1, &ka, &valueResult]() {
2509 status1 = DistributedDBNbTestTools::GetEntries(*g_nbBatchCrudDelegate, ka, valueResult);
2510 });
2511 status2 = DistributedDBNbTestTools::GetKeys(*g_nbBatchCrudDelegate, KEY_EMPTY, keyResult);
2512 sub.join();
2513 EXPECT_EQ(status1, OK);
2514 EXPECT_EQ(status2, OK);
2515 expectKeyResult.insert(expectKeyResult.end(), allKeysKA.begin(), allKeysKA.end());
2516 expectKeyResult.insert(expectKeyResult.end(), allKeysKB.begin(), allKeysKB.end());
2517 sort(keyResult.begin(), keyResult.end());
2518 sort(expectKeyResult.begin(), expectKeyResult.end());
2519 for (unsigned int index = 0; index < FIFTEEN_THOUSAND_RECORDS; index++) {
2520 string actResult(keyResult[index].begin(), keyResult[index].end());
2521 string expectResult(expectKeyResult[index].begin(), expectKeyResult[index].end());
2522 bool result = (actResult == expectResult);
2523 EXPECT_EQ(result, true);
2524 }
2525 EXPECT_TRUE(CompareEntriesVector(valueResult, entriesA));
2526 }
2527 #endif // GETKEYS_PRESSURE001
2528 }
2529