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_tools_unit_test.h"
19 #include "single_ver_data_message_schedule.h"
20 #include "single_ver_data_packet.h"
21 #include "single_ver_kv_sync_task_context.h"
22 
23 using namespace testing::ext;
24 using namespace DistributedDB;
25 using namespace DistributedDBUnitTest;
26 using namespace std;
27 
28 namespace {
29 }
30 
31 class DistributedDBSingleVerMsgScheduleTest : public testing::Test {
32 public:
33     static void SetUpTestCase(void);
34     static void TearDownTestCase(void);
35     void SetUp();
36     void TearDown();
37 };
38 
SetUpTestCase(void)39 void DistributedDBSingleVerMsgScheduleTest::SetUpTestCase(void)
40 {
41 }
42 
TearDownTestCase(void)43 void DistributedDBSingleVerMsgScheduleTest::TearDownTestCase(void)
44 {
45 }
46 
SetUp(void)47 void DistributedDBSingleVerMsgScheduleTest::SetUp(void)
48 {
49 }
50 
TearDown(void)51 void DistributedDBSingleVerMsgScheduleTest::TearDown(void)
52 {
53 }
54 
55 /**
56  * @tc.name: MsgSchedule001
57  * @tc.desc: Test MsgSchedule function with normal sequenceId
58  * @tc.type: FUNC
59  * @tc.require:
60  * @tc.author: zhuwentao
61  */
62 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule001, TestSize.Level0)
63 {
64     /**
65      * @tc.steps: step1. put msg sequence_3, sequence_2, sequence_1
66      * @tc.expected: put msg ok
67      */
68     SingleVerDataMessageSchedule msgSchedule;
69     auto *context = new SingleVerKvSyncTaskContext();
70     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
71     DataSyncMessageInfo info;
72     info.sessionId_ = 10;
73     bool isNeedHandle = true;
74     bool isNeedContinue = true;
75     for (uint32_t i = 3; i >= 1; i--) {
76         info.sequenceId_ = i;
77         info.packetId_ = i;
78         DistributedDB::Message *message = nullptr;
79         DistributedDBToolsUnitTest::BuildMessage(info, message);
80         msgSchedule.PutMsg(message);
81         if (i > 1) {
82             Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
83             ASSERT_TRUE(msg == nullptr);
84         }
85     }
86     /**
87      * @tc.steps: step2. get msg
88      * @tc.expected: get msg by sequence_1, sequence_2, sequence_3
89      */
90     for (uint32_t i = 1; i <= 3; i++) {
91         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
92         ASSERT_TRUE(msg != nullptr);
93         EXPECT_EQ(isNeedContinue, true);
94         EXPECT_EQ(isNeedHandle, true);
95         EXPECT_EQ(msg->GetSequenceId(), i);
96         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
97         delete msg;
98     }
99     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
100     ASSERT_TRUE(msg == nullptr);
101     RefObject::KillAndDecObjRef(context);
102     context = nullptr;
103 }
104 
105 /**
106  * @tc.name: MsgSchedule002
107  * @tc.desc: Test MsgSchedule function with by low version
108  * @tc.type: FUNC
109  * @tc.require:
110  * @tc.author: zhuwentao
111  */
112 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule002, TestSize.Level0)
113 {
114     /**
115      * @tc.steps: step1. put msg session1_sequence1, session2_sequence1
116      * @tc.expected: put msg ok
117      */
118     SingleVerDataMessageSchedule msgSchedule;
119     auto *context = new SingleVerKvSyncTaskContext();
120     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_RELEASE_2_0);
121     DataSyncMessageInfo info;
122     bool isNeedHandle = true;
123     bool isNeedContinue = true;
124     for (uint32_t i = 1; i <= 2; i++) {
125         info.sessionId_ = i;
126         info.sequenceId_ = 1;
127         DistributedDB::Message *message = nullptr;
128         DistributedDBToolsUnitTest::BuildMessage(info, message);
129         msgSchedule.PutMsg(message);
130     }
131     /**
132      * @tc.steps: step2. get msg
133      * @tc.expected: get msg by session2_sequence1
134      */
135     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
136     ASSERT_TRUE(msg != nullptr);
137     EXPECT_EQ(isNeedContinue, true);
138     EXPECT_EQ(isNeedHandle, true);
139     EXPECT_EQ(msg->GetSequenceId(), 1u);
140     msgSchedule.ScheduleInfoHandle(false, false, msg);
141     delete msg;
142     msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
143     ASSERT_TRUE(msg == nullptr);
144     RefObject::KillAndDecObjRef(context);
145     context = nullptr;
146 }
147 
148 /**
149  * @tc.name: MsgSchedule003
150  * @tc.desc: Test MsgSchedule function with cross sessionId
151  * @tc.type: FUNC
152  * @tc.require:
153  * @tc.author: zhuwentao
154  */
155 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule003, TestSize.Level0)
156 {
157     /**
158      * @tc.steps: step1. put msg session1_seq1, session2_seq1, session1_seq2, session2_seq2, and handle session1_seq1
159      * @tc.expected: handle ok
160      */
161     SingleVerDataMessageSchedule msgSchedule;
162     auto *context = new SingleVerKvSyncTaskContext();
163     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
164     DataSyncMessageInfo info;
165     bool isNeedHandle = true;
166     bool isNeedContinue = true;
167     info.sessionId_ = 1;
168     info.sequenceId_ = 1;
169     info.packetId_ = 1;
170     DistributedDB::Message *message = nullptr;
171     DistributedDBToolsUnitTest::BuildMessage(info, message);
172     msgSchedule.PutMsg(message);
173     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
174     ASSERT_TRUE(msg != nullptr);
175     EXPECT_EQ(isNeedContinue, true);
176     EXPECT_EQ(isNeedHandle, true);
177     msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
178     delete msg;
179     info.sessionId_ = 2;
180     info.sequenceId_ = 1;
181     info.packetId_ = 1;
182     DistributedDBToolsUnitTest::BuildMessage(info, message);
183     msgSchedule.PutMsg(message);
184     info.sessionId_ = 1;
185     info.sequenceId_ = 2;
186     info.packetId_ = 2;
187     DistributedDBToolsUnitTest::BuildMessage(info, message);
188     msgSchedule.PutMsg(message);
189     info.sessionId_ = 2;
190     info.sequenceId_ = 2;
191     info.packetId_ = 2;
192     DistributedDBToolsUnitTest::BuildMessage(info, message);
193     msgSchedule.PutMsg(message);
194 
195     /**
196      * @tc.steps: step2. get msg
197      * @tc.expected: get msg by session2_seq1, session2_seq2
198      */
199     for (uint32_t i = 1; i <= 2; i++) {
200         msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
201         ASSERT_TRUE(msg != nullptr);
202         EXPECT_EQ(isNeedContinue, true);
203         EXPECT_EQ(isNeedHandle, true);
204         EXPECT_EQ(msg->GetSequenceId(), i);
205         EXPECT_EQ(msg->GetSessionId(), 2u);
206         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
207         delete msg;
208     }
209     msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
210     ASSERT_TRUE(msg == nullptr);
211     RefObject::KillAndDecObjRef(context);
212     context = nullptr;
213 }
214 
215 /**
216  * @tc.name: MsgSchedule004
217  * @tc.desc: Test MsgSchedule function with same sessionId with different packetId
218  * @tc.type: FUNC
219  * @tc.require:
220  * @tc.author: zhuwentao
221  */
222 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule004, TestSize.Level0)
223 {
224     /**
225      * @tc.steps: step1. put msg seq2_packet2, seq3_packet3, seq1_packet4, seq2_packet5, seq3_packet6
226      * @tc.expected: put msg ok
227      */
228     SingleVerDataMessageSchedule msgSchedule;
229     auto *context = new SingleVerKvSyncTaskContext();
230     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
231     DataSyncMessageInfo info;
232     info.sessionId_ = 10;
233     bool isNeedHandle = true;
234     bool isNeedContinue = true;
235     for (uint32_t i = 2; i <= 3; i++) {
236         info.sequenceId_ = i;
237         info.packetId_ = i;
238         DistributedDB::Message *message = nullptr;
239         DistributedDBToolsUnitTest::BuildMessage(info, message);
240         msgSchedule.PutMsg(message);
241         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
242         ASSERT_TRUE(msg == nullptr);
243     }
244     for (uint32_t i = 1; i <= 3; i++) {
245         info.sequenceId_ = i;
246         info.packetId_ = i + 3;
247         DistributedDB::Message *message = nullptr;
248         DistributedDBToolsUnitTest::BuildMessage(info, message);
249         msgSchedule.PutMsg(message);
250     }
251     /**
252      * @tc.steps: step2. get msg
253      * @tc.expected: drop seq2_packet2, seq3_packet3 and get seq1_packet4, seq2_packet5, seq3_packet6
254      */
255     isNeedHandle = true;
256     isNeedContinue = true;
257     for (uint32_t i = 1; i <= 3; i++) {
258         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
259         ASSERT_TRUE(msg != nullptr);
260         EXPECT_EQ(isNeedContinue, true);
261         EXPECT_EQ(isNeedHandle, true);
262         EXPECT_EQ(msg->GetSequenceId(), i);
263         const DataRequestPacket *packet = msg->GetObject<DataRequestPacket>();
264         EXPECT_EQ(packet->GetPacketId(), i + 3);
265         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
266         delete msg;
267     }
268     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
269     ASSERT_TRUE(msg == nullptr);
270     RefObject::KillAndDecObjRef(context);
271     context = nullptr;
272 }
273 
274 /**
275  * @tc.name: MsgSchedule005
276  * @tc.desc: Test MsgSchedule function with same sessionId with different packetId
277  * @tc.type: FUNC
278  * @tc.require:
279  * @tc.author: zhuwentao
280  */
281 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule005, TestSize.Level0)
282 {
283     /**
284      * @tc.steps: step1. put msg seq1_packet4, seq2_packet5, seq2_packet2, seq3_packet3
285      * @tc.expected: put msg ok
286      */
287     SingleVerDataMessageSchedule msgSchedule;
288     auto *context = new SingleVerKvSyncTaskContext();
289     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
290     DataSyncMessageInfo info;
291     info.sessionId_ = 10;
292     bool isNeedHandle = true;
293     bool isNeedContinue = true;
294     for (uint32_t i = 1; i <= 2; i++) {
295         info.sequenceId_ = i;
296         info.packetId_ = i + 3;
297         DistributedDB::Message *message = nullptr;
298         DistributedDBToolsUnitTest::BuildMessage(info, message);
299         msgSchedule.PutMsg(message);
300     }
301     for (uint32_t i = 2; i <= 3; i++) {
302         info.sequenceId_ = i;
303         info.packetId_ = i;
304         DistributedDB::Message *message = nullptr;
305         DistributedDBToolsUnitTest::BuildMessage(info, message);
306         msgSchedule.PutMsg(message);
307     }
308     /**
309      * @tc.steps: step2. get msg
310      * @tc.expected: drop seq2_packet2, seq3_packet3 and get seq1_packet4, seq2_packet5
311      */
312     isNeedHandle = true;
313     isNeedContinue = true;
314     for (uint32_t i = 1; i <= 2; i++) {
315         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
316         ASSERT_TRUE(msg != nullptr);
317         EXPECT_EQ(isNeedContinue, true);
318         EXPECT_EQ(isNeedHandle, true);
319         EXPECT_EQ(msg->GetSequenceId(), i);
320         const DataRequestPacket *packet = msg->GetObject<DataRequestPacket>();
321         EXPECT_EQ(packet->GetPacketId(), i + 3);
322         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
323         delete msg;
324     }
325     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
326     ASSERT_TRUE(msg == nullptr);
327     RefObject::KillAndDecObjRef(context);
328     context = nullptr;
329 }
330 
331 /**
332  * @tc.name: MsgSchedule006
333  * @tc.desc: Test MsgSchedule function with same sessionId and same sequenceId and packetId
334  * @tc.type: FUNC
335  * @tc.require:
336  * @tc.author: zhuwentao
337  */
338 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule006, TestSize.Level0)
339 {
340     /**
341      * @tc.steps: step1. put msg seq1_packet1, seq2_packet2
342      * @tc.expected: put msg ok
343      */
344     SingleVerDataMessageSchedule msgSchedule;
345     auto *context = new SingleVerKvSyncTaskContext();
346     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
347     DataSyncMessageInfo info;
348     info.sessionId_ = 10;
349     bool isNeedHandle = true;
350     bool isNeedContinue = true;
351     for (uint32_t i = 1; i <= 2; i++) {
352         info.sequenceId_ = i;
353         info.packetId_ = i;
354         DistributedDB::Message *message = nullptr;
355         DistributedDBToolsUnitTest::BuildMessage(info, message);
356         msgSchedule.PutMsg(message);
357     }
358     for (uint32_t i = 1; i <= 2; i++) {
359         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
360         ASSERT_TRUE(msg != nullptr);
361         EXPECT_EQ(isNeedContinue, true);
362         EXPECT_EQ(isNeedHandle, true);
363         EXPECT_EQ(msg->GetSequenceId(), i);
364         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
365         delete msg;
366     }
367     /**
368      * @tc.steps: step2. put msg seq1_packet1, seq2_packet2 again and seq3_packet3
369      * @tc.expected: get msg ok and get seq1_packet1, seq2_packet2 and seq3_packet3
370      */
371     for (uint32_t i = 1; i <= 3; i++) {
372         info.sequenceId_ = i;
373         info.packetId_ = i;
374         DistributedDB::Message *message = nullptr;
375         DistributedDBToolsUnitTest::BuildMessage(info, message);
376         msgSchedule.PutMsg(message);
377     }
378     isNeedHandle = true;
379     isNeedContinue = true;
380     for (uint32_t i = 1; i <= 3; i++) {
381         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
382         ASSERT_TRUE(msg != nullptr);
383         EXPECT_EQ(isNeedContinue, true);
384         EXPECT_EQ(isNeedHandle, (i == 3) ? true : false);
385         EXPECT_EQ(msg->GetSequenceId(), i);
386         const DataRequestPacket *packet = msg->GetObject<DataRequestPacket>();
387         EXPECT_EQ(packet->GetPacketId(), i);
388         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
389         delete msg;
390     }
391     Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
392     ASSERT_TRUE(msg == nullptr);
393     RefObject::KillAndDecObjRef(context);
394     context = nullptr;
395 }
396 
397 /**
398  * @tc.name: MsgSchedule007
399  * @tc.desc: Test MsgSchedule function with same sessionId and duplicate sequenceId and low packetId
400  * @tc.type: FUNC
401  * @tc.require:
402  * @tc.author: zhuwentao
403  */
404 HWTEST_F(DistributedDBSingleVerMsgScheduleTest, MsgSchedule007, TestSize.Level0)
405 {
406     /**
407      * @tc.steps: step1. put msg seq1_packet4, seq2_packet5
408      * @tc.expected: put msg ok and get msg seq1_packet4, seq2_packet5
409      */
410     SingleVerDataMessageSchedule msgSchedule;
411     auto *context = new SingleVerKvSyncTaskContext();
412     context->SetRemoteSoftwareVersion(SOFTWARE_VERSION_CURRENT);
413     DataSyncMessageInfo info;
414     info.sessionId_ = 10;
415     bool isNeedHandle = true;
416     bool isNeedContinue = true;
417     for (uint32_t i = 1; i <= 2; i++) {
418         info.sequenceId_ = i;
419         info.packetId_ = i + 3;
420         DistributedDB::Message *message = nullptr;
421         DistributedDBToolsUnitTest::BuildMessage(info, message);
422         msgSchedule.PutMsg(message);
423     }
424     for (uint32_t i = 1; i <= 2; i++) {
425         Message *msg = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
426         ASSERT_TRUE(msg != nullptr);
427         EXPECT_EQ(isNeedContinue, true);
428         EXPECT_EQ(isNeedHandle, true);
429         EXPECT_EQ(msg->GetSequenceId(), i);
430         const DataRequestPacket *packet = msg->GetObject<DataRequestPacket>();
431         EXPECT_EQ(packet->GetPacketId(), i + 3);
432         msgSchedule.ScheduleInfoHandle(isNeedHandle, false, msg);
433         delete msg;
434     }
435     Message *msg2 = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
436     ASSERT_TRUE(msg2 == nullptr);
437     /**
438      * @tc.steps: step2. put msg seq1_packet1, seq2_packet2
439      * @tc.expected: get nullptr
440      */
441     for (uint32_t i = 1; i <= 2; i++) {
442         info.sequenceId_ = i;
443         info.packetId_ = i;
444         DistributedDB::Message *message = nullptr;
445         DistributedDBToolsUnitTest::BuildMessage(info, message);
446         msgSchedule.PutMsg(message);
447     }
448     isNeedHandle = true;
449     isNeedContinue = true;
450     for (uint32_t i = 1; i <= 3; i++) {
451         Message *msg3 = msgSchedule.MoveNextMsg(context, isNeedHandle, isNeedContinue);
452         EXPECT_EQ(isNeedContinue, true);
453         ASSERT_TRUE(msg3 == nullptr);
454     }
455     RefObject::KillAndDecObjRef(context);
456     context = nullptr;
457 }