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