• 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 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 }