quic_packet_generator_test.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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.
4
5#include "net/quic/quic_packet_generator.h"
6
7#include <string>
8
9#include "net/quic/crypto/crypto_protocol.h"
10#include "net/quic/crypto/null_encrypter.h"
11#include "net/quic/crypto/quic_decrypter.h"
12#include "net/quic/crypto/quic_encrypter.h"
13#include "net/quic/quic_utils.h"
14#include "net/quic/test_tools/quic_test_utils.h"
15#include "net/quic/test_tools/simple_quic_framer.h"
16#include "testing/gmock/include/gmock/gmock.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19using base::StringPiece;
20using testing::InSequence;
21using testing::Return;
22using testing::SaveArg;
23using testing::_;
24
25namespace net {
26namespace test {
27namespace {
28
29class MockDelegate : public QuicPacketGenerator::DelegateInterface {
30 public:
31  MockDelegate() {}
32  virtual ~MockDelegate() {}
33
34  MOCK_METHOD2(CanWrite, bool(Retransmission retransmission,
35                              HasRetransmittableData retransmittable));
36
37  MOCK_METHOD0(CreateAckFrame, QuicAckFrame*());
38  MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*());
39  MOCK_METHOD1(OnSerializedPacket, bool(const SerializedPacket& packet));
40
41  void SetCanWrite(bool can_write) {
42    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _))
43        .WillRepeatedly(Return(can_write));
44  }
45
46 private:
47  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
48};
49
50// Simple struct for describing the contents of a packet.
51// Useful in conjunction with a SimpleQuicFrame for validating
52// that a packet contains the expected frames.
53struct PacketContents {
54  PacketContents()
55      : num_ack_frames(0),
56        num_connection_close_frames(0),
57        num_feedback_frames(0),
58        num_goaway_frames(0),
59        num_rst_stream_frames(0),
60        num_stream_frames(0),
61        fec_group(0) {
62  }
63
64  size_t num_ack_frames;
65  size_t num_connection_close_frames;
66  size_t num_feedback_frames;
67  size_t num_goaway_frames;
68  size_t num_rst_stream_frames;
69  size_t num_stream_frames;
70
71  QuicFecGroupNumber fec_group;
72};
73
74}  // namespace
75
76class QuicPacketGeneratorTest : public ::testing::Test {
77 protected:
78  QuicPacketGeneratorTest()
79      : framer_(kQuicVersion1, QuicTime::Zero(), false),
80        creator_(42, &framer_, &random_, false),
81        generator_(&delegate_, &creator_),
82        packet_(0, NULL, 0, NULL),
83        packet2_(0, NULL, 0, NULL),
84        packet3_(0, NULL, 0, NULL),
85        packet4_(0, NULL, 0, NULL),
86        packet5_(0, NULL, 0, NULL) {
87  }
88
89  ~QuicPacketGeneratorTest() {
90    delete packet_.packet;
91    delete packet_.retransmittable_frames;
92    delete packet2_.packet;
93    delete packet2_.retransmittable_frames;
94    delete packet3_.packet;
95    delete packet3_.retransmittable_frames;
96    delete packet4_.packet;
97    delete packet4_.retransmittable_frames;
98    delete packet5_.packet;
99    delete packet5_.retransmittable_frames;
100  }
101
102  QuicAckFrame* CreateAckFrame() {
103    // TODO(rch): Initialize this so it can be verified later.
104    return new QuicAckFrame(0, QuicTime::Zero(), 0);
105  }
106
107  QuicCongestionFeedbackFrame* CreateFeedbackFrame() {
108    QuicCongestionFeedbackFrame* frame = new QuicCongestionFeedbackFrame;
109    frame->type = kFixRate;
110    frame->fix_rate.bitrate = QuicBandwidth::FromBytesPerSecond(42);
111    return frame;
112  }
113
114  QuicRstStreamFrame* CreateRstStreamFrame() {
115    return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR);
116  }
117
118  QuicGoAwayFrame* CreateGoAwayFrame() {
119    return new QuicGoAwayFrame(QUIC_NO_ERROR, 1, std::string());
120  }
121
122  void CheckPacketContains(const PacketContents& contents,
123                           const SerializedPacket& packet) {
124    size_t num_retransmittable_frames = contents.num_connection_close_frames +
125        contents.num_goaway_frames + contents.num_rst_stream_frames +
126        contents.num_stream_frames;
127    size_t num_frames = contents.num_feedback_frames + contents.num_ack_frames +
128        num_retransmittable_frames;
129
130    if (num_retransmittable_frames == 0) {
131      ASSERT_TRUE(packet.retransmittable_frames == NULL);
132    } else {
133      ASSERT_TRUE(packet.retransmittable_frames != NULL);
134      EXPECT_EQ(num_retransmittable_frames,
135                packet.retransmittable_frames->frames().size());
136    }
137
138    ASSERT_TRUE(packet.packet != NULL);
139    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
140    EXPECT_EQ(num_frames, simple_framer_.num_frames());
141    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
142    EXPECT_EQ(contents.num_connection_close_frames,
143              simple_framer_.connection_close_frames().size());
144    EXPECT_EQ(contents.num_feedback_frames,
145              simple_framer_.feedback_frames().size());
146    EXPECT_EQ(contents.num_goaway_frames,
147              simple_framer_.goaway_frames().size());
148    EXPECT_EQ(contents.num_rst_stream_frames,
149              simple_framer_.rst_stream_frames().size());
150    EXPECT_EQ(contents.num_stream_frames,
151              simple_framer_.stream_frames().size());
152    EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);
153  }
154
155  void CheckPacketHasSingleStreamFrame(const SerializedPacket& packet) {
156    ASSERT_TRUE(packet.retransmittable_frames != NULL);
157    EXPECT_EQ(1u, packet.retransmittable_frames->frames().size());
158    ASSERT_TRUE(packet.packet != NULL);
159    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
160    EXPECT_EQ(1u, simple_framer_.num_frames());
161    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
162  }
163
164  void CheckPacketIsFec(const SerializedPacket& packet,
165                        QuicPacketSequenceNumber fec_group) {
166    ASSERT_TRUE(packet.retransmittable_frames == NULL);
167    ASSERT_TRUE(packet.packet != NULL);
168    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
169    EXPECT_TRUE(simple_framer_.header().fec_flag);
170    EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
171  }
172
173  StringPiece CreateData(size_t len) {
174    data_array_.reset(new char[len]);
175    memset(data_array_.get(), '?', len);
176    return StringPiece(data_array_.get(), len);
177  }
178
179  QuicFramer framer_;
180  MockRandom random_;
181  QuicPacketCreator creator_;
182  testing::StrictMock<MockDelegate> delegate_;
183  QuicPacketGenerator generator_;
184  SimpleQuicFramer simple_framer_;
185  SerializedPacket packet_;
186  SerializedPacket packet2_;
187  SerializedPacket packet3_;
188  SerializedPacket packet4_;
189  SerializedPacket packet5_;
190
191 private:
192  scoped_ptr<char[]> data_array_;
193};
194
195TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
196  delegate_.SetCanWrite(false);
197
198  generator_.SetShouldSendAck(false);
199  EXPECT_TRUE(generator_.HasQueuedData());
200}
201
202TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
203  delegate_.SetCanWrite(true);
204  generator_.StartBatchOperations();
205
206  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
207
208  generator_.SetShouldSendAck(false);
209  EXPECT_TRUE(generator_.HasQueuedData());
210}
211
212TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
213  delegate_.SetCanWrite(true);
214
215  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
216  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
217      DoAll(SaveArg<0>(&packet_), Return(true)));
218
219  generator_.SetShouldSendAck(false);
220  EXPECT_FALSE(generator_.HasQueuedData());
221
222  PacketContents contents;
223  contents.num_ack_frames = 1;
224  CheckPacketContains(contents, packet_);
225}
226
227TEST_F(QuicPacketGeneratorTest,
228       ShouldSendAckWithFeedback_WritableAndShouldNotFlush) {
229  delegate_.SetCanWrite(true);
230  generator_.StartBatchOperations();
231
232  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
233  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
234      Return(CreateFeedbackFrame()));
235
236  generator_.SetShouldSendAck(true);
237  EXPECT_TRUE(generator_.HasQueuedData());
238}
239
240TEST_F(QuicPacketGeneratorTest,
241       ShouldSendAckWithFeedback_WritableAndShouldFlush) {
242  delegate_.SetCanWrite(true);
243
244  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
245  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
246      Return(CreateFeedbackFrame()));
247
248  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
249      DoAll(SaveArg<0>(&packet_), Return(true)));
250
251  generator_.SetShouldSendAck(true);
252  EXPECT_FALSE(generator_.HasQueuedData());
253
254  PacketContents contents;
255  contents.num_ack_frames = 1;
256  contents.num_feedback_frames = 1;
257  CheckPacketContains(contents, packet_);
258}
259
260TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
261  delegate_.SetCanWrite(false);
262
263  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
264  EXPECT_TRUE(generator_.HasQueuedData());
265}
266
267TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
268  delegate_.SetCanWrite(true);
269  generator_.StartBatchOperations();
270
271  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
272  EXPECT_TRUE(generator_.HasQueuedData());
273}
274
275TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
276  delegate_.SetCanWrite(true);
277
278  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
279      DoAll(SaveArg<0>(&packet_), Return(true)));
280
281  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
282  EXPECT_FALSE(generator_.HasQueuedData());
283
284  PacketContents contents;
285  contents.num_rst_stream_frames = 1;
286  CheckPacketContains(contents, packet_);
287}
288
289TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
290  delegate_.SetCanWrite(false);
291
292  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
293  EXPECT_EQ(0u, consumed.bytes_consumed);
294  EXPECT_FALSE(consumed.fin_consumed);
295  EXPECT_FALSE(generator_.HasQueuedData());
296}
297
298TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
299  delegate_.SetCanWrite(true);
300  generator_.StartBatchOperations();
301
302  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
303  EXPECT_EQ(3u, consumed.bytes_consumed);
304  EXPECT_TRUE(consumed.fin_consumed);
305  EXPECT_TRUE(generator_.HasQueuedData());
306}
307
308TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
309  delegate_.SetCanWrite(true);
310
311  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
312      DoAll(SaveArg<0>(&packet_), Return(true)));
313  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
314  EXPECT_EQ(3u, consumed.bytes_consumed);
315  EXPECT_TRUE(consumed.fin_consumed);
316  EXPECT_FALSE(generator_.HasQueuedData());
317
318  PacketContents contents;
319  contents.num_stream_frames = 1;
320  CheckPacketContains(contents, packet_);
321}
322
323TEST_F(QuicPacketGeneratorTest,
324       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
325  delegate_.SetCanWrite(true);
326  generator_.StartBatchOperations();
327
328  generator_.ConsumeData(1, "foo", 2, true);
329  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
330  EXPECT_EQ(4u, consumed.bytes_consumed);
331  EXPECT_FALSE(consumed.fin_consumed);
332  EXPECT_TRUE(generator_.HasQueuedData());
333}
334
335TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
336  delegate_.SetCanWrite(true);
337  generator_.StartBatchOperations();
338
339  generator_.ConsumeData(1, "foo", 2, true);
340  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
341  EXPECT_EQ(4u, consumed.bytes_consumed);
342  EXPECT_FALSE(consumed.fin_consumed);
343  EXPECT_TRUE(generator_.HasQueuedData());
344
345  // Now both frames will be flushed out.
346  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
347      DoAll(SaveArg<0>(&packet_), Return(true)));
348  generator_.FinishBatchOperations();
349  EXPECT_FALSE(generator_.HasQueuedData());
350
351  PacketContents contents;
352  contents.num_stream_frames = 2;
353  CheckPacketContains(contents, packet_);
354}
355
356TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) {
357  delegate_.SetCanWrite(true);
358
359  // Send FEC every two packets.
360  creator_.options()->max_packets_per_fec_group = 2;
361
362  {
363    InSequence dummy;
364    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
365        DoAll(SaveArg<0>(&packet_), Return(true)));
366    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
367        DoAll(SaveArg<0>(&packet2_), Return(true)));
368    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
369        DoAll(SaveArg<0>(&packet3_), Return(true)));
370    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
371        DoAll(SaveArg<0>(&packet4_), Return(true)));
372    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
373        DoAll(SaveArg<0>(&packet5_), Return(true)));
374  }
375
376  // Send enough data to create 3 packets: two full and one partial.
377  size_t data_len = 2 * kMaxPacketSize + 100;
378  QuicConsumedData consumed =
379      generator_.ConsumeData(3, CreateData(data_len), 0, true);
380  EXPECT_EQ(data_len, consumed.bytes_consumed);
381  EXPECT_TRUE(consumed.fin_consumed);
382  EXPECT_FALSE(generator_.HasQueuedData());
383
384  CheckPacketHasSingleStreamFrame(packet_);
385  CheckPacketHasSingleStreamFrame(packet2_);
386  CheckPacketIsFec(packet3_, 1);
387
388  CheckPacketHasSingleStreamFrame(packet4_);
389  CheckPacketIsFec(packet5_, 4);
390}
391
392TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) {
393  delegate_.SetCanWrite(true);
394
395  // Send FEC every six packets.
396  creator_.options()->max_packets_per_fec_group = 6;
397
398  {
399    InSequence dummy;
400    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
401        DoAll(SaveArg<0>(&packet_), Return(true)));
402    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
403        DoAll(SaveArg<0>(&packet2_), Return(true)));
404    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
405        DoAll(SaveArg<0>(&packet3_), Return(true)));
406  }
407
408  // Send enough data to create 2 packets: one full and one partial.
409  size_t data_len = 1 * kMaxPacketSize + 100;
410  QuicConsumedData consumed =
411      generator_.ConsumeData(3, CreateData(data_len), 0, true);
412  EXPECT_EQ(data_len, consumed.bytes_consumed);
413  EXPECT_TRUE(consumed.fin_consumed);
414  EXPECT_FALSE(generator_.HasQueuedData());
415
416  CheckPacketHasSingleStreamFrame(packet_);
417  CheckPacketHasSingleStreamFrame(packet2_);
418  CheckPacketIsFec(packet3_, 1);
419}
420
421TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
422  delegate_.SetCanWrite(false);
423
424  generator_.SetShouldSendAck(true);
425  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
426  EXPECT_TRUE(generator_.HasQueuedData());
427
428  delegate_.SetCanWrite(true);
429
430  generator_.StartBatchOperations();
431
432  // When the first write operation is invoked, the ack and feedback
433  // frames will be returned.
434  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
435  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
436      Return(CreateFeedbackFrame()));
437
438  // Send some data and a control frame
439  generator_.ConsumeData(3, "quux", 7, false);
440  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
441
442  // All five frames will be flushed out in a single packet.
443  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
444      DoAll(SaveArg<0>(&packet_), Return(true)));
445  generator_.FinishBatchOperations();
446  EXPECT_FALSE(generator_.HasQueuedData());
447
448  PacketContents contents;
449  contents.num_ack_frames = 1;
450  contents.num_goaway_frames = 1;
451  contents.num_feedback_frames = 1;
452  contents.num_rst_stream_frames = 1;
453  contents.num_stream_frames = 1;
454  CheckPacketContains(contents, packet_);
455}
456
457TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
458  delegate_.SetCanWrite(false);
459
460  generator_.SetShouldSendAck(true);
461  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
462  EXPECT_TRUE(generator_.HasQueuedData());
463
464  delegate_.SetCanWrite(true);
465
466  generator_.StartBatchOperations();
467
468  // When the first write operation is invoked, the ack and feedback
469  // frames will be returned.
470  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
471  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
472      Return(CreateFeedbackFrame()));
473
474  {
475    InSequence dummy;
476  // All five frames will be flushed out in a single packet
477  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
478      DoAll(SaveArg<0>(&packet_), Return(true)));
479  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
480      DoAll(SaveArg<0>(&packet2_), Return(true)));
481  }
482
483  // Send enough data to exceed one packet
484  size_t data_len = kMaxPacketSize + 100;
485  QuicConsumedData consumed =
486      generator_.ConsumeData(3, CreateData(data_len), 0, true);
487  EXPECT_EQ(data_len, consumed.bytes_consumed);
488  EXPECT_TRUE(consumed.fin_consumed);
489  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
490
491  generator_.FinishBatchOperations();
492  EXPECT_FALSE(generator_.HasQueuedData());
493
494  // The first packet should have the queued data and part of the stream data.
495  PacketContents contents;
496  contents.num_ack_frames = 1;
497  contents.num_feedback_frames = 1;
498  contents.num_rst_stream_frames = 1;
499  contents.num_stream_frames = 1;
500  CheckPacketContains(contents, packet_);
501
502  // The second should have the remainder of the stream data.
503  PacketContents contents2;
504  contents2.num_goaway_frames = 1;
505  contents2.num_stream_frames = 1;
506  CheckPacketContains(contents2, packet2_);
507}
508
509}  // namespace test
510}  // namespace net
511