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