| 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_stream_sequencer.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <cstdint> | |
| 9 #include <memory> | |
| 10 #include <utility> | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "base/logging.h" | |
| 14 #include "base/rand_util.h" | |
| 15 #include "net/base/ip_endpoint.h" | |
| 16 #include "net/quic/quic_flags.h" | |
| 17 #include "net/quic/quic_utils.h" | |
| 18 #include "net/quic/reliable_quic_stream.h" | |
| 19 #include "net/quic/test_tools/mock_clock.h" | |
| 20 #include "net/quic/test_tools/quic_stream_sequencer_peer.h" | |
| 21 #include "net/quic/test_tools/quic_test_utils.h" | |
| 22 #include "net/test/gtest_util.h" | |
| 23 #include "testing/gmock/include/gmock/gmock.h" | |
| 24 #include "testing/gmock_mutant.h" | |
| 25 #include "testing/gtest/include/gtest/gtest.h" | |
| 26 | |
| 27 using base::StringPiece; | |
| 28 using std::map; | |
| 29 using std::min; | |
| 30 using std::pair; | |
| 31 using std::string; | |
| 32 using std::vector; | |
| 33 using testing::_; | |
| 34 using testing::AnyNumber; | |
| 35 using testing::CreateFunctor; | |
| 36 using testing::InSequence; | |
| 37 using testing::Return; | |
| 38 using testing::StrEq; | |
| 39 | |
| 40 namespace net { | |
| 41 namespace test { | |
| 42 | |
| 43 class MockStream : public ReliableQuicStream { | |
| 44 public: | |
| 45 MockStream(QuicSession* session, QuicStreamId id) | |
| 46 : ReliableQuicStream(id, session) {} | |
| 47 | |
| 48 MOCK_METHOD0(OnFinRead, void()); | |
| 49 MOCK_METHOD0(OnDataAvailable, void()); | |
| 50 MOCK_METHOD2(CloseConnectionWithDetails, | |
| 51 void(QuicErrorCode error, const string& details)); | |
| 52 MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); | |
| 53 MOCK_METHOD0(OnCanWrite, void()); | |
| 54 virtual bool IsFlowControlEnabled() const { return true; } | |
| 55 | |
| 56 const IPEndPoint& PeerAddressOfLatestPacket() const override { | |
| 57 return peer_address_; | |
| 58 } | |
| 59 | |
| 60 protected: | |
| 61 IPEndPoint peer_address_ = IPEndPoint(net::test::Any4(), 65535); | |
| 62 }; | |
| 63 | |
| 64 namespace { | |
| 65 | |
| 66 static const char kPayload[] = | |
| 67 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | |
| 68 | |
| 69 class QuicStreamSequencerTest : public ::testing::Test { | |
| 70 public: | |
| 71 void ConsumeData(size_t num_bytes) { | |
| 72 char buffer[1024]; | |
| 73 ASSERT_GT(arraysize(buffer), num_bytes); | |
| 74 struct iovec iov; | |
| 75 iov.iov_base = buffer; | |
| 76 iov.iov_len = num_bytes; | |
| 77 ASSERT_EQ(static_cast<int>(num_bytes), sequencer_->Readv(&iov, 1)); | |
| 78 } | |
| 79 | |
| 80 protected: | |
| 81 QuicStreamSequencerTest() | |
| 82 : connection_(new MockQuicConnection(&helper_, | |
| 83 &alarm_factory_, | |
| 84 Perspective::IS_CLIENT)), | |
| 85 session_(connection_), | |
| 86 stream_(&session_, 1), | |
| 87 sequencer_(new QuicStreamSequencer(&stream_, &clock_)) {} | |
| 88 | |
| 89 // Verify that the data in first region match with the expected[0]. | |
| 90 bool VerifyReadableRegion(const vector<string>& expected) { | |
| 91 iovec iovecs[1]; | |
| 92 if (sequencer_->GetReadableRegions(iovecs, 1)) { | |
| 93 return (VerifyIovecs(iovecs, 1, vector<string>{expected[0]})); | |
| 94 } | |
| 95 return false; | |
| 96 } | |
| 97 | |
| 98 // Verify that the data in each of currently readable regions match with each | |
| 99 // item given in |expected|. | |
| 100 bool VerifyReadableRegions(const vector<string>& expected) { | |
| 101 iovec iovecs[5]; | |
| 102 size_t num_iovecs = | |
| 103 sequencer_->GetReadableRegions(iovecs, arraysize(iovecs)); | |
| 104 return VerifyReadableRegion(expected) && | |
| 105 VerifyIovecs(iovecs, num_iovecs, expected); | |
| 106 } | |
| 107 | |
| 108 bool VerifyIovecs(iovec* iovecs, | |
| 109 size_t num_iovecs, | |
| 110 const vector<string>& expected) { | |
| 111 int start_position = 0; | |
| 112 for (size_t i = 0; i < num_iovecs; ++i) { | |
| 113 if (!VerifyIovec(iovecs[i], | |
| 114 expected[0].substr(start_position, iovecs[i].iov_len))) { | |
| 115 return false; | |
| 116 } | |
| 117 start_position += iovecs[i].iov_len; | |
| 118 } | |
| 119 return true; | |
| 120 } | |
| 121 | |
| 122 bool VerifyIovec(const iovec& iovec, StringPiece expected) { | |
| 123 if (iovec.iov_len != expected.length()) { | |
| 124 LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs " | |
| 125 << expected.length(); | |
| 126 return false; | |
| 127 } | |
| 128 if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) { | |
| 129 LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base) | |
| 130 << " vs " << expected; | |
| 131 return false; | |
| 132 } | |
| 133 return true; | |
| 134 } | |
| 135 | |
| 136 void OnFinFrame(QuicStreamOffset byte_offset, const char* data) { | |
| 137 QuicStreamFrame frame; | |
| 138 frame.stream_id = 1; | |
| 139 frame.offset = byte_offset; | |
| 140 frame.data_buffer = data; | |
| 141 frame.data_length = strlen(data); | |
| 142 frame.fin = true; | |
| 143 sequencer_->OnStreamFrame(frame); | |
| 144 } | |
| 145 | |
| 146 void OnFrame(QuicStreamOffset byte_offset, const char* data) { | |
| 147 QuicStreamFrame frame; | |
| 148 frame.stream_id = 1; | |
| 149 frame.offset = byte_offset; | |
| 150 frame.data_buffer = data; | |
| 151 frame.data_length = strlen(data); | |
| 152 frame.fin = false; | |
| 153 sequencer_->OnStreamFrame(frame); | |
| 154 } | |
| 155 | |
| 156 size_t NumBufferedBytes() { | |
| 157 return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get()); | |
| 158 } | |
| 159 | |
| 160 MockQuicConnectionHelper helper_; | |
| 161 MockAlarmFactory alarm_factory_; | |
| 162 MockQuicConnection* connection_; | |
| 163 MockClock clock_; | |
| 164 MockQuicSpdySession session_; | |
| 165 testing::StrictMock<MockStream> stream_; | |
| 166 std::unique_ptr<QuicStreamSequencer> sequencer_; | |
| 167 }; | |
| 168 | |
| 169 // TODO(rch): reorder these tests so they build on each other. | |
| 170 | |
| 171 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { | |
| 172 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 173 .WillOnce(testing::Invoke( | |
| 174 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 175 base::Unretained(this), 3))); | |
| 176 | |
| 177 OnFrame(0, "abc"); | |
| 178 | |
| 179 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 180 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 181 EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed()); | |
| 182 // Ignore this - it matches a past packet number and we should not see it | |
| 183 // again. | |
| 184 OnFrame(0, "def"); | |
| 185 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 186 } | |
| 187 | |
| 188 TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) { | |
| 189 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 190 | |
| 191 OnFrame(0, "abc"); | |
| 192 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 193 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 194 | |
| 195 // Ignore this - it matches a buffered frame. | |
| 196 // Right now there's no checking that the payload is consistent. | |
| 197 OnFrame(0, "def"); | |
| 198 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 199 } | |
| 200 | |
| 201 TEST_F(QuicStreamSequencerTest, FullFrameConsumed) { | |
| 202 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 203 .WillOnce(testing::Invoke( | |
| 204 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 205 base::Unretained(this), 3))); | |
| 206 | |
| 207 OnFrame(0, "abc"); | |
| 208 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 209 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 210 } | |
| 211 | |
| 212 TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) { | |
| 213 sequencer_->SetBlockedUntilFlush(); | |
| 214 | |
| 215 OnFrame(0, "abc"); | |
| 216 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 217 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 218 | |
| 219 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 220 .WillOnce(testing::Invoke( | |
| 221 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 222 base::Unretained(this), 3))); | |
| 223 sequencer_->SetUnblocked(); | |
| 224 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 225 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 226 | |
| 227 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 228 .WillOnce(testing::Invoke( | |
| 229 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 230 base::Unretained(this), 3))); | |
| 231 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 232 OnFinFrame(3, "def"); | |
| 233 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 234 } | |
| 235 | |
| 236 TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) { | |
| 237 sequencer_->SetBlockedUntilFlush(); | |
| 238 | |
| 239 OnFinFrame(0, "abc"); | |
| 240 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 241 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 242 | |
| 243 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 244 .WillOnce(testing::Invoke( | |
| 245 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 246 base::Unretained(this), 3))); | |
| 247 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 248 sequencer_->SetUnblocked(); | |
| 249 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 250 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 251 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 252 } | |
| 253 | |
| 254 TEST_F(QuicStreamSequencerTest, EmptyFrame) { | |
| 255 EXPECT_CALL(stream_, | |
| 256 CloseConnectionWithDetails(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _)); | |
| 257 OnFrame(0, ""); | |
| 258 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 259 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 260 } | |
| 261 | |
| 262 TEST_F(QuicStreamSequencerTest, EmptyFinFrame) { | |
| 263 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 264 OnFinFrame(0, ""); | |
| 265 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 266 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 267 } | |
| 268 | |
| 269 TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) { | |
| 270 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 271 .WillOnce(testing::Invoke( | |
| 272 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 273 base::Unretained(this), 2))); | |
| 274 | |
| 275 OnFrame(0, "abc"); | |
| 276 EXPECT_EQ(1u, NumBufferedBytes()); | |
| 277 EXPECT_EQ(2u, sequencer_->NumBytesConsumed()); | |
| 278 } | |
| 279 | |
| 280 TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) { | |
| 281 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 282 | |
| 283 OnFrame(0, "abc"); | |
| 284 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 285 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 286 EXPECT_EQ(0, sequencer_->num_early_frames_received()); | |
| 287 } | |
| 288 | |
| 289 TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { | |
| 290 OnFrame(3, "abc"); | |
| 291 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 292 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 293 EXPECT_EQ(1, sequencer_->num_early_frames_received()); | |
| 294 } | |
| 295 | |
| 296 TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) { | |
| 297 // Buffer the first | |
| 298 OnFrame(6, "ghi"); | |
| 299 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 300 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 301 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
| 302 // Buffer the second | |
| 303 OnFrame(3, "def"); | |
| 304 EXPECT_EQ(6u, NumBufferedBytes()); | |
| 305 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 306 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
| 307 | |
| 308 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 309 .WillOnce(testing::Invoke( | |
| 310 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 311 base::Unretained(this), 9))); | |
| 312 | |
| 313 // Now process all of them at once. | |
| 314 OnFrame(0, "abc"); | |
| 315 EXPECT_EQ(9u, sequencer_->NumBytesConsumed()); | |
| 316 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
| 317 | |
| 318 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 319 } | |
| 320 | |
| 321 TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) { | |
| 322 InSequence s; | |
| 323 | |
| 324 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 325 .WillOnce(testing::Invoke( | |
| 326 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 327 base::Unretained(this), 3))); | |
| 328 OnFinFrame(0, "abc"); | |
| 329 | |
| 330 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 331 } | |
| 332 | |
| 333 TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) { | |
| 334 OnFinFrame(6, ""); | |
| 335 EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 336 | |
| 337 OnFrame(3, "def"); | |
| 338 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 339 .WillOnce(testing::Invoke( | |
| 340 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 341 base::Unretained(this), 6))); | |
| 342 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 343 OnFrame(0, "abc"); | |
| 344 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 345 } | |
| 346 | |
| 347 TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) { | |
| 348 OnFinFrame(3, ""); | |
| 349 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 350 | |
| 351 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 352 .WillOnce(testing::Invoke( | |
| 353 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
| 354 base::Unretained(this), 3))); | |
| 355 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 356 OnFrame(0, "abc"); | |
| 357 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 358 } | |
| 359 | |
| 360 TEST_F(QuicStreamSequencerTest, TerminateWithReadv) { | |
| 361 char buffer[3]; | |
| 362 | |
| 363 OnFinFrame(3, ""); | |
| 364 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 365 | |
| 366 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 367 | |
| 368 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 369 OnFrame(0, "abc"); | |
| 370 | |
| 371 iovec iov = {&buffer[0], 3}; | |
| 372 int bytes_read = sequencer_->Readv(&iov, 1); | |
| 373 EXPECT_EQ(3, bytes_read); | |
| 374 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 375 } | |
| 376 | |
| 377 TEST_F(QuicStreamSequencerTest, MutipleOffsets) { | |
| 378 OnFinFrame(3, ""); | |
| 379 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 380 | |
| 381 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | |
| 382 OnFinFrame(5, ""); | |
| 383 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 384 | |
| 385 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | |
| 386 OnFinFrame(1, ""); | |
| 387 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 388 | |
| 389 OnFinFrame(3, ""); | |
| 390 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
| 391 } | |
| 392 | |
| 393 class QuicSequencerRandomTest : public QuicStreamSequencerTest { | |
| 394 public: | |
| 395 typedef pair<int, string> Frame; | |
| 396 typedef vector<Frame> FrameList; | |
| 397 | |
| 398 void CreateFrames() { | |
| 399 int payload_size = arraysize(kPayload) - 1; | |
| 400 int remaining_payload = payload_size; | |
| 401 while (remaining_payload != 0) { | |
| 402 int size = min(OneToN(6), remaining_payload); | |
| 403 int index = payload_size - remaining_payload; | |
| 404 list_.push_back(std::make_pair(index, string(kPayload + index, size))); | |
| 405 remaining_payload -= size; | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 QuicSequencerRandomTest() { CreateFrames(); } | |
| 410 | |
| 411 int OneToN(int n) { return base::RandInt(1, n); } | |
| 412 | |
| 413 void ReadAvailableData() { | |
| 414 // Read all available data | |
| 415 char output[arraysize(kPayload) + 1]; | |
| 416 iovec iov; | |
| 417 iov.iov_base = output; | |
| 418 iov.iov_len = arraysize(output); | |
| 419 int bytes_read = sequencer_->Readv(&iov, 1); | |
| 420 EXPECT_NE(0, bytes_read); | |
| 421 output_.append(output, bytes_read); | |
| 422 } | |
| 423 | |
| 424 string output_; | |
| 425 // Data which peek at using GetReadableRegion if we back up. | |
| 426 string peeked_; | |
| 427 FrameList list_; | |
| 428 }; | |
| 429 | |
| 430 // All frames are processed as soon as we have sequential data. | |
| 431 // Infinite buffering, so all frames are acked right away. | |
| 432 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { | |
| 433 InSequence s; | |
| 434 EXPECT_CALL(stream_, OnDataAvailable()) | |
| 435 .Times(AnyNumber()) | |
| 436 .WillRepeatedly( | |
| 437 Invoke(this, &QuicSequencerRandomTest::ReadAvailableData)); | |
| 438 | |
| 439 while (!list_.empty()) { | |
| 440 int index = OneToN(list_.size()) - 1; | |
| 441 LOG(ERROR) << "Sending index " << index << " " << list_[index].second; | |
| 442 OnFrame(list_[index].first, list_[index].second.data()); | |
| 443 | |
| 444 list_.erase(list_.begin() + index); | |
| 445 } | |
| 446 | |
| 447 ASSERT_EQ(arraysize(kPayload) - 1, output_.size()); | |
| 448 EXPECT_EQ(kPayload, output_); | |
| 449 } | |
| 450 | |
| 451 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { | |
| 452 char buffer[10]; | |
| 453 iovec iov[2]; | |
| 454 iov[0].iov_base = &buffer[0]; | |
| 455 iov[0].iov_len = 5; | |
| 456 iov[1].iov_base = &buffer[5]; | |
| 457 iov[1].iov_len = 5; | |
| 458 | |
| 459 EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber()); | |
| 460 | |
| 461 while (output_.size() != arraysize(kPayload) - 1) { | |
| 462 if (!list_.empty() && (base::RandUint64() % 2 == 0)) { // Send data | |
| 463 int index = OneToN(list_.size()) - 1; | |
| 464 OnFrame(list_[index].first, list_[index].second.data()); | |
| 465 list_.erase(list_.begin() + index); | |
| 466 } else { // Read data | |
| 467 bool has_bytes = sequencer_->HasBytesToRead(); | |
| 468 iovec peek_iov[20]; | |
| 469 int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20); | |
| 470 QuicTime timestamp = clock_.ApproximateNow(); | |
| 471 if (has_bytes) { | |
| 472 ASSERT_LT(0, iovs_peeked); | |
| 473 ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov, ×tamp)); | |
| 474 } else { | |
| 475 ASSERT_EQ(0, iovs_peeked); | |
| 476 ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov, ×tamp)); | |
| 477 } | |
| 478 int total_bytes_to_peek = arraysize(buffer); | |
| 479 for (int i = 0; i < iovs_peeked; ++i) { | |
| 480 int bytes_to_peek = min<int>(peek_iov[i].iov_len, total_bytes_to_peek); | |
| 481 peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek); | |
| 482 total_bytes_to_peek -= bytes_to_peek; | |
| 483 if (total_bytes_to_peek == 0) { | |
| 484 break; | |
| 485 } | |
| 486 } | |
| 487 int bytes_read = sequencer_->Readv(iov, 2); | |
| 488 output_.append(buffer, bytes_read); | |
| 489 ASSERT_EQ(output_.size(), peeked_.size()); | |
| 490 } | |
| 491 } | |
| 492 EXPECT_EQ(string(kPayload), output_); | |
| 493 EXPECT_EQ(string(kPayload), peeked_); | |
| 494 } | |
| 495 | |
| 496 // Same as above, just using a different method for reading. | |
| 497 TEST_F(QuicStreamSequencerTest, MarkConsumed) { | |
| 498 InSequence s; | |
| 499 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 500 | |
| 501 OnFrame(0, "abc"); | |
| 502 OnFrame(3, "def"); | |
| 503 OnFrame(6, "ghi"); | |
| 504 | |
| 505 // abcdefghi buffered. | |
| 506 EXPECT_EQ(9u, sequencer_->NumBytesBuffered()); | |
| 507 | |
| 508 // Peek into the data. | |
| 509 vector<string> expected = {"abcdefghi"}; | |
| 510 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
| 511 | |
| 512 // Consume 1 byte. | |
| 513 sequencer_->MarkConsumed(1); | |
| 514 EXPECT_EQ(1u, stream_.flow_controller()->bytes_consumed()); | |
| 515 // Verify data. | |
| 516 vector<string> expected2 = {"bcdefghi"}; | |
| 517 ASSERT_TRUE(VerifyReadableRegions(expected2)); | |
| 518 EXPECT_EQ(8u, sequencer_->NumBytesBuffered()); | |
| 519 | |
| 520 // Consume 2 bytes. | |
| 521 sequencer_->MarkConsumed(2); | |
| 522 EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed()); | |
| 523 // Verify data. | |
| 524 vector<string> expected3 = {"defghi"}; | |
| 525 ASSERT_TRUE(VerifyReadableRegions(expected3)); | |
| 526 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
| 527 | |
| 528 // Consume 5 bytes. | |
| 529 sequencer_->MarkConsumed(5); | |
| 530 EXPECT_EQ(8u, stream_.flow_controller()->bytes_consumed()); | |
| 531 // Verify data. | |
| 532 vector<string> expected4{"i"}; | |
| 533 ASSERT_TRUE(VerifyReadableRegions(expected4)); | |
| 534 EXPECT_EQ(1u, sequencer_->NumBytesBuffered()); | |
| 535 } | |
| 536 | |
| 537 TEST_F(QuicStreamSequencerTest, MarkConsumedError) { | |
| 538 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 539 | |
| 540 OnFrame(0, "abc"); | |
| 541 OnFrame(9, "jklmnopqrstuvwxyz"); | |
| 542 | |
| 543 // Peek into the data. Only the first chunk should be readable because of the | |
| 544 // missing data. | |
| 545 vector<string> expected{"abc"}; | |
| 546 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
| 547 | |
| 548 // Now, attempt to mark consumed more data than was readable and expect the | |
| 549 // stream to be closed. | |
| 550 EXPECT_CALL(stream_, Reset(QUIC_ERROR_PROCESSING_STREAM)); | |
| 551 EXPECT_DFATAL(sequencer_->MarkConsumed(4), | |
| 552 "Invalid argument to MarkConsumed." | |
| 553 " expect to consume: 4, but not enough bytes available."); | |
| 554 } | |
| 555 | |
| 556 TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) { | |
| 557 InSequence s; | |
| 558 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 559 | |
| 560 OnFrame(0, "abc"); | |
| 561 OnFrame(3, "def"); | |
| 562 // Missing packet: 6, ghi. | |
| 563 OnFrame(9, "jkl"); | |
| 564 | |
| 565 vector<string> expected = {"abcdef"}; | |
| 566 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
| 567 | |
| 568 sequencer_->MarkConsumed(6); | |
| 569 } | |
| 570 | |
| 571 TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) { | |
| 572 // The peer should never send us non-identical stream frames which contain | |
| 573 // overlapping byte ranges - if they do, we close the connection. | |
| 574 | |
| 575 QuicStreamFrame frame1(kClientDataStreamId1, false, 1, StringPiece("hello")); | |
| 576 sequencer_->OnStreamFrame(frame1); | |
| 577 | |
| 578 QuicStreamFrame frame2(kClientDataStreamId1, false, 2, StringPiece("hello")); | |
| 579 EXPECT_CALL(stream_, | |
| 580 CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _)) | |
| 581 .Times(1); | |
| 582 sequencer_->OnStreamFrame(frame2); | |
| 583 } | |
| 584 | |
| 585 TEST_F(QuicStreamSequencerTest, InOrderTimestamps) { | |
| 586 // This test verifies that timestamps returned by | |
| 587 // GetReadableRegion() are in the correct sequence when frames | |
| 588 // arrive at the sequencer in order. | |
| 589 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 590 | |
| 591 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 592 | |
| 593 // Buffer the first frame. | |
| 594 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 595 QuicTime t1 = clock_.ApproximateNow(); | |
| 596 OnFrame(0, "abc"); | |
| 597 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 598 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 599 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
| 600 // Buffer the second frame. | |
| 601 QuicTime t2 = clock_.ApproximateNow(); | |
| 602 OnFrame(3, "def"); | |
| 603 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 604 EXPECT_EQ(6u, NumBufferedBytes()); | |
| 605 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 606 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
| 607 | |
| 608 iovec iovecs[1]; | |
| 609 QuicTime timestamp(QuicTime::Zero()); | |
| 610 | |
| 611 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
| 612 EXPECT_EQ(timestamp, t1); | |
| 613 QuicStreamSequencerTest::ConsumeData(3); | |
| 614 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 615 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 616 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
| 617 | |
| 618 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
| 619 EXPECT_EQ(timestamp, t2); | |
| 620 QuicStreamSequencerTest::ConsumeData(3); | |
| 621 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 622 EXPECT_EQ(6u, sequencer_->NumBytesConsumed()); | |
| 623 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
| 624 } | |
| 625 | |
| 626 TEST_F(QuicStreamSequencerTest, OutOfOrderTimestamps) { | |
| 627 // This test verifies that timestamps returned by | |
| 628 // GetReadableRegion() are in the correct sequence when frames | |
| 629 // arrive at the sequencer out of order. | |
| 630 EXPECT_CALL(stream_, OnDataAvailable()); | |
| 631 | |
| 632 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 633 | |
| 634 // Buffer the first frame | |
| 635 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 636 QuicTime t1 = clock_.ApproximateNow(); | |
| 637 OnFrame(3, "def"); | |
| 638 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 639 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 640 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
| 641 // Buffer the second frame | |
| 642 QuicTime t2 = clock_.ApproximateNow(); | |
| 643 OnFrame(0, "abc"); | |
| 644 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
| 645 EXPECT_EQ(6u, NumBufferedBytes()); | |
| 646 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
| 647 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
| 648 | |
| 649 iovec iovecs[1]; | |
| 650 QuicTime timestamp(QuicTime::Zero()); | |
| 651 | |
| 652 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
| 653 EXPECT_EQ(timestamp, t2); | |
| 654 QuicStreamSequencerTest::ConsumeData(3); | |
| 655 EXPECT_EQ(3u, NumBufferedBytes()); | |
| 656 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
| 657 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
| 658 | |
| 659 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
| 660 EXPECT_EQ(timestamp, t1); | |
| 661 QuicStreamSequencerTest::ConsumeData(3); | |
| 662 EXPECT_EQ(0u, NumBufferedBytes()); | |
| 663 EXPECT_EQ(6u, sequencer_->NumBytesConsumed()); | |
| 664 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
| 665 } | |
| 666 | |
| 667 } // namespace | |
| 668 } // namespace test | |
| 669 } // namespace net | |
| OLD | NEW |