- add sources.
[platform/framework/web/crosswalk.git] / src / net / dns / dns_session_unittest.cc
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.
4
5 #include "net/dns/dns_session.h"
6
7 #include <list>
8
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"
20
21 namespace net {
22
23 namespace {
24
25 class TestClientSocketFactory : public ClientSocketFactory {
26  public:
27   virtual ~TestClientSocketFactory();
28
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;
34
35   virtual scoped_ptr<StreamSocket> CreateTransportClientSocket(
36       const AddressList& addresses,
37       NetLog*, const NetLog::Source&) OVERRIDE {
38     NOTIMPLEMENTED();
39     return scoped_ptr<StreamSocket>();
40   }
41
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>();
49   }
50
51   virtual void ClearSSLSessionCache() OVERRIDE {
52     NOTIMPLEMENTED();
53   }
54
55  private:
56   std::list<SocketDataProvider*> data_providers_;
57 };
58
59 struct PoolEvent {
60   enum { ALLOCATE, FREE } action;
61   unsigned server_index;
62 };
63
64 class DnsSessionTest : public testing::Test {
65  public:
66   void OnSocketAllocated(unsigned server_index);
67   void OnSocketFreed(unsigned server_index);
68
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();
75
76   DnsConfig config_;
77   scoped_ptr<TestClientSocketFactory> test_client_socket_factory_;
78   scoped_refptr<DnsSession> session_;
79   NetLog::Source source_;
80
81  private:
82   bool ExpectEvent(const PoolEvent& event);
83   std::list<PoolEvent> events_;
84 };
85
86 class MockDnsSocketPool : public DnsSocketPool {
87  public:
88   MockDnsSocketPool(ClientSocketFactory* factory, DnsSessionTest* test)
89      : DnsSocketPool(factory), test_(test) { }
90
91   virtual ~MockDnsSocketPool() { }
92
93   virtual void Initialize(
94       const std::vector<IPEndPoint>* nameservers,
95       NetLog* net_log) OVERRIDE {
96     InitializeInternal(nameservers, net_log);
97   }
98
99   virtual scoped_ptr<DatagramClientSocket> AllocateSocket(
100       unsigned server_index) OVERRIDE {
101     test_->OnSocketAllocated(server_index);
102     return CreateConnectedSocket(server_index);
103   }
104
105   virtual void FreeSocket(
106       unsigned server_index,
107       scoped_ptr<DatagramClientSocket> socket) OVERRIDE {
108     test_->OnSocketFreed(server_index);
109   }
110
111  private:
112   DnsSessionTest* test_;
113 };
114
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);
125   }
126
127   test_client_socket_factory_.reset(new TestClientSocketFactory());
128
129   DnsSocketPool* dns_socket_pool =
130       new MockDnsSocketPool(test_client_socket_factory_.get(), this);
131
132   session_ = new DnsSession(config_,
133                             scoped_ptr<DnsSocketPool>(dns_socket_pool),
134                             base::Bind(&base::RandInt),
135                             NULL /* NetLog */);
136
137   events_.clear();
138 }
139
140 scoped_ptr<DnsSession::SocketLease> DnsSessionTest::Allocate(
141     unsigned server_index) {
142   return session_->AllocateSocket(server_index, source_);
143 }
144
145 bool DnsSessionTest::DidAllocate(unsigned server_index) {
146   PoolEvent expected_event = { PoolEvent::ALLOCATE, server_index };
147   return ExpectEvent(expected_event);
148 }
149
150 bool DnsSessionTest::DidFree(unsigned server_index) {
151   PoolEvent expected_event = { PoolEvent::FREE, server_index };
152   return ExpectEvent(expected_event);
153 }
154
155 bool DnsSessionTest::NoMoreEvents() {
156   return events_.empty();
157 }
158
159 void DnsSessionTest::OnSocketAllocated(unsigned server_index) {
160   PoolEvent event = { PoolEvent::ALLOCATE, server_index };
161   events_.push_back(event);
162 }
163
164 void DnsSessionTest::OnSocketFreed(unsigned server_index) {
165   PoolEvent event = { PoolEvent::FREE, server_index };
166   events_.push_back(event);
167 }
168
169 bool DnsSessionTest::ExpectEvent(const PoolEvent& expected) {
170   if (events_.empty()) {
171     return false;
172   }
173
174   const PoolEvent actual = events_.front();
175   if ((expected.action != actual.action)
176       || (expected.server_index != actual.server_index)) {
177     return false;
178   }
179   events_.pop_front();
180
181   return true;
182 }
183
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>();
198 }
199
200 TestClientSocketFactory::~TestClientSocketFactory() {
201   STLDeleteElements(&data_providers_);
202 }
203
204 TEST_F(DnsSessionTest, AllocateFree) {
205   scoped_ptr<DnsSession::SocketLease> lease1, lease2;
206
207   Initialize(2);
208   EXPECT_TRUE(NoMoreEvents());
209
210   lease1 = Allocate(0);
211   EXPECT_TRUE(DidAllocate(0));
212   EXPECT_TRUE(NoMoreEvents());
213
214   lease2 = Allocate(1);
215   EXPECT_TRUE(DidAllocate(1));
216   EXPECT_TRUE(NoMoreEvents());
217
218   lease1.reset();
219   EXPECT_TRUE(DidFree(0));
220   EXPECT_TRUE(NoMoreEvents());
221
222   lease2.reset();
223   EXPECT_TRUE(DidFree(1));
224   EXPECT_TRUE(NoMoreEvents());
225 }
226
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);
232 }
233
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);
240 }
241
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());
248 }
249
250 }  // namespace
251
252 } // namespace net