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

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: Change error code. Created 5 years, 8 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 packets for flow
3709 // control errors at session level.
3710 TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoPackets) {
3711 if (GetParam() < kProtoSPDY31)
3712 return;
3713
3714 const int32 session_max_recv_window_size = 500;
3715 const int32 first_packet_size = 200;
3716 const int32 second_packet_size = 400;
Ryan Hamilton 2015/04/27 15:27:18 nit: should these be "packet" sizes, or "frame" si
Bence 2015/04/28 13:33:18 These are frame sizes. Good catch. Done.
3717
3718 // First packet should not trigger a WINDOW_UPDATE.
3719 ASSERT_GT(session_max_recv_window_size / 2, first_packet_size);
3720 // Second packet would be fine had there been a WINDOW_UPDATE.
3721 ASSERT_GT(session_max_recv_window_size, second_packet_size);
3722 // But in fact, the two packets together overflow the receiving window at
3723 // session level.
3724 ASSERT_LT(session_max_recv_window_size,
3725 first_packet_size + second_packet_size);
3726
3727 session_deps_.host_resolver->set_synchronous_mode(true);
3728
3729 const std::string first_packet(first_packet_size, 'a');
3730 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
3731 1, first_packet.data(), first_packet_size, false));
3732 const std::string second_packet(second_packet_size, 'b');
3733 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
3734 1, second_packet.data(), second_packet_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 packet is immediately consumed and does not trigger WINDOW_UPDATE.
3754 data.RunFor(1);
3755 EXPECT_EQ(first_packet_size, session->session_unacked_recv_window_bytes_);
3756 EXPECT_EQ(session_max_recv_window_size, session->session_recv_window_size_);
3757 EXPECT_EQ(SpdySession::STATE_AVAILABLE, session->availability_state_);
3758
3759 // Second packet overflows receiving window, causes session to close.
3760 data.RunFor(1);
3761 EXPECT_EQ(SpdySession::STATE_DRAINING, session->availability_state_);
3762 }
3763
3764 // Regression test for a bug that was caused by including unsent WINDOW_UPDATE
3765 // deltas in the receiving window size when checking incoming packets for flow
3766 // control errors at stream level.
3767 TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoPackets) {
3768 if (GetParam() < kProtoSPDY3)
3769 return;
3770
3771 const int32 stream_max_recv_window_size = 500;
3772 const int32 first_packet_size = 200;
3773 const int32 second_packet_size = 400;
3774
3775 // First packet should not trigger a WINDOW_UPDATE.
3776 ASSERT_GT(stream_max_recv_window_size / 2, first_packet_size);
3777 // Second packet would be fine had there been a WINDOW_UPDATE.
3778 ASSERT_GT(stream_max_recv_window_size, second_packet_size);
3779 // But in fact, they should overflow the receiving window at stream level.
3780 ASSERT_LT(stream_max_recv_window_size,
3781 first_packet_size + second_packet_size);
3782
3783 scoped_ptr<SpdyFrame> req(
3784 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3785 scoped_ptr<SpdyFrame> rst(
3786 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
3787 MockWrite writes[] = {
3788 CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
3789 };
3790
3791 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3792 const std::string first_packet(first_packet_size, 'a');
3793 scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
3794 1, first_packet.data(), first_packet_size, false));
3795 const std::string second_packet(second_packet_size, 'b');
3796 scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
3797 1, second_packet.data(), second_packet_size, false));
3798 MockRead reads[] = {
3799 CreateMockRead(*resp, 1),
3800 CreateMockRead(*first, 2),
3801 CreateMockRead(*second, 3),
3802 MockRead(ASYNC, 0, 5),
3803 };
3804
3805 DeterministicSocketData data(reads, arraysize(reads), writes,
3806 arraysize(writes));
3807 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
3808 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3809
3810 CreateDeterministicNetworkSession();
3811 SpdySessionPoolPeer pool_peer(spdy_session_pool_);
3812 pool_peer.SetStreamInitialRecvWindowSize(stream_max_recv_window_size);
3813
3814 base::WeakPtr<SpdySession> session =
3815 CreateInsecureSpdySession(http_session_, key_, BoundNetLog());
3816 EXPECT_LE(SpdySession::FLOW_CONTROL_STREAM, session->flow_control_state());
3817
3818 base::WeakPtr<SpdyStream> spdy_stream = CreateStreamSynchronously(
3819 SPDY_REQUEST_RESPONSE_STREAM, session, test_url_, LOWEST, BoundNetLog());
3820 test::StreamDelegateDoNothing delegate(spdy_stream);
3821 spdy_stream->SetDelegate(&delegate);
3822
3823 scoped_ptr<SpdyHeaderBlock> headers(
3824 spdy_util_.ConstructGetHeaderBlock(kDefaultURL));
3825 EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders(
3826 headers.Pass(), NO_MORE_DATA_TO_SEND));
3827
3828 // Request and response.
3829 data.RunFor(2);
3830 EXPECT_TRUE(spdy_stream->IsLocallyClosed());
3831 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
3832
3833 // First packet.
3834 data.RunFor(1);
3835 EXPECT_TRUE(spdy_stream->IsLocallyClosed());
3836 EXPECT_EQ(stream_max_recv_window_size - first_packet_size,
3837 spdy_stream->recv_window_size());
3838
3839 // Consume first packet. This does not trigger a WINDOW_UPDATE.
3840 std::string received_data = delegate.TakeReceivedData();
3841 EXPECT_EQ(static_cast<size_t>(first_packet_size), received_data.size());
3842 EXPECT_EQ(stream_max_recv_window_size, spdy_stream->recv_window_size());
3843
3844 // Second packet overflows receiving window, causes the stream to close.
3845 data.RunFor(1);
3846 EXPECT_FALSE(spdy_stream.get());
3847
3848 // RST_STREAM
3849 data.RunFor(1);
3850 }
3851
3707 // A delegate that drops any received data. 3852 // A delegate that drops any received data.
3708 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { 3853 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
3709 public: 3854 public:
3710 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream, 3855 DropReceivedDataDelegate(const base::WeakPtr<SpdyStream>& stream,
3711 base::StringPiece data) 3856 base::StringPiece data)
3712 : StreamDelegateSendImmediate(stream, data) {} 3857 : StreamDelegateSendImmediate(stream, data) {}
3713 3858
3714 ~DropReceivedDataDelegate() override {} 3859 ~DropReceivedDataDelegate() override {}
3715 3860
3716 // Drop any received data. 3861 // Drop any received data.
(...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after
5198 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), 5343 ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(),
5199 "spdy_pooling.pem"); 5344 "spdy_pooling.pem");
5200 ssl_info.is_issued_by_known_root = true; 5345 ssl_info.is_issued_by_known_root = true;
5201 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin)); 5346 ssl_info.public_key_hashes.push_back(test::GetTestHashValue(primary_pin));
5202 5347
5203 EXPECT_TRUE(SpdySession::CanPool( 5348 EXPECT_TRUE(SpdySession::CanPool(
5204 &tss, ssl_info, "www.example.org", "mail.example.org")); 5349 &tss, ssl_info, "www.example.org", "mail.example.org"));
5205 } 5350 }
5206 5351
5207 } // namespace net 5352 } // 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