Probably broke Win7 Tests (dbg)(6). http://build.chromium.org/p/chromium.win/builders...
[chromium-blink-merge.git] / net / dns / dns_session_unittest.cc
blobed726f23234963f59f3532e05c42ab45345895d9
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"
7 #include <list>
9 #include "base/bind.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"
21 namespace net {
23 namespace {
25 class TestClientSocketFactory : public ClientSocketFactory {
26 public:
27 virtual ~TestClientSocketFactory();
29 virtual scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
30 DatagramSocket::BindType bind_type,
31 const RandIntCallback& rand_int_cb,
32 net::NetLog* net_log,
33 const net::NetLog::Source& source) OVERRIDE;
35 virtual scoped_ptr<StreamSocket> CreateTransportClientSocket(
36 const AddressList& addresses,
37 NetLog*, const NetLog::Source&) OVERRIDE {
38 NOTIMPLEMENTED();
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 {
47 NOTIMPLEMENTED();
48 return scoped_ptr<SSLClientSocket>();
51 virtual void ClearSSLSessionCache() OVERRIDE {
52 NOTIMPLEMENTED();
55 private:
56 std::list<SocketDataProvider*> data_providers_;
59 struct PoolEvent {
60 enum { ALLOCATE, FREE } action;
61 unsigned server_index;
64 class DnsSessionTest : public testing::Test {
65 public:
66 void OnSocketAllocated(unsigned server_index);
67 void OnSocketFreed(unsigned server_index);
69 protected:
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);
74 bool NoMoreEvents();
76 DnsConfig config_;
77 scoped_ptr<TestClientSocketFactory> test_client_socket_factory_;
78 scoped_refptr<DnsSession> session_;
79 NetLog::Source source_;
81 private:
82 bool ExpectEvent(const PoolEvent& event);
83 std::list<PoolEvent> events_;
86 class MockDnsSocketPool : public DnsSocketPool {
87 public:
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);
111 private:
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);
120 EXPECT_TRUE(rv);
121 for (unsigned char i = 0; i < num_servers; ++i) {
122 dns_ip[3] = 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),
135 NULL /* NetLog */);
137 events_.clear();
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()) {
171 return false;
174 const PoolEvent actual = events_.front();
175 if ((expected.action != actual.action)
176 || (expected.server_index != actual.server_index)) {
177 return false;
179 events_.pop_front();
181 return true;
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;
207 Initialize(2);
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());
218 lease1.reset();
219 EXPECT_TRUE(DidFree(0));
220 EXPECT_TRUE(NoMoreEvents());
222 lease2.reset();
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) {
229 Initialize(2);
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);
237 Initialize(2);
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);
245 Initialize(2);
246 base::TimeDelta timeout = session_->NextTimeout(0, 0);
247 EXPECT_EQ(config_.timeout.InMilliseconds(), timeout.InMilliseconds());
250 } // namespace
252 } // namespace net