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 }