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