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