1 /*
2 * Copyright (c) 2023 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 "cloud_syncer_test.h"
17 #include "distributeddb_tools_unit_test.h"
18 #include "mock_iclouddb.h"
19 #include "mock_icloud_sync_storage_interface.h"
20 #include "time_helper.h"
21 #include "types_export.h"
22 #include "virtual_communicator_aggregator.h"
23
24 using namespace testing::ext;
25 using namespace testing;
26 using namespace DistributedDB;
27 using namespace DistributedDBUnitTest;
28
29 namespace {
30 static int64_t g_photoCount = 10;
31 static double g_dataHeight = 166.0;
32 static uint64_t g_invalidOptCount = 5u;
33 class DistributedDBCloudSyncerDownloadTest : public testing::Test {
34 public:
35 static void SetUpTestCase(void);
36 static void TearDownTestCase(void);
37 void SetUp();
38 void TearDown();
39 protected:
40 VirtualCommunicatorAggregator *communicatorAggregator_ = nullptr;
41 };
42
43 MockICloudSyncStorageInterface *g_iCloud = nullptr;
44 std::shared_ptr<TestStorageProxy> g_storageProxy = nullptr;
45 MockICloudDB *g_idb = nullptr;
46 TestCloudSyncer *g_cloudSyncer = nullptr;
47
SetUpTestCase(void)48 void DistributedDBCloudSyncerDownloadTest::SetUpTestCase(void)
49 {
50 g_iCloud = new MockICloudSyncStorageInterface();
51 g_storageProxy = std::make_shared<TestStorageProxy>(g_iCloud);
52 g_cloudSyncer = new(std::nothrow) TestCloudSyncer(g_storageProxy);
53 ASSERT_NE(g_cloudSyncer, nullptr);
54 g_idb = new MockICloudDB();
55 g_cloudSyncer->SetMockICloudDB(g_idb);
56 }
57
TearDownTestCase(void)58 void DistributedDBCloudSyncerDownloadTest::TearDownTestCase(void)
59 {
60 g_cloudSyncer->CallClose();
61 RefObject::KillAndDecObjRef(g_cloudSyncer);
62 g_cloudSyncer = nullptr;
63 g_storageProxy = nullptr;
64 delete g_iCloud;
65 g_iCloud = nullptr;
66 }
67
SetUp(void)68 void DistributedDBCloudSyncerDownloadTest::SetUp(void)
69 {
70 DistributedDBToolsUnitTest::PrintTestCaseInfo();
71 communicatorAggregator_ = new (std::nothrow) VirtualCommunicatorAggregator();
72 ASSERT_TRUE(communicatorAggregator_ != nullptr);
73 RuntimeContext::GetInstance()->SetCommunicatorAggregator(communicatorAggregator_);
74 }
75
TearDown(void)76 void DistributedDBCloudSyncerDownloadTest::TearDown(void)
77 {
78 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
79 communicatorAggregator_ = nullptr;
80 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
81 }
82
GetRetCloudData(uint64_t cnt)83 std::vector<VBucket> GetRetCloudData(uint64_t cnt)
84 {
85 std::vector<uint8_t> photo(g_photoCount, 'v');
86 std::vector<VBucket> cloudData;
87 static uint64_t totalCnt = 0;
88 for (uint64_t i = totalCnt; i < totalCnt + cnt; ++i) {
89 VBucket data;
90 data.insert_or_assign("name", "Cloud" + std::to_string(i));
91 data.insert_or_assign("height", g_dataHeight);
92 data.insert_or_assign("married", (bool)0);
93 data.insert_or_assign("photo", photo);
94 data.insert_or_assign("age", 13L);
95 data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i));
96 data.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)i);
97 data.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)i);
98 data.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
99 data.insert_or_assign(CloudDbConstant::CURSOR_FIELD, std::to_string(i));
100 cloudData.push_back(data);
101 }
102 totalCnt += cnt;
103 return cloudData;
104 }
105
106 struct InvalidCloudDataOpt {
107 bool invalidGID = true;
108 bool invalidCreateField = true;
109 bool invalidModifyField = true;
110 bool invalidDeleteField = true;
111 bool invalidCursor = true;
112 };
113
GenerateTableSchema(TableSchema & tableSchema)114 void GenerateTableSchema(TableSchema &tableSchema)
115 {
116 tableSchema = {
117 "TestTable1",
118 "",
119 {{"name", TYPE_INDEX<std::string>, true}}
120 };
121 }
122
GetInvalidTypeCloudData(uint64_t cnt,InvalidCloudDataOpt fieldOpt)123 std::vector<VBucket> GetInvalidTypeCloudData(uint64_t cnt, InvalidCloudDataOpt fieldOpt)
124 {
125 std::vector<uint8_t> photo(g_photoCount, 'v');
126 std::vector<VBucket> cloudData;
127 static uint64_t totalCnt = 0;
128 for (uint64_t i = totalCnt; i < totalCnt + cnt; ++i) {
129 VBucket data;
130 data.insert_or_assign("name", "Cloud" + std::to_string(i));
131 data.insert_or_assign("height", g_dataHeight);
132 data.insert_or_assign("married", (bool)0);
133 data.insert_or_assign("photo", photo);
134 data.insert_or_assign("age", 13L);
135
136 if (fieldOpt.invalidGID) {
137 data.insert_or_assign(CloudDbConstant::GID_FIELD, (int64_t)i);
138 }
139 if (fieldOpt.invalidCreateField) {
140 data.insert_or_assign(CloudDbConstant::CREATE_FIELD, (Bytes)i);
141 }
142 if (fieldOpt.invalidModifyField) {
143 data.insert_or_assign(CloudDbConstant::MODIFY_FIELD, std::to_string(i));
144 }
145 if (fieldOpt.invalidDeleteField) {
146 data.insert_or_assign(CloudDbConstant::DELETE_FIELD, (int64_t)false);
147 }
148 if (fieldOpt.invalidCursor) {
149 data.insert_or_assign(CloudDbConstant::CURSOR_FIELD, (int64_t)i);
150 }
151 cloudData.push_back(data);
152 }
153 totalCnt += cnt;
154 return cloudData;
155 }
156
GetInvalidFieldCloudData(uint64_t cnt,InvalidCloudDataOpt fieldOpt)157 std::vector<VBucket> GetInvalidFieldCloudData(uint64_t cnt, InvalidCloudDataOpt fieldOpt)
158 {
159 std::vector<uint8_t> photo(g_photoCount, 'v');
160 std::vector<VBucket> cloudData;
161 static uint64_t totalCnt = 0;
162 for (uint64_t i = totalCnt; i < totalCnt + cnt; ++i) {
163 VBucket data;
164 data.insert_or_assign("name", "Cloud" + std::to_string(i));
165 data.insert_or_assign("height", g_dataHeight);
166 data.insert_or_assign("married", (bool)0);
167 data.insert_or_assign("photo", photo);
168 data.insert_or_assign("age", 13L);
169 // Invalid means don't have here
170 if (!fieldOpt.invalidGID) {
171 data.insert_or_assign(CloudDbConstant::GID_FIELD, std::to_string(i));
172 }
173 if (!fieldOpt.invalidCreateField) {
174 data.insert_or_assign(CloudDbConstant::CREATE_FIELD, (int64_t)i);
175 }
176 if (!fieldOpt.invalidModifyField) {
177 data.insert_or_assign(CloudDbConstant::MODIFY_FIELD, (int64_t)i);
178 }
179 if (!fieldOpt.invalidDeleteField) {
180 data.insert_or_assign(CloudDbConstant::DELETE_FIELD, false);
181 }
182 if (!fieldOpt.invalidCursor) {
183 data.insert_or_assign(CloudDbConstant::CURSOR_FIELD, std::to_string(i));
184 }
185 cloudData.push_back(data);
186 }
187 totalCnt += cnt;
188 return cloudData;
189 }
190
GetLogInfo(uint64_t timestamp,bool isDeleted)191 DataInfoWithLog GetLogInfo(uint64_t timestamp, bool isDeleted)
192 {
193 LogInfo logInfo;
194 logInfo.timestamp = timestamp;
195 logInfo.cloudGid = std::to_string(timestamp);
196 if (isDeleted) {
197 logInfo.flag = 1u;
198 }
199 DataInfoWithLog dataInfoWithLog;
200 dataInfoWithLog.logInfo = logInfo;
201 return dataInfoWithLog;
202 }
203
Expect2GetInfoByPrimaryKeyOrGidCall()204 static void Expect2GetInfoByPrimaryKeyOrGidCall()
205 {
206 EXPECT_CALL(*g_iCloud, GetInfoByPrimaryKeyOrGid(_, _, _, _))
207 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
208 info = GetLogInfo(0, false); // Gen data with timestamp 0
209 return E_OK;
210 })
211 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
212 info = GetLogInfo(1, false); // Gen data with timestamp 1
213 return E_OK;
214 })
215 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
216 info = GetLogInfo(2, false); // Gen data with timestamp 2
217 return E_OK;
218 })
219 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
220 info = GetLogInfo(3, false); // Gen data with timestamp 3
221 return E_OK;
222 })
223 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
224 info = GetLogInfo(4, false); // Gen data with timestamp 4
225 return E_OK;
226 });
227 }
228
229 /**
230 * @tc.name: DownloadMockTest001
231 * @tc.desc: Test situation with all possible output for GetCloudWaterMark
232 * @tc.type: FUNC
233 * @tc.require:
234 * @tc.author: WanYi
235 */
236 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest001, TestSize.Level1)
237 {
238 TaskId taskId = 1u;
239 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
240 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
241 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
242 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
243 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
244 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
245 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
246 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0702(const std::string &, VBucket &, std::vector<VBucket> &data) 247 .WillRepeatedly([](const std::string &, VBucket &, std::vector<VBucket> &data) {
248 data = GetRetCloudData(5); // Gen 5 data
249 return QUERY_END;
250 });
251 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
252
253 // 1. Read meta data success
254 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
255 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(E_OK));
256 Expect2GetInfoByPrimaryKeyOrGidCall();
257
258 int errCode = g_cloudSyncer->CallDoDownload(taskId);
259 EXPECT_EQ(errCode, E_OK);
260
261 // // 2. Failed to read water level
262 taskId = 3u;
263 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
264 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(-E_INVALID_DB));
265 errCode = g_cloudSyncer->CallDoDownload(taskId);
266 EXPECT_EQ(errCode, -E_INVALID_DB);
267
268 taskId = 4u;
269 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
270 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(-E_SECUREC_ERROR));
271 errCode = g_cloudSyncer->CallDoDownload(taskId);
272 EXPECT_EQ(errCode, -E_SECUREC_ERROR);
273
274 taskId = 5u;
275 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
276 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(-E_INVALID_ARGS));
277 errCode = g_cloudSyncer->CallDoDownload(taskId);
278 EXPECT_EQ(errCode, -E_INVALID_ARGS);
279 }
280
281 /**
282 * @tc.name: DownloadMockTest002
283 * @tc.desc: Test situation with all possible output for GetCloudWaterMark
284 * @tc.type: FUNC
285 * @tc.require:
286 * @tc.author: WanYi
287 */
288 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest002, TestSize.Level1)
289 {
290 TaskId taskId = 6u;
291 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
292 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
293 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
294 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
295 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
296 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
297 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
298 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
299 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0802(const std::string &, VBucket &, std::vector<VBucket> &data) 300 .WillRepeatedly([](const std::string &, VBucket &, std::vector<VBucket> &data) {
301 data = GetRetCloudData(5); // Gen 5 data
302 return QUERY_END;
303 });
304 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
305
306 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
307 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(-E_BUSY));
308 int errCode = g_cloudSyncer->CallDoDownload(taskId);
309 EXPECT_EQ(errCode, -E_BUSY);
310
311 taskId = 7u;
312 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
313 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(-E_NOT_FOUND));
314 Expect2GetInfoByPrimaryKeyOrGidCall();
315 errCode = g_cloudSyncer->CallDoDownload(taskId);
316 // when we coudln't find key in get meta data, read local water mark will return default value and E_OK
317 EXPECT_EQ(errCode, E_OK);
318
319 // Other sqlite error, like SQLITE_ERROR
320 taskId = 8u;
321 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_FORCE_PUSH);
322 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillOnce(Return(SQLITE_ERROR));
323 errCode = g_cloudSyncer->CallDoDownload(taskId);
324 EXPECT_EQ(errCode, SQLITE_ERROR);
325 }
326
327 /**
328 * @tc.name: DownloadMockQueryTest002
329 * @tc.desc: Test situation with all possible output for Query
330 * @tc.type: FUNC
331 * @tc.require:
332 * @tc.author: WanYi
333 */
334 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest002, TestSize.Level1)
335 {
336 TaskId taskId = 1u;
337 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
338 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
339 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
340 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
341 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
342 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
343 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
344 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
345 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
346
347 // 1. Query data success for the first time, but will not reach end
348 // 2. While quring second time, no more data comes back and return QUERY END
349 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
350 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0902(const std::string &, VBucket &, std::vector<VBucket> &data) 351 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
352 data = GetRetCloudData(5); // Gen 5 data
353 return QUERY_END;});
354 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
355 Expect2GetInfoByPrimaryKeyOrGidCall();
356 int errCode = g_cloudSyncer->CallDoDownload(taskId);
357 EXPECT_EQ(errCode, E_OK);
358 }
359
360 /**
361 * @tc.name: DownloadMockQueryTest003
362 * @tc.desc: Query data success but return invalid data (type mismatch)
363 * @tc.type: FUNC
364 * @tc.require:
365 * @tc.author: WanYi
366 */
367 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest003, TestSize.Level1)
368 {
369 TaskId taskId = 1u;
370 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
371 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
372 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
373 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
374 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
375 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
376 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
377 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
378 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
379 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
380
381 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
382 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0a02(const std::string &, VBucket &, std::vector<VBucket> &data) 383 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
384 InvalidCloudDataOpt opt;
385 opt.invalidCursor = false;
386 data = GetInvalidTypeCloudData(g_invalidOptCount, opt);
387 return QUERY_END;
388 });
389 int errCode = g_cloudSyncer->CallDoDownload(taskId);
390 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
391
392 taskId = 2u;
393 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
394 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0b02(const std::string &, VBucket &, std::vector<VBucket> &data) 395 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
396 InvalidCloudDataOpt opt;
397 opt.invalidCursor = false;
398 data = GetInvalidTypeCloudData(g_invalidOptCount, opt);
399 return QUERY_END;
400 });
401 errCode = g_cloudSyncer->CallDoDownload(taskId);
402 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
403
404
405 taskId = 3u;
406 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
407 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0c02(const std::string &, VBucket &, std::vector<VBucket> &data) 408 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
409 InvalidCloudDataOpt opt;
410 opt.invalidDeleteField = false;
411 data = GetInvalidTypeCloudData(g_invalidOptCount, opt);
412 return QUERY_END;
413 });
414 errCode = g_cloudSyncer->CallDoDownload(taskId);
415 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
416 }
417
418 /**
419 * @tc.name: DownloadMockQueryTest00302
420 * @tc.desc: Query data success but return invalid data (type mismatch)
421 * @tc.type: FUNC
422 * @tc.require:
423 * @tc.author: WanYi
424 */
425 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest00302, TestSize.Level1)
426 {
427 TaskId taskId = 4u;
428 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
429 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
430 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
431 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
432 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
433 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
434 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
435 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
436 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
437 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
438 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
439 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0d02(const std::string &, VBucket &, std::vector<VBucket> &data) 440 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
441 InvalidCloudDataOpt opt;
442 opt.invalidGID = false;
443 data = GetInvalidTypeCloudData(g_invalidOptCount, opt);
444 return QUERY_END;
445 });
446 int errCode = g_cloudSyncer->CallDoDownload(taskId);
447 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
448
449 taskId = 5u;
450 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
451 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0e02(const std::string &, VBucket &, std::vector<VBucket> &data) 452 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
453 InvalidCloudDataOpt opt;
454 opt.invalidModifyField = false;
455 data = GetInvalidTypeCloudData(g_invalidOptCount, opt);
456 return QUERY_END;
457 });
458 errCode = g_cloudSyncer->CallDoDownload(taskId);
459 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
460 }
461
462 /**
463 * @tc.name: DownloadMockQueryTest004
464 * @tc.desc: Query data success but return invalid data (field mismatch)
465 * @tc.type: FUNC
466 * @tc.require:
467 * @tc.author: WanYi
468 */
469 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest004, TestSize.Level1)
470 {
471 TaskId taskId = 1u;
472 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
473 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
474 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
475 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
476 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
477 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
478 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
479 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
480 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
481 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
482
483 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
484 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae0f02(const std::string &, VBucket &, std::vector<VBucket> &data) 485 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
486 InvalidCloudDataOpt opt;
487 opt.invalidCreateField = false;
488 data = GetInvalidFieldCloudData(g_invalidOptCount, opt);
489 return QUERY_END;
490 });
491 int errCode = g_cloudSyncer->CallDoDownload(taskId);
492 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
493
494 taskId = 2u;
495 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
496 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1002(const std::string &, VBucket &, std::vector<VBucket> &data) 497 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
498 InvalidCloudDataOpt opt;
499 opt.invalidCursor = false;
500 data = GetInvalidFieldCloudData(g_invalidOptCount, opt);
501 return QUERY_END;
502 });
503 errCode = g_cloudSyncer->CallDoDownload(taskId);
504 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
505 }
506
507 /**
508 * @tc.name: DownloadMockQueryTest00402
509 * @tc.desc: Query data success but return invalid data (field mismatch)
510 * @tc.type: FUNC
511 * @tc.require:
512 * @tc.author: WanYi
513 */
514 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest00402, TestSize.Level1)
515 {
516 TaskId taskId = 3u;
517 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
518 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
519 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
520 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
521 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
522 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
523 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
524 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
525 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
526 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
527 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
528 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1102(const std::string &, VBucket &, std::vector<VBucket> &data) 529 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
530 InvalidCloudDataOpt opt;
531 opt.invalidDeleteField = false;
532 data = GetInvalidFieldCloudData(g_invalidOptCount, opt);
533 return QUERY_END;
534 });
535 int errCode = g_cloudSyncer->CallDoDownload(taskId);
536 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
537
538 taskId = 4u;
539 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
540 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1202(const std::string &, VBucket &, std::vector<VBucket> &data) 541 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
542 InvalidCloudDataOpt opt;
543 opt.invalidGID = false;
544 data = GetInvalidFieldCloudData(g_invalidOptCount, opt);
545 return QUERY_END;
546 });
547 errCode = g_cloudSyncer->CallDoDownload(taskId);
548 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
549
550 taskId = 5u;
551 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
552 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1302(const std::string &, VBucket &, std::vector<VBucket> &data) 553 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
554 InvalidCloudDataOpt opt;
555 opt.invalidModifyField = false;
556 data = GetInvalidFieldCloudData(g_invalidOptCount, opt);
557 return QUERY_END;
558 });
559 errCode = g_cloudSyncer->CallDoDownload(taskId);
560 EXPECT_EQ(errCode, -E_CLOUD_ERROR);
561 }
562
563 /**
564 * @tc.name: DownloadMockQueryTest005
565 * @tc.desc: First time, query return OK but empty data set
566 * @tc.type: FUNC
567 * @tc.require:
568 * @tc.author: WanYi
569 */
570 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockQueryTest005, TestSize.Level1)
571 {
572 TaskId taskId = 1u;
573 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
574 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
575 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
576 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
577 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
578 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
579 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
580 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
581 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
582 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
583 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
584
585 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1402(const std::string &, VBucket &, std::vector<VBucket> &data) 586 .WillRepeatedly([](const std::string &, VBucket &, std::vector<VBucket> &data) {
587 data = GetRetCloudData(0); // Gen 0 data
588 return QUERY_END;
589 });
590 int errCode = g_cloudSyncer->CallDoDownload(taskId);
591 EXPECT_EQ(errCode, E_OK);
592 }
593
594 /**
595 * @tc.name: DownloadMockTest006
596 * @tc.desc: Data from cloud do not exist in local database.
597 * therefore, GetInfoByPrimaryKeyOrGid will indicate that the datum is -E_NOT_FOUND
598 * @tc.type: FUNC
599 * @tc.require:
600 * @tc.author: WanYi
601 */
602 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest006, TestSize.Level1)
603 {
604 TaskId taskId = 1u;
605 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
606 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
607 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
608 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
609 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
610 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
611 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
612 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
613 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
614 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _))
__anonb65cf8ae1502(const TableName &, TableSchema &tableSchema) 615 .WillRepeatedly([](const TableName &, TableSchema &tableSchema) {
616 GenerateTableSchema(tableSchema);
617 return E_OK;
618 });
619 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
620
621 EXPECT_CALL(*g_idb, Query(_, _, _))
__anonb65cf8ae1602(const std::string &, VBucket &, std::vector<VBucket> &data) 622 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
623 data = GetRetCloudData(5); // Gen 5 data
624 return QUERY_END;
625 });
626 EXPECT_CALL(*g_iCloud, GetInfoByPrimaryKeyOrGid(_, _, _, _))
__anonb65cf8ae1702(const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) 627 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
628 info = GetLogInfo(0, false); // Gen log info with timestamp 0
629 return E_OK;
630 })
__anonb65cf8ae1802(const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) 631 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
632 info = GetLogInfo(1, false); // Gen log info with timestamp 1
633 return -E_NOT_FOUND;
634 })
__anonb65cf8ae1902(const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) 635 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
636 info = GetLogInfo(2, false); // Gen log info with timestamp 2
637 return E_OK;
638 })
__anonb65cf8ae1a02(const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) 639 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
640 info = GetLogInfo(3, false); // Gen log info with timestamp 3
641 return E_OK;
642 })
__anonb65cf8ae1b02(const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) 643 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
644 info = GetLogInfo(4, false); // Gen log info with timestamp 4
645 return E_OK;
646 });
647 int errCode = g_cloudSyncer->CallDoDownload(taskId);
648 EXPECT_EQ(errCode, E_OK);
649 }
650
ExpectQueryCall()651 static void ExpectQueryCall()
652 {
653 EXPECT_CALL(*g_idb, Query(_, _, _))
654 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
655 data = GetRetCloudData(3); // Gen 3 data
656 return OK;
657 })
658 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
659 data = GetRetCloudData(3); // Gen 3 data
660 return OK;
661 })
662 .WillOnce([](const std::string &, VBucket &, std::vector<VBucket> &data) {
663 data = GetRetCloudData(4); // Gen 4 data
664 return QUERY_END;
665 });
666 }
667
ExpectGetInfoByPrimaryKeyOrGidCall()668 static void ExpectGetInfoByPrimaryKeyOrGidCall()
669 {
670 EXPECT_CALL(*g_iCloud, GetInfoByPrimaryKeyOrGid(_, _, _, _))
671 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
672 info = GetLogInfo(0, false); // Gen log info with timestamp 0
673 return -E_NOT_FOUND;
674 })
675 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
676 info = GetLogInfo(1, false); // Gen log info with timestamp 1
677 return -E_NOT_FOUND;
678 })
679 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
680 info = GetLogInfo(2, false); // Gen log info with timestamp 2
681 return E_OK;
682 })
683 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
684 info = GetLogInfo(3, false); // Gen log info with timestamp 3
685 return E_OK;
686 })
687 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
688 info = GetLogInfo(4, false); // Gen log info with timestamp 4
689 return E_OK;
690 })
691 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
692 info = GetLogInfo(5, false); // Gen log info with timestamp 5
693 return E_OK;
694 })
695 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
696 info = GetLogInfo(6, false); // Gen log info with timestamp 6
697 return -E_NOT_FOUND;
698 })
699 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
700 info = GetLogInfo(7, false); // Gen log info with timestamp 7
701 return -E_NOT_FOUND;
702 })
703 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
704 info = GetLogInfo(8, false); // Gen log info with timestamp 8
705 return E_OK;
706 })
707 .WillOnce([](const std::string &, const VBucket &, DataInfoWithLog &info, VBucket &) {
708 info = GetLogInfo(9, false); // Gen log info with timestamp 9
709 return E_OK;
710 });
711 }
712
713 /**
714 * @tc.name: DownloadMockTest007
715 * @tc.desc: Query return OK multiple times and return E_OK finally
716 * @tc.type: FUNC
717 * @tc.require:
718 * @tc.author: WanYi
719 */
720 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest007, TestSize.Level1)
721 {
722 TaskId taskId = 1u;
723 EXPECT_CALL(*g_iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
724 EXPECT_CALL(*g_iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly([](const QuerySyncObject &,
__anonb65cf8ae2902(const QuerySyncObject &, const Timestamp &, bool, bool, int64_t &count) 725 const Timestamp &, bool, bool, int64_t &count) {
726 count = 1;
727 return E_OK;
728 });
729 EXPECT_CALL(*g_iCloud, Commit()).WillRepeatedly(Return(E_OK));
730 EXPECT_CALL(*g_iCloud, Rollback()).WillRepeatedly(Return(E_OK));
731 EXPECT_CALL(*g_iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
732 EXPECT_CALL(*g_iCloud, PutMetaData(_, _)).WillRepeatedly(Return(E_OK));
733 EXPECT_CALL(*g_iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
734 EXPECT_CALL(*g_iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
735 EXPECT_CALL(*g_iCloud, TriggerObserverAction(_, _, _)).WillRepeatedly(Return());
736 EXPECT_CALL(*g_iCloud, GetCloudTableSchema(_, _))
__anonb65cf8ae2a02(const TableName &, TableSchema &tableSchema) 737 .WillRepeatedly([](const TableName &, TableSchema &tableSchema) {
738 GenerateTableSchema(tableSchema);
739 return E_OK;
740 });
741 g_cloudSyncer->InitCloudSyncer(taskId, SYNC_MODE_CLOUD_MERGE);
742 ExpectQueryCall();
743 ExpectGetInfoByPrimaryKeyOrGidCall();
__anonb65cf8ae2b02(const std::string &) 744 EXPECT_CALL(*g_idb, GetEmptyCursor(_)).WillRepeatedly([](const std::string &) {
745 return std::pair<DBStatus, std::string>(OK, std::string("test"));
746 });
747 int errCode = g_cloudSyncer->CallDoDownloadInNeed(true, true);
748 EXPECT_EQ(errCode, E_OK);
749 auto recorder = g_cloudSyncer->GetProcessRecorder();
750 ASSERT_NE(recorder, nullptr);
751 EXPECT_TRUE(recorder->IsDownloadFinish(0, g_cloudSyncer->GetCurrentContextTableName()));
752 }
753
754 /**
755 * @tc.name: DownloadMockTest008
756 * @tc.desc: Get sync param when task resume
757 * @tc.type: FUNC
758 * @tc.require:
759 * @tc.author: zhangqiquan
760 */
761 HWTEST_F(DistributedDBCloudSyncerDownloadTest, DownloadMockTest008, TestSize.Level0)
762 {
763 TaskId taskId = 1u;
764 g_cloudSyncer->SetTaskResume(taskId, true);
765
766 std::string expectCloudWaterMark = "waterMark";
767 ICloudSyncer::SyncParam param;
768 param.cloudWaterMark = expectCloudWaterMark;
769 param.tableName = "table";
770 g_cloudSyncer->SetResumeSyncParam(taskId, param);
771 g_cloudSyncer->SetCloudWaterMarks(param.tableName, param.cloudWaterMark);
772 ICloudSyncer::SyncParam actualParam;
773 EXPECT_EQ(g_cloudSyncer->CallGetSyncParamForDownload(taskId, actualParam), E_OK);
774 expectCloudWaterMark = "";
775 EXPECT_EQ(actualParam.cloudWaterMark, expectCloudWaterMark);
776
777 g_cloudSyncer->SetTaskResume(taskId, false);
778 g_cloudSyncer->ClearResumeTaskInfo(taskId);
779 }
780 }