Update V8 to version 4.6.61.
[chromium-blink-merge.git] / net / quic / quic_fec_group_test.cc
blob9f38da7fcabc377e7a8d171df3dbfae88941551b
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
3 // found in the LICENSE file.
5 #include "net/quic/quic_fec_group.h"
7 #include <algorithm>
8 #include <vector>
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "testing/gmock/include/gmock/gmock.h"
15 using ::testing::_;
16 using base::StringPiece;
18 namespace net {
20 namespace {
22 // kData[] and kEntropyFlag[] are indexed by packet sequence numbers, which
23 // start at 1, so their first elements are dummy.
24 const char* kData[] = {
25 "", // dummy
26 // kData[1] must be at least as long as every element of kData[], because
27 // it is used to calculate kDataMaxLen.
28 "abc12345678",
29 "987defg",
30 "ghi12345",
31 "987jlkmno",
32 "mno4567890",
33 "789pqrstuvw",
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];
40 const bool kEntropyFlag[] = {
41 false, // dummy
42 false,
43 true,
44 true,
45 false,
46 true,
47 true,
50 } // namespace
52 class QuicFecGroupTest : public ::testing::Test {
53 protected:
54 void RunTest(size_t num_packets, size_t lost_packet, bool out_of_order) {
55 // kData[] and kEntropyFlag[] are indexed by packet sequence numbers, which
56 // start at 1.
57 DCHECK_GE(arraysize(kData), num_packets);
58 scoped_ptr<char[]> redundancy(new char[kDataMaxLen]);
59 for (size_t i = 0; i < kDataMaxLen; i++) {
60 redundancy[i] = 0x00;
62 // XOR in the packets.
63 for (size_t packet = 1; packet <= num_packets; ++packet) {
64 for (size_t i = 0; i < kDataMaxLen; i++) {
65 uint8 byte = i > strlen(kData[packet]) ? 0x00 : kData[packet][i];
66 redundancy[i] = redundancy[i] ^ byte;
70 QuicFecGroup group;
72 // If we're out of order, send the FEC packet in the position of the
73 // lost packet. Otherwise send all (non-missing) packets, then FEC.
74 if (out_of_order) {
75 // Update the FEC state for each non-lost packet.
76 for (size_t packet = 1; packet <= num_packets; packet++) {
77 if (packet == lost_packet) {
78 ASSERT_FALSE(group.IsFinished());
79 QuicFecData fec;
80 fec.fec_group = 1u;
81 fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen);
82 ASSERT_TRUE(
83 group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec));
84 } else {
85 QuicPacketHeader header;
86 header.packet_sequence_number = packet;
87 header.entropy_flag = kEntropyFlag[packet];
88 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
89 kData[packet]));
91 ASSERT_TRUE(group.CanRevive() == (packet == num_packets));
93 } else {
94 // Update the FEC state for each non-lost packet.
95 for (size_t packet = 1; packet <= num_packets; packet++) {
96 if (packet == lost_packet) {
97 continue;
100 QuicPacketHeader header;
101 header.packet_sequence_number = packet;
102 header.entropy_flag = kEntropyFlag[packet];
103 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header,
104 kData[packet]));
105 ASSERT_FALSE(group.CanRevive());
108 ASSERT_FALSE(group.IsFinished());
109 // Attempt to revive the missing packet.
110 QuicFecData fec;
111 fec.fec_group = 1u;
112 fec.redundancy = StringPiece(redundancy.get(), kDataMaxLen);
114 ASSERT_TRUE(
115 group.UpdateFec(ENCRYPTION_FORWARD_SECURE, num_packets + 1, fec));
117 QuicPacketHeader header;
118 char recovered[kMaxPacketSize];
119 ASSERT_TRUE(group.CanRevive());
120 size_t len = group.Revive(&header, recovered, arraysize(recovered));
121 ASSERT_NE(0u, len)
122 << "Failed to revive packet " << lost_packet << " out of "
123 << num_packets;
124 EXPECT_EQ(lost_packet, header.packet_sequence_number)
125 << "Failed to revive packet " << lost_packet << " out of "
126 << num_packets;
127 // Revived packets have an unknown entropy.
128 EXPECT_FALSE(header.entropy_flag);
129 ASSERT_GE(len, strlen(kData[lost_packet])) << "Incorrect length";
130 for (size_t i = 0; i < strlen(kData[lost_packet]); i++) {
131 EXPECT_EQ(kData[lost_packet][i], recovered[i]);
133 ASSERT_TRUE(group.IsFinished());
137 TEST_F(QuicFecGroupTest, UpdateAndRevive) {
138 RunTest(2, 1, false);
139 RunTest(2, 2, false);
141 RunTest(3, 1, false);
142 RunTest(3, 2, false);
143 RunTest(3, 3, false);
146 TEST_F(QuicFecGroupTest, UpdateAndReviveOutOfOrder) {
147 RunTest(2, 1, true);
148 RunTest(2, 2, true);
150 RunTest(3, 1, true);
151 RunTest(3, 2, true);
152 RunTest(3, 3, true);
155 TEST_F(QuicFecGroupTest, UpdateFecIfReceivedPacketIsNotCovered) {
156 char data1[] = "abc123";
157 char redundancy[arraysize(data1)];
158 for (size_t i = 0; i < arraysize(data1); i++) {
159 redundancy[i] = data1[i];
162 QuicFecGroup group;
164 QuicPacketHeader header;
165 header.packet_sequence_number = 3;
166 group.Update(ENCRYPTION_FORWARD_SECURE, header, data1);
168 QuicFecData fec;
169 fec.fec_group = 1u;
170 fec.redundancy = redundancy;
172 header.packet_sequence_number = 2;
173 ASSERT_FALSE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 2, fec));
176 TEST_F(QuicFecGroupTest, ProtectsPacketsBefore) {
177 QuicPacketHeader header;
178 header.packet_sequence_number = 3;
180 QuicFecGroup group;
181 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
183 EXPECT_FALSE(group.ProtectsPacketsBefore(1));
184 EXPECT_FALSE(group.ProtectsPacketsBefore(2));
185 EXPECT_FALSE(group.ProtectsPacketsBefore(3));
186 EXPECT_TRUE(group.ProtectsPacketsBefore(4));
187 EXPECT_TRUE(group.ProtectsPacketsBefore(5));
188 EXPECT_TRUE(group.ProtectsPacketsBefore(50));
191 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithSeveralPackets) {
192 QuicPacketHeader header;
193 header.packet_sequence_number = 3;
195 QuicFecGroup group;
196 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
198 header.packet_sequence_number = 7;
199 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
201 header.packet_sequence_number = 5;
202 ASSERT_TRUE(group.Update(ENCRYPTION_FORWARD_SECURE, header, kDataSingle));
204 EXPECT_FALSE(group.ProtectsPacketsBefore(1));
205 EXPECT_FALSE(group.ProtectsPacketsBefore(2));
206 EXPECT_FALSE(group.ProtectsPacketsBefore(3));
207 EXPECT_TRUE(group.ProtectsPacketsBefore(4));
208 EXPECT_TRUE(group.ProtectsPacketsBefore(5));
209 EXPECT_TRUE(group.ProtectsPacketsBefore(6));
210 EXPECT_TRUE(group.ProtectsPacketsBefore(7));
211 EXPECT_TRUE(group.ProtectsPacketsBefore(8));
212 EXPECT_TRUE(group.ProtectsPacketsBefore(9));
213 EXPECT_TRUE(group.ProtectsPacketsBefore(50));
216 TEST_F(QuicFecGroupTest, ProtectsPacketsBeforeWithFecData) {
217 QuicFecData fec;
218 fec.fec_group = 2u;
219 fec.redundancy = kDataSingle;
221 QuicFecGroup group;
222 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 3, fec));
224 EXPECT_FALSE(group.ProtectsPacketsBefore(1));
225 EXPECT_FALSE(group.ProtectsPacketsBefore(2));
226 EXPECT_TRUE(group.ProtectsPacketsBefore(3));
227 EXPECT_TRUE(group.ProtectsPacketsBefore(4));
228 EXPECT_TRUE(group.ProtectsPacketsBefore(5));
229 EXPECT_TRUE(group.ProtectsPacketsBefore(50));
232 TEST_F(QuicFecGroupTest, EffectiveEncryptionLevel) {
233 QuicFecGroup group;
234 EXPECT_EQ(NUM_ENCRYPTION_LEVELS, group.effective_encryption_level());
236 QuicPacketHeader header;
237 header.packet_sequence_number = 5;
238 ASSERT_TRUE(group.Update(ENCRYPTION_INITIAL, header, kDataSingle));
239 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
241 QuicFecData fec;
242 fec.fec_group = 1u;
243 fec.redundancy = kDataSingle;
244 ASSERT_TRUE(group.UpdateFec(ENCRYPTION_FORWARD_SECURE, 7, fec));
245 EXPECT_EQ(ENCRYPTION_INITIAL, group.effective_encryption_level());
247 header.packet_sequence_number = 3;
248 ASSERT_TRUE(group.Update(ENCRYPTION_NONE, header, kDataSingle));
249 EXPECT_EQ(ENCRYPTION_NONE, group.effective_encryption_level());
252 } // namespace net