xref: /aosp_15_r20/external/webrtc/net/dcsctp/packet/chunk_validators_test.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "net/dcsctp/packet/chunk_validators.h"
11 
12 #include <utility>
13 
14 #include "rtc_base/gunit.h"
15 #include "test/gmock.h"
16 
17 namespace dcsctp {
18 namespace {
19 using ::testing::ElementsAre;
20 using ::testing::IsEmpty;
21 
TEST(ChunkValidatorsTest,NoGapAckBlocksAreValid)22 TEST(ChunkValidatorsTest, NoGapAckBlocksAreValid) {
23   SackChunk sack(TSN(123), /*a_rwnd=*/456,
24                  /*gap_ack_blocks=*/{}, {});
25 
26   EXPECT_TRUE(ChunkValidators::Validate(sack));
27 
28   SackChunk clean = ChunkValidators::Clean(std::move(sack));
29   EXPECT_THAT(clean.gap_ack_blocks(), IsEmpty());
30 }
31 
TEST(ChunkValidatorsTest,OneValidAckBlock)32 TEST(ChunkValidatorsTest, OneValidAckBlock) {
33   SackChunk sack(TSN(123), /*a_rwnd=*/456, {SackChunk::GapAckBlock(2, 3)}, {});
34 
35   EXPECT_TRUE(ChunkValidators::Validate(sack));
36 
37   SackChunk clean = ChunkValidators::Clean(std::move(sack));
38   EXPECT_THAT(clean.gap_ack_blocks(),
39               ElementsAre(SackChunk::GapAckBlock(2, 3)));
40 }
41 
TEST(ChunkValidatorsTest,TwoValidAckBlocks)42 TEST(ChunkValidatorsTest, TwoValidAckBlocks) {
43   SackChunk sack(TSN(123), /*a_rwnd=*/456,
44                  {SackChunk::GapAckBlock(2, 3), SackChunk::GapAckBlock(5, 6)},
45                  {});
46 
47   EXPECT_TRUE(ChunkValidators::Validate(sack));
48 
49   SackChunk clean = ChunkValidators::Clean(std::move(sack));
50   EXPECT_THAT(
51       clean.gap_ack_blocks(),
52       ElementsAre(SackChunk::GapAckBlock(2, 3), SackChunk::GapAckBlock(5, 6)));
53 }
54 
TEST(ChunkValidatorsTest,OneInvalidAckBlock)55 TEST(ChunkValidatorsTest, OneInvalidAckBlock) {
56   SackChunk sack(TSN(123), /*a_rwnd=*/456, {SackChunk::GapAckBlock(1, 2)}, {});
57 
58   EXPECT_FALSE(ChunkValidators::Validate(sack));
59 
60   // It's not strictly valid, but due to the renegable nature of gap ack blocks,
61   // the cum_ack_tsn can't simply be moved.
62   SackChunk clean = ChunkValidators::Clean(std::move(sack));
63   EXPECT_THAT(clean.gap_ack_blocks(),
64               ElementsAre(SackChunk::GapAckBlock(1, 2)));
65 }
66 
TEST(ChunkValidatorsTest,RemovesInvalidGapAckBlockFromSack)67 TEST(ChunkValidatorsTest, RemovesInvalidGapAckBlockFromSack) {
68   SackChunk sack(TSN(123), /*a_rwnd=*/456,
69                  {SackChunk::GapAckBlock(2, 3), SackChunk::GapAckBlock(6, 4)},
70                  {});
71 
72   EXPECT_FALSE(ChunkValidators::Validate(sack));
73 
74   SackChunk clean = ChunkValidators::Clean(std::move(sack));
75 
76   EXPECT_THAT(clean.gap_ack_blocks(),
77               ElementsAre(SackChunk::GapAckBlock(2, 3)));
78 }
79 
TEST(ChunkValidatorsTest,SortsGapAckBlocksInOrder)80 TEST(ChunkValidatorsTest, SortsGapAckBlocksInOrder) {
81   SackChunk sack(TSN(123), /*a_rwnd=*/456,
82                  {SackChunk::GapAckBlock(6, 7), SackChunk::GapAckBlock(3, 4)},
83                  {});
84 
85   EXPECT_FALSE(ChunkValidators::Validate(sack));
86 
87   SackChunk clean = ChunkValidators::Clean(std::move(sack));
88 
89   EXPECT_THAT(
90       clean.gap_ack_blocks(),
91       ElementsAre(SackChunk::GapAckBlock(3, 4), SackChunk::GapAckBlock(6, 7)));
92 }
93 
TEST(ChunkValidatorsTest,MergesAdjacentBlocks)94 TEST(ChunkValidatorsTest, MergesAdjacentBlocks) {
95   SackChunk sack(TSN(123), /*a_rwnd=*/456,
96                  {SackChunk::GapAckBlock(3, 4), SackChunk::GapAckBlock(5, 6)},
97                  {});
98 
99   EXPECT_FALSE(ChunkValidators::Validate(sack));
100 
101   SackChunk clean = ChunkValidators::Clean(std::move(sack));
102 
103   EXPECT_THAT(clean.gap_ack_blocks(),
104               ElementsAre(SackChunk::GapAckBlock(3, 6)));
105 }
106 
TEST(ChunkValidatorsTest,MergesOverlappingByOne)107 TEST(ChunkValidatorsTest, MergesOverlappingByOne) {
108   SackChunk sack(TSN(123), /*a_rwnd=*/456,
109                  {SackChunk::GapAckBlock(3, 4), SackChunk::GapAckBlock(4, 5)},
110                  {});
111 
112   SackChunk clean = ChunkValidators::Clean(std::move(sack));
113 
114   EXPECT_FALSE(ChunkValidators::Validate(sack));
115 
116   EXPECT_THAT(clean.gap_ack_blocks(),
117               ElementsAre(SackChunk::GapAckBlock(3, 5)));
118 }
119 
TEST(ChunkValidatorsTest,MergesOverlappingByMore)120 TEST(ChunkValidatorsTest, MergesOverlappingByMore) {
121   SackChunk sack(TSN(123), /*a_rwnd=*/456,
122                  {SackChunk::GapAckBlock(3, 10), SackChunk::GapAckBlock(4, 5)},
123                  {});
124 
125   EXPECT_FALSE(ChunkValidators::Validate(sack));
126 
127   SackChunk clean = ChunkValidators::Clean(std::move(sack));
128 
129   EXPECT_THAT(clean.gap_ack_blocks(),
130               ElementsAre(SackChunk::GapAckBlock(3, 10)));
131 }
132 
TEST(ChunkValidatorsTest,MergesBlocksStartingWithSameStartOffset)133 TEST(ChunkValidatorsTest, MergesBlocksStartingWithSameStartOffset) {
134   SackChunk sack(TSN(123), /*a_rwnd=*/456,
135                  {SackChunk::GapAckBlock(3, 7), SackChunk::GapAckBlock(3, 5),
136                   SackChunk::GapAckBlock(3, 9)},
137                  {});
138 
139   EXPECT_FALSE(ChunkValidators::Validate(sack));
140 
141   SackChunk clean = ChunkValidators::Clean(std::move(sack));
142 
143   EXPECT_THAT(clean.gap_ack_blocks(),
144               ElementsAre(SackChunk::GapAckBlock(3, 9)));
145 }
146 
TEST(ChunkValidatorsTest,MergesBlocksPartiallyOverlapping)147 TEST(ChunkValidatorsTest, MergesBlocksPartiallyOverlapping) {
148   SackChunk sack(TSN(123), /*a_rwnd=*/456,
149                  {SackChunk::GapAckBlock(3, 7), SackChunk::GapAckBlock(5, 9)},
150                  {});
151 
152   EXPECT_FALSE(ChunkValidators::Validate(sack));
153 
154   SackChunk clean = ChunkValidators::Clean(std::move(sack));
155 
156   EXPECT_THAT(clean.gap_ack_blocks(),
157               ElementsAre(SackChunk::GapAckBlock(3, 9)));
158 }
159 
160 }  // namespace
161 }  // namespace dcsctp
162