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
3 // found in the LICENSE file.
5 #include "net/dns/dns_session.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/rand_util.h"
12 #include "base/stl_util.h"
13 #include "net/base/net_log.h"
14 #include "net/dns/dns_protocol.h"
15 #include "net/dns/dns_socket_pool.h"
16 #include "net/socket/socket_test_util.h"
17 #include "net/socket/ssl_client_socket.h"
18 #include "net/socket/stream_socket.h"
19 #include "testing/gtest/include/gtest/gtest.h"
25 class TestClientSocketFactory
: public ClientSocketFactory
{
27 virtual ~TestClientSocketFactory();
29 virtual scoped_ptr
<DatagramClientSocket
> CreateDatagramClientSocket(
30 DatagramSocket::BindType bind_type
,
31 const RandIntCallback
& rand_int_cb
,
33 const net::NetLog::Source
& source
) OVERRIDE
;
35 virtual scoped_ptr
<StreamSocket
> CreateTransportClientSocket(
36 const AddressList
& addresses
,
37 NetLog
*, const NetLog::Source
&) OVERRIDE
{
39 return scoped_ptr
<StreamSocket
>();
42 virtual scoped_ptr
<SSLClientSocket
> CreateSSLClientSocket(
43 scoped_ptr
<ClientSocketHandle
> transport_socket
,
44 const HostPortPair
& host_and_port
,
45 const SSLConfig
& ssl_config
,
46 const SSLClientSocketContext
& context
) OVERRIDE
{
48 return scoped_ptr
<SSLClientSocket
>();
51 virtual void ClearSSLSessionCache() OVERRIDE
{
56 std::list
<SocketDataProvider
*> data_providers_
;
60 enum { ALLOCATE
, FREE
} action
;
61 unsigned server_index
;
64 class DnsSessionTest
: public testing::Test
{
66 void OnSocketAllocated(unsigned server_index
);
67 void OnSocketFreed(unsigned server_index
);
70 void Initialize(unsigned num_servers
);
71 scoped_ptr
<DnsSession::SocketLease
> Allocate(unsigned server_index
);
72 bool DidAllocate(unsigned server_index
);
73 bool DidFree(unsigned server_index
);
77 scoped_ptr
<TestClientSocketFactory
> test_client_socket_factory_
;
78 scoped_refptr
<DnsSession
> session_
;
79 NetLog::Source source_
;
82 bool ExpectEvent(const PoolEvent
& event
);
83 std::list
<PoolEvent
> events_
;
86 class MockDnsSocketPool
: public DnsSocketPool
{
88 MockDnsSocketPool(ClientSocketFactory
* factory
, DnsSessionTest
* test
)
89 : DnsSocketPool(factory
), test_(test
) { }
91 virtual ~MockDnsSocketPool() { }
93 virtual void Initialize(
94 const std::vector
<IPEndPoint
>* nameservers
,
95 NetLog
* net_log
) OVERRIDE
{
96 InitializeInternal(nameservers
, net_log
);
99 virtual scoped_ptr
<DatagramClientSocket
> AllocateSocket(
100 unsigned server_index
) OVERRIDE
{
101 test_
->OnSocketAllocated(server_index
);
102 return CreateConnectedSocket(server_index
);
105 virtual void FreeSocket(
106 unsigned server_index
,
107 scoped_ptr
<DatagramClientSocket
> socket
) OVERRIDE
{
108 test_
->OnSocketFreed(server_index
);
112 DnsSessionTest
* test_
;
115 void DnsSessionTest::Initialize(unsigned num_servers
) {
116 CHECK(num_servers
< 256u);
117 config_
.nameservers
.clear();
118 IPAddressNumber dns_ip
;
119 bool rv
= ParseIPLiteralToNumber("192.168.1.0", &dns_ip
);
121 for (unsigned char i
= 0; i
< num_servers
; ++i
) {
123 IPEndPoint
dns_endpoint(dns_ip
, dns_protocol::kDefaultPort
);
124 config_
.nameservers
.push_back(dns_endpoint
);
127 test_client_socket_factory_
.reset(new TestClientSocketFactory());
129 DnsSocketPool
* dns_socket_pool
=
130 new MockDnsSocketPool(test_client_socket_factory_
.get(), this);
132 session_
= new DnsSession(config_
,
133 scoped_ptr
<DnsSocketPool
>(dns_socket_pool
),
134 base::Bind(&base::RandInt
),
140 scoped_ptr
<DnsSession::SocketLease
> DnsSessionTest::Allocate(
141 unsigned server_index
) {
142 return session_
->AllocateSocket(server_index
, source_
);
145 bool DnsSessionTest::DidAllocate(unsigned server_index
) {
146 PoolEvent expected_event
= { PoolEvent::ALLOCATE
, server_index
};
147 return ExpectEvent(expected_event
);
150 bool DnsSessionTest::DidFree(unsigned server_index
) {
151 PoolEvent expected_event
= { PoolEvent::FREE
, server_index
};
152 return ExpectEvent(expected_event
);
155 bool DnsSessionTest::NoMoreEvents() {
156 return events_
.empty();
159 void DnsSessionTest::OnSocketAllocated(unsigned server_index
) {
160 PoolEvent event
= { PoolEvent::ALLOCATE
, server_index
};
161 events_
.push_back(event
);
164 void DnsSessionTest::OnSocketFreed(unsigned server_index
) {
165 PoolEvent event
= { PoolEvent::FREE
, server_index
};
166 events_
.push_back(event
);
169 bool DnsSessionTest::ExpectEvent(const PoolEvent
& expected
) {
170 if (events_
.empty()) {
174 const PoolEvent actual
= events_
.front();
175 if ((expected
.action
!= actual
.action
)
176 || (expected
.server_index
!= actual
.server_index
)) {
184 scoped_ptr
<DatagramClientSocket
>
185 TestClientSocketFactory::CreateDatagramClientSocket(
186 DatagramSocket::BindType bind_type
,
187 const RandIntCallback
& rand_int_cb
,
188 net::NetLog
* net_log
,
189 const net::NetLog::Source
& source
) {
190 // We're not actually expecting to send or receive any data, so use the
191 // simplest SocketDataProvider with no data supplied.
192 SocketDataProvider
* data_provider
= new StaticSocketDataProvider();
193 data_providers_
.push_back(data_provider
);
194 scoped_ptr
<MockUDPClientSocket
> socket(
195 new MockUDPClientSocket(data_provider
, net_log
));
196 data_provider
->set_socket(socket
.get());
197 return socket
.PassAs
<DatagramClientSocket
>();
200 TestClientSocketFactory::~TestClientSocketFactory() {
201 STLDeleteElements(&data_providers_
);
204 TEST_F(DnsSessionTest
, AllocateFree
) {
205 scoped_ptr
<DnsSession::SocketLease
> lease1
, lease2
;
208 EXPECT_TRUE(NoMoreEvents());
210 lease1
= Allocate(0);
211 EXPECT_TRUE(DidAllocate(0));
212 EXPECT_TRUE(NoMoreEvents());
214 lease2
= Allocate(1);
215 EXPECT_TRUE(DidAllocate(1));
216 EXPECT_TRUE(NoMoreEvents());
219 EXPECT_TRUE(DidFree(0));
220 EXPECT_TRUE(NoMoreEvents());
223 EXPECT_TRUE(DidFree(1));
224 EXPECT_TRUE(NoMoreEvents());
227 // Expect default calculated timeout to be within 10ms of in DnsConfig.
228 TEST_F(DnsSessionTest
, HistogramTimeoutNormal
) {
230 base::TimeDelta timeoutDelta
= session_
->NextTimeout(0, 0) - config_
.timeout
;
231 EXPECT_LT(timeoutDelta
.InMilliseconds(), 10);
234 // Expect short calculated timeout to be within 10ms of in DnsConfig.
235 TEST_F(DnsSessionTest
, HistogramTimeoutShort
) {
236 config_
.timeout
= base::TimeDelta::FromMilliseconds(15);
238 base::TimeDelta timeoutDelta
= session_
->NextTimeout(0, 0) - config_
.timeout
;
239 EXPECT_LT(timeoutDelta
.InMilliseconds(), 10);
242 // Expect long calculated timeout to be equal to one in DnsConfig.
243 TEST_F(DnsSessionTest
, HistogramTimeoutLong
) {
244 config_
.timeout
= base::TimeDelta::FromSeconds(15);
246 base::TimeDelta timeout
= session_
->NextTimeout(0, 0);
247 EXPECT_EQ(config_
.timeout
.InMilliseconds(), timeout
.InMilliseconds());