OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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/socket/transport_client_socket_pool_test_util.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/run_loop.h" | |
tyoshino (SeeGerritForStatus)
2014/06/24 05:46:52
include base/logging.h
Adam Rice
2014/06/24 06:28:37
Done.
| |
10 #include "net/base/ip_endpoint.h" | |
11 #include "net/base/load_timing_info.h" | |
12 #include "net/base/load_timing_info_test_util.h" | |
13 #include "net/base/net_util.h" | |
tyoshino (SeeGerritForStatus)
2014/06/24 05:46:52
include base/memory/weak_ptr.h
Adam Rice
2014/06/24 06:28:37
Done.
| |
14 #include "net/socket/client_socket_handle.h" | |
15 #include "net/socket/ssl_client_socket.h" | |
16 #include "net/udp/datagram_client_socket.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 namespace net { | |
20 | |
21 namespace { | |
22 | |
23 IPAddressNumber ParseIP(const std::string& ip) { | |
24 IPAddressNumber number; | |
25 CHECK(ParseIPLiteralToNumber(ip, &number)); | |
26 return number; | |
27 } | |
28 | |
29 // A StreamSocket which connects synchronously and successfully. | |
30 class MockConnectClientSocket : public StreamSocket { | |
31 public: | |
32 MockConnectClientSocket(const AddressList& addrlist, net::NetLog* net_log) | |
33 : connected_(false), | |
34 addrlist_(addrlist), | |
35 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {} | |
36 | |
37 // StreamSocket implementation. | |
38 virtual int Connect(const CompletionCallback& callback) OVERRIDE { | |
39 connected_ = true; | |
40 return OK; | |
41 } | |
42 virtual void Disconnect() OVERRIDE { connected_ = false; } | |
43 virtual bool IsConnected() const OVERRIDE { return connected_; } | |
44 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; } | |
45 | |
46 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { | |
47 *address = addrlist_.front(); | |
48 return OK; | |
49 } | |
50 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { | |
51 if (!connected_) | |
52 return ERR_SOCKET_NOT_CONNECTED; | |
53 if (addrlist_.front().GetFamily() == ADDRESS_FAMILY_IPV4) | |
54 SetIPv4Address(address); | |
55 else | |
56 SetIPv6Address(address); | |
57 return OK; | |
58 } | |
59 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; } | |
60 | |
61 virtual void SetSubresourceSpeculation() OVERRIDE {} | |
62 virtual void SetOmniboxSpeculation() OVERRIDE {} | |
63 virtual bool WasEverUsed() const OVERRIDE { return false; } | |
64 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } | |
65 virtual bool WasNpnNegotiated() const OVERRIDE { return false; } | |
66 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { | |
67 return kProtoUnknown; | |
68 } | |
69 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; } | |
70 | |
71 // Socket implementation. | |
72 virtual int Read(IOBuffer* buf, | |
73 int buf_len, | |
74 const CompletionCallback& callback) OVERRIDE { | |
75 return ERR_FAILED; | |
76 } | |
77 virtual int Write(IOBuffer* buf, | |
78 int buf_len, | |
79 const CompletionCallback& callback) OVERRIDE { | |
80 return ERR_FAILED; | |
81 } | |
82 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; } | |
83 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; } | |
84 | |
85 private: | |
86 bool connected_; | |
87 const AddressList addrlist_; | |
88 BoundNetLog net_log_; | |
89 | |
90 DISALLOW_COPY_AND_ASSIGN(MockConnectClientSocket); | |
91 }; | |
92 | |
93 class MockFailingClientSocket : public StreamSocket { | |
94 public: | |
95 MockFailingClientSocket(const AddressList& addrlist, net::NetLog* net_log) | |
96 : addrlist_(addrlist), | |
97 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {} | |
98 | |
99 // StreamSocket implementation. | |
100 virtual int Connect(const CompletionCallback& callback) OVERRIDE { | |
101 return ERR_CONNECTION_FAILED; | |
102 } | |
103 | |
104 virtual void Disconnect() OVERRIDE {} | |
105 | |
106 virtual bool IsConnected() const OVERRIDE { return false; } | |
107 virtual bool IsConnectedAndIdle() const OVERRIDE { return false; } | |
108 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { | |
109 return ERR_UNEXPECTED; | |
110 } | |
111 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { | |
112 return ERR_UNEXPECTED; | |
113 } | |
114 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; } | |
115 | |
116 virtual void SetSubresourceSpeculation() OVERRIDE {} | |
117 virtual void SetOmniboxSpeculation() OVERRIDE {} | |
118 virtual bool WasEverUsed() const OVERRIDE { return false; } | |
119 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } | |
120 virtual bool WasNpnNegotiated() const OVERRIDE { return false; } | |
121 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { | |
122 return kProtoUnknown; | |
123 } | |
124 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; } | |
125 | |
126 // Socket implementation. | |
127 virtual int Read(IOBuffer* buf, | |
128 int buf_len, | |
129 const CompletionCallback& callback) OVERRIDE { | |
130 return ERR_FAILED; | |
131 } | |
132 | |
133 virtual int Write(IOBuffer* buf, | |
134 int buf_len, | |
135 const CompletionCallback& callback) OVERRIDE { | |
136 return ERR_FAILED; | |
137 } | |
138 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; } | |
139 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; } | |
140 | |
141 private: | |
142 const AddressList addrlist_; | |
143 BoundNetLog net_log_; | |
144 | |
145 DISALLOW_COPY_AND_ASSIGN(MockFailingClientSocket); | |
146 }; | |
147 | |
148 class MockTriggerableClientSocket : public StreamSocket { | |
149 public: | |
150 // |should_connect| indicates whether the socket should successfully complete | |
151 // or fail. | |
152 MockTriggerableClientSocket(const AddressList& addrlist, | |
153 bool should_connect, | |
154 net::NetLog* net_log) | |
155 : should_connect_(should_connect), | |
156 is_connected_(false), | |
157 addrlist_(addrlist), | |
158 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), | |
159 weak_factory_(this) {} | |
160 | |
161 // Call this method to get a closure which will trigger the connect callback | |
162 // when called. The closure can be called even after the socket is deleted; it | |
163 // will safely do nothing. | |
164 base::Closure GetConnectCallback() { | |
165 return base::Bind(&MockTriggerableClientSocket::DoCallback, | |
166 weak_factory_.GetWeakPtr()); | |
167 } | |
168 | |
169 static scoped_ptr<StreamSocket> MakeMockPendingClientSocket( | |
170 const AddressList& addrlist, | |
171 bool should_connect, | |
172 net::NetLog* net_log) { | |
173 scoped_ptr<MockTriggerableClientSocket> socket( | |
174 new MockTriggerableClientSocket(addrlist, should_connect, net_log)); | |
175 base::MessageLoop::current()->PostTask(FROM_HERE, | |
176 socket->GetConnectCallback()); | |
177 return socket.PassAs<StreamSocket>(); | |
178 } | |
179 | |
180 static scoped_ptr<StreamSocket> MakeMockDelayedClientSocket( | |
181 const AddressList& addrlist, | |
182 bool should_connect, | |
183 const base::TimeDelta& delay, | |
184 net::NetLog* net_log) { | |
185 scoped_ptr<MockTriggerableClientSocket> socket( | |
186 new MockTriggerableClientSocket(addrlist, should_connect, net_log)); | |
187 base::MessageLoop::current()->PostDelayedTask( | |
188 FROM_HERE, socket->GetConnectCallback(), delay); | |
189 return socket.PassAs<StreamSocket>(); | |
190 } | |
191 | |
192 static scoped_ptr<StreamSocket> MakeMockStalledClientSocket( | |
193 const AddressList& addrlist, | |
194 net::NetLog* net_log) { | |
195 scoped_ptr<MockTriggerableClientSocket> socket( | |
196 new MockTriggerableClientSocket(addrlist, true, net_log)); | |
197 return socket.PassAs<StreamSocket>(); | |
198 } | |
199 | |
200 // StreamSocket implementation. | |
201 virtual int Connect(const CompletionCallback& callback) OVERRIDE { | |
202 DCHECK(callback_.is_null()); | |
203 callback_ = callback; | |
204 return ERR_IO_PENDING; | |
205 } | |
206 | |
207 virtual void Disconnect() OVERRIDE {} | |
208 | |
209 virtual bool IsConnected() const OVERRIDE { return is_connected_; } | |
210 virtual bool IsConnectedAndIdle() const OVERRIDE { return is_connected_; } | |
211 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE { | |
212 *address = addrlist_.front(); | |
213 return OK; | |
214 } | |
215 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE { | |
216 if (!is_connected_) | |
217 return ERR_SOCKET_NOT_CONNECTED; | |
218 if (addrlist_.front().GetFamily() == ADDRESS_FAMILY_IPV4) | |
219 SetIPv4Address(address); | |
220 else | |
221 SetIPv6Address(address); | |
222 return OK; | |
223 } | |
224 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; } | |
225 | |
226 virtual void SetSubresourceSpeculation() OVERRIDE {} | |
227 virtual void SetOmniboxSpeculation() OVERRIDE {} | |
228 virtual bool WasEverUsed() const OVERRIDE { return false; } | |
229 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } | |
230 virtual bool WasNpnNegotiated() const OVERRIDE { return false; } | |
231 virtual NextProto GetNegotiatedProtocol() const OVERRIDE { | |
232 return kProtoUnknown; | |
233 } | |
234 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; } | |
235 | |
236 // Socket implementation. | |
237 virtual int Read(IOBuffer* buf, | |
238 int buf_len, | |
239 const CompletionCallback& callback) OVERRIDE { | |
240 return ERR_FAILED; | |
241 } | |
242 | |
243 virtual int Write(IOBuffer* buf, | |
244 int buf_len, | |
245 const CompletionCallback& callback) OVERRIDE { | |
246 return ERR_FAILED; | |
247 } | |
248 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; } | |
249 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; } | |
250 | |
251 private: | |
252 void DoCallback() { | |
253 is_connected_ = should_connect_; | |
254 callback_.Run(is_connected_ ? OK : ERR_CONNECTION_FAILED); | |
255 } | |
256 | |
257 bool should_connect_; | |
258 bool is_connected_; | |
259 const AddressList addrlist_; | |
260 BoundNetLog net_log_; | |
261 CompletionCallback callback_; | |
262 | |
263 base::WeakPtrFactory<MockTriggerableClientSocket> weak_factory_; | |
264 | |
265 DISALLOW_COPY_AND_ASSIGN(MockTriggerableClientSocket); | |
266 }; | |
267 | |
268 } // namespace | |
269 | |
270 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) { | |
271 LoadTimingInfo load_timing_info; | |
272 // Only pass true in as |is_reused|, as in general, HttpStream types should | |
273 // have stricter concepts of reuse than socket pools. | |
274 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info)); | |
275 | |
276 EXPECT_TRUE(load_timing_info.socket_reused); | |
277 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
278 | |
279 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); | |
280 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); | |
281 } | |
282 | |
283 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) { | |
284 EXPECT_FALSE(handle.is_reused()); | |
285 | |
286 LoadTimingInfo load_timing_info; | |
287 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info)); | |
288 | |
289 EXPECT_FALSE(load_timing_info.socket_reused); | |
290 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); | |
291 | |
292 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, | |
293 CONNECT_TIMING_HAS_DNS_TIMES); | |
294 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); | |
295 | |
296 TestLoadTimingInfoConnectedReused(handle); | |
297 } | |
298 | |
299 void SetIPv4Address(IPEndPoint* address) { | |
300 *address = IPEndPoint(ParseIP("1.1.1.1"), 80); | |
301 } | |
302 | |
303 void SetIPv6Address(IPEndPoint* address) { | |
304 *address = IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80); | |
305 } | |
306 | |
307 MockTransportClientSocketFactory::MockTransportClientSocketFactory( | |
308 NetLog* net_log) | |
309 : net_log_(net_log), | |
310 allocation_count_(0), | |
311 client_socket_type_(MOCK_CLIENT_SOCKET), | |
312 client_socket_types_(NULL), | |
313 client_socket_index_(0), | |
314 client_socket_index_max_(0), | |
315 delay_(base::TimeDelta::FromMilliseconds( | |
316 ClientSocketPool::kMaxConnectRetryIntervalMs)) {} | |
317 | |
318 MockTransportClientSocketFactory::~MockTransportClientSocketFactory() {} | |
319 | |
320 scoped_ptr<DatagramClientSocket> | |
321 MockTransportClientSocketFactory::CreateDatagramClientSocket( | |
322 DatagramSocket::BindType bind_type, | |
323 const RandIntCallback& rand_int_cb, | |
324 NetLog* net_log, | |
325 const NetLog::Source& source) { | |
326 NOTREACHED(); | |
327 return scoped_ptr<DatagramClientSocket>(); | |
328 } | |
329 | |
330 scoped_ptr<StreamSocket> | |
331 MockTransportClientSocketFactory::CreateTransportClientSocket( | |
332 const AddressList& addresses, | |
333 NetLog* /* net_log */, | |
334 const NetLog::Source& /* source */) { | |
335 allocation_count_++; | |
336 | |
337 ClientSocketType type = client_socket_type_; | |
338 if (client_socket_types_ && client_socket_index_ < client_socket_index_max_) { | |
339 type = client_socket_types_[client_socket_index_++]; | |
340 } | |
341 | |
342 switch (type) { | |
343 case MOCK_CLIENT_SOCKET: | |
344 return scoped_ptr<StreamSocket>( | |
345 new MockConnectClientSocket(addresses, net_log_)); | |
346 case MOCK_FAILING_CLIENT_SOCKET: | |
347 return scoped_ptr<StreamSocket>( | |
348 new MockFailingClientSocket(addresses, net_log_)); | |
349 case MOCK_PENDING_CLIENT_SOCKET: | |
350 return MockTriggerableClientSocket::MakeMockPendingClientSocket( | |
351 addresses, true, net_log_); | |
352 case MOCK_PENDING_FAILING_CLIENT_SOCKET: | |
353 return MockTriggerableClientSocket::MakeMockPendingClientSocket( | |
354 addresses, false, net_log_); | |
355 case MOCK_DELAYED_CLIENT_SOCKET: | |
356 return MockTriggerableClientSocket::MakeMockDelayedClientSocket( | |
357 addresses, true, delay_, net_log_); | |
358 case MOCK_DELAYED_FAILING_CLIENT_SOCKET: | |
359 return MockTriggerableClientSocket::MakeMockDelayedClientSocket( | |
360 addresses, false, delay_, net_log_); | |
361 case MOCK_STALLED_CLIENT_SOCKET: | |
362 return MockTriggerableClientSocket::MakeMockStalledClientSocket(addresses, | |
363 net_log_); | |
364 case MOCK_TRIGGERABLE_CLIENT_SOCKET: { | |
365 scoped_ptr<MockTriggerableClientSocket> rv( | |
366 new MockTriggerableClientSocket(addresses, true, net_log_)); | |
367 triggerable_sockets_.push(rv->GetConnectCallback()); | |
368 // run_loop_quit_closure_ behaves like a condition variable. It will | |
369 // wake up WaitForTriggerableSocketCreation() if it is sleeping. We | |
370 // don't need to worry about atomicity because this code is | |
371 // single-threaded. | |
372 if (!run_loop_quit_closure_.is_null()) | |
373 run_loop_quit_closure_.Run(); | |
374 return rv.PassAs<StreamSocket>(); | |
375 } | |
376 default: | |
377 NOTREACHED(); | |
378 return scoped_ptr<StreamSocket>( | |
379 new MockConnectClientSocket(addresses, net_log_)); | |
380 } | |
381 } | |
382 | |
383 scoped_ptr<SSLClientSocket> | |
384 MockTransportClientSocketFactory::CreateSSLClientSocket( | |
385 scoped_ptr<ClientSocketHandle> transport_socket, | |
386 const HostPortPair& host_and_port, | |
387 const SSLConfig& ssl_config, | |
388 const SSLClientSocketContext& context) { | |
389 NOTIMPLEMENTED(); | |
390 return scoped_ptr<SSLClientSocket>(); | |
391 } | |
392 | |
393 void MockTransportClientSocketFactory::ClearSSLSessionCache() { | |
394 NOTIMPLEMENTED(); | |
395 } | |
396 | |
397 void MockTransportClientSocketFactory::set_client_socket_types( | |
398 ClientSocketType* type_list, | |
399 int num_types) { | |
400 DCHECK_GT(num_types, 0); | |
401 client_socket_types_ = type_list; | |
402 client_socket_index_ = 0; | |
403 client_socket_index_max_ = num_types; | |
404 } | |
405 | |
406 base::Closure | |
407 MockTransportClientSocketFactory::WaitForTriggerableSocketCreation() { | |
408 while (triggerable_sockets_.empty()) { | |
409 base::RunLoop run_loop; | |
410 run_loop_quit_closure_ = run_loop.QuitClosure(); | |
411 run_loop.Run(); | |
412 run_loop_quit_closure_.Reset(); | |
413 } | |
414 base::Closure trigger = triggerable_sockets_.front(); | |
415 triggerable_sockets_.pop(); | |
416 return trigger; | |
417 } | |
418 | |
419 } // namespace net | |
OLD | NEW |