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