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 
16 #include <gtest/gtest.h>
17 
18 #include "db_common.h"
19 #include "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "log_print.h"
22 
23 using namespace testing::ext;
24 using namespace DistributedDB;
25 using namespace DistributedDBUnitTest;
26 using namespace std;
27 
28 namespace {
29     const int BATCH_BASE_SIZE = 60;
30     const Key NULL_KEY;
31     const Key NULL_VALUE;
32     const int CONFLICT_ALL = 15;
33     const auto OLD_VALUE_TYPE = KvStoreNbConflictData::ValueType::OLD_VALUE;
34     const auto NEW_VALUE_TYPE = KvStoreNbConflictData::ValueType::NEW_VALUE;
35 
36     const int OBSERVER_SLEEP_TIME = 30;
37 
38     // define some variables to init a KvStoreDelegateManager object.
39     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
40     string g_testDir;
41     KvStoreConfig g_config;
42 
43     // define the g_kvNbDelegateCallback, used to get some information when open a kv store.
44     DBStatus g_kvDelegateStatus = INVALID_ARGS;
45     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
46 
47     struct SingleVerConflictData {
48         KvStoreNbConflictType type = CONFLICT_NATIVE_ALL;
49         Key key;
50         Value oldValue;
51         Value newValue;
52         bool oldIsDeleted = false;
53         bool newIsDeleted = false;
54         bool oldIsNative = false;
55         bool newIsNative = false;
56         int getoldValueErrCode = 0;
57         int getNewValueErrCode = 0;
operator ==__anon295c024f0110::SingleVerConflictData58         bool operator==(const SingleVerConflictData &comparedData) const
59         {
60             if (this->type == comparedData.type &&
61                 this->key == comparedData.key &&
62                 this->oldValue == comparedData.oldValue &&
63                 this->newValue == comparedData.newValue &&
64                 this->oldIsDeleted == comparedData.oldIsDeleted &&
65                 this->newIsDeleted == comparedData.newIsDeleted &&
66                 this->oldIsNative == comparedData.oldIsNative &&
67                 this->newIsNative == comparedData.newIsNative &&
68                 this->getoldValueErrCode == comparedData.getoldValueErrCode &&
69                 this->getNewValueErrCode == comparedData.getNewValueErrCode) {
70                 return true;
71             }
72             LOGD("type = %d, ctype = %d", this->type, comparedData.type);
73             DBCommon::PrintHexVector(this->key, __LINE__, "key");
74             DBCommon::PrintHexVector(comparedData.key, __LINE__, "ckey");
75             DBCommon::PrintHexVector(this->oldValue, __LINE__, "oldValue");
76             DBCommon::PrintHexVector(comparedData.oldValue, __LINE__, "coldValue");
77             DBCommon::PrintHexVector(this->newValue, __LINE__, "newValue");
78             DBCommon::PrintHexVector(comparedData.newValue, __LINE__, "cnewValue");
79 
80             LOGD("oldIsDeleted = %d, coldIsDeleted = %d", this->oldIsDeleted, comparedData.oldIsDeleted);
81             LOGD("newIsDeleted = %d, cnewIsDeleted = %d", this->newIsDeleted, comparedData.newIsDeleted);
82             LOGD("oldIsNative = %d, coldIsNative = %d", this->oldIsNative, comparedData.oldIsNative);
83             LOGD("newIsNative = %d, cnewIsNative = %d", this->newIsNative, comparedData.newIsNative);
84             LOGD("getoldValueErrCode = %d, cgetoldValueErrCode = %d", this->getoldValueErrCode,
85                 comparedData.getoldValueErrCode);
86             LOGD("getNewValueErrCode = %d, cgetNewValueErrCode = %d", this->getNewValueErrCode,
87                 comparedData.getNewValueErrCode);
88 
89             return false;
90         }
91     };
92     std::vector<SingleVerConflictData> g_conflictData;
93 
KvStoreNbDelegateCallback(DBStatus statusSrc,KvStoreNbDelegate * kvStoreSrc,DBStatus * statusDst,KvStoreNbDelegate ** kvStoreDst)94     void KvStoreNbDelegateCallback(DBStatus statusSrc, KvStoreNbDelegate *kvStoreSrc,
95         DBStatus *statusDst, KvStoreNbDelegate **kvStoreDst)
96     {
97         *statusDst = statusSrc;
98         *kvStoreDst = kvStoreSrc;
99     }
100 
101     // the type of g_kvNbDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
102     auto g_kvNbDelegateCallback = bind(&KvStoreNbDelegateCallback, placeholders::_1,
103         placeholders::_2, &g_kvDelegateStatus, &g_kvNbDelegatePtr);
104 
NotifierCallback(const KvStoreNbConflictData & data)105     void NotifierCallback(const KvStoreNbConflictData &data)
106     {
107         Key key;
108         Value oldValue;
109         Value newValue;
110         data.GetKey(key);
111         data.GetValue(OLD_VALUE_TYPE, oldValue);
112         LOGD("Get new value status:%d", data.GetValue(NEW_VALUE_TYPE, newValue));
113         LOGD("Type:%d", data.GetType());
114         DBCommon::PrintHexVector(oldValue, __LINE__);
115         DBCommon::PrintHexVector(newValue, __LINE__);
116         LOGD("Type:IsDeleted %d vs %d, IsNative %d vs %d", data.IsDeleted(OLD_VALUE_TYPE),
117             data.IsDeleted(NEW_VALUE_TYPE), data.IsNative(OLD_VALUE_TYPE), data.IsNative(NEW_VALUE_TYPE));
118         g_conflictData.push_back({data.GetType(), key, oldValue, newValue, data.IsDeleted(OLD_VALUE_TYPE),
119             data.IsDeleted(NEW_VALUE_TYPE), data.IsNative(OLD_VALUE_TYPE), data.IsNative(NEW_VALUE_TYPE),
120             data.GetValue(OLD_VALUE_TYPE, oldValue), data.GetValue(NEW_VALUE_TYPE, newValue)});
121     }
122 }
123 
124 class DistributedDBInterfacesNBTransactionTest : public testing::Test {
125 public:
126     static void SetUpTestCase(void);
127     static void TearDownTestCase(void);
128     void SetUp();
129     void TearDown();
130 };
131 
SetUpTestCase(void)132 void DistributedDBInterfacesNBTransactionTest::SetUpTestCase(void)
133 {
134     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
135     g_config.dataDir = g_testDir;
136     g_mgr.SetKvStoreConfig(g_config);
137     g_mgr.SetProcessLabel("DistributedDBInterfacesNBTransactionTest", "test");
138 }
139 
TearDownTestCase(void)140 void DistributedDBInterfacesNBTransactionTest::TearDownTestCase(void)
141 {
142     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
143         LOGE("rm test db files error!");
144     }
145 }
146 
SetUp(void)147 void DistributedDBInterfacesNBTransactionTest::SetUp(void)
148 {
149     DistributedDBToolsUnitTest::PrintTestCaseInfo();
150     g_kvDelegateStatus = INVALID_ARGS;
151     g_kvNbDelegatePtr = nullptr;
152 }
153 
TearDown(void)154 void DistributedDBInterfacesNBTransactionTest::TearDown(void) {}
155 
156 /**
157   * @tc.name: start001
158   * @tc.desc: Test the nb transaction start twice.
159   * @tc.type: FUNC
160   * @tc.require: AR000DPTQ9
161   * @tc.author: wumin
162   */
163 HWTEST_F(DistributedDBInterfacesNBTransactionTest, start001, TestSize.Level1)
164 {
165     const KvStoreNbDelegate::Option option = {true, false};
166     g_mgr.GetKvStore("distributed_nb_transaction_start001", option, g_kvNbDelegateCallback);
167     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
168     EXPECT_TRUE(g_kvDelegateStatus == OK);
169 
170     /**
171      * @tc.steps:step1. Start transaction.
172      * @tc.expected: step1. return OK.
173      */
174     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
175 
176     /**
177      * @tc.steps:step2. Start transaction again.
178      * @tc.expected: step2. return DB_ERROR.
179      */
180     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), DB_ERROR);
181 
182     // finilize
183     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
184     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_start001"), OK);
185     g_kvNbDelegatePtr = nullptr;
186 }
187 
188 /**
189   * @tc.name: start002
190   * @tc.desc: Test the nb transaction begin and end not match.
191   * @tc.type: FUNC
192   * @tc.require: AR000DPTQ9
193   * @tc.author: wumin
194   */
195 HWTEST_F(DistributedDBInterfacesNBTransactionTest, start002, TestSize.Level1)
196 {
197     const KvStoreNbDelegate::Option option = {true, false};
198     g_mgr.GetKvStore("distributed_nb_transaction_start002", option, g_kvNbDelegateCallback);
199     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
200     EXPECT_TRUE(g_kvDelegateStatus == OK);
201     /**
202      * @tc.steps:step1. Start transaction.
203      * @tc.expected: step1. return OK.
204      */
205     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
206     /**
207      * @tc.steps:step2. Rollback transaction.
208      * @tc.expected: step2. return OK.
209      */
210     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
211     /**
212      * @tc.steps:step3. Commit transaction.
213      * @tc.expected: step3. return DB_ERROR.
214      */
215     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), DB_ERROR);
216     /**
217      * @tc.steps:step4. Start transaction.
218      * @tc.expected: step4. return OK.
219      */
220     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
221     /**
222      * @tc.steps:step5. Commit transaction.
223      * @tc.expected: step5. return DB_ERROR.
224      */
225     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
226     /**
227      * @tc.steps:step6. Rollback transaction.
228      * @tc.expected: step6. return OK.
229      */
230     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), DB_ERROR);
231 
232     // finilize
233     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
234     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_start002"), OK);
235     g_kvNbDelegatePtr = nullptr;
236 }
237 
238 /**
239   * @tc.name: start003
240   * @tc.desc: Test the nb transaction rollback automatically when db close.
241   * @tc.type: FUNC
242   * @tc.require: AR000DPTQ9
243   * @tc.author: wumin
244   */
245 HWTEST_F(DistributedDBInterfacesNBTransactionTest, start003, TestSize.Level1)
246 {
247     const KvStoreNbDelegate::Option option = {true, false};
248     g_mgr.GetKvStore("distributed_nb_transaction_start003", option, g_kvNbDelegateCallback);
249     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
250     EXPECT_TRUE(g_kvDelegateStatus == OK);
251     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
252     /**
253      * @tc.steps:step1. Start transaction.
254      * @tc.expected: step1. return OK.
255      */
256     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
257 
258     /**
259      * @tc.steps:step2. Put (key1,value2)
260      * @tc.expected: step2. return OK.
261      */
262     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_2), OK);
263     /**
264      * @tc.steps:step3. Close db
265      * @tc.expected: step3. return OK.
266      */
267     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
268     g_kvNbDelegatePtr = nullptr;
269     /**
270      * @tc.steps:step4. Open db again
271      * @tc.expected: step4. return OK.
272      */
273     g_mgr.GetKvStore("distributed_nb_transaction_start003", option, g_kvNbDelegateCallback);
274     EXPECT_TRUE(g_kvDelegateStatus == OK);
275     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
276     /**
277      * @tc.steps:step5. Get key1
278      * @tc.expected: step5. return OK, value of key1 is value1.
279      */
280     Value value;
281     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_1, value), OK);
282     EXPECT_EQ(value, VALUE_1);
283 
284     // finilize
285     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
286     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_start003"), OK);
287     g_kvNbDelegatePtr = nullptr;
288 }
289 
290 /**
291   * @tc.name: start004
292   * @tc.desc: Test the nb operations return BUSY after transaction started.
293   * @tc.type: FUNC
294   * @tc.require: AR000DPTQ9
295   * @tc.author: wumin
296   */
297 HWTEST_F(DistributedDBInterfacesNBTransactionTest, start004, TestSize.Level4)
298 {
299     const KvStoreNbDelegate::Option option = {true, false};
300     g_mgr.GetKvStore("distributed_nb_transaction_start004", option, g_kvNbDelegateCallback);
301     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
302     EXPECT_TRUE(g_kvDelegateStatus == OK);
303     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
304     /**
305      * @tc.steps:step1. Start transaction.
306      * @tc.expected: step1. return OK.
307      */
308     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
309     /**
310      * @tc.steps:step2. Local data and sync data can be simultaneously operated in transactions.
311      * @tc.expected: step2. From September 2020 return OK.
312      */
313     EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(KEY_3, VALUE_3), OK);
314     EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocal(KEY_1), OK);
315 
316     CipherPassword password;
317     EXPECT_EQ(g_kvNbDelegatePtr->Rekey(password), BUSY);
318 
319     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
320     ASSERT_TRUE(observer != nullptr);
321     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(KEY_3, OBSERVER_CHANGES_NATIVE, observer), BUSY);
322     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(observer), NOT_FOUND);
323     delete observer;
324     observer = nullptr;
325 
326     std::string filePath = g_testDir + "/test.txt";
327     EXPECT_EQ(g_kvNbDelegatePtr->Export(filePath, password), BUSY);
328 
329     KvStoreResultSet *readResultSet = nullptr;
330     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(KEY_4, readResultSet), BUSY);
331     EXPECT_EQ(g_kvNbDelegatePtr->CloseResultSet(readResultSet), INVALID_ARGS);
332     /**
333      * @tc.steps:step1. Commit transaction.
334      * @tc.expected: step1. return OK.
335      */
336     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
337 
338     // finilize
339     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
340     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_start004"), OK);
341     g_kvNbDelegatePtr = nullptr;
342 }
343 
344 /**
345   * @tc.name: commit001
346   * @tc.desc: Test the nb transaction commit without start.
347   * @tc.type: FUNC
348   * @tc.require: AR000DPTQ9
349   * @tc.author: wumin
350   */
351 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit001, TestSize.Level1)
352 {
353     const KvStoreNbDelegate::Option option = {true, false};
354     g_mgr.GetKvStore("distributed_nb_transaction_commit001", option, g_kvNbDelegateCallback);
355     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
356     EXPECT_TRUE(g_kvDelegateStatus == OK);
357     /**
358      * @tc.steps:step1. Commit transaction.
359      * @tc.expected: step1. return DB_ERROR.
360      */
361     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), DB_ERROR);
362 
363     // finilize
364     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
365     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit001"), OK);
366     g_kvNbDelegatePtr = nullptr;
367 }
368 
369 /**
370   * @tc.name: commit002
371   * @tc.desc: Test the nb transaction commit twice.
372   * @tc.type: FUNC
373   * @tc.require: AR000DPTQ9
374   * @tc.author: wumin
375   */
376 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit002, TestSize.Level1)
377 {
378     const KvStoreNbDelegate::Option option = {true, false};
379     g_mgr.GetKvStore("distributed_nb_transaction_commit002", option, g_kvNbDelegateCallback);
380     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
381     EXPECT_TRUE(g_kvDelegateStatus == OK);
382     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
383     /**
384      * @tc.steps:step1. Start transaction.
385      * @tc.expected: step1. return OK.
386      */
387     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
388     /**
389      * @tc.steps:step2. Get key1
390      * @tc.expected: step2. return OK, value of key1 is value1.
391      */
392     Value value1;
393     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_1, value1), OK);
394     EXPECT_EQ(value1, VALUE_1);
395     /**
396      * @tc.steps:step3. Put (key2,value2)
397      * @tc.expected: step3. return OK.
398      */
399     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
400     /**
401      * @tc.steps:step4. Get key2
402      * @tc.expected: step4. return OK, value of key2 is value2.
403      */
404     Value value2;
405     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_2, value2), OK);
406     EXPECT_EQ(value2, VALUE_2);
407     /**
408      * @tc.steps:step5. Commit transaction.
409      * @tc.expected: step5. return OK.
410      */
411     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
412     /**
413      * @tc.steps:step6. Commit transaction again.
414      * @tc.expected: step6. return DB_ERROR.
415      */
416     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), DB_ERROR);
417 
418     // finilize
419     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
420     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit002"), OK);
421     g_kvNbDelegatePtr = nullptr;
422 }
423 
424 /**
425   * @tc.name: commit003
426   * @tc.desc: Test the entry size exceed the maximum limit in one transaction
427   * @tc.type: FUNC
428   * @tc.require: AR000DPTQ9
429   * @tc.author: wumin
430   */
431 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit003, TestSize.Level1)
432 {
433     const KvStoreNbDelegate::Option option = {true, false};
434     g_mgr.GetKvStore("distributed_nb_transaction_commit003", option, g_kvNbDelegateCallback);
435     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
436     EXPECT_TRUE(g_kvDelegateStatus == OK);
437     /**
438      * @tc.steps:step1. Start transaction.
439      * @tc.expected: step1. return OK.
440      */
441     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
442     /**
443      * @tc.steps:step2. Put (key1,value1) and Delete key1, sum size is 2KB
444      * @tc.expected: step2. return OK.
445      */
446     Key legalKey;
447     DistributedDBToolsUnitTest::GetRandomKeyValue(legalKey, DBConstant::MAX_KEY_SIZE); // 1K
448     Value legalValue;
449     DistributedDBToolsUnitTest::GetRandomKeyValue(legalValue, DBConstant::MAX_KEY_SIZE); // 1K
450     Value emptyValue;
451     EXPECT_EQ(g_kvNbDelegatePtr->Put(legalKey, emptyValue), OK);
452     EXPECT_EQ(g_kvNbDelegatePtr->Delete(legalKey), OK);
453     /**
454      * @tc.steps:step3. PutBatch 262143 records, each recode's key size is 1K, value size is 1k,
455      * the sum size is 512M - 4KB.
456      * @tc.expected: step3. return OK.
457      */
458 
459     vector<Entry> entrysBase; // size is 512M - 4KB
460     for (int i = 0; i < 262142; i++) { // 262143 * (legalValue + legalKey) is equal to 512M - 4KB.
461         entrysBase.push_back({legalKey, legalValue});
462     }
463 
464     vector<Key> keysBase; // size is 3KB
465     for (int i = 0; i < 3; i++) { // 3 * legalKey is equal to 3KB.
466         keysBase.push_back(legalKey);
467     }
468 
469     ASSERT_EQ(g_kvNbDelegatePtr->PutBatch(entrysBase), OK); // put 512M - 2KB size data into db.
470     /**
471      * @tc.steps:step4. PutBatch which entries size is 4KB and DeleteBatch record which keys size 3KB,
472      * and the sum size is 512M + 1KB
473      * @tc.expected: step4. return OVER_MAX_LIMITS.
474      */
475     vector<Entry> entrys1(entrysBase.begin(), entrysBase.begin() + 2); // 4KB
476     ASSERT_EQ(g_kvNbDelegatePtr->PutBatch(entrys1), OVER_MAX_LIMITS);
477 
478     vector<Key> keys1(keysBase.begin(), keysBase.end());
479     ASSERT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys1), OVER_MAX_LIMITS);
480     /**
481      * @tc.steps:step5. DeleteBatch record which keys size is 2KB, and the sum size is 512M
482      * @tc.expected:step5. return OK.
483      */
484     vector<Key> keys2(keysBase.begin(), keysBase.end() - 1);
485     ASSERT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys2), OK);
486     /**
487      * @tc.steps:step6. Commit.
488      * @tc.expected:step6. return OK.
489      */
490     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
491     // finilize
492     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
493     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit003"), OK);
494     g_kvNbDelegatePtr = nullptr;
495 }
496 
497 /**
498   * @tc.name: commit004
499   * @tc.desc: Test the nb normal operations in one transaction
500   * @tc.type: FUNC
501   * @tc.require: AR000DPTQ9
502   * @tc.author: wumin
503   */
504 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit004, TestSize.Level1)
505 {
506     const KvStoreNbDelegate::Option option = {true, false};
507     g_mgr.GetKvStore("distributed_nb_transaction_commit004", option, g_kvNbDelegateCallback);
508     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
509     EXPECT_TRUE(g_kvDelegateStatus == OK);
510     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
511     ASSERT_TRUE(observer != nullptr);
512     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(NULL_KEY, OBSERVER_CHANGES_NATIVE, observer), OK);
513     /**
514      * @tc.steps:step1. Start transaction.
515      * @tc.expected: step1. return OK.
516      */
517     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
518     /**
519      * @tc.steps:step2. Put (key1,value1) and (key2,value2)
520      * @tc.expected: step2. put OK.
521      */
522     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
523     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
524     /**
525      * @tc.steps:step3. Delete key2
526      * @tc.expected: step3. return OK.
527      */
528     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_2), OK);
529     /**
530      * @tc.steps:step4. PutBatch 65 records (from key3 to key67)
531      * @tc.expected: step4. return OK.
532      */
533     vector<Entry> entrysBase;
534     vector<Key> keysBase;
535     DistributedDBUnitTest::GenerateRecords(BATCH_BASE_SIZE + 7, entrysBase, keysBase);
536 
537     vector<Entry> entrys1(entrysBase.begin() + 2, entrysBase.end());
538     EXPECT_EQ(entrys1.size(), 65UL);
539     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrys1), OK);
540     /**
541      * @tc.steps:step5. DeleteBatch 60 records (from key8 to key67)
542      * @tc.expected: step5. return OK.
543      */
544     vector<Key> keys(keysBase.begin() + 7, keysBase.end());
545     EXPECT_EQ(keys.size(), 60UL);
546     EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys), OK);
547     /**
548      * @tc.steps:step6. Commit.
549      * @tc.expected: step6. return OK.
550      */
551     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
552     /**
553      * @tc.steps:step7. Check observer data.
554      * @tc.expected: step6. return OK.
555      */
556     vector<Entry> entriesRet;
557     Entry entry1 = {KEY_1, VALUE_1};
558     entriesRet.push_back(entry1);
559     entriesRet.insert(entriesRet.end(), entrysBase.begin() + 2, entrysBase.begin() + 7);
560     EXPECT_EQ(entriesRet.size(), 6UL);
561 
562     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
563     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(entriesRet, observer->GetEntriesInserted()));
564     /**
565      * @tc.steps:step8. GetEntries.
566      * @tc.expected: step8. return OK.
567      */
568     const Key prefix;
569     vector<Entry> entries;
570     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
571     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(entriesRet, entries, true));
572 
573     // finilize
574     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(observer), OK);
575     delete observer;
576     observer = nullptr;
577 
578     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
579     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit004"), OK);
580     g_kvNbDelegatePtr = nullptr;
581 }
582 
583 /**
584   * @tc.name: commit005
585   * @tc.desc: Test the conflict data report normally in one transaction
586   * @tc.type: FUNC
587   * @tc.require: AR000DPTQ9
588   * @tc.author: wumin
589   */
590 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit005, TestSize.Level1)
591 {
592     const KvStoreNbDelegate::Option option = {true, false};
593     g_mgr.GetKvStore("distributed_nb_transaction_commit005", option, g_kvNbDelegateCallback);
594     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
595     EXPECT_TRUE(g_kvDelegateStatus == OK);
596     EXPECT_TRUE(g_kvNbDelegatePtr->SetConflictNotifier(CONFLICT_ALL, NotifierCallback) == OK);
597 
598     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
599     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
600     /**
601      * @tc.steps:step1. Start transaction.
602      * @tc.expected: step1. return OK.
603      */
604     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
605     /**
606      * @tc.steps:step2. Put (key1,value3) and (key2,value4)
607      * @tc.expected: step2. put OK.
608      */
609     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_3), OK);
610     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_4), OK);
611     /**
612      * @tc.steps:step3. Delete key2
613      * @tc.expected: step3. return OK.
614      */
615     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_2), OK);
616     /**
617      * @tc.steps:step4. put (key3 ,value5) (key3 ,value6)
618      * @tc.expected: step4. return OK.
619      */
620     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_3, VALUE_5), OK);
621     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_3, VALUE_6), OK);
622     /**
623      * @tc.steps:step5. Commit.
624      * @tc.expected: step5. return OK.
625      */
626     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
627     /**
628      * @tc.steps:step6. Check conflict report data.
629      * @tc.expected: step6. return OK.
630      */
631     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
632     EXPECT_EQ(g_conflictData.size(), 2UL);
633     if (g_conflictData.size() == 2) {
634         SingleVerConflictData expectNotifyData1 = {KvStoreNbConflictType::CONFLICT_NATIVE_ALL,
635             KEY_1, VALUE_1, VALUE_3, false, false, true, true, OK, OK};
636         EXPECT_EQ(g_conflictData[0], expectNotifyData1);
637 
638         SingleVerConflictData expectNotifyData2 = {KvStoreNbConflictType::CONFLICT_NATIVE_ALL,
639             KEY_2, VALUE_2, NULL_VALUE, false, true, true, true, OK, DB_ERROR};
640         EXPECT_EQ(g_conflictData[1], expectNotifyData2);
641     }
642 
643     // finilize
644     g_conflictData.clear();
645     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
646     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit005"), OK);
647     g_kvNbDelegatePtr = nullptr;
648 }
649 
650 /**
651   * @tc.name: commit006
652   * @tc.desc: Test the conflict data report and observer function both be normal in one transaction
653   * @tc.type: FUNC
654   * @tc.require: AR000DPTQ9
655   * @tc.author: wumin
656   */
657 HWTEST_F(DistributedDBInterfacesNBTransactionTest, commit006, TestSize.Level1)
658 {
659     const KvStoreNbDelegate::Option option = {true, false};
660     g_mgr.GetKvStore("distributed_nb_transaction_commit006", option, g_kvNbDelegateCallback);
661     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
662     EXPECT_TRUE(g_kvDelegateStatus == OK);
663 
664     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
665     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_1), OK);
666 
667     EXPECT_TRUE(g_kvNbDelegatePtr->SetConflictNotifier(CONFLICT_ALL, NotifierCallback) == OK);
668 
669     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
670     ASSERT_TRUE(observer != nullptr);
671     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(NULL_KEY, OBSERVER_CHANGES_NATIVE, observer), OK);
672     /**
673      * @tc.steps:step1. Start transaction.
674      * @tc.expected: step1. return OK.
675      */
676     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
677     /**
678      * @tc.steps:step2. Put (key1,value2)
679      * @tc.expected: step2. put OK.
680      */
681     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_2), OK);
682     /**
683      * @tc.steps:step3. Commit.
684      * @tc.expected: step3. return OK.
685      */
686     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
687     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
688     /**
689      * @tc.steps:step4. Get value of key1.
690      * @tc.expected: step4. return OK, value of key1 is value2.
691      */
692     Value readValue;
693     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY_1, readValue), OK);
694     EXPECT_TRUE(readValue == VALUE_2);
695     /**
696      * @tc.steps:step5. Check observer data.
697      * @tc.expected: step5. return OK.
698      */
699     vector<Entry> entriesRet = {{KEY_1, VALUE_2}};
700     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(entriesRet, observer->GetEntriesInserted()));
701     /**
702      * @tc.steps:step6. Check conflict report data.
703      * @tc.expected: step6. return OK.
704      */
705     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
706     EXPECT_EQ(g_conflictData.size(), 1UL);
707     if (g_conflictData.size() == 1) {
708         SingleVerConflictData expectNotifyData = {KvStoreNbConflictType::CONFLICT_NATIVE_ALL,
709             KEY_1, {}, VALUE_2, true, false, true, true, DB_ERROR, OK};
710         EXPECT_EQ(g_conflictData[0], expectNotifyData);
711     }
712 
713     // finilize
714     g_conflictData.clear();
715     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(observer), OK);
716     delete observer;
717     observer = nullptr;
718 
719     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
720     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_commit006"), OK);
721     g_kvNbDelegatePtr = nullptr;
722 }
723 
724 /**
725   * @tc.name: rollback001
726   * @tc.desc: Test the transaction rollback without start.
727   * @tc.type: FUNC
728   * @tc.require: AR000DPTQ9
729   * @tc.author: wumin
730   */
731 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback001, TestSize.Level1)
732 {
733     const KvStoreNbDelegate::Option option = {true, false};
734     g_mgr.GetKvStore("distributed_nb_transaction_rollback001", option, g_kvNbDelegateCallback);
735     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
736     EXPECT_TRUE(g_kvDelegateStatus == OK);
737     /**
738      * @tc.steps:step1. Transaction rollback without start.
739      * @tc.expected: step1. return DB_ERROR.
740      */
741     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), DB_ERROR);
742 
743     // finilize
744     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
745     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback001"), OK);
746     g_kvNbDelegatePtr = nullptr;
747 }
748 
749 /**
750   * @tc.name: rollback002
751   * @tc.desc: Test the transaction rollback twice
752   * @tc.type: FUNC
753   * @tc.require: AR000DPTQ9
754   * @tc.author: wumin
755   */
756 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback002, TestSize.Level1)
757 {
758     const KvStoreNbDelegate::Option option = {true, false};
759     g_mgr.GetKvStore("distributed_nb_transaction_rollback002", option, g_kvNbDelegateCallback);
760     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
761     EXPECT_TRUE(g_kvDelegateStatus == OK);
762     /**
763      * @tc.steps:step1. Start transaction.
764      * @tc.expected: step1. return OK.
765      */
766     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
767     /**
768      * @tc.steps:step1. Rollback.
769      * @tc.expected: step1. return OK.
770      */
771     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
772     /**
773      * @tc.steps:step1. Transaction rollback without start.
774      * @tc.expected: step1. return DB_ERROR.
775      */
776     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), DB_ERROR);
777 
778     // finilize
779     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
780     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback002"), OK);
781     g_kvNbDelegatePtr = nullptr;
782 }
783 
784 /**
785   * @tc.name: rollback003
786   * @tc.desc: Test the Put operation rollback
787   * @tc.type: FUNC
788   * @tc.require: AR000DPTQ9
789   * @tc.author: wumin
790   */
791 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback003, TestSize.Level1)
792 {
793     const KvStoreNbDelegate::Option option = {true, false};
794     g_mgr.GetKvStore("distributed_nb_transaction_rollback003", option, g_kvNbDelegateCallback);
795     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
796     EXPECT_TRUE(g_kvDelegateStatus == OK);
797     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
798     /**
799      * @tc.steps:step1. Start transaction.
800      * @tc.expected: step1. return OK.
801      */
802     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
803     /**
804      * @tc.steps:step2. Put (key2,value2)
805      * @tc.expected: step2. return OK.
806      */
807     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
808     /**
809      * @tc.steps:step3. Rollback.
810      * @tc.expected: step3. return OK.
811      */
812     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
813     /**
814      * @tc.steps:step4. GetEntries.
815      * @tc.expected: step4. return OK.
816      */
817     const Key prefix;
818     vector<Entry> entries;
819     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
820     EXPECT_EQ(entries.size(), 1UL);
821     if (entries.size() > 0) {
822         EXPECT_EQ(entries[0].key, KEY_1);
823         EXPECT_EQ(entries[0].value, VALUE_1);
824     }
825 
826     // finilize
827     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
828     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback003"), OK);
829     g_kvNbDelegatePtr = nullptr;
830 }
831 
832 /**
833   * @tc.name: rollback004
834   * @tc.desc: Test the PutBatch operation rollback
835   * @tc.type: FUNC
836   * @tc.require: AR000DPTQ9
837   * @tc.author: wumin
838   */
839 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback004, TestSize.Level1)
840 {
841     const KvStoreNbDelegate::Option option = {true, false};
842     g_mgr.GetKvStore("distributed_nb_transaction_rollback004", option, g_kvNbDelegateCallback);
843     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
844     EXPECT_TRUE(g_kvDelegateStatus == OK);
845     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
846     /**
847      * @tc.steps:step1. Start transaction.
848      * @tc.expected: step1. return OK.
849      */
850     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
851     /**
852      * @tc.steps:step2. PutBatch 10 records
853      * @tc.expected: step2. return OK.
854      */
855     vector<Entry> entrysBase;
856     vector<Key> keysBase;
857     DistributedDBUnitTest::GenerateRecords(10, entrysBase, keysBase);
858 
859     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrysBase), OK);
860     /**
861      * @tc.steps:step3. Rollback.
862      * @tc.expected: step3. return OK.
863      */
864     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
865     /**
866      * @tc.steps:step4. GetEntries.
867      * @tc.expected: step4. return OK.
868      */
869     const Key prefix;
870     vector<Entry> entries;
871     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
872     EXPECT_EQ(entries.size(), 1UL);
873     if (entries.size() > 0) {
874         EXPECT_EQ(entries[0].key, KEY_1);
875         EXPECT_EQ(entries[0].value, VALUE_1);
876     }
877 
878     // finilize
879     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
880     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback004"), OK);
881     g_kvNbDelegatePtr = nullptr;
882 }
883 
884 /**
885   * @tc.name: rollback005
886   * @tc.desc: Test the modify operation rollback
887   * @tc.type: FUNC
888   * @tc.require: AR000DPTQ9
889   * @tc.author: wumin
890   */
891 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback005, TestSize.Level1)
892 {
893     const KvStoreNbDelegate::Option option = {true, false};
894     g_mgr.GetKvStore("distributed_nb_transaction_rollback005", option, g_kvNbDelegateCallback);
895     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
896     EXPECT_TRUE(g_kvDelegateStatus == OK);
897     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
898     /**
899      * @tc.steps:step1. Start transaction.
900      * @tc.expected: step1. return OK.
901      */
902     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
903     /**
904      * @tc.steps:step2. Put (key1,value2)
905      * @tc.expected: step2. return OK.
906      */
907     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_2), OK);
908     /**
909      * @tc.steps:step3. Rollback.
910      * @tc.expected: step3. return OK.
911      */
912     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
913     /**
914      * @tc.steps:step4. GetEntries.
915      * @tc.expected: step4. return OK.
916      */
917     const Key prefix;
918     vector<Entry> entries;
919     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
920     EXPECT_EQ(entries.size(), 1UL);
921     if (entries.size() > 0) {
922         EXPECT_EQ(entries[0].key, KEY_1);
923         EXPECT_EQ(entries[0].value, VALUE_1);
924     }
925 
926     // finilize
927     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
928     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback005"), OK);
929     g_kvNbDelegatePtr = nullptr;
930 }
931 
932 /**
933   * @tc.name: rollback006
934   * @tc.desc: Test the Delete operation rollback
935   * @tc.type: FUNC
936   * @tc.require: AR000DPTQ9
937   * @tc.author: wumin
938   */
939 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback006, TestSize.Level1)
940 {
941     const KvStoreNbDelegate::Option option = {true, false};
942     g_mgr.GetKvStore("distributed_nb_transaction_rollback006", option, g_kvNbDelegateCallback);
943     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
944     EXPECT_TRUE(g_kvDelegateStatus == OK);
945     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
946     /**
947      * @tc.steps:step1. Start transaction.
948      * @tc.expected: step1. return OK.
949      */
950     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
951     /**
952      * @tc.steps:step2. Delete key1
953      * @tc.expected: step2. return OK.
954      */
955     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_1), OK);
956     /**
957      * @tc.steps:step3. Rollback.
958      * @tc.expected: step3. return OK.
959      */
960     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
961     /**
962      * @tc.steps:step4. GetEntries.
963      * @tc.expected: step4. return OK.
964      */
965     const Key prefix;
966     vector<Entry> entries;
967     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
968     EXPECT_EQ(entries.size(), 1UL);
969     if (entries.size() > 0) {
970         EXPECT_EQ(entries[0].key, KEY_1);
971         EXPECT_EQ(entries[0].value, VALUE_1);
972     }
973 
974     // finilize
975     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
976     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback006"), OK);
977     g_kvNbDelegatePtr = nullptr;
978 }
979 
980 /**
981   * @tc.name: rollback007
982   * @tc.desc: Test the DeleteBatch operation rollback
983   * @tc.type: FUNC
984   * @tc.require: AR000DPTQ9
985   * @tc.author: wumin
986   */
987 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback007, TestSize.Level1)
988 {
989     const KvStoreNbDelegate::Option option = {true, false};
990     g_mgr.GetKvStore("distributed_nb_transaction_rollback007", option, g_kvNbDelegateCallback);
991     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
992     EXPECT_TRUE(g_kvDelegateStatus == OK);
993 
994     vector<Entry> entries;
995     vector<Key> keys;
996     DistributedDBUnitTest::GenerateRecords(10, entries, keys);
997 
998     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entries), OK);
999     /**
1000      * @tc.steps:step1. Start transaction.
1001      * @tc.expected: step1. return OK.
1002      */
1003     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
1004     /**
1005      * @tc.steps:step2. DeleteBatch from key1 to key10
1006      * @tc.expected: step2. return OK.
1007      */
1008     EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys), OK);
1009     /**
1010      * @tc.steps:step3. Rollback.
1011      * @tc.expected: step3. return OK.
1012      */
1013     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
1014     /**
1015      * @tc.steps:step4. GetEntries.
1016      * @tc.expected: step4. return OK.
1017      */
1018     const Key prefix;
1019     vector<Entry> entriesRet;
1020     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entriesRet), OK);
1021     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(entries, entriesRet));
1022 
1023     // finilize
1024     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1025     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback007"), OK);
1026     g_kvNbDelegatePtr = nullptr;
1027 }
1028 
1029 /**
1030   * @tc.name: rollback008
1031   * @tc.desc: Test the multiple operations rollback
1032   * @tc.type: FUNC
1033   * @tc.require: AR000DPTQ9
1034   * @tc.author: wumin
1035   */
1036 HWTEST_F(DistributedDBInterfacesNBTransactionTest, rollback008, TestSize.Level1)
1037 {
1038     const KvStoreNbDelegate::Option option = {true, false};
1039     g_mgr.GetKvStore("distributed_nb_transaction_rollback008", option, g_kvNbDelegateCallback);
1040     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
1041     EXPECT_TRUE(g_kvDelegateStatus == OK);
1042     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_1), OK);
1043     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_2, VALUE_2), OK);
1044     /**
1045      * @tc.steps:step1. Start transaction.
1046      * @tc.expected: step1. return OK.
1047      */
1048     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
1049     /**
1050      * @tc.steps:step2. Put (key3,value3) (key1,value4)
1051      * @tc.expected: step2. return OK.
1052      */
1053     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_3, VALUE_3), OK);
1054     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY_1, VALUE_4), OK);
1055     /**
1056      * @tc.steps:step3. Delete key2
1057      * @tc.expected: step3. return OK.
1058      */
1059     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY_2), OK);
1060     /**
1061      * @tc.steps:step4. PutBatch 10 records (from key3 to key12)
1062      * @tc.expected: step4. return OK.
1063      */
1064     vector<Entry> entrysBase;
1065     vector<Key> keysBase;
1066     DistributedDBUnitTest::GenerateRecords(12, entrysBase, keysBase);
1067 
1068     vector<Entry> entrys1(entrysBase.begin() + 2, entrysBase.end());
1069     EXPECT_EQ(entrys1.size(), 10UL);
1070     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entrys1), OK);
1071     /**
1072      * @tc.steps:step5. DeleteBatch 5 records (from key3 to key7)
1073      * @tc.expected: step5. return OK.
1074      */
1075     vector<Key> keys(keysBase.begin() + 2, keysBase.begin() + 7);
1076     EXPECT_EQ(keys.size(), 5UL);
1077     EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys), OK);
1078     /**
1079      * @tc.steps:step6. Commit.
1080      * @tc.expected: step6. return OK.
1081      */
1082     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
1083     /**
1084      * @tc.steps:step7. GetEntries.
1085      * @tc.expected: step7. return OK.
1086      */
1087     const Key prefix;
1088     vector<Entry> entries;
1089     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(prefix, entries), OK);
1090     EXPECT_EQ(entries.size(), 2UL);
1091     if (entries.size() > 1) {
1092         EXPECT_EQ(entries[0].key, KEY_1);
1093         EXPECT_EQ(entries[0].value, VALUE_1);
1094         EXPECT_EQ(entries[1].key, KEY_2);
1095         EXPECT_EQ(entries[1].value, VALUE_2);
1096     }
1097 
1098     // finilize
1099     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
1100     EXPECT_EQ(g_mgr.DeleteKvStore("distributed_nb_transaction_rollback008"), OK);
1101     g_kvNbDelegatePtr = nullptr;
1102 }