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