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 #include <thread>
18 
19 #include "db_constant.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "log_print.h"
23 
24 using namespace testing::ext;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27 using namespace std;
28 
29 namespace {
30     string g_testDir;
31     KvStoreConfig g_config;
32     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
33     DBStatus g_kvDelegateStatus = INVALID_ARGS;
34     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
35 
36     const int OBSERVER_SLEEP_TIME = 100;
37     const int BATCH_PRESET_SIZE_TEST = 10;
38     const int DIVIDE_BATCH_PRESET_SIZE = 5;
39 
40     const Key KEY1{'k', 'e', 'y', '1'};
41     const Key KEY2{'k', 'e', 'y', '2'};
42     const Value VALUE1{'v', 'a', 'l', 'u', 'e', '1'};
43     const Value VALUE2{'v', 'a', 'l', 'u', 'e', '2'};
44 
45     // the type of g_kvNbDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
46     auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback, placeholders::_1,
47         placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
48 }
49 
50 class DistributedDBInterfacesTransactionOptimizationTest : public testing::Test {
51 public:
52     static void SetUpTestCase(void);
53     static void TearDownTestCase(void);
54     void SetUp();
55     void TearDown();
56 };
57 
SetUpTestCase(void)58 void DistributedDBInterfacesTransactionOptimizationTest::SetUpTestCase(void)
59 {
60     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
61     g_config.dataDir = g_testDir;
62     g_mgr.SetKvStoreConfig(g_config);
63 }
64 
TearDownTestCase(void)65 void DistributedDBInterfacesTransactionOptimizationTest::TearDownTestCase(void)
66 {
67     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
68         LOGE("rm test db files error!");
69     }
70 }
71 
SetUp(void)72 void DistributedDBInterfacesTransactionOptimizationTest::SetUp(void)
73 {
74     DistributedDBToolsUnitTest::PrintTestCaseInfo();
75     g_kvDelegateStatus = INVALID_ARGS;
76     g_kvNbDelegatePtr = nullptr;
77 }
78 
TearDown(void)79 void DistributedDBInterfacesTransactionOptimizationTest::TearDown(void)
80 {
81     if (g_kvNbDelegatePtr != nullptr) {
82         g_mgr.CloseKvStore(g_kvNbDelegatePtr);
83         g_kvNbDelegatePtr = nullptr;
84     }
85 }
86 
87 /**
88   * @tc.name: BatchOperationsOfSyncAndLocal001
89   * @tc.desc: Verify the batch put and query functions of the sync and local data in the same transaction.
90   * @tc.type: FUNC
91   * @tc.require: AR000EPAS8
92   * @tc.author: changguicai
93   */
94 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, SyncAndLocalBatchOperations001, TestSize.Level1)
95 {
96     /**
97      * @tc.steps:step1. Get the nb delegate.
98      * @tc.expected: step1. Get results OK and non-null delegate.
99      */
100     std::string storeId("SyncAndLocalBatchOperations001");
101     KvStoreNbDelegate::Option option = {true, false, false};
102     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
103     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
104     EXPECT_TRUE(g_kvDelegateStatus == OK);
105 
106     /**
107      * @tc.steps:step2. Starting a transaction.
108      * @tc.expected: step2. The transaction is started successfully.
109      */
110     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
111 
112     vector<Entry> entries;
113     vector<Key> keys;
114     DistributedDBUnitTest::GenerateRecords(BATCH_PRESET_SIZE_TEST, entries, keys);
115     EXPECT_TRUE(entries.size() == BATCH_PRESET_SIZE_TEST);
116 
117     vector<Entry> localEntrys;
118     vector<Key> localKeys;
119     DistributedDBUnitTest::GenerateRecords(DIVIDE_BATCH_PRESET_SIZE, localEntrys, localKeys);
120     EXPECT_TRUE(localEntrys.size() == DIVIDE_BATCH_PRESET_SIZE);
121 
122     /**
123      * @tc.steps:step3. Put batch data.
124      * @tc.expected: step3. Returns OK.
125      */
126     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entries), OK);
127     EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(localEntrys), OK);
128 
129     Key keyPrefix;
130     std::vector<Entry> getSyncEntries;
131     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(keyPrefix, getSyncEntries), OK);
132     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(entries, getSyncEntries, true));
133 
134     std::vector<Entry> getLocalEntries;
135     EXPECT_EQ(g_kvNbDelegatePtr->GetLocalEntries(keyPrefix, getLocalEntries), OK);
136     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(localEntrys, getLocalEntries, true));
137 
138     /**
139      * @tc.steps:step4. Commit a transaction.
140      * @tc.expected: step4. Transaction submitted successfully.
141      */
142     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
143 
144     /**
145      * @tc.steps:step5. GetEntries after the transaction is submitted.
146      * @tc.expected: step5. GetEntries return OK and the geted data is correct.
147      */
148     getSyncEntries.clear();
149     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(keyPrefix, getSyncEntries), OK);
150     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(entries, getSyncEntries, true));
151 
152     getLocalEntries.clear();
153     EXPECT_EQ(g_kvNbDelegatePtr->GetLocalEntries(keyPrefix, getLocalEntries), OK);
154     EXPECT_TRUE(DistributedDBToolsUnitTest::IsEntriesEqual(localEntrys, getLocalEntries, true));
155 
156     /**
157      * @tc.steps:step6. Close the kv store.
158      * @tc.expected: step6. Results OK and delete successfully.
159      */
160     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
161     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
162     g_kvNbDelegatePtr = nullptr;
163 }
164 
165 /**
166   * @tc.name: SyncAndLocalSingleOperations001
167   * @tc.desc: Verify the single put and query functions of the sync and local data in the same transaction.
168   * @tc.type: FUNC
169   * @tc.require: AR000EPAS8
170   * @tc.author: changguicai
171   */
172 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, SyncAndLocalSingleOperations001, TestSize.Level1)
173 {
174     /**
175      * @tc.steps:step1. Get the nb delegate.
176      * @tc.expected: step1. Get results OK and non-null delegate.
177      */
178     std::string storeId("SyncAndLocalSingleOperations001");
179     KvStoreNbDelegate::Option option = {true, false, false};
180     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
181     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
182     EXPECT_TRUE(g_kvDelegateStatus == OK);
183 
184     /**
185      * @tc.steps:step2. Starting a transaction.
186      * @tc.expected: step2. The transaction is started successfully.
187      */
188     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
189 
190     /**
191      * @tc.steps:step3. Put and Get single data.
192      * @tc.expected: step3. Returns OK.
193      */
194     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY1, VALUE1), OK);
195     EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(KEY2, VALUE2), OK);
196 
197     Value getSyncValue;
198     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY1, getSyncValue), OK);
199     EXPECT_TRUE(DistributedDBToolsUnitTest::IsValueEqual(VALUE1, getSyncValue));
200 
201     Value getLocalValue;
202     EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(KEY2, getLocalValue), OK);
203     EXPECT_TRUE(DistributedDBToolsUnitTest::IsValueEqual(VALUE2, getLocalValue));
204 
205     /**
206      * @tc.steps:step4. Commit a transaction.
207      * @tc.expected: step4. Transaction submitted successfully.
208      */
209     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
210 
211     /**
212      * @tc.steps:step5. Get after the transaction is submitted.
213      * @tc.expected: step5. Get return OK and the geted data is correct.
214      */
215     getSyncValue.clear();
216     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY1, getSyncValue), OK);
217     EXPECT_TRUE(DistributedDBToolsUnitTest::IsValueEqual(VALUE1, getSyncValue));
218 
219     getLocalValue.clear();
220     EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(KEY2, getLocalValue), OK);
221     EXPECT_TRUE(DistributedDBToolsUnitTest::IsValueEqual(VALUE2, getLocalValue));
222 
223     /**
224      * @tc.steps:step6. Close the kv store.
225      * @tc.expected: step6. Results OK and delete successfully.
226      */
227     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
228     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
229     g_kvNbDelegatePtr = nullptr;
230 }
231 
232 /**
233   * @tc.name: DeleteInTransaction001
234   * @tc.desc: Verify that the sync and local functions can be deleted in the same transaction.
235   * @tc.type: FUNC
236   * @tc.require: AR000EPAS8
237   * @tc.author: changguicai
238   */
239 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, DeleteInTransaction001, TestSize.Level1)
240 {
241     /**
242      * @tc.steps:step1. Get the nb delegate.
243      * @tc.expected: step1. Get results OK and non-null delegate.
244      */
245     std::string storeId("DeleteInTransaction001");
246     KvStoreNbDelegate::Option option = {true, false, false};
247     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
248     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
249     EXPECT_TRUE(g_kvDelegateStatus == OK);
250 
251     /**
252      * @tc.steps:step2. Starting a transaction.
253      * @tc.expected: step2. The transaction is started successfully.
254      */
255     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
256 
257     /**
258      * @tc.steps:step3. Put and Get single data.
259      * @tc.expected: step3. Returns OK.
260      */
261     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY1, VALUE1), OK);
262     EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(KEY2, VALUE2), OK);
263 
264     /**
265      * @tc.steps:step4 Delete before the transaction is submitted.
266      * @tc.expected: step4. Delete return OK.
267      */
268     EXPECT_EQ(g_kvNbDelegatePtr->Delete(KEY1), OK);
269     EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocal(KEY2), OK);
270 
271     /**
272      * @tc.steps:step5 Commit a transaction.
273      * @tc.expected: step5 Transaction submitted successfully.
274      */
275     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
276 
277     /**
278      * @tc.steps:step6 Get after the transaction is submitted.
279      * @tc.expected: step6 Get return NOT_FOUND and the geted data is correct.
280      */
281     Value getSyncValue;
282     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY1, getSyncValue), NOT_FOUND);
283     Value getLocalValue;
284     EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(KEY2, getLocalValue), NOT_FOUND);
285 
286     /**
287      * @tc.steps:step7 Close the kv store.
288      * @tc.expected: step7 Results OK and delete successfully.
289      */
290     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
291     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
292     g_kvNbDelegatePtr = nullptr;
293 }
294 
295 /**
296   * @tc.name: DeleteBatchInTransaction001
297   * @tc.desc: Local data does not check readOnly.
298   * @tc.type: FUNC
299   * @tc.require: AR000EPAS8
300   * @tc.author: changguicai
301   */
302 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, DeleteBatchInTransaction001, TestSize.Level1)
303 {
304     /**
305      * @tc.steps:step1. Get the nb delegate.
306      * @tc.expected: step1. Get results OK and non-null delegate.
307      */
308     std::string storeId("DeleteBatchInTransaction001");
309     KvStoreNbDelegate::Option option = {true, false, false};
310     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
311     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
312     EXPECT_TRUE(g_kvDelegateStatus == OK);
313 
314     /**
315      * @tc.steps:step2. Starting a Transaction.
316      * @tc.expected: step2. The transaction is started successfully.
317      */
318     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
319 
320     vector<Entry> entries;
321     vector<Key> keys;
322     DistributedDBUnitTest::GenerateRecords(BATCH_PRESET_SIZE_TEST, entries, keys);
323     EXPECT_TRUE(entries.size() == BATCH_PRESET_SIZE_TEST);
324 
325     vector<Entry> localEntrys;
326     vector<Key> localKeys;
327     DistributedDBUnitTest::GenerateRecords(DIVIDE_BATCH_PRESET_SIZE, localEntrys, localKeys);
328     EXPECT_TRUE(localEntrys.size() == DIVIDE_BATCH_PRESET_SIZE);
329 
330     /**
331      * @tc.steps:step3. Put batch data.
332      * @tc.expected: step3. Returns OK.
333      */
334     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(entries), OK);
335     EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(localEntrys), OK);
336 
337     /**
338      * @tc.steps:step4 DeleteBatch before the transaction is submitted.
339      * @tc.expected: step4. Delete return OK.
340      */
341     EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(keys), OK);
342     EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocalBatch(localKeys), OK);
343 
344     /**
345      * @tc.steps:step5 Commit a transaction.
346      * @tc.expected: step5 Transaction submitted successfully.
347      */
348     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
349 
350     /**
351      * @tc.steps:step6 GetEntries after the transaction is submitted.
352      * @tc.expected: step6 GetEntries return NOT_FOUND and the geted data is correct.
353      */
354     Key keyPrefix;
355     std::vector<Entry> getSyncEntries;
356     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(keyPrefix, getSyncEntries), NOT_FOUND);
357     std::vector<Entry> getLocalEntries;
358     EXPECT_EQ(g_kvNbDelegatePtr->GetLocalEntries(keyPrefix, getLocalEntries), NOT_FOUND);
359 
360     /**
361      * @tc.steps:step7 Close the kv store.
362      * @tc.expected: step7 Results OK and delete successfully.
363      */
364     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
365     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
366     g_kvNbDelegatePtr = nullptr;
367 }
368 
369 /**
370   * @tc.name: SyncAndLocalObserver001
371   * @tc.desc: Verify the observer functions of the sync and local data in the same transaction.
372   * @tc.type: FUNC
373   * @tc.require: AR000EPAS8
374   * @tc.author: changguicai
375   */
376 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, SyncAndLocalObserver001, TestSize.Level1)
377 {
378     /**
379      * @tc.steps:step1. Get the nb delegate.
380      * @tc.expected: step1. Get results OK and non-null delegate.
381      */
382     std::string storeId("SyncAndLocalObserver001");
383     KvStoreNbDelegate::Option option = {true, false, false};
384     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
385     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
386     EXPECT_TRUE(g_kvDelegateStatus == OK);
387 
388     KvStoreObserverUnitTest *syncObserver = new (std::nothrow) KvStoreObserverUnitTest;
389     ASSERT_TRUE(syncObserver != nullptr);
390     KvStoreObserverUnitTest *localObserver = new (std::nothrow) KvStoreObserverUnitTest;
391     ASSERT_TRUE(localObserver != nullptr);
392 
393     /**
394      * @tc.steps:step2. Register the non-null observer for the special key.
395      * @tc.expected: step2. Register results OK.
396      */
397     Key key;
398     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, syncObserver), OK);
399     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, localObserver), OK);
400 
401     /**
402      * @tc.steps:step3. Starting a Transaction.
403      * @tc.expected: step3. The transaction is started successfully.
404      */
405     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
406 
407     /**
408      * @tc.steps:step4. Put batch data.
409      * @tc.expected: step4. Returns OK.
410      */
411     vector<Key> syncKeys;
412     vector<Entry> syncEntries;
413     DistributedDBUnitTest::GenerateRecords(BATCH_PRESET_SIZE_TEST, syncEntries, syncKeys);
414     EXPECT_TRUE(syncEntries.size() == BATCH_PRESET_SIZE_TEST);
415     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(syncEntries), OK);
416 
417     vector<Key> localKeys;
418     vector<Entry> localEntries;
419     DistributedDBUnitTest::GenerateRecords(DIVIDE_BATCH_PRESET_SIZE, localEntries, localKeys);
420     EXPECT_TRUE(localEntries.size() == DIVIDE_BATCH_PRESET_SIZE);
421     EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(localEntries), OK);
422 
423     /**
424      * @tc.steps:step5. Commit a transaction.
425      * @tc.expected: step5. Transaction submitted successfully.
426      */
427     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
428 
429     /**
430      * @tc.steps:step6. Check changed data.
431      * @tc.expected: step6. The inserted data is the same as the written data.
432      */
433     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
434     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(syncEntries, syncObserver->GetEntriesInserted()));
435     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(localEntries, localObserver->GetEntriesInserted()));
436 
437     /**
438      * @tc.steps:step7. UnRegister the observer.
439      * @tc.expected: step7. Returns OK.
440      */
441     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(syncObserver), OK);
442     delete syncObserver;
443     syncObserver = nullptr;
444     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(localObserver), OK);
445     delete localObserver;
446     localObserver = nullptr;
447 
448     /**
449      * @tc.steps:step8. Close the kv store.
450      * @tc.expected: step8. Results OK and delete successfully.
451      */
452     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
453     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
454     g_kvNbDelegatePtr = nullptr;
455 }
456 
457 /**
458   * @tc.name: OnlyDeleteInTransaction001
459   * @tc.desc: Verify the observer functions of delete operation in the transaction.
460   * @tc.type: FUNC
461   * @tc.require: AR000EPAS8
462   * @tc.author: changguicai
463   */
464 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, OnlyDeleteInTransaction001, TestSize.Level1)
465 {
466     /**
467      * @tc.steps:step1. Get the nb delegate.
468      * @tc.expected: step1. Get results OK and non-null delegate.
469      */
470     std::string storeId("OnlyDeleteInTransaction001");
471     KvStoreNbDelegate::Option option = {true, false, false};
472     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
473     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
474     EXPECT_TRUE(g_kvDelegateStatus == OK);
475 
476     /**
477      * @tc.steps:step2. Put batch data.
478      * @tc.expected: step2. Returns OK.
479      */
480     vector<Key> syncKeys;
481     vector<Entry> syncEntries;
482     DistributedDBUnitTest::GenerateRecords(BATCH_PRESET_SIZE_TEST, syncEntries, syncKeys);
483     EXPECT_TRUE(syncEntries.size() == BATCH_PRESET_SIZE_TEST);
484     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(syncEntries), OK);
485 
486     vector<Key> localKeys;
487     vector<Entry> localEntries;
488     DistributedDBUnitTest::GenerateRecords(DIVIDE_BATCH_PRESET_SIZE, localEntries, localKeys);
489     EXPECT_TRUE(localEntries.size() == DIVIDE_BATCH_PRESET_SIZE);
490     EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(localEntries), OK);
491 
492     KvStoreObserverUnitTest *syncObserver = new (std::nothrow) KvStoreObserverUnitTest;
493     ASSERT_TRUE(syncObserver != nullptr);
494     KvStoreObserverUnitTest *localObserver = new (std::nothrow) KvStoreObserverUnitTest;
495     ASSERT_TRUE(localObserver != nullptr);
496 
497     /**
498      * @tc.steps:step3. Register the non-null observer for the special key.
499      * @tc.expected: step3. Register results OK.
500      */
501     Key key;
502     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, syncObserver), OK);
503     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, localObserver), OK);
504 
505     /**
506      * @tc.steps:step4. Starting a Transaction.
507      * @tc.expected: step4. The transaction is started successfully.
508      */
509     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
510 
511     /**
512      * @tc.steps:step5 DeleteBatch before the transaction is submitted.
513      * @tc.expected: step5. Delete return OK.
514      */
515     EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch(syncKeys), OK);
516     EXPECT_EQ(g_kvNbDelegatePtr->DeleteLocalBatch(localKeys), OK);
517 
518     /**
519      * @tc.steps:step6. Commit a transaction.
520      * @tc.expected: step6. Transaction submitted successfully.
521      */
522     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
523 
524     /**
525      * @tc.steps:step7. Check changed data.
526      * @tc.expected: step7. The inserted data is the same as the written data.
527      */
528     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
529     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(syncEntries, syncObserver->GetEntriesDeleted()));
530     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(localEntries, localObserver->GetEntriesDeleted()));
531 
532     /**
533      * @tc.steps:step8. UnRegister the observer.
534      * @tc.expected: step8. Returns OK.
535      */
536     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(syncObserver), OK);
537     delete syncObserver;
538     syncObserver = nullptr;
539     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(localObserver), OK);
540     delete localObserver;
541     localObserver = nullptr;
542 
543     /**
544      * @tc.steps:step9. Close the kv store.
545      * @tc.expected: step9. Results OK and delete successfully.
546      */
547     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
548     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
549     g_kvNbDelegatePtr = nullptr;
550 }
551 
552 /**
553   * @tc.name: SyncAndLocalObserver002
554   * @tc.desc: Verify the observer functions of the sync and local data in the same transaction.
555   * @tc.type: FUNC
556   * @tc.require: AR000EPAS8
557   * @tc.author: changguicai
558   */
559 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, SyncAndLocalObserver002, TestSize.Level1)
560 {
561     /**
562      * @tc.steps:step1. Get the nb delegate.
563      * @tc.expected: step1. Get results OK and non-null delegate.
564      */
565     std::string storeId("SyncAndLocalObserver002");
566     KvStoreNbDelegate::Option option = {true, false, false};
567     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
568     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
569     EXPECT_TRUE(g_kvDelegateStatus == OK);
570 
571     KvStoreObserverUnitTest *syncObserver = new (std::nothrow) KvStoreObserverUnitTest;
572     ASSERT_TRUE(syncObserver != nullptr);
573     KvStoreObserverUnitTest *localObserver = new (std::nothrow) KvStoreObserverUnitTest;
574     ASSERT_TRUE(localObserver != nullptr);
575     /**
576      * @tc.steps:step2. Register the non-null observer for the special key.
577      * @tc.expected: step2. Register results OK.
578      */
579     Key key;
580     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, syncObserver), OK);
581     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, localObserver), OK);
582 
583     /**
584      * @tc.steps:step3. Starting a Transaction.
585      * @tc.expected: step3. The transaction is started successfully.
586      */
587     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
588 
589     /**
590      * @tc.steps:step4. Put data.
591      * @tc.expected: step4. Returns OK.
592      */
593     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY1, VALUE1), OK);
594     EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(KEY2, VALUE2), OK);
595 
596     /**
597      * @tc.steps:step5. Commit a transaction.
598      * @tc.expected: step5. Transaction submitted successfully.
599      */
600     EXPECT_EQ(g_kvNbDelegatePtr->Commit(), OK);
601 
602     std::vector<DistributedDB::Entry> syncEntries;
603     Entry syncEntry{KEY1, VALUE1};
604     syncEntries.emplace_back(syncEntry);
605     std::vector<DistributedDB::Entry> localEntries;
606     Entry localEntry{KEY2, VALUE2};
607     localEntries.emplace_back(localEntry);
608 
609     /**
610      * @tc.steps:step6. Check changed data.
611      * @tc.expected: step6. The inserted data is the same as the written data.
612      */
613     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
614     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(syncEntries, syncObserver->GetEntriesInserted()));
615     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(localEntries, localObserver->GetEntriesInserted()));
616 
617     /**
618      * @tc.steps:step7. UnRegister the observer.
619      * @tc.expected: step7. Returns OK.
620      */
621     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(syncObserver), OK);
622     delete syncObserver;
623     syncObserver = nullptr;
624     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(localObserver), OK);
625     delete localObserver;
626     localObserver = nullptr;
627 
628     /**
629      * @tc.steps:step8. Close the kv store.
630      * @tc.expected: step8. Results OK and delete successfully.
631      */
632     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
633     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
634     g_kvNbDelegatePtr = nullptr;
635 }
636 
637 /**
638   * @tc.name: PutRollback001
639   * @tc.desc: Verify that a transaction can be rolled back after data is put.
640   * @tc.type: FUNC
641   * @tc.require: AR000EPAS8
642   * @tc.author: changguicai
643   */
644 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, PutRollback001, TestSize.Level1)
645 {
646     /**
647      * @tc.steps:step1. Get the nb delegate.
648      * @tc.expected: step1. Get results OK and non-null delegate.
649      */
650     std::string storeId("PutRollback001");
651     KvStoreNbDelegate::Option option = {true, false, false};
652     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
653     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
654     EXPECT_TRUE(g_kvDelegateStatus == OK);
655 
656     KvStoreObserverUnitTest *syncObserver = new (std::nothrow) KvStoreObserverUnitTest;
657     ASSERT_TRUE(syncObserver != nullptr);
658     KvStoreObserverUnitTest *localObserver = new (std::nothrow) KvStoreObserverUnitTest;
659     ASSERT_TRUE(localObserver != nullptr);
660     /**
661      * @tc.steps:step2. Register the non-null observer for the special key.
662      * @tc.expected: step2. Register results OK.
663      */
664     Key key;
665     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, syncObserver), OK);
666     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, localObserver), OK);
667 
668     /**
669      * @tc.steps:step3. Starting a Transaction.
670      * @tc.expected: step3. The transaction is started successfully.
671      */
672     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
673 
674     /**
675      * @tc.steps:step3. Put data.
676      * @tc.expected: step3. Returns OK.
677      */
678     EXPECT_EQ(g_kvNbDelegatePtr->Put(KEY1, VALUE1), OK);
679     EXPECT_EQ(g_kvNbDelegatePtr->PutLocal(KEY2, VALUE2), OK);
680 
681     /**
682      * @tc.steps:step3. Transaction rollback.
683      * @tc.expected: step3. Returns OK.
684      */
685     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
686 
687     /**
688      * @tc.steps:step4. After the rollback, query the database and observe the changed data.
689      * @tc.expected: step4. Get return NOT_FOUND. The changed data is empty.
690      */
691     Value value;
692     EXPECT_EQ(g_kvNbDelegatePtr->Get(KEY1, value), NOT_FOUND);
693     EXPECT_EQ(g_kvNbDelegatePtr->GetLocal(KEY2, value), NOT_FOUND);
694 
695     std::vector<DistributedDB::Entry> empty;
696     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
697     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(empty, syncObserver->GetEntriesInserted()));
698     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(empty, localObserver->GetEntriesInserted()));
699 
700     /**
701      * @tc.steps:step5. UnRegister the observer.
702      * @tc.expected: step5. Returns OK.
703      */
704     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(syncObserver), OK);
705     delete syncObserver;
706     syncObserver = nullptr;
707     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(localObserver), OK);
708     delete localObserver;
709     localObserver = nullptr;
710 
711     /**
712      * @tc.steps:step6. Close the kv store.
713      * @tc.expected: step6. Results OK and delete successfully.
714      */
715     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
716     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
717     g_kvNbDelegatePtr = nullptr;
718 }
719 
720 /**
721   * @tc.name: PutBatchRollback001
722   * @tc.desc: Verify that a transaction can be rolled back after data is put.
723   * @tc.type: FUNC
724   * @tc.require: AR000EPAS8
725   * @tc.author: changguicai
726   */
727 HWTEST_F(DistributedDBInterfacesTransactionOptimizationTest, PutBatchRollback001, TestSize.Level1)
728 {
729     /**
730      * @tc.steps:step1. Get the nb delegate.
731      * @tc.expected: step1. Get results OK and non-null delegate.
732      */
733     std::string storeId("OptimizeObserver008");
734     KvStoreNbDelegate::Option option = {true, false, false};
735     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
736     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
737     EXPECT_TRUE(g_kvDelegateStatus == OK);
738 
739     KvStoreObserverUnitTest *syncObserver = new (std::nothrow) KvStoreObserverUnitTest;
740     ASSERT_TRUE(syncObserver != nullptr);
741     KvStoreObserverUnitTest *localObserver = new (std::nothrow) KvStoreObserverUnitTest;
742     ASSERT_TRUE(localObserver != nullptr);
743     /**
744      * @tc.steps:step2. Register the non-null observer for the special key.
745      * @tc.expected: step2. Register results OK.
746      */
747     Key key;
748     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_NATIVE, syncObserver), OK);
749     EXPECT_EQ(g_kvNbDelegatePtr->RegisterObserver(key, OBSERVER_CHANGES_LOCAL_ONLY, localObserver), OK);
750 
751     /**
752      * @tc.steps:step3. Starting a Transaction.
753      * @tc.expected: step3. The transaction is started successfully.
754      */
755     EXPECT_EQ(g_kvNbDelegatePtr->StartTransaction(), OK);
756 
757     /**
758      * @tc.steps:step3. Put batch data.
759      * @tc.expected: step3. Returns OK.
760      */
761     std::vector<Key> syncKeys;
762     std::vector<Entry> syncEntries;
763     DistributedDBUnitTest::GenerateRecords(BATCH_PRESET_SIZE_TEST, syncEntries, syncKeys);
764     EXPECT_TRUE(syncEntries.size() == BATCH_PRESET_SIZE_TEST);
765     EXPECT_EQ(g_kvNbDelegatePtr->PutBatch(syncEntries), OK);
766 
767     std::vector<Key> localKeys;
768     std::vector<Entry> localEntries;
769     DistributedDBUnitTest::GenerateRecords(DIVIDE_BATCH_PRESET_SIZE, localEntries, localKeys);
770     EXPECT_TRUE(localEntries.size() == DIVIDE_BATCH_PRESET_SIZE);
771     EXPECT_EQ(g_kvNbDelegatePtr->PutLocalBatch(localEntries), OK);
772 
773     /**
774      * @tc.steps:step3. Transaction rollback.
775      * @tc.expected: step3. Returns OK.
776      */
777     EXPECT_EQ(g_kvNbDelegatePtr->Rollback(), OK);
778 
779     /**
780      * @tc.steps:step4. After the rollback, query the database and observe the changed data.
781      * @tc.expected: step4. Get return NOT_FOUND. The changed data is empty.
782      */
783     Key keyPrefix;
784     std::vector<Entry> entries;
785     EXPECT_EQ(g_kvNbDelegatePtr->GetEntries(keyPrefix, entries), NOT_FOUND);
786     EXPECT_EQ(g_kvNbDelegatePtr->GetLocalEntries(keyPrefix, entries), NOT_FOUND);
787 
788     std::this_thread::sleep_for(std::chrono::milliseconds(OBSERVER_SLEEP_TIME));
789     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(entries, syncObserver->GetEntriesInserted()));
790     EXPECT_TRUE(DistributedDBToolsUnitTest::CheckObserverResult(entries, localObserver->GetEntriesInserted()));
791 
792     /**
793      * @tc.steps:step5. UnRegister the observer.
794      * @tc.expected: step5. Returns OK.
795      */
796     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(syncObserver), OK);
797     delete syncObserver;
798     syncObserver = nullptr;
799     EXPECT_EQ(g_kvNbDelegatePtr->UnRegisterObserver(localObserver), OK);
800     delete localObserver;
801     localObserver = nullptr;
802 
803     /**
804      * @tc.steps:step6. Close the kv store.
805      * @tc.expected: step6. Results OK and delete successfully.
806      */
807     EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
808     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
809     g_kvNbDelegatePtr = nullptr;
810 }
811 
812