Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: net/spdy/spdy_session_unittest.cc

Issue 1051213006: Fix flow control enforcement condition. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: s/packet/data frame/g Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/spdy/spdy_session.h" 5 #include "net/spdy/spdy_session.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 3686 matching lines...) Expand 10 before | Expand all | Expand 10 after
3697 3697
3698 // Request and response. 3698 // Request and response.
3699 data.RunFor(2); 3699 data.RunFor(2);
3700 EXPECT_EQ(1u, spdy_stream->stream_id()); 3700 EXPECT_EQ(1u, spdy_stream->stream_id());
3701 3701
3702 // Too large data frame causes flow control error, should close stream. 3702 // Too large data frame causes flow control error, should close stream.
3703 data.RunFor(1); 3703 data.RunFor(1);
3704 EXPECT_EQ(nullptr, spdy_stream.get()); 3704 EXPECT_EQ(nullptr, spdy_stream.get());
3705 } 3705 }
3706 3706
3707 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE
3708 // deltas in the receiving window size when checking incoming frames for flow
3709 // control errors at session level.
3710 TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) {
3711 if (GetParam() < kProtoSPDY31)
3712 return;
3713
3714 const int32 session_max_recv_window_size = 500;
3715 const int32 first_data_frame_size = 200;
3716 const int32 second_data_frame_size = 400;
3717
3718 // First data frame should not trigger a WINDOW_UPDATE.
3719 ASSERT_GT(session_max_recv_window_size / 2, first_data_frame_size);
3720 // Second data frame would be fine had there been a WINDOW_UPDATE.
3721 ASSERT_GT(session_max_recv_window_size, second_data_frame_size);
3722 // But in fact, the two data frames together overflow the receiving window at
3723 // session level.
3724 ASSERT_LT(session_max_recv_window_size,
3725 first_data_frame_size + second_data_frame_size);
3726
3727 session_deps_.host_resolver->set_synchronous_mode(true);
3728
3729 const std::string first_data_frame(first_data_frame_size, 'a');
3730 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
3731 1, first_data_frame.data(), first_data_frame_size, false));
3732 const std::string second_data_frame(second_data_frame_size, 'b');
3733 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
3734 1, second_data_frame.data(), second_data_frame_size, false));
3735 MockRead reads[] = {
3736 CreateMockRead(*first, 0),
3737 CreateMockRead(*second, 1),
3738 MockRead(ASYNC, 0, 2),
3739 };
3740 DeterministicSocketData data(reads, arraysize(reads), NULL, 0);
3741 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
3742 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3743
3744 CreateDeterministicNetworkSession();
3745 base::WeakPtr<SpdySession> session =
3746 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3747 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3748 session->flow_control_state());
3749 // Setting session level receiving window size to smaller than initial is not
3750 // possible via SpdySessionPoolPeer.
3751 session->session_recv_window_size_ = session_max_recv_window_size;
3752
3753 // First data frame is immediately consumed and does not trigger
3754 // WINDOW_UPDATE.
3755 data.RunFor(1);
3756 EXPECT_EQ(first_data_frame_size, session->session_unacked_recv_window_bytes_);
3757 EXPECT_EQ(session_max_recv_window_size, session->session_recv_window_size_);
3758 EXPECT_EQ(SpdySession::STATE_AVAILABLE, session->availability_state_);
3759
3760 // Second data frame overflows receiving window, causes session to close.
3761 data.RunFor(1);
3762 EXPECT_EQ(SpdySession::STATE_DRAINING, session->availability_state_);
3763 }
3764
3765 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE
3766 // deltas in the receiving window size when checking incoming data frames for
3767 // flow control errors at stream level.
3768 TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) {
3769 if (GetParam() < kProtoSPDY3)
3770 return;
3771
3772 const int32 stream_max_recv_window_size = 500;
3773 const int32 first_data_frame_size = 200;
3774 const int32 second_data_frame_size = 400;
3775
3776 // First data frame should not trigger a WINDOW_UPDATE.
3777 ASSERT_GT(stream_max_recv_window_size / 2, first_data_frame_size);
3778 // Second data frame would be fine had there been a WINDOW_UPDATE.
3779 ASSERT_GT(stream_max_recv_window_size, second_data_frame_size);
3780 // But in fact, they should overflow the receiving window at stream level.
3781 ASSERT_LT(stream_max_recv_window_size,
3782 first_data_frame_size + second_data_frame_size);
3783
3784 scoped_ptr<SpdyFrame> req(
3785 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3786 scoped_ptr<SpdyFrame> rst(
3787 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
3788 MockWrite writes[] = {
3789 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
3790 };
3791
3792 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3793 const std::string first_data_frame(first_data_frame_size, 'a');
3794 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
3795 1, first_data_frame.data(), first_data_frame_size, false));
3796 const std::string second_data_frame(second_data_frame_size, 'b');
3797 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
3798 1, second_data_frame.data(), second_data_frame_size, false));
3799 MockRead reads[] = {
3800 CreateMockRead(*resp, 1),
3801 CreateMockRead(*first, 2),
3802 CreateMockRead(*second, 3),
3803 MockRead(ASYNC, 0, 5),
3804 };
3805
3806 DeterministicSocketData data(reads, arraysize(reads), writes,
3807 arraysize(writes));
3808 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
3809 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3810
3811 CreateDeterministicNetworkSession();
3812 SpdySessionPoolPeer pool_peer(spdy_session_pool_);
3813 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size);
3814
3815 base::WeakPtr<SpdySession> session =
3816 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3817 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
3818
3819 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
3820 SPDY_REQUEST_RESPONSE_STREAM, session, test_url_, LOWEST, BoundNetLog());
3821 test::StreamDelegateDoNothing delegate(spdy_stream);
3822 spdy_stream->SetDelegate(&delegate);
3823
3824 scoped_ptr<SpdyHeaderBlock> headers(
3825 spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
3826 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
3827 headers.Pass(), NO_MORE_DATA_TO_SEND));
3828
3829 // Request and response.
3830 data.RunFor(2);
3831 EXPECT_TRUE(spdy_stream->IsLocallyClosed());
3832 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
3833
3834 // First data frame.
3835 data.RunFor(1);
3836 EXPECT_TRUE(spdy_stream->IsLocallyClosed());
3837 EXPECT_EQ(stream_max_recv_window_size - first_data_frame_size,
3838 spdy_stream->recv_window_size());
3839
3840 // Consume first data frame. This does not trigger a WINDOW_UPDATE.
3841 std::string received_data = delegate.TakeReceivedData();
3842 EXPECT_EQ(static_cast<size_t>(first_data_frame_size), received_data.size());
3843 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
3844
3845 // Second data frame overflows receiving window, causes the stream to close.
3846 data.RunFor(1);
3847 EXPECT_FALSE(spdy_stream.get());
3848
3849 // RST_STREAM
3850 data.RunFor(1);
3851 }
3852
3707 // A delegate that drops any received data. 3853 // A delegate that drops any received data.
3708 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { 3854 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
3709 public: 3855 public:
3710 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, 3856 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
3711 base::StringPiece data) 3857 base::StringPiece data)
3712 : StreamDelegateSendImmediate(stream, data) {} 3858 : StreamDelegateSendImmediate(stream, data) {}
3713 3859
3714 ~DropReceivedDataDelegate() override {} 3860 ~DropReceivedDataDelegate() override {}
3715 3861
3716 // Drop any received data. 3862 // Drop any received data.
(...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after
5198 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 5344 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
5199 "spdy_pooling.pem"); 5345 "spdy_pooling.pem");
5200 ssl_info.is_issued_by_known_root = true; 5346 ssl_info.is_issued_by_known_root = true;
5201 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); 5347 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin));
5202 5348
5203 EXPECT_TRUE(SpdySession::CanPool( 5349 EXPECT_TRUE(SpdySession::CanPool(
5204 &tss, ssl_info, "www.example.org", "mail.example.org")); 5350 &tss, ssl_info, "www.example.org", "mail.example.org"));
5205 } 5351 }
5206 5352
5207 } // namespace net 5353 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698