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

Unified 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, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_network_transaction_unittest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_session_unittest.cc
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 9c516076110b775d3712b068595b6d110f7ea1dd..cce77ef1b197466cfb39aab31b16186299bdb2a5 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -2182,134 +2182,6 @@ TEST_P(SpdySessionTest, NeedsCredentials) {
spdy_session_pool_->Remove(session);
}
-TEST_P(SpdySessionTest, SendCredentials) {
- if (GetParam() < kProtoSPDY3)
- return;
-
- MockConnect connect_data(SYNCHRONOUS, OK);
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
- };
- SettingsMap settings;
- scoped_ptr<SpdyFrame> settings_frame(
- spdy_util_.ConstructSpdySettings(settings));
- MockWrite writes[] = {
- CreateMockWrite(*settings_frame),
- };
- StaticSocketDataProvider data(reads, arraysize(reads),
- writes, arraysize(writes));
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- ssl.channel_id_sent = true;
- ssl.protocol_negotiated = GetParam();
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
- CreateNetworkSession();
-
- const GURL kTestUrl("https://www.foo.com");
- HostPortPair test_host_port_pair(kTestUrl.host(), 443);
- SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
-
- scoped_refptr<SpdySession> session = GetSession(key);
-
- SSLConfig ssl_config;
- scoped_refptr<TransportSocketParams> transport_params(
- new TransportSocketParams(test_host_port_pair,
- MEDIUM,
- false,
- false,
- OnHostResolutionCallback()));
- scoped_refptr<SOCKSSocketParams> socks_params;
- scoped_refptr<HttpProxySocketParams> http_proxy_params;
- scoped_refptr<SSLSocketParams> ssl_params(
- new SSLSocketParams(transport_params,
- socks_params,
- http_proxy_params,
- ProxyServer::SCHEME_DIRECT,
- test_host_port_pair,
- ssl_config,
- 0,
- false,
- false));
- scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
- EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
- ssl_params, MEDIUM, CompletionCallback(),
- http_session_->GetSSLSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL),
- BoundNetLog()));
-
- EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
- EXPECT_TRUE(session->NeedsCredentials());
-
- // Flush the SpdySession::OnReadComplete() task.
- base::MessageLoop::current()->RunUntilIdle();
-
- spdy_session_pool_->Remove(session);
- EXPECT_FALSE(spdy_session_pool_->HasSession(key));
-}
-
-TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
- if (GetParam() < kProtoSPDY3)
- return;
-
- // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
- // gets sent.
- SettingsMap new_settings;
- int32 window_size = 1;
- new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
- SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
-
- // Set up the socket so we read a SETTINGS frame that sets
- // INITIAL_WINDOW_SIZE.
- MockConnect connect_data(SYNCHRONOUS, OK);
- scoped_ptr<SpdyFrame> settings_frame(
- spdy_util_.ConstructSpdySettings(new_settings));
- MockRead reads[] = {
- CreateMockRead(*settings_frame, 0),
- MockRead(ASYNC, 0, 1) // EOF
- };
-
- session_deps_.host_resolver->set_synchronous_mode(true);
-
- scoped_ptr<DeterministicSocketData> data(
- new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
- data->set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
-
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
-
- CreateDeterministicNetworkSession();
-
- scoped_refptr<SpdySession> session = CreateInitializedSession();
- base::WeakPtr<SpdyStream> spdy_stream1 =
- CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
- session, test_url_, MEDIUM, BoundNetLog());
- ASSERT_TRUE(spdy_stream1.get() != NULL);
- TestCompletionCallback callback1;
- EXPECT_NE(spdy_stream1->send_window_size(), window_size);
-
- data->RunFor(1); // Process the SETTINGS frame, but not the EOF
- base::MessageLoop::current()->RunUntilIdle();
- EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
- EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
-
- // Release the first one, this will allow the second to be created.
- spdy_stream1->Cancel();
- EXPECT_EQ(NULL, spdy_stream1.get());
-
- base::WeakPtr<SpdyStream> spdy_stream2 =
- CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
- session, test_url_, MEDIUM, BoundNetLog());
- ASSERT_TRUE(spdy_stream2.get() != NULL);
- EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
- spdy_stream2->Cancel();
- EXPECT_EQ(NULL, spdy_stream2.get());
-}
-
// Test that SpdySession::DoRead reads data from the socket without yielding.
// This test makes 32k - 1 bytes of data available on the socket for reading. It
// then verifies that it has read all the available data without yielding.
@@ -2718,95 +2590,557 @@ TEST_P(SpdySessionTest, ProtocolNegotiation) {
EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
}
-// SpdySession::{Increase,Decrease}RecvWindowSize should properly
-// adjust the session receive window size for SPDY 3.1 and higher. In
-// addition, SpdySession::IncreaseRecvWindowSize should trigger
-// sending a WINDOW_UPDATE frame for a large enough delta.
-TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
- if (GetParam() < kProtoSPDY31)
- return;
-
- session_deps_.host_resolver->set_synchronous_mode(true);
-
- const int32 delta_window_size = 100;
+// Tests the case of a non-SPDY request closing an idle SPDY session when no
+// pointers to the idle session are currently held.
+TEST_P(SpdySessionTest, CloseOneIdleConnection) {
+ ClientSocketPoolManager::set_max_sockets_per_group(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+ ClientSocketPoolManager::set_max_sockets_per_pool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
- MockRead(ASYNC, 0, 1) // EOF
- };
- scoped_ptr<SpdyFrame> window_update(
- spdy_util_.ConstructSpdyWindowUpdate(
- kSessionFlowControlStreamId,
- kSpdySessionInitialWindowSize + delta_window_size));
- MockWrite writes[] = {
- CreateMockWrite(*window_update, 0),
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
};
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
-
- SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
- session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
-
- CreateDeterministicNetworkSession();
- scoped_refptr<SpdySession> session = GetSession(key_);
- InitializeSession(
- http_session_.get(), session.get(), test_host_port_pair_);
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session->flow_control_state());
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
- EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+ CreateNetworkSession();
- session->IncreaseRecvWindowSize(delta_window_size);
- EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
- session->session_recv_window_size_);
- EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_);
+ TransportClientSocketPool* pool =
+ http_session_->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL);
- // Should trigger sending a WINDOW_UPDATE frame.
- session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize);
- EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size +
- kSpdySessionInitialWindowSize,
- session->session_recv_window_size_);
- EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+ // Create an idle SPDY session.
+ SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+ scoped_refptr<SpdySession> session1 = GetSession(key1);
+ EXPECT_EQ(
+ OK,
+ InitializeSession(http_session_.get(), session1.get(),
+ key1.host_port_pair()));
+ EXPECT_FALSE(pool->IsStalled());
+ // Release the pointer to the session so it can be closed.
+ session1 = NULL;
- data.RunFor(1);
+ // Trying to create a new connection should cause the pool to be stalled, and
+ // post a task asynchronously to try and close the session.
+ TestCompletionCallback callback2;
+ HostPortPair host_port2("2.com", 80);
+ scoped_refptr<TransportSocketParams> params2(
+ new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
+ OnHostResolutionCallback()));
+ scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
+ EXPECT_EQ(ERR_IO_PENDING,
+ connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
+ callback2.callback(), pool, BoundNetLog()));
+ EXPECT_TRUE(pool->IsStalled());
- session->DecreaseRecvWindowSize(
- kSpdySessionInitialWindowSize + delta_window_size +
- kSpdySessionInitialWindowSize);
- EXPECT_EQ(0, session->session_recv_window_size_);
- EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+ // The socket pool should close the connection asynchronously and establish a
+ // new connection.
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_FALSE(pool->IsStalled());
}
-// SpdySession::{Increase,Decrease}SendWindowSize should properly
-// adjust the session send window size when the "enable_spdy_31" flag
-// is set.
-TEST_P(SpdySessionTest, AdjustSendWindowSize) {
- if (GetParam() < kProtoSPDY31)
- return;
-
- session_deps_.host_resolver->set_synchronous_mode(true);
+// Tests the case of a non-SPDY request closing an idle SPDY session when no
+// pointers to the idle session are currently held, in the case the SPDY session
+// has an alias.
+TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
+ ClientSocketPoolManager::set_max_sockets_per_group(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+ ClientSocketPoolManager::set_max_sockets_per_pool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
- MockRead(SYNCHRONOUS, 0, 0) // EOF
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
};
StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
- CreateNetworkSession();
- scoped_refptr<SpdySession> session = GetSession(key_);
- InitializeSession(
- http_session_.get(), session.get(), test_host_port_pair_);
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session->flow_control_state());
+ session_deps_.host_resolver->set_synchronous_mode(true);
+ session_deps_.host_resolver->rules()->AddIPLiteralRule(
+ "1.com", "192.168.0.2", std::string());
+ session_deps_.host_resolver->rules()->AddIPLiteralRule(
+ "2.com", "192.168.0.2", std::string());
+ // Not strictly needed.
+ session_deps_.host_resolver->rules()->AddIPLiteralRule(
+ "3.com", "192.168.0.3", std::string());
- const int32 delta_window_size = 100;
+ CreateNetworkSession();
- EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
+ TransportClientSocketPool* pool =
+ http_session_->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL);
+
+ // Create an idle SPDY session.
+ SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+ scoped_refptr<SpdySession> session1 = GetSession(key1);
+ EXPECT_EQ(
+ OK,
+ InitializeSession(http_session_.get(), session1.get(),
+ key1.host_port_pair()));
+ EXPECT_FALSE(pool->IsStalled());
+
+ // Set up an alias for the idle SPDY session, increasing its ref count to 2.
+ SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+ SpdySessionPoolPeer pool_peer(spdy_session_pool_);
+ HostResolver::RequestInfo info(key2.host_port_pair());
+ AddressList addresses;
+ // Pre-populate the DNS cache, since a synchronous resolution is required in
+ // order to create the alias.
+ session_deps_.host_resolver->Resolve(
+ info, &addresses, CompletionCallback(), NULL, BoundNetLog());
+ // Add the alias for the first session's key. Has to be done manually since
+ // the usual process is bypassed.
+ pool_peer.AddAlias(addresses.front(), key1);
+ // Get a session for |key2|, which should return the session created earlier.
+ scoped_refptr<SpdySession> session2 =
+ spdy_session_pool_->Get(key2, BoundNetLog());
+ ASSERT_EQ(session1.get(), session2.get());
+ EXPECT_FALSE(pool->IsStalled());
+
+ // Release both the pointers to the session so it can be closed.
+ session1 = NULL;
+ session2 = NULL;
+
+ // Trying to create a new connection should cause the pool to be stalled, and
+ // post a task asynchronously to try and close the session.
+ TestCompletionCallback callback3;
+ HostPortPair host_port3("3.com", 80);
+ scoped_refptr<TransportSocketParams> params3(
+ new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false,
+ OnHostResolutionCallback()));
+ scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
+ EXPECT_EQ(ERR_IO_PENDING,
+ connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
+ callback3.callback(), pool, BoundNetLog()));
+ EXPECT_TRUE(pool->IsStalled());
+
+ // The socket pool should close the connection asynchronously and establish a
+ // new connection.
+ EXPECT_EQ(OK, callback3.WaitForResult());
+ EXPECT_FALSE(pool->IsStalled());
+}
+
+// Tests the case of a non-SPDY request closing an idle SPDY session when a
+// pointer to the idle session is still held.
+TEST_P(SpdySessionTest, CloseOneIdleConnectionSessionStillHeld) {
+ ClientSocketPoolManager::set_max_sockets_per_group(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+ ClientSocketPoolManager::set_max_sockets_per_pool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
+ };
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+
+ TransportClientSocketPool* pool =
+ http_session_->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL);
+
+ // Create an idle SPDY session.
+ SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+ scoped_refptr<SpdySession> session1 = GetSession(key1);
+ EXPECT_EQ(
+ OK,
+ InitializeSession(http_session_.get(), session1.get(),
+ key1.host_port_pair()));
+ EXPECT_FALSE(pool->IsStalled());
+
+ // Trying to create a new connection should cause the pool to be stalled, and
+ // post a task asynchronously to try and close the session.
+ TestCompletionCallback callback2;
+ HostPortPair host_port2("2.com", 80);
+ scoped_refptr<TransportSocketParams> params2(
+ new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
+ OnHostResolutionCallback()));
+ scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
+ EXPECT_EQ(ERR_IO_PENDING,
+ connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
+ callback2.callback(), pool, BoundNetLog()));
+ EXPECT_TRUE(pool->IsStalled());
+
+ // Running the message loop should cause the session to prepare to be closed,
+ // but since there's still an outstanding reference, it should not be closed
+ // yet.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(pool->IsStalled());
+ EXPECT_FALSE(callback2.have_result());
+
+ // Release the pointer to the session so it can be closed.
+ session1 = NULL;
+ EXPECT_EQ(OK, callback2.WaitForResult());
+ EXPECT_FALSE(pool->IsStalled());
+}
+
+// Tests that a non-SPDY request can't close a SPDY session that's currently in
+// use.
+TEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) {
+ ClientSocketPoolManager::set_max_sockets_per_group(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+ ClientSocketPoolManager::set_max_sockets_per_pool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
+ };
+ scoped_ptr<SpdyFrame> req1(
+ spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
+ scoped_ptr<SpdyFrame> cancel1(
+ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ MockWrite writes[] = {
+ CreateMockWrite(*req1, 1),
+ CreateMockWrite(*cancel1, 1),
+ };
+ StaticSocketDataProvider data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+
+ TransportClientSocketPool* pool =
+ http_session_->GetTransportSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL);
+
+ // Create a SPDY session.
+ GURL url1("http://www.google.com");
+ SpdySessionKey key1(HostPortPair(url1.host(), 80),
+ ProxyServer::Direct(), kPrivacyModeDisabled);
+ scoped_refptr<SpdySession> session1 = GetSession(key1);
+ EXPECT_EQ(
+ OK,
+ InitializeSession(http_session_.get(), session1.get(),
+ key1.host_port_pair()));
+ EXPECT_FALSE(pool->IsStalled());
+
+ // Create a stream using the session, and send a request.
+
+ TestCompletionCallback callback1;
+ base::WeakPtr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
+ session1, url1, DEFAULT_PRIORITY,
+ BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get());
+ test::StreamDelegateDoNothing delegate1(spdy_stream1);
+ spdy_stream1->SetDelegate(&delegate1);
+
+ scoped_ptr<SpdyHeaderBlock> headers1(
+ spdy_util_.ConstructGetHeaderBlock(url1.spec()));
+ EXPECT_EQ(ERR_IO_PENDING,
+ spdy_stream1->SendRequestHeaders(
+ headers1.Pass(), NO_MORE_DATA_TO_SEND));
+ EXPECT_TRUE(spdy_stream1->HasUrl());
+
+ base::MessageLoop::current()->RunUntilIdle();
+
+ // Release the session, so holding onto a pointer here does not affect
+ // anything.
+ session1 = NULL;
+
+ // Trying to create a new connection should cause the pool to be stalled, and
+ // post a task asynchronously to try and close the session.
+ TestCompletionCallback callback2;
+ HostPortPair host_port2("2.com", 80);
+ scoped_refptr<TransportSocketParams> params2(
+ new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
+ OnHostResolutionCallback()));
+ scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
+ EXPECT_EQ(ERR_IO_PENDING,
+ connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
+ callback2.callback(), pool, BoundNetLog()));
+ EXPECT_TRUE(pool->IsStalled());
+
+ // Running the message loop should cause the socket pool to ask the SPDY
+ // session to close an idle socket, but since the socket is in use, nothing
+ // happens.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(pool->IsStalled());
+ EXPECT_FALSE(callback2.have_result());
+
+ // Cancelling the request should still not release the session's socket,
+ // since the session is still kept alive by the SpdySessionPool.
+ ASSERT_TRUE(spdy_stream1.get());
+ spdy_stream1->Cancel();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_TRUE(pool->IsStalled());
+ EXPECT_FALSE(callback2.have_result());
+}
+
+// Verify that SpdySessionKey and therefore SpdySession is different when
+// privacy mode is enabled or disabled.
+TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
+ CreateDeterministicNetworkSession();
+
+ HostPortPair host_port_pair("www.google.com", 443);
+ SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
+ kPrivacyModeEnabled);
+ SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+
+ // Add SpdySession with PrivacyMode Enabled to the pool.
+ scoped_refptr<SpdySession> session_privacy_enabled =
+ spdy_session_pool_->Get(key_privacy_enabled, BoundNetLog());
+
+ EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+
+ // Add SpdySession with PrivacyMode Disabled to the pool.
+ scoped_refptr<SpdySession> session_privacy_disabled =
+ spdy_session_pool_->Get(key_privacy_disabled, BoundNetLog());
+
+ EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
+ EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
+
+ spdy_session_pool_->Remove(session_privacy_enabled);
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
+ EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
+
+ spdy_session_pool_->Remove(session_privacy_disabled);
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+}
+
+// The tests below are only for SPDY/3 and above.
+
+TEST_P(SpdySessionTest, SendCredentials) {
+ if (GetParam() < kProtoSPDY3)
+ return;
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
+ };
+ SettingsMap settings;
+ scoped_ptr<SpdyFrame> settings_frame(
+ spdy_util_.ConstructSpdySettings(settings));
+ MockWrite writes[] = {
+ CreateMockWrite(*settings_frame),
+ };
+ StaticSocketDataProvider data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ ssl.channel_id_sent = true;
+ ssl.protocol_negotiated = GetParam();
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ CreateNetworkSession();
+
+ const GURL kTestUrl("https://www.foo.com");
+ HostPortPair test_host_port_pair(kTestUrl.host(), 443);
+ SpdySessionKey key(test_host_port_pair, ProxyServer::Direct(),
+ kPrivacyModeDisabled);
+
+ scoped_refptr<SpdySession> session = GetSession(key);
+
+ SSLConfig ssl_config;
+ scoped_refptr<TransportSocketParams> transport_params(
+ new TransportSocketParams(test_host_port_pair,
+ MEDIUM,
+ false,
+ false,
+ OnHostResolutionCallback()));
+ scoped_refptr<SOCKSSocketParams> socks_params;
+ scoped_refptr<HttpProxySocketParams> http_proxy_params;
+ scoped_refptr<SSLSocketParams> ssl_params(
+ new SSLSocketParams(transport_params,
+ socks_params,
+ http_proxy_params,
+ ProxyServer::SCHEME_DIRECT,
+ test_host_port_pair,
+ ssl_config,
+ 0,
+ false,
+ false));
+ scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
+ EXPECT_EQ(OK, connection->Init(test_host_port_pair.ToString(),
+ ssl_params, MEDIUM, CompletionCallback(),
+ http_session_->GetSSLSocketPool(
+ HttpNetworkSession::NORMAL_SOCKET_POOL),
+ BoundNetLog()));
+
+ EXPECT_EQ(OK, session->InitializeWithSocket(connection.release(), true, OK));
+ EXPECT_TRUE(session->NeedsCredentials());
+
+ // Flush the SpdySession::OnReadComplete() task.
+ base::MessageLoop::current()->RunUntilIdle();
+
+ spdy_session_pool_->Remove(session);
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key));
+}
+
+TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) {
+ if (GetParam() < kProtoSPDY3)
+ return;
+
+ // Set SETTINGS_INITIAL_WINDOW_SIZE to a small number so that WINDOW_UPDATE
+ // gets sent.
+ SettingsMap new_settings;
+ int32 window_size = 1;
+ new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
+ SettingsFlagsAndValue(SETTINGS_FLAG_NONE, window_size);
+
+ // Set up the socket so we read a SETTINGS frame that sets
+ // INITIAL_WINDOW_SIZE.
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ scoped_ptr<SpdyFrame> settings_frame(
+ spdy_util_.ConstructSpdySettings(new_settings));
+ MockRead reads[] = {
+ CreateMockRead(*settings_frame, 0),
+ MockRead(ASYNC, 0, 1) // EOF
+ };
+
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ scoped_ptr<DeterministicSocketData> data(
+ new DeterministicSocketData(reads, arraysize(reads), NULL, 0));
+ data->set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(data.get());
+
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ CreateDeterministicNetworkSession();
+
+ scoped_refptr<SpdySession> session = CreateInitializedSession();
+ base::WeakPtr<SpdyStream> spdy_stream1 =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream1.get() != NULL);
+ TestCompletionCallback callback1;
+ EXPECT_NE(spdy_stream1->send_window_size(), window_size);
+
+ data->RunFor(1); // Process the SETTINGS frame, but not the EOF
+ base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_EQ(session->stream_initial_send_window_size(), window_size);
+ EXPECT_EQ(spdy_stream1->send_window_size(), window_size);
+
+ // Release the first one, this will allow the second to be created.
+ spdy_stream1->Cancel();
+ EXPECT_EQ(NULL, spdy_stream1.get());
+
+ base::WeakPtr<SpdyStream> spdy_stream2 =
+ CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
+ session, test_url_, MEDIUM, BoundNetLog());
+ ASSERT_TRUE(spdy_stream2.get() != NULL);
+ EXPECT_EQ(spdy_stream2->send_window_size(), window_size);
+ spdy_stream2->Cancel();
+ EXPECT_EQ(NULL, spdy_stream2.get());
+}
+
+// The tests below are only for SPDY/3.1 and above.
+
+// SpdySession::{Increase,Decrease}RecvWindowSize should properly
+// adjust the session receive window size for SPDY 3.1 and higher. In
+// addition, SpdySession::IncreaseRecvWindowSize should trigger
+// sending a WINDOW_UPDATE frame for a large enough delta.
+TEST_P(SpdySessionTest, AdjustRecvWindowSize) {
+ if (GetParam() < kProtoSPDY31)
+ return;
+
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ const int32 delta_window_size = 100;
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(ASYNC, 0, 1) // EOF
+ };
+ scoped_ptr<SpdyFrame> window_update(
+ spdy_util_.ConstructSpdyWindowUpdate(
+ kSessionFlowControlStreamId,
+ kSpdySessionInitialWindowSize + delta_window_size));
+ MockWrite writes[] = {
+ CreateMockWrite(*window_update, 0),
+ };
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ data.set_connect_data(connect_data);
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
+
+ SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
+ session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
+
+ CreateDeterministicNetworkSession();
+ scoped_refptr<SpdySession> session = GetSession(key_);
+ InitializeSession(
+ http_session_.get(), session.get(), test_host_port_pair_);
+ EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
+ session->flow_control_state());
+
+ EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+
+ session->IncreaseRecvWindowSize(delta_window_size);
+ EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
+ session->session_recv_window_size_);
+ EXPECT_EQ(delta_window_size, session->session_unacked_recv_window_bytes_);
+
+ // Should trigger sending a WINDOW_UPDATE frame.
+ session->IncreaseRecvWindowSize(kSpdySessionInitialWindowSize);
+ EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size +
+ kSpdySessionInitialWindowSize,
+ session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+
+ data.RunFor(1);
+
+ session->DecreaseRecvWindowSize(
+ kSpdySessionInitialWindowSize + delta_window_size +
+ kSpdySessionInitialWindowSize);
+ EXPECT_EQ(0, session->session_recv_window_size_);
+ EXPECT_EQ(0, session->session_unacked_recv_window_bytes_);
+}
+
+// SpdySession::{Increase,Decrease}SendWindowSize should properly
+// adjust the session send window size when the "enable_spdy_31" flag
+// is set.
+TEST_P(SpdySessionTest, AdjustSendWindowSize) {
+ if (GetParam() < kProtoSPDY31)
+ return;
+
+ session_deps_.host_resolver->set_synchronous_mode(true);
+
+ MockConnect connect_data(SYNCHRONOUS, OK);
+ MockRead reads[] = {
+ MockRead(SYNCHRONOUS, 0, 0) // EOF
+ };
+ StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
+ data.set_connect_data(connect_data);
+ session_deps_.socket_factory->AddSocketDataProvider(&data);
+
+ CreateNetworkSession();
+ scoped_refptr<SpdySession> session = GetSession(key_);
+ InitializeSession(
+ http_session_.get(), session.get(), test_host_port_pair_);
+ EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
+ session->flow_control_state());
+
+ const int32 delta_window_size = 100;
+
+ EXPECT_EQ(kSpdySessionInitialWindowSize, session->session_send_window_size_);
session->IncreaseSendWindowSize(delta_window_size);
EXPECT_EQ(kSpdySessionInitialWindowSize + delta_window_size,
@@ -3425,205 +3759,20 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
EXPECT_TRUE(stream1->send_stalled_by_flow_control());
EXPECT_FALSE(stream2->send_stalled_by_flow_control());
- // This should then unstall stream1.
- UnstallSessionSend(session.get(), kBodyDataSize);
-
- EXPECT_FALSE(stream1->send_stalled_by_flow_control());
- EXPECT_FALSE(stream2->send_stalled_by_flow_control());
-
- data.RunFor(4);
-
- EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
- EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
-
- EXPECT_TRUE(delegate1.send_headers_completed());
- EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
- EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
-
- EXPECT_TRUE(delegate2.send_headers_completed());
- EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
- EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
- EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
-
- EXPECT_TRUE(data.at_write_eof());
-}
-
-// Delegate that closes a given stream after sending its body.
-class StreamClosingDelegate : public test::StreamDelegateWithBody {
- public:
- StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
- base::StringPiece data)
- : StreamDelegateWithBody(stream, data) {}
-
- virtual ~StreamClosingDelegate() {}
-
- void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
- stream_to_close_ = stream_to_close;
- }
-
- virtual void OnDataSent() OVERRIDE {
- test::StreamDelegateWithBody::OnDataSent();
- if (stream_to_close_.get()) {
- stream_to_close_->Close();
- EXPECT_EQ(NULL, stream_to_close_.get());
- }
- }
-
- private:
- base::WeakPtr<SpdyStream> stream_to_close_;
-};
-
-// Cause a stall by reducing the flow control send window to
-// 0. Unstalling the session should properly handle deleted streams.
-TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
- if (GetParam() < kProtoSPDY31)
- return;
-
- const char kStreamUrl[] = "http://www.google.com/";
- GURL url(kStreamUrl);
-
- session_deps_.host_resolver->set_synchronous_mode(true);
-
- scoped_ptr<SpdyFrame> req1(
- spdy_util_.ConstructSpdyPost(
- kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
- scoped_ptr<SpdyFrame> req2(
- spdy_util_.ConstructSpdyPost(
- kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
- scoped_ptr<SpdyFrame> req3(
- spdy_util_.ConstructSpdyPost(
- kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
- scoped_ptr<SpdyFrame> body2(
- spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
- MockWrite writes[] = {
- CreateMockWrite(*req1, 0),
- CreateMockWrite(*req2, 1),
- CreateMockWrite(*req3, 2),
- CreateMockWrite(*body2, 3),
- };
-
- scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
- MockRead reads[] = {
- CreateMockRead(*resp2, 4),
- MockRead(ASYNC, 0, 0, 5), // EOF
- };
-
- DeterministicSocketData data(reads, arraysize(reads),
- writes, arraysize(writes));
- MockConnect connect_data(SYNCHRONOUS, OK);
- data.set_connect_data(connect_data);
-
- session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
-
- CreateDeterministicNetworkSession();
- scoped_refptr<SpdySession> session = GetSession(key_);
- InitializeSession(
- http_session_.get(), session.get(), test_host_port_pair_);
- EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
- session->flow_control_state());
-
- base::WeakPtr<SpdyStream> stream1 =
- CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
- session, url, LOWEST, BoundNetLog());
- ASSERT_TRUE(stream1.get() != NULL);
-
- test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
- stream1->SetDelegate(&delegate1);
-
- EXPECT_FALSE(stream1->HasUrl());
-
- base::WeakPtr<SpdyStream> stream2 =
- CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
- session, url, LOWEST, BoundNetLog());
- ASSERT_TRUE(stream2.get() != NULL);
-
- StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
- stream2->SetDelegate(&delegate2);
-
- EXPECT_FALSE(stream2->HasUrl());
-
- base::WeakPtr<SpdyStream> stream3 =
- CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
- session, url, LOWEST, BoundNetLog());
- ASSERT_TRUE(stream3.get() != NULL);
-
- test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
- stream3->SetDelegate(&delegate3);
-
- EXPECT_FALSE(stream3->HasUrl());
-
- EXPECT_FALSE(stream1->send_stalled_by_flow_control());
- EXPECT_FALSE(stream2->send_stalled_by_flow_control());
- EXPECT_FALSE(stream3->send_stalled_by_flow_control());
-
- StallSessionSend(session.get());
-
- scoped_ptr<SpdyHeaderBlock> headers1(
- spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
- EXPECT_TRUE(stream1->HasUrl());
- EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec());
-
- data.RunFor(1);
- EXPECT_EQ(1u, stream1->stream_id());
- EXPECT_TRUE(stream1->send_stalled_by_flow_control());
-
- scoped_ptr<SpdyHeaderBlock> headers2(
- spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
- EXPECT_TRUE(stream2->HasUrl());
- EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec());
-
- data.RunFor(1);
- EXPECT_EQ(3u, stream2->stream_id());
- EXPECT_TRUE(stream2->send_stalled_by_flow_control());
-
- scoped_ptr<SpdyHeaderBlock> headers3(
- spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
- EXPECT_EQ(ERR_IO_PENDING,
- stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
- EXPECT_TRUE(stream3->HasUrl());
- EXPECT_EQ(kStreamUrl, stream3->GetUrl().spec());
-
- data.RunFor(1);
- EXPECT_EQ(5u, stream3->stream_id());
- EXPECT_TRUE(stream3->send_stalled_by_flow_control());
-
- SpdyStreamId stream_id1 = stream1->stream_id();
- SpdyStreamId stream_id2 = stream2->stream_id();
- SpdyStreamId stream_id3 = stream3->stream_id();
-
- // Close stream1 preemptively.
- session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
- EXPECT_EQ(NULL, stream1.get());
-
- EXPECT_FALSE(session->IsStreamActive(stream_id1));
- EXPECT_TRUE(session->IsStreamActive(stream_id2));
- EXPECT_TRUE(session->IsStreamActive(stream_id3));
-
- // Unstall stream2, which should then close stream3.
- delegate2.set_stream_to_close(stream3);
- UnstallSessionSend(session.get(), kBodyDataSize);
-
- data.RunFor(1);
- EXPECT_EQ(NULL, stream3.get());
+ // This should then unstall stream1.
+ UnstallSessionSend(session.get(), kBodyDataSize);
+ EXPECT_FALSE(stream1->send_stalled_by_flow_control());
EXPECT_FALSE(stream2->send_stalled_by_flow_control());
- EXPECT_FALSE(session->IsStreamActive(stream_id1));
- EXPECT_TRUE(session->IsStreamActive(stream_id2));
- EXPECT_FALSE(session->IsStreamActive(stream_id3));
- data.RunFor(2);
- EXPECT_EQ(NULL, stream2.get());
+ data.RunFor(4);
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
- EXPECT_EQ(OK, delegate3.WaitForClose());
EXPECT_TRUE(delegate1.send_headers_completed());
+ EXPECT_EQ("200", delegate1.GetResponseHeaderValue(":status"));
+ EXPECT_EQ("HTTP/1.1", delegate1.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
EXPECT_TRUE(delegate2.send_headers_completed());
@@ -3631,16 +3780,37 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
- EXPECT_TRUE(delegate3.send_headers_completed());
- EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
-
EXPECT_TRUE(data.at_write_eof());
}
+// Delegate that closes a given stream after sending its body.
+class StreamClosingDelegate : public test::StreamDelegateWithBody {
+ public:
+ StreamClosingDelegate(const base::WeakPtr<SpdyStream>& stream,
+ base::StringPiece data)
+ : StreamDelegateWithBody(stream, data) {}
+
+ virtual ~StreamClosingDelegate() {}
+
+ void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) {
+ stream_to_close_ = stream_to_close;
+ }
+
+ virtual void OnDataSent() OVERRIDE {
+ test::StreamDelegateWithBody::OnDataSent();
+ if (stream_to_close_.get()) {
+ stream_to_close_->Close();
+ EXPECT_EQ(NULL, stream_to_close_.get());
+ }
+ }
+
+ private:
+ base::WeakPtr<SpdyStream> stream_to_close_;
+};
+
// Cause a stall by reducing the flow control send window to
-// 0. Unstalling the session should properly handle the session itself
-// being closed.
-TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
+// 0. Unstalling the session should properly handle deleted streams.
+TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
if (GetParam() < kProtoSPDY31)
return;
@@ -3655,15 +3825,22 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
scoped_ptr<SpdyFrame> req2(
spdy_util_.ConstructSpdyPost(
kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
- scoped_ptr<SpdyFrame> body1(
- spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
+ scoped_ptr<SpdyFrame> req3(
+ spdy_util_.ConstructSpdyPost(
+ kStreamUrl, 5, kBodyDataSize, LOWEST, NULL, 0));
+ scoped_ptr<SpdyFrame> body2(
+ spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
MockWrite writes[] = {
CreateMockWrite(*req1, 0),
CreateMockWrite(*req2, 1),
+ CreateMockWrite(*req3, 2),
+ CreateMockWrite(*body2, 3),
};
+ scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
MockRead reads[] = {
- MockRead(ASYNC, 0, 0, 2), // EOF
+ CreateMockRead(*resp2, 4),
+ MockRead(ASYNC, 0, 0, 5), // EOF
};
DeterministicSocketData data(reads, arraysize(reads),
@@ -3695,13 +3872,24 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
session, url, LOWEST, BoundNetLog());
ASSERT_TRUE(stream2.get() != NULL);
- test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
+ StreamClosingDelegate delegate2(stream2, kBodyDataStringPiece);
stream2->SetDelegate(&delegate2);
EXPECT_FALSE(stream2->HasUrl());
+ base::WeakPtr<SpdyStream> stream3 =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
+ session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(stream3.get() != NULL);
+
+ test::StreamDelegateWithBody delegate3(stream3, kBodyDataStringPiece);
+ stream3->SetDelegate(&delegate3);
+
+ EXPECT_FALSE(stream3->HasUrl());
+
EXPECT_FALSE(stream1->send_stalled_by_flow_control());
EXPECT_FALSE(stream2->send_stalled_by_flow_control());
+ EXPECT_FALSE(stream3->send_stalled_by_flow_control());
StallSessionSend(session.get());
@@ -3727,359 +3915,174 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
EXPECT_EQ(3u, stream2->stream_id());
EXPECT_TRUE(stream2->send_stalled_by_flow_control());
- EXPECT_TRUE(spdy_session_pool_->HasSession(key_));
-
- // Unstall stream1.
- UnstallSessionSend(session.get(), kBodyDataSize);
-
- // Close the session (since we can't do it from within the delegate
- // method, since it's in the stream's loop).
- session->CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "Closing session");
- session = NULL;
-
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_));
-
- EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
- EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
-
- EXPECT_TRUE(delegate1.send_headers_completed());
- EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
-
- EXPECT_TRUE(delegate2.send_headers_completed());
- EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
-
- EXPECT_TRUE(data.at_write_eof());
-}
-
-
-// Tests the case of a non-SPDY request closing an idle SPDY session when no
-// pointers to the idle session are currently held.
-TEST_P(SpdySessionTest, CloseOneIdleConnection) {
- ClientSocketPoolManager::set_max_sockets_per_group(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
- ClientSocketPoolManager::set_max_sockets_per_pool(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
-
- MockConnect connect_data(SYNCHRONOUS, OK);
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
- };
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- CreateNetworkSession();
-
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
-
- // Create an idle SPDY session.
- SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
- scoped_refptr<SpdySession> session1 = GetSession(key1);
- EXPECT_EQ(
- OK,
- InitializeSession(http_session_.get(), session1.get(),
- key1.host_port_pair()));
- EXPECT_FALSE(pool->IsStalled());
- // Release the pointer to the session so it can be closed.
- session1 = NULL;
-
- // Trying to create a new connection should cause the pool to be stalled, and
- // post a task asynchronously to try and close the session.
- TestCompletionCallback callback2;
- HostPortPair host_port2("2.com", 80);
- scoped_refptr<TransportSocketParams> params2(
- new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
- OnHostResolutionCallback()));
- scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
+ scoped_ptr<SpdyHeaderBlock> headers3(
+ spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
- callback2.callback(), pool, BoundNetLog()));
- EXPECT_TRUE(pool->IsStalled());
-
- // The socket pool should close the connection asynchronously and establish a
- // new connection.
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_FALSE(pool->IsStalled());
-}
-
-// Tests the case of a non-SPDY request closing an idle SPDY session when no
-// pointers to the idle session are currently held, in the case the SPDY session
-// has an alias.
-TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) {
- ClientSocketPoolManager::set_max_sockets_per_group(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
- ClientSocketPoolManager::set_max_sockets_per_pool(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
-
- MockConnect connect_data(SYNCHRONOUS, OK);
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
- };
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
-
- session_deps_.host_resolver->set_synchronous_mode(true);
- session_deps_.host_resolver->rules()->AddIPLiteralRule(
- "1.com", "192.168.0.2", std::string());
- session_deps_.host_resolver->rules()->AddIPLiteralRule(
- "2.com", "192.168.0.2", std::string());
- // Not strictly needed.
- session_deps_.host_resolver->rules()->AddIPLiteralRule(
- "3.com", "192.168.0.3", std::string());
-
- CreateNetworkSession();
-
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
-
- // Create an idle SPDY session.
- SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
- scoped_refptr<SpdySession> session1 = GetSession(key1);
- EXPECT_EQ(
- OK,
- InitializeSession(http_session_.get(), session1.get(),
- key1.host_port_pair()));
- EXPECT_FALSE(pool->IsStalled());
-
- // Set up an alias for the idle SPDY session, increasing its ref count to 2.
- SpdySessionKey key2(HostPortPair("2.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
- SpdySessionPoolPeer pool_peer(spdy_session_pool_);
- HostResolver::RequestInfo info(key2.host_port_pair());
- AddressList addresses;
- // Pre-populate the DNS cache, since a synchronous resolution is required in
- // order to create the alias.
- session_deps_.host_resolver->Resolve(
- info, &addresses, CompletionCallback(), NULL, BoundNetLog());
- // Add the alias for the first session's key. Has to be done manually since
- // the usual process is bypassed.
- pool_peer.AddAlias(addresses.front(), key1);
- // Get a session for |key2|, which should return the session created earlier.
- scoped_refptr<SpdySession> session2 =
- spdy_session_pool_->Get(key2, BoundNetLog());
- ASSERT_EQ(session1.get(), session2.get());
- EXPECT_FALSE(pool->IsStalled());
+ stream3->SendRequestHeaders(headers3.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_TRUE(stream3->HasUrl());
+ EXPECT_EQ(kStreamUrl, stream3->GetUrl().spec());
- // Release both the pointers to the session so it can be closed.
- session1 = NULL;
- session2 = NULL;
+ data.RunFor(1);
+ EXPECT_EQ(5u, stream3->stream_id());
+ EXPECT_TRUE(stream3->send_stalled_by_flow_control());
- // Trying to create a new connection should cause the pool to be stalled, and
- // post a task asynchronously to try and close the session.
- TestCompletionCallback callback3;
- HostPortPair host_port3("3.com", 80);
- scoped_refptr<TransportSocketParams> params3(
- new TransportSocketParams(host_port3, DEFAULT_PRIORITY, false, false,
- OnHostResolutionCallback()));
- scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle);
- EXPECT_EQ(ERR_IO_PENDING,
- connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY,
- callback3.callback(), pool, BoundNetLog()));
- EXPECT_TRUE(pool->IsStalled());
+ SpdyStreamId stream_id1 = stream1->stream_id();
+ SpdyStreamId stream_id2 = stream2->stream_id();
+ SpdyStreamId stream_id3 = stream3->stream_id();
- // The socket pool should close the connection asynchronously and establish a
- // new connection.
- EXPECT_EQ(OK, callback3.WaitForResult());
- EXPECT_FALSE(pool->IsStalled());
-}
+ // Close stream1 preemptively.
+ session->CloseActiveStream(stream_id1, ERR_CONNECTION_CLOSED);
+ EXPECT_EQ(NULL, stream1.get());
-// Tests the case of a non-SPDY request closing an idle SPDY session when a
-// pointer to the idle session is still held.
-TEST_P(SpdySessionTest, CloseOneIdleConnectionSessionStillHeld) {
- ClientSocketPoolManager::set_max_sockets_per_group(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
- ClientSocketPoolManager::set_max_sockets_per_pool(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+ EXPECT_FALSE(session->IsStreamActive(stream_id1));
+ EXPECT_TRUE(session->IsStreamActive(stream_id2));
+ EXPECT_TRUE(session->IsStreamActive(stream_id3));
- MockConnect connect_data(SYNCHRONOUS, OK);
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
- };
- StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
- data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
+ // Unstall stream2, which should then close stream3.
+ delegate2.set_stream_to_close(stream3);
+ UnstallSessionSend(session.get(), kBodyDataSize);
- CreateNetworkSession();
+ data.RunFor(1);
+ EXPECT_EQ(NULL, stream3.get());
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+ EXPECT_FALSE(stream2->send_stalled_by_flow_control());
+ EXPECT_FALSE(session->IsStreamActive(stream_id1));
+ EXPECT_TRUE(session->IsStreamActive(stream_id2));
+ EXPECT_FALSE(session->IsStreamActive(stream_id3));
- // Create an idle SPDY session.
- SpdySessionKey key1(HostPortPair("1.com", 80), ProxyServer::Direct(),
- kPrivacyModeDisabled);
- scoped_refptr<SpdySession> session1 = GetSession(key1);
- EXPECT_EQ(
- OK,
- InitializeSession(http_session_.get(), session1.get(),
- key1.host_port_pair()));
- EXPECT_FALSE(pool->IsStalled());
+ data.RunFor(2);
+ EXPECT_EQ(NULL, stream2.get());
- // Trying to create a new connection should cause the pool to be stalled, and
- // post a task asynchronously to try and close the session.
- TestCompletionCallback callback2;
- HostPortPair host_port2("2.com", 80);
- scoped_refptr<TransportSocketParams> params2(
- new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
- OnHostResolutionCallback()));
- scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
- EXPECT_EQ(ERR_IO_PENDING,
- connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
- callback2.callback(), pool, BoundNetLog()));
- EXPECT_TRUE(pool->IsStalled());
+ EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
+ EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
+ EXPECT_EQ(OK, delegate3.WaitForClose());
- // Running the message loop should cause the session to prepare to be closed,
- // but since there's still an outstanding reference, it should not be closed
- // yet.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(pool->IsStalled());
- EXPECT_FALSE(callback2.have_result());
+ EXPECT_TRUE(delegate1.send_headers_completed());
+ EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
- // Release the pointer to the session so it can be closed.
- session1 = NULL;
- EXPECT_EQ(OK, callback2.WaitForResult());
- EXPECT_FALSE(pool->IsStalled());
+ EXPECT_TRUE(delegate2.send_headers_completed());
+ EXPECT_EQ("200", delegate2.GetResponseHeaderValue(":status"));
+ EXPECT_EQ("HTTP/1.1", delegate2.GetResponseHeaderValue(":version"));
+ EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
+
+ EXPECT_TRUE(delegate3.send_headers_completed());
+ EXPECT_EQ(std::string(), delegate3.TakeReceivedData());
+
+ EXPECT_TRUE(data.at_write_eof());
}
-// Tests that a non-SPDY request can't close a SPDY session that's currently in
-// use.
-TEST_P(SpdySessionTest, CloseOneIdleConnectionFailsWhenSessionInUse) {
- ClientSocketPoolManager::set_max_sockets_per_group(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
- ClientSocketPoolManager::set_max_sockets_per_pool(
- HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
+// Cause a stall by reducing the flow control send window to
+// 0. Unstalling the session should properly handle the session itself
+// being closed.
+TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
+ if (GetParam() < kProtoSPDY31)
+ return;
+
+ const char kStreamUrl[] = "http://www.google.com/";
+ GURL url(kStreamUrl);
+
+ session_deps_.host_resolver->set_synchronous_mode(true);
- MockConnect connect_data(SYNCHRONOUS, OK);
- MockRead reads[] = {
- MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever.
- };
scoped_ptr<SpdyFrame> req1(
- spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
- scoped_ptr<SpdyFrame> cancel1(
- spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
+ spdy_util_.ConstructSpdyPost(
+ kStreamUrl, 1, kBodyDataSize, LOWEST, NULL, 0));
+ scoped_ptr<SpdyFrame> req2(
+ spdy_util_.ConstructSpdyPost(
+ kStreamUrl, 3, kBodyDataSize, LOWEST, NULL, 0));
+ scoped_ptr<SpdyFrame> body1(
+ spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
MockWrite writes[] = {
- CreateMockWrite(*req1, 1),
- CreateMockWrite(*cancel1, 1),
+ CreateMockWrite(*req1, 0),
+ CreateMockWrite(*req2, 1),
};
- StaticSocketDataProvider data(reads, arraysize(reads),
- writes, arraysize(writes));
+
+ MockRead reads[] = {
+ MockRead(ASYNC, 0, 0, 2), // EOF
+ };
+
+ DeterministicSocketData data(reads, arraysize(reads),
+ writes, arraysize(writes));
+ MockConnect connect_data(SYNCHRONOUS, OK);
data.set_connect_data(connect_data);
- session_deps_.socket_factory->AddSocketDataProvider(&data);
- CreateNetworkSession();
+ session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data);
- TransportClientSocketPool* pool =
- http_session_->GetTransportSocketPool(
- HttpNetworkSession::NORMAL_SOCKET_POOL);
+ CreateDeterministicNetworkSession();
+ scoped_refptr<SpdySession> session = GetSession(key_);
+ InitializeSession(
+ http_session_.get(), session.get(), test_host_port_pair_);
+ EXPECT_EQ(SpdySession::FLOW_CONTROL_STREAM_AND_SESSION,
+ session->flow_control_state());
- // Create a SPDY session.
- GURL url1("http://www.google.com");
- SpdySessionKey key1(HostPortPair(url1.host(), 80),
- ProxyServer::Direct(), kPrivacyModeDisabled);
- scoped_refptr<SpdySession> session1 = GetSession(key1);
- EXPECT_EQ(
- OK,
- InitializeSession(http_session_.get(), session1.get(),
- key1.host_port_pair()));
- EXPECT_FALSE(pool->IsStalled());
+ base::WeakPtr<SpdyStream> stream1 =
+ CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
+ session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(stream1.get() != NULL);
- // Create a stream using the session, and send a request.
+ test::StreamDelegateWithBody delegate1(stream1, kBodyDataStringPiece);
+ stream1->SetDelegate(&delegate1);
- TestCompletionCallback callback1;
- base::WeakPtr<SpdyStream> spdy_stream1 =
+ EXPECT_FALSE(stream1->HasUrl());
+
+ base::WeakPtr<SpdyStream> stream2 =
CreateStreamSynchronously(SPDY_REQUEST_RESPONSE_STREAM,
- session1, url1, DEFAULT_PRIORITY,
- BoundNetLog());
- ASSERT_TRUE(spdy_stream1.get());
- test::StreamDelegateDoNothing delegate1(spdy_stream1);
- spdy_stream1->SetDelegate(&delegate1);
+ session, url, LOWEST, BoundNetLog());
+ ASSERT_TRUE(stream2.get() != NULL);
- scoped_ptr<SpdyHeaderBlock> headers1(
- spdy_util_.ConstructGetHeaderBlock(url1.spec()));
- EXPECT_EQ(ERR_IO_PENDING,
- spdy_stream1->SendRequestHeaders(
- headers1.Pass(), NO_MORE_DATA_TO_SEND));
- EXPECT_TRUE(spdy_stream1->HasUrl());
+ test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece);
+ stream2->SetDelegate(&delegate2);
- base::MessageLoop::current()->RunUntilIdle();
+ EXPECT_FALSE(stream2->HasUrl());
- // Release the session, so holding onto a pointer here does not affect
- // anything.
- session1 = NULL;
+ EXPECT_FALSE(stream1->send_stalled_by_flow_control());
+ EXPECT_FALSE(stream2->send_stalled_by_flow_control());
- // Trying to create a new connection should cause the pool to be stalled, and
- // post a task asynchronously to try and close the session.
- TestCompletionCallback callback2;
- HostPortPair host_port2("2.com", 80);
- scoped_refptr<TransportSocketParams> params2(
- new TransportSocketParams(host_port2, DEFAULT_PRIORITY, false, false,
- OnHostResolutionCallback()));
- scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle);
+ StallSessionSend(session.get());
+
+ scoped_ptr<SpdyHeaderBlock> headers1(
+ spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
EXPECT_EQ(ERR_IO_PENDING,
- connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY,
- callback2.callback(), pool, BoundNetLog()));
- EXPECT_TRUE(pool->IsStalled());
+ stream1->SendRequestHeaders(headers1.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_TRUE(stream1->HasUrl());
+ EXPECT_EQ(kStreamUrl, stream1->GetUrl().spec());
- // Running the message loop should cause the socket pool to ask the SPDY
- // session to close an idle socket, but since the socket is in use, nothing
- // happens.
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(pool->IsStalled());
- EXPECT_FALSE(callback2.have_result());
+ data.RunFor(1);
+ EXPECT_EQ(1u, stream1->stream_id());
+ EXPECT_TRUE(stream1->send_stalled_by_flow_control());
- // Cancelling the request should still not release the session's socket,
- // since the session is still kept alive by the SpdySessionPool.
- ASSERT_TRUE(spdy_stream1.get());
- spdy_stream1->Cancel();
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(pool->IsStalled());
- EXPECT_FALSE(callback2.have_result());
-}
+ scoped_ptr<SpdyHeaderBlock> headers2(
+ spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kBodyDataSize));
+ EXPECT_EQ(ERR_IO_PENDING,
+ stream2->SendRequestHeaders(headers2.Pass(), MORE_DATA_TO_SEND));
+ EXPECT_TRUE(stream2->HasUrl());
+ EXPECT_EQ(kStreamUrl, stream2->GetUrl().spec());
-// Verify that SpdySessionKey and therefore SpdySession is different when
-// privacy mode is enabled or disabled.
-TEST_P(SpdySessionTest, SpdySessionKeyPrivacyMode) {
- CreateDeterministicNetworkSession();
+ data.RunFor(1);
+ EXPECT_EQ(3u, stream2->stream_id());
+ EXPECT_TRUE(stream2->send_stalled_by_flow_control());
- HostPortPair host_port_pair("www.google.com", 443);
- SpdySessionKey key_privacy_enabled(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeEnabled);
- SpdySessionKey key_privacy_disabled(host_port_pair, ProxyServer::Direct(),
- kPrivacyModeDisabled);
+ EXPECT_TRUE(spdy_session_pool_->HasSession(key_));
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+ // Unstall stream1.
+ UnstallSessionSend(session.get(), kBodyDataSize);
- // Add SpdySession with PrivacyMode Enabled to the pool.
- scoped_refptr<SpdySession> session_privacy_enabled =
- spdy_session_pool_->Get(key_privacy_enabled, BoundNetLog());
+ // Close the session (since we can't do it from within the delegate
+ // method, since it's in the stream's loop).
+ session->CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "Closing session");
+ session = NULL;
- EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+ EXPECT_FALSE(spdy_session_pool_->HasSession(key_));
- // Add SpdySession with PrivacyMode Disabled to the pool.
- scoped_refptr<SpdySession> session_privacy_disabled =
- spdy_session_pool_->Get(key_privacy_disabled, BoundNetLog());
+ EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate1.WaitForClose());
+ EXPECT_EQ(ERR_CONNECTION_CLOSED, delegate2.WaitForClose());
- EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_enabled));
- EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
+ EXPECT_TRUE(delegate1.send_headers_completed());
+ EXPECT_EQ(std::string(), delegate1.TakeReceivedData());
- spdy_session_pool_->Remove(session_privacy_enabled);
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
- EXPECT_TRUE(spdy_session_pool_->HasSession(key_privacy_disabled));
+ EXPECT_TRUE(delegate2.send_headers_completed());
+ EXPECT_EQ(std::string(), delegate2.TakeReceivedData());
- spdy_session_pool_->Remove(session_privacy_disabled);
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_enabled));
- EXPECT_FALSE(spdy_session_pool_->HasSession(key_privacy_disabled));
+ EXPECT_TRUE(data.at_write_eof());
}
} // namespace net
« 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