| 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/chromium/quic_chromium_client_stream.h" | 5 #include "net/quic/chromium/quic_chromium_client_stream.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 const QuicStreamId kTestStreamId = 5u; | 39 const QuicStreamId kTestStreamId = 5u; |
| 40 | 40 |
| 41 class MockDelegate : public QuicChromiumClientStream::Delegate { | 41 class MockDelegate : public QuicChromiumClientStream::Delegate { |
| 42 public: | 42 public: |
| 43 MockDelegate() {} | 43 MockDelegate() {} |
| 44 | 44 |
| 45 MOCK_METHOD0(OnSendData, int()); | 45 MOCK_METHOD0(OnSendData, int()); |
| 46 MOCK_METHOD2(OnSendDataComplete, int(int, bool*)); | 46 MOCK_METHOD2(OnSendDataComplete, int(int, bool*)); |
| 47 void OnHeadersAvailable(const SpdyHeaderBlock& headers, | 47 void OnInitialHeadersAvailable(const SpdyHeaderBlock& headers, |
| 48 size_t frame_len) override { | 48 size_t frame_len) override { |
| 49 headers_ = headers.Clone(); | 49 headers_ = headers.Clone(); |
| 50 OnHeadersAvailableMock(headers, frame_len); | 50 OnInitialHeadersAvailableMock(headers, frame_len); |
| 51 } | 51 } |
| 52 MOCK_METHOD2(OnHeadersAvailableMock, | 52 MOCK_METHOD2(OnInitialHeadersAvailableMock, |
| 53 void(const SpdyHeaderBlock& headers, size_t frame_len)); |
| 54 void OnTrailingHeadersAvailable(const SpdyHeaderBlock& headers, |
| 55 size_t frame_len) override { |
| 56 trailers_ = headers.Clone(); |
| 57 OnTrailingHeadersAvailableMock(headers, frame_len); |
| 58 } |
| 59 MOCK_METHOD2(OnTrailingHeadersAvailableMock, |
| 53 void(const SpdyHeaderBlock& headers, size_t frame_len)); | 60 void(const SpdyHeaderBlock& headers, size_t frame_len)); |
| 54 MOCK_METHOD2(OnDataReceived, int(const char*, int)); | 61 MOCK_METHOD2(OnDataReceived, int(const char*, int)); |
| 55 MOCK_METHOD0(OnDataAvailable, void()); | 62 MOCK_METHOD0(OnDataAvailable, void()); |
| 56 MOCK_METHOD0(OnClose, void()); | 63 MOCK_METHOD0(OnClose, void()); |
| 57 MOCK_METHOD1(OnError, void(int)); | 64 MOCK_METHOD1(OnError, void(int)); |
| 58 MOCK_METHOD0(HasSendHeadersComplete, bool()); | 65 MOCK_METHOD0(HasSendHeadersComplete, bool()); |
| 59 | 66 |
| 60 SpdyHeaderBlock headers_; | 67 SpdyHeaderBlock headers_; |
| 68 SpdyHeaderBlock trailers_; |
| 61 | 69 |
| 62 private: | 70 private: |
| 63 DISALLOW_COPY_AND_ASSIGN(MockDelegate); | 71 DISALLOW_COPY_AND_ASSIGN(MockDelegate); |
| 64 }; | 72 }; |
| 65 | 73 |
| 66 class TestQuicClientSessionBaseStream : public QuicSpdyStream { | 74 class TestQuicClientSessionBaseStream : public QuicSpdyStream { |
| 67 public: | 75 public: |
| 68 TestQuicClientSessionBaseStream(QuicStreamId id, QuicSpdySession* session) | 76 TestQuicClientSessionBaseStream(QuicStreamId id, QuicSpdySession* session) |
| 69 : QuicSpdyStream(id, session) {} | 77 : QuicSpdyStream(id, session) {} |
| 70 | 78 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 } | 254 } |
| 247 | 255 |
| 248 QuicHeaderList ProcessTrailers(const SpdyHeaderBlock& headers) { | 256 QuicHeaderList ProcessTrailers(const SpdyHeaderBlock& headers) { |
| 249 QuicHeaderList h = AsHeaderList(headers); | 257 QuicHeaderList h = AsHeaderList(headers); |
| 250 stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h); | 258 stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h); |
| 251 return h; | 259 return h; |
| 252 } | 260 } |
| 253 | 261 |
| 254 QuicHeaderList ProcessHeadersFull(const SpdyHeaderBlock& headers) { | 262 QuicHeaderList ProcessHeadersFull(const SpdyHeaderBlock& headers) { |
| 255 QuicHeaderList h = ProcessHeaders(headers); | 263 QuicHeaderList h = ProcessHeaders(headers); |
| 256 EXPECT_CALL(delegate_, | 264 EXPECT_CALL(delegate_, OnInitialHeadersAvailableMock( |
| 257 OnHeadersAvailableMock(_, h.uncompressed_header_bytes())); | 265 _, h.uncompressed_header_bytes())); |
| 258 base::RunLoop().RunUntilIdle(); | 266 base::RunLoop().RunUntilIdle(); |
| 259 EXPECT_EQ(headers, delegate_.headers_); | 267 EXPECT_EQ(headers, delegate_.headers_); |
| 260 EXPECT_TRUE(stream_->header_list().empty()); | 268 EXPECT_TRUE(stream_->header_list().empty()); |
| 261 return h; | 269 return h; |
| 262 } | 270 } |
| 263 | 271 |
| 264 QuicStreamId GetNthClientInitiatedStreamId(int n) { | 272 QuicStreamId GetNthClientInitiatedStreamId(int n) { |
| 265 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); | 273 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); |
| 266 } | 274 } |
| 267 | 275 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 378 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), |
| 371 QuicStringPiece(data, arraysize(data) - 1)))); | 379 QuicStringPiece(data, arraysize(data) - 1)))); |
| 372 | 380 |
| 373 SpdyHeaderBlock trailers; | 381 SpdyHeaderBlock trailers; |
| 374 trailers["bar"] = "foo"; | 382 trailers["bar"] = "foo"; |
| 375 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 383 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
| 376 | 384 |
| 377 auto t = ProcessTrailers(trailers); | 385 auto t = ProcessTrailers(trailers); |
| 378 base::RunLoop run_loop; | 386 base::RunLoop run_loop; |
| 379 EXPECT_CALL(delegate_, | 387 EXPECT_CALL(delegate_, |
| 380 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 388 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 381 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); | 389 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); |
| 382 | 390 |
| 383 run_loop.Run(); | 391 run_loop.Run(); |
| 384 | 392 |
| 385 // OnDataAvailable callback should follow trailers notification. | 393 // OnDataAvailable callback should follow trailers notification. |
| 386 base::RunLoop run_loop3; | 394 base::RunLoop run_loop3; |
| 387 EXPECT_CALL(delegate_, OnDataAvailable()) | 395 EXPECT_CALL(delegate_, OnDataAvailable()) |
| 388 .Times(1) | 396 .Times(1) |
| 389 .WillOnce(testing::DoAll( | 397 .WillOnce(testing::DoAll( |
| 390 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 398 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
| 391 base::Unretained(this), | 399 base::Unretained(this), |
| 392 QuicStringPiece())), | 400 QuicStringPiece())), |
| 393 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | 401 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); |
| 394 run_loop3.Run(); | 402 run_loop3.Run(); |
| 395 | 403 |
| 396 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 404 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 397 trailers.erase(kFinalOffsetHeaderKey); | 405 trailers.erase(kFinalOffsetHeaderKey); |
| 398 EXPECT_EQ(trailers, delegate_.headers_); | 406 EXPECT_EQ(trailers, delegate_.trailers_); |
| 399 base::RunLoop().RunUntilIdle(); | 407 base::RunLoop().RunUntilIdle(); |
| 400 EXPECT_CALL(delegate_, OnClose()); | 408 EXPECT_CALL(delegate_, OnClose()); |
| 401 } | 409 } |
| 402 | 410 |
| 403 // Tests that trailers are marked as consumed only before delegate is to be | 411 // Tests that trailers are marked as consumed only before delegate is to be |
| 404 // immediately notified about trailers. | 412 // immediately notified about trailers. |
| 405 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { | 413 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { |
| 406 InitializeHeaders(); | 414 InitializeHeaders(); |
| 407 ProcessHeadersFull(headers_); | 415 ProcessHeadersFull(headers_); |
| 408 | 416 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 427 EXPECT_THAT(stream_->Read(buffer.get(), 1), IsError(ERR_IO_PENDING)); | 435 EXPECT_THAT(stream_->Read(buffer.get(), 1), IsError(ERR_IO_PENDING)); |
| 428 | 436 |
| 429 SpdyHeaderBlock trailers; | 437 SpdyHeaderBlock trailers; |
| 430 trailers["bar"] = "foo"; | 438 trailers["bar"] = "foo"; |
| 431 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 439 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
| 432 QuicHeaderList t = ProcessTrailers(trailers); | 440 QuicHeaderList t = ProcessTrailers(trailers); |
| 433 EXPECT_FALSE(stream_->IsDoneReading()); | 441 EXPECT_FALSE(stream_->IsDoneReading()); |
| 434 | 442 |
| 435 base::RunLoop run_loop2; | 443 base::RunLoop run_loop2; |
| 436 EXPECT_CALL(delegate_, | 444 EXPECT_CALL(delegate_, |
| 437 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 445 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 438 .WillOnce( | 446 .WillOnce( |
| 439 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 447 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
| 440 | 448 |
| 441 run_loop2.Run(); | 449 run_loop2.Run(); |
| 442 | 450 |
| 443 // OnDataAvailable callback should follow trailers notification. | 451 // OnDataAvailable callback should follow trailers notification. |
| 444 base::RunLoop run_loop3; | 452 base::RunLoop run_loop3; |
| 445 EXPECT_CALL(delegate_, OnDataAvailable()) | 453 EXPECT_CALL(delegate_, OnDataAvailable()) |
| 446 .Times(1) | 454 .Times(1) |
| 447 .WillOnce(testing::DoAll( | 455 .WillOnce(testing::DoAll( |
| 448 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 456 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
| 449 base::Unretained(this), | 457 base::Unretained(this), |
| 450 QuicStringPiece())), | 458 QuicStringPiece())), |
| 451 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | 459 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); |
| 452 run_loop3.Run(); | 460 run_loop3.Run(); |
| 453 | 461 |
| 454 // Make sure the stream is properly closed since trailers and data are all | 462 // Make sure the stream is properly closed since trailers and data are all |
| 455 // consumed. | 463 // consumed. |
| 456 EXPECT_TRUE(stream_->IsDoneReading()); | 464 EXPECT_TRUE(stream_->IsDoneReading()); |
| 457 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 465 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 458 trailers.erase(kFinalOffsetHeaderKey); | 466 trailers.erase(kFinalOffsetHeaderKey); |
| 459 EXPECT_EQ(trailers, delegate_.headers_); | 467 EXPECT_EQ(trailers, delegate_.trailers_); |
| 460 | 468 |
| 461 base::RunLoop().RunUntilIdle(); | 469 base::RunLoop().RunUntilIdle(); |
| 462 EXPECT_CALL(delegate_, OnClose()); | 470 EXPECT_CALL(delegate_, OnClose()); |
| 463 } | 471 } |
| 464 | 472 |
| 465 // Test that if Read() is called after response body is read and after trailers | 473 // Test that if Read() is called after response body is read and after trailers |
| 466 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead | 474 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead |
| 467 // of 0 (EOF). | 475 // of 0 (EOF). |
| 468 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { | 476 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { |
| 469 InitializeHeaders(); | 477 InitializeHeaders(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 494 | 502 |
| 495 // Read again, it return ERR_IO_PENDING. | 503 // Read again, it return ERR_IO_PENDING. |
| 496 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 504 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); |
| 497 EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING); | 505 EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING); |
| 498 | 506 |
| 499 // Trailers are not delivered | 507 // Trailers are not delivered |
| 500 EXPECT_FALSE(stream_->IsDoneReading()); | 508 EXPECT_FALSE(stream_->IsDoneReading()); |
| 501 | 509 |
| 502 base::RunLoop run_loop2; | 510 base::RunLoop run_loop2; |
| 503 EXPECT_CALL(delegate_, | 511 EXPECT_CALL(delegate_, |
| 504 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 512 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 505 .WillOnce( | 513 .WillOnce( |
| 506 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 514 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
| 507 | 515 |
| 508 run_loop2.Run(); | 516 run_loop2.Run(); |
| 509 | 517 |
| 510 base::RunLoop run_loop3; | 518 base::RunLoop run_loop3; |
| 511 // OnDataAvailable() should follow right after and Read() will return 0. | 519 // OnDataAvailable() should follow right after and Read() will return 0. |
| 512 EXPECT_CALL(delegate_, OnDataAvailable()) | 520 EXPECT_CALL(delegate_, OnDataAvailable()) |
| 513 .WillOnce(testing::DoAll( | 521 .WillOnce(testing::DoAll( |
| 514 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 522 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
| 515 base::Unretained(this), | 523 base::Unretained(this), |
| 516 QuicStringPiece())), | 524 QuicStringPiece())), |
| 517 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); | 525 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); |
| 518 run_loop3.Run(); | 526 run_loop3.Run(); |
| 519 | 527 |
| 520 // Make sure the stream is properly closed since trailers and data are all | 528 // Make sure the stream is properly closed since trailers and data are all |
| 521 // consumed. | 529 // consumed. |
| 522 EXPECT_TRUE(stream_->IsDoneReading()); | 530 EXPECT_TRUE(stream_->IsDoneReading()); |
| 523 | 531 |
| 524 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 532 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 525 trailers.erase(kFinalOffsetHeaderKey); | 533 trailers.erase(kFinalOffsetHeaderKey); |
| 526 EXPECT_EQ(trailers, delegate_.headers_); | 534 EXPECT_EQ(trailers, delegate_.trailers_); |
| 527 | 535 |
| 528 base::RunLoop().RunUntilIdle(); | 536 base::RunLoop().RunUntilIdle(); |
| 529 EXPECT_CALL(delegate_, OnClose()); | 537 EXPECT_CALL(delegate_, OnClose()); |
| 530 } | 538 } |
| 531 | 539 |
| 532 TEST_P(QuicChromiumClientStreamTest, WriteStreamData) { | 540 TEST_P(QuicChromiumClientStreamTest, WriteStreamData) { |
| 533 EXPECT_CALL(delegate_, OnClose()); | 541 EXPECT_CALL(delegate_, OnClose()); |
| 534 | 542 |
| 535 const char kData1[] = "hello world"; | 543 const char kData1[] = "hello world"; |
| 536 const size_t kDataLen = arraysize(kData1); | 544 const size_t kDataLen = arraysize(kData1); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 | 631 |
| 624 InitializeHeaders(); | 632 InitializeHeaders(); |
| 625 | 633 |
| 626 // Receive the headers before the delegate is set. | 634 // Receive the headers before the delegate is set. |
| 627 QuicHeaderList header_list = AsHeaderList(headers_); | 635 QuicHeaderList header_list = AsHeaderList(headers_); |
| 628 stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(), | 636 stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(), |
| 629 header_list); | 637 header_list); |
| 630 EXPECT_TRUE(delegate2_.headers_.empty()); | 638 EXPECT_TRUE(delegate2_.headers_.empty()); |
| 631 | 639 |
| 632 // Now set the delegate and verify that the headers are delivered. | 640 // Now set the delegate and verify that the headers are delivered. |
| 633 EXPECT_CALL(delegate2_, OnHeadersAvailableMock( | 641 EXPECT_CALL(delegate2_, OnInitialHeadersAvailableMock( |
| 634 _, header_list.uncompressed_header_bytes())); | 642 _, header_list.uncompressed_header_bytes())); |
| 635 stream2->SetDelegate(&delegate2_); | 643 stream2->SetDelegate(&delegate2_); |
| 636 base::RunLoop().RunUntilIdle(); | 644 base::RunLoop().RunUntilIdle(); |
| 637 EXPECT_EQ(headers_, delegate2_.headers_); | 645 EXPECT_EQ(headers_, delegate2_.headers_); |
| 638 | 646 |
| 639 // Both delegates should be notified that theirs streams are closed. | 647 // Both delegates should be notified that theirs streams are closed. |
| 640 EXPECT_CALL(delegate2_, OnClose()); | 648 EXPECT_CALL(delegate2_, OnClose()); |
| 641 EXPECT_CALL(delegate_, OnClose()); | 649 EXPECT_CALL(delegate_, OnClose()); |
| 642 } | 650 } |
| 643 | 651 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 655 QuicHeaderList header_list = AsHeaderList(headers_); | 663 QuicHeaderList header_list = AsHeaderList(headers_); |
| 656 stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(), | 664 stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(), |
| 657 header_list); | 665 header_list); |
| 658 EXPECT_TRUE(delegate2_.headers_.empty()); | 666 EXPECT_TRUE(delegate2_.headers_.empty()); |
| 659 const char data[] = "hello world!"; | 667 const char data[] = "hello world!"; |
| 660 stream2->OnStreamFrame(QuicStreamFrame(stream_id, /*fin=*/false, | 668 stream2->OnStreamFrame(QuicStreamFrame(stream_id, /*fin=*/false, |
| 661 /*offset=*/0, data)); | 669 /*offset=*/0, data)); |
| 662 | 670 |
| 663 // Now set the delegate and verify that the headers are delivered, but | 671 // Now set the delegate and verify that the headers are delivered, but |
| 664 // not the data, which needs to be read explicitly. | 672 // not the data, which needs to be read explicitly. |
| 665 EXPECT_CALL(delegate2_, OnHeadersAvailableMock( | 673 EXPECT_CALL(delegate2_, OnInitialHeadersAvailableMock( |
| 666 _, header_list.uncompressed_header_bytes())); | 674 _, header_list.uncompressed_header_bytes())); |
| 667 stream2->SetDelegate(&delegate2_); | 675 stream2->SetDelegate(&delegate2_); |
| 668 base::RunLoop().RunUntilIdle(); | 676 base::RunLoop().RunUntilIdle(); |
| 669 EXPECT_EQ(headers_, delegate2_.headers_); | 677 EXPECT_EQ(headers_, delegate2_.headers_); |
| 670 base::RunLoop().RunUntilIdle(); | 678 base::RunLoop().RunUntilIdle(); |
| 671 | 679 |
| 672 // Now explicitly read the data. | 680 // Now explicitly read the data. |
| 673 int data_len = arraysize(data) - 1; | 681 int data_len = arraysize(data) - 1; |
| 674 scoped_refptr<IOBuffer> buffer(new IOBuffer(data_len + 1)); | 682 scoped_refptr<IOBuffer> buffer(new IOBuffer(data_len + 1)); |
| 675 ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1)); | 683 ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1)); |
| 676 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | 684 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
| 677 | 685 |
| 678 // Both delegates should be notified that theirs streams are closed. | 686 // Both delegates should be notified that theirs streams are closed. |
| 679 EXPECT_CALL(delegate2_, OnClose()); | 687 EXPECT_CALL(delegate2_, OnClose()); |
| 680 EXPECT_CALL(delegate_, OnClose()); | 688 EXPECT_CALL(delegate_, OnClose()); |
| 681 } | 689 } |
| 682 | 690 |
| 683 } // namespace | 691 } // namespace |
| 684 } // namespace test | 692 } // namespace test |
| 685 } // namespace net | 693 } // namespace net |
| OLD | NEW |