| 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 |