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 * @tc.steps: step2. Register the OnMessageCallback to virtual communicator
206 */
207 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
208 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
209 /**
210 * @tc.steps: step3. Fetch timeOffset value
211 * @tc.expected: step3. (offsetB - offsetA ) - timeOffset < 100ms.
212 */
213 TimeOffset timeOffset;
214 g_timeSyncA->GetTimeOffset(timeOffset, TIME_SYNC_WAIT_TIME);
215 TimeOffset offsetB = g_metadataB->GetLocalTimeOffset();
216 TimeOffset offsetA = g_metadataA->GetLocalTimeOffset();
217 EXPECT_TRUE(abs(offsetB - offsetA - timeOffset) < NETWORK_DELAY);
218 }
219
220 /**
221 * @tc.name: NormalSync003
222 * @tc.desc: Verify time sync function is normal between two time sync instance with different localTimeOffset.
223 * @tc.type: FUNC
224 * @tc.require: AR000C05EP AR000CQE0G
225 * @tc.author: wumin
226 */
227 HWTEST_F(DistributedDBTimeSyncTest, NormalSync003, TestSize.Level0)
228 {
229 /**
230 * @tc.steps: step1. Initialize the time sync A and B
231 * @tc.steps: step2. Write the timeOffset into time sync A and B
232 * @tc.expected: step1. Initialize time sync A and B successfully
233 * @tc.expected: step2. Write the timeOffset into time sync A and B successfully.
234 */
235 g_metadataA->Initialize(g_syncInterfaceA);
236
237 // set timeOffset for timeSyncA
238 TimeOffset offsetA = 1;
239 g_metadataA->SaveLocalTimeOffset(offsetA);
240
241 int errCode;
242 // initialize timeSyncA
243 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
244 EXPECT_TRUE(errCode == E_OK);
245
246 // set timeOffset for timeSyncA
247 g_metadataB->Initialize(g_syncInterfaceB);
248 TimeOffset offsetB = 100 * 1000 * 1000;
249 g_metadataB->SaveLocalTimeOffset(offsetB);
250
251 // initialize timeSyncB
252 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
253 EXPECT_TRUE(errCode == E_OK);
254 /**
255 * @tc.steps: step3. Register the OnMessageCallback to virtual communicator
256 */
257 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
258 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
259 /**
260 * @tc.steps: step4. Fetch timeOffset value
261 * @tc.expected: step4. (offsetB - offsetA ) - timeOffset < 100ms.
262 */
263 TimeOffset timeOffset = 0;
264 g_timeSyncA->GetTimeOffset(timeOffset, TIME_SYNC_WAIT_TIME);
265
266 TimeOffset absTimeOffset = abs(timeOffset);
267 EXPECT_TRUE(abs(offsetB - offsetA - absTimeOffset) < NETWORK_DELAY);
268 }
269
270 /**
271 * @tc.name: NetDisconnetSyncTest001
272 * @tc.desc: Verify time sync function return failed when the virtual communicator disabled.
273 * @tc.type: FUNC
274 * @tc.require: AR000C05EP AR000CQE0G
275 * @tc.author: wumin
276 */
277 HWTEST_F(DistributedDBTimeSyncTest, NetDisconnetSyncTest001, TestSize.Level0)
278 {
279 /**
280 * @tc.steps: step1. Initialize the time sync A and B
281 * @tc.expected: step1. Initialize time sync A and B successfully
282 */
283 g_metadataA->Initialize(g_syncInterfaceA);
284 int errCode;
285 // initialize timeSyncA
286 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
287 EXPECT_TRUE(errCode == E_OK);
288
289 g_metadataB->Initialize(g_syncInterfaceB);
290 // initialize timeSyncB
291 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
292 EXPECT_TRUE(errCode == E_OK);
293
294 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
295 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
296 /**
297 * @tc.steps: step2. Disable the virtual communicator
298 */
299 g_virtualCommunicator->Disable();
300 /**
301 * @tc.steps: step3. Start time sync function
302 * @tc.expected: step3. time sync return -E_PERIPHERAL_INTERFACE_FAIL
303 */
304 errCode = g_timeSyncA->SyncStart();
305 EXPECT_TRUE(errCode == -E_PERIPHERAL_INTERFACE_FAIL);
306 }
307
308 /**
309 * @tc.name: InvalidMessgeTest001
310 * @tc.desc: Verify RequestReceive() return failed with invalid input.
311 * @tc.type: FUNC
312 * @tc.require: AR000C05EP AR000CQE0G
313 * @tc.author: wumin
314 */
315 HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest001, TestSize.Level0)
316 {
317 /**
318 * @tc.steps: step1. Initialize the time sync A and B
319 * @tc.expected: step1. Initialize time sync A and B successfully
320 */
321 g_metadataA->Initialize(g_syncInterfaceA);
322 int errCode;
323 // initialize timeSyncA
324 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
325 EXPECT_TRUE(errCode == E_OK);
326
327 g_metadataB->Initialize(g_syncInterfaceB);
328 // initialize timeSyncB
329 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
330 EXPECT_TRUE(errCode == E_OK);
331
332 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
333
334 Message *msg = new (std::nothrow) Message();
335 ASSERT_TRUE(msg != nullptr);
336
337 /**
338 * @tc.steps: step2. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_REQUEST and no data set
339 * @tc.expected: step2. RequestRecv() return -E_INVALID_ARGS
340 */
341 msg->SetMessageId(TIME_SYNC_MESSAGE);
342 msg->SetMessageType(TYPE_REQUEST);
343 SendConfig conf = {false, false, 0};
344 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
345 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
346
347 TimeSyncPacket data;
348 data.SetSourceTimeBegin(0);
349 data.SetSourceTimeEnd(0);
350 data.SetTargetTimeBegin(0);
351 data.SetTargetTimeEnd(0);
352 /**
353 * @tc.steps: step3. SendMessage with id = DATA_SYNC_MESSAGE, type = TYPE_REQUEST
354 * @tc.expected: step3. RequestRecv() return -E_INVALID_ARGS
355 */
356 msg = new (std::nothrow) Message();
357 ASSERT_TRUE(msg != nullptr);
358 msg->SetMessageId(DATA_SYNC_MESSAGE);
359 msg->SetMessageType(TYPE_REQUEST);
360 msg->SetCopiedObject<>(data);
361 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
362 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
363 /**
364 * @tc.steps: step4. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_RESPONSE
365 * @tc.expected: step4. RequestRecv() return -E_INVALID_ARGS
366 */
367 msg = new (std::nothrow) Message();
368 ASSERT_TRUE(msg != nullptr);
369 msg->SetMessageId(TIME_SYNC_MESSAGE);
370 msg->SetMessageType(TYPE_RESPONSE);
371 msg->SetCopiedObject<>(data);
372 errCode = g_virtualCommunicator->SendMessage(DEVICE_B, msg, conf);
373 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
374 }
375
376 /**
377 * @tc.name: InvalidMessgeTest002
378 * @tc.desc: Verify AckRec() return failed with invalid input.
379 * @tc.type: FUNC
380 * @tc.require: AR000C05EP AR000CQE0G
381 * @tc.author: wumin
382 */
383 HWTEST_F(DistributedDBTimeSyncTest, InvalidMessgeTest002, TestSize.Level0)
384 {
385 /**
386 * @tc.steps: step1. Initialize the time sync A and B
387 * @tc.expected: step1. Initialize time sync A and B successfully
388 */
389 g_metadataA->Initialize(g_syncInterfaceA);
390 int errCode;
391 // initialize timeSyncA
392 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
393 EXPECT_TRUE(errCode == E_OK);
394
395 g_metadataB->Initialize(g_syncInterfaceB);
396 // initialize timeSyncB
397 errCode = g_timeSyncB->Initialize(g_virtualCommunicator, g_metadataB, g_syncInterfaceB, DEVICE_A);
398 EXPECT_TRUE(errCode == E_OK);
399 g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
400 g_virtualCommunicator->SetTimeSync(g_timeSyncA, g_timeSyncB, DEVICE_A, g_syncTaskContext);
401
402 Message *msg = new (std::nothrow) Message();
403 ASSERT_TRUE(msg != nullptr);
404
405 /**
406 * @tc.steps: step2. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_RESPONSE and no data set
407 * @tc.expected: step2. AckRecv() return -E_INVALID_ARGS
408 */
409 msg->SetMessageId(TIME_SYNC_MESSAGE);
410 msg->SetMessageType(TYPE_RESPONSE);
411 SendConfig conf = {false, false, 0};
412 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
413 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
414
415 TimeSyncPacket data;
416 data.SetSourceTimeBegin(0);
417 data.SetSourceTimeEnd(0);
418 data.SetTargetTimeBegin(0);
419 data.SetTargetTimeEnd(0);
420 /**
421 * @tc.steps: step3. SendMessage with id = DATA_SYNC_MESSAGE, type = TYPE_RESPONSE and no data set
422 * @tc.expected: step3. AckRecv() return -E_INVALID_ARGS
423 */
424 msg = new (std::nothrow) Message();
425 ASSERT_TRUE(msg != nullptr);
426 msg->SetMessageId(DATA_SYNC_MESSAGE);
427 msg->SetMessageType(TYPE_RESPONSE);
428 msg->SetCopiedObject<>(data);
429 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
430 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
431 /**
432 * @tc.steps: step4. SendMessage with id = TIME_SYNC_MESSAGE, type = TYPE_REQUEST and no data set
433 * @tc.expected: step4. AckRecv() return -E_INVALID_ARGS
434 */
435 msg = new (std::nothrow) Message();
436 ASSERT_TRUE(msg != nullptr);
437 msg->SetMessageId(TIME_SYNC_MESSAGE);
438 msg->SetMessageType(TYPE_REQUEST);
439 msg->SetCopiedObject<>(data);
440 errCode = g_virtualCommunicator->SendMessage(DEVICE_A, msg, conf);
441 EXPECT_TRUE(errCode == -E_INVALID_ARGS);
442 }
443
444 /**
445 * @tc.name: SyncTimeout001
446 * @tc.desc: Verify the timeout scenario for time sync.
447 * @tc.type: FUNC
448 * @tc.require: AR000C05EP AR000CQE0G
449 * @tc.author: wumin
450 */
451 HWTEST_F(DistributedDBTimeSyncTest, SyncTimeout001, TestSize.Level2)
452 {
453 // initialize timeSyncA
454 g_metadataA->Initialize(g_syncInterfaceA);
455 int errCode;
456 errCode = g_timeSyncA->Initialize(g_virtualCommunicator, g_metadataA, g_syncInterfaceA, DEVICE_B);
457 EXPECT_TRUE(errCode == E_OK);
458
459 /**
460 * @tc.steps: step1. Initialize the syncTaskContext
461 * @tc.expected: step1. Initialize syncTaskContext successfully
462 */
463 errCode = g_syncTaskContext->Initialize(DEVICE_B, g_syncInterfaceA, g_metadataA, g_virtualCommunicator);
464 EXPECT_TRUE(errCode == E_OK);
465 /**
466 * @tc.steps: step2. Start the time syc task invoking StartSync() method
467 * @tc.expected: step2. Start the time sync task return E_TIMEOUT
468 */
469 TimeOffset offset;
470 errCode = g_timeSyncA->GetTimeOffset(offset, TIME_SYNC_WAIT_TIME);
471 EXPECT_TRUE(errCode == -E_TIMEOUT);
472 }