| 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_stream_sequencer.h" | 5 #include "net/quic/quic_stream_sequencer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | 73 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
| 74 | 74 |
| 75 class QuicStreamSequencerTest : public ::testing::Test { | 75 class QuicStreamSequencerTest : public ::testing::Test { |
| 76 protected: | 76 protected: |
| 77 QuicStreamSequencerTest() | 77 QuicStreamSequencerTest() |
| 78 : session_(NULL), | 78 : session_(NULL), |
| 79 stream_(session_, 1), | 79 stream_(session_, 1), |
| 80 sequencer_(new QuicStreamSequencerPeer(&stream_)) { | 80 sequencer_(new QuicStreamSequencerPeer(&stream_)) { |
| 81 } | 81 } |
| 82 | 82 |
| 83 bool VerifyReadableRegions(const char** expected, size_t num_expected) { | |
| 84 iovec iovecs[5]; | |
| 85 size_t num_iovecs = sequencer_->GetReadableRegions(iovecs, | |
| 86 arraysize(iovecs)); | |
| 87 return VerifyIovecs(iovecs, num_iovecs, expected, num_expected); | |
| 88 } | |
| 89 | |
| 90 bool VerifyIovecs(iovec* iovecs, | |
| 91 size_t num_iovecs, | |
| 92 const char** expected, | |
| 93 size_t num_expected) { | |
| 94 if (num_expected != num_iovecs) { | |
| 95 LOG(ERROR) << "Incorrect number of iovecs. Expected: " | |
| 96 << num_expected << " Actual: " << num_iovecs; | |
| 97 return false; | |
| 98 } | |
| 99 for (size_t i = 0; i < num_expected; ++i) { | |
| 100 if (!VerifyIovec(iovecs[i], expected[i])) { | |
| 101 return false; | |
| 102 } | |
| 103 } | |
| 104 return true; | |
| 105 } | |
| 106 | |
| 107 bool VerifyIovec(const iovec& iovec, StringPiece expected) { | |
| 108 if (iovec.iov_len != expected.length()) { | |
| 109 LOG(ERROR) << "Invalid length: " << iovec.iov_len | |
| 110 << " vs " << expected.length(); | |
| 111 return false; | |
| 112 } | |
| 113 if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) { | |
| 114 LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base) | |
| 115 << " vs " << expected.data(); | |
| 116 return false; | |
| 117 } | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 QuicSession* session_; | 83 QuicSession* session_; |
| 122 testing::StrictMock<MockStream> stream_; | 84 testing::StrictMock<MockStream> stream_; |
| 123 scoped_ptr<QuicStreamSequencerPeer> sequencer_; | 85 scoped_ptr<QuicStreamSequencerPeer> sequencer_; |
| 124 }; | 86 }; |
| 125 | 87 |
| 126 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { | 88 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { |
| 127 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)) | 89 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)) |
| 128 .WillOnce(Return(3)); | 90 .WillOnce(Return(3)); |
| 129 | 91 |
| 130 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | 92 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 204 |
| 243 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); | 205 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); |
| 244 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); | 206 EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); |
| 245 EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3)); | 207 EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3)); |
| 246 | 208 |
| 247 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); | 209 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); |
| 248 EXPECT_EQ(12u, sequencer_->num_bytes_consumed()); | 210 EXPECT_EQ(12u, sequencer_->num_bytes_consumed()); |
| 249 EXPECT_EQ(0u, sequencer_->frames()->size()); | 211 EXPECT_EQ(0u, sequencer_->frames()->size()); |
| 250 } | 212 } |
| 251 | 213 |
| 252 TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithReadv) { | |
| 253 sequencer_->SetMemoryLimit(9); | |
| 254 char buffer[20]; | |
| 255 iovec iov[2]; | |
| 256 iov[0].iov_base = &buffer[0]; | |
| 257 iov[0].iov_len = 1; | |
| 258 iov[1].iov_base = &buffer[1]; | |
| 259 iov[1].iov_len = 2; | |
| 260 | |
| 261 // Push abc - process. | |
| 262 // Push jkl - buffer (not next data) | |
| 263 // Push def - don't process. | |
| 264 // Push mno - drop (too far out) | |
| 265 // Push ghi - buffer (def not processed) | |
| 266 // Read 2. | |
| 267 // Push mno - buffer (not all read) | |
| 268 // Read all | |
| 269 // Push pqr - process | |
| 270 | |
| 271 InSequence s; | |
| 272 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); | |
| 273 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(0)); | |
| 274 EXPECT_CALL(stream_, ProcessData(StrEq("pqr"), 3)).WillOnce(Return(3)); | |
| 275 | |
| 276 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | |
| 277 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); | |
| 278 EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); | |
| 279 EXPECT_FALSE(sequencer_->OnFrame(12, "mno", 3)); | |
| 280 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); | |
| 281 | |
| 282 // Read 3 bytes. | |
| 283 EXPECT_EQ(3, sequencer_->Readv(iov, 2)); | |
| 284 EXPECT_EQ(0, strncmp(buffer, "def", 3)); | |
| 285 | |
| 286 // Now we have space to bufer this. | |
| 287 EXPECT_TRUE(sequencer_->OnFrame(12, "mno", 3)); | |
| 288 | |
| 289 // Read the remaining 9 bytes. | |
| 290 iov[1].iov_len = 19; | |
| 291 EXPECT_EQ(9, sequencer_->Readv(iov, 2)); | |
| 292 EXPECT_EQ(0, strncmp(buffer, "ghijklmno", 9)); | |
| 293 | |
| 294 EXPECT_TRUE(sequencer_->OnFrame(15, "pqr", 3)); | |
| 295 } | |
| 296 | |
| 297 // Same as above, just using a different method for reading. | |
| 298 TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithGetReadableRegion) { | |
| 299 sequencer_->SetMemoryLimit(9); | |
| 300 | |
| 301 InSequence s; | |
| 302 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); | |
| 303 EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(0)); | |
| 304 EXPECT_CALL(stream_, ProcessData(StrEq("pqr"), 3)).WillOnce(Return(3)); | |
| 305 | |
| 306 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | |
| 307 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); | |
| 308 EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); | |
| 309 EXPECT_FALSE(sequencer_->OnFrame(12, "mno", 3)); | |
| 310 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); | |
| 311 | |
| 312 // Read 3 bytes. | |
| 313 const char* expected[] = {"def", "ghi", "jkl"}; | |
| 314 ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected))); | |
| 315 char buffer[9]; | |
| 316 iovec read_iov = { &buffer[0], 3 }; | |
| 317 ASSERT_EQ(3, sequencer_->Readv(&read_iov, 1)); | |
| 318 | |
| 319 // Now we have space to bufer this. | |
| 320 EXPECT_TRUE(sequencer_->OnFrame(12, "mno", 3)); | |
| 321 | |
| 322 // Read the remaining 9 bytes. | |
| 323 const char* expected2[] = {"ghi", "jkl", "mno"}; | |
| 324 ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2))); | |
| 325 read_iov.iov_len = 9; | |
| 326 ASSERT_EQ(9, sequencer_->Readv(&read_iov, 1)); | |
| 327 | |
| 328 EXPECT_TRUE(sequencer_->OnFrame(15, "pqr", 3)); | |
| 329 } | |
| 330 | |
| 331 // Same as above, just using a different method for reading. | |
| 332 TEST_F(QuicStreamSequencerTest, MarkConsumed) { | |
| 333 sequencer_->SetMemoryLimit(9); | |
| 334 | |
| 335 InSequence s; | |
| 336 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); | |
| 337 | |
| 338 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | |
| 339 EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); | |
| 340 EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); | |
| 341 | |
| 342 // Peek into the data. | |
| 343 const char* expected[] = {"abc", "def", "ghi"}; | |
| 344 ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected))); | |
| 345 | |
| 346 // Consume 1 byte. | |
| 347 sequencer_->MarkConsumed(1); | |
| 348 // Verify data. | |
| 349 const char* expected2[] = {"bc", "def", "ghi"}; | |
| 350 ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2))); | |
| 351 | |
| 352 // Consume 2 bytes. | |
| 353 sequencer_->MarkConsumed(2); | |
| 354 // Verify data. | |
| 355 const char* expected3[] = {"def", "ghi"}; | |
| 356 ASSERT_TRUE(VerifyReadableRegions(expected3, arraysize(expected3))); | |
| 357 | |
| 358 // Consume 5 bytes. | |
| 359 sequencer_->MarkConsumed(5); | |
| 360 // Verify data. | |
| 361 const char* expected4[] = {"i"}; | |
| 362 ASSERT_TRUE(VerifyReadableRegions(expected4, arraysize(expected4))); | |
| 363 } | |
| 364 | |
| 365 TEST_F(QuicStreamSequencerTest, BasicCloseOrdered) { | 214 TEST_F(QuicStreamSequencerTest, BasicCloseOrdered) { |
| 366 InSequence s; | 215 InSequence s; |
| 367 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); | 216 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
| 368 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | 217 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
| 369 | 218 |
| 370 EXPECT_CALL(stream_, TerminateFromPeer(false)); | 219 EXPECT_CALL(stream_, TerminateFromPeer(false)); |
| 371 sequencer_->CloseStreamAtOffset(3, false); | 220 sequencer_->CloseStreamAtOffset(3, false); |
| 372 EXPECT_EQ(3u, sequencer_->close_offset()); | 221 EXPECT_EQ(3u, sequencer_->close_offset()); |
| 373 } | 222 } |
| 374 | 223 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 | 297 |
| 449 sequencer_->CloseStreamAtOffset(3, true); | 298 sequencer_->CloseStreamAtOffset(3, true); |
| 450 EXPECT_EQ(3u, sequencer_->close_offset()); | 299 EXPECT_EQ(3u, sequencer_->close_offset()); |
| 451 | 300 |
| 452 InSequence s; | 301 InSequence s; |
| 453 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); | 302 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
| 454 EXPECT_CALL(stream_, TerminateFromPeer(false)); | 303 EXPECT_CALL(stream_, TerminateFromPeer(false)); |
| 455 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | 304 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
| 456 } | 305 } |
| 457 | 306 |
| 458 TEST_F(QuicStreamSequencerTest, TerminateWithReadv) { | |
| 459 char buffer[3]; | |
| 460 | |
| 461 sequencer_->CloseStreamAtOffset(3, true); | |
| 462 EXPECT_EQ(3u, sequencer_->close_offset()); | |
| 463 | |
| 464 EXPECT_FALSE(sequencer_->IsHalfClosed()); | |
| 465 | |
| 466 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); | |
| 467 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | |
| 468 | |
| 469 iovec iov = { &buffer[0], 3 }; | |
| 470 int bytes_read = sequencer_->Readv(&iov, 1); | |
| 471 EXPECT_EQ(3, bytes_read); | |
| 472 EXPECT_TRUE(sequencer_->IsHalfClosed()); | |
| 473 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 474 } | |
| 475 | |
| 476 TEST_F(QuicStreamSequencerTest, CloseWithReadv) { | |
| 477 char buffer[3]; | |
| 478 | |
| 479 sequencer_->CloseStreamAtOffset(3, false); | |
| 480 EXPECT_EQ(3u, sequencer_->close_offset()); | |
| 481 | |
| 482 EXPECT_FALSE(sequencer_->IsClosed()); | |
| 483 | |
| 484 EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(0)); | |
| 485 EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); | |
| 486 | |
| 487 iovec iov = { &buffer[0], 3 }; | |
| 488 int bytes_read = sequencer_->Readv(&iov, 1); | |
| 489 EXPECT_EQ(3, bytes_read); | |
| 490 EXPECT_TRUE(sequencer_->IsHalfClosed()); | |
| 491 EXPECT_TRUE(sequencer_->IsClosed()); | |
| 492 } | |
| 493 | |
| 494 TEST_F(QuicStreamSequencerTest, MutipleOffsets) { | 307 TEST_F(QuicStreamSequencerTest, MutipleOffsets) { |
| 495 sequencer_->CloseStreamAtOffset(3, false); | 308 sequencer_->CloseStreamAtOffset(3, false); |
| 496 EXPECT_EQ(3u, sequencer_->close_offset()); | 309 EXPECT_EQ(3u, sequencer_->close_offset()); |
| 497 | 310 |
| 498 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | 311 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); |
| 499 sequencer_->CloseStreamAtOffset(5, false); | 312 sequencer_->CloseStreamAtOffset(5, false); |
| 500 EXPECT_EQ(3u, sequencer_->close_offset()); | 313 EXPECT_EQ(3u, sequencer_->close_offset()); |
| 501 | 314 |
| 502 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | 315 EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); |
| 503 sequencer_->CloseStreamAtOffset(1, false); | 316 sequencer_->CloseStreamAtOffset(1, false); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 list_[index].second.size()); | 399 list_[index].second.size()); |
| 587 if (acked) { | 400 if (acked) { |
| 588 list_.erase(list_.begin() + index); | 401 list_.erase(list_.begin() + index); |
| 589 } | 402 } |
| 590 } | 403 } |
| 591 } | 404 } |
| 592 | 405 |
| 593 } // namespace | 406 } // namespace |
| 594 } // namespace test | 407 } // namespace test |
| 595 } // namespace net | 408 } // namespace net |
| OLD | NEW |