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 "distributeddb_data_generate_unit_test.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "kv_virtual_device.h"
22 #include "kv_store_nb_delegate.h"
23 #include "platform_specific.h"
24 #include "kv_store_nb_delegate_impl.h"
25 #include "process_system_api_adapter_impl.h"
26 #include "virtual_communicator_aggregator.h"
27 #include "virtual_cloud_db.h"
28 #include "sqlite_utils.h"
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33 
34 namespace {
35 static std::string HWM_HEAD = "naturalbase_cloud_meta_sync_data_";
36 string g_testDir;
37 KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
38 CloudSyncOption g_CloudSyncoption;
39 const std::string USER_ID_2 = "user2";
40 const std::string USER_ID_3 = "user3";
41 class DistributedDBCloudKvTest : public testing::Test {
42 public:
43     static void SetUpTestCase();
44     static void TearDownTestCase();
45     void SetUp();
46     void TearDown();
47     void InsertRecord(int num);
48     void SetDeviceId(const Key &key, const std::string &deviceId);
49     void SetFlag(const Key &key, LogInfoFlag flag);
50     int CheckFlag(const Key &key, LogInfoFlag flag);
51     int CheckLogTable(const std::string &deviceId);
52     int CheckWaterMark(const std::string &key);
53     int ChangeUserId(const std::string &deviceId, const std::string &wantUserId);
54     int ChangeHashKey(const std::string &deviceId);
55 protected:
56     DBStatus GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId, KvStoreNbDelegate::Option option,
57         bool invalidSchema = false);
58     void CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId);
59     void BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option,
60         int expectSyncResult = OK);
61     void SyncAndGetProcessInfo(KvStoreNbDelegate *delegate, CloudSyncOption option);
62     bool CheckUserSyncInfo(const vector<std::string> users, const vector<DBStatus> userStatus,
63         const vector<Info> userExpectInfo);
64     static DataBaseSchema GetDataBaseSchema(bool invalidSchema);
65     std::shared_ptr<VirtualCloudDb> virtualCloudDb_ = nullptr;
66     std::shared_ptr<VirtualCloudDb> virtualCloudDb2_ = nullptr;
67     KvStoreConfig config_;
68     KvStoreNbDelegate* kvDelegatePtrS1_ = nullptr;
69     KvStoreNbDelegate* kvDelegatePtrS2_ = nullptr;
70     SyncProcess lastProcess_;
71     std::map<std::string, SyncProcess> lastSyncProcess_;
72     VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
73     KvVirtualDevice *deviceB_ = nullptr;
74 };
75 
SetUpTestCase()76 void DistributedDBCloudKvTest::SetUpTestCase()
77 {
78     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
79     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
80         LOGE("rm test db files error!");
81     }
82     g_CloudSyncoption.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
83     g_CloudSyncoption.users.push_back(USER_ID);
84     g_CloudSyncoption.devices.push_back("cloud");
85 
86     string dir = g_testDir + "/single_ver";
87     DIR* dirTmp = opendir(dir.c_str());
88     if (dirTmp == nullptr) {
89         OS::MakeDBDirectory(dir);
90     } else {
91         closedir(dirTmp);
92     }
93 }
94 
TearDownTestCase()95 void DistributedDBCloudKvTest::TearDownTestCase()
96 {
97     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
98         LOGE("rm test db files error!");
99     }
100 }
101 
SetUp()102 void DistributedDBCloudKvTest::SetUp()
103 {
104     DistributedDBToolsUnitTest::PrintTestCaseInfo();
105     config_.dataDir = g_testDir;
106     /**
107      * @tc.setup: create virtual device B and C, and get a KvStoreNbDelegate as deviceA
108      */
109     virtualCloudDb_ = std::make_shared<VirtualCloudDb>();
110     virtualCloudDb2_ = std::make_shared<VirtualCloudDb>();
111     g_mgr.SetKvStoreConfig(config_);
112     KvStoreNbDelegate::Option option1;
113     ASSERT_EQ(GetKvStore(kvDelegatePtrS1_, STORE_ID_1, option1), OK);
114     // set aggregator after get store1, only store2 can sync with p2p
115     communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
116     ASSERT_TRUE(communicatorAggregator_ != nullptr);
117     RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
118     KvStoreNbDelegate::Option option2;
119     ASSERT_EQ(GetKvStore(kvDelegatePtrS2_, STORE_ID_2, option2), OK);
120 
121     deviceB_ = new (std::nothrow) KvVirtualDevice("DEVICE_B");
122     ASSERT_TRUE(deviceB_ != nullptr);
123     auto syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
124     ASSERT_TRUE(syncInterfaceB != nullptr);
125     ASSERT_EQ(deviceB_->Initialize(communicatorAggregator_, syncInterfaceB), E_OK);
126 }
127 
TearDown()128 void DistributedDBCloudKvTest::TearDown()
129 {
130     CloseKvStore(kvDelegatePtrS1_, STORE_ID_1);
131     CloseKvStore(kvDelegatePtrS2_, STORE_ID_2);
132     virtualCloudDb_ = nullptr;
133     virtualCloudDb2_ = nullptr;
134     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
135         LOGE("rm test db files error!");
136     }
137 
138     if (deviceB_ != nullptr) {
139         delete deviceB_;
140         deviceB_ = nullptr;
141     }
142 
143     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
144     communicatorAggregator_ = nullptr;
145     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
146 }
147 
BlockSync(KvStoreNbDelegate * delegate,DBStatus expectDBStatus,CloudSyncOption option,int expectSyncResult)148 void DistributedDBCloudKvTest::BlockSync(KvStoreNbDelegate *delegate, DBStatus expectDBStatus, CloudSyncOption option,
149     int expectSyncResult)
150 {
151     if (delegate == nullptr) {
152         return;
153     }
154     std::mutex dataMutex;
155     std::condition_variable cv;
156     bool finish = false;
157     SyncProcess last;
158     auto callback = [expectDBStatus, &last, &cv, &dataMutex, &finish, &option](const std::map<std::string,
159         SyncProcess> &process) {
160         size_t notifyCnt = 0;
161         for (const auto &item: process) {
162             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
163             if (item.second.process != DistributedDB::FINISHED) {
164                 continue;
165             }
166             EXPECT_EQ(item.second.errCode, expectDBStatus);
167             {
168                 std::lock_guard<std::mutex> autoLock(dataMutex);
169                 notifyCnt++;
170                 std::set<std::string> userSet(option.users.begin(), option.users.end());
171                 if (notifyCnt == userSet.size()) {
172                     finish = true;
173                     last = item.second;
174                     cv.notify_one();
175                 }
176             }
177         }
178     };
179     auto actualRet = delegate->Sync(option, callback);
180     EXPECT_EQ(actualRet, expectSyncResult);
181     if (actualRet == OK) {
182         std::unique_lock<std::mutex> uniqueLock(dataMutex);
183         cv.wait(uniqueLock, [&finish]() {
184             return finish;
185         });
186     }
187     lastProcess_ = last;
188 }
189 
GetDataBaseSchema(bool invalidSchema)190 DataBaseSchema DistributedDBCloudKvTest::GetDataBaseSchema(bool invalidSchema)
191 {
192     DataBaseSchema schema;
193     TableSchema tableSchema;
194     tableSchema.name = invalidSchema ? "invalid_schema_name" : CloudDbConstant::CLOUD_KV_TABLE_NAME;
195     Field field;
196     field.colName = CloudDbConstant::CLOUD_KV_FIELD_KEY;
197     field.type = TYPE_INDEX<std::string>;
198     field.primary = true;
199     tableSchema.fields.push_back(field);
200     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE;
201     field.primary = false;
202     tableSchema.fields.push_back(field);
203     field.colName = CloudDbConstant::CLOUD_KV_FIELD_ORI_DEVICE;
204     tableSchema.fields.push_back(field);
205     field.colName = CloudDbConstant::CLOUD_KV_FIELD_VALUE;
206     tableSchema.fields.push_back(field);
207     field.colName = CloudDbConstant::CLOUD_KV_FIELD_DEVICE_CREATE_TIME;
208     field.type = TYPE_INDEX<int64_t>;
209     tableSchema.fields.push_back(field);
210     schema.tables.push_back(tableSchema);
211     return schema;
212 }
213 
GetKvStore(KvStoreNbDelegate * & delegate,const std::string & storeId,KvStoreNbDelegate::Option option,bool invalidSchema)214 DBStatus DistributedDBCloudKvTest::GetKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId,
215     KvStoreNbDelegate::Option option, bool invalidSchema)
216 {
217     DBStatus openRet = OK;
218     g_mgr.GetKvStore(storeId, option, [&openRet, &delegate](DBStatus status, KvStoreNbDelegate *openDelegate) {
219         openRet = status;
220         delegate = openDelegate;
221     });
222     EXPECT_EQ(openRet, OK);
223     EXPECT_NE(delegate, nullptr);
224 
225     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
226     cloudDbs[USER_ID] = virtualCloudDb_;
227     cloudDbs[USER_ID_2] = virtualCloudDb2_;
228     delegate->SetCloudDB(cloudDbs);
229     std::map<std::string, DataBaseSchema> schemas;
230     schemas[USER_ID] = GetDataBaseSchema(invalidSchema);
231     schemas[USER_ID_2] = GetDataBaseSchema(invalidSchema);
232     return delegate->SetCloudDbSchema(schemas);
233 }
234 
CloseKvStore(KvStoreNbDelegate * & delegate,const std::string & storeId)235 void DistributedDBCloudKvTest::CloseKvStore(KvStoreNbDelegate *&delegate, const std::string &storeId)
236 {
237     if (delegate != nullptr) {
238         ASSERT_EQ(g_mgr.CloseKvStore(delegate), OK);
239         delegate = nullptr;
240         DBStatus status = g_mgr.DeleteKvStore(storeId);
241         LOGD("delete kv store status %d store %s", status, storeId.c_str());
242         ASSERT_EQ(status, OK);
243     }
244 }
245 
SyncAndGetProcessInfo(KvStoreNbDelegate * delegate,CloudSyncOption option)246 void DistributedDBCloudKvTest::SyncAndGetProcessInfo(KvStoreNbDelegate *delegate, CloudSyncOption option)
247 {
248     if (delegate == nullptr) {
249         return;
250     }
251     std::mutex dataMutex;
252     std::condition_variable cv;
253     bool isFinish = false;
254     vector<std::map<std::string, SyncProcess>> lists;
255     auto callback = [&cv, &dataMutex, &isFinish, &option, &lists](const std::map<std::string, SyncProcess> &process) {
256         size_t notifyCnt = 0;
257         for (const auto &item: process) {
258             LOGD("user = %s, status = %d", item.first.c_str(), item.second.process);
259             if (item.second.process != DistributedDB::FINISHED) {
260                 continue;
261             }
262             {
263                 std::lock_guard<std::mutex> autoLock(dataMutex);
264                 notifyCnt++;
265                 std::set<std::string> userSet(option.users.begin(), option.users.end());
266                 if (notifyCnt == userSet.size()) {
267                     isFinish = true;
268                     cv.notify_one();
269                 }
270                 lists.push_back(process);
271             }
272         }
273     };
274     auto ret = delegate->Sync(option, callback);
275     EXPECT_EQ(ret, OK);
276     if (ret == OK) {
277         std::unique_lock<std::mutex> uniqueLock(dataMutex);
278         cv.wait(uniqueLock, [&isFinish]() {
279             return isFinish;
280         });
281     }
282     lastSyncProcess_ = lists.back();
283 }
284 
CheckUserSyncInfo(const vector<std::string> users,const vector<DBStatus> userStatus,const vector<Info> userExpectInfo)285 bool DistributedDBCloudKvTest::CheckUserSyncInfo(const vector<std::string> users, const vector<DBStatus> userStatus,
286     const vector<Info> userExpectInfo)
287 {
288     uint32_t idx = 0;
289     for (auto &it: lastSyncProcess_) {
290         if ((idx >= users.size()) || (idx >= userStatus.size()) || (idx >= userExpectInfo.size())) {
291             return false;
292         }
293         string user = it.first;
294         if (user.compare(0, user.length(), users[idx]) != 0) {
295             return false;
296         }
297         SyncProcess actualSyncProcess = it.second;
298         EXPECT_EQ(actualSyncProcess.process, FINISHED);
299         EXPECT_EQ(actualSyncProcess.errCode, userStatus[idx]);
300         for (const auto &table : actualSyncProcess.tableProcess) {
301             EXPECT_EQ(table.second.upLoadInfo.total, userExpectInfo[idx].total);
302             EXPECT_EQ(table.second.upLoadInfo.successCount, userExpectInfo[idx].successCount);
303             EXPECT_EQ(table.second.upLoadInfo.insertCount, userExpectInfo[idx].insertCount);
304             EXPECT_EQ(table.second.upLoadInfo.failCount, userExpectInfo[idx].failCount);
305         }
306         idx++;
307     }
308     return true;
309 }
310 
311 /**
312  * @tc.name: NormalSync001
313  * @tc.desc: Test normal push sync for add data.
314  * @tc.type: FUNC
315  * @tc.require:
316  * @tc.author: zhangqiquan
317  */
318 HWTEST_F(DistributedDBCloudKvTest, NormalSync001, TestSize.Level0)
319 {
320     Key key = {'k'};
321     Value expectValue = {'v'};
322     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anon341701840702(const std::string &origin) 323     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
324         LOGW("origin is %s", origin.c_str());
325         return origin + "1";
326     });
327     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
328     for (const auto &table : lastProcess_.tableProcess) {
329         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
330         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
331     }
332     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
333     for (const auto &table : lastProcess_.tableProcess) {
334         EXPECT_EQ(table.second.downLoadInfo.total, 2u); // download 2 records
335         EXPECT_EQ(table.second.downLoadInfo.insertCount, 2u); // download 2 records
336     }
337     Value actualValue;
338     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
339     EXPECT_EQ(actualValue, expectValue);
340     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
341     auto result = kvDelegatePtrS2_->GetCloudVersion("");
342     EXPECT_EQ(result.first, OK);
343     for (const auto &item : result.second) {
344         EXPECT_EQ(item.second, "1");
345     }
346 }
347 
348 /**
349  * @tc.name: NormalSync002
350  * @tc.desc: Test normal push pull sync for add data.
351  * @tc.type: FUNC
352  * @tc.require:
353  * @tc.author: zhangqiquan
354  */
355 HWTEST_F(DistributedDBCloudKvTest, NormalSync002, TestSize.Level0)
356 {
357     /**
358      * @tc.steps: step1. store1 put (k1,v1) store2 put (k2,v2)
359      * @tc.expected: step1. both put ok
360      */
361     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
362     Key key1 = {'k', '1'};
363     Value expectValue1 = {'v', '1'};
364     Key key2 = {'k', '2'};
365     Value expectValue2 = {'v', '2'};
366     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
367     ASSERT_EQ(kvDelegatePtrS2_->Put(key2, expectValue2), OK);
368     /**
369      * @tc.steps: step2. both store1 and store2 sync
370      * @tc.expected: step2. both sync ok, and store2 got (k1,v1) store1 not exist (k2,v2)
371      */
372     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
373     LOGW("Store1 sync end");
374     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
375     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
376     LOGW("Store2 sync end");
377     Value actualValue;
378     EXPECT_EQ(kvDelegatePtrS2_->Get(key1, actualValue), OK);
379     std::vector<Entry> entries;
380     EXPECT_EQ(kvDelegatePtrS2_->GetDeviceEntries(std::string("DEVICES_A"), entries), OK);
381     EXPECT_EQ(entries.size(), 1u); // 1 record
382     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
383     EXPECT_EQ(actualValue, expectValue1);
384     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
385     /**
386      * @tc.steps: step3. store1 sync again
387      * @tc.expected: step3. sync ok store1 got (k2,v2)
388      */
389     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
390     LOGW("Store1 sync end");
391     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), OK);
392     EXPECT_EQ(actualValue, expectValue2);
393 }
394 
395 /**
396  * @tc.name: NormalSync003
397  * @tc.desc: Test normal pull sync for update data.
398  * @tc.type: FUNC
399  * @tc.require:
400  * @tc.author: zhangqiquan
401  */
402 HWTEST_F(DistributedDBCloudKvTest, NormalSync003, TestSize.Level0)
403 {
404     /**
405      * @tc.steps: step1. store1 put (k1,v1) store2 put (k1,v2)
406      * @tc.expected: step1. both put ok
407      */
408     Key key = {'k', '1'};
409     Value expectValue1 = {'v', '1'};
410     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue1), OK);
411     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
412     Value expectValue2 = {'v', '2'};
413     ASSERT_EQ(kvDelegatePtrS2_->Put(key, expectValue2), OK);
414     /**
415      * @tc.steps: step2. both store1 and store2 sync
416      * @tc.expected: step2. both sync ok and store2 got (k1,v2)
417      */
418     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
419     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
420     Value actualValue;
421     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
422     EXPECT_EQ(actualValue, expectValue2);
423     /**
424      * @tc.steps: step2. store1 sync again
425      * @tc.expected: step2. sync ok and store1 got (k1,v2)
426      */
427     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
428     EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
429     EXPECT_EQ(actualValue, expectValue2);
430 }
431 
432 /**
433  * @tc.name: NormalSync004
434  * @tc.desc: Test normal push sync for delete data.
435  * @tc.type: FUNC
436  * @tc.require:
437  * @tc.author: zhangqiquan
438  */
439 HWTEST_F(DistributedDBCloudKvTest, NormalSync004, TestSize.Level0)
440 {
441     /**
442      * @tc.steps: step1. store1 put (k1,v1) and both sync
443      * @tc.expected: step1. put ok and both sync ok
444      */
445     Key key = {'k'};
446     Value expectValue = {'v'};
447     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
448     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
449     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
450     Value actualValue;
451     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
452     EXPECT_EQ(actualValue, expectValue);
453     /**
454      * @tc.steps: step2. store1 delete (k1,v1) and both sync
455      * @tc.expected: step2. both put ok
456      */
457     ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK);
458     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
459     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
460     actualValue.clear();
461     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
462     EXPECT_NE(actualValue, expectValue);
463 }
464 
465 /**
466  * @tc.name: NormalSync005
467  * @tc.desc: Test normal push sync for add data.
468  * @tc.type: FUNC
469  * @tc.require:
470  * @tc.author: zhangqiquan
471  */
472 HWTEST_F(DistributedDBCloudKvTest, NormalSync005, TestSize.Level1)
473 {
474     for (int i = 0; i < 60; ++i) { // sync 60 records
475         Key key = {'k'};
476         Value expectValue = {'v'};
477         key.push_back(static_cast<uint8_t>(i));
478         expectValue.push_back(static_cast<uint8_t>(i));
479         ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
480     }
481     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
482     for (const auto &process : lastProcess_.tableProcess) {
483         EXPECT_EQ(process.second.upLoadInfo.insertCount, 60u); // sync 60 records
484     }
485     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
486     for (const auto &process : lastProcess_.tableProcess) {
487         EXPECT_EQ(process.second.downLoadInfo.insertCount, 60u); // sync 60 records
488     }
489 }
490 
491 /**
492  * @tc.name: NormalSync006
493  * @tc.desc: Test normal push sync with insert delete update.
494  * @tc.type: FUNC
495  * @tc.require:
496  * @tc.author: zhangqiquan
497  */
498 HWTEST_F(DistributedDBCloudKvTest, NormalSync006, TestSize.Level0)
499 {
500     Key k1 = {'k', '1'};
501     Key k2 = {'k', '2'};
502     Value v1 = {'v', '1'};
503     Value v2 = {'v', '2'};
504     Value v3 = {'v', '3'};
505     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
506     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK);
507     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v3), OK);
508     ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK);
509     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
510     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
511     Value actualValue;
512     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), NOT_FOUND);
513     EXPECT_EQ(kvDelegatePtrS2_->Get(k2, actualValue), OK);
514     EXPECT_EQ(actualValue, v3);
515 }
516 
517 /**
518  * @tc.name: NormalSync007
519  * @tc.desc: Test normal push sync with download and upload.
520  * @tc.type: FUNC
521  * @tc.require:
522  * @tc.author: zhangqiquan
523  */
524 HWTEST_F(DistributedDBCloudKvTest, NormalSync007, TestSize.Level0)
525 {
526     Key k1 = {'k', '1'};
527     Key k2 = {'k', '2'};
528     Key k3 = {'k', '3'};
529     Key k4 = {'k', '4'};
530     Value v1 = {'v', '1'};
531     Value v2 = {'v', '2'};
532     Value v3 = {'v', '3'};
533     ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v1), OK);
534     ASSERT_EQ(kvDelegatePtrS2_->Put(k2, v1), OK);
535     ASSERT_EQ(kvDelegatePtrS2_->Put(k3, v1), OK);
536     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
537     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v2), OK);
538     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v2), OK);
539     ASSERT_EQ(kvDelegatePtrS1_->Put(k4, v2), OK);
540     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
541     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
542     ASSERT_EQ(kvDelegatePtrS2_->Put(k4, v3), OK);
543     ASSERT_EQ(kvDelegatePtrS1_->Delete(k2), OK);
544     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
545 }
546 
547 /**
548  * @tc.name: NormalSync008
549  * @tc.desc: Test complex sync.
550  * @tc.type: FUNC
551  * @tc.require:
552  * @tc.author: zhangqiquan
553  */
554 HWTEST_F(DistributedDBCloudKvTest, NormalSync008, TestSize.Level0)
555 {
556     Key k1 = {'k', '1'};
557     Value v1 = {'v', '1'};
558     deviceB_->PutData(k1, v1, 1u, 0); // 1 is current timestamp
559     deviceB_->Sync(SyncMode::SYNC_MODE_PUSH_ONLY, true);
560     Value actualValue;
561     EXPECT_EQ(kvDelegatePtrS2_->Get(k1, actualValue), OK);
562     EXPECT_EQ(actualValue, v1);
563     CloudSyncOption option;
564     option.mode = SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH;
565     option.users.push_back(USER_ID);
566     option.devices.push_back("cloud");
567     BlockSync(kvDelegatePtrS2_, OK, option);
568     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
569     EXPECT_EQ(kvDelegatePtrS1_->Get(k1, actualValue), NOT_FOUND);
570 }
571 
572 /**
573  * @tc.name: NormalSync009
574  * @tc.desc: Test normal push sync with download and upload.
575  * @tc.type: FUNC
576  * @tc.require:
577  * @tc.author: zhangqiquan
578  */
579 HWTEST_F(DistributedDBCloudKvTest, NormalSync009, TestSize.Level0)
580 {
581     Key k1 = {'k', '1'};
582     Key k2 = {'k', '2'};
583     Key k3 = {'k', '3'};
584     Value v1 = {'v', '1'};
585     Value v2 = {'v', '2'};
586     Value v3 = {'v', '3'};
587     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
588     ASSERT_EQ(kvDelegatePtrS1_->Put(k2, v1), OK);
589     ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK);
590     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
591     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
592     ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v2), OK);
593     ASSERT_EQ(kvDelegatePtrS2_->Put(k3, v2), OK);
594     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
595     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
596     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
597 }
598 
599 /**
600  * @tc.name: NormalSync010
601  * @tc.desc: Test normal push sync for add data with different user.
602  * @tc.type: FUNC
603  * @tc.require:
604  * @tc.author: zhangshijie
605  */
606 HWTEST_F(DistributedDBCloudKvTest, NormalSync010, TestSize.Level0)
607 {
608     // add <k1, v1>, sync to cloud with user1
609     Key key1 = {'k', '1'};
610     Value expectValue1 = {'v', '1'};
611     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
612     CloudSyncOption option;
613     option.users.push_back(USER_ID);
614     option.devices.push_back("cloud");
615     BlockSync(kvDelegatePtrS1_, OK, option);
616     for (const auto &table : lastProcess_.tableProcess) {
617         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
618     }
619 
620     // add <k2, v2>, sync to cloud with user2
621     Key key2 = {'k', '2'};
622     Value expectValue2 = {'v', '2'};
623     ASSERT_EQ(kvDelegatePtrS1_->Put(key2, expectValue2), OK);
624     option.users.clear();
625     option.users.push_back(USER_ID_2);
626     BlockSync(kvDelegatePtrS1_, OK, option);
627     for (const auto &table : lastProcess_.tableProcess) {
628         EXPECT_EQ(table.second.upLoadInfo.total, 2u);
629     }
630 
631     option.users.clear();
632     option.users.push_back(USER_ID);
633     option.users.push_back(USER_ID_2);
634     BlockSync(kvDelegatePtrS2_, OK, option);
635     for (const auto &table : lastProcess_.tableProcess) {
636         EXPECT_EQ(table.second.downLoadInfo.total, 2u);
637     }
638     Value actualValue;
639     EXPECT_EQ(kvDelegatePtrS2_->Get(key1, actualValue), OK);
640     EXPECT_EQ(actualValue, expectValue1);
641     Value actualValue2;
642     EXPECT_EQ(kvDelegatePtrS2_->Get(key2, actualValue2), OK);
643     EXPECT_EQ(actualValue2, expectValue2);
644 }
645 
646 /**
647  * @tc.name: NormalSync011
648  * @tc.desc: Do not synchronize when security label is S4.
649  * @tc.type: FUNC
650  * @tc.require:
651  * @tc.author: liaoyonghuang
652  */
653 HWTEST_F(DistributedDBCloudKvTest, NormalSync011, TestSize.Level0)
654 {
655     std::shared_ptr<ProcessSystemApiAdapterImpl> g_adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
656     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(g_adapter);
657     KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr;
658 
659     KvStoreNbDelegate::Option option;
660     option.secOption.securityLabel = S4;
661     EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option), OK);
662     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
663     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
664     BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption, SECURITY_OPTION_CHECK_ERROR);
665     CloseKvStore(kvDelegatePtrS3_, STORE_ID_3);
666 }
667 
668 /**
669  * @tc.name: NormalSync012
670  * @tc.desc: Test normal push sync with memory db.
671  * @tc.type: FUNC
672  * @tc.require:
673  * @tc.author: zhangqiquan
674  */
675 HWTEST_F(DistributedDBCloudKvTest, NormalSync012, TestSize.Level0)
676 {
677     KvStoreNbDelegate *memoryDB1 = nullptr;
678     KvStoreNbDelegate::Option option1;
679     option1.isMemoryDb = true;
680     GetKvStore(memoryDB1, STORE_ID_3, option1);
681     ASSERT_NE(memoryDB1, nullptr);
682     KvStoreNbDelegate *memoryDB2 = nullptr;
683     KvStoreNbDelegate::Option option2;
684     option2.isMemoryDb = true;
685     GetKvStore(memoryDB2, STORE_ID_4, option2);
686     EXPECT_NE(memoryDB2, nullptr);
687     Key key1 = {'k', '1'};
688     Value expectValue1 = {'v', '1'};
689     EXPECT_EQ(memoryDB1->Put(key1, expectValue1), OK);
690     BlockSync(memoryDB1, OK, g_CloudSyncoption);
691     BlockSync(memoryDB2, OK, g_CloudSyncoption);
692     EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK);
693     EXPECT_EQ(g_mgr.CloseKvStore(memoryDB2), OK);
694 }
695 
696 /**
697  * @tc.name: NormalSync013
698  * @tc.desc: Test the wrong schema.
699  * @tc.type: FUNC
700  * @tc.require:
701  * @tc.author: liaoyonghuang
702  */
703 HWTEST_F(DistributedDBCloudKvTest, NormalSync013, TestSize.Level0)
704 {
705     KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr;
706     KvStoreNbDelegate::Option option;
707     EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option, true), INVALID_SCHEMA);
708     CloseKvStore(kvDelegatePtrS3_, STORE_ID_3);
709 }
710 
711 /**
712  * @tc.name: NormalSync014
713  * @tc.desc: Test sync after user change.
714  * @tc.type: FUNC
715  * @tc.require:
716  * @tc.author: liaoyonghuang
717  */
718 HWTEST_F(DistributedDBCloudKvTest, NormalSync014, TestSize.Level1)
719 {
720     /**
721      * @tc.steps: step1. kvDelegatePtrS1_ put and sync data (k1, v1)
722      * @tc.expected: step1.ok
723      */
724     g_mgr.SetSyncActivationCheckCallback([] (const std::string &userId, const std::string &appId,
__anon341701840802(const std::string &userId, const std::string &appId, const std::string &storeId)725         const std::string &storeId)-> bool {
726         return true;
727     });
728     KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr;
729     KvStoreNbDelegate::Option option;
730     option.syncDualTupleMode = true;
731     GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option);
732     Key key = {'k', '1'};
733     Value value = {'v', '1'};
734     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
735     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
736     /**
737      * @tc.steps: step2. Set sync block time 2s, and change user in sync block time
738      * @tc.expected: step2. Sync return  USER_CHANGED.
739      */
740     virtualCloudDb_->SetBlockTime(2000); // 2000ms
__anon341701840902() 741     std::thread thread([&]() {
742         std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // sleep for 1000ms
743         g_mgr.SetSyncActivationCheckCallback([] (const std::string &userId, const std::string &appId,
744             const std::string &storeId)-> bool {
745             return false;
746         });
747         RuntimeContext::GetInstance()->NotifyUserChanged();
748     });
749     BlockSync(kvDelegatePtrS3_, USER_CHANGED, g_CloudSyncoption);
750     thread.join();
751     CloseKvStore(kvDelegatePtrS3_, STORE_ID_3);
752 }
753 
754 /**
755  * @tc.name: NormalSync015
756  * @tc.desc: Test sync in all process.
757  * @tc.type: FUNC
758  * @tc.require:
759  * @tc.author: zhangqiquan
760  */
761 HWTEST_F(DistributedDBCloudKvTest, NormalSync015, TestSize.Level0)
762 {
763     Key key = {'k'};
764     Value expectValue = {'v'};
765     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
766     auto option = g_CloudSyncoption;
767     auto action = static_cast<uint32_t>(LockAction::INSERT) | static_cast<uint32_t>(LockAction::UPDATE)
768         | static_cast<uint32_t>(LockAction::DELETE) | static_cast<uint32_t>(LockAction::DOWNLOAD);
769     option.lockAction = static_cast<LockAction>(action);
770     BlockSync(kvDelegatePtrS1_, OK, option);
771     for (const auto &table : lastProcess_.tableProcess) {
772         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
773     }
774     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
775     Value actualValue;
776     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
777     EXPECT_EQ(actualValue, expectValue);
778 }
779 
780 /**
781  * @tc.name: NormalSync016
782  * @tc.desc: Device A and device B have the same key data,
783  *           and then devices B and A perform cloud synchronization sequentially.
784  *           Finally, device A updates the data and performs cloud synchronization.
785  *           Test if there is new data inserted into the cloud database.
786  * @tc.type: FUNC
787  * @tc.require:
788  * @tc.author: liaoyonghuang
789  */
790 HWTEST_F(DistributedDBCloudKvTest, NormalSync016, TestSize.Level0)
791 {
792     Key key = {'k', '1'};
793     Value value1 = {'v', '1'};
794     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value1), OK);
795     Value value2 = {'v', '2'};
796     ASSERT_EQ(kvDelegatePtrS2_->Put(key, value2), OK);
797     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
798     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
799 
800     Value value3 = {'v', '3'};
801     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value3), OK);
__anon341701840b02(VBucket &record) 802     virtualCloudDb_->SetInsertHook([](VBucket &record) {
803         for (auto &recordData : record) {
804             std::string insertKey = "key";
805             Type insertValue = "k1";
806             EXPECT_FALSE(recordData.first == insertKey && recordData.second == insertValue);
807         }
808     });
809     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
810     virtualCloudDb_->SetInsertHook(nullptr);
811 }
812 
813 /**
814  * @tc.name: NormalSync017
815  * @tc.desc: Test duplicate addition, deletion, and sync.
816  * @tc.type: FUNC
817  * @tc.require:
818  * @tc.author: liaoyonghuang
819  */
820 HWTEST_F(DistributedDBCloudKvTest, NormalSync017, TestSize.Level0)
821 {
822     Key key = {'k'};
823     Value value = {'v'};
824     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
825     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
826     ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK);
827     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
828     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
829     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
830 }
831 
832 /**
833  * @tc.name: NormalSync018
834  * @tc.desc: Test putBatch and sync with memory db.
835  * @tc.type: FUNC
836  * @tc.require:
837  * @tc.author: liaoyonghuang
838  */
839 HWTEST_F(DistributedDBCloudKvTest, NormalSync018, TestSize.Level0)
840 {
841     /**
842      * @tc.steps:step1. Get two Memory DB.
843      * @tc.expected: step1 OK.
844      */
845     KvStoreNbDelegate *memoryDB1 = nullptr;
846     KvStoreNbDelegate::Option option1;
847     option1.isMemoryDb = true;
848     GetKvStore(memoryDB1, STORE_ID_3, option1);
849     ASSERT_NE(memoryDB1, nullptr);
850     KvStoreNbDelegate *memoryDB2 = nullptr;
851     KvStoreNbDelegate::Option option2;
852     option2.isMemoryDb = true;
853     GetKvStore(memoryDB2, STORE_ID_4, option2);
854     EXPECT_NE(memoryDB2, nullptr);
855 
856     /**
857      * @tc.steps:step2. put 301 records and sync to cloud.
858      * @tc.expected: step2 OK.
859      */
860     vector<Entry> entries;
861     int count = 301; // put 301 records.
862     for (int i = 0; i < count; i++) {
863         std::string keyStr = "k_" + std::to_string(i);
864         std::string valueStr = "v_" + std::to_string(i);
865         Key key(keyStr.begin(), keyStr.end());
866         Value value(valueStr.begin(), valueStr.end());
867         entries.push_back({key, value});
868     }
869     EXPECT_EQ(memoryDB1->PutBatch(entries), OK);
870     BlockSync(memoryDB1, OK, g_CloudSyncoption);
871 
872     /**
873      * @tc.steps:step3. Sync from cloud and check values.
874      * @tc.expected: step3 OK.
875      */
876     BlockSync(memoryDB2, OK, g_CloudSyncoption);
877     for (int i = 0; i < count; i++) {
878         std::string keyStr = "k_" + std::to_string(i);
879         std::string valueStr = "v_" + std::to_string(i);
880         Key key(keyStr.begin(), keyStr.end());
881         Value expectValue(valueStr.begin(), valueStr.end());
882         Value actualValue;
883         EXPECT_EQ(memoryDB2->Get(key, actualValue), OK);
884         EXPECT_EQ(actualValue, expectValue);
885     }
886     EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK);
887     EXPECT_EQ(g_mgr.CloseKvStore(memoryDB2), OK);
888 }
889 
890 /**
891  * @tc.name: NormalSync019
892  * @tc.desc: Test dataItem has same time.
893  * @tc.type: FUNC
894  * @tc.require:
895  * @tc.author: zhangqiquan
896  */
897 HWTEST_F(DistributedDBCloudKvTest, NormalSync019, TestSize.Level0)
898 {
899     Key k1 = {'k', '1'};
900     Value v1 = {'v', '1'};
901     ASSERT_EQ(kvDelegatePtrS2_->Put(k1, v1), OK);
902     deviceB_->Sync(SyncMode::SYNC_MODE_PULL_ONLY, true);
903 
904     VirtualDataItem dataItem;
905     deviceB_->GetData(k1, dataItem);
906     EXPECT_EQ(dataItem.timestamp, dataItem.writeTimestamp);
907 }
908 
909 /**
910  * @tc.name: NormalSync020
911  * @tc.desc: Test sync with two users.
912  * @tc.type: FUNC
913  * @tc.require:
914  * @tc.author: liaoyonghuang
915  */
916 HWTEST_F(DistributedDBCloudKvTest, NormalSync020, TestSize.Level0)
917 {
918     /**
919      * @tc.steps:step1. Inserts a piece of data.
920      * @tc.expected: step1 OK.
921      */
922     Key k1 = {'k', '1'};
923     Value v1 = {'v', '1'};
924     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
925     /**
926      * @tc.steps:step2. sync with two users.
927      * @tc.expected: step2 OK.
928      */
929     CloudSyncOption option;
930     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
931     option.users.push_back(USER_ID);
932     option.users.push_back(USER_ID_2);
933     option.devices.push_back("cloud");
934     BlockSync(kvDelegatePtrS1_, OK, option);
935     /**
936      * @tc.steps:step3. Check upLoadInfo.batchIndex of two users.
937      * @tc.expected: Both users have a upLoadInfo.batchIndex of 1.
938      */
939     for (const auto &table : lastProcess_.tableProcess) {
940         EXPECT_EQ(table.second.upLoadInfo.batchIndex, 1u);
941     }
942 }
943 
944 /**
945  * @tc.name: NormalSync021
946  * @tc.desc: Test Get Func to get cloudVersion.
947  * @tc.type: FUNC
948  * @tc.require:
949  * @tc.author: caihaoting
950  */
951 HWTEST_F(DistributedDBCloudKvTest, NormalSync021, TestSize.Level0)
952 {
953     /**
954      * @tc.steps:step1. store2 GetCloudVersion.
955      * @tc.expected: step1 OK.
956      */
957     Key key = {'k'};
958     Value expectValue = {'v'};
959     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anon341701840c02(const std::string &origin) 960     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
961         LOGW("origin is %s", origin.c_str());
962         return origin + "1";
963     });
964     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
965     for (const auto &table : lastProcess_.tableProcess) {
966         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
967     }
968     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
969     Value actualValue;
970     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
971     EXPECT_EQ(actualValue, expectValue);
972     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
973     auto result = kvDelegatePtrS2_->GetCloudVersion("");
974     EXPECT_EQ(result.first, OK);
975     for (auto item : result.second) {
976         EXPECT_EQ(item.second, "1");
977     }
978     /**
979      * @tc.steps:step2. store2 GetCloudVersion.
980      * @tc.expected: step2 NOT_FOUND.
981      */
982     Key keyB;
983     Value actualValueB;
984     std::string deviceB = DBCommon::TransferStringToHex(DBCommon::TransferHashString("DEVICE_B"));
985     std::string versionDeviceBStr = "naturalbase_cloud_version_" + deviceB;
986     const char *buffer = versionDeviceBStr.c_str();
987     for (uint32_t i = 0; i < versionDeviceBStr.size(); i++) {
988         keyB.emplace_back(buffer[i]);
989     }
990     EXPECT_EQ(kvDelegatePtrS2_->Get(keyB, actualValueB), NOT_FOUND);
991 }
992 
993 /**
994  * @tc.name: NormalSync022
995  * @tc.desc: Test Cloud sync without schema.
996  * @tc.type: FUNC
997  * @tc.require:
998  * @tc.author: zhangqiquan
999  */
1000 HWTEST_F(DistributedDBCloudKvTest, NormalSync022, TestSize.Level0)
1001 {
1002     /**
1003      * @tc.steps:step1. Get Memory DB.
1004      * @tc.expected: step1 OK.
1005      */
1006     KvStoreNbDelegate *memoryDB1 = nullptr;
1007     KvStoreNbDelegate::Option option;
1008     option.isMemoryDb = true;
1009     DBStatus openRet = OK;
__anon341701840d02(DBStatus status, KvStoreNbDelegate *openDelegate) 1010     g_mgr.GetKvStore(STORE_ID_4, option, [&openRet, &memoryDB1](DBStatus status, KvStoreNbDelegate *openDelegate) {
1011         openRet = status;
1012         memoryDB1 = openDelegate;
1013     });
1014     EXPECT_EQ(openRet, OK);
1015     ASSERT_NE(memoryDB1, nullptr);
1016     /**
1017      * @tc.steps:step2. Sync without cloud schema.
1018      * @tc.expected: step2 CLOUD_ERROR.
1019      */
1020     BlockSync(memoryDB1, OK, g_CloudSyncoption, CLOUD_ERROR);
1021     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
1022     cloudDbs[USER_ID] = virtualCloudDb_;
1023     cloudDbs[USER_ID_2] = virtualCloudDb2_;
1024     memoryDB1->SetCloudDB(cloudDbs);
1025     BlockSync(memoryDB1, OK, g_CloudSyncoption, SCHEMA_MISMATCH);
1026     EXPECT_EQ(g_mgr.CloseKvStore(memoryDB1), OK);
1027 }
1028 
1029 /**
1030  * @tc.name: NormalSync023
1031  * @tc.desc: Test normal local delete before cloud delete.
1032  * @tc.type: FUNC
1033  * @tc.require:
1034  * @tc.author: zhangqiquan
1035  */
1036 HWTEST_F(DistributedDBCloudKvTest, NormalSync023, TestSize.Level0)
1037 {
1038     Key k1 = {'k', '1'};
1039     Value v1 = {'v', '1'};
1040     ASSERT_EQ(kvDelegatePtrS1_->Put(k1, v1), OK);
1041     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
1042     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1043     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1044     ASSERT_EQ(kvDelegatePtrS2_->Delete(k1), OK);
1045     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep 100ms
1046     ASSERT_EQ(kvDelegatePtrS1_->Delete(k1), OK);
1047     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1048     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1049 }
1050 
1051 /**
1052  * @tc.name: NormalSync024
1053  * @tc.desc: Test duplicate addition, deletion, and sync.
1054  * @tc.type: FUNC
1055  * @tc.require:
1056  * @tc.author: liaoyonghuang
1057  */
1058 HWTEST_F(DistributedDBCloudKvTest, NormalSync024, TestSize.Level0)
1059 {
1060     /**
1061      * @tc.steps:step1. Device A inserts data and synchronizes, then Device B synchronizes.
1062      * @tc.expected: step1 OK.
1063      */
1064     Key key = {'k'};
1065     Value value = {'v'};
1066     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1067     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1068     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1069     /**
1070      * @tc.steps:step2. Device A deletes data and synchronizes, then Device B synchronizes.
1071      * @tc.expected: step2 OK.
1072      */
1073     ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK);
1074     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1075     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1076     /**
1077      * @tc.steps:step3. Device B inserts data and synchronizes it.
1078      * @tc.expected: step3 OK.
1079      */
1080     int insertNum = 0;
__anon341701840e02(VBucket &record) 1081     virtualCloudDb_->SetInsertHook([&insertNum](VBucket &record) {
1082         insertNum++;
1083     });
1084     ASSERT_EQ(kvDelegatePtrS2_->Put(key, value), OK);
1085     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1086     EXPECT_TRUE(insertNum > 0);
1087     virtualCloudDb_->SetInsertHook(nullptr);
1088 }
1089 
1090 /**
1091  * @tc.name: NormalSync026
1092  * @tc.desc: Test delete when sync mode DEVICE_COLLABORATION.
1093  * @tc.type: FUNC
1094  * @tc.require:
1095  * @tc.author: liaoyonghuang
1096  */
1097 HWTEST_F(DistributedDBCloudKvTest, NormalSync026, TestSize.Level0)
1098 {
1099     /**
1100      * @tc.steps:step1. Create a database with the DEVICE_COLLABORATION mode on device1.
1101      * @tc.expected: step1 OK.
1102      */
1103     KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr;
1104     KvStoreNbDelegate::Option option;
1105     option.conflictResolvePolicy = DEVICE_COLLABORATION;
1106     EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option), OK);
1107     /**
1108      * @tc.steps:step2. put 1 record and sync.
1109      * @tc.expected: step2 OK.
1110      */
1111     Key key = {'k'};
1112     Value expectValue1 = {'v', '1'};
1113     ASSERT_EQ(kvDelegatePtrS3_->Put(key, expectValue1), OK);
1114     BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption);
1115     /**
1116      * @tc.steps:step3. Update this record on device2.
1117      * @tc.expected: step3 OK.
1118      */
1119     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1120     ASSERT_EQ(kvDelegatePtrS1_->Delete(key), OK);
1121     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1122     /**
1123      * @tc.steps:step4. device1 sync.
1124      * @tc.expected: The record was not covered by the cloud and cloud was covered.
1125      */
1126     BlockSync(kvDelegatePtrS3_, OK, g_CloudSyncoption);
1127     Value actualValue1;
1128     EXPECT_EQ(kvDelegatePtrS3_->Get(key, actualValue1), OK);
1129     EXPECT_EQ(actualValue1, expectValue1);
1130     CloseKvStore(kvDelegatePtrS3_, STORE_ID_3);
1131 }
1132 
1133 /**
1134  * @tc.name: NormalSync028
1135  * @tc.desc: Test multi user sync.
1136  * @tc.type: FUNC
1137  * @tc.require:
1138  * @tc.author: caihaoting
1139  */
1140 HWTEST_F(DistributedDBCloudKvTest, NormalSync028, TestSize.Level0)
1141 {
1142     /**
1143      * @tc.steps:step1. put 1 record and sync.
1144      * @tc.expected: step1 OK.
1145      */
1146     Key key = {'k'};
1147     Value value = {'v'};
1148     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1149     auto option = g_CloudSyncoption;
1150     option.users = {USER_ID, USER_ID_2};
1151     BlockSync(kvDelegatePtrS1_, OK, option);
1152     option.users = {USER_ID_2};
1153     BlockSync(kvDelegatePtrS2_, OK, option);
1154     option.users = {USER_ID, USER_ID_2};
1155     BlockSync(kvDelegatePtrS2_, OK, option);
1156     EXPECT_EQ(lastProcess_.tableProcess[USER_ID_2].downLoadInfo.total, 0u);
1157 }
1158 
1159 /**
1160  * @tc.name: NormalSync031
1161  * @tc.desc: Test sync with error local device
1162  * @tc.type: FUNC
1163  * @tc.require:
1164  * @tc.author: zhangqiquan
1165  */
1166 HWTEST_F(DistributedDBCloudKvTest, NormalSync031, TestSize.Level0)
1167 {
1168     /**
1169      * @tc.steps:step1. put 1 record and sync.
1170      * @tc.expected: step1 OK.
1171      */
1172     Key key = {'k'};
1173     Value value = {'v'};
1174     ASSERT_EQ(kvDelegatePtrS2_->Put(key, value), OK);
1175     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1176     /**
1177      * @tc.steps:step2. Set local devices error and sync.
1178      * @tc.expected: step2 sync fail.
1179      */
1180     communicatorAggregator_->MockGetLocalDeviceRes(-E_CLOUD_ERROR);
1181     BlockSync(kvDelegatePtrS1_, CLOUD_ERROR, g_CloudSyncoption);
1182     communicatorAggregator_->MockGetLocalDeviceRes(E_OK);
1183     for (const auto &table : lastProcess_.tableProcess) {
1184         EXPECT_EQ(table.second.downLoadInfo.total, 0u);
1185         EXPECT_EQ(table.second.downLoadInfo.failCount, 0u);
1186         EXPECT_EQ(table.second.upLoadInfo.total, 0u);
1187     }
1188 }
1189 
1190 /**
1191  * @tc.name: NormalSync032
1192  * @tc.desc: Test some record upload fail in 1 batch.
1193  * @tc.type: FUNC
1194  * @tc.require:
1195  * @tc.author: liaoyonghuang
1196  */
1197 HWTEST_F(DistributedDBCloudKvTest, NormalSync032, TestSize.Level0)
1198 {
1199     /**
1200      * @tc.steps:step1. put 10 records.
1201      * @tc.expected: step1 ok.
1202      */
1203     vector<Entry> entries;
1204     int count = 10; // put 10 records.
1205     for (int i = 0; i < count; i++) {
1206         std::string keyStr = "k_" + std::to_string(i);
1207         std::string valueStr = "v_" + std::to_string(i);
1208         Key key(keyStr.begin(), keyStr.end());
1209         Value value(valueStr.begin(), valueStr.end());
1210         entries.push_back({key, value});
1211     }
1212     EXPECT_EQ(kvDelegatePtrS1_->PutBatch(entries), OK);
1213     /**
1214      * @tc.steps:step2. sync and set the last record upload fail.
1215      * @tc.expected: step2 sync fail and upLoadInfo.failCount is 1.
1216      */
1217     int uploadFailId = 0;
1218     virtualCloudDb_->ForkInsertConflict([&uploadFailId](const std::string &tableName, VBucket &extend, VBucket &record,
__anon341701840f02(const std::string &tableName, VBucket &extend, VBucket &record, std::vector<VirtualCloudDb::CloudData> &cloudDataVec) 1219         std::vector<VirtualCloudDb::CloudData> &cloudDataVec) {
1220         uploadFailId++;
1221         if (uploadFailId == 10) { // 10 is the last record
1222             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_ERROR);
1223             return CLOUD_ERROR;
1224         }
1225         return OK;
1226     });
1227     BlockSync(kvDelegatePtrS1_, CLOUD_ERROR, g_CloudSyncoption);
1228     for (const auto &table : lastProcess_.tableProcess) {
1229         EXPECT_EQ(table.second.upLoadInfo.total, 10u);
1230         EXPECT_EQ(table.second.upLoadInfo.successCount, 9u);
1231         EXPECT_EQ(table.second.upLoadInfo.insertCount, 9u);
1232         EXPECT_EQ(table.second.upLoadInfo.failCount, 1u);
1233     }
1234     virtualCloudDb_->ForkUpload(nullptr);
1235 }
1236 
1237 /**
1238  * @tc.name: NormalSync033
1239  * @tc.desc: test sync with different operation type and check upLoadInfo
1240  * @tc.type: FUNC
1241  * @tc.require:
1242  * @tc.author: liaoyonghuang
1243  */
1244 HWTEST_F(DistributedDBCloudKvTest, NormalSync033, TestSize.Level0)
1245 {
1246     /**
1247      * @tc.steps:step1. put local records {k1, v1} {k2, v2} and sync to cloud.
1248      * @tc.expected: step1 ok.
1249      */
1250     Key key1 = {'k', '1'};
1251     Value value1 = {'v', '1'};
1252     kvDelegatePtrS1_->Put(key1, value1);
1253     Key key2 = {'k', '2'};
1254     Value value2 = {'v', '2'};
1255     kvDelegatePtrS1_->Put(key2, value2);
1256     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1257     /**
1258      * @tc.steps:step2. put {k3, v3}, delete {k1, v1}, and put {k2, v3}
1259      * @tc.expected: step2 ok.
1260      */
1261     Key key3 = {'k', '3'};
1262     Value value3 = {'v', '3'};
1263     kvDelegatePtrS1_->Put(key3, value3);
1264     kvDelegatePtrS1_->Delete(key1);
1265     kvDelegatePtrS1_->Put(key2, value3);
1266     /**
1267      * @tc.steps:step3. sync and check upLoadInfo
1268      * @tc.expected: step3 ok.
1269      */
1270     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1271     for (const auto &table : lastProcess_.tableProcess) {
1272         EXPECT_EQ(table.second.upLoadInfo.total, 3u);
1273         EXPECT_EQ(table.second.upLoadInfo.batchIndex, 3u);
1274         EXPECT_EQ(table.second.upLoadInfo.successCount, 3u);
1275         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
1276         EXPECT_EQ(table.second.upLoadInfo.deleteCount, 1u);
1277         EXPECT_EQ(table.second.upLoadInfo.updateCount, 1u);
1278         EXPECT_EQ(table.second.upLoadInfo.failCount, 0u);
1279     }
1280 }
1281 
1282 /**
1283  * @tc.name: NormalSync036
1284  * @tc.desc: test sync data with SetCloudSyncConfig.
1285  * @tc.type: FUNC
1286  * @tc.require:
1287  * @tc.author: caihaoting
1288  */
1289 HWTEST_F(DistributedDBCloudKvTest, NormalSync036, TestSize.Level0)
1290 {
1291     /**
1292      * @tc.steps:step1. put data and SetCloudSyncConfig.
1293      * @tc.expected: step1 ok.
1294      */
1295     CloudSyncConfig config;
1296     int maxUploadCount = 40;
1297     config.maxUploadCount = maxUploadCount;
1298     kvDelegatePtrS1_->SetCloudSyncConfig(config);
1299     Key key = {'k', '1'};
1300     Value value = {'v', '1'};
1301     kvDelegatePtrS1_->Put(key, value);
1302     /**
1303      * @tc.steps:step2. sync.
1304      * @tc.expected: step2 ok.
1305      */
1306     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1307 }
1308 
1309 /**
1310  * @tc.name: NormalSync041
1311  * @tc.desc: Test concurrent sync and close DB.
1312  * @tc.type: FUNC
1313  * @tc.require:
1314  * @tc.author: liaoyonghuang
1315  */
1316 HWTEST_F(DistributedDBCloudKvTest, NormalSync041, TestSize.Level1)
1317 {
1318     /**
1319      * @tc.steps:step1. put data to cloud.
1320      * @tc.expected: step1 ok.
1321      */
1322     Key key = {'k', '1'};
1323     Value value = {'v', '1'};
1324     kvDelegatePtrS1_->Put(key, value);
1325     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1326 
1327     /**
1328      * @tc.steps:step2. sync and close DB concurrently.
1329      * @tc.expected: step2 ok.
1330      */
1331     KvStoreNbDelegate* kvDelegatePtrS3_ = nullptr;
1332     KvStoreNbDelegate::Option option;
1333     EXPECT_EQ(GetKvStore(kvDelegatePtrS3_, STORE_ID_3, option), OK);
__anon341701841002(const std::string &tableName, VBucket &extend) 1334     virtualCloudDb_->ForkQuery([](const std::string &tableName, VBucket &extend) {
1335         std::this_thread::sleep_for(std::chrono::milliseconds(200)); // sleep for 200ms
1336     });
1337     KvStoreDelegateManager &mgr = g_mgr;
__anon341701841102() 1338     std::thread syncThread([&mgr, &kvDelegatePtrS3_]() {
1339         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
1340         EXPECT_EQ(mgr.CloseKvStore(kvDelegatePtrS3_), OK);
1341     });
1342     EXPECT_EQ(kvDelegatePtrS3_->Sync(g_CloudSyncoption, nullptr), OK);
1343     syncThread.join();
1344 }
1345 
1346 /**
1347  * @tc.name: NormalSync045
1348  * @tc.desc: Test some record upload fail in 1 batch and extend size greater than record size
1349  * @tc.type: FUNC
1350  * @tc.require:
1351  * @tc.author: zhangtao
1352  */
1353 HWTEST_F(DistributedDBCloudKvTest, NormalSync045, TestSize.Level0)
1354 {
1355     /**
1356      * @tc.steps:step1. put 10 records.
1357      * @tc.expected: step1 ok.
1358      */
1359     vector<Entry> entries;
1360     int count = 10; // put 10 records.
1361     for (int i = 0; i < count; i++) {
1362         std::string keyStr = "k_" + std::to_string(i);
1363         std::string valueStr = "v_" + std::to_string(i);
1364         Key key(keyStr.begin(), keyStr.end());
1365         Value value(valueStr.begin(), valueStr.end());
1366         entries.push_back({key, value});
1367     }
1368     EXPECT_EQ(kvDelegatePtrS1_->PutBatch(entries), OK);
1369     /**
1370      * @tc.steps:step2. sync and add one empty extend as result
1371      * @tc.expected: step2 sync fail and upLoadInfo.failCount is 10. 1 batch failed.
1372      */
1373     std::atomic<int> missCount = -1;
1374     virtualCloudDb_->SetClearExtend(missCount);
1375     BlockSync(kvDelegatePtrS1_, CLOUD_ERROR, g_CloudSyncoption);
1376     for (const auto &table : lastProcess_.tableProcess) {
1377         EXPECT_EQ(table.second.upLoadInfo.total, 10u);
1378         EXPECT_EQ(table.second.upLoadInfo.successCount, 0u);
1379         EXPECT_EQ(table.second.upLoadInfo.insertCount, 0u);
1380         EXPECT_EQ(table.second.upLoadInfo.failCount, 10u);
1381     }
1382     virtualCloudDb_->ForkUpload(nullptr);
1383 }
1384 
1385 /**
1386  * @tc.name: NormalSync046
1387  * @tc.desc: Test RemoveDeviceData with FLAG_ONLY option and empty deviceName
1388  * @tc.type: FUNC
1389  * @tc.require:
1390  * @tc.author: chenghuitao
1391  */
1392 HWTEST_F(DistributedDBCloudKvTest, NormalSync046, TestSize.Level0)
1393 {
1394     /**
1395      * @tc.steps: step1. store1 put (k1,v1) and (k2,v2)
1396      * @tc.expected: step1. both put ok
1397      */
1398     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
__anon341701841202(const std::string &origin) 1399     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
1400         LOGW("origin is %s", origin.c_str());
1401         return origin + "1";
1402     });
1403     Key key1 = {'k', '1'};
1404     Value expectValue1 = {'v', '1'};
1405     Key key2 = {'k', '2'};
1406     Value expectValue2 = {'v', '2'};
1407     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
1408     ASSERT_EQ(kvDelegatePtrS1_->Put(key2, expectValue2), OK);
1409     /**
1410      * @tc.steps: step2. DEVICE_A with store1 sync and DEVICE_B with store2 sync
1411      * @tc.expected: step2. both sync ok, and store2 got (k1,v1) and (k2,v2)
1412      */
1413     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1414     LOGW("Store1 sync end");
1415     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
1416     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1417     LOGW("Store2 sync end");
1418     Value actualValue;
1419     EXPECT_EQ(kvDelegatePtrS2_->Get(key1, actualValue), OK);
1420     EXPECT_EQ(actualValue, expectValue1);
1421     EXPECT_EQ(kvDelegatePtrS2_->Get(key2, actualValue), OK);
1422     EXPECT_EQ(actualValue, expectValue2);
1423     /**
1424      * @tc.steps: step3. store2 RevoveDeviceData with FLAG_ONLY option
1425      * @tc.expected: step3. store2 delete DEVICE_A's version CloudVersion data successfully
1426      */
1427     auto result = kvDelegatePtrS2_->GetCloudVersion("");
1428     EXPECT_EQ(result.first, OK);
1429     for (auto item : result.second) {
1430         EXPECT_EQ(item.second, "1");
1431     }
1432     EXPECT_EQ(kvDelegatePtrS2_->RemoveDeviceData("", ClearMode::FLAG_ONLY), OK);
1433     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
1434     result = kvDelegatePtrS2_->GetCloudVersion("");
1435     EXPECT_EQ(result.first, NOT_FOUND);
1436     for (auto item : result.second) {
1437         EXPECT_EQ(item.second, "");
1438     }
1439 }
1440 
1441 /**
1442  * @tc.name: NormalSync047
1443  * @tc.desc: Test multi users sync when user1 sync fail.
1444  * @tc.type: FUNC
1445  * @tc.require:
1446  * @tc.author: suyue
1447  */
1448 HWTEST_F(DistributedDBCloudKvTest, NormalSync047, TestSize.Level0)
1449 {
1450     /**
1451      * @tc.steps: step1. put 20 records.
1452      * @tc.expected: step1. ok.
1453      */
1454     vector<Entry> entries;
1455     int count = 20; // put 20 records.
1456     for (int i = 0; i < count; i++) {
1457         std::string keyStr = "k_" + std::to_string(i);
1458         std::string valueStr = "v_" + std::to_string(i);
1459         Key key(keyStr.begin(), keyStr.end());
1460         Value value(valueStr.begin(), valueStr.end());
1461         entries.push_back({key, value});
1462     }
1463     EXPECT_EQ(kvDelegatePtrS1_->PutBatch(entries), OK);
1464 
1465     /**
1466      * @tc.steps: step2. multi users sync and set user1 fail.
1467      * @tc.expected: step2. user1 sync fail and other user sync success.
1468      */
1469     int uploadFailId = 0;
1470     virtualCloudDb_->ForkInsertConflict([&uploadFailId](const std::string &tableName, VBucket &extend, VBucket &record,
__anon341701841302(const std::string &tableName, VBucket &extend, VBucket &record, vector<VirtualCloudDb::CloudData> &cloudDataVec) 1471         vector<VirtualCloudDb::CloudData> &cloudDataVec) {
1472         uploadFailId++;
1473         if (uploadFailId > 15) { // the first 15 records success
1474             extend[CloudDbConstant::ERROR_FIELD] = static_cast<int64_t>(DBStatus::CLOUD_ERROR);
1475             return CLOUD_ERROR;
1476         }
1477         return OK;
1478     });
1479     CloudSyncOption option;
1480     option.mode = SyncMode::SYNC_MODE_CLOUD_FORCE_PUSH;
1481     option.users.push_back(USER_ID);
1482     option.users.push_back(USER_ID_2);
1483     option.devices.push_back("cloud");
1484     SyncAndGetProcessInfo(kvDelegatePtrS1_, option);
1485 
1486     vector<DBStatus> userStatus = {CLOUD_ERROR, OK};
1487     vector<Info> userExpectInfo = {{1u, 20u, 15u, 5u, 15u, 0u, 0u}, {1u, 20u, 20u, 0u, 20u, 0u, 0u}};
1488     EXPECT_TRUE(CheckUserSyncInfo(option.users, userStatus, userExpectInfo));
1489     virtualCloudDb_->ForkUpload(nullptr);
1490 }
1491 
1492 /**
1493  * @tc.name: NormalSync048
1494  * @tc.desc: test sync data while cloud delete on record and local do not have this record.
1495  * @tc.type: FUNC
1496  * @tc.require:
1497  * @tc.author: tankaisheng
1498  */
1499 HWTEST_F(DistributedDBCloudKvTest, NormalSync048, TestSize.Level0)
1500 {
1501     /**
1502      * @tc.steps: step1. deviceB put {k1, v1} {k2, v2} and sync to cloud
1503      * @tc.expected: step1. ok.
1504      */
1505     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
1506     Key key1 = {'k', '1'};
1507     Value expectValue1 = {'v', '1'};
1508     Key key2 = {'k', '2'};
1509     Value expectValue2 = {'v', '2'};
1510     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
1511     ASSERT_EQ(kvDelegatePtrS1_->Put(key2, expectValue2), OK);
1512     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1513 
1514     /**
1515      * @tc.steps: step2. deviceB delete {k1, v1} and sync to cloud
1516      * @tc.expected: step2. ok.
1517      */
1518     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
1519     ASSERT_EQ(kvDelegatePtrS1_->Delete(key1), OK);
1520     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
1521 
1522     /**
1523      * @tc.steps: step3. deviceA sync to cloud
1524      * @tc.expected: step3. ok.
1525      */
1526     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
1527     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1528     Value actualValue2;
1529     ASSERT_EQ(kvDelegatePtrS2_->Get(key2, actualValue2), OK);
1530     ASSERT_EQ(actualValue2, expectValue2);
1531 }
1532 
1533 /**
1534  * @tc.name: SyncOptionCheck001
1535  * @tc.desc: Test sync without user.
1536  * @tc.type: FUNC
1537  * @tc.require:
1538  * @tc.author: liaoyonghuang
1539  */
1540 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck001, TestSize.Level0)
1541 {
1542     /**
1543      * @tc.steps:step1. Device 1 inserts a piece of data.
1544      * @tc.expected: step1 OK.
1545      */
1546     Key key = {'k'};
1547     Value value = {'v'};
1548     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1549     /**
1550      * @tc.steps:step2. Set option without user, and attempt to sync
1551      * @tc.expected: step2 return INVALID_ARGS.
1552      */
1553     CloudSyncOption option;
1554     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
1555     option.devices.push_back("cloud");
1556     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
1557     /**
1558      * @tc.steps:step3. Device 2 sync and attempt to get data.
1559      * @tc.expected: step3 sync OK but data NOT_FOUND.
1560      */
1561     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1562     Value actualValue;
1563     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
1564 }
1565 
1566 /**
1567  * @tc.name: SyncOptionCheck002
1568  * @tc.desc: Test sync with invalid waitTime.
1569  * @tc.type: FUNC
1570  * @tc.require:
1571  * @tc.author: liaoyonghuang
1572  */
1573 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck002, TestSize.Level0)
1574 {
1575     /**
1576      * @tc.steps:step1. Device 1 inserts a piece of data.
1577      * @tc.expected: step1 OK.
1578      */
1579     Key key = {'k'};
1580     Value value = {'v'};
1581     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1582     /**
1583      * @tc.steps:step2. Set invalid waitTime of sync option and sync.
1584      * @tc.expected: step2 return INVALID_ARGS.
1585      */
1586     CloudSyncOption option;
1587     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
1588     option.users.push_back(USER_ID);
1589     option.devices.push_back("cloud");
1590     option.waitTime = -2; // -2 is invalid waitTime.
1591     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
1592     /**
1593      * @tc.steps:step3. Device 2 sync and attempt to get data.
1594      * @tc.expected: step3 sync OK but data NOT_FOUND.
1595      */
1596     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1597     Value actualValue;
1598     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
1599 }
1600 
1601 /**
1602  * @tc.name: SyncOptionCheck003
1603  * @tc.desc: Test sync with users which have not been sync to cloud.
1604  * @tc.type: FUNC
1605  * @tc.require:
1606  * @tc.author: liaoyonghuang
1607  */
1608 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck003, TestSize.Level0)
1609 {
1610     /**
1611      * @tc.steps:step1. Device 1 inserts a piece of data.
1612      * @tc.expected: step1 OK.
1613      */
1614     Key key = {'k'};
1615     Value value = {'v'};
1616     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1617     /**
1618      * @tc.steps:step2. Set user1 and user3 to option and sync.
1619      * @tc.expected: step2 return INVALID_ARGS.
1620      */
1621     CloudSyncOption option;
1622     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
1623     option.users.push_back(USER_ID);
1624     option.users.push_back(USER_ID_3);
1625     option.devices.push_back("cloud");
1626     BlockSync(kvDelegatePtrS1_, OK, option, INVALID_ARGS);
1627     /**
1628      * @tc.steps:step3. Device 2 sync and attempt to get data.
1629      * @tc.expected: step3 sync OK but data NOT_FOUND.
1630      */
1631     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
1632     Value actualValue;
1633     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), NOT_FOUND);
1634 }
1635 
1636 /**
1637  * @tc.name: SyncOptionCheck004
1638  * @tc.desc: Test sync with user when schema is not same.
1639  * @tc.type: FUNC
1640  * @tc.require:
1641  * @tc.author: caihaoting
1642  */
1643 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck004, TestSize.Level0)
1644 {
1645     /**
1646      * @tc.steps:step1. Device 1 inserts a piece of data.
1647      * @tc.expected: step1 OK.
1648      */
1649     Key key = {'k'};
1650     Value value = {'v'};
1651     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1652     /**
1653      * @tc.steps:step2. Set user1 to option and user2 to schema and sync.
1654      * @tc.expected: step2 return SCHEMA_MISMATCH.
1655      */
1656     CloudSyncOption option;
1657     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
1658     option.users.push_back(USER_ID);
1659     option.devices.push_back("cloud");
1660     std::map<std::string, DataBaseSchema> schemas;
1661     schemas[USER_ID_2] = GetDataBaseSchema(false);
1662     kvDelegatePtrS1_->SetCloudDbSchema(schemas);
1663     BlockSync(kvDelegatePtrS1_, OK, option, SCHEMA_MISMATCH);
1664 }
1665 
1666 /**
1667  * @tc.name: SyncOptionCheck005
1668  * @tc.desc: Testing registration of observer exceeded the upper limit.
1669  * @tc.type: FUNC
1670  * @tc.require:
1671  * @tc.author: liaoyonghuang
1672  */
1673 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck005, TestSize.Level0)
1674 {
1675     /**
1676      * @tc.steps:step1. Register MAX_OBSERVER_COUNT observers.
1677      * @tc.expected: step1 OK.
1678      */
1679     std::vector<KvStoreObserverUnitTest *> observerList;
1680     for (int i = 0; i < DBConstant::MAX_OBSERVER_COUNT; i++) {
1681         auto *observer = new (std::nothrow) KvStoreObserverUnitTest;
1682         observerList.push_back(observer);
1683         EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, observer), OK);
1684     }
1685     /**
1686      * @tc.steps:step2. Register one more observer.
1687      * @tc.expected: step2 Registration failed, return OVER_MAX_LIMITS.
1688      */
1689     auto *overMaxObserver = new (std::nothrow) KvStoreObserverUnitTest;
1690     EXPECT_EQ(kvDelegatePtrS1_->RegisterObserver({}, OBSERVER_CHANGES_CLOUD, overMaxObserver), OVER_MAX_LIMITS);
1691     /**
1692      * @tc.steps:step3. UnRegister all observers.
1693      * @tc.expected: step3 OK.
1694      */
1695     EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(overMaxObserver), NOT_FOUND);
1696     delete overMaxObserver;
1697     overMaxObserver = nullptr;
1698     for (auto &observer : observerList) {
1699         EXPECT_EQ(kvDelegatePtrS1_->UnRegisterObserver(observer), OK);
1700         delete observer;
1701         observer = nullptr;
1702     }
1703 }
1704 
1705 /**
1706  * @tc.name: SyncOptionCheck008
1707  * @tc.desc: Test kv sync with query InKeys.
1708  * @tc.type: FUNC
1709  * @tc.require:
1710  * @tc.author: luoguo
1711  */
1712 HWTEST_F(DistributedDBCloudKvTest, SyncOptionCheck008, TestSize.Level0)
1713 {
1714     /**
1715      * @tc.steps:step1. Device 1 inserts a piece of data.
1716      * @tc.expected: step1 OK.
1717      */
1718     Key key = {'k'};
1719     Value value = {'v'};
1720     ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
1721     /**
1722      * @tc.steps:step2. Set query to option sync.
1723      * @tc.expected: step2 return OK.
1724      */
1725     std::set<Key> keys;
1726     CloudSyncOption option;
1727     option.query = Query::Select().InKeys(keys);
1728     option.mode = SyncMode::SYNC_MODE_CLOUD_MERGE;
1729     option.users.push_back(USER_ID);
1730     option.users.push_back(USER_ID);
1731     option.devices.push_back("cloud");
1732     BlockSync(kvDelegatePtrS1_, OK, option, OK);
1733 }
1734 
SetFlag(const Key & key,LogInfoFlag flag)1735 void DistributedDBCloudKvTest::SetFlag(const Key &key, LogInfoFlag flag)
1736 {
1737     sqlite3 *db_;
1738     uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1739     std::string fileUrl = g_testDir + "/" \
1740         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1741     ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr) == SQLITE_OK);
1742     int errCode = E_OK;
1743     std::string sql = "UPDATE sync_data SET flag=? WHERE Key=?";
1744     sqlite3_stmt *statement = nullptr;
1745     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1746     if (errCode != E_OK) {
1747         SQLiteUtils::ResetStatement(statement, true, errCode);
1748     }
1749     ASSERT_EQ(errCode, E_OK);
1750     errCode = SQLiteUtils::BindInt64ToStatement(statement, 1, static_cast<int64_t>(flag)); // 1st arg.
1751     ASSERT_EQ(errCode, E_OK);
1752     errCode = SQLiteUtils::BindBlobToStatement(statement, 2, key, true); // 2nd arg.
1753     ASSERT_EQ(errCode, E_OK);
1754     if (errCode != E_OK) {
1755         SQLiteUtils::ResetStatement(statement, true, errCode);
1756     }
1757     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1758     SQLiteUtils::ResetStatement(statement, true, errCode);
1759     EXPECT_EQ(errCode, E_OK);
1760     sqlite3_close_v2(db_);
1761 }
1762 
CheckFlag(const Key & key,LogInfoFlag flag)1763 int DistributedDBCloudKvTest::CheckFlag(const Key &key, LogInfoFlag flag)
1764 {
1765     sqlite3 *db_;
1766     uint64_t openFlag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1767     std::string fileUrl = g_testDir + "/" \
1768         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1769     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, openFlag, nullptr);
1770     if (errCode != E_OK) {
1771         return NOT_FOUND;
1772     }
1773     std::string sql = "SELECT * FROM sync_data WHERE Key =? AND (flag=?)";
1774     sqlite3_stmt *statement = nullptr;
1775     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1776     if (errCode != E_OK) {
1777         SQLiteUtils::ResetStatement(statement, true, errCode);
1778         return NOT_FOUND;
1779     }
1780     std::vector<uint8_t> keyVec(key.begin(), key.end());
1781     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // 1st arg.
1782     if (errCode != E_OK) {
1783         SQLiteUtils::ResetStatement(statement, true, errCode);
1784         return NOT_FOUND;
1785     }
1786     errCode = SQLiteUtils::BindInt64ToStatement(statement, 2, static_cast<int64_t>(flag)); // 2nd arg.
1787     if (errCode != E_OK) {
1788         SQLiteUtils::ResetStatement(statement, true, errCode);
1789         return NOT_FOUND;
1790     }
1791     errCode = SQLiteUtils::StepWithRetry(statement);
1792     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1793         SQLiteUtils::ResetStatement(statement, true, errCode);
1794         sqlite3_close_v2(db_);
1795         return NOT_FOUND; // cant find.
1796     }
1797     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1798         SQLiteUtils::ResetStatement(statement, true, errCode);
1799         sqlite3_close_v2(db_);
1800         return OK;
1801     }
1802     SQLiteUtils::ResetStatement(statement, true, errCode);
1803     EXPECT_EQ(errCode, E_OK);
1804     sqlite3_close_v2(db_);
1805     return NOT_FOUND;
1806 }
1807 
CheckWaterMark(const std::string & user)1808 int DistributedDBCloudKvTest::CheckWaterMark(const std::string &user)
1809 {
1810     sqlite3 *db_;
1811     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1812     std::string fileUrl = g_testDir + "/" \
1813         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1814     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
1815     if (errCode != E_OK) {
1816         return NOT_FOUND;
1817     }
1818     std::string sql;
1819     if (user.empty()) {
1820         sql = "SELECT * FROM meta_data WHERE KEY LIKE 'naturalbase_cloud_meta_sync_data_%'";
1821     } else {
1822         sql = "SELECT * FROM meta_data WHERE KEY =?;";
1823     }
1824     sqlite3_stmt *statement = nullptr;
1825     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1826     if (errCode != E_OK) {
1827         SQLiteUtils::ResetStatement(statement, true, errCode);
1828         return NOT_FOUND;
1829     }
1830     if (!user.empty()) {
1831         std::string waterMarkKey = HWM_HEAD + user;
1832         std::vector<uint8_t> keyVec(waterMarkKey.begin(), waterMarkKey.end());
1833         errCode = SQLiteUtils::BindBlobToStatement(statement, 1, keyVec, true); // only one arg.
1834         if (errCode != E_OK) {
1835             SQLiteUtils::ResetStatement(statement, true, errCode);
1836             return NOT_FOUND;
1837         }
1838     }
1839     errCode = SQLiteUtils::StepWithRetry(statement);
1840     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1841         SQLiteUtils::ResetStatement(statement, true, errCode);
1842         sqlite3_close_v2(db_);
1843         return NOT_FOUND; // cant find.
1844     }
1845     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1846         SQLiteUtils::ResetStatement(statement, true, errCode);
1847         sqlite3_close_v2(db_);
1848         return OK;
1849     }
1850     SQLiteUtils::ResetStatement(statement, true, errCode);
1851     EXPECT_EQ(errCode, E_OK);
1852     sqlite3_close_v2(db_);
1853     return NOT_FOUND;
1854 }
1855 
SetDeviceId(const Key & key,const std::string & deviceId)1856 void DistributedDBCloudKvTest::SetDeviceId(const Key &key, const std::string &deviceId)
1857 {
1858     sqlite3 *db_;
1859     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1860     std::string fileUrl = g_testDir + "/" \
1861         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1862     ASSERT_TRUE(sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr) == SQLITE_OK);
1863     int errCode = E_OK;
1864     std::string sql = "UPDATE sync_data SET device=? WHERE Key=?";
1865     sqlite3_stmt *statement = nullptr;
1866     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1867     if (errCode != E_OK) {
1868         SQLiteUtils::ResetStatement(statement, true, errCode);
1869     }
1870     ASSERT_EQ(errCode, E_OK);
1871     std::string hashDevice = DBCommon::TransferHashString(deviceId);
1872     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
1873     int bindIndex = 1;
1874     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, deviceIdVec, true); // only one arg.
1875     ASSERT_EQ(errCode, E_OK);
1876     if (errCode != E_OK) {
1877         SQLiteUtils::ResetStatement(statement, true, errCode);
1878     }
1879     bindIndex++;
1880     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, key, true); // only one arg.
1881     if (errCode != E_OK) {
1882         SQLiteUtils::ResetStatement(statement, true, errCode);
1883     }
1884     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1885     SQLiteUtils::ResetStatement(statement, true, errCode);
1886     EXPECT_EQ(errCode, E_OK);
1887     sqlite3_close_v2(db_);
1888 }
1889 
CheckLogTable(const std::string & deviceId)1890 int DistributedDBCloudKvTest::CheckLogTable(const std::string &deviceId)
1891 {
1892     sqlite3 *db_;
1893     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1894     std::string fileUrl = g_testDir + "/" \
1895         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1896     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
1897     if (errCode != E_OK) {
1898         return NOT_FOUND;
1899     }
1900     std::string sql = "SELECT * FROM naturalbase_kv_aux_sync_data_log WHERE hash_key IN" \
1901         "(SELECT hash_key FROM sync_data WHERE device =?);";
1902     sqlite3_stmt *statement = nullptr;
1903     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1904     if (errCode != E_OK) {
1905         SQLiteUtils::ResetStatement(statement, true, errCode);
1906         return NOT_FOUND;
1907     }
1908     std::string hashDevice = DBCommon::TransferHashString(deviceId);
1909     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
1910     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, deviceIdVec, true); // only one arg.
1911     if (errCode != E_OK) {
1912         SQLiteUtils::ResetStatement(statement, true, errCode);
1913         return NOT_FOUND;
1914     }
1915     errCode = SQLiteUtils::StepWithRetry(statement);
1916     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1917         SQLiteUtils::ResetStatement(statement, true, errCode);
1918         sqlite3_close_v2(db_);
1919         return NOT_FOUND; // cant find.
1920     }
1921     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) {
1922         SQLiteUtils::ResetStatement(statement, true, errCode);
1923         sqlite3_close_v2(db_);
1924         return OK;
1925     }
1926     SQLiteUtils::ResetStatement(statement, true, errCode);
1927     EXPECT_EQ(errCode, E_OK);
1928     sqlite3_close_v2(db_);
1929     return NOT_FOUND;
1930 }
1931 
ChangeUserId(const std::string & deviceId,const std::string & wantUserId)1932 int DistributedDBCloudKvTest::ChangeUserId(const std::string &deviceId, const std::string &wantUserId)
1933 {
1934     sqlite3 *db_;
1935     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1936     std::string fileUrl = g_testDir + "/" \
1937         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1938     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
1939     if (errCode != E_OK) {
1940         return INVALID_ARGS;
1941     }
1942     std::string sql = "UPDATE naturalbase_kv_aux_sync_data_log SET userid =? WHERE hash_key IN" \
1943         "(SELECT hash_key FROM sync_data WHERE device =? AND (flag=0x100));";
1944     sqlite3_stmt *statement = nullptr;
1945     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1946     if (errCode != E_OK) {
1947         SQLiteUtils::ResetStatement(statement, true, errCode);
1948         return INVALID_ARGS;
1949     }
1950     int bindIndex = 1;
1951     errCode = SQLiteUtils::BindTextToStatement(statement, bindIndex, wantUserId); // only one arg.
1952     if (errCode != E_OK) {
1953         SQLiteUtils::ResetStatement(statement, true, errCode);
1954         return INVALID_ARGS;
1955     }
1956     bindIndex++;
1957     std::string hashDevice = DBCommon::TransferHashString(deviceId);
1958     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
1959     errCode = SQLiteUtils::BindBlobToStatement(statement, bindIndex, deviceIdVec, true); // only one arg.
1960     if (errCode != E_OK) {
1961         SQLiteUtils::ResetStatement(statement, true, errCode);
1962         return INVALID_ARGS;
1963     }
1964     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
1965     SQLiteUtils::ResetStatement(statement, true, errCode);
1966     EXPECT_EQ(errCode, E_OK);
1967     sqlite3_close_v2(db_);
1968     return INVALID_ARGS;
1969 }
1970 
ChangeHashKey(const std::string & deviceId)1971 int DistributedDBCloudKvTest::ChangeHashKey(const std::string &deviceId)
1972 {
1973     sqlite3 *db_;
1974     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
1975     std::string fileUrl = g_testDir + "/" \
1976         "2d23c8a0ffadafcaa03507a4ec2290c83babddcab07c0e2945fbba93efc7eec0/single_ver/main/gen_natural_store.db";
1977     int errCode = sqlite3_open_v2(fileUrl.c_str(), &db_, flag, nullptr);
1978     if (errCode != E_OK) {
1979         return INVALID_ARGS;
1980     }
1981     std::string updataLogTableSql = "UPDATE naturalbase_kv_aux_sync_data_log SET hash_Key ='99';";
1982     sqlite3_stmt *statement = nullptr;
1983     errCode = SQLiteUtils::GetStatement(db_, updataLogTableSql, statement);
1984     if (errCode != E_OK) {
1985         SQLiteUtils::ResetStatement(statement, true, errCode);
1986         return INVALID_ARGS;
1987     }
1988     errCode = SQLiteUtils::StepWithRetry(statement);
1989     if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) {
1990         SQLiteUtils::ResetStatement(statement, true, errCode);
1991     }
1992 
1993     std::string sql = "UPDATE sync_data SET hash_Key ='99' WHERE device =? AND (flag=0x100);";
1994     errCode = SQLiteUtils::GetStatement(db_, sql, statement);
1995     if (errCode != E_OK) {
1996         SQLiteUtils::ResetStatement(statement, true, errCode);
1997         return INVALID_ARGS;
1998     }
1999     std::string hashDevice = DBCommon::TransferHashString(deviceId);
2000     std::vector<uint8_t> deviceIdVec(hashDevice.begin(), hashDevice.end());
2001     errCode = SQLiteUtils::BindBlobToStatement(statement, 1, deviceIdVec, true); // only one arg.
2002     if (errCode != E_OK) {
2003         SQLiteUtils::ResetStatement(statement, true, errCode);
2004         sqlite3_close_v2(db_);
2005         return OK; // cant find.
2006     }
2007     EXPECT_EQ(SQLiteUtils::StepWithRetry(statement), SQLiteUtils::MapSQLiteErrno(SQLITE_DONE));
2008     SQLiteUtils::ResetStatement(statement, true, errCode);
2009     EXPECT_EQ(errCode, E_OK);
2010     sqlite3_close_v2(db_);
2011     return INVALID_ARGS;
2012 }
2013 
InsertRecord(int num)2014 void DistributedDBCloudKvTest::InsertRecord(int num)
2015 {
2016     for (int i = 0; i < num; i++) {
2017         Key key;
2018         key.push_back('k');
2019         key.push_back('0' + i);
2020         Value value;
2021         value.push_back('k');
2022         value.push_back('0' + i);
2023         ASSERT_EQ(kvDelegatePtrS1_->Put(key, value), OK);
2024         BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
2025         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2026         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2027     }
2028 }
2029 
2030 /**
2031  * @tc.name: RemoveDeviceTest001
2032  * @tc.desc: remove all log table record with empty deviceId and FLAG_ONLY flag
2033  * @tc.type: FUNC
2034  * @tc.require:
2035  * @tc.author: mazhao
2036  */
2037 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest001, TestSize.Level0)
2038 {
2039     /**
2040      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
2041      * (Key:k2, device:2, userId:0)
2042      * * @tc.expected: step1. insert successfully
2043     */
2044     int recordNum = 3;
2045     InsertRecord(recordNum);
2046     for (int i = 0; i < recordNum; i++) {
2047         Key key;
2048         key.push_back('k');
2049         key.push_back('0' + i);
2050         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2051         SetDeviceId(key, std::to_string(i));
2052         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2053     }
2054     /**
2055      * @tc.steps: step2. Check three Log record whether exist or not;
2056      * * @tc.expected: step2. record exist
2057     */
2058     for (int i = 0; i < recordNum; i++) {
2059         Key key;
2060         key.push_back('k');
2061         key.push_back('0' + i);
2062         Value actualValue;
2063         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2064         std::string deviceId = std::to_string(i);
2065         EXPECT_EQ(CheckLogTable(deviceId), OK);
2066         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
2067         EXPECT_EQ(CheckWaterMark(""), OK);
2068     }
2069     /**
2070      * @tc.steps: step3. remove log data with empty deviceId.
2071      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
2072     */
2073     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_ONLY), OK);
2074     for (int i = 0; i < recordNum; i++) {
2075         Key key;
2076         key.push_back('k');
2077         key.push_back('0' + i);
2078         Value actualValue;
2079         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2080         std::string deviceId = std::to_string(i);
2081         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
2082         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_LOCAL), OK);
2083         EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
2084     }
2085 }
2086 
2087 /**
2088  * @tc.name: RemoveDeviceTest002
2089  * @tc.desc: remove all record with empty deviceId and FLAG_AND_DATA flag
2090  * @tc.type: FUNC
2091  * @tc.require:
2092  * @tc.author: mazhao
2093  */
2094 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest002, TestSize.Level0)
2095 {
2096     /**
2097      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
2098      * (Key:k2, device:2, userId:0)
2099      * * @tc.expected: step1. insert successfully
2100     */
2101     int recordNum = 3;
2102     InsertRecord(recordNum);
2103     for (int i = 0; i < recordNum; i++) {
2104         Key key;
2105         key.push_back('k');
2106         key.push_back('0' + i);
2107         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2108         SetDeviceId(key, std::to_string(i));
2109         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2110     }
2111     /**
2112      * @tc.steps: step2. Check three Log record whether exist or not;
2113      * * @tc.expected: step2. record exist
2114     */
2115     for (int i = 0; i < recordNum; i++) {
2116         Key key;
2117         key.push_back('k');
2118         key.push_back('0' + i);
2119         Value actualValue;
2120         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2121         std::string deviceId = std::to_string(i);
2122         EXPECT_EQ(CheckLogTable(deviceId), OK);
2123         EXPECT_EQ(CheckWaterMark(""), OK);
2124     }
2125     /**
2126      * @tc.steps: step3. remove log data with empty deviceId.
2127      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
2128     */
2129     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::FLAG_AND_DATA), OK);
2130     for (int i = 0; i < recordNum; i++) {
2131         Key key;
2132         key.push_back('k');
2133         key.push_back('0' + i);
2134         Value actualValue;
2135         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), NOT_FOUND);
2136         std::string deviceId = std::to_string(i);
2137         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
2138         EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
2139     }
2140 }
2141 
2142 /**
2143  * @tc.name: RemoveDeviceTest003
2144  * @tc.desc: remove record with deviceId
2145  * @tc.type: FUNC
2146  * @tc.require:
2147  * @tc.author: mazhao
2148  */
2149 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest003, TestSize.Level0)
2150 {
2151     /**
2152      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user0),
2153      * (Key:k2, device:2, userId:0)
2154      * * @tc.expected: step1. insert successfully
2155     */
2156     int recordNum = 3;
2157     InsertRecord(recordNum);
2158     for (int i = 0; i < recordNum; i++) {
2159         Key key;
2160         key.push_back('k');
2161         key.push_back('0' + i);
2162         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2163         SetDeviceId(key, std::to_string(i));
2164         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2165     }
2166     /**
2167      * @tc.steps: step2. Check three Log record whether exist or not;
2168      * * @tc.expected: step2. record exist
2169     */
2170     for (int i = 0; i < recordNum; i++) {
2171         Key key;
2172         key.push_back('k');
2173         key.push_back('0' + i);
2174         Value actualValue;
2175         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2176         std::string deviceId = std::to_string(i);
2177         EXPECT_EQ(CheckLogTable(deviceId), OK);
2178         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag become 0x2;
2179         EXPECT_EQ(CheckWaterMark(""), OK);
2180     }
2181     /**
2182      * @tc.steps: step3. remove "2" deviceId log data with FLAG_AND_DATA, remove "1" with FLAG_ONLY.
2183      * * @tc.expected: step3. remove OK
2184     */
2185     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("1", ClearMode::FLAG_ONLY), OK);
2186     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("2", ClearMode::FLAG_AND_DATA), OK);
2187     Key key1({'k', '1'});
2188     std::string deviceId1 = "1";
2189     Value actualValue;
2190     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
2191     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
2192     EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
2193     Key key2({'k', '2'});
2194     std::string deviceId2 = "2";
2195     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
2196     EXPECT_EQ(CheckLogTable(deviceId2), NOT_FOUND);
2197     EXPECT_EQ(CheckWaterMark(""), NOT_FOUND);
2198 }
2199 
2200 /**
2201  * @tc.name: RemoveDeviceTest004
2202  * @tc.desc: remove all record with userId and empty deviceId.
2203  * @tc.type: FUNC
2204  * @tc.require:
2205  * @tc.author: mazhao
2206  */
2207 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest004, TestSize.Level0)
2208 {
2209     /**
2210      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
2211      * (Key:k2, device:2, userId:2)
2212      * * @tc.expected: step1. insert successfully
2213     */
2214     int recordNum = 3;
2215     std::string userHead = "user";
2216     InsertRecord(recordNum);
2217     for (int i = 0; i < recordNum; i++) {
2218         Key key;
2219         key.push_back('k');
2220         key.push_back('0' + i);
2221         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2222         SetDeviceId(key, std::to_string(i));
2223         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
2224         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2225         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
2226     }
2227     EXPECT_EQ(CheckWaterMark(userHead + "0"), OK);
2228     /**
2229      * @tc.steps: step2. Check three Log record whether exist or not;
2230      * * @tc.expected: step2. record exist
2231     */
2232     for (int i = 0; i < recordNum; i++) {
2233         Key key;
2234         key.push_back('k');
2235         key.push_back('0' + i);
2236         Value actualValue;
2237         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2238         std::string deviceId = std::to_string(i);
2239         EXPECT_EQ(CheckLogTable(deviceId), OK);
2240     }
2241     /**
2242      * @tc.steps: step3. remove "user1" userid log data with FLAG_AND_DATA, remove "user2" userid with FLAG_ONLY.
2243      * * @tc.expected: step3. remove OK
2244     */
2245     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "user0", ClearMode::FLAG_ONLY), OK);
2246     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "user2", ClearMode::FLAG_AND_DATA), OK);
2247     Key key0({'k', '0'});
2248     std::string deviceId1 = "0";
2249     Value actualValue;
2250     EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK);
2251     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
2252     EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
2253     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
2254     Key key2({'k', '2'});
2255     std::string deviceId2 = "2";
2256     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
2257     EXPECT_EQ(CheckLogTable(deviceId2), NOT_FOUND);
2258 }
2259 
2260 /**
2261  * @tc.name: RemoveDeviceTest005
2262  * @tc.desc: remove record with userId and deviceId.
2263  * @tc.type: FUNC
2264  * @tc.require:
2265  * @tc.author: mazhao
2266  */
2267 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest005, TestSize.Level0)
2268 {
2269     /**
2270      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
2271      * (Key:k2, device:2, userId:2)
2272      * * @tc.expected: step1. insert successfully
2273     */
2274     int recordNum = 3;
2275     InsertRecord(recordNum);
2276     std::string userHead = "user";
2277     for (int i = 0; i < recordNum; i++) {
2278         Key key;
2279         key.push_back('k');
2280         key.push_back('0' + i);
2281         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2282         SetDeviceId(key, std::to_string(i));
2283         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
2284         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2285     }
2286     EXPECT_EQ(CheckWaterMark(userHead + "0"), OK);
2287     /**
2288      * @tc.steps: step2. Check three Log record whether exist or not;
2289      * * @tc.expected: step2. record exist
2290     */
2291     for (int i = 0; i < recordNum; i++) {
2292         Key key;
2293         key.push_back('k');
2294         key.push_back('0' + i);
2295         Value actualValue;
2296         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2297         std::string deviceId = std::to_string(i);
2298         EXPECT_EQ(CheckLogTable(deviceId), OK);
2299         EXPECT_EQ(CheckFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE), OK);
2300     }
2301     /**
2302      * @tc.steps: step3. remove "user1" userid log data with FLAG_AND_DATA, remove "user0" userid with FLAG_ONLY.
2303      * remove "user2" userid log data with dismatch deviceId, it cant not remove the data.
2304      * * @tc.expected: step3. remove OK
2305     */
2306     std::string deviceId0 = "0";
2307     std::string deviceId1 = "1";
2308     std::string deviceId2 = "2";
2309     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user0", ClearMode::FLAG_ONLY), OK);
2310     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user1", ClearMode::FLAG_AND_DATA), OK);
2311     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user2", ClearMode::FLAG_AND_DATA), OK);
2312     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId0, "user2", ClearMode::FLAG_ONLY), OK);
2313     Key key0({'k', '0'});
2314     Value actualValue;
2315     EXPECT_EQ(kvDelegatePtrS1_->Get(key0, actualValue), OK);
2316     EXPECT_EQ(CheckLogTable(deviceId0), NOT_FOUND);
2317     EXPECT_EQ(CheckFlag(key0, LogInfoFlag::FLAG_LOCAL), OK); // flag become 0x2;
2318     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
2319     Key key1({'k', '1'});
2320     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND);
2321     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
2322     Key key2({'k', '2'});;
2323     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), OK);
2324     EXPECT_EQ(CheckLogTable(deviceId2), OK);
2325 }
2326 
2327 /**
2328  * @tc.name: RemoveDeviceTest006
2329  * @tc.desc: remove record with userId and deviceId, and there are same hashKey record in log table.
2330  * @tc.type: FUNC
2331  * @tc.require:
2332  * @tc.author: mazhao
2333  */
2334 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest006, TestSize.Level0)
2335 {
2336     /**
2337      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
2338      * (Key:k2, device:2, userId:2)
2339      * * @tc.expected: step1. insert successfully
2340     */
2341     int recordNum = 3;
2342     InsertRecord(recordNum);
2343     std::string userHead = "user";
2344     for (int i = 0; i < recordNum; i++) {
2345         Key key;
2346         key.push_back('k');
2347         key.push_back('0' + i);
2348         SetFlag(key, LogInfoFlag::FLAG_CLOUD_WRITE);
2349         SetDeviceId(key, std::to_string(i));
2350         ChangeUserId(std::to_string(i), userHead + std::to_string(i));
2351         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2352     }
2353     /**
2354      * @tc.steps: step2. Check three Log record whether exist or not;
2355      * * @tc.expected: step2. record exist
2356     */
2357     for (int i = 0; i < recordNum; i++) {
2358         Key key;
2359         key.push_back('k');
2360         key.push_back('0' + i);
2361         Value actualValue;
2362         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2363         std::string deviceId = std::to_string(i);
2364         EXPECT_EQ(CheckLogTable(deviceId), OK);
2365     }
2366     /**
2367      * @tc.steps: step3. Make log table all users's hashKey become same hashKey '99', and the hashKey in syncTable
2368      *  where device is deviceId1 also become '99',remove data with FLAG_AND_DATA flag.
2369      * * @tc.expected: step3. remove OK
2370     */
2371     std::string deviceId1 = "1";
2372     std::string deviceId2 = "2";
2373     std::string deviceId0 = "0";
2374     DistributedDBCloudKvTest::ChangeHashKey(deviceId1);
2375     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user1", ClearMode::FLAG_AND_DATA), OK);
2376     Key key1({'k', '1'});
2377     Value actualValue;
2378     // there are other users with same hash_key connect with this data in sync_data table, cant not remove the data.
2379     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
2380     EXPECT_EQ(CheckLogTable(deviceId1), OK); // match user2 and user0;
2381     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user2", ClearMode::FLAG_AND_DATA), OK);
2382     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), OK);
2383     EXPECT_EQ(CheckLogTable(deviceId1), OK); // only user0 match the hash_key that same as device1.
2384     EXPECT_EQ(CheckFlag(key1, LogInfoFlag::FLAG_CLOUD_WRITE), OK); // flag still 0x100;
2385     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId1, "user0", ClearMode::FLAG_AND_DATA), OK);
2386     // all log have been deleted, so data would also be deleted.
2387     EXPECT_EQ(kvDelegatePtrS1_->Get(key1, actualValue), NOT_FOUND);
2388     EXPECT_EQ(CheckLogTable(deviceId1), NOT_FOUND);
2389     EXPECT_EQ(CheckWaterMark(userHead + "0"), NOT_FOUND);
2390 }
2391 
2392 /**
2393  * @tc.name: RemoveDeviceTest007
2394  * @tc.desc: remove record with invalid deviceId and mode.
2395  * @tc.type: FUNC
2396  * @tc.require:
2397  * @tc.author: mazhao
2398  */
2399 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest007, TestSize.Level0)
2400 {
2401     /**
2402      * @tc.steps: step1. Test removeDeviceData with invalid length deviceId.
2403      * * @tc.expected:
2404     */
2405     std::string deviceId = std::string(128, 'a');
2406     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, ClearMode::FLAG_AND_DATA), OK);
2407     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "user1", ClearMode::FLAG_AND_DATA), OK);
2408 
2409     std::string invaliDeviceId = std::string(129, 'a');
2410     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(invaliDeviceId, ClearMode::FLAG_AND_DATA), INVALID_ARGS);
2411     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(invaliDeviceId, "user1", ClearMode::FLAG_AND_DATA), INVALID_ARGS);
2412 
2413     /**
2414      * @tc.steps: step2. Test removeDeviceData with invalid mode.
2415      * * @tc.expected:
2416     */
2417     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT);
2418     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "user1", ClearMode::CLEAR_SHARED_TABLE), NOT_SUPPORT);
2419 }
2420 
2421 /**
2422  * @tc.name: RemoveDeviceTest008
2423  * @tc.desc: remove record without mode.
2424  * @tc.type: FUNC
2425  * @tc.require:
2426  * @tc.author: liaoyonnghuang
2427  */
2428 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest008, TestSize.Level0)
2429 {
2430     /**
2431      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
2432      * (Key:k2, device:2, userId:2)
2433      * * @tc.expected: step1. insert successfully
2434     */
2435     int recordNum = 3;
2436     InsertRecord(recordNum);
2437     for (int i = 0; i < recordNum; i++) {
2438         Key key;
2439         key.push_back('k');
2440         key.push_back('0' + i);
2441         SetFlag(key, LogInfoFlag::FLAG_CLOUD);
2442         SetDeviceId(key, std::to_string(i));
2443         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2444     }
2445 
2446     /**
2447      * @tc.steps: step2. Check three Log record whether exist or not;
2448      * * @tc.expected: step2. record exist
2449     */
2450     for (int i = 0; i < recordNum; i++) {
2451         Key key;
2452         key.push_back('k');
2453         key.push_back('0' + i);
2454         Value actualValue;
2455         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2456     }
2457     /**
2458      * @tc.steps: step3. Remove data without mode.
2459      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
2460     */
2461     for (int i = 0; i < recordNum; i++) {
2462         EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i)), OK);
2463     }
2464     for (int i = 0; i < recordNum; i++) {
2465         Key key;
2466         key.push_back('k');
2467         key.push_back('0' + i);
2468         Value actualValue;
2469         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), NOT_FOUND);
2470     }
2471 }
2472 
2473 /**
2474  * @tc.name: RemoveDeviceTest009
2475  * @tc.desc: remove record without mode FLAG_AND_DATA.
2476  * @tc.type: FUNC
2477  * @tc.require:
2478  * @tc.author: liaoyonnghuang
2479  */
2480 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest009, TestSize.Level0)
2481 {
2482     /**
2483      * @tc.steps: step1. Insert three record (Key:k0, device:0, userId:user0), (Key:k1, device:1, userId:user1),
2484      * (Key:k2, device:2, userId:2)
2485      * * @tc.expected: step1. insert successfully
2486     */
2487     int recordNum = 3;
2488     InsertRecord(recordNum);
2489     for (int i = 0; i < recordNum; i++) {
2490         Key key;
2491         key.push_back('k');
2492         key.push_back('0' + i);
2493         SetFlag(key, LogInfoFlag::FLAG_CLOUD);
2494         SetDeviceId(key, std::to_string(i));
2495         std::this_thread::sleep_for(std::chrono::milliseconds(100)); // sleep for 100ms
2496     }
2497 
2498     /**
2499      * @tc.steps: step2. Check three Log record whether exist or not;
2500      * * @tc.expected: step2. record exist
2501     */
2502     for (int i = 0; i < recordNum; i++) {
2503         Key key;
2504         key.push_back('k');
2505         key.push_back('0' + i);
2506         Value actualValue;
2507         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2508         std::string deviceId = std::to_string(i);
2509         EXPECT_EQ(CheckLogTable(deviceId), OK);
2510     }
2511     /**
2512      * @tc.steps: step3. Remove data without mode FLAG_AND_DATA.
2513      * * @tc.expected: step3. remove OK, there are not user record exist in log table.
2514     */
2515     for (int i = 0; i < recordNum; i++) {
2516         EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(std::to_string(i), ClearMode::FLAG_AND_DATA), OK);
2517     }
2518     for (int i = 0; i < recordNum; i++) {
2519         Key key;
2520         key.push_back('k');
2521         key.push_back('0' + i);
2522         Value actualValue;
2523         EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2524         std::string deviceId = std::to_string(i);
2525         EXPECT_EQ(CheckLogTable(deviceId), NOT_FOUND);
2526     }
2527 }
2528 
2529 /**
2530  * @tc.name: RemoveDeviceTest010
2531  * @tc.desc: remove record with invalid mode.
2532  * @tc.type: FUNC
2533  * @tc.require:
2534  * @tc.author: zhangqiquan
2535  */
2536 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest010, TestSize.Level0)
2537 {
2538     std::string deviceId = std::string(128, 'a');
2539     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_ONLY), INVALID_ARGS);
2540     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::CLEAR_SHARED_TABLE), INVALID_ARGS);
2541     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::FLAG_AND_DATA), INVALID_ARGS);
2542     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(deviceId, "", ClearMode::DEFAULT), OK);
2543     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", "", ClearMode::DEFAULT), OK);
2544     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData("", ClearMode::DEFAULT), OK);
2545 }
2546 
2547 /**
2548  * @tc.name: RemoveDeviceTest011
2549  * @tc.desc: remove record while conn is nullptr.
2550  * @tc.type: FUNC
2551  * @tc.require:
2552  * @tc.author: caihaoting
2553  */
2554 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest011, TestSize.Level0)
2555 {
2556     const KvStoreNbDelegate::Option option = {true, true};
2557     KvStoreNbDelegate *kvDelegateInvalidPtrS1_ = nullptr;
2558     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS1_, "RemoveDeviceTest011", option), OK);
2559     ASSERT_NE(kvDelegateInvalidPtrS1_, nullptr);
2560     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS1_);
2561     EXPECT_EQ(kvStoreImpl->Close(), OK);
2562     EXPECT_EQ(kvDelegateInvalidPtrS1_->RemoveDeviceData("", ClearMode::FLAG_ONLY), DB_ERROR);
2563     EXPECT_EQ(kvDelegateInvalidPtrS1_->RemoveDeviceData("", "", ClearMode::FLAG_ONLY), DB_ERROR);
2564     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS1_), OK);
2565 }
2566 
2567 /**
2568  * @tc.name: RemoveDeviceTest012
2569  * @tc.desc: Test remove all data from other device.
2570  * @tc.type: FUNC
2571  * @tc.require:
2572  * @tc.author: liaoyonghuang
2573  */
2574 HWTEST_F(DistributedDBCloudKvTest, RemoveDeviceTest012, TestSize.Level0)
2575 {
2576     /**
2577      * @tc.steps: step1. Insert three record, k0 from device sync, k1 from local write, k2 from cloud sync.
2578      * * @tc.expected: step1. insert successfully
2579     */
2580     int recordNum = 3;
2581     InsertRecord(recordNum);
2582     SetFlag({'k', '0'}, LogInfoFlag::FLAG_CLOUD);
2583     SetFlag({'k', '1'}, LogInfoFlag::FLAG_LOCAL);
2584     /**
2585      * @tc.steps: step2. Remove data from device sync and cloud sync, and remove log.
2586      * * @tc.expected: step2. All data and log are removed except data from local write.
2587     */
2588     EXPECT_EQ(kvDelegatePtrS1_->RemoveDeviceData(), OK);
2589     Value actualValue;
2590     Value expectValue = {'k', '1'};
2591     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '1'}, actualValue), OK);
2592     EXPECT_EQ(actualValue, expectValue);
2593     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '0'}, actualValue), NOT_FOUND);
2594     EXPECT_EQ(kvDelegatePtrS1_->Get({'k', '2'}, actualValue), NOT_FOUND);
2595 }
2596 
2597 /**
2598  * @tc.name: NormalSyncInvalid001
2599  * @tc.desc: Test normal push not sync and get cloud version.
2600  * @tc.type: FUNC
2601  * @tc.require:
2602  * @tc.author: caihaoting
2603  */
2604 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid001, TestSize.Level0)
2605 {
2606     Key key = {'k'};
2607     Value expectValue = {'v'};
2608     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anon341701841402(const std::string &origin) 2609     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
2610         LOGW("origin is %s", origin.c_str());
2611         return origin + "1";
2612     });
2613     Value actualValue;
2614     EXPECT_EQ(kvDelegatePtrS1_->Get(key, actualValue), OK);
2615     EXPECT_EQ(actualValue, expectValue);
2616     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
2617     auto result = kvDelegatePtrS1_->GetCloudVersion("");
2618     EXPECT_EQ(result.first, NOT_FOUND);
2619 }
2620 
2621 /**
2622  * @tc.name: NormalSyncInvalid002
2623  * @tc.desc: Test normal push sync and use invalidDevice to get cloud version.
2624  * @tc.type: FUNC
2625  * @tc.require:
2626  * @tc.author: caihaoting
2627  */
2628 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid002, TestSize.Level0)
2629 {
2630     Key key = {'k'};
2631     Value expectValue = {'v'};
2632     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
__anon341701841502(const std::string &origin) 2633     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
2634         LOGW("origin is %s", origin.c_str());
2635         return origin + "1";
2636     });
2637     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
2638     for (const auto &table : lastProcess_.tableProcess) {
2639         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
2640         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
2641     }
2642     BlockSync(kvDelegatePtrS2_, OK, g_CloudSyncoption);
2643     for (const auto &table : lastProcess_.tableProcess) {
2644         EXPECT_EQ(table.second.downLoadInfo.total, 2u); // download 2 records
2645         EXPECT_EQ(table.second.downLoadInfo.insertCount, 2u); // download 2 records
2646     }
2647     Value actualValue;
2648     EXPECT_EQ(kvDelegatePtrS2_->Get(key, actualValue), OK);
2649     EXPECT_EQ(actualValue, expectValue);
2650     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
2651     std::string invalidDevice = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0');
2652     auto result = kvDelegatePtrS2_->GetCloudVersion(invalidDevice);
2653     EXPECT_EQ(result.first, INVALID_ARGS);
2654 }
2655 
2656 /**
2657  * @tc.name: NormalSyncInvalid003
2658  * @tc.desc: Test normal push sync for add data while conn is nullptr.
2659  * @tc.type: FUNC
2660  * @tc.require:
2661  * @tc.author: caihaoting
2662  */
2663 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid003, TestSize.Level0)
2664 {
2665     const KvStoreNbDelegate::Option option = {true, true};
2666     KvStoreNbDelegate *kvDelegateInvalidPtrS1_ = nullptr;
2667     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS1_, "NormalSyncInvalid003", option), OK);
2668     ASSERT_NE(kvDelegateInvalidPtrS1_, nullptr);
2669     Key key = {'k'};
2670     Value expectValue = {'v'};
2671     ASSERT_EQ(kvDelegateInvalidPtrS1_->Put(key, expectValue), OK);
__anon341701841602(const std::string &origin) 2672     kvDelegateInvalidPtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
2673         LOGW("origin is %s", origin.c_str());
2674         return origin + "1";
2675     });
2676     BlockSync(kvDelegateInvalidPtrS1_, OK, g_CloudSyncoption);
2677     for (const auto &table : lastProcess_.tableProcess) {
2678         EXPECT_EQ(table.second.upLoadInfo.total, 1u);
2679         EXPECT_EQ(table.second.upLoadInfo.insertCount, 1u);
2680     }
2681     Value actualValue;
2682     EXPECT_EQ(kvDelegateInvalidPtrS1_->Get(key, actualValue), OK);
2683     EXPECT_EQ(actualValue, expectValue);
2684     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS1_);
2685     EXPECT_EQ(kvStoreImpl->Close(), OK);
2686     kvDelegateInvalidPtrS1_->SetGenCloudVersionCallback(nullptr);
2687     auto result = kvDelegateInvalidPtrS1_->GetCloudVersion("");
2688     EXPECT_EQ(result.first, DB_ERROR);
2689     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS1_), OK);
2690 }
2691 
2692 /**
2693  * @tc.name: NormalSyncInvalid004
2694  * @tc.desc: Test normal push sync use GetDeviceEntries while conn is nullptr.
2695  * @tc.type: FUNC
2696  * @tc.require:
2697  * @tc.author: caihaoting
2698  */
2699 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid004, TestSize.Level0)
2700 {
2701     const KvStoreNbDelegate::Option option = {true, true};
2702     KvStoreNbDelegate *kvDelegateInvalidPtrS2_ = nullptr;
2703     ASSERT_EQ(GetKvStore(kvDelegateInvalidPtrS2_, "NormalSyncInvalid004", option), OK);
2704     ASSERT_NE(kvDelegateInvalidPtrS2_, nullptr);
2705     /**
2706      * @tc.steps: step1. store1 put (k1,v1) store2 put (k2,v2)
2707      * @tc.expected: step1. both put ok
2708      */
2709     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
__anon341701841702(const std::string &origin) 2710     kvDelegatePtrS1_->SetGenCloudVersionCallback([](const std::string &origin) {
2711         LOGW("origin is %s", origin.c_str());
2712         return origin + "1";
2713     });
__anon341701841802(const std::string &origin) 2714     kvDelegateInvalidPtrS2_->SetGenCloudVersionCallback([](const std::string &origin) {
2715         LOGW("origin is %s", origin.c_str());
2716         return origin + "1";
2717     });
2718     Key key1 = {'k', '1'};
2719     Value expectValue1 = {'v', '1'};
2720     Key key2 = {'k', '2'};
2721     Value expectValue2 = {'v', '2'};
2722     ASSERT_EQ(kvDelegatePtrS1_->Put(key1, expectValue1), OK);
2723     ASSERT_EQ(kvDelegateInvalidPtrS2_->Put(key2, expectValue2), OK);
2724     /**
2725      * @tc.steps: step2. both store1 and store2 sync while conn is nullptr
2726      * @tc.expected: step2. both sync ok, and store2 got (k1,v1) store1 not exist (k2,v2)
2727      */
2728     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption);
2729     LOGW("Store1 sync end");
2730     communicatorAggregator_->SetLocalDeviceId("DEVICES_B");
2731     BlockSync(kvDelegateInvalidPtrS2_, OK, g_CloudSyncoption);
2732     LOGW("Store2 sync end");
2733     Value actualValue;
2734     EXPECT_EQ(kvDelegateInvalidPtrS2_->Get(key1, actualValue), OK);
2735 
2736     /**
2737      * @tc.steps: step3. use GetDeviceEntries while conn is nullptr
2738      * @tc.expected: step3. DB_ERROR
2739      */
2740     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegateInvalidPtrS2_);
2741     EXPECT_EQ(kvStoreImpl->Close(), OK);
2742     std::vector<Entry> entries;
2743     EXPECT_EQ(kvDelegateInvalidPtrS2_->GetDeviceEntries(std::string("DEVICES_A"), entries), DB_ERROR);
2744     EXPECT_EQ(entries.size(), 0u); // 1 record
2745     communicatorAggregator_->SetLocalDeviceId("DEVICES_A");
2746     EXPECT_EQ(actualValue, expectValue1);
2747     EXPECT_EQ(kvDelegatePtrS1_->Get(key2, actualValue), NOT_FOUND);
2748 
2749     kvDelegatePtrS1_->SetGenCloudVersionCallback(nullptr);
2750     kvDelegateInvalidPtrS2_->SetGenCloudVersionCallback(nullptr);
2751     EXPECT_EQ(g_mgr.CloseKvStore(kvDelegateInvalidPtrS2_), OK);
2752 }
2753 
2754 /**
2755  * @tc.name: NormalSyncInvalid005
2756  * @tc.desc: Test normal sync with invalid parm.
2757  * @tc.type: FUNC
2758  * @tc.require:
2759  * @tc.author: caihaoting
2760  */
2761 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid005, TestSize.Level0)
2762 {
2763     Key key = {'k'};
2764     Value expectValue = {'v'};
2765     ASSERT_EQ(kvDelegatePtrS1_->Put(key, expectValue), OK);
2766     auto devices = g_CloudSyncoption.devices;
2767     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, nullptr), NOT_SUPPORT);
2768     Query query = Query::Select().Range({}, {});
2769     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, SyncMode::SYNC_MODE_CLOUD_MERGE, nullptr, query, true), NOT_SUPPORT);
2770     auto mode = g_CloudSyncoption.mode;
2771     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr, query, true), NOT_SUPPORT);
2772     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
2773     EXPECT_EQ(kvStoreImpl->Close(), OK);
2774     BlockSync(kvDelegatePtrS1_, OK, g_CloudSyncoption, DB_ERROR);
2775     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr), DB_ERROR);
2776     EXPECT_EQ(kvDelegatePtrS1_->Sync(devices, mode, nullptr, query, true), DB_ERROR);
2777 }
2778 
2779 /**
2780  * @tc.name: NormalSyncInvalid006
2781  * @tc.desc: Test normal sync set cloudDB while cloudDB is empty and conn is nullptr.
2782  * @tc.type: FUNC
2783  * @tc.require:
2784  * @tc.author: caihaoting
2785  */
2786 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid006, TestSize.Level0)
2787 {
2788     /**
2789      * @tc.steps: step1. set cloudDB while cloudDB is empty
2790      * @tc.expected: step1. INVALID_ARGS
2791      */
2792     std::map<std::string, std::shared_ptr<ICloudDb>> cloudDbs;
2793     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDB(cloudDbs), INVALID_ARGS);
2794     /**
2795      * @tc.steps: step2. set cloudDB while conn is nullptr
2796      * @tc.expected: step2. DB_ERROR
2797      */
2798     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
2799     EXPECT_EQ(kvStoreImpl->Close(), OK);
2800     cloudDbs[USER_ID] = virtualCloudDb_;
2801     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDB(cloudDbs), DB_ERROR);
2802 }
2803 
2804 /**
2805  * @tc.name: NormalSyncInvalid007
2806  * @tc.desc: Test normal sync set cloudDb schema while conn is nullptr.
2807  * @tc.type: FUNC
2808  * @tc.require:
2809  * @tc.author: caihaoting
2810  */
2811 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid007, TestSize.Level0)
2812 {
2813     /**
2814      * @tc.steps: step1. set cloudDB schema while conn is nullptr
2815      * @tc.expected: step1. DB_ERROR
2816      */
2817     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
2818     EXPECT_EQ(kvStoreImpl->Close(), OK);
2819     std::map<std::string, DataBaseSchema> schemas;
2820     schemas[USER_ID] = GetDataBaseSchema(true);
2821     EXPECT_EQ(kvDelegatePtrS1_->SetCloudDbSchema(schemas), DB_ERROR);
2822 }
2823 
2824 /**
2825  * @tc.name: NormalSyncInvalid008
2826  * @tc.desc: Test SetCloudSyncConfig with invalid parm.
2827  * @tc.type: FUNC
2828  * @tc.require:
2829  * @tc.author: caihaoting
2830  */
2831 HWTEST_F(DistributedDBCloudKvTest, NormalSyncInvalid008, TestSize.Level0)
2832 {
2833     /**
2834      * @tc.steps: step1. SetCloudSyncConfig with invalid maxUploadCount.
2835      * @tc.expected: step1. INVALID_ARGS
2836      */
2837     CloudSyncConfig config;
2838     int maxUploadCount = 0;
2839     config.maxUploadCount = maxUploadCount;
2840     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
2841     maxUploadCount = 2001;
2842     config.maxUploadCount = maxUploadCount;
2843     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
2844     maxUploadCount = 50;
2845     config.maxUploadCount = maxUploadCount;
2846     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
2847 
2848     /**
2849      * @tc.steps: step2. SetCloudSyncConfig with invalid maxUploadSize.
2850      * @tc.expected: step2. INVALID_ARGS
2851      */
2852     int maxUploadSize = 1023;
2853     config.maxUploadSize = maxUploadSize;
2854     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
2855     maxUploadSize = 128 * 1024 * 1024 + 1;
2856     config.maxUploadSize = maxUploadSize;
2857     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
2858     maxUploadSize = 10240;
2859     config.maxUploadSize = maxUploadSize;
2860     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
2861 
2862     /**
2863      * @tc.steps: step3. SetCloudSyncConfig with invalid maxRetryConflictTimes.
2864      * @tc.expected: step3. INVALID_ARGS
2865      */
2866     int maxRetryConflictTimes = -2;
2867     config.maxRetryConflictTimes = maxRetryConflictTimes;
2868     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), INVALID_ARGS);
2869     maxRetryConflictTimes = 2;
2870     config.maxRetryConflictTimes = maxRetryConflictTimes;
2871     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), OK);
2872 
2873     /**
2874      * @tc.steps: step4. SetCloudSyncConfig while conn is nullptr
2875      * @tc.expected: step4. DB_ERROR
2876      */
2877     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvDelegatePtrS1_);
2878     EXPECT_EQ(kvStoreImpl->Close(), OK);
2879     EXPECT_EQ(kvDelegatePtrS1_->SetCloudSyncConfig(config), DB_ERROR);
2880 }
2881 }
2882