This source file includes following definitions.
- spdy_session_pool_
- CreateNetworkSession
- key_
- OnRequestHeadersSent
- OnResponseHeadersUpdated
- OnDataReceived
- OnDataSent
- OnClose
- TEST_P
- TEST_P
- TEST_P
- RunIPPoolingTest
- TEST_P
- TEST_P
- TEST_P
#include "net/spdy/spdy_session_pool.h"
#include <cstddef>
#include <string>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "net/dns/host_cache.h"
#include "net/http/http_network_session.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/transport_client_socket_pool.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_test_util_common.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace {
class SpdySessionPoolTest : public ::testing::Test,
public ::testing::WithParamInterface<NextProto> {
protected:
enum SpdyPoolCloseSessionsType {
SPDY_POOL_CLOSE_SESSIONS_MANUALLY,
SPDY_POOL_CLOSE_CURRENT_SESSIONS,
SPDY_POOL_CLOSE_IDLE_SESSIONS,
};
SpdySessionPoolTest()
: session_deps_(GetParam()),
spdy_session_pool_(NULL) {}
void CreateNetworkSession() {
http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
spdy_session_pool_ = http_session_->spdy_session_pool();
}
void RunIPPoolingTest(SpdyPoolCloseSessionsType close_sessions_type);
SpdySessionDependencies session_deps_;
scoped_refptr<HttpNetworkSession> http_session_;
SpdySessionPool* spdy_session_pool_;
};
INSTANTIATE_TEST_CASE_P(
NextProto,
SpdySessionPoolTest,
testing::Values(kProtoDeprecatedSPDY2,
kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
kProtoHTTP2Draft04));
class SessionOpeningDelegate : public SpdyStream::Delegate {
public:
SessionOpeningDelegate(SpdySessionPool* spdy_session_pool,
const SpdySessionKey& key)
: spdy_session_pool_(spdy_session_pool),
key_(key) {}
virtual ~SessionOpeningDelegate() {}
virtual void OnRequestHeadersSent() OVERRIDE {}
virtual SpdyResponseHeadersStatus OnResponseHeadersUpdated(
const SpdyHeaderBlock& response_headers) OVERRIDE {
return RESPONSE_HEADERS_ARE_COMPLETE;
}
virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) OVERRIDE {}
virtual void OnDataSent() OVERRIDE {}
virtual void OnClose(int status) OVERRIDE {
ignore_result(CreateFakeSpdySession(spdy_session_pool_, key_));
}
private:
SpdySessionPool* const spdy_session_pool_;
const SpdySessionKey key_;
};
TEST_P(SpdySessionPoolTest, CloseCurrentSessions) {
const char kTestHost[] = "www.foo.com";
const int kTestPort = 80;
session_deps_.host_resolver->set_synchronous_mode(true);
HostPortPair test_host_port_pair(kTestHost, kTestPort);
SpdySessionKey test_key =
SpdySessionKey(
test_host_port_pair, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
MockRead(SYNCHRONOUS, ERR_IO_PENDING)
};
StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, test_key, BoundNetLog());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_key));
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, GURL("http://www.foo.com"),
MEDIUM, BoundNetLog());
SessionOpeningDelegate delegate(spdy_session_pool_, test_key);
spdy_stream->SetDelegate(&delegate);
spdy_session_pool_->CloseCurrentSessions(net::ERR_ABORTED);
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_key));
}
TEST_P(SpdySessionPoolTest, CloseCurrentIdleSessions) {
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
MockRead(ASYNC, 0, 0)
};
session_deps_.host_resolver->set_synchronous_mode(true);
StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
CreateNetworkSession();
const std::string kTestHost1("http://www.a.com");
HostPortPair test_host_port_pair1(kTestHost1, 80);
SpdySessionKey key1(test_host_port_pair1, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session1 =
CreateInsecureSpdySession(http_session_, key1, BoundNetLog());
GURL url1(kTestHost1);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session1, url1, MEDIUM, BoundNetLog());
ASSERT_TRUE(spdy_stream1.get() != NULL);
session_deps_.socket_factory->AddSocketDataProvider(&data);
const std::string kTestHost2("http://www.b.com");
HostPortPair test_host_port_pair2(kTestHost2, 80);
SpdySessionKey key2(test_host_port_pair2, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session2 =
CreateInsecureSpdySession(http_session_, key2, BoundNetLog());
GURL url2(kTestHost2);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session2, url2, MEDIUM, BoundNetLog());
ASSERT_TRUE(spdy_stream2.get() != NULL);
session_deps_.socket_factory->AddSocketDataProvider(&data);
const std::string kTestHost3("http://www.c.com");
HostPortPair test_host_port_pair3(kTestHost3, 80);
SpdySessionKey key3(test_host_port_pair3, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
base::WeakPtr<SpdySession> session3 =
CreateInsecureSpdySession(http_session_, key3, BoundNetLog());
GURL url3(kTestHost3);
base::WeakPtr<SpdyStream> spdy_stream3 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session3, url3, MEDIUM, BoundNetLog());
ASSERT_TRUE(spdy_stream3.get() != NULL);
EXPECT_TRUE(session1->is_active());
EXPECT_FALSE(session1->IsClosed());
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
EXPECT_TRUE(session3->is_active());
EXPECT_FALSE(session3->IsClosed());
spdy_session_pool_->CloseCurrentIdleSessions();
EXPECT_TRUE(session1->is_active());
EXPECT_FALSE(session1->IsClosed());
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
EXPECT_TRUE(session3->is_active());
EXPECT_FALSE(session3->IsClosed());
session1->CloseCreatedStream(spdy_stream1, OK);
EXPECT_EQ(NULL, spdy_stream1.get());
session3->CloseCreatedStream(spdy_stream3, OK);
EXPECT_EQ(NULL, spdy_stream3.get());
EXPECT_FALSE(session1->is_active());
EXPECT_FALSE(session1->IsClosed());
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
EXPECT_FALSE(session3->is_active());
EXPECT_FALSE(session3->IsClosed());
spdy_session_pool_->CloseCurrentIdleSessions();
EXPECT_TRUE(session1 == NULL);
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
EXPECT_TRUE(session3 == NULL);
spdy_session_pool_->CloseCurrentIdleSessions();
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
session2->CloseCreatedStream(spdy_stream2, OK);
EXPECT_EQ(NULL, spdy_stream2.get());
EXPECT_FALSE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
spdy_session_pool_->CloseCurrentIdleSessions();
EXPECT_TRUE(session2 == NULL);
}
TEST_P(SpdySessionPoolTest, CloseAllSessions) {
const char kTestHost[] = "www.foo.com";
const int kTestPort = 80;
session_deps_.host_resolver->set_synchronous_mode(true);
HostPortPair test_host_port_pair(kTestHost, kTestPort);
SpdySessionKey test_key =
SpdySessionKey(
test_host_port_pair, ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
MockRead(SYNCHRONOUS, ERR_IO_PENDING)
};
StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(http_session_, test_key, BoundNetLog());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_key));
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, GURL("http://www.foo.com"),
MEDIUM, BoundNetLog());
SessionOpeningDelegate delegate(spdy_session_pool_, test_key);
spdy_stream->SetDelegate(&delegate);
spdy_session_pool_->CloseAllSessions();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_key));
}
void SpdySessionPoolTest::RunIPPoolingTest(
SpdyPoolCloseSessionsType close_sessions_type) {
const int kTestPort = 80;
struct TestHosts {
std::string url;
std::string name;
std::string iplist;
SpdySessionKey key;
AddressList addresses;
} test_hosts[] = {
{ "http:://www.foo.com",
"www.foo.com",
"192.0.2.33,192.168.0.1,192.168.0.5"
},
{ "http://js.foo.com",
"js.foo.com",
"192.168.0.2,192.168.0.3,192.168.0.5,192.0.2.33"
},
{ "http://images.foo.com",
"images.foo.com",
"192.168.0.4,192.168.0.3"
},
};
session_deps_.host_resolver->set_synchronous_mode(true);
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
session_deps_.host_resolver->rules()->AddIPLiteralRule(
test_hosts[i].name, test_hosts[i].iplist, std::string());
HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
session_deps_.host_resolver->Resolve(info,
DEFAULT_PRIORITY,
&test_hosts[i].addresses,
CompletionCallback(),
NULL,
BoundNetLog());
test_hosts[i].key = SpdySessionKey(
HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
PRIVACY_MODE_DISABLED);
}
MockConnect connect_data(SYNCHRONOUS, OK);
MockRead reads[] = {
MockRead(SYNCHRONOUS, ERR_IO_PENDING)
};
StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
data.set_connect_data(connect_data);
session_deps_.socket_factory->AddSocketDataProvider(&data);
SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
CreateNetworkSession();
base::WeakPtr<SpdySession> session =
CreateInsecureSpdySession(
http_session_, test_hosts[0].key, BoundNetLog());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
SpdySessionKey proxy_key(test_hosts[1].key.host_port_pair(),
ProxyServer::FromPacString("HTTP http://proxy.foo.com/"),
PRIVACY_MODE_DISABLED);
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, proxy_key));
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
session_deps_.socket_factory->AddSocketDataProvider(&data);
base::WeakPtr<SpdySession> session2 =
CreateInsecureSpdySession(
http_session_, test_hosts[2].key, BoundNetLog());
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[0].key));
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
base::WeakPtr<SpdySession> session1 =
spdy_session_pool_->FindAvailableSession(
test_hosts[1].key, BoundNetLog());
EXPECT_EQ(session.get(), session1.get());
EXPECT_NE(session2.get(), session1.get());
SpdySessionPoolPeer pool_peer(spdy_session_pool_);
pool_peer.RemoveAliases(test_hosts[0].key);
pool_peer.RemoveAliases(test_hosts[1].key);
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
session_deps_.host_resolver->GetHostCache()->clear();
EXPECT_TRUE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
switch (close_sessions_type) {
case SPDY_POOL_CLOSE_SESSIONS_MANUALLY:
session->CloseSessionOnError(ERR_ABORTED, std::string());
EXPECT_TRUE(session == NULL);
session2->CloseSessionOnError(ERR_ABORTED, std::string());
EXPECT_TRUE(session2 == NULL);
break;
case SPDY_POOL_CLOSE_CURRENT_SESSIONS:
spdy_session_pool_->CloseCurrentSessions(ERR_ABORTED);
break;
case SPDY_POOL_CLOSE_IDLE_SESSIONS:
GURL url(test_hosts[0].url);
base::WeakPtr<SpdyStream> spdy_stream =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session, url, MEDIUM, BoundNetLog());
GURL url1(test_hosts[1].url);
base::WeakPtr<SpdyStream> spdy_stream1 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session1, url1, MEDIUM, BoundNetLog());
GURL url2(test_hosts[2].url);
base::WeakPtr<SpdyStream> spdy_stream2 =
CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM,
session2, url2, MEDIUM, BoundNetLog());
session->CloseCreatedStream(spdy_stream, OK);
EXPECT_EQ(NULL, spdy_stream.get());
session1->CloseCreatedStream(spdy_stream1, OK);
EXPECT_EQ(NULL, spdy_stream1.get());
EXPECT_FALSE(session->is_active());
EXPECT_FALSE(session->IsClosed());
EXPECT_FALSE(session1->is_active());
EXPECT_FALSE(session1->IsClosed());
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
spdy_session_pool_->CloseCurrentIdleSessions();
EXPECT_TRUE(session == NULL);
EXPECT_TRUE(session1 == NULL);
EXPECT_TRUE(session2->is_active());
EXPECT_FALSE(session2->IsClosed());
spdy_stream2->Cancel();
EXPECT_EQ(NULL, spdy_stream.get());
EXPECT_EQ(NULL, spdy_stream1.get());
EXPECT_EQ(NULL, spdy_stream2.get());
session2->CloseSessionOnError(ERR_ABORTED, std::string());
EXPECT_TRUE(session2 == NULL);
break;
}
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[0].key));
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[1].key));
EXPECT_FALSE(HasSpdySession(spdy_session_pool_, test_hosts[2].key));
}
TEST_P(SpdySessionPoolTest, IPPooling) {
RunIPPoolingTest(SPDY_POOL_CLOSE_SESSIONS_MANUALLY);
}
TEST_P(SpdySessionPoolTest, IPPoolingCloseCurrentSessions) {
RunIPPoolingTest(SPDY_POOL_CLOSE_CURRENT_SESSIONS);
}
TEST_P(SpdySessionPoolTest, IPPoolingCloseIdleSessions) {
RunIPPoolingTest(SPDY_POOL_CLOSE_IDLE_SESSIONS);
}
}
}