xref: /aosp_15_r20/external/webrtc/net/dcsctp/rx/interleaved_reassembly_streams_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/rx/interleaved_reassembly_streams.h"
11 
12 #include <cstdint>
13 #include <memory>
14 #include <utility>
15 
16 #include "net/dcsctp/common/sequence_numbers.h"
17 #include "net/dcsctp/packet/chunk/forward_tsn_common.h"
18 #include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h"
19 #include "net/dcsctp/packet/data.h"
20 #include "net/dcsctp/rx/reassembly_streams.h"
21 #include "net/dcsctp/testing/data_generator.h"
22 #include "rtc_base/gunit.h"
23 #include "test/gmock.h"
24 
25 namespace dcsctp {
26 namespace {
27 using ::testing::MockFunction;
28 using ::testing::NiceMock;
29 
30 class InterleavedReassemblyStreamsTest : public testing::Test {
31  protected:
tsn(uint32_t value)32   UnwrappedTSN tsn(uint32_t value) { return tsn_.Unwrap(TSN(value)); }
33 
InterleavedReassemblyStreamsTest()34   InterleavedReassemblyStreamsTest() {}
35   DataGenerator gen_;
36   UnwrappedTSN::Unwrapper tsn_;
37 };
38 
TEST_F(InterleavedReassemblyStreamsTest,AddUnorderedMessageReturnsCorrectSize)39 TEST_F(InterleavedReassemblyStreamsTest,
40        AddUnorderedMessageReturnsCorrectSize) {
41   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
42 
43   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
44 
45   EXPECT_EQ(streams.Add(tsn(1), gen_.Unordered({1}, "B")), 1);
46   EXPECT_EQ(streams.Add(tsn(2), gen_.Unordered({2, 3, 4})), 3);
47   EXPECT_EQ(streams.Add(tsn(3), gen_.Unordered({5, 6})), 2);
48   // Adding the end fragment should make it empty again.
49   EXPECT_EQ(streams.Add(tsn(4), gen_.Unordered({7}, "E")), -6);
50 }
51 
TEST_F(InterleavedReassemblyStreamsTest,AddSimpleOrderedMessageReturnsCorrectSize)52 TEST_F(InterleavedReassemblyStreamsTest,
53        AddSimpleOrderedMessageReturnsCorrectSize) {
54   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
55 
56   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
57 
58   EXPECT_EQ(streams.Add(tsn(1), gen_.Ordered({1}, "B")), 1);
59   EXPECT_EQ(streams.Add(tsn(2), gen_.Ordered({2, 3, 4})), 3);
60   EXPECT_EQ(streams.Add(tsn(3), gen_.Ordered({5, 6})), 2);
61   EXPECT_EQ(streams.Add(tsn(4), gen_.Ordered({7}, "E")), -6);
62 }
63 
TEST_F(InterleavedReassemblyStreamsTest,AddMoreComplexOrderedMessageReturnsCorrectSize)64 TEST_F(InterleavedReassemblyStreamsTest,
65        AddMoreComplexOrderedMessageReturnsCorrectSize) {
66   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
67 
68   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
69 
70   EXPECT_EQ(streams.Add(tsn(1), gen_.Ordered({1}, "B")), 1);
71   Data late = gen_.Ordered({2, 3, 4});
72   EXPECT_EQ(streams.Add(tsn(3), gen_.Ordered({5, 6})), 2);
73   EXPECT_EQ(streams.Add(tsn(4), gen_.Ordered({7}, "E")), 1);
74 
75   EXPECT_EQ(streams.Add(tsn(5), gen_.Ordered({1}, "BE")), 1);
76   EXPECT_EQ(streams.Add(tsn(6), gen_.Ordered({5, 6}, "B")), 2);
77   EXPECT_EQ(streams.Add(tsn(7), gen_.Ordered({7}, "E")), 1);
78   EXPECT_EQ(streams.Add(tsn(2), std::move(late)), -8);
79 }
80 
TEST_F(InterleavedReassemblyStreamsTest,DeleteUnorderedMessageReturnsCorrectSize)81 TEST_F(InterleavedReassemblyStreamsTest,
82        DeleteUnorderedMessageReturnsCorrectSize) {
83   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
84 
85   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
86 
87   EXPECT_EQ(streams.Add(tsn(1), gen_.Unordered({1}, "B")), 1);
88   EXPECT_EQ(streams.Add(tsn(2), gen_.Unordered({2, 3, 4})), 3);
89   EXPECT_EQ(streams.Add(tsn(3), gen_.Unordered({5, 6})), 2);
90 
91   IForwardTsnChunk::SkippedStream skipped[] = {
92       IForwardTsnChunk::SkippedStream(IsUnordered(true), StreamID(1), MID(0))};
93   EXPECT_EQ(streams.HandleForwardTsn(tsn(3), skipped), 6u);
94 }
95 
TEST_F(InterleavedReassemblyStreamsTest,DeleteSimpleOrderedMessageReturnsCorrectSize)96 TEST_F(InterleavedReassemblyStreamsTest,
97        DeleteSimpleOrderedMessageReturnsCorrectSize) {
98   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
99 
100   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
101 
102   EXPECT_EQ(streams.Add(tsn(1), gen_.Ordered({1}, "B")), 1);
103   EXPECT_EQ(streams.Add(tsn(2), gen_.Ordered({2, 3, 4})), 3);
104   EXPECT_EQ(streams.Add(tsn(3), gen_.Ordered({5, 6})), 2);
105 
106   IForwardTsnChunk::SkippedStream skipped[] = {
107       IForwardTsnChunk::SkippedStream(IsUnordered(false), StreamID(1), MID(0))};
108   EXPECT_EQ(streams.HandleForwardTsn(tsn(3), skipped), 6u);
109 }
110 
TEST_F(InterleavedReassemblyStreamsTest,DeleteManyOrderedMessagesReturnsCorrectSize)111 TEST_F(InterleavedReassemblyStreamsTest,
112        DeleteManyOrderedMessagesReturnsCorrectSize) {
113   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
114 
115   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
116 
117   EXPECT_EQ(streams.Add(tsn(1), gen_.Ordered({1}, "B")), 1);
118   gen_.Ordered({2, 3, 4});
119   EXPECT_EQ(streams.Add(tsn(3), gen_.Ordered({5, 6})), 2);
120   EXPECT_EQ(streams.Add(tsn(4), gen_.Ordered({7}, "E")), 1);
121 
122   EXPECT_EQ(streams.Add(tsn(5), gen_.Ordered({1}, "BE")), 1);
123   EXPECT_EQ(streams.Add(tsn(6), gen_.Ordered({5, 6}, "B")), 2);
124   EXPECT_EQ(streams.Add(tsn(7), gen_.Ordered({7}, "E")), 1);
125 
126   // Expire all three messages
127   IForwardTsnChunk::SkippedStream skipped[] = {
128       IForwardTsnChunk::SkippedStream(IsUnordered(false), StreamID(1), MID(2))};
129   EXPECT_EQ(streams.HandleForwardTsn(tsn(8), skipped), 8u);
130 }
131 
TEST_F(InterleavedReassemblyStreamsTest,DeleteOrderedMessageDelivesTwoReturnsCorrectSize)132 TEST_F(InterleavedReassemblyStreamsTest,
133        DeleteOrderedMessageDelivesTwoReturnsCorrectSize) {
134   NiceMock<MockFunction<ReassemblyStreams::OnAssembledMessage>> on_assembled;
135 
136   InterleavedReassemblyStreams streams("", on_assembled.AsStdFunction());
137 
138   EXPECT_EQ(streams.Add(tsn(1), gen_.Ordered({1}, "B")), 1);
139   gen_.Ordered({2, 3, 4});
140   EXPECT_EQ(streams.Add(tsn(3), gen_.Ordered({5, 6})), 2);
141   EXPECT_EQ(streams.Add(tsn(4), gen_.Ordered({7}, "E")), 1);
142 
143   EXPECT_EQ(streams.Add(tsn(5), gen_.Ordered({1}, "BE")), 1);
144   EXPECT_EQ(streams.Add(tsn(6), gen_.Ordered({5, 6}, "B")), 2);
145   EXPECT_EQ(streams.Add(tsn(7), gen_.Ordered({7}, "E")), 1);
146 
147   // The first ordered message expire, and the following two are delivered.
148   IForwardTsnChunk::SkippedStream skipped[] = {
149       IForwardTsnChunk::SkippedStream(IsUnordered(false), StreamID(1), MID(0))};
150   EXPECT_EQ(streams.HandleForwardTsn(tsn(4), skipped), 8u);
151 }
152 
153 }  // namespace
154 }  // namespace dcsctp
155