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

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

Issue 14311002: [SPDY] Avoid leaking bytes from the session flow control receive window (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 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 | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.h » ('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/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "net/base/io_buffer.h" 8 #include "net/base/io_buffer.h"
9 #include "net/base/ip_endpoint.h" 9 #include "net/base/ip_endpoint.h"
10 #include "net/base/net_log_unittest.h" 10 #include "net/base/net_log_unittest.h"
(...skipping 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2267 2267
2268 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_); 2268 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2269 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 2269 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2270 2270
2271 data.RunFor(3); 2271 data.RunFor(3);
2272 2272
2273 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_); 2273 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2274 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 2274 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2275 } 2275 }
2276 2276
2277 // A delegate that drops any received data.
2278 class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate {
2279 public:
2280 DropReceivedDataDelegate(const scoped_refptr<SpdyStream>& stream,
2281 base::StringPiece data)
2282 : StreamDelegateSendImmediate(
2283 stream, scoped_ptr<SpdyHeaderBlock>(), data) {}
2284
2285 virtual ~DropReceivedDataDelegate() {}
2286
2287 // Drop any received data.
2288 virtual int OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {
2289 return OK;
2290 }
2291 };
2292
2293 // Send data back and forth but use a delegate that drops its received
2294 // data. The receive window should still increase to its original
2295 // value, i.e. we shouldn't "leak" receive window bytes.
2296 TEST_F(SpdySessionSpdy3Test, SessionFlowControlNoReceiveLeaks31) {
2297 const char kStreamUrl[] = "http://www.google.com/";
2298
2299 session_deps_.enable_spdy_31 = true;
2300
2301 const int32 msg_data_size = 100;
2302 const std::string msg_data(msg_data_size, 'a');
2303
2304 MockConnect connect_data(SYNCHRONOUS, OK);
2305
2306 scoped_ptr<SpdyFrame> initial_window_update(
2307 ConstructSpdyWindowUpdate(
2308 kSessionFlowControlStreamId,
2309 kDefaultInitialRecvWindowSize - kSpdySessionInitialWindowSize));
2310 scoped_ptr<SpdyFrame> req(
2311 ConstructSpdyPost(kStreamUrl, 1, msg_data_size, MEDIUM, NULL, 0));
2312 scoped_ptr<SpdyFrame> msg(
2313 ConstructSpdyBodyFrame(1, msg_data.data(), msg_data_size, false));
2314 MockWrite writes[] = {
2315 CreateMockWrite(*initial_window_update, 0),
2316 CreateMockWrite(*req, 1),
2317 CreateMockWrite(*msg, 3),
2318 };
2319
2320 scoped_ptr<SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
2321 scoped_ptr<SpdyFrame> echo(
2322 ConstructSpdyBodyFrame(1, msg_data.data(), msg_data_size, false));
2323 scoped_ptr<SpdyFrame> window_update(
2324 ConstructSpdyWindowUpdate(
2325 kSessionFlowControlStreamId, msg_data_size));
2326 MockRead reads[] = {
2327 CreateMockRead(*resp, 2),
2328 CreateMockRead(*echo, 4),
2329 MockRead(ASYNC, 0, 5) // EOF
2330 };
2331
2332 // Create SpdySession and SpdyStream and send the request.
2333 DeterministicSocketData data(reads, arraysize(reads),
2334 writes, arraysize(writes));
2335 data.set_connect_data(connect_data);
2336 session_deps_.host_resolver->set_synchronous_mode(true);
2337 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
2338
2339 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2340 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
2341
2342 CreateDeterministicNetworkSession();
2343
2344 scoped_refptr<SpdySession> session = CreateInitializedSession();
2345
2346 GURL url(kStreamUrl);
2347 scoped_refptr<SpdyStream> stream =
2348 CreateStreamSynchronously(session, url, MEDIUM, BoundNetLog());
2349 ASSERT_TRUE(stream.get() != NULL);
2350 EXPECT_EQ(0u, stream->stream_id());
2351
2352 DropReceivedDataDelegate delegate(stream, msg_data);
2353 stream->SetDelegate(&delegate);
2354
2355 stream->set_spdy_headers(
2356 ConstructPostHeaderBlock(url.spec(), msg_data_size));
2357 EXPECT_TRUE(stream->HasUrl());
2358 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(true));
2359
2360 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2361 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2362
2363 data.RunFor(5);
2364
2365 EXPECT_TRUE(data.at_write_eof());
2366 EXPECT_TRUE(data.at_read_eof());
2367
2368 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2369 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
2370
2371 stream->Close();
2372
2373 EXPECT_EQ(OK, delegate.WaitForClose());
2374
2375 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2376 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
2377 }
2378
2277 // Send data back and forth; the send and receive windows should 2379 // Send data back and forth; the send and receive windows should
2278 // change appropriately. 2380 // change appropriately.
2279 TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) { 2381 TEST_F(SpdySessionSpdy3Test, SessionFlowControlEndToEnd31) {
2280 const char kStreamUrl[] = "http://www.google.com/"; 2382 const char kStreamUrl[] = "http://www.google.com/";
2281 2383
2282 session_deps_.enable_spdy_31 = true; 2384 session_deps_.enable_spdy_31 = true;
2283 2385
2284 const int32 msg_data_size = 100; 2386 const int32 msg_data_size = 100;
2285 const std::string msg_data(msg_data_size, 'a'); 2387 const std::string msg_data(msg_data_size, 'a');
2286 2388
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 data.RunFor(1); 2479 data.RunFor(1);
2378 2480
2379 EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_); 2481 EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
2380 EXPECT_EQ(kDefaultInitialRecvWindowSize - msg_data_size, 2482 EXPECT_EQ(kDefaultInitialRecvWindowSize - msg_data_size,
2381 session->session_recv_window_size_); 2483 session->session_recv_window_size_);
2382 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 2484 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2383 2485
2384 EXPECT_TRUE(data.at_write_eof()); 2486 EXPECT_TRUE(data.at_write_eof());
2385 EXPECT_TRUE(data.at_read_eof()); 2487 EXPECT_TRUE(data.at_read_eof());
2386 2488
2387 // Normally done by the delegate, but not by our test delegate. 2489 EXPECT_EQ(msg_data, delegate.TakeReceivedData());
2388 session->IncreaseRecvWindowSize(msg_data_size);
2389 2490
2491 // Draining the delegate's read queue should increase our receive
2492 // window.
2390 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_); 2493 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2391 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_); 2494 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
2392 2495
2393 stream->Close(); 2496 stream->Close();
2394 2497
2395 EXPECT_EQ(OK, delegate.WaitForClose()); 2498 EXPECT_EQ(OK, delegate.WaitForClose());
2499
2500 EXPECT_EQ(kDefaultInitialRecvWindowSize, session->session_recv_window_size_);
2501 EXPECT_EQ(msg_data_size, session->session_unacked_recv_window_bytes_);
2396 } 2502 }
2397 2503
2398 // Cause a stall by reducing the flow control send window to 0. The 2504 // Cause a stall by reducing the flow control send window to 0. The
2399 // stream should resume when that window is then increased. 2505 // stream should resume when that window is then increased.
2400 TEST_F(SpdySessionSpdy3Test, ResumeAfterSendWindowSizeIncrease31) { 2506 TEST_F(SpdySessionSpdy3Test, ResumeAfterSendWindowSizeIncrease31) {
2401 const char kStreamUrl[] = "http://www.google.com/"; 2507 const char kStreamUrl[] = "http://www.google.com/";
2402 GURL url(kStreamUrl); 2508 GURL url(kStreamUrl);
2403 2509
2404 session_deps_.enable_spdy_31 = true; 2510 session_deps_.enable_spdy_31 = true;
2405 session_deps_.host_resolver->set_synchronous_mode(true); 2511 session_deps_.host_resolver->set_synchronous_mode(true);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 2577
2472 EXPECT_FALSE(stream->send_stalled_by_flow_control()); 2578 EXPECT_FALSE(stream->send_stalled_by_flow_control());
2473 2579
2474 data.RunFor(3); 2580 data.RunFor(3);
2475 2581
2476 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose()); 2582 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate.WaitForClose());
2477 2583
2478 EXPECT_TRUE(delegate.send_headers_completed()); 2584 EXPECT_TRUE(delegate.send_headers_completed());
2479 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status")); 2585 EXPECT_EQ("200", delegate.GetResponseHeaderValue(":status"));
2480 EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version")); 2586 EXPECT_EQ("HTTP/1.1", delegate.GetResponseHeaderValue(":version"));
2481 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate.received_data()); 2587 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate.TakeReceivedData());
2482 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate.body_data_sent()); 2588 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate.body_data_sent());
2483 } 2589 }
2484 2590
2485 // Cause a stall by reducing the flow control send window to 0. The 2591 // Cause a stall by reducing the flow control send window to 0. The
2486 // streams should resume in priority order when that window is then 2592 // streams should resume in priority order when that window is then
2487 // increased. 2593 // increased.
2488 TEST_F(SpdySessionSpdy3Test, ResumeByPriorityAfterSendWindowSizeIncrease31) { 2594 TEST_F(SpdySessionSpdy3Test, ResumeByPriorityAfterSendWindowSizeIncrease31) {
2489 const char kStreamUrl[] = "http://www.google.com/"; 2595 const char kStreamUrl[] = "http://www.google.com/";
2490 GURL url(kStreamUrl); 2596 GURL url(kStreamUrl);
2491 2597
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 2713 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
2608 2714
2609 data.RunFor(3); 2715 data.RunFor(3);
2610 2716
2611 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 2717 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
2612 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 2718 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
2613 2719
2614 EXPECT_TRUE(delegate1.send_headers_completed()); 2720 EXPECT_TRUE(delegate1.send_headers_completed());
2615 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 2721 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
2616 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); 2722 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
2617 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate1.received_data()); 2723 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate1.TakeReceivedData());
2618 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate1.body_data_sent()); 2724 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate1.body_data_sent());
2619 2725
2620 EXPECT_TRUE(delegate2.send_headers_completed()); 2726 EXPECT_TRUE(delegate2.send_headers_completed());
2621 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 2727 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
2622 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 2728 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
2623 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.received_data()); 2729 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.TakeReceivedData());
2624 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent()); 2730 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent());
2625 } 2731 }
2626 2732
2627 // Delegate that closes a given stream after sending its body. 2733 // Delegate that closes a given stream after sending its body.
2628 class StreamClosingDelegate : public test::StreamDelegateWithBody { 2734 class StreamClosingDelegate : public test::StreamDelegateWithBody {
2629 public: 2735 public:
2630 StreamClosingDelegate(const scoped_refptr<SpdyStream>& stream, 2736 StreamClosingDelegate(const scoped_refptr<SpdyStream>& stream,
2631 base::StringPiece data) 2737 base::StringPiece data)
2632 : StreamDelegateWithBody(stream, data) {} 2738 : StreamDelegateWithBody(stream, data) {}
2633 2739
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 2907
2802 data.RunFor(3); 2908 data.RunFor(3);
2803 2909
2804 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 2910 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
2805 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 2911 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
2806 EXPECT_EQ(OK, delegate3.WaitForClose()); 2912 EXPECT_EQ(OK, delegate3.WaitForClose());
2807 2913
2808 EXPECT_TRUE(delegate1.send_headers_completed()); 2914 EXPECT_TRUE(delegate1.send_headers_completed());
2809 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 2915 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
2810 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); 2916 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
2811 EXPECT_EQ("", delegate1.received_data()); 2917 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
2812 EXPECT_EQ(0, delegate1.body_data_sent()); 2918 EXPECT_EQ(0, delegate1.body_data_sent());
2813 2919
2814 EXPECT_TRUE(delegate2.send_headers_completed()); 2920 EXPECT_TRUE(delegate2.send_headers_completed());
2815 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 2921 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
2816 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 2922 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
2817 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.received_data()); 2923 EXPECT_EQ(kBodyDataStringPiece.as_string(), delegate2.TakeReceivedData());
2818 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent()); 2924 EXPECT_EQ(static_cast<int>(kBodyDataSize), delegate2.body_data_sent());
2819 2925
2820 EXPECT_TRUE(delegate3.send_headers_completed()); 2926 EXPECT_TRUE(delegate3.send_headers_completed());
2821 EXPECT_EQ("200", delegate3.GetResponseHeaderValue(":status")); 2927 EXPECT_EQ("200", delegate3.GetResponseHeaderValue(":status"));
2822 EXPECT_EQ("HTTP/1.1", delegate3.GetResponseHeaderValue(":version")); 2928 EXPECT_EQ("HTTP/1.1", delegate3.GetResponseHeaderValue(":version"));
2823 EXPECT_EQ("", delegate3.received_data()); 2929 EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
2824 EXPECT_EQ(0, delegate3.body_data_sent()); 2930 EXPECT_EQ(0, delegate3.body_data_sent());
2825 } 2931 }
2826 2932
2827 // Delegate that closes a given session after sending its body. 2933 // Delegate that closes a given session after sending its body.
2828 class SessionClosingDelegate : public test::StreamDelegateWithBody { 2934 class SessionClosingDelegate : public test::StreamDelegateWithBody {
2829 public: 2935 public:
2830 SessionClosingDelegate(const scoped_refptr<SpdyStream>& stream, 2936 SessionClosingDelegate(const scoped_refptr<SpdyStream>& stream,
2831 base::StringPiece data) 2937 base::StringPiece data)
2832 : StreamDelegateWithBody(stream, data) {} 2938 : StreamDelegateWithBody(stream, data) {}
2833 2939
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 session = NULL; 3068 session = NULL;
2963 3069
2964 EXPECT_FALSE(spdy_session_pool_->HasSession(pair_)); 3070 EXPECT_FALSE(spdy_session_pool_->HasSession(pair_));
2965 3071
2966 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 3072 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
2967 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 3073 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
2968 3074
2969 EXPECT_TRUE(delegate1.send_headers_completed()); 3075 EXPECT_TRUE(delegate1.send_headers_completed());
2970 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 3076 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
2971 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); 3077 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
2972 EXPECT_EQ("", delegate1.received_data()); 3078 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
2973 EXPECT_EQ(0, delegate1.body_data_sent()); 3079 EXPECT_EQ(0, delegate1.body_data_sent());
2974 3080
2975 EXPECT_TRUE(delegate2.send_headers_completed()); 3081 EXPECT_TRUE(delegate2.send_headers_completed());
2976 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 3082 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
2977 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 3083 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
2978 EXPECT_EQ("", delegate2.received_data()); 3084 EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
2979 EXPECT_EQ(0, delegate2.body_data_sent()); 3085 EXPECT_EQ(0, delegate2.body_data_sent());
2980 } 3086 }
2981 3087
2982 } // namespace net 3088 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.cc ('k') | net/spdy/spdy_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698