| 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 "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 namespace net { |
| 20 |
| 21 namespace { |
| 22 |
| 23 class TestClientSocketFactory : public ClientSocketFactory { |
| 24 public: |
| 25 virtual ~TestClientSocketFactory(); |
| 26 |
| 27 virtual DatagramClientSocket* CreateDatagramClientSocket( |
| 28 DatagramSocket::BindType bind_type, |
| 29 const RandIntCallback& rand_int_cb, |
| 30 net::NetLog* net_log, |
| 31 const net::NetLog::Source& source) OVERRIDE; |
| 32 |
| 33 virtual StreamSocket* CreateTransportClientSocket( |
| 34 const AddressList& addresses, |
| 35 NetLog*, const NetLog::Source&) OVERRIDE { |
| 36 NOTIMPLEMENTED(); |
| 37 return NULL; |
| 38 } |
| 39 |
| 40 virtual SSLClientSocket* CreateSSLClientSocket( |
| 41 ClientSocketHandle* transport_socket, |
| 42 const HostPortPair& host_and_port, |
| 43 const SSLConfig& ssl_config, |
| 44 const SSLClientSocketContext& context) OVERRIDE { |
| 45 NOTIMPLEMENTED(); |
| 46 return NULL; |
| 47 } |
| 48 |
| 49 virtual void ClearSSLSessionCache() OVERRIDE { |
| 50 NOTIMPLEMENTED(); |
| 51 } |
| 52 |
| 53 private: |
| 54 std::list<SocketDataProvider*> data_providers_; |
| 55 }; |
| 56 |
| 57 struct PoolEvent { |
| 58 enum { ALLOCATE, FREE } action; |
| 59 unsigned server_index; |
| 60 }; |
| 61 |
| 62 class DnsSessionTest : public testing::Test { |
| 63 public: |
| 64 void OnSocketAllocated(unsigned server_index); |
| 65 void OnSocketFreed(unsigned server_index); |
| 66 |
| 67 protected: |
| 68 void Initialize(unsigned num_servers); |
| 69 scoped_ptr<DnsSession::SocketLease> Allocate(unsigned server_index); |
| 70 bool DidAllocate(unsigned server_index); |
| 71 bool DidFree(unsigned server_index); |
| 72 bool NoMoreEvents(); |
| 73 |
| 74 DnsConfig config_; |
| 75 scoped_ptr<TestClientSocketFactory> test_client_socket_factory_; |
| 76 scoped_refptr<DnsSession> session_; |
| 77 NetLog::Source source_; |
| 78 |
| 79 private: |
| 80 bool ExpectEvent(const PoolEvent& event); |
| 81 std::list<PoolEvent> events_; |
| 82 }; |
| 83 |
| 84 class MockDnsSocketPool : public DnsSocketPool { |
| 85 public: |
| 86 MockDnsSocketPool(ClientSocketFactory* factory, DnsSessionTest* test) |
| 87 : DnsSocketPool(factory), test_(test) { } |
| 88 |
| 89 virtual ~MockDnsSocketPool() { } |
| 90 |
| 91 virtual void Initialize( |
| 92 const std::vector<IPEndPoint>* nameservers, |
| 93 NetLog* net_log) OVERRIDE { |
| 94 InitializeInternal(nameservers, net_log); |
| 95 } |
| 96 |
| 97 virtual scoped_ptr<DatagramClientSocket> AllocateSocket( |
| 98 unsigned server_index) OVERRIDE { |
| 99 test_->OnSocketAllocated(server_index); |
| 100 return CreateConnectedSocket(server_index); |
| 101 } |
| 102 |
| 103 virtual void FreeSocket( |
| 104 unsigned server_index, |
| 105 scoped_ptr<DatagramClientSocket> socket) OVERRIDE { |
| 106 test_->OnSocketFreed(server_index); |
| 107 } |
| 108 |
| 109 private: |
| 110 DnsSessionTest* test_; |
| 111 }; |
| 112 |
| 113 void DnsSessionTest::Initialize(unsigned num_servers) { |
| 114 CHECK(num_servers < 256u); |
| 115 config_.nameservers.clear(); |
| 116 IPAddressNumber dns_ip; |
| 117 bool rv = ParseIPLiteralToNumber("192.168.1.0", &dns_ip); |
| 118 EXPECT_TRUE(rv); |
| 119 for (unsigned char i = 0; i < num_servers; ++i) { |
| 120 dns_ip[3] = i; |
| 121 IPEndPoint dns_endpoint(dns_ip, dns_protocol::kDefaultPort); |
| 122 config_.nameservers.push_back(dns_endpoint); |
| 123 } |
| 124 |
| 125 test_client_socket_factory_.reset(new TestClientSocketFactory()); |
| 126 |
| 127 DnsSocketPool* dns_socket_pool = |
| 128 new MockDnsSocketPool(test_client_socket_factory_.get(), this); |
| 129 |
| 130 session_ = new DnsSession(config_, |
| 131 scoped_ptr<DnsSocketPool>(dns_socket_pool), |
| 132 base::Bind(&base::RandInt), |
| 133 NULL /* NetLog */); |
| 134 |
| 135 events_.clear(); |
| 136 } |
| 137 |
| 138 scoped_ptr<DnsSession::SocketLease> DnsSessionTest::Allocate( |
| 139 unsigned server_index) { |
| 140 return session_->AllocateSocket(server_index, source_); |
| 141 } |
| 142 |
| 143 bool DnsSessionTest::DidAllocate(unsigned server_index) { |
| 144 PoolEvent expected_event = { PoolEvent::ALLOCATE, server_index }; |
| 145 return ExpectEvent(expected_event); |
| 146 } |
| 147 |
| 148 bool DnsSessionTest::DidFree(unsigned server_index) { |
| 149 PoolEvent expected_event = { PoolEvent::FREE, server_index }; |
| 150 return ExpectEvent(expected_event); |
| 151 } |
| 152 |
| 153 bool DnsSessionTest::NoMoreEvents() { |
| 154 return events_.empty(); |
| 155 } |
| 156 |
| 157 void DnsSessionTest::OnSocketAllocated(unsigned server_index) { |
| 158 PoolEvent event = { PoolEvent::ALLOCATE, server_index }; |
| 159 events_.push_back(event); |
| 160 } |
| 161 |
| 162 void DnsSessionTest::OnSocketFreed(unsigned server_index) { |
| 163 PoolEvent event = { PoolEvent::FREE, server_index }; |
| 164 events_.push_back(event); |
| 165 } |
| 166 |
| 167 bool DnsSessionTest::ExpectEvent(const PoolEvent& expected) { |
| 168 if (events_.empty()) { |
| 169 return false; |
| 170 } |
| 171 |
| 172 const PoolEvent actual = events_.front(); |
| 173 if ((expected.action != actual.action) |
| 174 || (expected.server_index != actual.server_index)) { |
| 175 return false; |
| 176 } |
| 177 events_.pop_front(); |
| 178 |
| 179 return true; |
| 180 } |
| 181 |
| 182 DatagramClientSocket* 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 MockUDPClientSocket* socket = new MockUDPClientSocket(data_provider, net_log); |
| 192 data_provider->set_socket(socket); |
| 193 return socket; |
| 194 } |
| 195 |
| 196 TestClientSocketFactory::~TestClientSocketFactory() { |
| 197 STLDeleteElements(&data_providers_); |
| 198 } |
| 199 |
| 200 TEST_F(DnsSessionTest, AllocateFree) { |
| 201 scoped_ptr<DnsSession::SocketLease> lease1, lease2; |
| 202 |
| 203 Initialize(2); |
| 204 EXPECT_TRUE(NoMoreEvents()); |
| 205 |
| 206 lease1 = Allocate(0); |
| 207 EXPECT_TRUE(DidAllocate(0)); |
| 208 EXPECT_TRUE(NoMoreEvents()); |
| 209 |
| 210 lease2 = Allocate(1); |
| 211 EXPECT_TRUE(DidAllocate(1)); |
| 212 EXPECT_TRUE(NoMoreEvents()); |
| 213 |
| 214 lease1.reset(); |
| 215 EXPECT_TRUE(DidFree(0)); |
| 216 EXPECT_TRUE(NoMoreEvents()); |
| 217 |
| 218 lease2.reset(); |
| 219 EXPECT_TRUE(DidFree(1)); |
| 220 EXPECT_TRUE(NoMoreEvents()); |
| 221 } |
| 222 |
| 223 } // namespace |
| 224 |
| 225 } // namespace net |
| OLD | NEW |