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