Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: net/socket/websocket_transport_client_socket_pool_unittest.cc

Issue 240873003: Create WebSocketTransportClientSocketPool (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Changes from tyoshino review. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
tyoshino (SeeGerritForStatus) 2014/06/11 08:22:22 2014
Adam Rice 2014/06/11 08:28:27 Done.
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/websocket_transport_client_socket_pool.h"
6
7 #include <queue>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/macros.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/run_loop.h"
17 #include "base/threading/platform_thread.h"
18 #include "net/base/capturing_net_log.h"
19 #include "net/base/ip_endpoint.h"
20 #include "net/base/load_timing_info.h"
21 #include "net/base/load_timing_info_test_util.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/net_util.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/dns/mock_host_resolver.h"
26 #include "net/socket/client_socket_factory.h"
27 #include "net/socket/client_socket_handle.h"
28 #include "net/socket/client_socket_pool_histograms.h"
29 #include "net/socket/socket_test_util.h"
30 #include "net/socket/ssl_client_socket.h"
31 #include "net/socket/stream_socket.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33
34 namespace net {
35
36 using internal::ClientSocketPoolBaseHelper;
37
38 namespace {
39
40 const int kMaxSockets = 32;
41 const int kMaxSocketsPerGroup = 6;
42 const net::RequestPriority kDefaultPriority = LOW;
43
44 // Make sure |handle| sets load times correctly when it has been assigned a
45 // reused socket.
46 void TestLoadTimingInfoConnectedReused(const ClientSocketHandle& handle) {
47 LoadTimingInfo load_timing_info;
48 // Only pass true in as |is_reused|, as in general, HttpStream types should
49 // have stricter concepts of reuse than socket pools.
50 EXPECT_TRUE(handle.GetLoadTimingInfo(true, &load_timing_info));
51
52 EXPECT_TRUE(load_timing_info.socket_reused);
53 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
54
55 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
56 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
57 }
58
59 // Make sure |handle| sets load times correctly when it has been assigned a
60 // fresh socket. Also runs TestLoadTimingInfoConnectedReused, since the owner
61 // of a connection where |is_reused| is false may consider the connection
62 // reused.
63 void TestLoadTimingInfoConnectedNotReused(const ClientSocketHandle& handle) {
64 EXPECT_FALSE(handle.is_reused());
65
66 LoadTimingInfo load_timing_info;
67 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));
68
69 EXPECT_FALSE(load_timing_info.socket_reused);
70 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
71
72 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
73 CONNECT_TIMING_HAS_DNS_TIMES);
74 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
75
76 TestLoadTimingInfoConnectedReused(handle);
77 }
78
79 void SetIPv4Address(IPEndPoint* address) {
80 IPAddressNumber number;
81 CHECK(ParseIPLiteralToNumber("1.1.1.1", &number));
82 *address = IPEndPoint(number, 80);
83 }
84
85 void SetIPv6Address(IPEndPoint* address) {
86 IPAddressNumber number;
87 CHECK(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
88 *address = IPEndPoint(number, 80);
89 }
90
91 class MockClientSocket : public StreamSocket {
92 public:
93 MockClientSocket(const AddressList& addrlist, net::NetLog* net_log)
94 : connected_(false),
95 addrlist_(addrlist),
96 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {}
97
98 // StreamSocket implementation.
99 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
100 connected_ = true;
101 return OK;
102 }
103 virtual void Disconnect() OVERRIDE { connected_ = false; }
104 virtual bool IsConnected() const OVERRIDE { return connected_; }
105 virtual bool IsConnectedAndIdle() const OVERRIDE { return connected_; }
106 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE {
107 *address = addrlist_.front();
108 return OK;
109 }
110 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE {
111 if (!connected_)
112 return ERR_SOCKET_NOT_CONNECTED;
113 if (addrlist_.front().GetFamily() == ADDRESS_FAMILY_IPV4)
114 SetIPv4Address(address);
115 else
116 SetIPv6Address(address);
117 return OK;
118 }
119 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; }
120
121 virtual void SetSubresourceSpeculation() OVERRIDE {}
122 virtual void SetOmniboxSpeculation() OVERRIDE {}
123 virtual bool WasEverUsed() const OVERRIDE { return false; }
124 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; }
125 virtual bool WasNpnNegotiated() const OVERRIDE { return false; }
126 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
127 return kProtoUnknown;
128 }
129 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; }
130
131 // Socket implementation.
132 virtual int Read(IOBuffer* buf,
133 int buf_len,
134 const CompletionCallback& callback) OVERRIDE {
135 return ERR_FAILED;
136 }
137 virtual int Write(IOBuffer* buf,
138 int buf_len,
139 const CompletionCallback& callback) OVERRIDE {
140 return ERR_FAILED;
141 }
142 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; }
143 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; }
144
145 private:
146 bool connected_;
147 const AddressList addrlist_;
148 BoundNetLog net_log_;
149
150 DISALLOW_COPY_AND_ASSIGN(MockClientSocket);
151 };
152
153 class MockFailingClientSocket : public StreamSocket {
154 public:
155 MockFailingClientSocket(const AddressList& addrlist, net::NetLog* net_log)
156 : addrlist_(addrlist),
157 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {}
158
159 // StreamSocket implementation.
160 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
161 return ERR_CONNECTION_FAILED;
162 }
163
164 virtual void Disconnect() OVERRIDE {}
165
166 virtual bool IsConnected() const OVERRIDE { return false; }
167 virtual bool IsConnectedAndIdle() const OVERRIDE { return false; }
168 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE {
169 return ERR_UNEXPECTED;
170 }
171 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE {
172 return ERR_UNEXPECTED;
173 }
174 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; }
175
176 virtual void SetSubresourceSpeculation() OVERRIDE {}
177 virtual void SetOmniboxSpeculation() OVERRIDE {}
178 virtual bool WasEverUsed() const OVERRIDE { return false; }
179 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; }
180 virtual bool WasNpnNegotiated() const OVERRIDE { return false; }
181 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
182 return kProtoUnknown;
183 }
184 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; }
185
186 // Socket implementation.
187 virtual int Read(IOBuffer* buf,
188 int buf_len,
189 const CompletionCallback& callback) OVERRIDE {
190 return ERR_FAILED;
191 }
192
193 virtual int Write(IOBuffer* buf,
194 int buf_len,
195 const CompletionCallback& callback) OVERRIDE {
196 return ERR_FAILED;
197 }
198 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; }
199 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; }
200
201 private:
202 const AddressList addrlist_;
203 BoundNetLog net_log_;
204
205 DISALLOW_COPY_AND_ASSIGN(MockFailingClientSocket);
206 };
207
208 class MockTriggerableClientSocket : public StreamSocket {
209 public:
210 // |should_connect| indicates whether the socket should successfully complete
211 // or fail.
212 MockTriggerableClientSocket(const AddressList& addrlist,
213 bool should_connect,
214 net::NetLog* net_log)
215 : should_connect_(should_connect),
216 is_connected_(false),
217 addrlist_(addrlist),
218 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)),
219 weak_factory_(this) {}
220
221 // Call this method to get a closure which will trigger the connect callback
222 // when called. The closure can be called even after the socket is deleted; it
223 // will safely do nothing.
224 base::Closure GetConnectCallback() {
225 return base::Bind(&MockTriggerableClientSocket::DoCallback,
226 weak_factory_.GetWeakPtr());
227 }
228
229 static scoped_ptr<StreamSocket> MakeMockPendingClientSocket(
230 const AddressList& addrlist,
231 bool should_connect,
232 net::NetLog* net_log) {
233 scoped_ptr<MockTriggerableClientSocket> socket(
234 new MockTriggerableClientSocket(addrlist, should_connect, net_log));
235 base::MessageLoop::current()->PostTask(FROM_HERE,
236 socket->GetConnectCallback());
237 return socket.PassAs<StreamSocket>();
238 }
239
240 static scoped_ptr<StreamSocket> MakeMockDelayedClientSocket(
241 const AddressList& addrlist,
242 bool should_connect,
243 const base::TimeDelta& delay,
244 net::NetLog* net_log) {
245 scoped_ptr<MockTriggerableClientSocket> socket(
246 new MockTriggerableClientSocket(addrlist, should_connect, net_log));
247 base::MessageLoop::current()->PostDelayedTask(
248 FROM_HERE, socket->GetConnectCallback(), delay);
249 return socket.PassAs<StreamSocket>();
250 }
251
252 static scoped_ptr<StreamSocket> MakeMockStalledClientSocket(
253 const AddressList& addrlist,
254 net::NetLog* net_log) {
255 scoped_ptr<MockTriggerableClientSocket> socket(
256 new MockTriggerableClientSocket(addrlist, true, net_log));
257 return socket.PassAs<StreamSocket>();
258 }
259
260 // StreamSocket implementation.
261 virtual int Connect(const CompletionCallback& callback) OVERRIDE {
262 DCHECK(callback_.is_null());
263 callback_ = callback;
264 return ERR_IO_PENDING;
265 }
266
267 virtual void Disconnect() OVERRIDE {}
268
269 virtual bool IsConnected() const OVERRIDE { return is_connected_; }
270 virtual bool IsConnectedAndIdle() const OVERRIDE { return is_connected_; }
271 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE {
272 *address = addrlist_.front();
273 return OK;
274 }
275 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE {
276 if (!is_connected_)
277 return ERR_SOCKET_NOT_CONNECTED;
278 if (addrlist_.front().GetFamily() == ADDRESS_FAMILY_IPV4)
279 SetIPv4Address(address);
280 else
281 SetIPv6Address(address);
282 return OK;
283 }
284 virtual const BoundNetLog& NetLog() const OVERRIDE { return net_log_; }
285
286 virtual void SetSubresourceSpeculation() OVERRIDE {}
287 virtual void SetOmniboxSpeculation() OVERRIDE {}
288 virtual bool WasEverUsed() const OVERRIDE { return false; }
289 virtual bool UsingTCPFastOpen() const OVERRIDE { return false; }
290 virtual bool WasNpnNegotiated() const OVERRIDE { return false; }
291 virtual NextProto GetNegotiatedProtocol() const OVERRIDE {
292 return kProtoUnknown;
293 }
294 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE { return false; }
295
296 // Socket implementation.
297 virtual int Read(IOBuffer* buf,
298 int buf_len,
299 const CompletionCallback& callback) OVERRIDE {
300 return ERR_FAILED;
301 }
302
303 virtual int Write(IOBuffer* buf,
304 int buf_len,
305 const CompletionCallback& callback) OVERRIDE {
306 return ERR_FAILED;
307 }
308 virtual int SetReceiveBufferSize(int32 size) OVERRIDE { return OK; }
309 virtual int SetSendBufferSize(int32 size) OVERRIDE { return OK; }
310
311 private:
312 void DoCallback() {
313 is_connected_ = should_connect_;
314 callback_.Run(is_connected_ ? OK : ERR_CONNECTION_FAILED);
315 }
316
317 bool should_connect_;
318 bool is_connected_;
319 const AddressList addrlist_;
320 BoundNetLog net_log_;
321 CompletionCallback callback_;
322
323 base::WeakPtrFactory<MockTriggerableClientSocket> weak_factory_;
324
325 DISALLOW_COPY_AND_ASSIGN(MockTriggerableClientSocket);
326 };
327
328 class MockClientSocketFactory : public ClientSocketFactory {
329 public:
330 enum ClientSocketType {
331 MOCK_CLIENT_SOCKET,
332 MOCK_FAILING_CLIENT_SOCKET,
333 MOCK_PENDING_CLIENT_SOCKET,
334 MOCK_PENDING_FAILING_CLIENT_SOCKET,
335 // A delayed socket will pause before connecting through the message loop.
336 MOCK_DELAYED_CLIENT_SOCKET,
337 // A delayed socket that fails.
338 MOCK_DELAYED_FAILING_CLIENT_SOCKET,
339 // A stalled socket that never connects at all.
340 MOCK_STALLED_CLIENT_SOCKET,
341 // A socket that can be triggered to connect explicitly.
342 MOCK_TRIGGERABLE_CLIENT_SOCKET,
343 };
344
345 explicit MockClientSocketFactory(NetLog* net_log)
346 : net_log_(net_log),
347 allocation_count_(0),
348 client_socket_type_(MOCK_CLIENT_SOCKET),
349 client_socket_types_(NULL),
350 client_socket_index_(0),
351 client_socket_index_max_(0),
352 delay_(base::TimeDelta::FromMilliseconds(
353 ClientSocketPool::kMaxConnectRetryIntervalMs)) {}
354
355 virtual scoped_ptr<DatagramClientSocket> CreateDatagramClientSocket(
356 DatagramSocket::BindType bind_type,
357 const RandIntCallback& rand_int_cb,
358 NetLog* net_log,
359 const NetLog::Source& source) OVERRIDE {
360 NOTREACHED();
361 return scoped_ptr<DatagramClientSocket>();
362 }
363
364 virtual scoped_ptr<StreamSocket> CreateTransportClientSocket(
365 const AddressList& addresses,
366 NetLog* /* net_log */,
367 const NetLog::Source& /* source */) OVERRIDE {
368 allocation_count_++;
369
370 ClientSocketType type = client_socket_type_;
371 if (client_socket_types_ &&
372 client_socket_index_ < client_socket_index_max_) {
373 type = client_socket_types_[client_socket_index_++];
374 }
375
376 switch (type) {
377 case MOCK_CLIENT_SOCKET:
378 return scoped_ptr<StreamSocket>(
379 new MockClientSocket(addresses, net_log_));
380 case MOCK_FAILING_CLIENT_SOCKET:
381 return scoped_ptr<StreamSocket>(
382 new MockFailingClientSocket(addresses, net_log_));
383 case MOCK_PENDING_CLIENT_SOCKET:
384 return MockTriggerableClientSocket::MakeMockPendingClientSocket(
385 addresses, true, net_log_);
386 case MOCK_PENDING_FAILING_CLIENT_SOCKET:
387 return MockTriggerableClientSocket::MakeMockPendingClientSocket(
388 addresses, false, net_log_);
389 case MOCK_DELAYED_CLIENT_SOCKET:
390 return MockTriggerableClientSocket::MakeMockDelayedClientSocket(
391 addresses, true, delay_, net_log_);
392 case MOCK_DELAYED_FAILING_CLIENT_SOCKET:
393 return MockTriggerableClientSocket::MakeMockDelayedClientSocket(
394 addresses, false, delay_, net_log_);
395 case MOCK_STALLED_CLIENT_SOCKET:
396 return MockTriggerableClientSocket::MakeMockStalledClientSocket(
397 addresses, net_log_);
398 case MOCK_TRIGGERABLE_CLIENT_SOCKET: {
399 scoped_ptr<MockTriggerableClientSocket> rv(
400 new MockTriggerableClientSocket(addresses, true, net_log_));
401 triggerable_sockets_.push(rv->GetConnectCallback());
402 // run_loop_quit_closure_ behaves like a condition variable. It will
403 // wake up WaitForTriggerableSocketCreation() if it is sleeping. We
404 // don't need to worry about atomicity because this code is
405 // single-threaded.
406 if (!run_loop_quit_closure_.is_null())
407 run_loop_quit_closure_.Run();
408 return rv.PassAs<StreamSocket>();
409 }
410 default:
411 NOTREACHED();
412 return scoped_ptr<StreamSocket>(
413 new MockClientSocket(addresses, net_log_));
414 }
415 }
416
417 virtual scoped_ptr<SSLClientSocket> CreateSSLClientSocket(
418 scoped_ptr<ClientSocketHandle> transport_socket,
419 const HostPortPair& host_and_port,
420 const SSLConfig& ssl_config,
421 const SSLClientSocketContext& context) OVERRIDE {
422 NOTIMPLEMENTED();
423 return scoped_ptr<SSLClientSocket>();
424 }
425
426 virtual void ClearSSLSessionCache() OVERRIDE { NOTIMPLEMENTED(); }
427
428 int allocation_count() const { return allocation_count_; }
429
430 // Set the default ClientSocketType.
431 void set_client_socket_type(ClientSocketType type) {
432 client_socket_type_ = type;
433 }
434
435 // Set a list of ClientSocketTypes to be used.
436 void set_client_socket_types(ClientSocketType* type_list, int num_types) {
437 DCHECK_GT(num_types, 0);
438 client_socket_types_ = type_list;
439 client_socket_index_ = 0;
440 client_socket_index_max_ = num_types;
441 }
442
443 void set_delay(base::TimeDelta delay) { delay_ = delay; }
444
445 base::Closure WaitForTriggerableSocketCreation() {
446 while (triggerable_sockets_.empty()) {
447 base::RunLoop run_loop;
448 run_loop_quit_closure_ = run_loop.QuitClosure();
449 run_loop.Run();
450 run_loop_quit_closure_.Reset();
451 }
452 base::Closure trigger = triggerable_sockets_.front();
453 triggerable_sockets_.pop();
454 return trigger;
455 }
456
457 private:
458 NetLog* net_log_;
459 int allocation_count_;
460 ClientSocketType client_socket_type_;
461 ClientSocketType* client_socket_types_;
462 int client_socket_index_;
463 int client_socket_index_max_;
464 base::TimeDelta delay_;
465 std::queue<base::Closure> triggerable_sockets_;
466 base::Closure run_loop_quit_closure_;
467
468 DISALLOW_COPY_AND_ASSIGN(MockClientSocketFactory);
469 };
470
471 class WebSocketTransportClientSocketPoolTest : public testing::Test {
472 protected:
473 WebSocketTransportClientSocketPoolTest()
474 : params_(new TransportSocketParams(HostPortPair("www.google.com", 80),
475 false,
476 false,
477 OnHostResolutionCallback())),
478 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
479 host_resolver_(new MockHostResolver),
480 client_socket_factory_(&net_log_),
481 pool_(kMaxSockets,
482 kMaxSocketsPerGroup,
483 histograms_.get(),
484 host_resolver_.get(),
485 &client_socket_factory_,
486 NULL) {}
487
488 virtual ~WebSocketTransportClientSocketPoolTest() {}
489
490 int StartRequest(const std::string& group_name, RequestPriority priority) {
491 scoped_refptr<TransportSocketParams> params(
492 new TransportSocketParams(HostPortPair("www.google.com", 80),
493 false,
494 false,
495 OnHostResolutionCallback()));
496 return test_base_.StartRequestUsingPool(
497 &pool_, group_name, priority, params);
498 }
499
500 int GetOrderOfRequest(size_t index) {
501 return test_base_.GetOrderOfRequest(index);
502 }
503
504 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
505 return test_base_.ReleaseOneConnection(keep_alive);
506 }
507
508 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
509 test_base_.ReleaseAllConnections(keep_alive);
510 }
511
512 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
513 size_t completion_count() const { return test_base_.completion_count(); }
514
515 CapturingNetLog net_log_;
516 scoped_refptr<TransportSocketParams> params_;
517 scoped_ptr<ClientSocketPoolHistograms> histograms_;
518 scoped_ptr<MockHostResolver> host_resolver_;
519 MockClientSocketFactory client_socket_factory_;
520 WebSocketTransportClientSocketPool pool_;
521 ClientSocketPoolTest test_base_;
522
523 private:
524 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest);
525 };
526
527 TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
528 TestCompletionCallback callback;
529 ClientSocketHandle handle;
530 int rv = handle.Init(
531 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
532 EXPECT_EQ(ERR_IO_PENDING, rv);
533 EXPECT_FALSE(handle.is_initialized());
534 EXPECT_FALSE(handle.socket());
535
536 EXPECT_EQ(OK, callback.WaitForResult());
537 EXPECT_TRUE(handle.is_initialized());
538 EXPECT_TRUE(handle.socket());
539 TestLoadTimingInfoConnectedNotReused(handle);
540 }
541
542 // Make sure that WebSocketTransportConnectJob passes on its priority to its
543 // HostResolver request on Init.
544 TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
545 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
546 RequestPriority priority = static_cast<RequestPriority>(i);
547 TestCompletionCallback callback;
548 ClientSocketHandle handle;
549 EXPECT_EQ(ERR_IO_PENDING,
550 handle.Init("a",
551 params_,
552 priority,
553 callback.callback(),
554 &pool_,
555 BoundNetLog()));
556 EXPECT_EQ(priority, host_resolver_->last_request_priority());
557 }
558 }
559
560 TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
561 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
562 TestCompletionCallback callback;
563 ClientSocketHandle handle;
564 HostPortPair host_port_pair("unresolvable.host.name", 80);
565 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
566 host_port_pair, false, false, OnHostResolutionCallback()));
567 EXPECT_EQ(ERR_IO_PENDING,
568 handle.Init("a",
569 dest,
570 kDefaultPriority,
571 callback.callback(),
572 &pool_,
573 BoundNetLog()));
574 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult());
575 }
576
577 TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
578 client_socket_factory_.set_client_socket_type(
579 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
580 TestCompletionCallback callback;
581 ClientSocketHandle handle;
582 EXPECT_EQ(ERR_IO_PENDING,
583 handle.Init("a",
584 params_,
585 kDefaultPriority,
586 callback.callback(),
587 &pool_,
588 BoundNetLog()));
589 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
590
591 // Make the host resolutions complete synchronously this time.
592 host_resolver_->set_synchronous_mode(true);
593 EXPECT_EQ(ERR_CONNECTION_FAILED,
594 handle.Init("a",
595 params_,
596 kDefaultPriority,
597 callback.callback(),
598 &pool_,
599 BoundNetLog()));
600 }
601
602 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
603 // First request finishes asynchronously.
604 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
605 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
606
607 // Make all subsequent host resolutions complete synchronously.
608 host_resolver_->set_synchronous_mode(true);
609
610 // Rest of them wait for the first socket to be released.
611 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
612 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
613 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
614 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
615 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
616
617 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
618
619 EXPECT_EQ(6, client_socket_factory_.allocation_count());
620
621 // One initial asynchronous request and then 5 pending requests.
622 EXPECT_EQ(6U, completion_count());
623
624 // The requests finish in FIFO order.
625 EXPECT_EQ(1, GetOrderOfRequest(1));
626 EXPECT_EQ(2, GetOrderOfRequest(2));
627 EXPECT_EQ(3, GetOrderOfRequest(3));
628 EXPECT_EQ(4, GetOrderOfRequest(4));
629 EXPECT_EQ(5, GetOrderOfRequest(5));
630 EXPECT_EQ(6, GetOrderOfRequest(6));
631
632 // Make sure we test order of all requests made.
633 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
634 }
635
636 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
637 // First request finishes asynchronously.
638 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
639 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
640
641 // Make all subsequent host resolutions complete synchronously.
642 host_resolver_->set_synchronous_mode(true);
643
644 // Rest of them wait foe the first socket to be released.
645 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
646 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
647 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
648 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
649 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
650
651 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
652
653 // The pending requests should finish successfully.
654 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
655 EXPECT_EQ(OK, (*requests())[2]->WaitForResult());
656 EXPECT_EQ(OK, (*requests())[3]->WaitForResult());
657 EXPECT_EQ(OK, (*requests())[4]->WaitForResult());
658 EXPECT_EQ(OK, (*requests())[5]->WaitForResult());
659
660 EXPECT_EQ(static_cast<int>(requests()->size()),
661 client_socket_factory_.allocation_count());
662
663 // First asynchronous request, and then last 5 pending requests.
664 EXPECT_EQ(6U, completion_count());
665 }
666
667 // This test will start up a RequestSocket() and then immediately Cancel() it.
668 // The pending host resolution will eventually complete, and destroy the
669 // ClientSocketPool which will crash if the group was not cleared properly.
670 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
671 TestCompletionCallback callback;
672 ClientSocketHandle handle;
673 EXPECT_EQ(ERR_IO_PENDING,
674 handle.Init("a",
675 params_,
676 kDefaultPriority,
677 callback.callback(),
678 &pool_,
679 BoundNetLog()));
680 handle.Reset();
681 }
682
683 TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
684 ClientSocketHandle handle;
685 TestCompletionCallback callback;
686 ClientSocketHandle handle2;
687 TestCompletionCallback callback2;
688
689 EXPECT_EQ(ERR_IO_PENDING,
690 handle.Init("a",
691 params_,
692 kDefaultPriority,
693 callback.callback(),
694 &pool_,
695 BoundNetLog()));
696 EXPECT_EQ(ERR_IO_PENDING,
697 handle2.Init("a",
698 params_,
699 kDefaultPriority,
700 callback2.callback(),
701 &pool_,
702 BoundNetLog()));
703
704 handle.Reset();
705
706 EXPECT_EQ(OK, callback2.WaitForResult());
707 handle2.Reset();
708 }
709
710 TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
711 client_socket_factory_.set_client_socket_type(
712 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
713 ClientSocketHandle handle;
714 TestCompletionCallback callback;
715 EXPECT_EQ(ERR_IO_PENDING,
716 handle.Init("a",
717 params_,
718 kDefaultPriority,
719 callback.callback(),
720 &pool_,
721 BoundNetLog()));
722
723 handle.Reset();
724
725 TestCompletionCallback callback2;
726 EXPECT_EQ(ERR_IO_PENDING,
727 handle.Init("a",
728 params_,
729 kDefaultPriority,
730 callback2.callback(),
731 &pool_,
732 BoundNetLog()));
733
734 host_resolver_->set_synchronous_mode(true);
735 // At this point, handle has two ConnectingSockets out for it. Due to the
736 // setting the mock resolver into synchronous mode, the host resolution for
737 // both will return in the same loop of the MessageLoop. The client socket
738 // is a pending socket, so the Connect() will asynchronously complete on the
739 // next loop of the MessageLoop. That means that the first
740 // ConnectingSocket will enter OnIOComplete, and then the second one will.
741 // If the first one is not cancelled, it will advance the load state, and
742 // then the second one will crash.
743
744 EXPECT_EQ(OK, callback2.WaitForResult());
745 EXPECT_FALSE(callback.have_result());
746
747 handle.Reset();
748 }
749
750 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
751 // First request finishes asynchronously.
752 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
753 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
754
755 // Make all subsequent host resolutions complete synchronously.
756 host_resolver_->set_synchronous_mode(true);
757
758 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
759 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
760 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
761 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
762 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
763
764 // Cancel a request.
765 const size_t index_to_cancel = 2;
766 EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
767 (*requests())[index_to_cancel]->handle()->Reset();
768
769 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
770
771 EXPECT_EQ(5, client_socket_factory_.allocation_count());
772
773 EXPECT_EQ(1, GetOrderOfRequest(1));
774 EXPECT_EQ(2, GetOrderOfRequest(2));
775 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
776 GetOrderOfRequest(3)); // Canceled request.
777 EXPECT_EQ(3, GetOrderOfRequest(4));
778 EXPECT_EQ(4, GetOrderOfRequest(5));
779 EXPECT_EQ(5, GetOrderOfRequest(6));
780
781 // Make sure we test order of all requests made.
782 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
783 }
784
785 class RequestSocketCallback : public TestCompletionCallbackBase {
786 public:
787 RequestSocketCallback(ClientSocketHandle* handle,
788 WebSocketTransportClientSocketPool* pool)
789 : handle_(handle),
790 pool_(pool),
791 within_callback_(false),
792 callback_(base::Bind(&RequestSocketCallback::OnComplete,
793 base::Unretained(this))) {}
794
795 virtual ~RequestSocketCallback() {}
796
797 const CompletionCallback& callback() const { return callback_; }
798
799 private:
800 void OnComplete(int result) {
801 SetResult(result);
802 ASSERT_EQ(OK, result);
803
804 if (!within_callback_) {
805 // Don't allow reuse of the socket. Disconnect it and then release it and
806 // run through the MessageLoop once to get it completely released.
807 handle_->socket()->Disconnect();
808 handle_->Reset();
809 {
810 base::MessageLoop::ScopedNestableTaskAllower allow(
811 base::MessageLoop::current());
812 base::MessageLoop::current()->RunUntilIdle();
813 }
814 within_callback_ = true;
815 scoped_refptr<TransportSocketParams> dest(
816 new TransportSocketParams(HostPortPair("www.google.com", 80),
817 false,
818 false,
819 OnHostResolutionCallback()));
820 int rv =
821 handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog());
822 EXPECT_EQ(OK, rv);
823 }
824 }
825
826 ClientSocketHandle* const handle_;
827 WebSocketTransportClientSocketPool* const pool_;
828 bool within_callback_;
829 CompletionCallback callback_;
830
831 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback);
832 };
833
834 TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
835 ClientSocketHandle handle;
836 RequestSocketCallback callback(&handle, &pool_);
837 scoped_refptr<TransportSocketParams> dest(
838 new TransportSocketParams(HostPortPair("www.google.com", 80),
839 false,
840 false,
841 OnHostResolutionCallback()));
842 int rv = handle.Init(
843 "a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog());
844 ASSERT_EQ(ERR_IO_PENDING, rv);
845
846 // The callback is going to request "www.google.com". We want it to complete
847 // synchronously this time.
848 host_resolver_->set_synchronous_mode(true);
849
850 EXPECT_EQ(OK, callback.WaitForResult());
851
852 handle.Reset();
853 }
854
855 // Make sure that pending requests get serviced after active requests get
856 // cancelled.
857 TEST_F(WebSocketTransportClientSocketPoolTest,
858 CancelActiveRequestWithPendingRequests) {
859 client_socket_factory_.set_client_socket_type(
860 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
861
862 // Queue up all the requests
863 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
864 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
865 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
866 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
867 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
868 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
869 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
870 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
871 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
872
873 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
874 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
875 for (int i = 0; i < kMaxSocketsPerGroup; i++)
876 (*requests())[i]->handle()->Reset();
877
878 // Let's wait for the rest to complete now.
879 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
880 EXPECT_EQ(OK, (*requests())[i]->WaitForResult());
881 (*requests())[i]->handle()->Reset();
882 }
883
884 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
885 }
886
887 // Make sure that pending requests get serviced after active requests fail.
888 TEST_F(WebSocketTransportClientSocketPoolTest,
889 FailingActiveRequestWithPendingRequests) {
890 client_socket_factory_.set_client_socket_type(
891 MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
892
893 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
894 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
895
896 // Queue up all the requests
897 for (int i = 0; i < kNumRequests; i++)
898 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
899
900 for (int i = 0; i < kNumRequests; i++)
901 EXPECT_EQ(ERR_CONNECTION_FAILED, (*requests())[i]->WaitForResult());
902 }
903
904 // The lock on the endpoint is released when a ClientSocketHandle is reset.
905 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
906 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
907 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
908 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
909 EXPECT_FALSE((*requests())[1]->handle()->is_initialized());
910 (*requests())[0]->handle()->Reset();
911 base::RunLoop().RunUntilIdle();
912 EXPECT_TRUE((*requests())[1]->handle()->is_initialized());
913 }
914
915 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
916 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
917 TestCompletionCallback callback;
918 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle);
919 int rv = handle->Init(
920 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
921 EXPECT_EQ(ERR_IO_PENDING, rv);
922
923 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
924 EXPECT_EQ(OK, callback.WaitForResult());
925 EXPECT_FALSE((*requests())[0]->handle()->is_initialized());
926 handle.reset();
927 base::RunLoop().RunUntilIdle();
928 EXPECT_TRUE((*requests())[0]->handle()->is_initialized());
929 }
930
931 // A new connection is performed when the lock on the previous connection is
932 // explicity released.
933 TEST_F(WebSocketTransportClientSocketPoolTest,
934 ConnectionProceedsOnExplicitRelease) {
935 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
936 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
937 EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
938 EXPECT_FALSE((*requests())[1]->handle()->is_initialized());
939 WebSocketTransportClientSocketPool::UnlockEndpoint(
940 (*requests())[0]->handle());
941 base::RunLoop().RunUntilIdle();
942 EXPECT_TRUE((*requests())[1]->handle()->is_initialized());
943 }
944
945 // A connection which is cancelled before completion does not block subsequent
946 // connections.
947 TEST_F(WebSocketTransportClientSocketPoolTest,
948 CancelDuringConnectionReleasesLock) {
949 MockClientSocketFactory::ClientSocketType case_types[] = {
950 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
951 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
952
953 client_socket_factory_.set_client_socket_types(case_types,
954 arraysize(case_types));
955
956 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
957 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
958 base::RunLoop().RunUntilIdle();
959 pool_.CancelRequest("a", ((*requests())[0])->handle());
960 EXPECT_EQ(OK, (*requests())[1]->WaitForResult());
961 }
962
963 // Test the case of the IPv6 address stalling, and falling back to the IPv4
964 // socket which finishes first.
965 TEST_F(WebSocketTransportClientSocketPoolTest,
966 IPv6FallbackSocketIPv4FinishesFirst) {
967 WebSocketTransportClientSocketPool pool(kMaxSockets,
968 kMaxSocketsPerGroup,
969 histograms_.get(),
970 host_resolver_.get(),
971 &client_socket_factory_,
972 NULL);
973
974 MockClientSocketFactory::ClientSocketType case_types[] = {
975 // This is the IPv6 socket.
976 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
977 // This is the IPv4 socket.
978 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
979
980 client_socket_factory_.set_client_socket_types(case_types, 2);
981
982 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
983 host_resolver_->rules()->AddIPLiteralRule(
984 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
985
986 TestCompletionCallback callback;
987 ClientSocketHandle handle;
988 int rv =
989 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
990 EXPECT_EQ(ERR_IO_PENDING, rv);
991 EXPECT_FALSE(handle.is_initialized());
992 EXPECT_FALSE(handle.socket());
993
994 EXPECT_EQ(OK, callback.WaitForResult());
995 EXPECT_TRUE(handle.is_initialized());
996 EXPECT_TRUE(handle.socket());
997 IPEndPoint endpoint;
998 handle.socket()->GetLocalAddress(&endpoint);
999 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
1000 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1001 }
1002
1003 // Test the case of the IPv6 address being slow, thus falling back to trying to
1004 // connect to the IPv4 address, but having the connect to the IPv6 address
1005 // finish first.
1006 TEST_F(WebSocketTransportClientSocketPoolTest,
1007 IPv6FallbackSocketIPv6FinishesFirst) {
1008 WebSocketTransportClientSocketPool pool(kMaxSockets,
1009 kMaxSocketsPerGroup,
1010 histograms_.get(),
1011 host_resolver_.get(),
1012 &client_socket_factory_,
1013 NULL);
1014
1015 MockClientSocketFactory::ClientSocketType case_types[] = {
1016 // This is the IPv6 socket.
1017 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
1018 // This is the IPv4 socket.
1019 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET};
1020
1021 client_socket_factory_.set_client_socket_types(case_types, 2);
1022 client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds(
1023 TransportConnectJobCommon::kIPv6FallbackTimerInMs + 50));
1024
1025 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
1026 host_resolver_->rules()->AddIPLiteralRule(
1027 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
1028
1029 TestCompletionCallback callback;
1030 ClientSocketHandle handle;
1031 int rv =
1032 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1033 EXPECT_EQ(ERR_IO_PENDING, rv);
1034 EXPECT_FALSE(handle.is_initialized());
1035 EXPECT_FALSE(handle.socket());
1036
1037 EXPECT_EQ(OK, callback.WaitForResult());
1038 EXPECT_TRUE(handle.is_initialized());
1039 EXPECT_TRUE(handle.socket());
1040 IPEndPoint endpoint;
1041 handle.socket()->GetLocalAddress(&endpoint);
1042 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
1043 EXPECT_EQ(2, client_socket_factory_.allocation_count());
1044 }
1045
1046 TEST_F(WebSocketTransportClientSocketPoolTest,
1047 IPv6NoIPv4AddressesToFallbackTo) {
1048 WebSocketTransportClientSocketPool pool(kMaxSockets,
1049 kMaxSocketsPerGroup,
1050 histograms_.get(),
1051 host_resolver_.get(),
1052 &client_socket_factory_,
1053 NULL);
1054
1055 client_socket_factory_.set_client_socket_type(
1056 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
1057
1058 // Resolve an AddressList with only IPv6 addresses.
1059 host_resolver_->rules()->AddIPLiteralRule(
1060 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
1061
1062 TestCompletionCallback callback;
1063 ClientSocketHandle handle;
1064 int rv =
1065 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1066 EXPECT_EQ(ERR_IO_PENDING, rv);
1067 EXPECT_FALSE(handle.is_initialized());
1068 EXPECT_FALSE(handle.socket());
1069
1070 EXPECT_EQ(OK, callback.WaitForResult());
1071 EXPECT_TRUE(handle.is_initialized());
1072 EXPECT_TRUE(handle.socket());
1073 IPEndPoint endpoint;
1074 handle.socket()->GetLocalAddress(&endpoint);
1075 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
1076 EXPECT_EQ(1, client_socket_factory_.allocation_count());
1077 }
1078
1079 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
1080 WebSocketTransportClientSocketPool pool(kMaxSockets,
1081 kMaxSocketsPerGroup,
1082 histograms_.get(),
1083 host_resolver_.get(),
1084 &client_socket_factory_,
1085 NULL);
1086
1087 client_socket_factory_.set_client_socket_type(
1088 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
1089
1090 // Resolve an AddressList with only IPv4 addresses.
1091 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
1092
1093 TestCompletionCallback callback;
1094 ClientSocketHandle handle;
1095 int rv =
1096 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1097 EXPECT_EQ(ERR_IO_PENDING, rv);
1098 EXPECT_FALSE(handle.is_initialized());
1099 EXPECT_FALSE(handle.socket());
1100
1101 EXPECT_EQ(OK, callback.WaitForResult());
1102 EXPECT_TRUE(handle.is_initialized());
1103 EXPECT_TRUE(handle.socket());
1104 IPEndPoint endpoint;
1105 handle.socket()->GetLocalAddress(&endpoint);
1106 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
1107 EXPECT_EQ(1, client_socket_factory_.allocation_count());
1108 }
1109
1110 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
1111 // proceeed immediately.
1112 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
1113 WebSocketTransportClientSocketPool pool(kMaxSockets,
1114 kMaxSocketsPerGroup,
1115 histograms_.get(),
1116 host_resolver_.get(),
1117 &client_socket_factory_,
1118 NULL);
1119
1120 MockClientSocketFactory::ClientSocketType case_types[] = {
1121 // First IPv6 socket.
1122 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
1123 // Second IPv6 socket.
1124 MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
1125 // This is the IPv4 socket.
1126 MockClientSocketFactory::MOCK_CLIENT_SOCKET};
1127
1128 client_socket_factory_.set_client_socket_types(case_types,
1129 arraysize(case_types));
1130
1131 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
1132 host_resolver_->rules()->AddIPLiteralRule(
1133 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
1134 host_resolver_->set_synchronous_mode(true);
1135 TestCompletionCallback callback;
1136 ClientSocketHandle handle;
1137 int rv =
1138 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1139 EXPECT_EQ(OK, rv);
1140 ASSERT_TRUE(handle.socket());
1141
1142 IPEndPoint endpoint;
1143 handle.socket()->GetPeerAddress(&endpoint);
1144 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
1145 }
1146
1147 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
1148 // connections proceed immediately.
1149 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
1150 WebSocketTransportClientSocketPool pool(kMaxSockets,
1151 kMaxSocketsPerGroup,
1152 histograms_.get(),
1153 host_resolver_.get(),
1154 &client_socket_factory_,
1155 NULL);
1156
1157 MockClientSocketFactory::ClientSocketType case_types[] = {
1158 // First IPv6 socket.
1159 MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
1160 // Second IPv6 socket.
1161 MockClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
1162 // This is the IPv4 socket.
1163 MockClientSocketFactory::MOCK_CLIENT_SOCKET};
1164
1165 client_socket_factory_.set_client_socket_types(case_types,
1166 arraysize(case_types));
1167
1168 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
1169 host_resolver_->rules()->AddIPLiteralRule(
1170 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
1171
1172 TestCompletionCallback callback;
1173 ClientSocketHandle handle;
1174 int rv =
1175 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1176 EXPECT_EQ(ERR_IO_PENDING, rv);
1177 EXPECT_FALSE(handle.socket());
1178
1179 base::Time start(base::Time::NowFromSystemTime());
1180 EXPECT_EQ(OK, callback.WaitForResult());
1181 EXPECT_LT(base::Time::NowFromSystemTime() - start,
1182 base::TimeDelta::FromMilliseconds(
1183 TransportConnectJobCommon::kIPv6FallbackTimerInMs));
1184 ASSERT_TRUE(handle.socket());
1185
1186 IPEndPoint endpoint;
1187 handle.socket()->GetPeerAddress(&endpoint);
1188 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
1189 }
1190
1191 // If two sockets connect successfully, the one which connected first wins (this
1192 // can only happen if the sockets are different types, since sockets of the same
1193 // type do not race).
1194 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
1195 WebSocketTransportClientSocketPool pool(kMaxSockets,
1196 kMaxSocketsPerGroup,
1197 histograms_.get(),
1198 host_resolver_.get(),
1199 &client_socket_factory_,
1200 NULL);
1201
1202 client_socket_factory_.set_client_socket_type(
1203 MockClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
1204
1205 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
1206 host_resolver_->rules()->AddIPLiteralRule(
1207 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
1208
1209 TestCompletionCallback callback;
1210 ClientSocketHandle handle;
1211 int rv =
1212 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1213 EXPECT_EQ(ERR_IO_PENDING, rv);
1214 ASSERT_FALSE(handle.socket());
1215
1216 base::Closure ipv6_connect_trigger =
1217 client_socket_factory_.WaitForTriggerableSocketCreation();
1218 base::Closure ipv4_connect_trigger =
1219 client_socket_factory_.WaitForTriggerableSocketCreation();
1220
1221 ipv4_connect_trigger.Run();
1222 ipv6_connect_trigger.Run();
1223
1224 EXPECT_EQ(OK, callback.WaitForResult());
1225 ASSERT_TRUE(handle.socket());
1226
1227 IPEndPoint endpoint;
1228 handle.socket()->GetPeerAddress(&endpoint);
1229 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
1230 }
1231
1232 // We should not report failure until all connections have failed.
1233 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
1234 WebSocketTransportClientSocketPool pool(kMaxSockets,
1235 kMaxSocketsPerGroup,
1236 histograms_.get(),
1237 host_resolver_.get(),
1238 &client_socket_factory_,
1239 NULL);
1240
1241 client_socket_factory_.set_client_socket_type(
1242 MockClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
1243 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
1244 TransportConnectJobCommon::kIPv6FallbackTimerInMs / 3);
1245 client_socket_factory_.set_delay(delay);
1246
1247 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 address.
1248 host_resolver_->rules()->AddIPLiteralRule("*",
1249 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
1250 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
1251 "1.1.1.1,2.2.2.2",
1252 std::string());
1253
1254 // Expected order of events:
1255 // After 100ms: Connect to 1:abcd::3:4:ff times out
1256 // After 200ms: Connect to 2:abcd::3:4:ff times out
1257 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
1258 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
1259 // After 500ms: Connect to 2.2.2.2 times out
1260
1261 TestCompletionCallback callback;
1262 ClientSocketHandle handle;
1263 base::Time start(base::Time::NowFromSystemTime());
1264 int rv =
1265 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1266 EXPECT_EQ(ERR_IO_PENDING, rv);
1267
1268 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
1269
1270 EXPECT_GE(base::Time::NowFromSystemTime() - start, delay * 5);
1271 }
1272
1273 // Global timeout for all connects applies. This test is disabled by default
1274 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
1275 // want to run it.
1276 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
1277 WebSocketTransportClientSocketPool pool(kMaxSockets,
1278 kMaxSocketsPerGroup,
1279 histograms_.get(),
1280 host_resolver_.get(),
1281 &client_socket_factory_,
1282 NULL);
1283 const base::TimeDelta connect_job_timeout = pool.ConnectionTimeout();
1284
1285 client_socket_factory_.set_client_socket_type(
1286 MockClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
1287 client_socket_factory_.set_delay(base::TimeDelta::FromSeconds(1) +
1288 connect_job_timeout / 6);
1289
1290 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 address.
1291 host_resolver_->rules()->AddIPLiteralRule("*",
1292 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
1293 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
1294 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
1295 "1.1.1.1,2.2.2.2,3.3.3.3,"
1296 "4.4.4.4,5.5.5.5,6.6.6.6",
1297 std::string());
1298
1299 TestCompletionCallback callback;
1300 ClientSocketHandle handle;
1301
1302 int rv =
1303 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
1304 EXPECT_EQ(ERR_IO_PENDING, rv);
1305
1306 EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult());
1307 }
1308
1309 } // namespace
1310
1311 } // namespace net
OLDNEW
« no previous file with comments | « net/socket/websocket_transport_client_socket_pool.cc ('k') | net/websockets/websocket_basic_handshake_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698