1 /*
2 * Copyright (c) 2021 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 <gtest/gtest.h>
17
18 #include "distributeddb_data_generate_unit_test.h"
19 #include "distributeddb_tools_unit_test.h"
20 #include "isyncer.h"
21 #include "single_ver_sync_state_machine.h"
22 #include "single_ver_kv_sync_task_context.h"
23 #include "sync_types.h"
24 #include "virtual_single_ver_sync_db_Interface.h"
25 #include "virtual_time_sync_communicator.h"
26
27 using namespace std;
28 using namespace testing::ext;
29 using namespace DistributedDB;
30
31 namespace {
32 const std::string DEVICE_A = "deviceA";
33 const std::string DEVICE_B = "deviceB";
34 VirtualTimeSyncCommunicator *g_virtualCommunicator = nullptr;
35 TimeSync *g_timeSyncA = nullptr;
36 TimeSync *g_timeSyncB = nullptr;
37 VirtualSingleVerSyncDBInterface *g_syncInterfaceA = nullptr;
38 VirtualSingleVerSyncDBInterface *g_syncInterfaceB = nullptr;
39 std::shared_ptr<Metadata> g_metadataA = nullptr;
40 std::shared_ptr<Metadata> g_metadataB = nullptr;
41 SingleVerSyncTaskContext *g_syncTaskContext = nullptr;
42 const int NETWORK_DELAY = 100 * 1000; // 100ms
43 }
44
45 class DistributedDBTimeSyncTest : public testing::Test {
46 public:
47 static void SetUpTestCase(void);
48 static void TearDownTestCase(void);
49 void SetUp();
50 void TearDown();
51 };
52
SetUpTestCase(void)53 void DistributedDBTimeSyncTest::SetUpTestCase(void)
54 {
55 /**
56 * @tc.setup: NA
57 */
58 }
59
TearDownTestCase(void)60 void DistributedDBTimeSyncTest::TearDownTestCase(void)
61 {
62 /**
63 * @tc.teardown: NA
64 */
65 }
66
SetUp(void)67 void DistributedDBTimeSyncTest::SetUp(void)
68 {
69 DistributedDBUnitTest::DistributedDBToolsUnitTest::PrintTestCaseInfo();
70 /**
71 * @tc.setup: create the instance for virtual communicator, virtual storage component and time syncer
72 */
73 g_virtualCommunicator = new (std::nothrow) VirtualTimeSyncCommunicator();
74 ASSERT_TRUE(g_virtualCommunicator != nullptr);
75
76 g_syncInterfaceA = new (std::nothrow) VirtualSingleVerSyncDBInterface();
77 ASSERT_TRUE(g_syncInterfaceA != nullptr);
78
79 g_metadataA = std::make_shared<Metadata>();
80
81 g_syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface;
82 ASSERT_TRUE(g_syncInterfaceB != nullptr);
83
84 g_metadataB = std::make_shared<Metadata>();
85
86 g_timeSyncA = new (std::nothrow) TimeSync();
87 ASSERT_TRUE(g_timeSyncA != nullptr);
88
89 g_timeSyncB = new (std::nothrow) TimeSync();
90 ASSERT_TRUE(g_timeSyncB != nullptr);
91
92 g_syncTaskContext = new (std::nothrow) SingleVerKvSyncTaskContext();
93 ASSERT_TRUE(g_syncTaskContext != nullptr);
94 }
95
TearDown(void)96 void DistributedDBTimeSyncTest::TearDown(void)
97 {
98 /**
99 * @tc.teardown: delete the ptr for testing
100 */
101 if (g_syncTaskContext != nullptr) {
102 RefObject::DecObjRef(g_syncTaskContext);
103 g_syncTaskContext = nullptr;
104 }
105 if (g_syncInterfaceA != nullptr) {
106 delete g_syncInterfaceA;
107 g_syncInterfaceA = nullptr;
108 }
109 if (g_syncInterfaceB != nullptr) {
110 delete g_syncInterfaceB;
111 g_syncInterfaceB = nullptr;
112 }
113
114 g_metadataA = nullptr;
115 g_metadataB = nullptr;
116 if (g_timeSyncA != nullptr) {
117 delete g_timeSyncA;
118 g_timeSyncA = nullptr;
119 }
120 if (g_timeSyncB != nullptr) {
121 delete g_timeSyncB;
122 g_timeSyncB = nullptr;
123 }
124 if (g_virtualCommunicator != nullptr) {
125 delete g_virtualCommunicator;
126 g_virtualCommunicator = nullptr;
127 }
128 }
129
130 /**
131 * @tc.name: NormalSync001
132 * @tc.desc: Verify time sync function is normal between two time sync instance with different timestamp.
133 * @tc.type: FUNC
134 * @tc.require: AR000C05EP AR000CQE0G
135 * @tc.author: wumin
136 */
137 HWTEST_F(DistributedDBTimeSyncTest, NormalSync001, TestSize.Level0)
138 {
139 /**
140 * @tc.steps: step1. Initialize the time sync A and B
141 * @tc.steps: step2. Write the timestamp into virtual storage component
142 * @tc.expected: step1. Initialize time sync A and B successfully
143 * @tc.expected: step2. Write the timestamp into virtual storage component successfully.
144 */
145 g_metadataA->Initialize(g_syncInterfaceA);
146 TimeOffset offsetA = 100 * 1000 * 1000; // 100 seconds
147 // set timestamp for A virtual storage component
148 g_syncInterfaceA->PutData(DistributedDBUnitTest::KEY_1, DistributedDBUnitTest::VALUE_1,
149 TimeHelper::GetSysCurrentTime() + TimeHelper::BASE_OFFSET + offsetA, 0);
150 int errCode;
151 // initialize timeSyncA
152 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
153 EXPECT_TRUE(errCode == E_OK);
154
155 g_metadataB->Initialize(g_syncInterfaceB);
156 TimeOffset offsetB = 200 * 1000 * 1000; // 200 seconds
157 // set timestamp for B virtual storage component
158 g_syncInterfaceB->PutData(DistributedDBUnitTest::KEY_1, DistributedDBUnitTest::VALUE_1,
159 TimeHelper::GetSysCurrentTime() + TimeHelper::BASE_OFFSET + offsetB, 0);
160 // initialize timeSyncB
161 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
162 EXPECT_TRUE(errCode == E_OK);
163
164 /**
165 * @tc.steps: step3. Register the OnMessageCallback to virtual communicator
166 */
167 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
168 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
169
170 /**
171 * @tc.steps: step4. Fetch timeOffset value
172 * @tc.expected: step4. (offsetB - offsetA ) - timeOffset < 100ms.
173 */
174 TimeOffset timeOffset = 0;
175 g_timeSyncA->GetTimeOffset(timeOffset, TIME_SYNC_WAIT_TIME);
176 offsetB = g_metadataB->GetLocalTimeOffset();
177 offsetA = g_metadataA->GetLocalTimeOffset();
178 EXPECT_TRUE(abs(offsetB - offsetA - timeOffset) < NETWORK_DELAY);
179 }
180
181 /**
182 * @tc.name: NormalSync002
183 * @tc.desc: Verify time sync function is normal between two time sync instance with the same timestamp.
184 * @tc.type: FUNC
185 * @tc.require: AR000C05EP AR000CQE0G
186 * @tc.author: wumin
187 */
188 HWTEST_F(DistributedDBTimeSyncTest, NormalSync002, TestSize.Level0)
189 {
190 /**
191 * @tc.steps: step1. Initialize the time sync A and B
192 * @tc.expected: step1. Initialize time sync A and B successfully
193 */
194 g_metadataA->Initialize(g_syncInterfaceA);
195 int errCode;
196 // initialize timeSyncA
197 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
198 EXPECT_TRUE(errCode == E_OK);
199
200 g_metadataB->Initialize(g_syncInterfaceB);
201 // initialize timeSyncB
202 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
203 EXPECT_TRUE(errCode == E_OK);
204
205 /**
206 * @tc.steps: step2. Register the OnMessageCallback to virtual communicator
207 */
208 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
209 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
210
211 /**
212 * @tc.steps: step3. Fetch timeOffset value
213 * @tc.expected: step3. (offsetB - offsetA ) - timeOffset < 100ms.
214 */
215 TimeOffset timeOffset;
216 g_timeSyncA->GetTimeOffset(timeOffset, TIME_SYNC_WAIT_TIME);
217 TimeOffset offsetB = g_metadataB->GetLocalTimeOffset();
218 TimeOffset offsetA = g_metadataA->GetLocalTimeOffset();
219 EXPECT_TRUE(abs(offsetB - offsetA - timeOffset) < NETWORK_DELAY);
220 }
221
222 /**
223 * @tc.name: NormalSync003
224 * @tc.desc: Verify time sync function is normal between two time sync instance with different localTimeOffset.
225 * @tc.type: FUNC
226 * @tc.require: AR000C05EP AR000CQE0G
227 * @tc.author: wumin
228 */
229 HWTEST_F(DistributedDBTimeSyncTest, NormalSync003, TestSize.Level0)
230 {
231 /**
232 * @tc.steps: step1. Initialize the time sync A and B
233 * @tc.steps: step2. Write the timeOffset into time sync A and B
234 * @tc.expected: step1. Initialize time sync A and B successfully
235 * @tc.expected: step2. Write the timeOffset into time sync A and B successfully.
236 */
237 g_metadataA->Initialize(g_syncInterfaceA);
238
239 // set timeOffset for timeSyncA
240 TimeOffset offsetA = 1;
241 g_metadataA->SaveLocalTimeOffset(offsetA);
242
243 int errCode;
244 // initialize timeSyncA
245 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
246 EXPECT_TRUE(errCode == E_OK);
247
248 // set timeOffset for timeSyncA
249 g_metadataB->Initialize(g_syncInterfaceB);
250 TimeOffset offsetB = 100 * 1000 * 1000;
251 g_metadataB->SaveLocalTimeOffset(offsetB);
252
253 // initialize timeSyncB
254 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
255 EXPECT_TRUE(errCode == E_OK);
256
257 /**
258 * @tc.steps: step3. Register the OnMessageCallback to virtual communicator
259 */
260 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
261 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
262
263 /**
264 * @tc.steps: step4. Fetch timeOffset value
265 * @tc.expected: step4. (offsetB - offsetA ) - timeOffset < 100ms.
266 */
267 TimeOffset timeOffset = 0;
268 g_timeSyncA->GetTimeOffset(timeOffset, TIME_SYNC_WAIT_TIME);
269
270 TimeOffset absTimeOffset = abs(timeOffset);
271 EXPECT_TRUE(abs(offsetB - offsetA - absTimeOffset) < NETWORK_DELAY);
272 }
273
274 /**
275 * @tc.name: NetDisconnetSyncTest001
276 * @tc.desc: Verify time sync function return failed when the virtual communicator disabled.
277 * @tc.type: FUNC
278 * @tc.require: AR000C05EP AR000CQE0G
279 * @tc.author: wumin
280 */
281 HWTEST_F(DistributedDBTimeSyncTest, NetDisconnetSyncTest001, TestSize.Level0)
282 {
283 /**
284 * @tc.steps: step1. Initialize the time sync A and B
285 * @tc.expected: step1. Initialize time sync A and B successfully
286 */
287 g_metadataA->Initialize(g_syncInterfaceA);
288 int errCode;
289 // initialize timeSyncA
290 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
291 EXPECT_TRUE(errCode == E_OK);
292
293 g_metadataB->Initialize(g_syncInterfaceB);
294 // initialize timeSyncB
295 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
296 EXPECT_TRUE(errCode == E_OK);
297
298 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
299 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
300
301 /**
302 * @tc.steps: step2. Disable the virtual communicator
303 */
304 g_virtualCommunicator->Disable();
305
306 /**
307 * @tc.steps: step3. Start time sync function
308 * @tc.expected: step3. time sync return -E_PERIPHERAL_INTERFACE_FAIL
309 */
310 errCode = g_timeSyncA->SyncStart();
311 EXPECT_TRUE(errCode == -E_PERIPHERAL_INTERFACE_FAIL);
312 }
313
314 /**
315 * @tc.name: InvalidMessgeTest001
316 * @tc.desc: Verify RequestReceive() return failed with invalid input.
317 * @tc.type: FUNC
318 * @tc.require: AR000C05EP AR000CQE0G
319 * @tc.author: wumin
320 */
321 HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest001, TestSize.Level0)
322 {
323 /**
324 * @tc.steps: step1. Initialize the time sync A and B
325 * @tc.expected: step1. Initialize time sync A and B successfully
326 */
327 g_metadataA->Initialize(g_syncInterfaceA);
328 int errCode;
329 // initialize timeSyncA
330 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
331 EXPECT_TRUE(errCode == E_OK);
332
333 g_metadataB->Initialize(g_syncInterfaceB);
334 // initialize timeSyncB
335 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
336 EXPECT_TRUE(errCode == E_OK);
337
338 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
339
340 Message *msg = new (std::nothrow) Message();
341 ASSERT_TRUE(msg != nullptr);
342
343 /**
344 * @tc.steps: step2. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_REQUEST and no data set
345 * @tc.expected: step2. RequestRecv() return -E_INVALID_ARGS
346 */
347 msg->SetMessageId(TIME_SYNC_MESSAGE);
348 msg->SetMessageType(TYPE_REQUEST);
349 SendConfig conf = {false, false, 0};
350 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
351 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
352
353 TimeSyncPacket data;
354 data.SetSourceTimeBegin(0);
355 data.SetSourceTimeEnd(0);
356 data.SetTargetTimeBegin(0);
357 data.SetTargetTimeEnd(0);
358
359 /**
360 * @tc.steps: step3. SendMessage with id = DATA_SYNC_MESSAGE, type = TYPE_REQUEST
361 * @tc.expected: step3. RequestRecv() return -E_INVALID_ARGS
362 */
363 msg = new (std::nothrow) Message();
364 ASSERT_TRUE(msg != nullptr);
365 msg->SetMessageId(DATA_SYNC_MESSAGE);
366 msg->SetMessageType(TYPE_REQUEST);
367 msg->SetCopiedObject<>(data);
368 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
369 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
370
371 /**
372 * @tc.steps: step4. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_RESPONSE
373 * @tc.expected: step4. RequestRecv() return -E_INVALID_ARGS
374 */
375 msg = new (std::nothrow) Message();
376 ASSERT_TRUE(msg != nullptr);
377 msg->SetMessageId(TIME_SYNC_MESSAGE);
378 msg->SetMessageType(TYPE_RESPONSE);
379 msg->SetCopiedObject<>(data);
380 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
381 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
382 }
383
384 /**
385 * @tc.name: InvalidMessgeTest002
386 * @tc.desc: Verify AckRec() return failed with invalid input.
387 * @tc.type: FUNC
388 * @tc.require: AR000C05EP AR000CQE0G
389 * @tc.author: wumin
390 */
391 HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest002, TestSize.Level0)
392 {
393 /**
394 * @tc.steps: step1. Initialize the time sync A and B
395 * @tc.expected: step1. Initialize time sync A and B successfully
396 */
397 g_metadataA->Initialize(g_syncInterfaceA);
398 int errCode;
399 // initialize timeSyncA
400 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
401 EXPECT_TRUE(errCode == E_OK);
402
403 g_metadataB->Initialize(g_syncInterfaceB);
404 // initialize timeSyncB
405 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
406 EXPECT_TRUE(errCode == E_OK);
407
408 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
409 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
410
411 Message *msg = new (std::nothrow) Message();
412 ASSERT_TRUE(msg != nullptr);
413
414 /**
415 * @tc.steps: step2. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_RESPONSE and no data set
416 * @tc.expected: step2. AckRecv() return -E_INVALID_ARGS
417 */
418 msg->SetMessageId(TIME_SYNC_MESSAGE);
419 msg->SetMessageType(TYPE_RESPONSE);
420 SendConfig conf = {false, false, 0};
421 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
422 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
423
424 TimeSyncPacket data;
425 data.SetSourceTimeBegin(0);
426 data.SetSourceTimeEnd(0);
427 data.SetTargetTimeBegin(0);
428 data.SetTargetTimeEnd(0);
429
430 /**
431 * @tc.steps: step3. SendMessage with id = DATA_SYNC_MESSAGE, type = TYPE_RESPONSE and no data set
432 * @tc.expected: step3. AckRecv() return -E_INVALID_ARGS
433 */
434 msg = new (std::nothrow) Message();
435 ASSERT_TRUE(msg != nullptr);
436 msg->SetMessageId(DATA_SYNC_MESSAGE);
437 msg->SetMessageType(TYPE_RESPONSE);
438 msg->SetCopiedObject<>(data);
439 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
440 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
441
442 /**
443 * @tc.steps: step4. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_REQUEST and no data set
444 * @tc.expected: step4. AckRecv() return -E_INVALID_ARGS
445 */
446 msg = new (std::nothrow) Message();
447 ASSERT_TRUE(msg != nullptr);
448 msg->SetMessageId(TIME_SYNC_MESSAGE);
449 msg->SetMessageType(TYPE_REQUEST);
450 msg->SetCopiedObject<>(data);
451 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
452 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
453 }
454
455 /**
456 * @tc.name: SyncTimeout001
457 * @tc.desc: Verify the timeout scenario for time sync.
458 * @tc.type: FUNC
459 * @tc.require: AR000C05EP AR000CQE0G
460 * @tc.author: wumin
461 */
462 HWTEST_F(DistributedDBTimeSyncTest, SyncTimeout001, TestSize.Level2)
463 {
464 // initialize timeSyncA
465 g_metadataA->Initialize(g_syncInterfaceA);
466 int errCode;
467 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
468 EXPECT_TRUE(errCode == E_OK);
469
470 /**
471 * @tc.steps: step1. Initialize the syncTaskContext
472 * @tc.expected: step1. Initialize syncTaskContext successfully
473 */
474 errCode = g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
475 EXPECT_TRUE(errCode == E_OK);
476
477 /**
478 * @tc.steps: step2. Start the time syc task invoking StartSync() method
479 * @tc.expected: step2. Start the time sync task return E_TIMEOUT
480 */
481 TimeOffset offset;
482 errCode = g_timeSyncA->GetTimeOffset(offset, TIME_SYNC_WAIT_TIME);
483 EXPECT_TRUE(errCode == -E_TIMEOUT);
484 }