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
17 #include "cloud_syncer_test.h"
18 #include "distributeddb_tools_unit_test.h"
19 #include "mock_iclouddb.h"
20 #include "mock_icloud_sync_storage_interface.h"
21
22
23 using namespace testing::ext;
24 using namespace testing;
25 using namespace DistributedDB;
26 using namespace DistributedDBUnitTest;
27
28 namespace {
29 class DistributedDBCloudSyncerProgressManagerTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35 };
36
SetUpTestCase(void)37 void DistributedDBCloudSyncerProgressManagerTest::SetUpTestCase(void)
38 {
39 }
40
TearDownTestCase(void)41 void DistributedDBCloudSyncerProgressManagerTest::TearDownTestCase(void)
42 {
43 }
44
SetUp(void)45 void DistributedDBCloudSyncerProgressManagerTest::SetUp(void)
46 {
47 DistributedDBToolsUnitTest::PrintTestCaseInfo();
48 }
49
TearDown(void)50 void DistributedDBCloudSyncerProgressManagerTest::TearDown(void)
51 {
52 }
53
54 /**
55 * @tc.name: SyncerMgrCheck001
56 * @tc.desc: Test case1 about Synchronization parameter
57 * @tc.type: FUNC
58 * @tc.require: SR000HPUOS
59 * @tc.author: huangboxin
60 */
61 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck001, TestSize.Level1)
62 {
63 // Synchronization parameter checks
64 MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface();
65 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
66 TestCloudSyncer cloudSyncer(storageProxy);
67 std::shared_ptr<MockICloudDB> idb = std::make_shared<MockICloudDB>();
68 cloudSyncer.SetMockICloudDB(idb);
69 std::vector<DeviceID> devices = {"cloud"};
70 std::vector<std::string> tables = {"TestTableA", "TestTableB" };
71
72 // check different sync mode
73 cloudSyncer.InitCloudSyncerForSync();
74
75 EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END));
76 EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK));
77 EXPECT_CALL(*idb, HeartBeat()).WillRepeatedly(Return(OK));
78 EXPECT_CALL(*idb, Lock()).WillRepeatedly(Return(std::pair<DBStatus, uint32_t>(OK, 10)));
79 EXPECT_CALL(*idb, UnLock()).WillRepeatedly(Return(OK));
80 EXPECT_CALL(*iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
81 EXPECT_CALL(*iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
82 EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
83 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
84 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK));
85 EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
86 EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
87 EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK));
88
89 SyncProcess res;
90 int errCode = cloudSyncer.Sync(devices, SYNC_MODE_CLOUD_FORCE_PUSH, tables, [&res](
__anon444c46650202( const std::map<std::string, SyncProcess> &process) 91 const std::map<std::string, SyncProcess> &process) {
92 res = process.begin()->second;
93 }, 5000);
94 EXPECT_EQ(errCode, E_OK);
95 std::this_thread::sleep_for(std::chrono::seconds(1));
96 EXPECT_EQ(res.process, FINISHED);
97
98 TestCloudSyncer cloudSyncer2(storageProxy);
99 cloudSyncer2.InitCloudSyncerForSync();
100 cloudSyncer2.SetMockICloudDB(idb);
101 errCode = cloudSyncer2.Sync(devices, SYNC_MODE_CLOUD_FORCE_PULL, tables, [&res](
__anon444c46650302( const std::map<std::string, SyncProcess> &process) 102 const std::map<std::string, SyncProcess> &process) {
103 res = process.begin()->second;
104 }, 5000);
105 EXPECT_EQ(errCode, E_OK);
106 std::this_thread::sleep_for(std::chrono::seconds(1));
107 EXPECT_EQ(res.process, FINISHED);
108
109 RuntimeContext::GetInstance()->StopTaskPool();
110 storageProxy.reset();
111 delete iCloud;
112 }
113
114 /**
115 * @tc.name: SyncerMgrCheck002
116 * @tc.desc: Test case2 about Synchronization parameter
117 * @tc.type: FUNC
118 * @tc.require: SR000HPUOS
119 * @tc.author: huangboxin
120 */
121 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck002, TestSize.Level1)
122 {
123 MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface();
124 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
125 std::shared_ptr<MockICloudDB> idb = std::make_shared<MockICloudDB>();
126 TestCloudSyncer cloudSyncer3(storageProxy);
127 cloudSyncer3.SetMockICloudDB(idb);
128 cloudSyncer3.InitCloudSyncerForSync();
129
130 std::vector<DeviceID> devices = {"cloud"};
131 std::vector<std::string> tables = {"TestTableA", "TestTableB" };
132 EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END));
133 EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK));
134 EXPECT_CALL(*idb, HeartBeat()).WillRepeatedly(Return(OK));
135 EXPECT_CALL(*idb, Lock()).WillRepeatedly(Return(std::pair<DBStatus, uint32_t>(OK, 10)));
136 EXPECT_CALL(*idb, UnLock()).WillRepeatedly(Return(OK));
137 EXPECT_CALL(*iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
138 EXPECT_CALL(*iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
139 EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
140 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
141 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK));
142 EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
143 EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
144 EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK));
145
146 SyncProcess res;
147 int errCode = cloudSyncer3.Sync(devices, SYNC_MODE_CLOUD_MERGE, tables, [&res](
__anon444c46650402( const std::map<std::string, SyncProcess> &process) 148 const std::map<std::string, SyncProcess> &process) {
149 res = process.begin()->second;
150 }, 5000);
151 EXPECT_EQ(errCode, E_OK);
152 std::this_thread::sleep_for(std::chrono::seconds(1));
153 EXPECT_EQ(res.process, FINISHED);
154
155 TestCloudSyncer cloudSyncer4(storageProxy);
156 cloudSyncer4.InitCloudSyncerForSync();
157 cloudSyncer4.SetMockICloudDB(idb);
158 errCode = cloudSyncer4.Sync(devices, SYNC_MODE_PULL_ONLY, tables, [&res](
__anon444c46650502( const std::map<std::string, SyncProcess> &process) 159 const std::map<std::string, SyncProcess> &process) {
160 res = process.begin()->second;
161 }, 5000);
162 EXPECT_EQ(errCode, -E_NOT_SUPPORT);
163 std::this_thread::sleep_for(std::chrono::seconds(1));
164 EXPECT_EQ(res.process, FINISHED);
165
166 RuntimeContext::GetInstance()->StopTaskPool();
167 storageProxy.reset();
168 delete iCloud;
169 idb = nullptr;
170 }
171
172 /**
173 * @tc.name: SyncerMgrCheck003
174 * @tc.desc: Test case2 about Synchronization parameter
175 * @tc.type: FUNC
176 * @tc.require: SR000HPUOS
177 * @tc.author: huangboxin
178 */
179 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck003, TestSize.Level1)
180 {
181 MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface();
182 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
183 TestCloudSyncer cloudSyncer5(storageProxy);
184 std::shared_ptr<MockICloudDB> idb = std::make_shared<MockICloudDB>();
185 cloudSyncer5.SetMockICloudDB(idb);
186 cloudSyncer5.InitCloudSyncerForSync();
187
188 std::vector<std::string> tables = {"TestTableA", "TestTableB" };
189 EXPECT_CALL(*idb, Query(_, _, _)).WillRepeatedly(Return(QUERY_END));
190 EXPECT_CALL(*idb, BatchInsert(_, _, _)).WillRepeatedly(Return(OK));
191 EXPECT_CALL(*idb, HeartBeat()).WillRepeatedly(Return(OK));
192 EXPECT_CALL(*idb, Lock()).WillRepeatedly(Return(std::pair<DBStatus, uint32_t>(OK, 10)));
193 EXPECT_CALL(*idb, UnLock()).WillRepeatedly(Return(OK));
194 EXPECT_CALL(*iCloud, StartTransaction(_)).WillRepeatedly(Return(E_OK));
195 EXPECT_CALL(*iCloud, PutCloudSyncData(_, _)).WillRepeatedly(Return(E_OK));
196 EXPECT_CALL(*iCloud, GetMetaData(_, _)).WillRepeatedly(Return(E_OK));
197 EXPECT_CALL(*iCloud, ChkSchema(_)).WillRepeatedly(Return(E_OK));
198 EXPECT_CALL(*iCloud, Commit()).WillRepeatedly(Return(E_OK));
199 EXPECT_CALL(*iCloud, GetUploadCount(_, _, _, _, _)).WillRepeatedly(Return(E_OK));
200 EXPECT_CALL(*iCloud, GetCloudTableSchema(_, _)).WillRepeatedly(Return(E_OK));
201 EXPECT_CALL(*iCloud, GetCloudData).WillRepeatedly(Return(E_OK));
202
203 SyncProcess res;
204 // check if device is empty
205 std::vector<DeviceID> devices = {};
206 int errCode = cloudSyncer5.Sync(devices, SYNC_MODE_CLOUD_MERGE, tables, [&res](
__anon444c46650602( const std::map<std::string, SyncProcess> &process) 207 const std::map<std::string, SyncProcess> &process) {
208 res = process.begin()->second;
209 }, 5000);
210 EXPECT_EQ(errCode, -E_INVALID_ARGS);
211 std::string invalidDevice = std::string(DBConstant::MAX_DEV_LENGTH + 1, '0');
212 devices.emplace_back(invalidDevice);
213 EXPECT_EQ(cloudSyncer5.Sync(devices, SYNC_MODE_CLOUD_MERGE, tables, nullptr, 5000), -E_INVALID_ARGS); // 5000 ms
214 std::this_thread::sleep_for(std::chrono::seconds(1));
215 RuntimeContext::GetInstance()->StopTaskPool();
216 storageProxy.reset();
217 delete iCloud;
218 idb = nullptr;
219 }
220 /**
221 * @tc.name: SyncerMgrCheck004
222 * @tc.desc: Test the number of queues
223
224 * @tc.type: FUNC
225 * @tc.require: SR000HPUOS
226 * @tc.author: huangboxin
227 */
228 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck004, TestSize.Level1)
229 {
230 // Check the number of queues
231 MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface();
232 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
233 TestCloudSyncer cloudSyncer(storageProxy);
234 std::shared_ptr<MockICloudDB> idb = std::make_shared<MockICloudDB>();
235 cloudSyncer.SetMockICloudDB(idb);
236 std::vector<std::string> tables = {"TestTableA", "TestTableB" };
237 SyncProcessCallback onProcess;
238 // current limit is 32;
239 for (int i = 1; i <= 32; i++) {
240 cloudSyncer.taskInfo_ = cloudSyncer.SetAndGetCloudTaskInfo(SYNC_MODE_CLOUD_FORCE_PUSH, tables, onProcess, 5000);
241 int errCode = cloudSyncer.CallTryToAddSyncTask(std::move(cloudSyncer.taskInfo_));
242 EXPECT_EQ(errCode, E_OK);
243 }
244 cloudSyncer.taskInfo_ = cloudSyncer.SetAndGetCloudTaskInfo(SYNC_MODE_CLOUD_FORCE_PUSH, tables, onProcess, 5000);
245 int errCode = cloudSyncer.CallTryToAddSyncTask(std::move(cloudSyncer.taskInfo_));
246 EXPECT_EQ(errCode, -E_BUSY);
247
248 cloudSyncer.PopTaskQueue();
249 cloudSyncer.PopTaskQueue();
250
251 // After pop task from taskQueue, it should be ok to call TryToAddSyncTask
252 cloudSyncer.taskInfo_ = cloudSyncer.SetAndGetCloudTaskInfo(SYNC_MODE_CLOUD_FORCE_PUSH, tables, onProcess, 5000);
253 errCode = cloudSyncer.CallTryToAddSyncTask(std::move(cloudSyncer.taskInfo_));
254 EXPECT_EQ(errCode, E_OK);
255
256 RuntimeContext::GetInstance()->StopTaskPool();
257 storageProxy.reset();
258 delete iCloud;
259 idb = nullptr;
260 }
261
262 /**
263 * @tc.name: SyncerMgrCheck005
264 * @tc.desc: Test Single-threaded execution of tasks
265 * @tc.type: FUNC
266 * @tc.require: SR000HPUOS
267 * @tc.author: huangboxin
268 */
269 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMgrCheck005, TestSize.Level1)
270 {
271 // Single-threaded execution of tasks
272 MockICloudSyncStorageInterface *iCloud = new MockICloudSyncStorageInterface();
273 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
274 TestCloudSyncer cloudSyncer(storageProxy);
275 std::shared_ptr<MockICloudDB> idb = std::make_shared<MockICloudDB>();
276 cloudSyncer.SetMockICloudDB(idb);
277
278 std::vector<string> devices = {"cloud"};
279 std::vector<std::string> tables = {"TestTableA", "TestTableB" };
280
281 cloudSyncer.InitCloudSyncer(0u, SYNC_MODE_CLOUD_FORCE_PUSH);
282 int errCode = cloudSyncer.CreateCloudTaskInfoAndCallTryToAddSync(SYNC_MODE_CLOUD_FORCE_PUSH, tables, {}, 5000);
283 errCode = cloudSyncer.CallPrepareSync(1u);
284 EXPECT_EQ(errCode, E_OK);
285
286 cloudSyncer.InitCloudSyncer(2u, SYNC_MODE_CLOUD_FORCE_PUSH);
287 errCode = cloudSyncer.CallPrepareSync(2u);
288 EXPECT_EQ(errCode, -E_DB_CLOSED);
289
290 RuntimeContext::GetInstance()->StopTaskPool();
291 storageProxy.reset();
292 delete iCloud;
293 idb = nullptr;
294 }
295
296 /**
297 * @tc.name: SyncerMockCheck001
298 * @tc.desc: Test Syncer pause tasks
299 * @tc.type: FUNC
300 * @tc.require:
301 * @tc.author: zhangqiquan
302 */
303 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMockCheck001, TestSize.Level0)
304 {
305 auto *iCloud = new MockICloudSyncStorageInterface();
306 ASSERT_NE(iCloud, nullptr);
307 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
308 auto cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy);
309 ASSERT_NE(cloudSyncer, nullptr);
310
311 cloudSyncer->SetCurrentContext(2u); // 2 is taskId
312 cloudSyncer->SetLastTaskId(3u); // 3 is taskId
313 cloudSyncer->SetCurrentTaskPause();
314 cloudSyncer->SetAssetFields("test", {{}});
315 cloudSyncer->SetAssetDownloadList(1);
316 EXPECT_EQ(cloudSyncer->CallDownloadAssets(), -E_TASK_PAUSED);
317 cloudSyncer->SetCurrentContext(0);
318 cloudSyncer->Close();
319 RefObject::KillAndDecObjRef(cloudSyncer);
320 storageProxy.reset();
321 delete iCloud;
322 }
323
324 /**
325 * @tc.name: SyncerMockCheck002
326 * @tc.desc: Test Syncer get current query
327 * @tc.type: FUNC
328 * @tc.require:
329 * @tc.author: zhangqiquan
330 */
331 HWTEST_F(DistributedDBCloudSyncerProgressManagerTest, SyncerMockCheck002, TestSize.Level0)
332 {
333 auto *iCloud = new MockICloudSyncStorageInterface();
334 std::shared_ptr<TestStorageProxy> storageProxy = std::make_shared<TestStorageProxy>(iCloud);
335 ASSERT_NE(iCloud, nullptr);
336 EXPECT_CALL(*iCloud, GetIdentify).WillRepeatedly(Return(""));
337 auto cloudSyncer = new(std::nothrow) TestCloudSyncer(storageProxy);
338 ASSERT_NE(cloudSyncer, nullptr);
339
340 // prepare current query and last query
341 // make them has diff sort type
342 const TaskId currentTask = 2u;
343 QuerySyncObject currentQuery;
344 currentQuery.SetTableName("current");
345 currentQuery.SetSortType(SortType::TIMESTAMP_ASC);
346 cloudSyncer->SetQuerySyncObject(currentTask, currentQuery);
347 const TaskId lastTask = 3u;
348 QuerySyncObject lastQuery;
349 lastQuery.SetTableName("last");
350 lastQuery.SetSortType(SortType::TIMESTAMP_DESC);
351 cloudSyncer->SetQuerySyncObject(lastTask, lastQuery);
352 cloudSyncer->SetCurrentContext(currentTask);
353 cloudSyncer->SetLastTaskId(lastTask);
354 // check get current query from syncer
355 QuerySyncObject actualQuery = cloudSyncer->CallGetQuerySyncObject(currentQuery.GetTableName());
356 EXPECT_EQ(actualQuery.GetSortType(), currentQuery.GetSortType());
357 EXPECT_NE(actualQuery.GetSortType(), lastQuery.GetSortType());
358
359 cloudSyncer->SetCurrentContext(0);
360 cloudSyncer->Close();
361 RefObject::KillAndDecObjRef(cloudSyncer);
362 storageProxy = nullptr;
363 delete iCloud;
364 }
365 }