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