• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "cloud/cloud_db_constant.h"
19 #include "db_base64_utils.h"
20 #include "distributeddb_data_generate_unit_test.h"
21 #include "distributeddb_tools_unit_test.h"
22 #include "kv_virtual_device.h"
23 #include "kv_store_nb_delegate.h"
24 #include "kv_store_nb_delegate_impl.h"
25 #include "platform_specific.h"
26 #include "process_system_api_adapter_impl.h"
27 #include "virtual_communicator_aggregator.h"
28 #include "virtual_cloud_db.h"
29 #include "sqlite_utils.h"
30 #include "time_helper.h"
31 #include "sqlite_cloud_kv_store.h"
32 #include "kv_storage_handle.h"
33 
34 using namespace testing::ext;
35 using namespace DistributedDB;
36 using namespace DistributedDBUnitTest;
37 using namespace std;
38 
39 namespace {
40 static std::string HWM_HEAD = "naturalbase_cloud_meta_sync_data_";
41 string g_testDir;
42 KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
43 CloudSyncOption g_CloudSyncoption;
44 const std::string USER_ID_2 = "user2";
45 const std::string USER_ID_3 = "user3";
46 const Key KEY_1 = {'k', '1'};
47 const Key KEY_2 = {'k', '2'};
48 const Key KEY_3 = {'k', '3'};
49 const Value VALUE_1 = {'v', '1'};
50 const Value VALUE_2 = {'v', '2'};
51 const Value VALUE_3 = {'v', '3'};
52 class DistributedDBCloudKvStoreTest : public testing::Test {
53 public:
54     static void SetUpTestCase();
55     static void TearDownTestCase();
56     void SetUp();
57     void TearDown();
58     void InsertRecord(int num);
59     void SetDeviceId(const Key &key, const std::string &deviceId);
60     void SetFlag(const Key &key, LogInfoFlag flag);
61     int CheckFlag(const Key &key, LogInfoFlag flag);
62     int CheckLogTable(const std::string &deviceId);
63     int CheckWaterMark(const std::string &key);
64     int ChangeUserId(const std::string &deviceId, const std::string &wantUserId);
65     int ChangeHashKey(const std::string &deviceId);
66 protected:
67     DBStatus GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, KvStoreNbDelegate::Option option,
68         bool invalidSchema = false);
69     void CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId);
70     void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option,
71         DBStatus expectSyncResult = OK);
72     void SyncAndGetProcessInfo(KvStoreNbDelegate *delegate, CloudSyncOption option);
73     bool CheckUserSyncInfo(const vector<std::string> users, const vector<DBStatus> userStatus,
74         const vector<Info> userExpectInfo);
75     static DataBaseSchema GetDataBaseSchema(bool invalidSchema);
76     std::shared_ptr<VirtualCloudDb> virtualCloudDb_ = nullptr;
77     std::shared_ptr<VirtualCloudDb> virtualCloudDb2_ = nullptr;
78     KvStoreConfig config_;
79     KvStoreNbDelegate* kvDelegatePtrS1_ = nullptr;
80     KvStoreNbDelegate* kvDelegatePtrS2_ = nullptr;
81     SyncProcess lastProcess_;
82     std::map<std::string, SyncProcess> lastSyncProcess_;
83     VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
84     KvVirtualDevice *deviceB_ = nullptr;
85 };
86 
SetUpTestCase()87 void DistributedDBCloudKvStoreTest::SetUpTestCase()
88 {
89     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
90     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
91         LOGE("rm test db files error!");
92     }
93     RuntimeContext::GetInstance()->ClearAllDeviceTimeInfo();
94     g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
95     g_CloudSyncoption.users.push_back(USER_ID);
96     g_CloudSyncoption.devices.push_back("cloud");
97 
98     string dir = g_testDir + "/single_ver";
99     DIR* dirTmp = opendir(dir.c_str());
100     if (dirTmp == nullptr) {
101         OS::MakeDBDirectory(dir);
102     } else {
103         closedir(dirTmp);
104     }
105 }
106 
TearDownTestCase()107 void DistributedDBCloudKvStoreTest::TearDownTestCase()
108 {
109     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
110         LOGE("rm test db files error!");
111     }
112     g_CloudSyncoption.users.clear();
113     g_CloudSyncoption.devices.clear();
114 }
115 
SetUp()116 void DistributedDBCloudKvStoreTest::SetUp()
117 {
118     DistributedDBToolsUnitTest::PrintTestCaseInfo();
119     config_.dataDir = g_testDir;
120     /**
121      * @tc.setup: create virtual device B and C, and get a KvStoreNbDelegate as deviceA
122      */
123     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
124     virtualCloudDb2_ = std::make_shared<VirtualCloudDb>();
125     g_mgr.SetKvStoreConfig(config_);
126     KvStoreNbDelegate::Option option1;
127     ASSERT_EQ(GetKvStore(kvDelegatePtrS1_, STORE_ID_1, option1), OK);
128     // set aggregator after get store1, only store2 can sync with p2p
129     communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
130     ASSERT_TRUE(communicatorAggregator_ != nullptr);
131     RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
132     KvStoreNbDelegate::Option option2;
133     ASSERT_EQ(GetKvStore(kvDelegatePtrS2_, STORE_ID_2, option2), OK);
134 
135     deviceB_ = new (std::nothrow) KvVirtualDevice("DEVICE_B");
136     ASSERT_TRUE(deviceB_ != nullptr);
137     auto syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
138     ASSERT_TRUE(syncInterfaceB != nullptr);
139     ASSERT_EQ(deviceB_->Initialize(communicatorAggregator_, syncInterfaceB), E_OK);
140 }
141 
TearDown()142 void DistributedDBCloudKvStoreTest::TearDown()
143 {
144     CloseKvStore(kvDelegatePtrS1_, STORE_ID_1);
145     CloseKvStore(kvDelegatePtrS2_, STORE_ID_2);
146     virtualCloudDb_ = nullptr;
147     virtualCloudDb2_ = nullptr;
148     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
149         LOGE("rm test db files error!");
150     }
151 
152     if (deviceB_ != nullptr) {
153         delete deviceB_;
154         deviceB_ = nullptr;
155     }
156 
157     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
158     communicatorAggregator_ = nullptr;
159     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
160 }
161 
BlockSync(KvStoreNbDelegate * delegate,DBStatus expectDBStatus,CloudSyncOption option,DBStatus expectSyncResult)162 void DistributedDBCloudKvStoreTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus,
163     CloudSyncOption option, DBStatus expectSyncResult)
164 {
165     if (delegate == nullptr) {
166         return;
167     }
168     std::mutex dataMutex;
169     std::condition_variable cv;
170     bool finish = false;
171     SyncProcess last;
172     auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map<std::string,
173         SyncProcess> &process) {
174         size_t notifyCnt = 0;
175         for (const auto &item: process) {
176             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
177             if (item.second.process != DistributedDB::FINISHED) {
178                 continue;
179             }
180             EXPECT_EQ(item.second.errCode, expectDBStatus);
181             {
182                 std::lock_guard<std::mutex> autoLock(dataMutex);
183                 notifyCnt++;
184                 std::set<std::string> userSet(option.users.begin(), option.users.end());
185                 if (notifyCnt == userSet.size()) {
186                     finish = true;
187                     last = item.second;
188                     cv.notify_one();
189                 }
190             }
191         }
192     };
193     auto actualRet = delegate->Sync(option, callback);
194     EXPECT_EQ(actualRet, expectSyncResult);
195     if (actualRet == OK) {
196         std::unique_lock<std::mutex> uniqueLock(dataMutex);
197         cv.wait(uniqueLock, [&finish]() {
198             return finish;
199         });
200     }
201     lastProcess_ = last;
202 }
203 
GetDataBaseSchema(bool invalidSchema)204 DataBaseSchema DistributedDBCloudKvStoreTest::GetDataBaseSchema(bool invalidSchema)
205 {
206     DataBaseSchema schema;
207     TableSchema tableSchema;
208     tableSchema.name = invalidSchema ? "invalid_schema_name" : CloudDbConstant::CLOUD_KV_TABLE_NAME;
209     Field field;
210     field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY;
211     field.type = TYPE_INDEX<std::string>;
212     field.primary = true;
213     tableSchema.fields.push_back(field);
214     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE;
215     field.primary = false;
216     tableSchema.fields.push_back(field);
217     field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE;
218     tableSchema.fields.push_back(field);
219     field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE;
220     tableSchema.fields.push_back(field);
221     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME;
222     field.type = TYPE_INDEX<int64_t>;
223     tableSchema.fields.push_back(field);
224     schema.tables.push_back(tableSchema);
225     return schema;
226 }
227 
228 
GetKvStore(KvStoreNbDelegate * & delegate,const std::string & storeId,KvStoreNbDelegate::Option option,bool invalidSchema)229 DBStatus DistributedDBCloudKvStoreTest::GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId,
230     KvStoreNbDelegate::Option option, bool invalidSchema)
231 {
232     DBStatus openRet = OK;
233     g_mgr.GetKvStore(storeId, option, [&openRet, &delegate](DBStatus status, KvStoreNbDelegate *openDelegate) {
234         openRet = status;
235         delegate = openDelegate;
236     });
237     EXPECT_EQ(openRet, OK);
238     EXPECT_NE(delegate, nullptr);
239 
240     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
241     cloudDbs[USER_ID] = virtualCloudDb_;
242     cloudDbs[USER_ID_2] = virtualCloudDb2_;
243     delegate->SetCloudDB(cloudDbs);
244     std::map<std::string, DataBaseSchema> schemas;
245     schemas[USER_ID] = GetDataBaseSchema(invalidSchema);
246     schemas[USER_ID_2] = GetDataBaseSchema(invalidSchema);
247     return delegate->SetCloudDbSchema(schemas);
248 }
249 
CloseKvStore(KvStoreNbDelegate * & delegate,const std::string & storeId)250 void DistributedDBCloudKvStoreTest::CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId)
251 {
252     if (delegate != nullptr) {
253         ASSERT_EQ(g_mgr.CloseKvStore(delegate), OK);
254         delegate = nullptr;
255         DBStatus status = g_mgr.DeleteKvStore(storeId);
256         LOGD("delete kv store status %d store %s", status, storeId.c_str());
257         ASSERT_EQ(status, OK);
258     }
259 }
260 
SyncAndGetProcessInfo(KvStoreNbDelegate * delegate,CloudSyncOption option)261 void DistributedDBCloudKvStoreTest::SyncAndGetProcessInfo(KvStoreNbDelegate *delegate, CloudSyncOption option)
262 {
263     if (delegate == nullptr) {
264         return;
265     }
266     std::mutex dataMutex;
267     std::condition_variable cv;
268     bool isFinish = false;
269     vector<std::map<std::string, SyncProcess>> lists;
270     auto callback = [&cv, &dataMutex, &isFinish, &option, &lists](const std::map<std::string, SyncProcess> &process) {
271         size_t notifyCnt = 0;
272         for (const auto &item: process) {
273             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
274             if (item.second.process != DistributedDB::FINISHED) {
275                 continue;
276             }
277             {
278                 std::lock_guard<std::mutex> autoLock(dataMutex);
279                 notifyCnt++;
280                 std::set<std::string> userSet(option.users.begin(), option.users.end());
281                 if (notifyCnt == userSet.size()) {
282                     isFinish = true;
283                     cv.notify_one();
284                 }
285                 lists.push_back(process);
286             }
287         }
288     };
289     auto ret = delegate->Sync(option, callback);
290     EXPECT_EQ(ret, OK);
291     if (ret == OK) {
292         std::unique_lock<std::mutex> uniqueLock(dataMutex);
293         cv.wait(uniqueLock, [&isFinish]() {
294             return isFinish;
295         });
296     }
297     lastSyncProcess_ = lists.back();
298 }
299 
CheckUserSyncInfo(const vector<std::string> users,const vector<DBStatus> userStatus,const vector<Info> userExpectInfo)300 bool DistributedDBCloudKvStoreTest::CheckUserSyncInfo(const vector<std::string> users,
301     const vector<DBStatus> userStatus, const vector<Info> userExpectInfo)
302 {
303     uint32_t idx = 0;
304     for (auto &it: lastSyncProcess_) {
305         if ((idx >= users.size()) || (idx >= userStatus.size()) || (idx >= userExpectInfo.size())) {
306             return false;
307         }
308         string user = it.first;
309         if (user.compare(0, user.length(), users[idx]) != 0) {
310             return false;
311         }
312         SyncProcess actualSyncProcess = it.second;
313         EXPECT_EQ(actualSyncProcess.process, FINISHED);
314         EXPECT_EQ(actualSyncProcess.errCode, userStatus[idx]);
315         for (const auto &table : actualSyncProcess.tableProcess) {
316             EXPECT_EQ(table.second.upLoadInfo.total, userExpectInfo[idx].total);
317             EXPECT_EQ(table.second.upLoadInfo.successCount, userExpectInfo[idx].successCount);
318             EXPECT_EQ(table.second.upLoadInfo.insertCount, userExpectInfo[idx].insertCount);
319             EXPECT_EQ(table.second.upLoadInfo.failCount, userExpectInfo[idx].failCount);
320         }
321         idx++;
322     }
323     return true;
324 }
325 
326 /**
327  * @tc.name: SyncOptionCheck001
328  * @tc.desc: Test sync without user.
329  * @tc.type: FUNC
330  * @tc.require:
331  * @tc.author: liaoyonghuang
332  */
333 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck001, TestSize.Level0)
334 {
335     /**
336      * @tc.steps:step1. Device 1 inserts a piece of data.
337      * @tc.expected: step1 OK.
338      */
339     Key key = {'k'};
340     Value value = {'v'};
341     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
342     /**
343      * @tc.steps:step2. Set option without user, and attempt to sync
344      * @tc.expected: step2 return INVALID_ARGS.
345      */
346     CloudSyncOption option;
347     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
348     option.devices.push_back("cloud");
349     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
350     /**
351      * @tc.steps:step3. Device 2 sync and attempt to get data.
352      * @tc.expected: step3 sync OK but data NOT_FOUND.
353      */
354     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
355     Value actualValue;
356     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
357 }
358 
359 /**
360  * @tc.name: SyncOptionCheck002
361  * @tc.desc: Test sync with invalid waitTime.
362  * @tc.type: FUNC
363  * @tc.require:
364  * @tc.author: liaoyonghuang
365  */
366 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck002, TestSize.Level0)
367 {
368     /**
369      * @tc.steps:step1. Device 1 inserts a piece of data.
370      * @tc.expected: step1 OK.
371      */
372     Key key = {'k'};
373     Value value = {'v'};
374     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
375     /**
376      * @tc.steps:step2. Set invalid waitTime of sync option and sync.
377      * @tc.expected: step2 return INVALID_ARGS.
378      */
379     CloudSyncOption option;
380     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
381     option.users.push_back(USER_ID);
382     option.devices.push_back("cloud");
383     option.waitTime = -2; // -2 is invalid waitTime.
384     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
385     /**
386      * @tc.steps:step3. Device 2 sync and attempt to get data.
387      * @tc.expected: step3 sync OK but data NOT_FOUND.
388      */
389     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
390     Value actualValue;
391     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
392 }
393 
394 /**
395  * @tc.name: SyncOptionCheck003
396  * @tc.desc: Test sync with users which have not been sync to cloud.
397  * @tc.type: FUNC
398  * @tc.require:
399  * @tc.author: liaoyonghuang
400  */
401 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck003, TestSize.Level0)
402 {
403     /**
404      * @tc.steps:step1. Device 1 inserts a piece of data.
405      * @tc.expected: step1 OK.
406      */
407     Key key = {'k'};
408     Value value = {'v'};
409     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
410     /**
411      * @tc.steps:step2. Set user1 and user3 to option and sync.
412      * @tc.expected: step2 return INVALID_ARGS.
413      */
414     CloudSyncOption option;
415     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
416     option.users.push_back(USER_ID);
417     option.users.push_back(USER_ID_3);
418     option.devices.push_back("cloud");
419     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
420     /**
421      * @tc.steps:step3. Device 2 sync and attempt to get data.
422      * @tc.expected: step3 sync OK but data NOT_FOUND.
423      */
424     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
425     Value actualValue;
426     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
427 }
428 
429 /**
430  * @tc.name: SyncOptionCheck004
431  * @tc.desc: Test sync with user when schema is not same.
432  * @tc.type: FUNC
433  * @tc.require:
434  * @tc.author: caihaoting
435  */
436 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck004, TestSize.Level0)
437 {
438     /**
439      * @tc.steps:step1. Device 1 inserts a piece of data.
440      * @tc.expected: step1 OK.
441      */
442     Key key = {'k'};
443     Value value = {'v'};
444     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
445     /**
446      * @tc.steps:step2. Set user1 to option and user2 to schema and sync.
447      * @tc.expected: step2 return SCHEMA_MISMATCH.
448      */
449     CloudSyncOption option;
450     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
451     option.users.push_back(USER_ID);
452     option.devices.push_back("cloud");
453     std::map<std::string, DataBaseSchema> schemas;
454     schemas[USER_ID_2] = GetDataBaseSchema(false);
455     kvDelegatePtrS1_->SetCloudDbSchema(schemas);
456     BlockSync(kvDelegatePtrS1_, OK, option, SCHEMA_MISMATCH);
457 }
458 
459 /**
460  * @tc.name: SyncOptionCheck005
461  * @tc.desc: Testing registration of observer exceeded the upper limit.
462  * @tc.type: FUNC
463  * @tc.require:
464  * @tc.author: liaoyonghuang
465  */
466 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck005, TestSize.Level0)
467 {
468     /**
469      * @tc.steps:step1. Register MAX_OBSERVER_COUNT observers.
470      * @tc.expected: step1 OK.
471      */
472     std::vector<KvStoreObserverUnitTest *> observerList;
473     for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) {
474         auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
475         observerList.push_back(observer);
476         EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, observer), OK);
477     }
478     /**
479      * @tc.steps:step2. Register one more observer.
480      * @tc.expected: step2 Registration failed, return OVER_MAX_LIMITS.
481      */
482     auto *overMaxObserver = new (std::nothrow) KvStoreObserverUnitTest;
483     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, overMaxObserver), OVER_MAX_LIMITS);
484     /**
485      * @tc.steps:step3. UnRegister all observers.
486      * @tc.expected: step3 OK.
487      */
488     EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(overMaxObserver), NOT_FOUND);
489     delete overMaxObserver;
490     overMaxObserver = nullptr;
491     for (auto &observer : observerList) {
492         EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(observer), OK);
493         delete observer;
494         observer = nullptr;
495     }
496 }
497 
498 /**
499  * @tc.name: SyncOptionCheck006
500  * @tc.desc: Test sync with schema db
501  * @tc.type: FUNC
502  * @tc.require:
503  * @tc.author: zhangqiquan
504  */
505 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck006, TestSize.Level0)
506 {
507     KvStoreNbDelegate::Option option;
508     option.schema = "{\"SCHEMA_VERSION\":\"1.0\","
509         "\"SCHEMA_MODE\":\"STRICT\","
510         "\"SCHEMA_DEFINE\":{"
511         "\"field_name1\":\"BOOL\","
512         "\"field_name2\":\"INTEGER, NOT NULL\""
513         "},"
514         "\"SCHEMA_INDEXES\":[\"$.field_name1\", \"$.field_name2\"]}";
515     KvStoreNbDelegate *kvDelegatePtr = nullptr;
516     ASSERT_EQ(GetKvStore(kvDelegatePtr, STORE_ID_4, option), OK);
517     ASSERT_NE(kvDelegatePtr, nullptr);
518     BlockSync(kvDelegatePtr, NOT_SUPPORT, g_CloudSyncoption, NOT_SUPPORT);
519     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegatePtr), OK);
520 }
521 
522 /**
523  * @tc.name: SyncOptionCheck007
524  * @tc.desc: Test sync with repetitive user.
525  * @tc.type: FUNC
526  * @tc.require:
527  * @tc.author: liaoyonghuang
528  */
529 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck007, TestSize.Level0)
530 {
531     /**
532      * @tc.steps:step1. Device 1 inserts a piece of data.
533      * @tc.expected: step1 OK.
534      */
535     Key key = {'k'};
536     Value value = {'v'};
537     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
538     /**
539      * @tc.steps:step2. Set user1 2 times to option sync.
540      * @tc.expected: step2 return OK.
541      */
542     CloudSyncOption option;
543     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
544     option.users.push_back(USER_ID);
545     option.users.push_back(USER_ID);
546     option.devices.push_back("cloud");
547     BlockSync(kvDelegatePtrS1_, OK, option, OK);
548 }
549 
550 /**
551  * @tc.name: SyncOptionCheck008
552  * @tc.desc: Test kc sync with query .
553  * @tc.type: FUNC
554  * @tc.require:
555  * @tc.author: luoguo
556  */
557 HWTEST_F(DistributedDBCloudKvStoreTest, SyncOptionCheck008, TestSize.Level0)
558 {
559     /**
560      * @tc.steps:step1. Device 1 inserts a piece of data.
561      * @tc.expected: step1 OK.
562      */
563     Key key = {'k'};
564     Value value = {'v'};
565     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
566     /**
567      * @tc.steps:step2. Set query to option sync.
568      * @tc.expected: step2 return OK.
569      */
570     std::set<Key> keys;
571     CloudSyncOption option;
572     option.query = Query::Select().InKeys(keys);
573     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
574     option.users.push_back(USER_ID);
575     option.users.push_back(USER_ID);
576     option.devices.push_back("cloud");
577     BlockSync(kvDelegatePtrS1_, OK, option, OK);
578 }
579 
SetFlag(const Key & key,LogInfoFlag flag)580 void DistributedDBCloudKvStoreTest::SetFlag(const Key &key, LogInfoFlag flag)
581 {
582     sqlite3 *db_;
583     uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
584     std::string fileUrl = g_testDir + "/" \
585         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
586     ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr) == SQLITE_OK);
587     int errCode = E_OK;
588     std::string sql = "UPDATE sync_data SET flag=? WHERE Key=?";
589     sqlite3_stmt *statement = nullptr;
590     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
591     if (errCode != E_OK) {
592         SQLiteUtils::ResetStatement(statement, true, errCode);
593     }
594     ASSERT_EQ(errCode, E_OK);
595     errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, static_cast<int64_t>(flag)); // 1st arg.
596     ASSERT_EQ(errCode, E_OK);
597     errCode = SQLiteUtils::BindBlobToStatement(statement, 2, key, true); // 2nd arg.
598     ASSERT_EQ(errCode, E_OK);
599     if (errCode != E_OK) {
600         SQLiteUtils::ResetStatement(statement, true, errCode);
601     }
602     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
603     SQLiteUtils::ResetStatement(statement, true, errCode);
604     EXPECT_EQ(errCode, E_OK);
605     sqlite3_close_v2(db_);
606 }
607 
CheckFlag(const Key & key,LogInfoFlag flag)608 int DistributedDBCloudKvStoreTest::CheckFlag(const Key &key, LogInfoFlag flag)
609 {
610     sqlite3 *db_;
611     uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
612     std::string fileUrl = g_testDir + "/" \
613         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
614     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr);
615     if (errCode != E_OK) {
616         return NOT_FOUND;
617     }
618     std::string sql = "SELECT * FROM sync_data WHERE Key =? AND (flag=?)";
619     sqlite3_stmt *statement = nullptr;
620     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
621     if (errCode != E_OK) {
622         SQLiteUtils::ResetStatement(statement, true, errCode);
623         return NOT_FOUND;
624     }
625     std::vector<uint8_t> keyVec(key.begin(), key.end());
626     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // 1st arg.
627     if (errCode != E_OK) {
628         SQLiteUtils::ResetStatement(statement, true, errCode);
629         return NOT_FOUND;
630     }
631     errCode = SQLiteUtils::BindInt64ToStatement(statement, 2, static_cast<int64_t>(flag)); // 2nd arg.
632     if (errCode != E_OK) {
633         SQLiteUtils::ResetStatement(statement, true, errCode);
634         return NOT_FOUND;
635     }
636     errCode = SQLiteUtils::StepWithRetry(statement);
637     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
638         SQLiteUtils::ResetStatement(statement, true, errCode);
639         sqlite3_close_v2(db_);
640         return NOT_FOUND; // cant find.
641     }
642     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
643         SQLiteUtils::ResetStatement(statement, true, errCode);
644         sqlite3_close_v2(db_);
645         return OK;
646     }
647     SQLiteUtils::ResetStatement(statement, true, errCode);
648     EXPECT_EQ(errCode, E_OK);
649     sqlite3_close_v2(db_);
650     return NOT_FOUND;
651 }
652 
CheckWaterMark(const std::string & user)653 int DistributedDBCloudKvStoreTest::CheckWaterMark(const std::string &user)
654 {
655     sqlite3 *db_;
656     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
657     std::string fileUrl = g_testDir + "/" \
658         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
659     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
660     if (errCode != E_OK) {
661         return NOT_FOUND;
662     }
663     std::string sql;
664     if (user.empty()) {
665         sql = "SELECT * FROM meta_data WHERE KEY LIKE 'naturalbase_cloud_meta_sync_data_%'";
666     } else {
667         sql = "SELECT * FROM meta_data WHERE KEY =?;";
668     }
669     sqlite3_stmt *statement = nullptr;
670     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
671     if (errCode != E_OK) {
672         SQLiteUtils::ResetStatement(statement, true, errCode);
673         return NOT_FOUND;
674     }
675     if (!user.empty()) {
676         std::string waterMarkKey = HWM_HEAD + user;
677         std::vector<uint8_t> keyVec(waterMarkKey.begin(), waterMarkKey.end());
678         errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // only one arg.
679         if (errCode != E_OK) {
680             SQLiteUtils::ResetStatement(statement, true, errCode);
681             return NOT_FOUND;
682         }
683     }
684     errCode = SQLiteUtils::StepWithRetry(statement);
685     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
686         SQLiteUtils::ResetStatement(statement, true, errCode);
687         sqlite3_close_v2(db_);
688         return NOT_FOUND; // cant find.
689     }
690     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
691         SQLiteUtils::ResetStatement(statement, true, errCode);
692         sqlite3_close_v2(db_);
693         return OK;
694     }
695     SQLiteUtils::ResetStatement(statement, true, errCode);
696     EXPECT_EQ(errCode, E_OK);
697     sqlite3_close_v2(db_);
698     return NOT_FOUND;
699 }
700 
SetDeviceId(const Key & key,const std::string & deviceId)701 void DistributedDBCloudKvStoreTest::SetDeviceId(const Key &key, const std::string &deviceId)
702 {
703     sqlite3 *db_;
704     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
705     std::string fileUrl = g_testDir + "/" \
706         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
707     ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr) == SQLITE_OK);
708     int errCode = E_OK;
709     std::string sql = "UPDATE sync_data SET device=? WHERE Key=?";
710     sqlite3_stmt *statement = nullptr;
711     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
712     if (errCode != E_OK) {
713         SQLiteUtils::ResetStatement(statement, true, errCode);
714     }
715     ASSERT_EQ(errCode, E_OK);
716     std::string hashDevice = DBCommon::TransferHashString(deviceId);
717     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
718     int bindIndex = 1;
719     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, deviceIdVec, true); // only one arg.
720     ASSERT_EQ(errCode, E_OK);
721     if (errCode != E_OK) {
722         SQLiteUtils::ResetStatement(statement, true, errCode);
723     }
724     bindIndex++;
725     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, key, true); // only one arg.
726     if (errCode != E_OK) {
727         SQLiteUtils::ResetStatement(statement, true, errCode);
728     }
729     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
730     SQLiteUtils::ResetStatement(statement, true, errCode);
731     EXPECT_EQ(errCode, E_OK);
732     sqlite3_close_v2(db_);
733 }
734 
CheckLogTable(const std::string & deviceId)735 int DistributedDBCloudKvStoreTest::CheckLogTable(const std::string &deviceId)
736 {
737     sqlite3 *db_;
738     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
739     std::string fileUrl = g_testDir + "/" \
740         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
741     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
742     if (errCode != E_OK) {
743         return NOT_FOUND;
744     }
745     std::string sql = "SELECT * FROM naturalbase_kv_aux_sync_data_log WHERE hash_key IN" \
746         "(SELECT hash_key FROM sync_data WHERE device =?);";
747     sqlite3_stmt *statement = nullptr;
748     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
749     if (errCode != E_OK) {
750         SQLiteUtils::ResetStatement(statement, true, errCode);
751         return NOT_FOUND;
752     }
753     std::string hashDevice = DBCommon::TransferHashString(deviceId);
754     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
755     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, deviceIdVec, true); // only one arg.
756     if (errCode != E_OK) {
757         SQLiteUtils::ResetStatement(statement, true, errCode);
758         return NOT_FOUND;
759     }
760     errCode = SQLiteUtils::StepWithRetry(statement);
761     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
762         SQLiteUtils::ResetStatement(statement, true, errCode);
763         sqlite3_close_v2(db_);
764         return NOT_FOUND; // cant find.
765     }
766     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
767         SQLiteUtils::ResetStatement(statement, true, errCode);
768         sqlite3_close_v2(db_);
769         return OK;
770     }
771     SQLiteUtils::ResetStatement(statement, true, errCode);
772     EXPECT_EQ(errCode, E_OK);
773     sqlite3_close_v2(db_);
774     return NOT_FOUND;
775 }
776 
ChangeUserId(const std::string & deviceId,const std::string & wantUserId)777 int DistributedDBCloudKvStoreTest::ChangeUserId(const std::string &deviceId, const std::string &wantUserId)
778 {
779     sqlite3 *db_;
780     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
781     std::string fileUrl = g_testDir + "/" \
782         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
783     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
784     if (errCode != E_OK) {
785         return INVALID_ARGS;
786     }
787     std::string sql = "UPDATE naturalbase_kv_aux_sync_data_log SET userid =? WHERE hash_key IN" \
788         "(SELECT hash_key FROM sync_data WHERE device =? AND (flag=0x100));";
789     sqlite3_stmt *statement = nullptr;
790     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
791     if (errCode != E_OK) {
792         SQLiteUtils::ResetStatement(statement, true, errCode);
793         return INVALID_ARGS;
794     }
795     int bindIndex = 1;
796     errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, wantUserId); // only one arg.
797     if (errCode != E_OK) {
798         SQLiteUtils::ResetStatement(statement, true, errCode);
799         return INVALID_ARGS;
800     }
801     bindIndex++;
802     std::string hashDevice = DBCommon::TransferHashString(deviceId);
803     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
804     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, deviceIdVec, true); // only one arg.
805     if (errCode != E_OK) {
806         SQLiteUtils::ResetStatement(statement, true, errCode);
807         return INVALID_ARGS;
808     }
809     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
810     SQLiteUtils::ResetStatement(statement, true, errCode);
811     EXPECT_EQ(errCode, E_OK);
812     sqlite3_close_v2(db_);
813     return INVALID_ARGS;
814 }
815 
ChangeHashKey(const std::string & deviceId)816 int DistributedDBCloudKvStoreTest::ChangeHashKey(const std::string &deviceId)
817 {
818     sqlite3 *db_;
819     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
820     std::string fileUrl = g_testDir + "/" \
821         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
822     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
823     if (errCode != E_OK) {
824         return INVALID_ARGS;
825     }
826     std::string updataLogTableSql = "UPDATE naturalbase_kv_aux_sync_data_log SET hash_Key ='99';";
827     sqlite3_stmt *statement = nullptr;
828     errCode = SQLiteUtils::GetStatement(db_, updataLogTableSql, statement);
829     if (errCode != E_OK) {
830         SQLiteUtils::ResetStatement(statement, true, errCode);
831         return INVALID_ARGS;
832     }
833     errCode = SQLiteUtils::StepWithRetry(statement);
834     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
835         SQLiteUtils::ResetStatement(statement, true, errCode);
836     }
837 
838     std::string sql = "UPDATE sync_data SET hash_Key ='99' WHERE device =? AND (flag=0x100);";
839     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
840     if (errCode != E_OK) {
841         SQLiteUtils::ResetStatement(statement, true, errCode);
842         return INVALID_ARGS;
843     }
844     std::string hashDevice = DBCommon::TransferHashString(deviceId);
845     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
846     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, deviceIdVec, true); // only one arg.
847     if (errCode != E_OK) {
848         SQLiteUtils::ResetStatement(statement, true, errCode);
849         sqlite3_close_v2(db_);
850         return OK; // cant find.
851     }
852     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
853     SQLiteUtils::ResetStatement(statement, true, errCode);
854     EXPECT_EQ(errCode, E_OK);
855     sqlite3_close_v2(db_);
856     return INVALID_ARGS;
857 }
858 
InsertRecord(int num)859 void DistributedDBCloudKvStoreTest::InsertRecord(int num)
860 {
861     for (int i = 0; i < num; i++) {
862         Key key;
863         key.push_back('k');
864         key.push_back('0' + i);
865         Value value;
866         value.push_back('k');
867         value.push_back('0' + i);
868         ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
869         BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
870         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
871         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
872     }
873 }
874 
875 /**
876  * @tc.name: RemoveDeviceTest001
877  * @tc.desc: remove all log table record with empty deviceId and FLAG_ONLY flag
878  * @tc.type: FUNC
879  * @tc.require:
880  * @tc.author: mazhao
881  */
882 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest001, TestSize.Level0)
883 {
884     /**
885      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
886      * (Key:k2, device:2, userId:0)
887      * * @tc.expected: step1. insert successfully
888     */
889     int recordNum = 3;
890     InsertRecord(recordNum);
891     for (int i = 0; i < recordNum; i++) {
892         Key key;
893         key.push_back('k');
894         key.push_back('0' + i);
895         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
896         SetDeviceId(key, std::to_string(i));
897         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
898     }
899     /**
900      * @tc.steps: step2. Check three Log record whether exist or not;
901      * * @tc.expected: step2. record exist
902     */
903     for (int i = 0; i < recordNum; i++) {
904         Key key;
905         key.push_back('k');
906         key.push_back('0' + i);
907         Value actualValue;
908         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
909         std::string deviceId = std::to_string(i);
910         EXPECT_EQ(CheckLogTable(deviceId), OK);
911         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
912         EXPECT_EQ(CheckWaterMark(""), OK);
913     }
914     /**
915      * @tc.steps: step3. remove log data with empty deviceId.
916      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
917     */
918     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_ONLY), OK);
919     for (int i = 0; i < recordNum; i++) {
920         Key key;
921         key.push_back('k');
922         key.push_back('0' + i);
923         Value actualValue;
924         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
925         std::string deviceId = std::to_string(i);
926         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
927         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_LOCAL), OK);
928         EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
929     }
930 }
931 
932 /**
933  * @tc.name: RemoveDeviceTest002
934  * @tc.desc: remove all record with empty deviceId and FLAG_AND_DATA flag
935  * @tc.type: FUNC
936  * @tc.require:
937  * @tc.author: mazhao
938  */
939 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest002, TestSize.Level0)
940 {
941     /**
942      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
943      * (Key:k2, device:2, userId:0)
944      * * @tc.expected: step1. insert successfully
945     */
946     int recordNum = 3;
947     InsertRecord(recordNum);
948     for (int i = 0; i < recordNum; i++) {
949         Key key;
950         key.push_back('k');
951         key.push_back('0' + i);
952         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
953         SetDeviceId(key, std::to_string(i));
954         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
955     }
956     /**
957      * @tc.steps: step2. Check three Log record whether exist or not;
958      * * @tc.expected: step2. record exist
959     */
960     for (int i = 0; i < recordNum; i++) {
961         Key key;
962         key.push_back('k');
963         key.push_back('0' + i);
964         Value actualValue;
965         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
966         std::string deviceId = std::to_string(i);
967         EXPECT_EQ(CheckLogTable(deviceId), OK);
968         EXPECT_EQ(CheckWaterMark(""), OK);
969     }
970     /**
971      * @tc.steps: step3. remove log data with empty deviceId.
972      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
973     */
974     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK);
975     for (int i = 0; i < recordNum; i++) {
976         Key key;
977         key.push_back('k');
978         key.push_back('0' + i);
979         Value actualValue;
980         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), NOT_FOUND);
981         std::string deviceId = std::to_string(i);
982         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
983         EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
984     }
985 }
986 
987 /**
988  * @tc.name: RemoveDeviceTest003
989  * @tc.desc: remove record with deviceId
990  * @tc.type: FUNC
991  * @tc.require:
992  * @tc.author: mazhao
993  */
994 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest003, TestSize.Level0)
995 {
996     /**
997      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
998      * (Key:k2, device:2, userId:0)
999      * * @tc.expected: step1. insert successfully
1000     */
1001     int recordNum = 3;
1002     InsertRecord(recordNum);
1003     for (int i = 0; i < recordNum; i++) {
1004         Key key;
1005         key.push_back('k');
1006         key.push_back('0' + i);
1007         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
1008         SetDeviceId(key, std::to_string(i));
1009         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1010     }
1011     /**
1012      * @tc.steps: step2. Check three Log record whether exist or not;
1013      * * @tc.expected: step2. record exist
1014     */
1015     for (int i = 0; i < recordNum; i++) {
1016         Key key;
1017         key.push_back('k');
1018         key.push_back('0' + i);
1019         Value actualValue;
1020         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1021         std::string deviceId = std::to_string(i);
1022         EXPECT_EQ(CheckLogTable(deviceId), OK);
1023         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag become 0x2;
1024         EXPECT_EQ(CheckWaterMark(""), OK);
1025     }
1026     /**
1027      * @tc.steps: step3. remove "2" deviceId log data with FLAG_AND_DATA, remove "1" with FLAG_ONLY.
1028      * * @tc.expected: step3. remove OK
1029     */
1030     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("1", ClearMode::FLAG_ONLY), OK);
1031     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("2", ClearMode::FLAG_AND_DATA), OK);
1032     Key key1({'k', '1'});
1033     std::string deviceId1 = "1";
1034     Value actualValue;
1035     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
1036     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
1037     EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
1038     Key key2({'k', '2'});
1039     std::string deviceId2 = "2";
1040     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
1041     EXPECT_EQ(CheckLogTable(deviceId2), NOT_FOUND);
1042     EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
1043 }
1044 
1045 /**
1046  * @tc.name: RemoveDeviceTest004
1047  * @tc.desc: remove all record with userId and empty deviceId.
1048  * @tc.type: FUNC
1049  * @tc.require:
1050  * @tc.author: mazhao
1051  */
1052 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest004, TestSize.Level0)
1053 {
1054     /**
1055      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
1056      * (Key:k2, device:2, userId:2)
1057      * * @tc.expected: step1. insert successfully
1058     */
1059     int recordNum = 3;
1060     std::string userHead = "user";
1061     InsertRecord(recordNum);
1062     for (int i = 0; i < recordNum; i++) {
1063         Key key;
1064         key.push_back('k');
1065         key.push_back('0' + i);
1066         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
1067         SetDeviceId(key, std::to_string(i));
1068         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
1069         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1070         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
1071     }
1072     EXPECT_EQ(CheckWaterMark(userHead + "0"), OK);
1073     /**
1074      * @tc.steps: step2. Check three Log record whether exist or not;
1075      * * @tc.expected: step2. record exist
1076     */
1077     for (int i = 0; i < recordNum; i++) {
1078         Key key;
1079         key.push_back('k');
1080         key.push_back('0' + i);
1081         Value actualValue;
1082         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1083         std::string deviceId = std::to_string(i);
1084         EXPECT_EQ(CheckLogTable(deviceId), OK);
1085     }
1086     /**
1087      * @tc.steps: step3. remove "user1" userid log data with FLAG_AND_DATA, remove "user2" userid with FLAG_ONLY.
1088      * * @tc.expected: step3. remove OK
1089     */
1090     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "user0", ClearMode::FLAG_ONLY), OK);
1091     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "user2", ClearMode::FLAG_AND_DATA), OK);
1092     Key key0({'k', '0'});
1093     std::string deviceId1 = "0";
1094     Value actualValue;
1095     EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK);
1096     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
1097     EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
1098     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
1099     Key key2({'k', '2'});
1100     std::string deviceId2 = "2";
1101     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
1102     EXPECT_EQ(CheckLogTable(deviceId2), NOT_FOUND);
1103 }
1104 
1105 /**
1106  * @tc.name: RemoveDeviceTest005
1107  * @tc.desc: remove record with userId and deviceId.
1108  * @tc.type: FUNC
1109  * @tc.require:
1110  * @tc.author: mazhao
1111  */
1112 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest005, TestSize.Level0)
1113 {
1114     /**
1115      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
1116      * (Key:k2, device:2, userId:2)
1117      * * @tc.expected: step1. insert successfully
1118     */
1119     int recordNum = 3;
1120     InsertRecord(recordNum);
1121     std::string userHead = "user";
1122     for (int i = 0; i < recordNum; i++) {
1123         Key key;
1124         key.push_back('k');
1125         key.push_back('0' + i);
1126         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
1127         SetDeviceId(key, std::to_string(i));
1128         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
1129         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1130     }
1131     EXPECT_EQ(CheckWaterMark(userHead + "0"), OK);
1132     /**
1133      * @tc.steps: step2. Check three Log record whether exist or not;
1134      * * @tc.expected: step2. record exist
1135     */
1136     for (int i = 0; i < recordNum; i++) {
1137         Key key;
1138         key.push_back('k');
1139         key.push_back('0' + i);
1140         Value actualValue;
1141         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1142         std::string deviceId = std::to_string(i);
1143         EXPECT_EQ(CheckLogTable(deviceId), OK);
1144         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
1145     }
1146     /**
1147      * @tc.steps: step3. remove "user1" userid log data with FLAG_AND_DATA, remove "user0" userid with FLAG_ONLY.
1148      * remove "user2" userid log data with dismatch deviceId, it cant not remove the data.
1149      * * @tc.expected: step3. remove OK
1150     */
1151     std::string deviceId0 = "0";
1152     std::string deviceId1 = "1";
1153     std::string deviceId2 = "2";
1154     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user0", ClearMode::FLAG_ONLY), OK);
1155     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user1", ClearMode::FLAG_AND_DATA), OK);
1156     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user2", ClearMode::FLAG_AND_DATA), OK);
1157     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user2", ClearMode::FLAG_ONLY), OK);
1158     Key key0({'k', '0'});
1159     Value actualValue;
1160     EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK);
1161     EXPECT_EQ(CheckLogTable(deviceId0), NOT_FOUND);
1162     EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
1163     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
1164     Key key1({'k', '1'});
1165     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND);
1166     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
1167     Key key2({'k', '2'});;
1168     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), OK);
1169     EXPECT_EQ(CheckLogTable(deviceId2), OK);
1170 }
1171 
1172 /**
1173  * @tc.name: RemoveDeviceTest006
1174  * @tc.desc: remove record with userId and deviceId, and there are same hashKey record in log table.
1175  * @tc.type: FUNC
1176  * @tc.require:
1177  * @tc.author: mazhao
1178  */
1179 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest006, TestSize.Level0)
1180 {
1181     /**
1182      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
1183      * (Key:k2, device:2, userId:2)
1184      * * @tc.expected: step1. insert successfully
1185     */
1186     int recordNum = 3;
1187     InsertRecord(recordNum);
1188     std::string userHead = "user";
1189     for (int i = 0; i < recordNum; i++) {
1190         Key key;
1191         key.push_back('k');
1192         key.push_back('0' + i);
1193         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
1194         SetDeviceId(key, std::to_string(i));
1195         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
1196         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1197     }
1198     /**
1199      * @tc.steps: step2. Check three Log record whether exist or not;
1200      * * @tc.expected: step2. record exist
1201     */
1202     for (int i = 0; i < recordNum; i++) {
1203         Key key;
1204         key.push_back('k');
1205         key.push_back('0' + i);
1206         Value actualValue;
1207         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1208         std::string deviceId = std::to_string(i);
1209         EXPECT_EQ(CheckLogTable(deviceId), OK);
1210     }
1211     /**
1212      * @tc.steps: step3. Make log table all users's hashKey become same hashKey '99', and the hashKey in syncTable
1213      *  where device is deviceId1 also become '99',remove data with FLAG_AND_DATA flag.
1214      * * @tc.expected: step3. remove OK
1215     */
1216     std::string deviceId1 = "1";
1217     std::string deviceId2 = "2";
1218     std::string deviceId0 = "0";
1219     DistributedDBCloudKvStoreTest::ChangeHashKey(deviceId1);
1220     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user1", ClearMode::FLAG_AND_DATA), OK);
1221     Key key1({'k', '1'});
1222     Value actualValue;
1223     // there are other users with same hash_key connect with this data in sync_data table, cant not remove the data.
1224     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
1225     EXPECT_EQ(CheckLogTable(deviceId1), OK); // match user2 and user0;
1226     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user2", ClearMode::FLAG_AND_DATA), OK);
1227     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
1228     EXPECT_EQ(CheckLogTable(deviceId1), OK); // only user0 match the hash_key that same as device1.
1229     EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag still 0x100;
1230     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user0", ClearMode::FLAG_AND_DATA), OK);
1231     // all log have been deleted, so data would also be deleted.
1232     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND);
1233     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
1234     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
1235 }
1236 
1237 /**
1238  * @tc.name: RemoveDeviceTest007
1239  * @tc.desc: remove record with invalid deviceId and mode.
1240  * @tc.type: FUNC
1241  * @tc.require:
1242  * @tc.author: mazhao
1243  */
1244 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest007, TestSize.Level0)
1245 {
1246     /**
1247      * @tc.steps: step1. Test removeDeviceData with invalid length deviceId.
1248      * * @tc.expected:
1249     */
1250     std::string deviceId = std::string(128, 'a');
1251     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, ClearMode::FLAG_AND_DATA), OK);
1252     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "user1", ClearMode::FLAG_AND_DATA), OK);
1253 
1254     std::string invaliDeviceId = std::string(129, 'a');
1255     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(invaliDeviceId, ClearMode::FLAG_AND_DATA), INVALID_ARGS);
1256     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(invaliDeviceId, "user1", ClearMode::FLAG_AND_DATA), INVALID_ARGS);
1257 
1258     /**
1259      * @tc.steps: step2. Test removeDeviceData with invalid mode.
1260      * * @tc.expected:
1261     */
1262     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT);
1263     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "user1", ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT);
1264 }
1265 
1266 /**
1267  * @tc.name: RemoveDeviceTest008
1268  * @tc.desc: remove record without mode.
1269  * @tc.type: FUNC
1270  * @tc.require:
1271  * @tc.author: liaoyonghuang
1272  */
1273 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest008, TestSize.Level0)
1274 {
1275     /**
1276      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
1277      * (Key:k2, device:2, userId:2)
1278      * * @tc.expected: step1. insert successfully
1279     */
1280     int recordNum = 3;
1281     InsertRecord(recordNum);
1282     for (int i = 0; i < recordNum; i++) {
1283         Key key;
1284         key.push_back('k');
1285         key.push_back('0' + i);
1286         SetFlag(key, LogInfoFlag::FLAG_CLOUD);
1287         SetDeviceId(key, std::to_string(i));
1288         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1289     }
1290 
1291     /**
1292      * @tc.steps: step2. Check three Log record whether exist or not;
1293      * * @tc.expected: step2. record exist
1294     */
1295     for (int i = 0; i < recordNum; i++) {
1296         Key key;
1297         key.push_back('k');
1298         key.push_back('0' + i);
1299         Value actualValue;
1300         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1301     }
1302     /**
1303      * @tc.steps: step3. Remove data without mode.
1304      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
1305     */
1306     for (int i = 0; i < recordNum; i++) {
1307         EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i)), OK);
1308     }
1309     for (int i = 0; i < recordNum; i++) {
1310         Key key;
1311         key.push_back('k');
1312         key.push_back('0' + i);
1313         Value actualValue;
1314         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), NOT_FOUND);
1315     }
1316 }
1317 
1318 /**
1319  * @tc.name: RemoveDeviceTest009
1320  * @tc.desc: remove record without mode FLAG_AND_DATA.
1321  * @tc.type: FUNC
1322  * @tc.require:
1323  * @tc.author: liaoyonghuang
1324  */
1325 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest009, TestSize.Level0)
1326 {
1327     /**
1328      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
1329      * (Key:k2, device:2, userId:2)
1330      * * @tc.expected: step1. insert successfully
1331     */
1332     int recordNum = 3;
1333     InsertRecord(recordNum);
1334     for (int i = 0; i < recordNum; i++) {
1335         Key key;
1336         key.push_back('k');
1337         key.push_back('0' + i);
1338         SetFlag(key, LogInfoFlag::FLAG_CLOUD);
1339         SetDeviceId(key, std::to_string(i));
1340         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1341     }
1342 
1343     /**
1344      * @tc.steps: step2. Check three Log record whether exist or not;
1345      * * @tc.expected: step2. record exist
1346     */
1347     for (int i = 0; i < recordNum; i++) {
1348         Key key;
1349         key.push_back('k');
1350         key.push_back('0' + i);
1351         Value actualValue;
1352         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1353         std::string deviceId = std::to_string(i);
1354         EXPECT_EQ(CheckLogTable(deviceId), OK);
1355     }
1356     /**
1357      * @tc.steps: step3. Remove data without mode FLAG_AND_DATA.
1358      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
1359     */
1360     for (int i = 0; i < recordNum; i++) {
1361         EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i), ClearMode::FLAG_AND_DATA), OK);
1362     }
1363     for (int i = 0; i < recordNum; i++) {
1364         Key key;
1365         key.push_back('k');
1366         key.push_back('0' + i);
1367         Value actualValue;
1368         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1369         std::string deviceId = std::to_string(i);
1370         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
1371     }
1372 }
1373 
1374 /**
1375  * @tc.name: RemoveDeviceTest010
1376  * @tc.desc: remove record with invalid mode.
1377  * @tc.type: FUNC
1378  * @tc.require:
1379  * @tc.author: zhangqiquan
1380  */
1381 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest010, TestSize.Level0)
1382 {
1383     std::string deviceId = std::string(128, 'a');
1384     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_ONLY), INVALID_ARGS);
1385     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::CLEAR_SHARED_TABLE), INVALID_ARGS);
1386     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_AND_DATA), INVALID_ARGS);
1387     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::DEFAULT), OK);
1388     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "", ClearMode::DEFAULT), OK);
1389     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::DEFAULT), OK);
1390 }
1391 
1392 /**
1393  * @tc.name: RemoveDeviceTest011
1394  * @tc.desc: remove record while conn is nullptr.
1395  * @tc.type: FUNC
1396  * @tc.require:
1397  * @tc.author: caihaoting
1398  */
1399 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest011, TestSize.Level0)
1400 {
1401     const KvStoreNbDelegate::Option option = {true, true};
1402     KvStoreNbDelegate *kvDelegateInvalidPtrS1_ = nullptr;
1403     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS1_, "RemoveDeviceTest011", option), OK);
1404     ASSERT_NE(kvDelegateInvalidPtrS1_, nullptr);
1405     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS1_);
1406     EXPECT_EQ(kvStoreImpl->Close(), OK);
1407     EXPECT_EQ(kvDelegateInvalidPtrS1_->RemoveDeviceData("", ClearMode::FLAG_ONLY), DB_ERROR);
1408     EXPECT_EQ(kvDelegateInvalidPtrS1_->RemoveDeviceData("", "", ClearMode::FLAG_ONLY), DB_ERROR);
1409     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS1_), OK);
1410 }
1411 
1412 /**
1413  * @tc.name: RemoveDeviceTest012
1414  * @tc.desc: Test remove all data from other device.
1415  * @tc.type: FUNC
1416  * @tc.require:
1417  * @tc.author: liaoyonghuang
1418  */
1419 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest012, TestSize.Level0)
1420 {
1421     /**
1422      * @tc.steps: step1. Insert three record, k0 from device sync, k1 from local write, k2 from cloud sync.
1423      * * @tc.expected: step1. insert successfully
1424     */
1425     int recordNum = 3;
1426     InsertRecord(recordNum);
1427     SetFlag({'k', '0'}, LogInfoFlag::FLAG_CLOUD);
1428     SetFlag({'k', '1'}, LogInfoFlag::FLAG_LOCAL);
1429     /**
1430      * @tc.steps: step2. Remove data from device sync and cloud sync, and remove log.
1431      * * @tc.expected: step2. All data and log are removed except data from local write.
1432     */
1433     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(), OK);
1434     Value actualValue;
1435     Value expectValue = {'k', '1'};
1436     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '1'}, actualValue), OK);
1437     EXPECT_EQ(actualValue, expectValue);
1438     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '0'}, actualValue), NOT_FOUND);
1439     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '2'}, actualValue), NOT_FOUND);
1440 }
1441 
1442 /**
1443  * @tc.name: RemoveDeviceTest013
1444  * @tc.desc: remove log record with FLAG_ONLY and empty deviceId.
1445  * @tc.type: FUNC
1446  * @tc.require:
1447  * @tc.author: wangxiangdong
1448  */
1449 HWTEST_F(DistributedDBCloudKvStoreTest, RemoveDeviceTest013, TestSize.Level0)
1450 {
1451     /**
1452      * @tc.steps: step1. Insert data
1453      * * @tc.expected: step1. insert successfully
1454     */
1455     Key k1 = {'k', '1'};
1456     Value v1 = {'v', '1'};
1457     deviceB_->PutData(k1, v1, TimeHelper::GetSysCurrentTime() + TimeHelper::BASE_OFFSET, 0);
1458     /**
1459      * @tc.steps: step2. sync between devices
1460      * * @tc.expected: step2. insert successfully
1461     */
1462     deviceB_->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true);
1463     Value actualValue;
1464     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK);
1465     EXPECT_EQ(actualValue, v1);
1466     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
1467     /**
1468      * @tc.steps: step3. sync with cloud
1469      * * @tc.expected: step3. OK
1470     */
1471     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1472     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1473     Value actualValue2;
1474     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue2), OK);
1475     EXPECT_EQ(actualValue2, v1);
1476     EXPECT_EQ(kvDelegatePtrS2_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK);
1477     Value actualValue3;
1478     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue3), NOT_FOUND);
1479     /**
1480      * @tc.steps: step4. sync between devices and check result
1481      * * @tc.expected: step4. OK
1482     */
1483     deviceB_->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true);
1484     Value actualValue4;
1485     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue4), OK);
1486     EXPECT_EQ(actualValue4, v1);
1487 }
1488 
1489 /**
1490  * @tc.name: NormalSyncInvalid001
1491  * @tc.desc: Test normal push not sync and get cloud version.
1492  * @tc.type: FUNC
1493  * @tc.require:
1494  * @tc.author: caihaoting
1495  */
1496 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid001, TestSize.Level0)
1497 {
1498     Key key = {'k'};
1499     Value expectValue = {'v'};
1500     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anonec23d47b0702(const std::string &origin) 1501     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
1502         LOGW("origin is %s", origin.c_str());
1503         return origin + "1";
1504     });
1505     Value actualValue;
1506     EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
1507     EXPECT_EQ(actualValue, expectValue);
1508     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
1509     auto result = kvDelegatePtrS1_->GetCloudVersion("");
1510     EXPECT_EQ(result.first, NOT_FOUND);
1511 }
1512 
1513 /**
1514  * @tc.name: NormalSyncInvalid002
1515  * @tc.desc: Test normal push sync and use invalidDevice to get cloud version.
1516  * @tc.type: FUNC
1517  * @tc.require:
1518  * @tc.author: caihaoting
1519  */
1520 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid002, TestSize.Level0)
1521 {
1522     Key key = {'k'};
1523     Value expectValue = {'v'};
1524     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anonec23d47b0802(const std::string &origin) 1525     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
1526         LOGW("origin is %s", origin.c_str());
1527         return origin + "1";
1528     });
1529     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1530     for (const auto &table : lastProcess_.tableProcess) {
1531         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
1532         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
1533     }
1534     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1535     for (const auto &table : lastProcess_.tableProcess) {
1536         EXPECT_EQ(table.second.downLoadInfo.total, 2u); // download 2 records
1537         EXPECT_EQ(table.second.downLoadInfo.insertCount, 2u); // download 2 records
1538     }
1539     Value actualValue;
1540     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
1541     EXPECT_EQ(actualValue, expectValue);
1542     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
1543     std::string invalidDevice = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0');
1544     auto result = kvDelegatePtrS2_->GetCloudVersion(invalidDevice);
1545     EXPECT_EQ(result.first, INVALID_ARGS);
1546 }
1547 
1548 /**
1549  * @tc.name: NormalSyncInvalid003
1550  * @tc.desc: Test normal push sync for add data while conn is nullptr.
1551  * @tc.type: FUNC
1552  * @tc.require:
1553  * @tc.author: caihaoting
1554  */
1555 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid003, TestSize.Level0)
1556 {
1557     const KvStoreNbDelegate::Option option = {true, true};
1558     KvStoreNbDelegate *kvDelegateInvalidPtrS1_ = nullptr;
1559     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS1_, "NormalSyncInvalid003", option), OK);
1560     ASSERT_NE(kvDelegateInvalidPtrS1_, nullptr);
1561     Key key = {'k'};
1562     Value expectValue = {'v'};
1563     ASSERT_EQ(kvDelegateInvalidPtrS1_->Put(key, expectValue), OK);
__anonec23d47b0902(const std::string &origin) 1564     kvDelegateInvalidPtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
1565         LOGW("origin is %s", origin.c_str());
1566         return origin + "1";
1567     });
1568     BlockSync(kvDelegateInvalidPtrS1_, OK, g_CloudSyncoption);
1569     for (const auto &table : lastProcess_.tableProcess) {
1570         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
1571         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
1572     }
1573     Value actualValue;
1574     EXPECT_EQ(kvDelegateInvalidPtrS1_->Get(key, actualValue), OK);
1575     EXPECT_EQ(actualValue, expectValue);
1576     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS1_);
1577     EXPECT_EQ(kvStoreImpl->Close(), OK);
1578     kvDelegateInvalidPtrS1_->SetGenCloudVersionCallback(nullptr);
1579     auto result = kvDelegateInvalidPtrS1_->GetCloudVersion("");
1580     EXPECT_EQ(result.first, DB_ERROR);
1581     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS1_), OK);
1582 }
1583 
1584 /**
1585  * @tc.name: NormalSyncInvalid004
1586  * @tc.desc: Test normal push sync use GetDeviceEntries while conn is nullptr.
1587  * @tc.type: FUNC
1588  * @tc.require:
1589  * @tc.author: caihaoting
1590  */
1591 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid004, TestSize.Level0)
1592 {
1593     const KvStoreNbDelegate::Option option = {true, true};
1594     KvStoreNbDelegate *kvDelegateInvalidPtrS2_ = nullptr;
1595     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS2_, "NormalSyncInvalid004", option), OK);
1596     ASSERT_NE(kvDelegateInvalidPtrS2_, nullptr);
1597     /**
1598      * @tc.steps: step1. store1 put (k1,v1) store2 put (k2,v2)
1599      * @tc.expected: step1. both put ok
1600      */
1601     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
__anonec23d47b0a02(const std::string &origin) 1602     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
1603         LOGW("origin is %s", origin.c_str());
1604         return origin + "1";
1605     });
__anonec23d47b0b02(const std::string &origin) 1606     kvDelegateInvalidPtrS2_->SetGenCloudVersionCallback([](const std::string &origin) {
1607         LOGW("origin is %s", origin.c_str());
1608         return origin + "1";
1609     });
1610     Key key1 = {'k', '1'};
1611     Value expectValue1 = {'v', '1'};
1612     Key key2 = {'k', '2'};
1613     Value expectValue2 = {'v', '2'};
1614     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
1615     ASSERT_EQ(kvDelegateInvalidPtrS2_->Put(key2, expectValue2), OK);
1616     /**
1617      * @tc.steps: step2. both store1 and store2 sync while conn is nullptr
1618      * @tc.expected: step2. both sync ok, and store2 got (k1,v1) store1 not exist (k2,v2)
1619      */
1620     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1621     LOGW("Store1 sync end");
1622     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
1623     BlockSync(kvDelegateInvalidPtrS2_, OK, g_CloudSyncoption);
1624     LOGW("Store2 sync end");
1625     Value actualValue;
1626     EXPECT_EQ(kvDelegateInvalidPtrS2_->Get(key1, actualValue), OK);
1627 
1628     /**
1629      * @tc.steps: step3. use GetDeviceEntries while conn is nullptr
1630      * @tc.expected: step3. DB_ERROR
1631      */
1632     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS2_);
1633     EXPECT_EQ(kvStoreImpl->Close(), OK);
1634     std::vector<Entry> entries;
1635     EXPECT_EQ(kvDelegateInvalidPtrS2_->GetDeviceEntries(std::string("DEVICES_A"), entries), DB_ERROR);
1636     EXPECT_EQ(entries.size(), 0u); // 1 record
1637     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
1638     EXPECT_EQ(actualValue, expectValue1);
1639     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
1640 
1641     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
1642     kvDelegateInvalidPtrS2_->SetGenCloudVersionCallback(nullptr);
1643     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS2_), OK);
1644 }
1645 
1646 /**
1647  * @tc.name: NormalSyncInvalid005
1648  * @tc.desc: Test normal sync with invalid parm.
1649  * @tc.type: FUNC
1650  * @tc.require:
1651  * @tc.author: caihaoting
1652  */
1653 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid005, TestSize.Level0)
1654 {
1655     Key key = {'k'};
1656     Value expectValue = {'v'};
1657     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
1658     auto devices = g_CloudSyncoption.devices;
1659     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, nullptr), NOT_SUPPORT);
1660     Query query = Query::Select().Range({}, {});
1661     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, nullptr, query, true), NOT_SUPPORT);
1662     auto mode = g_CloudSyncoption.mode;
1663     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr, query, true), NOT_SUPPORT);
1664     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
1665     EXPECT_EQ(kvStoreImpl->Close(), OK);
1666     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption, DB_ERROR);
1667     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr), DB_ERROR);
1668     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr, query, true), DB_ERROR);
1669 }
1670 
1671 /**
1672  * @tc.name: NormalSyncInvalid006
1673  * @tc.desc: Test normal sync set cloudDB while cloudDB is empty and conn is nullptr.
1674  * @tc.type: FUNC
1675  * @tc.require:
1676  * @tc.author: caihaoting
1677  */
1678 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid006, TestSize.Level0)
1679 {
1680     /**
1681      * @tc.steps: step1. set cloudDB while cloudDB is empty
1682      * @tc.expected: step1. INVALID_ARGS
1683      */
1684     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
1685     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDB(cloudDbs), INVALID_ARGS);
1686     /**
1687      * @tc.steps: step2. set cloudDB while conn is nullptr
1688      * @tc.expected: step2. DB_ERROR
1689      */
1690     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
1691     EXPECT_EQ(kvStoreImpl->Close(), OK);
1692     cloudDbs[USER_ID] = virtualCloudDb_;
1693     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDB(cloudDbs), DB_ERROR);
1694 }
1695 
1696 /**
1697  * @tc.name: NormalSyncInvalid007
1698  * @tc.desc: Test normal sync set cloudDb schema while conn is nullptr.
1699  * @tc.type: FUNC
1700  * @tc.require:
1701  * @tc.author: caihaoting
1702  */
1703 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid007, TestSize.Level0)
1704 {
1705     /**
1706      * @tc.steps: step1. set cloudDB schema while conn is nullptr
1707      * @tc.expected: step1. DB_ERROR
1708      */
1709     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
1710     EXPECT_EQ(kvStoreImpl->Close(), OK);
1711     std::map<std::string, DataBaseSchema> schemas;
1712     schemas[USER_ID] = GetDataBaseSchema(true);
1713     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDbSchema(schemas), DB_ERROR);
1714 }
1715 
1716 /**
1717  * @tc.name: NormalSyncInvalid008
1718  * @tc.desc: Test SetCloudSyncConfig with invalid parm.
1719  * @tc.type: FUNC
1720  * @tc.require:
1721  * @tc.author: caihaoting
1722  */
1723 HWTEST_F(DistributedDBCloudKvStoreTest, NormalSyncInvalid008, TestSize.Level0)
1724 {
1725     /**
1726      * @tc.steps: step1. SetCloudSyncConfig with invalid maxUploadCount.
1727      * @tc.expected: step1. INVALID_ARGS
1728      */
1729     CloudSyncConfig config;
1730     int maxUploadCount = 0;
1731     config.maxUploadCount = maxUploadCount;
1732     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
1733     maxUploadCount = 2001;
1734     config.maxUploadCount = maxUploadCount;
1735     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
1736     maxUploadCount = 50;
1737     config.maxUploadCount = maxUploadCount;
1738     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
1739 
1740     /**
1741      * @tc.steps: step2. SetCloudSyncConfig with invalid maxUploadSize.
1742      * @tc.expected: step2. INVALID_ARGS
1743      */
1744     int maxUploadSize = 1023;
1745     config.maxUploadSize = maxUploadSize;
1746     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
1747     maxUploadSize = 128 * 1024 * 1024 + 1;
1748     config.maxUploadSize = maxUploadSize;
1749     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
1750     maxUploadSize = 10240;
1751     config.maxUploadSize = maxUploadSize;
1752     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
1753 
1754     /**
1755      * @tc.steps: step3. SetCloudSyncConfig with invalid maxRetryConflictTimes.
1756      * @tc.expected: step3. INVALID_ARGS
1757      */
1758     int maxRetryConflictTimes = -2;
1759     config.maxRetryConflictTimes = maxRetryConflictTimes;
1760     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
1761     maxRetryConflictTimes = 2;
1762     config.maxRetryConflictTimes = maxRetryConflictTimes;
1763     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
1764 
1765     /**
1766      * @tc.steps: step4. SetCloudSyncConfig while conn is nullptr
1767      * @tc.expected: step4. DB_ERROR
1768      */
1769     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
1770     EXPECT_EQ(kvStoreImpl->Close(), OK);
1771     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), DB_ERROR);
1772 }
1773 
1774 /**
1775  * @tc.name: ConflictSync001
1776  * @tc.desc: test upload delete with version conflict error under merge mode, then success after retry.
1777  * @tc.type: FUNC
1778  * @tc.require:
1779  * @tc.author: suyuchen
1780  */
1781 HWTEST_F(DistributedDBCloudKvStoreTest, ConflictSync001, TestSize.Level0)
1782 {
1783     /**
1784      * @tc.steps: step1. Set the retry count to 2
1785      * @tc.expected: step1. ok.
1786      */
1787     CloudSyncConfig config;
1788     config.maxRetryConflictTimes = 2;
1789     kvDelegatePtrS1_->SetCloudSyncConfig(config);
1790     /**
1791      * @tc.steps: step2. Put 2 records and set flag to cloud
1792      * @tc.expected: step2. ok.
1793      */
1794     InsertRecord(2);
1795     SetFlag({'k', '0'}, LogInfoFlag::FLAG_CLOUD);
1796     SetFlag({'k', '1'}, LogInfoFlag::FLAG_CLOUD);
1797     /**
1798      * @tc.steps: step3. delete {k1, v1}
1799      * @tc.expected: step3. ok.
1800      */
1801     kvDelegatePtrS1_->Delete(KEY_1);
1802     /**
1803      * @tc.steps: step4. Set CLOUD_VERSION_CONFLICT when upload, and do sync
1804      * @tc.expected: step4. OK.
1805      */
1806     int recordIndex = 0;
1807     virtualCloudDb_->ForkInsertConflict([&recordIndex](const std::string &tableName, VBucket &extend, VBucket &record,
__anonec23d47b0c02(const std::string &tableName, VBucket &extend, VBucket &record, vector<VirtualCloudDb::CloudData> &cloudDataVec) 1808         vector<VirtualCloudDb::CloudData> &cloudDataVec) {
1809         recordIndex++;
1810         if (recordIndex == 1) { // set 1st record return CLOUD_VERSION_CONFLICT
1811             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_VERSION_CONFLICT);
1812             return CLOUD_VERSION_CONFLICT;
1813         }
1814         return OK;
1815     });
1816     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1817     /**
1818      * @tc.steps: step5. Check last process
1819      * @tc.expected: step5. ok.
1820      */
1821     for (const auto &table : lastProcess_.tableProcess) {
1822         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
1823         EXPECT_EQ(table.second.upLoadInfo.successCount, 1u);
1824         EXPECT_EQ(table.second.upLoadInfo.failCount, 0u);
1825         EXPECT_EQ(table.second.upLoadInfo.deleteCount, 1u);
1826     }
1827     virtualCloudDb_->ForkInsertConflict(nullptr);
1828 }
1829 
1830 /**
1831  * @tc.name: ObserverDataChangeTest001
1832  * @tc.desc: test RegisterObserver interface with OBSERVER_CHANGES_CLOUD mode.
1833  * @tc.type: FUNC
1834  * @tc.require:
1835  * @tc.author: suyue
1836  */
1837 HWTEST_F(DistributedDBCloudKvStoreTest, ObserverDataChangeTest001, TestSize.Level0)
1838 {
1839     /**
1840      * @tc.steps: step1. delegate1 insert two data and sync with cloud
1841      * @tc.expected: step1. insert and sync ok
1842     */
1843     Key k1 = {'k', '1'};
1844     Value v1 = {'v', '1'};
1845     Key k2 = {'k', '2'};
1846     Value v2 = {'v', '2'};
1847     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
1848     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK);
1849     Value actualValue;
1850     EXPECT_EQ(kvDelegatePtrS1_->Get(k1, actualValue), OK);
1851     EXPECT_EQ(actualValue, v1);
1852     EXPECT_EQ(kvDelegatePtrS1_->Get(k2, actualValue), OK);
1853     EXPECT_EQ(actualValue, v2);
1854     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1855 
1856     /**
1857      * @tc.steps: step2. delegate2 call RegisterObserver with OBSERVER_CHANGES_CLOUD mode
1858      * @tc.expected: step2. sync with cloud and check data change success
1859     */
1860     auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
1861     EXPECT_EQ(kvDelegatePtrS2_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, observer), OK);
1862     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1863     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK);
1864     EXPECT_EQ(actualValue, v1);
1865     EXPECT_EQ(kvDelegatePtrS2_->Get(k2, actualValue), OK);
1866     EXPECT_EQ(actualValue, v2);
1867     EXPECT_EQ(static_cast<int>(observer->GetCallCount()), 1);
1868     auto changeData = observer->GetChangedData();
1869     ASSERT_EQ(changeData.size(), 1u);
1870     EXPECT_EQ(changeData[CloudDbConstant::CLOUD_KV_TABLE_NAME].primaryData[OP_INSERT].size(), 2u);
1871     EXPECT_EQ(changeData[CloudDbConstant::CLOUD_KV_TABLE_NAME].primaryData[OP_UPDATE].size(), 0u);
1872 
1873     observer->ResetToZero();
1874     EXPECT_EQ(kvDelegatePtrS2_->UnRegisterObserver(observer), OK);
1875     delete observer;
1876     observer = nullptr;
1877 }
1878 
1879 /**
1880  * @tc.name: ObserverDataChangeTest002
1881  * @tc.desc: test RegisterObserver interface with OBSERVER_CHANGES_CLOUD | OBSERVER_CHANGES_BRIEF mode.
1882  * @tc.type: FUNC
1883  * @tc.require:
1884  * @tc.author: suyue
1885  */
1886 HWTEST_F(DistributedDBCloudKvStoreTest, ObserverDataChangeTest002, TestSize.Level0)
1887 {
1888     /**
1889      * @tc.steps: step1. insert data and delegate1 sync with cloud
1890      * @tc.expected: step1. insert and sync ok
1891     */
1892     Key k1 = {'k', '1'};
1893     Value v1 = {'v', '1'};
1894     ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v1), OK);
1895     Value actualValue;
1896     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK) ;
1897     EXPECT_EQ(actualValue, v1);
1898     std::this_thread::sleep_for(std::chrono::milliseconds(1)); // sleep for 1ms
1899     Key k2 = {'k', '2'};
1900     Value v2 = {'v', '2'};
1901     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v2), OK);
1902     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK);
1903     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1904 
1905     /**
1906      * @tc.steps: step2. delegate2 call RegisterObserver with OBSERVER_CHANGES_CLOUD | OBSERVER_CHANGES_BRIEF mode
1907      * @tc.expected: step2. sync with cloud and check data change success
1908     */
1909     auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
1910     EXPECT_EQ(kvDelegatePtrS2_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD | OBSERVER_CHANGES_BRIEF, observer), OK);
1911     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1912     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK);
1913     EXPECT_EQ(actualValue, v2);
1914     EXPECT_EQ(kvDelegatePtrS2_->Get(k2, actualValue), OK);
1915     EXPECT_EQ(actualValue, v2);
1916     EXPECT_EQ(static_cast<int>(observer->GetCallCount()), 1);
1917     auto changeData = observer->GetChangedData();
1918     ASSERT_EQ(changeData.size(), 1u);
1919     EXPECT_EQ(changeData[CloudDbConstant::CLOUD_KV_TABLE_NAME].primaryData[OP_INSERT].size(), 1u);
1920     EXPECT_EQ(changeData[CloudDbConstant::CLOUD_KV_TABLE_NAME].primaryData[OP_UPDATE].size(), 1u);
1921 
1922     observer->ResetToZero();
1923     EXPECT_EQ(kvDelegatePtrS2_->UnRegisterObserver(observer), OK);
1924     delete observer;
1925     observer = nullptr;
1926 }
1927 
1928 /**
1929  * @tc.name: ObserverDataChangeTest003
1930  * @tc.desc: test RegisterObserver interface with err mode.
1931  * @tc.type: FUNC
1932  * @tc.require:
1933  * @tc.author: suyue
1934  */
1935 HWTEST_F(DistributedDBCloudKvStoreTest, ObserverDataChangeTest003, TestSize.Level0)
1936 {
1937     /**
1938      * @tc.steps: step1. call RegisterObserver with err mode (out of enum range of 0x100 to 0xF00)
1939      * @tc.expected: step1. return INVALID_ARGS
1940     */
1941     auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
1942     unsigned int errMode = 0x1000;
1943     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD | errMode, observer), INVALID_ARGS);
1944     errMode = 0x110;
1945     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD | errMode, observer), INVALID_ARGS);
1946     errMode = OBSERVER_CHANGES_LOCAL_ONLY;
1947     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD | errMode, observer), INVALID_ARGS);
1948     delete observer;
1949     observer = nullptr;
1950 }
1951 
1952 /**
1953  * @tc.name: ObserverDataChangeTest004
1954  * @tc.desc: test register cloud observer twice
1955  * @tc.type: FUNC
1956  * @tc.require:
1957  * @tc.author: suyue
1958  */
1959 HWTEST_F(DistributedDBCloudKvStoreTest, ObserverDataChangeTest004, TestSize.Level0)
1960 {
1961     /**
1962      * @tc.steps: step1. register cloud observer twice
1963      * @tc.expected: step1. return ALREADY_SET
1964     */
1965     auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
1966     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD | OBSERVER_CHANGES_BRIEF, observer), OK);
1967     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, observer), ALREADY_SET);
1968     observer->ResetToZero();
1969     EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(observer), OK);
1970     delete observer;
1971     observer = nullptr;
1972 }
1973 
1974 /**
1975  * @tc.name: StartTransactionForAsyncDownloadTest001
1976  * @tc.desc: test StartTransactionForAsyncDownload function
1977  * @tc.type: FUNC
1978  * @tc.require:
1979  * @tc.author: tiansimiao
1980  */
1981 HWTEST_F(DistributedDBCloudKvStoreTest, StartTransactionForAsyncDownloadTest001, TestSize.Level0)
1982 {
1983     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
1984     SqliteCloudKvStore kvStoreObj(storageHandle.get());
1985     EXPECT_EQ(kvStoreObj.StartTransaction(TransactType::IMMEDIATE, true), -E_INVALID_DB);
1986 }
1987 
1988 /**
1989  * @tc.name: StartTransactionForAsyncDownloadTest002
1990  * @tc.desc: test StartTransactionForAsyncDownload function restart
1991  * @tc.type: FUNC
1992  * @tc.require:
1993  * @tc.author: tiansimiao
1994  */
1995 HWTEST_F(DistributedDBCloudKvStoreTest, StartTransactionForAsyncDownloadTest002, TestSize.Level0)
1996 {
1997     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
1998     SqliteCloudKvStore kvStoreObj(storageHandle.get());
1999     kvStoreObj.StartTransaction(TransactType::IMMEDIATE, true);
2000     kvStoreObj.Commit();
2001     EXPECT_EQ(kvStoreObj.StartTransaction(TransactType::IMMEDIATE, true), -E_INVALID_DB);
2002 }
2003 
2004 /**
2005  * @tc.name: StartTransactionForAsyncDownloadTest003
2006  * @tc.desc: test StartTransactionForAsyncDownload function
2007  * @tc.type: FUNC
2008  * @tc.require:
2009  * @tc.author: tiansimiao
2010  */
2011 HWTEST_F(DistributedDBCloudKvStoreTest, StartTransactionForAsyncDownloadTest003, TestSize.Level0)
2012 {
2013     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
2014     SqliteCloudKvStore kvStoreObj(storageHandle.get());
2015     EXPECT_EQ(kvStoreObj.StartTransaction(TransactType::DEFERRED, true), -E_INVALID_DB);
2016 }
2017 
2018 /**
2019  * @tc.name: CommitForAsyncDownloadTest001
2020  * @tc.desc: test CommitForAsyncDownload function
2021  * @tc.type: FUNC
2022  * @tc.require:
2023  * @tc.author: tiansimiao
2024  */
2025 HWTEST_F(DistributedDBCloudKvStoreTest, CommitForAsyncDownloadTest001, TestSize.Level0)
2026 {
2027     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
2028     SqliteCloudKvStore kvStoreObj(storageHandle.get());
2029     EXPECT_EQ(kvStoreObj.Commit(true), E_OK);
2030 }
2031 
2032 /**
2033  * @tc.name: CommitForAsyncDownloadTest002
2034  * @tc.desc: test CommitForAsyncDownload function
2035  * @tc.type: FUNC
2036  * @tc.require:
2037  * @tc.author: tiansimiao
2038  */
2039 HWTEST_F(DistributedDBCloudKvStoreTest, CommitForAsyncDownloadTest002, TestSize.Level0)
2040 {
2041     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
2042     SqliteCloudKvStore kvStoreObj(storageHandle.get());
2043     kvStoreObj.StartTransaction(TransactType::IMMEDIATE, true);
2044     EXPECT_EQ(kvStoreObj.Commit(true), E_OK);
2045 }
2046 
2047 /**
2048  * @tc.name: RollbackForAsyncDownloadTest001
2049  * @tc.desc: test RollbackForAsyncDownload function
2050  * @tc.type: FUNC
2051  * @tc.require:
2052  * @tc.author: tiansimiao
2053  */
2054 HWTEST_F(DistributedDBCloudKvStoreTest, RollbackForAsyncDownloadTest001, TestSize.Level0)
2055 {
2056     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
2057     SqliteCloudKvStore kvStoreObj(storageHandle.get());
2058     EXPECT_EQ(kvStoreObj.Rollback(true), E_OK);
2059 }
2060 
2061 /**
2062  * @tc.name: RollbackForAsyncDownloadTest002
2063  * @tc.desc: test RollbackForAsyncDownload function
2064  * @tc.type: FUNC
2065  * @tc.require:
2066  * @tc.author: tiansimiao
2067  */
2068 HWTEST_F(DistributedDBCloudKvStoreTest, RollbackForAsyncDownloadTest002, TestSize.Level0)
2069 {
2070     std::shared_ptr<KvStorageHandle> storageHandle = std::make_shared<SQLiteSingleVerNaturalStore>();
2071     SqliteCloudKvStore kvStoreObj(storageHandle.get());
2072     kvStoreObj.StartTransaction(TransactType::IMMEDIATE, true);
2073     EXPECT_EQ(kvStoreObj.Rollback(true), E_OK);
2074 }
2075 }
2076