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