OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_fec_group.h" | 5 #include "net/quic/quic_fec_group.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
14 | 14 |
15 using ::testing::_; | 15 using ::testing::_; |
16 using base::StringPiece; | 16 using base::StringPiece; |
17 | 17 |
18 namespace net { | 18 namespace net { |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 const char* const kData[] = { | 22 // kData[] and kEntropyFlag[] are indexed by packet sequence numbers, which |
23 "abc12345678", | 23 // start at 1, so their first elements are dummy. |
24 "987defg", | 24 const char* kData[] = { |
25 "ghi12345", | 25 "", // dummy |
26 "987jlkmno", | 26 // kData[1] must be at least as long as every element of kData[], because |
27 "mno4567890", | 27 // it is used to calculate kDataMaxLen. |
28 "789pqrstuvw", | 28 "abc12345678", |
| 29 "987defg", |
| 30 "ghi12345", |
| 31 "987jlkmno", |
| 32 "mno4567890", |
| 33 "789pqrstuvw", |
29 }; | 34 }; |
| 35 // The maximum length of an element of kData. |
| 36 const size_t kDataMaxLen = strlen(kData[1]); |
| 37 // A suitable test data string, whose length is kDataMaxLen. |
| 38 const char* kDataSingle = kData[1]; |
30 | 39 |
31 const bool kEntropyFlag[] = { | 40 const bool kEntropyFlag[] = { |
32 false, | 41 false, // dummy |
33 true, | 42 false, |
34 true, | 43 true, |
35 false, | 44 true, |
36 true, | 45 false, |
37 true, | 46 true, |
| 47 true, |
38 }; | 48 }; |
39 | 49 |
40 } // namespace | 50 } // namespace |
41 | 51 |
42 class QuicFecGroupTest : public ::testing::Test { | 52 class QuicFecGroupTest : public ::testing::Test { |
43 protected: | 53 protected: |
44 void RunTest(size_t num_packets, size_t lost_packet, bool out_of_order) { | 54 void RunTest(size_t num_packets, size_t lost_packet, bool out_of_order) { |
45 size_t max_len = strlen(kData[0]); | 55 // kData[] and kEntropyFlag[] are indexed by packet sequence numbers, which |
46 scoped_ptr<char[]> redundancy(new char[max_len]); | 56 // start at 1. |
47 for (size_t packet = 0; packet < num_packets; ++packet) { | 57 DCHECK_GE(arraysize(kData), num_packets); |
48 for (size_t i = 0; i < max_len; i++) { | 58 scoped_ptr<char[]> redundancy(new char[kDataMaxLen]); |
49 if (packet == 0) { | 59 for (size_t i = 0; i < kDataMaxLen; i++) { |
50 // Initialize to the first packet. | 60 redundancy[i] = 0x00; |
51 redundancy[i] = kData[0][i]; | 61 } |
52 continue; | 62 // XOR in the packets. |
53 } | 63 for (size_t packet = 1; packet <= num_packets; ++packet) { |
54 // XOR in the remaining packets. | 64 for (size_t i = 0; i < kDataMaxLen; i++) { |
55 uint8 byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i]; | 65 uint8 byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i]; |
56 redundancy[i] = redundancy[i] ^ byte; | 66 redundancy[i] = redundancy[i] ^ byte; |
57 } | 67 } |
58 } | 68 } |
59 | 69 |
60 QuicFecGroup group; | 70 QuicFecGroup group; |
61 | 71 |
62 // If we're out of order, send the FEC packet in the position of the | 72 // If we're out of order, send the FEC packet in the position of the |
63 // lost packet. Otherwise send all (non-missing) packets, then FEC. | 73 // lost packet. Otherwise send all (non-missing) packets, then FEC. |
64 if (out_of_order) { | 74 if (out_of_order) { |
65 // Update the FEC state for each non-lost packet. | 75 // Update the FEC state for each non-lost packet. |
66 for (size_t packet = 0; packet < num_packets; packet++) { | 76 for (size_t packet = 1; packet <= num_packets; packet++) { |
67 if (packet == lost_packet) { | 77 if (packet == lost_packet) { |
68 ASSERT_FALSE(group.IsFinished()); | 78 ASSERT_FALSE(group.IsFinished()); |
69 QuicFecData fec; | 79 QuicFecData fec; |
70 fec.fec_group = 0; | 80 fec.fec_group = 1u; |
71 fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0])); | 81 fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen); |
72 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets, | 82 ASSERT_TRUE( |
73 fec)); | 83 group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec)); |
74 } else { | 84 } else { |
75 QuicPacketHeader header; | 85 QuicPacketHeader header; |
76 header.packet_sequence_number = packet; | 86 header.packet_sequence_number = packet; |
77 header.entropy_flag = kEntropyFlag[packet]; | 87 header.entropy_flag = kEntropyFlag[packet]; |
78 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, | 88 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, |
79 kData[packet])); | 89 kData[packet])); |
80 } | 90 } |
81 ASSERT_TRUE(group.CanRevive() == (packet == num_packets - 1)); | 91 ASSERT_TRUE(group.CanRevive() == (packet == num_packets)); |
82 } | 92 } |
83 } else { | 93 } else { |
84 // Update the FEC state for each non-lost packet. | 94 // Update the FEC state for each non-lost packet. |
85 for (size_t packet = 0; packet < num_packets; packet++) { | 95 for (size_t packet = 1; packet <= num_packets; packet++) { |
86 if (packet == lost_packet) { | 96 if (packet == lost_packet) { |
87 continue; | 97 continue; |
88 } | 98 } |
89 | 99 |
90 QuicPacketHeader header; | 100 QuicPacketHeader header; |
91 header.packet_sequence_number = packet; | 101 header.packet_sequence_number = packet; |
92 header.entropy_flag = kEntropyFlag[packet]; | 102 header.entropy_flag = kEntropyFlag[packet]; |
93 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, | 103 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, |
94 kData[packet])); | 104 kData[packet])); |
95 ASSERT_FALSE(group.CanRevive()); | 105 ASSERT_FALSE(group.CanRevive()); |
96 } | 106 } |
97 | 107 |
98 ASSERT_FALSE(group.IsFinished()); | 108 ASSERT_FALSE(group.IsFinished()); |
99 // Attempt to revive the missing packet. | 109 // Attempt to revive the missing packet. |
100 QuicFecData fec; | 110 QuicFecData fec; |
101 fec.fec_group = 0; | 111 fec.fec_group = 1u; |
102 fec.redundancy = StringPiece(redundancy.get(), strlen(kData[0])); | 112 fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen); |
103 | 113 |
104 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets, | 114 ASSERT_TRUE( |
105 fec)); | 115 group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec)); |
106 } | 116 } |
107 QuicPacketHeader header; | 117 QuicPacketHeader header; |
108 char recovered[kMaxPacketSize]; | 118 char recovered[kMaxPacketSize]; |
109 ASSERT_TRUE(group.CanRevive()); | 119 ASSERT_TRUE(group.CanRevive()); |
110 size_t len = group.Revive(&header, recovered, arraysize(recovered)); | 120 size_t len = group.Revive(&header, recovered, arraysize(recovered)); |
111 ASSERT_NE(0u, len) | 121 ASSERT_NE(0u, len) |
112 << "Failed to revive packet " << lost_packet << " out of " | 122 << "Failed to revive packet " << lost_packet << " out of " |
113 << num_packets; | 123 << num_packets; |
114 EXPECT_EQ(lost_packet, header.packet_sequence_number) | 124 EXPECT_EQ(lost_packet, header.packet_sequence_number) |
115 << "Failed to revive packet " << lost_packet << " out of " | 125 << "Failed to revive packet " << lost_packet << " out of " |
116 << num_packets; | 126 << num_packets; |
117 // Revived packets have an unknown entropy. | 127 // Revived packets have an unknown entropy. |
118 EXPECT_FALSE(header.entropy_flag); | 128 EXPECT_FALSE(header.entropy_flag); |
119 ASSERT_GE(len, strlen(kData[lost_packet])) << "Incorrect length"; | 129 ASSERT_GE(len, strlen(kData[lost_packet])) << "Incorrect length"; |
120 for (size_t i = 0; i < strlen(kData[lost_packet]); i++) { | 130 for (size_t i = 0; i < strlen(kData[lost_packet]); i++) { |
121 EXPECT_EQ(kData[lost_packet][i], recovered[i]); | 131 EXPECT_EQ(kData[lost_packet][i], recovered[i]); |
122 } | 132 } |
123 ASSERT_TRUE(group.IsFinished()); | 133 ASSERT_TRUE(group.IsFinished()); |
124 } | 134 } |
125 }; | 135 }; |
126 | 136 |
127 TEST_F(QuicFecGroupTest, UpdateAndRevive) { | 137 TEST_F(QuicFecGroupTest, UpdateAndRevive) { |
128 RunTest(2, 0, false); | |
129 RunTest(2, 1, false); | 138 RunTest(2, 1, false); |
| 139 RunTest(2, 2, false); |
130 | 140 |
131 RunTest(3, 0, false); | |
132 RunTest(3, 1, false); | 141 RunTest(3, 1, false); |
133 RunTest(3, 2, false); | 142 RunTest(3, 2, false); |
| 143 RunTest(3, 3, false); |
134 } | 144 } |
135 | 145 |
136 TEST_F(QuicFecGroupTest, UpdateAndReviveOutOfOrder) { | 146 TEST_F(QuicFecGroupTest, UpdateAndReviveOutOfOrder) { |
137 RunTest(2, 0, true); | |
138 RunTest(2, 1, true); | 147 RunTest(2, 1, true); |
| 148 RunTest(2, 2, true); |
139 | 149 |
140 RunTest(3, 0, true); | |
141 RunTest(3, 1, true); | 150 RunTest(3, 1, true); |
142 RunTest(3, 2, true); | 151 RunTest(3, 2, true); |
| 152 RunTest(3, 3, true); |
143 } | 153 } |
144 | 154 |
145 TEST_F(QuicFecGroupTest, UpdateFecIfReceivedPacketIsNotCovered) { | 155 TEST_F(QuicFecGroupTest, UpdateFecIfReceivedPacketIsNotCovered) { |
146 char data1[] = "abc123"; | 156 char data1[] = "abc123"; |
147 char redundancy[arraysize(data1)]; | 157 char redundancy[arraysize(data1)]; |
148 for (size_t i = 0; i < arraysize(data1); i++) { | 158 for (size_t i = 0; i < arraysize(data1); i++) { |
149 redundancy[i] = data1[i]; | 159 redundancy[i] = data1[i]; |
150 } | 160 } |
151 | 161 |
152 QuicFecGroup group; | 162 QuicFecGroup group; |
153 | 163 |
154 QuicPacketHeader header; | 164 QuicPacketHeader header; |
155 header.packet_sequence_number = 3; | 165 header.packet_sequence_number = 3; |
156 group.Update(ENCRYPTION_FORWARD_SECURE, header, data1); | 166 group.Update(ENCRYPTION_FORWARD_SECURE, header, data1); |
157 | 167 |
158 QuicFecData fec; | 168 QuicFecData fec; |
159 fec.fec_group = 1; | 169 fec.fec_group = 1u; |
160 fec.redundancy = redundancy; | 170 fec.redundancy = redundancy; |
161 | 171 |
162 header.packet_sequence_number = 2; | 172 header.packet_sequence_number = 2; |
163 ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 2, fec)); | 173 ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 2, fec)); |
164 } | 174 } |
165 | 175 |
166 TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) { | 176 TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) { |
167 QuicPacketHeader header; | 177 QuicPacketHeader header; |
168 header.packet_sequence_number = 3; | 178 header.packet_sequence_number = 3; |
169 | 179 |
170 QuicFecGroup group; | 180 QuicFecGroup group; |
171 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0])); | 181 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle)); |
172 | 182 |
173 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); | 183 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); |
174 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); | 184 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); |
175 EXPECT_FALSE(group.ProtectsPacketsBefore(3)); | 185 EXPECT_FALSE(group.ProtectsPacketsBefore(3)); |
176 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); | 186 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); |
177 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); | 187 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); |
178 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); | 188 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); |
179 } | 189 } |
180 | 190 |
181 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithSeveralPackets) { | 191 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithSeveralPackets) { |
182 QuicPacketHeader header; | 192 QuicPacketHeader header; |
183 header.packet_sequence_number = 3; | 193 header.packet_sequence_number = 3; |
184 | 194 |
185 QuicFecGroup group; | 195 QuicFecGroup group; |
186 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0])); | 196 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle)); |
187 | 197 |
188 header.packet_sequence_number = 7; | 198 header.packet_sequence_number = 7; |
189 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0])); | 199 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle)); |
190 | 200 |
191 header.packet_sequence_number = 5; | 201 header.packet_sequence_number = 5; |
192 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kData[0])); | 202 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle)); |
193 | 203 |
194 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); | 204 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); |
195 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); | 205 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); |
196 EXPECT_FALSE(group.ProtectsPacketsBefore(3)); | 206 EXPECT_FALSE(group.ProtectsPacketsBefore(3)); |
197 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); | 207 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); |
198 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); | 208 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); |
199 EXPECT_TRUE(group.ProtectsPacketsBefore(6)); | 209 EXPECT_TRUE(group.ProtectsPacketsBefore(6)); |
200 EXPECT_TRUE(group.ProtectsPacketsBefore(7)); | 210 EXPECT_TRUE(group.ProtectsPacketsBefore(7)); |
201 EXPECT_TRUE(group.ProtectsPacketsBefore(8)); | 211 EXPECT_TRUE(group.ProtectsPacketsBefore(8)); |
202 EXPECT_TRUE(group.ProtectsPacketsBefore(9)); | 212 EXPECT_TRUE(group.ProtectsPacketsBefore(9)); |
203 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); | 213 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); |
204 } | 214 } |
205 | 215 |
206 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithFecData) { | 216 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithFecData) { |
207 QuicFecData fec; | 217 QuicFecData fec; |
208 fec.fec_group = 2; | 218 fec.fec_group = 2u; |
209 fec.redundancy = kData[0]; | 219 fec.redundancy = kDataSingle; |
210 | 220 |
211 QuicFecGroup group; | 221 QuicFecGroup group; |
212 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 3, fec)); | 222 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 3, fec)); |
213 | 223 |
214 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); | 224 EXPECT_FALSE(group.ProtectsPacketsBefore(1)); |
215 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); | 225 EXPECT_FALSE(group.ProtectsPacketsBefore(2)); |
216 EXPECT_TRUE(group.ProtectsPacketsBefore(3)); | 226 EXPECT_TRUE(group.ProtectsPacketsBefore(3)); |
217 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); | 227 EXPECT_TRUE(group.ProtectsPacketsBefore(4)); |
218 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); | 228 EXPECT_TRUE(group.ProtectsPacketsBefore(5)); |
219 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); | 229 EXPECT_TRUE(group.ProtectsPacketsBefore(50)); |
220 } | 230 } |
221 | 231 |
222 TEST_F(QuicFecGroupTest, EffectiveEncryptionLevel) { | 232 TEST_F(QuicFecGroupTest, EffectiveEncryptionLevel) { |
223 QuicFecGroup group; | 233 QuicFecGroup group; |
224 EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.effective_encryption_level()); | 234 EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.effective_encryption_level()); |
225 | 235 |
226 QuicPacketHeader header; | 236 QuicPacketHeader header; |
227 header.packet_sequence_number = 5; | 237 header.packet_sequence_number = 5; |
228 ASSERT_TRUE(group.Update(ENCRYPTION_INITIAL, header, kData[0])); | 238 ASSERT_TRUE(group.Update(ENCRYPTION_INITIAL, header, kDataSingle)); |
229 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level()); | 239 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level()); |
230 | 240 |
231 QuicFecData fec; | 241 QuicFecData fec; |
232 fec.fec_group = 0; | 242 fec.fec_group = 1u; |
233 fec.redundancy = kData[0]; | 243 fec.redundancy = kDataSingle; |
234 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 7, fec)); | 244 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 7, fec)); |
235 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level()); | 245 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level()); |
236 | 246 |
237 header.packet_sequence_number = 3; | 247 header.packet_sequence_number = 3; |
238 ASSERT_TRUE(group.Update(ENCRYPTION_NONE, header, kData[0])); | 248 ASSERT_TRUE(group.Update(ENCRYPTION_NONE, header, kDataSingle)); |
239 EXPECT_EQ(ENCRYPTION_NONE, group.effective_encryption_level()); | 249 EXPECT_EQ(ENCRYPTION_NONE, group.effective_encryption_level()); |
240 } | 250 } |
241 | 251 |
242 } // namespace net | 252 } // namespace net |
OLD | NEW |