OLD | NEW |
| (Empty) |
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 ~TestClientSocketFactory() override; | |
28 | |
29 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 scoped_ptr<StreamSocket> CreateTransportClientSocket( | |
36 const AddressList& addresses, | |
37 NetLog*, | |
38 const NetLog::Source&) override { | |
39 NOTIMPLEMENTED(); | |
40 return scoped_ptr<StreamSocket>(); | |
41 } | |
42 | |
43 scoped_ptr<SSLClientSocket> CreateSSLClientSocket( | |
44 scoped_ptr<ClientSocketHandle> transport_socket, | |
45 const HostPortPair& host_and_port, | |
46 const SSLConfig& ssl_config, | |
47 const SSLClientSocketContext& context) override { | |
48 NOTIMPLEMENTED(); | |
49 return scoped_ptr<SSLClientSocket>(); | |
50 } | |
51 | |
52 void ClearSSLSessionCache() override { NOTIMPLEMENTED(); } | |
53 | |
54 private: | |
55 std::list<SocketDataProvider*> data_providers_; | |
56 }; | |
57 | |
58 struct PoolEvent { | |
59 enum { ALLOCATE, FREE } action; | |
60 unsigned server_index; | |
61 }; | |
62 | |
63 class DnsSessionTest : public testing::Test { | |
64 public: | |
65 void OnSocketAllocated(unsigned server_index); | |
66 void OnSocketFreed(unsigned server_index); | |
67 | |
68 protected: | |
69 void Initialize(unsigned num_servers); | |
70 scoped_ptr<DnsSession::SocketLease> Allocate(unsigned server_index); | |
71 bool DidAllocate(unsigned server_index); | |
72 bool DidFree(unsigned server_index); | |
73 bool NoMoreEvents(); | |
74 | |
75 DnsConfig config_; | |
76 scoped_ptr<TestClientSocketFactory> test_client_socket_factory_; | |
77 scoped_refptr<DnsSession> session_; | |
78 NetLog::Source source_; | |
79 | |
80 private: | |
81 bool ExpectEvent(const PoolEvent& event); | |
82 std::list<PoolEvent> events_; | |
83 }; | |
84 | |
85 class MockDnsSocketPool : public DnsSocketPool { | |
86 public: | |
87 MockDnsSocketPool(ClientSocketFactory* factory, DnsSessionTest* test) | |
88 : DnsSocketPool(factory), test_(test) { } | |
89 | |
90 ~MockDnsSocketPool() override {} | |
91 | |
92 void Initialize(const std::vector<IPEndPoint>* nameservers, | |
93 NetLog* net_log) override { | |
94 InitializeInternal(nameservers, net_log); | |
95 } | |
96 | |
97 scoped_ptr<DatagramClientSocket> AllocateSocket( | |
98 unsigned server_index) override { | |
99 test_->OnSocketAllocated(server_index); | |
100 return CreateConnectedSocket(server_index); | |
101 } | |
102 | |
103 void FreeSocket(unsigned server_index, | |
104 scoped_ptr<DatagramClientSocket> socket) override { | |
105 test_->OnSocketFreed(server_index); | |
106 } | |
107 | |
108 private: | |
109 DnsSessionTest* test_; | |
110 }; | |
111 | |
112 void DnsSessionTest::Initialize(unsigned num_servers) { | |
113 CHECK(num_servers < 256u); | |
114 config_.nameservers.clear(); | |
115 IPAddressNumber dns_ip; | |
116 bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip); | |
117 EXPECT_TRUE(rv); | |
118 for (unsigned char i = 0; i < num_servers; ++i) { | |
119 dns_ip[3] = i; | |
120 IPEndPoint dns_endpoint(dns_ip, dns_protocol::kDefaultPort); | |
121 config_.nameservers.push_back(dns_endpoint); | |
122 } | |
123 | |
124 test_client_socket_factory_.reset(new TestClientSocketFactory()); | |
125 | |
126 DnsSocketPool* dns_socket_pool = | |
127 new MockDnsSocketPool(test_client_socket_factory_.get(), this); | |
128 | |
129 session_ = new DnsSession(config_, | |
130 scoped_ptr<DnsSocketPool>(dns_socket_pool), | |
131 base::Bind(&base::RandInt), | |
132 NULL /* NetLog */); | |
133 | |
134 events_.clear(); | |
135 } | |
136 | |
137 scoped_ptr<DnsSession::SocketLease> DnsSessionTest::Allocate( | |
138 unsigned server_index) { | |
139 return session_->AllocateSocket(server_index, source_); | |
140 } | |
141 | |
142 bool DnsSessionTest::DidAllocate(unsigned server_index) { | |
143 PoolEvent expected_event = { PoolEvent::ALLOCATE, server_index }; | |
144 return ExpectEvent(expected_event); | |
145 } | |
146 | |
147 bool DnsSessionTest::DidFree(unsigned server_index) { | |
148 PoolEvent expected_event = { PoolEvent::FREE, server_index }; | |
149 return ExpectEvent(expected_event); | |
150 } | |
151 | |
152 bool DnsSessionTest::NoMoreEvents() { | |
153 return events_.empty(); | |
154 } | |
155 | |
156 void DnsSessionTest::OnSocketAllocated(unsigned server_index) { | |
157 PoolEvent event = { PoolEvent::ALLOCATE, server_index }; | |
158 events_.push_back(event); | |
159 } | |
160 | |
161 void DnsSessionTest::OnSocketFreed(unsigned server_index) { | |
162 PoolEvent event = { PoolEvent::FREE, server_index }; | |
163 events_.push_back(event); | |
164 } | |
165 | |
166 bool DnsSessionTest::ExpectEvent(const PoolEvent& expected) { | |
167 if (events_.empty()) { | |
168 return false; | |
169 } | |
170 | |
171 const PoolEvent actual = events_.front(); | |
172 if ((expected.action != actual.action) | |
173 || (expected.server_index != actual.server_index)) { | |
174 return false; | |
175 } | |
176 events_.pop_front(); | |
177 | |
178 return true; | |
179 } | |
180 | |
181 scoped_ptr<DatagramClientSocket> | |
182 TestClientSocketFactory::CreateDatagramClientSocket( | |
183 DatagramSocket::BindType bind_type, | |
184 const RandIntCallback& rand_int_cb, | |
185 net::NetLog* net_log, | |
186 const net::NetLog::Source& source) { | |
187 // We're not actually expecting to send or receive any data, so use the | |
188 // simplest SocketDataProvider with no data supplied. | |
189 SocketDataProvider* data_provider = new StaticSocketDataProvider(); | |
190 data_providers_.push_back(data_provider); | |
191 scoped_ptr<MockUDPClientSocket> socket( | |
192 new MockUDPClientSocket(data_provider, net_log)); | |
193 data_provider->set_socket(socket.get()); | |
194 return socket.Pass(); | |
195 } | |
196 | |
197 TestClientSocketFactory::~TestClientSocketFactory() { | |
198 STLDeleteElements(&data_providers_); | |
199 } | |
200 | |
201 TEST_F(DnsSessionTest, AllocateFree) { | |
202 scoped_ptr<DnsSession::SocketLease> lease1, lease2; | |
203 | |
204 Initialize(2); | |
205 EXPECT_TRUE(NoMoreEvents()); | |
206 | |
207 lease1 = Allocate(0); | |
208 EXPECT_TRUE(DidAllocate(0)); | |
209 EXPECT_TRUE(NoMoreEvents()); | |
210 | |
211 lease2 = Allocate(1); | |
212 EXPECT_TRUE(DidAllocate(1)); | |
213 EXPECT_TRUE(NoMoreEvents()); | |
214 | |
215 lease1.reset(); | |
216 EXPECT_TRUE(DidFree(0)); | |
217 EXPECT_TRUE(NoMoreEvents()); | |
218 | |
219 lease2.reset(); | |
220 EXPECT_TRUE(DidFree(1)); | |
221 EXPECT_TRUE(NoMoreEvents()); | |
222 } | |
223 | |
224 // Expect default calculated timeout to be within 10ms of in DnsConfig. | |
225 TEST_F(DnsSessionTest, HistogramTimeoutNormal) { | |
226 Initialize(2); | |
227 base::TimeDelta timeoutDelta = session_->NextTimeout(0, 0) - config_.timeout; | |
228 EXPECT_LT(timeoutDelta.InMilliseconds(), 10); | |
229 } | |
230 | |
231 // Expect short calculated timeout to be within 10ms of in DnsConfig. | |
232 TEST_F(DnsSessionTest, HistogramTimeoutShort) { | |
233 config_.timeout = base::TimeDelta::FromMilliseconds(15); | |
234 Initialize(2); | |
235 base::TimeDelta timeoutDelta = session_->NextTimeout(0, 0) - config_.timeout; | |
236 EXPECT_LT(timeoutDelta.InMilliseconds(), 10); | |
237 } | |
238 | |
239 // Expect long calculated timeout to be equal to one in DnsConfig. | |
240 TEST_F(DnsSessionTest, HistogramTimeoutLong) { | |
241 config_.timeout = base::TimeDelta::FromSeconds(15); | |
242 Initialize(2); | |
243 base::TimeDelta timeout = session_->NextTimeout(0, 0); | |
244 EXPECT_EQ(config_.timeout.InMilliseconds(), timeout.InMilliseconds()); | |
245 } | |
246 | |
247 } // namespace | |
248 | |
249 } // namespace net | |
OLD | NEW |