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

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

Issue 18114008: [SPDY] Organize tests by minimum version needed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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_network_transaction_unittest.cc ('k') | no next file » | 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/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h" 10 #include "base/run_loop.h"
(...skipping 2164 matching lines...) Expand 10 before | Expand all | Expand 10 after
2175 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK)); 2175 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
2176 2176
2177 EXPECT_EQ(spdy_util_.spdy_version() >= SPDY3, session->NeedsCredentials()); 2177 EXPECT_EQ(spdy_util_.spdy_version() >= SPDY3, session->NeedsCredentials());
2178 2178
2179 // Flush the SpdySession::OnReadComplete() task. 2179 // Flush the SpdySession::OnReadComplete() task.
2180 base::MessageLoop::current()->RunUntilIdle(); 2180 base::MessageLoop::current()->RunUntilIdle();
2181 2181
2182 spdy_session_pool_->Remove(session); 2182 spdy_session_pool_->Remove(session);
2183 } 2183 }
2184 2184
2185 TEST_P(SpdySessionTest, SendCredentials) {
2186 if (GetParam() < kProtoSPDY3)
2187 return;
2188
2189 MockConnect connect_data(SYNCHRONOUS, OK);
2190 MockRead reads[] = {
2191 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2192 };
2193 SettingsMap settings;
2194 scoped_ptr<SpdyFrame> settings_frame(
2195 spdy_util_.ConstructSpdySettings(settings));
2196 MockWrite writes[] = {
2197 CreateMockWrite(*settings_frame),
2198 };
2199 StaticSocketDataProvider data(reads, arraysize(reads),
2200 writes, arraysize(writes));
2201 data.set_connect_data(connect_data);
2202 session_deps_.socket_factory->AddSocketDataProvider(&data);
2203
2204 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2205 ssl.channel_id_sent = true;
2206 ssl.protocol_negotiated = GetParam();
2207 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2208
2209 CreateNetworkSession();
2210
2211 const GURL kTestUrl("https://www.foo.com");
2212 HostPortPair test_host_port_pair(kTestUrl.host(), 443);
2213 SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
2214 kPrivacyModeDisabled);
2215
2216 scoped_refptr<SpdySession> session = GetSession(key);
2217
2218 SSLConfig ssl_config;
2219 scoped_refptr<TransportSocketParams> transport_params(
2220 new TransportSocketParams(test_host_port_pair,
2221 MEDIUM,
2222 false,
2223 false,
2224 OnHostResolutionCallback()));
2225 scoped_refptr<SOCKSSocketParams> socks_params;
2226 scoped_refptr<HttpProxySocketParams> http_proxy_params;
2227 scoped_refptr<SSLSocketParams> ssl_params(
2228 new SSLSocketParams(transport_params,
2229 socks_params,
2230 http_proxy_params,
2231 ProxyServer::SCHEME_DIRECT,
2232 test_host_port_pair,
2233 ssl_config,
2234 0,
2235 false,
2236 false));
2237 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
2238 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
2239 ssl_params, MEDIUM, CompletionCallback(),
2240 http_session_->GetSSLSocketPool(
2241 HttpNetworkSession::NORMAL_SOCKET_POOL),
2242 BoundNetLog()));
2243
2244 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
2245 EXPECT_TRUE(session->NeedsCredentials());
2246
2247 // Flush the SpdySession::OnReadComplete() task.
2248 base::MessageLoop::current()->RunUntilIdle();
2249
2250 spdy_session_pool_->Remove(session);
2251 EXPECT_FALSE(spdy_session_pool_->HasSession(key));
2252 }
2253
2254 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
2255 if (GetParam() < kProtoSPDY3)
2256 return;
2257
2258 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
2259 // gets sent.
2260 SettingsMap new_settings;
2261 int32 window_size = 1;
2262 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
2263 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
2264
2265 // Set up the socket so we read a SETTINGS frame that sets
2266 // INITIAL_WINDOW_SIZE.
2267 MockConnect connect_data(SYNCHRONOUS, OK);
2268 scoped_ptr<SpdyFrame> settings_frame(
2269 spdy_util_.ConstructSpdySettings(new_settings));
2270 MockRead reads[] = {
2271 CreateMockRead(*settings_frame, 0),
2272 MockRead(ASYNC, 0, 1) // EOF
2273 };
2274
2275 session_deps_.host_resolver->set_synchronous_mode(true);
2276
2277 scoped_ptr<DeterministicSocketData> data(
2278 new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
2279 data->set_connect_data(connect_data);
2280 session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
2281
2282 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2284
2285 CreateDeterministicNetworkSession();
2286
2287 scoped_refptr<SpdySession> session = CreateInitializedSession();
2288 base::WeakPtr<SpdyStream> spdy_stream1 =
2289 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
2290 session, test_url_, MEDIUM, BoundNetLog());
2291 ASSERT_TRUE(spdy_stream1.get() != NULL);
2292 TestCompletionCallback callback1;
2293 EXPECT_NE(spdy_stream1->send_window_size(), window_size);
2294
2295 data->RunFor(1); // Process the SETTINGS frame, but not the EOF
2296 base::MessageLoop::current()->RunUntilIdle();
2297 EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
2298 EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
2299
2300 // Release the first one, this will allow the second to be created.
2301 spdy_stream1->Cancel();
2302 EXPECT_EQ(NULL, spdy_stream1.get());
2303
2304 base::WeakPtr<SpdyStream> spdy_stream2 =
2305 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
2306 session, test_url_, MEDIUM, BoundNetLog());
2307 ASSERT_TRUE(spdy_stream2.get() != NULL);
2308 EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
2309 spdy_stream2->Cancel();
2310 EXPECT_EQ(NULL, spdy_stream2.get());
2311 }
2312
2313 // Test that SpdySession::DoRead reads data from the socket without yielding. 2185 // Test that SpdySession::DoRead reads data from the socket without yielding.
2314 // This test makes 32k - 1 bytes of data available on the socket for reading. It 2186 // This test makes 32k - 1 bytes of data available on the socket for reading. It
2315 // then verifies that it has read all the available data without yielding. 2187 // then verifies that it has read all the available data without yielding.
2316 TEST_P(SpdySessionTest, ReadDataWithoutYielding) { 2188 TEST_P(SpdySessionTest, ReadDataWithoutYielding) {
2317 MockConnect connect_data(SYNCHRONOUS, OK); 2189 MockConnect connect_data(SYNCHRONOUS, OK);
2318 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 2190 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
2319 2191
2320 scoped_ptr<SpdyFrame> req1( 2192 scoped_ptr<SpdyFrame> req1(
2321 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true)); 2193 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, MEDIUM, true));
2322 MockWrite writes[] = { 2194 MockWrite writes[] = {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
2711 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION, 2583 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
2712 session->flow_control_state()); 2584 session->flow_control_state());
2713 EXPECT_EQ(kSpdySessionInitialWindowSize, 2585 EXPECT_EQ(kSpdySessionInitialWindowSize,
2714 session->session_send_window_size_); 2586 session->session_send_window_size_);
2715 EXPECT_EQ(kSpdySessionInitialWindowSize, 2587 EXPECT_EQ(kSpdySessionInitialWindowSize,
2716 session->session_recv_window_size_); 2588 session->session_recv_window_size_);
2717 } 2589 }
2718 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_); 2590 EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
2719 } 2591 }
2720 2592
2593 // Tests the case of a non-SPDY request closing an idle SPDY session when no
2594 // pointers to the idle session are currently held.
2595 TEST_P(SpdySessionTest, CloseOneIdleConnection) {
2596 ClientSocketPoolManager::set_max_sockets_per_group(
2597 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2598 ClientSocketPoolManager::set_max_sockets_per_pool(
2599 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2600
2601 MockConnect connect_data(SYNCHRONOUS, OK);
2602 MockRead reads[] = {
2603 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2604 };
2605 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2606 data.set_connect_data(connect_data);
2607 session_deps_.socket_factory->AddSocketDataProvider(&data);
2608 session_deps_.socket_factory->AddSocketDataProvider(&data);
2609
2610 CreateNetworkSession();
2611
2612 TransportClientSocketPool* pool =
2613 http_session_->GetTransportSocketPool(
2614 HttpNetworkSession::NORMAL_SOCKET_POOL);
2615
2616 // Create an idle SPDY session.
2617 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
2618 kPrivacyModeDisabled);
2619 scoped_refptr<SpdySession> session1 = GetSession(key1);
2620 EXPECT_EQ(
2621 OK,
2622 InitializeSession(http_session_.get(), session1.get(),
2623 key1.host_port_pair()));
2624 EXPECT_FALSE(pool->IsStalled());
2625 // Release the pointer to the session so it can be closed.
2626 session1 = NULL;
2627
2628 // Trying to create a new connection should cause the pool to be stalled, and
2629 // post a task asynchronously to try and close the session.
2630 TestCompletionCallback callback2;
2631 HostPortPair host_port2("2.com", 80);
2632 scoped_refptr<TransportSocketParams> params2(
2633 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
2634 OnHostResolutionCallback()));
2635 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
2636 EXPECT_EQ(ERR_IO_PENDING,
2637 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
2638 callback2.callback(), pool, BoundNetLog()));
2639 EXPECT_TRUE(pool->IsStalled());
2640
2641 // The socket pool should close the connection asynchronously and establish a
2642 // new connection.
2643 EXPECT_EQ(OK, callback2.WaitForResult());
2644 EXPECT_FALSE(pool->IsStalled());
2645 }
2646
2647 // Tests the case of a non-SPDY request closing an idle SPDY session when no
2648 // pointers to the idle session are currently held, in the case the SPDY session
2649 // has an alias.
2650 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
2651 ClientSocketPoolManager::set_max_sockets_per_group(
2652 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2653 ClientSocketPoolManager::set_max_sockets_per_pool(
2654 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2655
2656 MockConnect connect_data(SYNCHRONOUS, OK);
2657 MockRead reads[] = {
2658 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2659 };
2660 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2661 data.set_connect_data(connect_data);
2662 session_deps_.socket_factory->AddSocketDataProvider(&data);
2663 session_deps_.socket_factory->AddSocketDataProvider(&data);
2664
2665 session_deps_.host_resolver->set_synchronous_mode(true);
2666 session_deps_.host_resolver->rules()->AddIPLiteralRule(
2667 "1.com", "192.168.0.2", std::string());
2668 session_deps_.host_resolver->rules()->AddIPLiteralRule(
2669 "2.com", "192.168.0.2", std::string());
2670 // Not strictly needed.
2671 session_deps_.host_resolver->rules()->AddIPLiteralRule(
2672 "3.com", "192.168.0.3", std::string());
2673
2674 CreateNetworkSession();
2675
2676 TransportClientSocketPool* pool =
2677 http_session_->GetTransportSocketPool(
2678 HttpNetworkSession::NORMAL_SOCKET_POOL);
2679
2680 // Create an idle SPDY session.
2681 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
2682 kPrivacyModeDisabled);
2683 scoped_refptr<SpdySession> session1 = GetSession(key1);
2684 EXPECT_EQ(
2685 OK,
2686 InitializeSession(http_session_.get(), session1.get(),
2687 key1.host_port_pair()));
2688 EXPECT_FALSE(pool->IsStalled());
2689
2690 // Set up an alias for the idle SPDY session, increasing its ref count to 2.
2691 SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
2692 kPrivacyModeDisabled);
2693 SpdySessionPoolPeer pool_peer(spdy_session_pool_);
2694 HostResolver::RequestInfo info(key2.host_port_pair());
2695 AddressList addresses;
2696 // Pre-populate the DNS cache, since a synchronous resolution is required in
2697 // order to create the alias.
2698 session_deps_.host_resolver->Resolve(
2699 info, &addresses, CompletionCallback(), NULL, BoundNetLog());
2700 // Add the alias for the first session's key. Has to be done manually since
2701 // the usual process is bypassed.
2702 pool_peer.AddAlias(addresses.front(), key1);
2703 // Get a session for |key2|, which should return the session created earlier.
2704 scoped_refptr<SpdySession> session2 =
2705 spdy_session_pool_->Get(key2, BoundNetLog());
2706 ASSERT_EQ(session1.get(), session2.get());
2707 EXPECT_FALSE(pool->IsStalled());
2708
2709 // Release both the pointers to the session so it can be closed.
2710 session1 = NULL;
2711 session2 = NULL;
2712
2713 // Trying to create a new connection should cause the pool to be stalled, and
2714 // post a task asynchronously to try and close the session.
2715 TestCompletionCallback callback3;
2716 HostPortPair host_port3("3.com", 80);
2717 scoped_refptr<TransportSocketParams> params3(
2718 new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false,
2719 OnHostResolutionCallback()));
2720 scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
2721 EXPECT_EQ(ERR_IO_PENDING,
2722 connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
2723 callback3.callback(), pool, BoundNetLog()));
2724 EXPECT_TRUE(pool->IsStalled());
2725
2726 // The socket pool should close the connection asynchronously and establish a
2727 // new connection.
2728 EXPECT_EQ(OK, callback3.WaitForResult());
2729 EXPECT_FALSE(pool->IsStalled());
2730 }
2731
2732 // Tests the case of a non-SPDY request closing an idle SPDY session when a
2733 // pointer to the idle session is still held.
2734 TEST_P(SpdySessionTest, CloseOneIdleConnectionSessionStillHeld) {
2735 ClientSocketPoolManager::set_max_sockets_per_group(
2736 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2737 ClientSocketPoolManager::set_max_sockets_per_pool(
2738 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2739
2740 MockConnect connect_data(SYNCHRONOUS, OK);
2741 MockRead reads[] = {
2742 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2743 };
2744 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
2745 data.set_connect_data(connect_data);
2746 session_deps_.socket_factory->AddSocketDataProvider(&data);
2747 session_deps_.socket_factory->AddSocketDataProvider(&data);
2748
2749 CreateNetworkSession();
2750
2751 TransportClientSocketPool* pool =
2752 http_session_->GetTransportSocketPool(
2753 HttpNetworkSession::NORMAL_SOCKET_POOL);
2754
2755 // Create an idle SPDY session.
2756 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
2757 kPrivacyModeDisabled);
2758 scoped_refptr<SpdySession> session1 = GetSession(key1);
2759 EXPECT_EQ(
2760 OK,
2761 InitializeSession(http_session_.get(), session1.get(),
2762 key1.host_port_pair()));
2763 EXPECT_FALSE(pool->IsStalled());
2764
2765 // Trying to create a new connection should cause the pool to be stalled, and
2766 // post a task asynchronously to try and close the session.
2767 TestCompletionCallback callback2;
2768 HostPortPair host_port2("2.com", 80);
2769 scoped_refptr<TransportSocketParams> params2(
2770 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
2771 OnHostResolutionCallback()));
2772 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
2773 EXPECT_EQ(ERR_IO_PENDING,
2774 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
2775 callback2.callback(), pool, BoundNetLog()));
2776 EXPECT_TRUE(pool->IsStalled());
2777
2778 // Running the message loop should cause the session to prepare to be closed,
2779 // but since there's still an outstanding reference, it should not be closed
2780 // yet.
2781 base::RunLoop().RunUntilIdle();
2782 EXPECT_TRUE(pool->IsStalled());
2783 EXPECT_FALSE(callback2.have_result());
2784
2785 // Release the pointer to the session so it can be closed.
2786 session1 = NULL;
2787 EXPECT_EQ(OK, callback2.WaitForResult());
2788 EXPECT_FALSE(pool->IsStalled());
2789 }
2790
2791 // Tests that a non-SPDY request can't close a SPDY session that's currently in
2792 // use.
2793 TEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) {
2794 ClientSocketPoolManager::set_max_sockets_per_group(
2795 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2796 ClientSocketPoolManager::set_max_sockets_per_pool(
2797 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
2798
2799 MockConnect connect_data(SYNCHRONOUS, OK);
2800 MockRead reads[] = {
2801 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2802 };
2803 scoped_ptr<SpdyFrame> req1(
2804 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2805 scoped_ptr<SpdyFrame> cancel1(
2806 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2807 MockWrite writes[] = {
2808 CreateMockWrite(*req1, 1),
2809 CreateMockWrite(*cancel1, 1),
2810 };
2811 StaticSocketDataProvider data(reads, arraysize(reads),
2812 writes, arraysize(writes));
2813 data.set_connect_data(connect_data);
2814 session_deps_.socket_factory->AddSocketDataProvider(&data);
2815
2816 CreateNetworkSession();
2817
2818 TransportClientSocketPool* pool =
2819 http_session_->GetTransportSocketPool(
2820 HttpNetworkSession::NORMAL_SOCKET_POOL);
2821
2822 // Create a SPDY session.
2823 GURL url1("http://www.google.com");
2824 SpdySessionKey key1(HostPortPair(url1.host(), 80),
2825 ProxyServer::Direct(), kPrivacyModeDisabled);
2826 scoped_refptr<SpdySession> session1 = GetSession(key1);
2827 EXPECT_EQ(
2828 OK,
2829 InitializeSession(http_session_.get(), session1.get(),
2830 key1.host_port_pair()));
2831 EXPECT_FALSE(pool->IsStalled());
2832
2833 // Create a stream using the session, and send a request.
2834
2835 TestCompletionCallback callback1;
2836 base::WeakPtr<SpdyStream> spdy_stream1 =
2837 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
2838 session1, url1, DEFAULT_PRIORITY,
2839 BoundNetLog());
2840 ASSERT_TRUE(spdy_stream1.get());
2841 test::StreamDelegateDoNothing delegate1(spdy_stream1);
2842 spdy_stream1->SetDelegate(&delegate1);
2843
2844 scoped_ptr<SpdyHeaderBlock> headers1(
2845 spdy_util_.ConstructGetHeaderBlock(url1.spec()));
2846 EXPECT_EQ(ERR_IO_PENDING,
2847 spdy_stream1->SendRequestHeaders(
2848 headers1.Pass(), NO_MORE_DATA_TO_SEND));
2849 EXPECT_TRUE(spdy_stream1->HasUrl());
2850
2851 base::MessageLoop::current()->RunUntilIdle();
2852
2853 // Release the session, so holding onto a pointer here does not affect
2854 // anything.
2855 session1 = NULL;
2856
2857 // Trying to create a new connection should cause the pool to be stalled, and
2858 // post a task asynchronously to try and close the session.
2859 TestCompletionCallback callback2;
2860 HostPortPair host_port2("2.com", 80);
2861 scoped_refptr<TransportSocketParams> params2(
2862 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
2863 OnHostResolutionCallback()));
2864 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
2865 EXPECT_EQ(ERR_IO_PENDING,
2866 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
2867 callback2.callback(), pool, BoundNetLog()));
2868 EXPECT_TRUE(pool->IsStalled());
2869
2870 // Running the message loop should cause the socket pool to ask the SPDY
2871 // session to close an idle socket, but since the socket is in use, nothing
2872 // happens.
2873 base::RunLoop().RunUntilIdle();
2874 EXPECT_TRUE(pool->IsStalled());
2875 EXPECT_FALSE(callback2.have_result());
2876
2877 // Cancelling the request should still not release the session's socket,
2878 // since the session is still kept alive by the SpdySessionPool.
2879 ASSERT_TRUE(spdy_stream1.get());
2880 spdy_stream1->Cancel();
2881 base::RunLoop().RunUntilIdle();
2882 EXPECT_TRUE(pool->IsStalled());
2883 EXPECT_FALSE(callback2.have_result());
2884 }
2885
2886 // Verify that SpdySessionKey and therefore SpdySession is different when
2887 // privacy mode is enabled or disabled.
2888 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
2889 CreateDeterministicNetworkSession();
2890
2891 HostPortPair host_port_pair("www.google.com", 443);
2892 SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
2893 kPrivacyModeEnabled);
2894 SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
2895 kPrivacyModeDisabled);
2896
2897 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
2898 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
2899
2900 // Add SpdySession with PrivacyMode Enabled to the pool.
2901 scoped_refptr<SpdySession> session_privacy_enabled =
2902 spdy_session_pool_->Get(key_privacy_enabled, BoundNetLog());
2903
2904 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
2905 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
2906
2907 // Add SpdySession with PrivacyMode Disabled to the pool.
2908 scoped_refptr<SpdySession> session_privacy_disabled =
2909 spdy_session_pool_->Get(key_privacy_disabled, BoundNetLog());
2910
2911 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
2912 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
2913
2914 spdy_session_pool_->Remove(session_privacy_enabled);
2915 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
2916 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
2917
2918 spdy_session_pool_->Remove(session_privacy_disabled);
2919 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
2920 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
2921 }
2922
2923 // The tests below are only for SPDY/3 and above.
2924
2925 TEST_P(SpdySessionTest, SendCredentials) {
2926 if (GetParam() < kProtoSPDY3)
2927 return;
2928
2929 MockConnect connect_data(SYNCHRONOUS, OK);
2930 MockRead reads[] = {
2931 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
2932 };
2933 SettingsMap settings;
2934 scoped_ptr<SpdyFrame> settings_frame(
2935 spdy_util_.ConstructSpdySettings(settings));
2936 MockWrite writes[] = {
2937 CreateMockWrite(*settings_frame),
2938 };
2939 StaticSocketDataProvider data(reads, arraysize(reads),
2940 writes, arraysize(writes));
2941 data.set_connect_data(connect_data);
2942 session_deps_.socket_factory->AddSocketDataProvider(&data);
2943
2944 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
2945 ssl.channel_id_sent = true;
2946 ssl.protocol_negotiated = GetParam();
2947 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2948
2949 CreateNetworkSession();
2950
2951 const GURL kTestUrl("https://www.foo.com");
2952 HostPortPair test_host_port_pair(kTestUrl.host(), 443);
2953 SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
2954 kPrivacyModeDisabled);
2955
2956 scoped_refptr<SpdySession> session = GetSession(key);
2957
2958 SSLConfig ssl_config;
2959 scoped_refptr<TransportSocketParams> transport_params(
2960 new TransportSocketParams(test_host_port_pair,
2961 MEDIUM,
2962 false,
2963 false,
2964 OnHostResolutionCallback()));
2965 scoped_refptr<SOCKSSocketParams> socks_params;
2966 scoped_refptr<HttpProxySocketParams> http_proxy_params;
2967 scoped_refptr<SSLSocketParams> ssl_params(
2968 new SSLSocketParams(transport_params,
2969 socks_params,
2970 http_proxy_params,
2971 ProxyServer::SCHEME_DIRECT,
2972 test_host_port_pair,
2973 ssl_config,
2974 0,
2975 false,
2976 false));
2977 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
2978 EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
2979 ssl_params, MEDIUM, CompletionCallback(),
2980 http_session_->GetSSLSocketPool(
2981 HttpNetworkSession::NORMAL_SOCKET_POOL),
2982 BoundNetLog()));
2983
2984 EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
2985 EXPECT_TRUE(session->NeedsCredentials());
2986
2987 // Flush the SpdySession::OnReadComplete() task.
2988 base::MessageLoop::current()->RunUntilIdle();
2989
2990 spdy_session_pool_->Remove(session);
2991 EXPECT_FALSE(spdy_session_pool_->HasSession(key));
2992 }
2993
2994 TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
2995 if (GetParam() < kProtoSPDY3)
2996 return;
2997
2998 // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
2999 // gets sent.
3000 SettingsMap new_settings;
3001 int32 window_size = 1;
3002 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
3003 SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
3004
3005 // Set up the socket so we read a SETTINGS frame that sets
3006 // INITIAL_WINDOW_SIZE.
3007 MockConnect connect_data(SYNCHRONOUS, OK);
3008 scoped_ptr<SpdyFrame> settings_frame(
3009 spdy_util_.ConstructSpdySettings(new_settings));
3010 MockRead reads[] = {
3011 CreateMockRead(*settings_frame, 0),
3012 MockRead(ASYNC, 0, 1) // EOF
3013 };
3014
3015 session_deps_.host_resolver->set_synchronous_mode(true);
3016
3017 scoped_ptr<DeterministicSocketData> data(
3018 new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
3019 data->set_connect_data(connect_data);
3020 session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
3021
3022 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
3023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3024
3025 CreateDeterministicNetworkSession();
3026
3027 scoped_refptr<SpdySession> session = CreateInitializedSession();
3028 base::WeakPtr<SpdyStream> spdy_stream1 =
3029 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3030 session, test_url_, MEDIUM, BoundNetLog());
3031 ASSERT_TRUE(spdy_stream1.get() != NULL);
3032 TestCompletionCallback callback1;
3033 EXPECT_NE(spdy_stream1->send_window_size(), window_size);
3034
3035 data->RunFor(1); // Process the SETTINGS frame, but not the EOF
3036 base::MessageLoop::current()->RunUntilIdle();
3037 EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
3038 EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
3039
3040 // Release the first one, this will allow the second to be created.
3041 spdy_stream1->Cancel();
3042 EXPECT_EQ(NULL, spdy_stream1.get());
3043
3044 base::WeakPtr<SpdyStream> spdy_stream2 =
3045 CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
3046 session, test_url_, MEDIUM, BoundNetLog());
3047 ASSERT_TRUE(spdy_stream2.get() != NULL);
3048 EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
3049 spdy_stream2->Cancel();
3050 EXPECT_EQ(NULL, spdy_stream2.get());
3051 }
3052
3053 // The tests below are only for SPDY/3.1 and above.
3054
2721 // SpdySession::{Increase,Decrease}RecvWindowSize should properly 3055 // SpdySession::{Increase,Decrease}RecvWindowSize should properly
2722 // adjust the session receive window size for SPDY 3.1 and higher. In 3056 // adjust the session receive window size for SPDY 3.1 and higher. In
2723 // addition, SpdySession::IncreaseRecvWindowSize should trigger 3057 // addition, SpdySession::IncreaseRecvWindowSize should trigger
2724 // sending a WINDOW_UPDATE frame for a large enough delta. 3058 // sending a WINDOW_UPDATE frame for a large enough delta.
2725 TEST_P(SpdySessionTest, AdjustRecvWindowSize) { 3059 TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
2726 if (GetParam() < kProtoSPDY31) 3060 if (GetParam() < kProtoSPDY31)
2727 return; 3061 return;
2728 3062
2729 session_deps_.host_resolver->set_synchronous_mode(true); 3063 session_deps_.host_resolver->set_synchronous_mode(true);
2730 3064
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
3435 3769
3436 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 3770 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
3437 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 3771 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
3438 3772
3439 EXPECT_TRUE(delegate1.send_headers_completed()); 3773 EXPECT_TRUE(delegate1.send_headers_completed());
3440 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status")); 3774 EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
3441 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version")); 3775 EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
3442 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 3776 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
3443 3777
3444 EXPECT_TRUE(delegate2.send_headers_completed()); 3778 EXPECT_TRUE(delegate2.send_headers_completed());
3445 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
3446 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
3447 EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
3448
3449 EXPECT_TRUE(data.at_write_eof());
3450 }
3451
3452 // Delegate that closes a given stream after sending its body.
3453 class StreamClosingDelegate : public test::StreamDelegateWithBody {
3454 public:
3455 StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
3456 base::StringPiece data)
3457 : StreamDelegateWithBody(stream, data) {}
3458
3459 virtual ~StreamClosingDelegate() {}
3460
3461 void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
3462 stream_to_close_ = stream_to_close;
3463 }
3464
3465 virtual void OnDataSent() OVERRIDE {
3466 test::StreamDelegateWithBody::OnDataSent();
3467 if (stream_to_close_.get()) {
3468 stream_to_close_->Close();
3469 EXPECT_EQ(NULL, stream_to_close_.get());
3470 }
3471 }
3472
3473 private:
3474 base::WeakPtr<SpdyStream> stream_to_close_;
3475 };
3476
3477 // Cause a stall by reducing the flow control send window to
3478 // 0. Unstalling the session should properly handle deleted streams.
3479 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
3480 if (GetParam() < kProtoSPDY31)
3481 return;
3482
3483 const char kStreamUrl[] = "http://www.google.com/";
3484 GURL url(kStreamUrl);
3485
3486 session_deps_.host_resolver->set_synchronous_mode(true);
3487
3488 scoped_ptr<SpdyFrame> req1(
3489 spdy_util_.ConstructSpdyPost(
3490 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3491 scoped_ptr<SpdyFrame> req2(
3492 spdy_util_.ConstructSpdyPost(
3493 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
3494 scoped_ptr<SpdyFrame> req3(
3495 spdy_util_.ConstructSpdyPost(
3496 kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
3497 scoped_ptr<SpdyFrame> body2(
3498 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
3499 MockWrite writes[] = {
3500 CreateMockWrite(*req1, 0),
3501 CreateMockWrite(*req2, 1),
3502 CreateMockWrite(*req3, 2),
3503 CreateMockWrite(*body2, 3),
3504 };
3505
3506 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3507 MockRead reads[] = {
3508 CreateMockRead(*resp2, 4),
3509 MockRead(ASYNC, 0, 0, 5), // EOF
3510 };
3511
3512 DeterministicSocketData data(reads, arraysize(reads),
3513 writes, arraysize(writes));
3514 MockConnect connect_data(SYNCHRONOUS, OK);
3515 data.set_connect_data(connect_data);
3516
3517 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3518
3519 CreateDeterministicNetworkSession();
3520 scoped_refptr<SpdySession> session = GetSession(key_);
3521 InitializeSession(
3522 http_session_.get(), session.get(), test_host_port_pair_);
3523 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
3524 session->flow_control_state());
3525
3526 base::WeakPtr<SpdyStream> stream1 =
3527 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3528 session, url, LOWEST, BoundNetLog());
3529 ASSERT_TRUE(stream1.get() != NULL);
3530
3531 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
3532 stream1->SetDelegate(&delegate1);
3533
3534 EXPECT_FALSE(stream1->HasUrl());
3535
3536 base::WeakPtr<SpdyStream> stream2 =
3537 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3538 session, url, LOWEST, BoundNetLog());
3539 ASSERT_TRUE(stream2.get() != NULL);
3540
3541 StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
3542 stream2->SetDelegate(&delegate2);
3543
3544 EXPECT_FALSE(stream2->HasUrl());
3545
3546 base::WeakPtr<SpdyStream> stream3 =
3547 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3548 session, url, LOWEST, BoundNetLog());
3549 ASSERT_TRUE(stream3.get() != NULL);
3550
3551 test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
3552 stream3->SetDelegate(&delegate3);
3553
3554 EXPECT_FALSE(stream3->HasUrl());
3555
3556 EXPECT_FALSE(stream1->send_stalled_by_flow_control());
3557 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3558 EXPECT_FALSE(stream3->send_stalled_by_flow_control());
3559
3560 StallSessionSend(session.get());
3561
3562 scoped_ptr<SpdyHeaderBlock> headers1(
3563 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3564 EXPECT_EQ(ERR_IO_PENDING,
3565 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
3566 EXPECT_TRUE(stream1->HasUrl());
3567 EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec());
3568
3569 data.RunFor(1);
3570 EXPECT_EQ(1u, stream1->stream_id());
3571 EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3572
3573 scoped_ptr<SpdyHeaderBlock> headers2(
3574 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3575 EXPECT_EQ(ERR_IO_PENDING,
3576 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
3577 EXPECT_TRUE(stream2->HasUrl());
3578 EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec());
3579
3580 data.RunFor(1);
3581 EXPECT_EQ(3u, stream2->stream_id());
3582 EXPECT_TRUE(stream2->send_stalled_by_flow_control());
3583
3584 scoped_ptr<SpdyHeaderBlock> headers3(
3585 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3586 EXPECT_EQ(ERR_IO_PENDING,
3587 stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
3588 EXPECT_TRUE(stream3->HasUrl());
3589 EXPECT_EQ(kStreamUrl, stream3->GetUrl().spec());
3590
3591 data.RunFor(1);
3592 EXPECT_EQ(5u, stream3->stream_id());
3593 EXPECT_TRUE(stream3->send_stalled_by_flow_control());
3594
3595 SpdyStreamId stream_id1 = stream1->stream_id();
3596 SpdyStreamId stream_id2 = stream2->stream_id();
3597 SpdyStreamId stream_id3 = stream3->stream_id();
3598
3599 // Close stream1 preemptively.
3600 session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
3601 EXPECT_EQ(NULL, stream1.get());
3602
3603 EXPECT_FALSE(session->IsStreamActive(stream_id1));
3604 EXPECT_TRUE(session->IsStreamActive(stream_id2));
3605 EXPECT_TRUE(session->IsStreamActive(stream_id3));
3606
3607 // Unstall stream2, which should then close stream3.
3608 delegate2.set_stream_to_close(stream3);
3609 UnstallSessionSend(session.get(), kBodyDataSize);
3610
3611 data.RunFor(1);
3612 EXPECT_EQ(NULL, stream3.get());
3613
3614 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3615 EXPECT_FALSE(session->IsStreamActive(stream_id1));
3616 EXPECT_TRUE(session->IsStreamActive(stream_id2));
3617 EXPECT_FALSE(session->IsStreamActive(stream_id3));
3618
3619 data.RunFor(2);
3620 EXPECT_EQ(NULL, stream2.get());
3621
3622 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
3623 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
3624 EXPECT_EQ(OK, delegate3.WaitForClose());
3625
3626 EXPECT_TRUE(delegate1.send_headers_completed());
3627 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
3628
3629 EXPECT_TRUE(delegate2.send_headers_completed());
3630 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status")); 3779 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
3631 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version")); 3780 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
3632 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 3781 EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
3633 3782
3634 EXPECT_TRUE(delegate3.send_headers_completed());
3635 EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
3636
3637 EXPECT_TRUE(data.at_write_eof()); 3783 EXPECT_TRUE(data.at_write_eof());
3638 } 3784 }
3639 3785
3786 // Delegate that closes a given stream after sending its body.
3787 class StreamClosingDelegate : public test::StreamDelegateWithBody {
3788 public:
3789 StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
3790 base::StringPiece data)
3791 : StreamDelegateWithBody(stream, data) {}
3792
3793 virtual ~StreamClosingDelegate() {}
3794
3795 void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
3796 stream_to_close_ = stream_to_close;
3797 }
3798
3799 virtual void OnDataSent() OVERRIDE {
3800 test::StreamDelegateWithBody::OnDataSent();
3801 if (stream_to_close_.get()) {
3802 stream_to_close_->Close();
3803 EXPECT_EQ(NULL, stream_to_close_.get());
3804 }
3805 }
3806
3807 private:
3808 base::WeakPtr<SpdyStream> stream_to_close_;
3809 };
3810
3640 // Cause a stall by reducing the flow control send window to 3811 // Cause a stall by reducing the flow control send window to
3641 // 0. Unstalling the session should properly handle the session itself 3812 // 0. Unstalling the session should properly handle deleted streams.
3642 // being closed. 3813 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
3643 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
3644 if (GetParam() < kProtoSPDY31) 3814 if (GetParam() < kProtoSPDY31)
3645 return; 3815 return;
3646 3816
3647 const char kStreamUrl[] = "http://www.google.com/"; 3817 const char kStreamUrl[] = "http://www.google.com/";
3648 GURL url(kStreamUrl); 3818 GURL url(kStreamUrl);
3649 3819
3650 session_deps_.host_resolver->set_synchronous_mode(true); 3820 session_deps_.host_resolver->set_synchronous_mode(true);
3651 3821
3652 scoped_ptr<SpdyFrame> req1( 3822 scoped_ptr<SpdyFrame> req1(
3653 spdy_util_.ConstructSpdyPost( 3823 spdy_util_.ConstructSpdyPost(
3654 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0)); 3824 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3655 scoped_ptr<SpdyFrame> req2( 3825 scoped_ptr<SpdyFrame> req2(
3656 spdy_util_.ConstructSpdyPost( 3826 spdy_util_.ConstructSpdyPost(
3657 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0)); 3827 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
3658 scoped_ptr<SpdyFrame> body1( 3828 scoped_ptr<SpdyFrame> req3(
3659 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); 3829 spdy_util_.ConstructSpdyPost(
3830 kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
3831 scoped_ptr<SpdyFrame> body2(
3832 spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
3660 MockWrite writes[] = { 3833 MockWrite writes[] = {
3661 CreateMockWrite(*req1, 0), 3834 CreateMockWrite(*req1, 0),
3662 CreateMockWrite(*req2, 1), 3835 CreateMockWrite(*req2, 1),
3836 CreateMockWrite(*req3, 2),
3837 CreateMockWrite(*body2, 3),
3663 }; 3838 };
3664 3839
3840 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3665 MockRead reads[] = { 3841 MockRead reads[] = {
3666 MockRead(ASYNC, 0, 0, 2), // EOF 3842 CreateMockRead(*resp2, 4),
3843 MockRead(ASYNC, 0, 0, 5), // EOF
3667 }; 3844 };
3668 3845
3669 DeterministicSocketData data(reads, arraysize(reads), 3846 DeterministicSocketData data(reads, arraysize(reads),
3670 writes, arraysize(writes)); 3847 writes, arraysize(writes));
3671 MockConnect connect_data(SYNCHRONOUS, OK); 3848 MockConnect connect_data(SYNCHRONOUS, OK);
3672 data.set_connect_data(connect_data); 3849 data.set_connect_data(connect_data);
3673 3850
3674 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data); 3851 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
3675 3852
3676 CreateDeterministicNetworkSession(); 3853 CreateDeterministicNetworkSession();
(...skipping 11 matching lines...) Expand all
3688 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece); 3865 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
3689 stream1->SetDelegate(&delegate1); 3866 stream1->SetDelegate(&delegate1);
3690 3867
3691 EXPECT_FALSE(stream1->HasUrl()); 3868 EXPECT_FALSE(stream1->HasUrl());
3692 3869
3693 base::WeakPtr<SpdyStream> stream2 = 3870 base::WeakPtr<SpdyStream> stream2 =
3694 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM, 3871 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3695 session, url, LOWEST, BoundNetLog()); 3872 session, url, LOWEST, BoundNetLog());
3696 ASSERT_TRUE(stream2.get() != NULL); 3873 ASSERT_TRUE(stream2.get() != NULL);
3697 3874
3698 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); 3875 StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
3699 stream2->SetDelegate(&delegate2); 3876 stream2->SetDelegate(&delegate2);
3700 3877
3701 EXPECT_FALSE(stream2->HasUrl()); 3878 EXPECT_FALSE(stream2->HasUrl());
3702 3879
3880 base::WeakPtr<SpdyStream> stream3 =
3881 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
3882 session, url, LOWEST, BoundNetLog());
3883 ASSERT_TRUE(stream3.get() != NULL);
3884
3885 test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
3886 stream3->SetDelegate(&delegate3);
3887
3888 EXPECT_FALSE(stream3->HasUrl());
3889
3703 EXPECT_FALSE(stream1->send_stalled_by_flow_control()); 3890 EXPECT_FALSE(stream1->send_stalled_by_flow_control());
3704 EXPECT_FALSE(stream2->send_stalled_by_flow_control()); 3891 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3892 EXPECT_FALSE(stream3->send_stalled_by_flow_control());
3705 3893
3706 StallSessionSend(session.get()); 3894 StallSessionSend(session.get());
3707 3895
3708 scoped_ptr<SpdyHeaderBlock> headers1( 3896 scoped_ptr<SpdyHeaderBlock> headers1(
3709 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 3897 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3710 EXPECT_EQ(ERR_IO_PENDING, 3898 EXPECT_EQ(ERR_IO_PENDING,
3711 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND)); 3899 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
3712 EXPECT_TRUE(stream1->HasUrl()); 3900 EXPECT_TRUE(stream1->HasUrl());
3713 EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec()); 3901 EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec());
3714 3902
3715 data.RunFor(1); 3903 data.RunFor(1);
3716 EXPECT_EQ(1u, stream1->stream_id()); 3904 EXPECT_EQ(1u, stream1->stream_id());
3717 EXPECT_TRUE(stream1->send_stalled_by_flow_control()); 3905 EXPECT_TRUE(stream1->send_stalled_by_flow_control());
3718 3906
3719 scoped_ptr<SpdyHeaderBlock> headers2( 3907 scoped_ptr<SpdyHeaderBlock> headers2(
3720 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize)); 3908 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3721 EXPECT_EQ(ERR_IO_PENDING, 3909 EXPECT_EQ(ERR_IO_PENDING,
3722 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND)); 3910 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
3723 EXPECT_TRUE(stream2->HasUrl()); 3911 EXPECT_TRUE(stream2->HasUrl());
3724 EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec()); 3912 EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec());
3725 3913
3726 data.RunFor(1); 3914 data.RunFor(1);
3727 EXPECT_EQ(3u, stream2->stream_id()); 3915 EXPECT_EQ(3u, stream2->stream_id());
3728 EXPECT_TRUE(stream2->send_stalled_by_flow_control()); 3916 EXPECT_TRUE(stream2->send_stalled_by_flow_control());
3729 3917
3918 scoped_ptr<SpdyHeaderBlock> headers3(
3919 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
3920 EXPECT_EQ(ERR_IO_PENDING,
3921 stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
3922 EXPECT_TRUE(stream3->HasUrl());
3923 EXPECT_EQ(kStreamUrl, stream3->GetUrl().spec());
3924
3925 data.RunFor(1);
3926 EXPECT_EQ(5u, stream3->stream_id());
3927 EXPECT_TRUE(stream3->send_stalled_by_flow_control());
3928
3929 SpdyStreamId stream_id1 = stream1->stream_id();
3930 SpdyStreamId stream_id2 = stream2->stream_id();
3931 SpdyStreamId stream_id3 = stream3->stream_id();
3932
3933 // Close stream1 preemptively.
3934 session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
3935 EXPECT_EQ(NULL, stream1.get());
3936
3937 EXPECT_FALSE(session->IsStreamActive(stream_id1));
3938 EXPECT_TRUE(session->IsStreamActive(stream_id2));
3939 EXPECT_TRUE(session->IsStreamActive(stream_id3));
3940
3941 // Unstall stream2, which should then close stream3.
3942 delegate2.set_stream_to_close(stream3);
3943 UnstallSessionSend(session.get(), kBodyDataSize);
3944
3945 data.RunFor(1);
3946 EXPECT_EQ(NULL, stream3.get());
3947
3948 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
3949 EXPECT_FALSE(session->IsStreamActive(stream_id1));
3950 EXPECT_TRUE(session->IsStreamActive(stream_id2));
3951 EXPECT_FALSE(session->IsStreamActive(stream_id3));
3952
3953 data.RunFor(2);
3954 EXPECT_EQ(NULL, stream2.get());
3955
3956 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
3957 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
3958 EXPECT_EQ(OK, delegate3.WaitForClose());
3959
3960 EXPECT_TRUE(delegate1.send_headers_completed());
3961 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
3962
3963 EXPECT_TRUE(delegate2.send_headers_completed());
3964 EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
3965 EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
3966 EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
3967
3968 EXPECT_TRUE(delegate3.send_headers_completed());
3969 EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
3970
3971 EXPECT_TRUE(data.at_write_eof());
3972 }
3973
3974 // Cause a stall by reducing the flow control send window to
3975 // 0. Unstalling the session should properly handle the session itself
3976 // being closed.
3977 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
3978 if (GetParam() < kProtoSPDY31)
3979 return;
3980
3981 const char kStreamUrl[] = "http://www.google.com/";
3982 GURL url(kStreamUrl);
3983
3984 session_deps_.host_resolver->set_synchronous_mode(true);
3985
3986 scoped_ptr<SpdyFrame> req1(
3987 spdy_util_.ConstructSpdyPost(
3988 kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
3989 scoped_ptr<SpdyFrame> req2(
3990 spdy_util_.ConstructSpdyPost(
3991 kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
3992 scoped_ptr<SpdyFrame> body1(
3993 spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
3994 MockWrite writes[] = {
3995 CreateMockWrite(*req1, 0),
3996 CreateMockWrite(*req2, 1),
3997 };
3998
3999 MockRead reads[] = {
4000 MockRead(ASYNC, 0, 0, 2), // EOF
4001 };
4002
4003 DeterministicSocketData data(reads, arraysize(reads),
4004 writes, arraysize(writes));
4005 MockConnect connect_data(SYNCHRONOUS, OK);
4006 data.set_connect_data(connect_data);
4007
4008 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
4009
4010 CreateDeterministicNetworkSession();
4011 scoped_refptr<SpdySession> session = GetSession(key_);
4012 InitializeSession(
4013 http_session_.get(), session.get(), test_host_port_pair_);
4014 EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
4015 session->flow_control_state());
4016
4017 base::WeakPtr<SpdyStream> stream1 =
4018 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
4019 session, url, LOWEST, BoundNetLog());
4020 ASSERT_TRUE(stream1.get() != NULL);
4021
4022 test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
4023 stream1->SetDelegate(&delegate1);
4024
4025 EXPECT_FALSE(stream1->HasUrl());
4026
4027 base::WeakPtr<SpdyStream> stream2 =
4028 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
4029 session, url, LOWEST, BoundNetLog());
4030 ASSERT_TRUE(stream2.get() != NULL);
4031
4032 test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
4033 stream2->SetDelegate(&delegate2);
4034
4035 EXPECT_FALSE(stream2->HasUrl());
4036
4037 EXPECT_FALSE(stream1->send_stalled_by_flow_control());
4038 EXPECT_FALSE(stream2->send_stalled_by_flow_control());
4039
4040 StallSessionSend(session.get());
4041
4042 scoped_ptr<SpdyHeaderBlock> headers1(
4043 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
4044 EXPECT_EQ(ERR_IO_PENDING,
4045 stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
4046 EXPECT_TRUE(stream1->HasUrl());
4047 EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec());
4048
4049 data.RunFor(1);
4050 EXPECT_EQ(1u, stream1->stream_id());
4051 EXPECT_TRUE(stream1->send_stalled_by_flow_control());
4052
4053 scoped_ptr<SpdyHeaderBlock> headers2(
4054 spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
4055 EXPECT_EQ(ERR_IO_PENDING,
4056 stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
4057 EXPECT_TRUE(stream2->HasUrl());
4058 EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec());
4059
4060 data.RunFor(1);
4061 EXPECT_EQ(3u, stream2->stream_id());
4062 EXPECT_TRUE(stream2->send_stalled_by_flow_control());
4063
3730 EXPECT_TRUE(spdy_session_pool_->HasSession(key_)); 4064 EXPECT_TRUE(spdy_session_pool_->HasSession(key_));
3731 4065
3732 // Unstall stream1. 4066 // Unstall stream1.
3733 UnstallSessionSend(session.get(), kBodyDataSize); 4067 UnstallSessionSend(session.get(), kBodyDataSize);
3734 4068
3735 // Close the session (since we can't do it from within the delegate 4069 // Close the session (since we can't do it from within the delegate
3736 // method, since it's in the stream's loop). 4070 // method, since it's in the stream's loop).
3737 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "Closing session"); 4071 session->CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "Closing session");
3738 session = NULL; 4072 session = NULL;
3739 4073
3740 EXPECT_FALSE(spdy_session_pool_->HasSession(key_)); 4074 EXPECT_FALSE(spdy_session_pool_->HasSession(key_));
3741 4075
3742 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose()); 4076 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
3743 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose()); 4077 EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
3744 4078
3745 EXPECT_TRUE(delegate1.send_headers_completed()); 4079 EXPECT_TRUE(delegate1.send_headers_completed());
3746 EXPECT_EQ(std::string(), delegate1.TakeReceivedData()); 4080 EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
3747 4081
3748 EXPECT_TRUE(delegate2.send_headers_completed()); 4082 EXPECT_TRUE(delegate2.send_headers_completed());
3749 EXPECT_EQ(std::string(), delegate2.TakeReceivedData()); 4083 EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
3750 4084
3751 EXPECT_TRUE(data.at_write_eof()); 4085 EXPECT_TRUE(data.at_write_eof());
3752 } 4086 }
3753 4087
3754
3755 // Tests the case of a non-SPDY request closing an idle SPDY session when no
3756 // pointers to the idle session are currently held.
3757 TEST_P(SpdySessionTest, CloseOneIdleConnection) {
3758 ClientSocketPoolManager::set_max_sockets_per_group(
3759 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3760 ClientSocketPoolManager::set_max_sockets_per_pool(
3761 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3762
3763 MockConnect connect_data(SYNCHRONOUS, OK);
3764 MockRead reads[] = {
3765 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3766 };
3767 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
3768 data.set_connect_data(connect_data);
3769 session_deps_.socket_factory->AddSocketDataProvider(&data);
3770 session_deps_.socket_factory->AddSocketDataProvider(&data);
3771
3772 CreateNetworkSession();
3773
3774 TransportClientSocketPool* pool =
3775 http_session_->GetTransportSocketPool(
3776 HttpNetworkSession::NORMAL_SOCKET_POOL);
3777
3778 // Create an idle SPDY session.
3779 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
3780 kPrivacyModeDisabled);
3781 scoped_refptr<SpdySession> session1 = GetSession(key1);
3782 EXPECT_EQ(
3783 OK,
3784 InitializeSession(http_session_.get(), session1.get(),
3785 key1.host_port_pair()));
3786 EXPECT_FALSE(pool->IsStalled());
3787 // Release the pointer to the session so it can be closed.
3788 session1 = NULL;
3789
3790 // Trying to create a new connection should cause the pool to be stalled, and
3791 // post a task asynchronously to try and close the session.
3792 TestCompletionCallback callback2;
3793 HostPortPair host_port2("2.com", 80);
3794 scoped_refptr<TransportSocketParams> params2(
3795 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
3796 OnHostResolutionCallback()));
3797 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
3798 EXPECT_EQ(ERR_IO_PENDING,
3799 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
3800 callback2.callback(), pool, BoundNetLog()));
3801 EXPECT_TRUE(pool->IsStalled());
3802
3803 // The socket pool should close the connection asynchronously and establish a
3804 // new connection.
3805 EXPECT_EQ(OK, callback2.WaitForResult());
3806 EXPECT_FALSE(pool->IsStalled());
3807 }
3808
3809 // Tests the case of a non-SPDY request closing an idle SPDY session when no
3810 // pointers to the idle session are currently held, in the case the SPDY session
3811 // has an alias.
3812 TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
3813 ClientSocketPoolManager::set_max_sockets_per_group(
3814 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3815 ClientSocketPoolManager::set_max_sockets_per_pool(
3816 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3817
3818 MockConnect connect_data(SYNCHRONOUS, OK);
3819 MockRead reads[] = {
3820 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3821 };
3822 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
3823 data.set_connect_data(connect_data);
3824 session_deps_.socket_factory->AddSocketDataProvider(&data);
3825 session_deps_.socket_factory->AddSocketDataProvider(&data);
3826
3827 session_deps_.host_resolver->set_synchronous_mode(true);
3828 session_deps_.host_resolver->rules()->AddIPLiteralRule(
3829 "1.com", "192.168.0.2", std::string());
3830 session_deps_.host_resolver->rules()->AddIPLiteralRule(
3831 "2.com", "192.168.0.2", std::string());
3832 // Not strictly needed.
3833 session_deps_.host_resolver->rules()->AddIPLiteralRule(
3834 "3.com", "192.168.0.3", std::string());
3835
3836 CreateNetworkSession();
3837
3838 TransportClientSocketPool* pool =
3839 http_session_->GetTransportSocketPool(
3840 HttpNetworkSession::NORMAL_SOCKET_POOL);
3841
3842 // Create an idle SPDY session.
3843 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
3844 kPrivacyModeDisabled);
3845 scoped_refptr<SpdySession> session1 = GetSession(key1);
3846 EXPECT_EQ(
3847 OK,
3848 InitializeSession(http_session_.get(), session1.get(),
3849 key1.host_port_pair()));
3850 EXPECT_FALSE(pool->IsStalled());
3851
3852 // Set up an alias for the idle SPDY session, increasing its ref count to 2.
3853 SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
3854 kPrivacyModeDisabled);
3855 SpdySessionPoolPeer pool_peer(spdy_session_pool_);
3856 HostResolver::RequestInfo info(key2.host_port_pair());
3857 AddressList addresses;
3858 // Pre-populate the DNS cache, since a synchronous resolution is required in
3859 // order to create the alias.
3860 session_deps_.host_resolver->Resolve(
3861 info, &addresses, CompletionCallback(), NULL, BoundNetLog());
3862 // Add the alias for the first session's key. Has to be done manually since
3863 // the usual process is bypassed.
3864 pool_peer.AddAlias(addresses.front(), key1);
3865 // Get a session for |key2|, which should return the session created earlier.
3866 scoped_refptr<SpdySession> session2 =
3867 spdy_session_pool_->Get(key2, BoundNetLog());
3868 ASSERT_EQ(session1.get(), session2.get());
3869 EXPECT_FALSE(pool->IsStalled());
3870
3871 // Release both the pointers to the session so it can be closed.
3872 session1 = NULL;
3873 session2 = NULL;
3874
3875 // Trying to create a new connection should cause the pool to be stalled, and
3876 // post a task asynchronously to try and close the session.
3877 TestCompletionCallback callback3;
3878 HostPortPair host_port3("3.com", 80);
3879 scoped_refptr<TransportSocketParams> params3(
3880 new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false,
3881 OnHostResolutionCallback()));
3882 scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
3883 EXPECT_EQ(ERR_IO_PENDING,
3884 connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
3885 callback3.callback(), pool, BoundNetLog()));
3886 EXPECT_TRUE(pool->IsStalled());
3887
3888 // The socket pool should close the connection asynchronously and establish a
3889 // new connection.
3890 EXPECT_EQ(OK, callback3.WaitForResult());
3891 EXPECT_FALSE(pool->IsStalled());
3892 }
3893
3894 // Tests the case of a non-SPDY request closing an idle SPDY session when a
3895 // pointer to the idle session is still held.
3896 TEST_P(SpdySessionTest, CloseOneIdleConnectionSessionStillHeld) {
3897 ClientSocketPoolManager::set_max_sockets_per_group(
3898 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3899 ClientSocketPoolManager::set_max_sockets_per_pool(
3900 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3901
3902 MockConnect connect_data(SYNCHRONOUS, OK);
3903 MockRead reads[] = {
3904 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3905 };
3906 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
3907 data.set_connect_data(connect_data);
3908 session_deps_.socket_factory->AddSocketDataProvider(&data);
3909 session_deps_.socket_factory->AddSocketDataProvider(&data);
3910
3911 CreateNetworkSession();
3912
3913 TransportClientSocketPool* pool =
3914 http_session_->GetTransportSocketPool(
3915 HttpNetworkSession::NORMAL_SOCKET_POOL);
3916
3917 // Create an idle SPDY session.
3918 SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
3919 kPrivacyModeDisabled);
3920 scoped_refptr<SpdySession> session1 = GetSession(key1);
3921 EXPECT_EQ(
3922 OK,
3923 InitializeSession(http_session_.get(), session1.get(),
3924 key1.host_port_pair()));
3925 EXPECT_FALSE(pool->IsStalled());
3926
3927 // Trying to create a new connection should cause the pool to be stalled, and
3928 // post a task asynchronously to try and close the session.
3929 TestCompletionCallback callback2;
3930 HostPortPair host_port2("2.com", 80);
3931 scoped_refptr<TransportSocketParams> params2(
3932 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
3933 OnHostResolutionCallback()));
3934 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
3935 EXPECT_EQ(ERR_IO_PENDING,
3936 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
3937 callback2.callback(), pool, BoundNetLog()));
3938 EXPECT_TRUE(pool->IsStalled());
3939
3940 // Running the message loop should cause the session to prepare to be closed,
3941 // but since there's still an outstanding reference, it should not be closed
3942 // yet.
3943 base::RunLoop().RunUntilIdle();
3944 EXPECT_TRUE(pool->IsStalled());
3945 EXPECT_FALSE(callback2.have_result());
3946
3947 // Release the pointer to the session so it can be closed.
3948 session1 = NULL;
3949 EXPECT_EQ(OK, callback2.WaitForResult());
3950 EXPECT_FALSE(pool->IsStalled());
3951 }
3952
3953 // Tests that a non-SPDY request can't close a SPDY session that's currently in
3954 // use.
3955 TEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) {
3956 ClientSocketPoolManager::set_max_sockets_per_group(
3957 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3958 ClientSocketPoolManager::set_max_sockets_per_pool(
3959 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
3960
3961 MockConnect connect_data(SYNCHRONOUS, OK);
3962 MockRead reads[] = {
3963 MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
3964 };
3965 scoped_ptr<SpdyFrame> req1(
3966 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3967 scoped_ptr<SpdyFrame> cancel1(
3968 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
3969 MockWrite writes[] = {
3970 CreateMockWrite(*req1, 1),
3971 CreateMockWrite(*cancel1, 1),
3972 };
3973 StaticSocketDataProvider data(reads, arraysize(reads),
3974 writes, arraysize(writes));
3975 data.set_connect_data(connect_data);
3976 session_deps_.socket_factory->AddSocketDataProvider(&data);
3977
3978 CreateNetworkSession();
3979
3980 TransportClientSocketPool* pool =
3981 http_session_->GetTransportSocketPool(
3982 HttpNetworkSession::NORMAL_SOCKET_POOL);
3983
3984 // Create a SPDY session.
3985 GURL url1("http://www.google.com");
3986 SpdySessionKey key1(HostPortPair(url1.host(), 80),
3987 ProxyServer::Direct(), kPrivacyModeDisabled);
3988 scoped_refptr<SpdySession> session1 = GetSession(key1);
3989 EXPECT_EQ(
3990 OK,
3991 InitializeSession(http_session_.get(), session1.get(),
3992 key1.host_port_pair()));
3993 EXPECT_FALSE(pool->IsStalled());
3994
3995 // Create a stream using the session, and send a request.
3996
3997 TestCompletionCallback callback1;
3998 base::WeakPtr<SpdyStream> spdy_stream1 =
3999 CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
4000 session1, url1, DEFAULT_PRIORITY,
4001 BoundNetLog());
4002 ASSERT_TRUE(spdy_stream1.get());
4003 test::StreamDelegateDoNothing delegate1(spdy_stream1);
4004 spdy_stream1->SetDelegate(&delegate1);
4005
4006 scoped_ptr<SpdyHeaderBlock> headers1(
4007 spdy_util_.ConstructGetHeaderBlock(url1.spec()));
4008 EXPECT_EQ(ERR_IO_PENDING,
4009 spdy_stream1->SendRequestHeaders(
4010 headers1.Pass(), NO_MORE_DATA_TO_SEND));
4011 EXPECT_TRUE(spdy_stream1->HasUrl());
4012
4013 base::MessageLoop::current()->RunUntilIdle();
4014
4015 // Release the session, so holding onto a pointer here does not affect
4016 // anything.
4017 session1 = NULL;
4018
4019 // Trying to create a new connection should cause the pool to be stalled, and
4020 // post a task asynchronously to try and close the session.
4021 TestCompletionCallback callback2;
4022 HostPortPair host_port2("2.com", 80);
4023 scoped_refptr<TransportSocketParams> params2(
4024 new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
4025 OnHostResolutionCallback()));
4026 scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
4027 EXPECT_EQ(ERR_IO_PENDING,
4028 connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
4029 callback2.callback(), pool, BoundNetLog()));
4030 EXPECT_TRUE(pool->IsStalled());
4031
4032 // Running the message loop should cause the socket pool to ask the SPDY
4033 // session to close an idle socket, but since the socket is in use, nothing
4034 // happens.
4035 base::RunLoop().RunUntilIdle();
4036 EXPECT_TRUE(pool->IsStalled());
4037 EXPECT_FALSE(callback2.have_result());
4038
4039 // Cancelling the request should still not release the session's socket,
4040 // since the session is still kept alive by the SpdySessionPool.
4041 ASSERT_TRUE(spdy_stream1.get());
4042 spdy_stream1->Cancel();
4043 base::RunLoop().RunUntilIdle();
4044 EXPECT_TRUE(pool->IsStalled());
4045 EXPECT_FALSE(callback2.have_result());
4046 }
4047
4048 // Verify that SpdySessionKey and therefore SpdySession is different when
4049 // privacy mode is enabled or disabled.
4050 TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
4051 CreateDeterministicNetworkSession();
4052
4053 HostPortPair host_port_pair("www.google.com", 443);
4054 SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
4055 kPrivacyModeEnabled);
4056 SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
4057 kPrivacyModeDisabled);
4058
4059 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
4060 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
4061
4062 // Add SpdySession with PrivacyMode Enabled to the pool.
4063 scoped_refptr<SpdySession> session_privacy_enabled =
4064 spdy_session_pool_->Get(key_privacy_enabled, BoundNetLog());
4065
4066 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
4067 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
4068
4069 // Add SpdySession with PrivacyMode Disabled to the pool.
4070 scoped_refptr<SpdySession> session_privacy_disabled =
4071 spdy_session_pool_->Get(key_privacy_disabled, BoundNetLog());
4072
4073 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
4074 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
4075
4076 spdy_session_pool_->Remove(session_privacy_enabled);
4077 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
4078 EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
4079
4080 spdy_session_pool_->Remove(session_privacy_disabled);
4081 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
4082 EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
4083 }
4084
4085 } // namespace net 4088 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_network_transaction_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698