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

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: Fixes for clang style complaints. 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 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/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/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "net/base/capturing_net_log.h"
16 #include "net/base/ip_endpoint.h"
17 #include "net/base/load_timing_info.h"
18 #include "net/base/load_timing_info_test_util.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/net_util.h"
21 #include "net/base/test_completion_callback.h"
22 #include "net/dns/mock_host_resolver.h"
23 #include "net/socket/client_socket_handle.h"
24 #include "net/socket/client_socket_pool_histograms.h"
25 #include "net/socket/socket_test_util.h"
26 #include "net/socket/stream_socket.h"
27 #include "net/socket/transport_client_socket_pool_test_util.h"
28 #include "net/socket/websocket_endpoint_lock_manager.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 namespace net {
32
33 namespace {
34
35 const int kMaxSockets = 32;
36 const int kMaxSocketsPerGroup = 6;
37 const net::RequestPriority kDefaultPriority = LOW;
38
39 class WebSocketTransportClientSocketPoolTest : public testing::Test {
40 protected:
41 WebSocketTransportClientSocketPoolTest()
42 : params_(new TransportSocketParams(HostPortPair("www.google.com", 80),
43 false,
44 false,
45 OnHostResolutionCallback())),
46 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
47 host_resolver_(new MockHostResolver),
48 client_socket_factory_(&net_log_),
49 pool_(kMaxSockets,
50 kMaxSocketsPerGroup,
51 histograms_.get(),
52 host_resolver_.get(),
53 &client_socket_factory_,
54 NULL) {}
55
56 virtual ~WebSocketTransportClientSocketPoolTest() {
57 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
58 EXPECT_TRUE(WebSocketEndpointLockManager::GetInstance()->IsEmpty());
59 }
60
61 int StartRequest(const std::string& group_name, RequestPriority priority) {
62 scoped_refptr<TransportSocketParams> params(
63 new TransportSocketParams(HostPortPair("www.google.com", 80),
64 false,
65 false,
66 OnHostResolutionCallback()));
67 return test_base_.StartRequestUsingPool(
68 &pool_, group_name, priority, params);
69 }
70
71 int GetOrderOfRequest(size_t index) {
72 return test_base_.GetOrderOfRequest(index);
73 }
74
75 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
76 return test_base_.ReleaseOneConnection(keep_alive);
77 }
78
79 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
80 test_base_.ReleaseAllConnections(keep_alive);
81 }
82
83 TestSocketRequest* request(int i) { return test_base_.request(i); }
84
85 ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
86 size_t completion_count() const { return test_base_.completion_count(); }
87
88 CapturingNetLog net_log_;
89 scoped_refptr<TransportSocketParams> params_;
90 scoped_ptr<ClientSocketPoolHistograms> histograms_;
91 scoped_ptr<MockHostResolver> host_resolver_;
92 MockTransportClientSocketFactory client_socket_factory_;
93 WebSocketTransportClientSocketPool pool_;
94 ClientSocketPoolTest test_base_;
95
96 private:
97 DISALLOW_COPY_AND_ASSIGN(WebSocketTransportClientSocketPoolTest);
98 };
99
100 TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
101 TestCompletionCallback callback;
102 ClientSocketHandle handle;
103 int rv = handle.Init(
104 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
105 EXPECT_EQ(ERR_IO_PENDING, rv);
106 EXPECT_FALSE(handle.is_initialized());
107 EXPECT_FALSE(handle.socket());
108
109 EXPECT_EQ(OK, callback.WaitForResult());
110 EXPECT_TRUE(handle.is_initialized());
111 EXPECT_TRUE(handle.socket());
112 TestLoadTimingInfoConnectedNotReused(handle);
113 }
114
115 // Make sure that WebSocketTransportConnectJob passes on its priority to its
116 // HostResolver request on Init.
117 TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
118 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
119 RequestPriority priority = static_cast<RequestPriority>(i);
120 TestCompletionCallback callback;
121 ClientSocketHandle handle;
122 EXPECT_EQ(ERR_IO_PENDING,
123 handle.Init("a",
124 params_,
125 priority,
126 callback.callback(),
127 &pool_,
128 BoundNetLog()));
129 EXPECT_EQ(priority, host_resolver_->last_request_priority());
130 }
131 }
132
133 TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
134 host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
135 TestCompletionCallback callback;
136 ClientSocketHandle handle;
137 HostPortPair host_port_pair("unresolvable.host.name", 80);
138 scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
139 host_port_pair, false, false, OnHostResolutionCallback()));
140 EXPECT_EQ(ERR_IO_PENDING,
141 handle.Init("a",
142 dest,
143 kDefaultPriority,
144 callback.callback(),
145 &pool_,
146 BoundNetLog()));
147 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult());
148 }
149
150 TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
151 client_socket_factory_.set_client_socket_type(
152 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
153 TestCompletionCallback callback;
154 ClientSocketHandle handle;
155 EXPECT_EQ(ERR_IO_PENDING,
156 handle.Init("a",
157 params_,
158 kDefaultPriority,
159 callback.callback(),
160 &pool_,
161 BoundNetLog()));
162 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
163
164 // Make the host resolutions complete synchronously this time.
165 host_resolver_->set_synchronous_mode(true);
166 EXPECT_EQ(ERR_CONNECTION_FAILED,
167 handle.Init("a",
168 params_,
169 kDefaultPriority,
170 callback.callback(),
171 &pool_,
172 BoundNetLog()));
173 }
174
175 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
176 // First request finishes asynchronously.
177 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
178 EXPECT_EQ(OK, request(0)->WaitForResult());
179
180 // Make all subsequent host resolutions complete synchronously.
181 host_resolver_->set_synchronous_mode(true);
182
183 // Rest of them wait for the first socket to be released.
184 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
185 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
186 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
187 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
188 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
189
190 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
191
192 EXPECT_EQ(6, client_socket_factory_.allocation_count());
193
194 // One initial asynchronous request and then 5 pending requests.
195 EXPECT_EQ(6U, completion_count());
196
197 // The requests finish in FIFO order.
198 EXPECT_EQ(1, GetOrderOfRequest(1));
199 EXPECT_EQ(2, GetOrderOfRequest(2));
200 EXPECT_EQ(3, GetOrderOfRequest(3));
201 EXPECT_EQ(4, GetOrderOfRequest(4));
202 EXPECT_EQ(5, GetOrderOfRequest(5));
203 EXPECT_EQ(6, GetOrderOfRequest(6));
204
205 // Make sure we test order of all requests made.
206 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
207 }
208
209 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
210 // First request finishes asynchronously.
211 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
212 EXPECT_EQ(OK, request(0)->WaitForResult());
213
214 // Make all subsequent host resolutions complete synchronously.
215 host_resolver_->set_synchronous_mode(true);
216
217 // Rest of them wait foe the first socket to be released.
218 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
219 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
220 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
221 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
222 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
223
224 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
225
226 // The pending requests should finish successfully.
227 EXPECT_EQ(OK, request(1)->WaitForResult());
228 EXPECT_EQ(OK, request(2)->WaitForResult());
229 EXPECT_EQ(OK, request(3)->WaitForResult());
230 EXPECT_EQ(OK, request(4)->WaitForResult());
231 EXPECT_EQ(OK, request(5)->WaitForResult());
232
233 EXPECT_EQ(static_cast<int>(requests()->size()),
234 client_socket_factory_.allocation_count());
235
236 // First asynchronous request, and then last 5 pending requests.
237 EXPECT_EQ(6U, completion_count());
238 }
239
240 // This test will start up a RequestSocket() and then immediately Cancel() it.
241 // The pending host resolution will eventually complete, and destroy the
242 // ClientSocketPool which will crash if the group was not cleared properly.
243 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
244 TestCompletionCallback callback;
245 ClientSocketHandle handle;
246 EXPECT_EQ(ERR_IO_PENDING,
247 handle.Init("a",
248 params_,
249 kDefaultPriority,
250 callback.callback(),
251 &pool_,
252 BoundNetLog()));
253 handle.Reset();
254 }
255
256 TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
257 ClientSocketHandle handle;
258 TestCompletionCallback callback;
259 ClientSocketHandle handle2;
260 TestCompletionCallback callback2;
261
262 EXPECT_EQ(ERR_IO_PENDING,
263 handle.Init("a",
264 params_,
265 kDefaultPriority,
266 callback.callback(),
267 &pool_,
268 BoundNetLog()));
269 EXPECT_EQ(ERR_IO_PENDING,
270 handle2.Init("a",
271 params_,
272 kDefaultPriority,
273 callback2.callback(),
274 &pool_,
275 BoundNetLog()));
276
277 handle.Reset();
278
279 EXPECT_EQ(OK, callback2.WaitForResult());
280 handle2.Reset();
281 }
282
283 TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
284 client_socket_factory_.set_client_socket_type(
285 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
286 ClientSocketHandle handle;
287 TestCompletionCallback callback;
288 EXPECT_EQ(ERR_IO_PENDING,
289 handle.Init("a",
290 params_,
291 kDefaultPriority,
292 callback.callback(),
293 &pool_,
294 BoundNetLog()));
295
296 handle.Reset();
297
298 TestCompletionCallback callback2;
299 EXPECT_EQ(ERR_IO_PENDING,
300 handle.Init("a",
301 params_,
302 kDefaultPriority,
303 callback2.callback(),
304 &pool_,
305 BoundNetLog()));
306
307 host_resolver_->set_synchronous_mode(true);
308 // At this point, handle has two ConnectingSockets out for it. Due to the
309 // setting the mock resolver into synchronous mode, the host resolution for
310 // both will return in the same loop of the MessageLoop. The client socket
311 // is a pending socket, so the Connect() will asynchronously complete on the
312 // next loop of the MessageLoop. That means that the first
313 // ConnectingSocket will enter OnIOComplete, and then the second one will.
314 // If the first one is not cancelled, it will advance the load state, and
315 // then the second one will crash.
316
317 EXPECT_EQ(OK, callback2.WaitForResult());
318 EXPECT_FALSE(callback.have_result());
319
320 handle.Reset();
321 }
322
323 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
324 // First request finishes asynchronously.
325 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
326 EXPECT_EQ(OK, request(0)->WaitForResult());
327
328 // Make all subsequent host resolutions complete synchronously.
329 host_resolver_->set_synchronous_mode(true);
330
331 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
332 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
333 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
334 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
335 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
336
337 // Cancel a request.
338 const size_t index_to_cancel = 2;
339 EXPECT_FALSE(request(index_to_cancel)->handle()->is_initialized());
340 request(index_to_cancel)->handle()->Reset();
341
342 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
343
344 EXPECT_EQ(5, client_socket_factory_.allocation_count());
345
346 EXPECT_EQ(1, GetOrderOfRequest(1));
347 EXPECT_EQ(2, GetOrderOfRequest(2));
348 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
349 GetOrderOfRequest(3)); // Canceled request.
350 EXPECT_EQ(3, GetOrderOfRequest(4));
351 EXPECT_EQ(4, GetOrderOfRequest(5));
352 EXPECT_EQ(5, GetOrderOfRequest(6));
353
354 // Make sure we test order of all requests made.
355 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
356 }
357
358 class RequestSocketCallback : public TestCompletionCallbackBase {
359 public:
360 RequestSocketCallback(ClientSocketHandle* handle,
361 WebSocketTransportClientSocketPool* pool)
362 : handle_(handle),
363 pool_(pool),
364 within_callback_(false),
365 callback_(base::Bind(&RequestSocketCallback::OnComplete,
366 base::Unretained(this))) {}
367
368 virtual ~RequestSocketCallback() {}
369
370 const CompletionCallback& callback() const { return callback_; }
371
372 private:
373 void OnComplete(int result) {
374 SetResult(result);
375 ASSERT_EQ(OK, result);
376
377 if (!within_callback_) {
378 // Don't allow reuse of the socket. Disconnect it and then release it and
379 // run through the MessageLoop once to get it completely released.
380 handle_->socket()->Disconnect();
381 handle_->Reset();
382 {
383 base::MessageLoop::ScopedNestableTaskAllower allow(
384 base::MessageLoop::current());
385 base::MessageLoop::current()->RunUntilIdle();
386 }
387 within_callback_ = true;
388 scoped_refptr<TransportSocketParams> dest(
389 new TransportSocketParams(HostPortPair("www.google.com", 80),
390 false,
391 false,
392 OnHostResolutionCallback()));
393 int rv =
394 handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog());
395 EXPECT_EQ(OK, rv);
396 }
397 }
398
399 ClientSocketHandle* const handle_;
400 WebSocketTransportClientSocketPool* const pool_;
401 bool within_callback_;
402 CompletionCallback callback_;
403
404 DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback);
405 };
406
407 TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
408 ClientSocketHandle handle;
409 RequestSocketCallback callback(&handle, &pool_);
410 scoped_refptr<TransportSocketParams> dest(
411 new TransportSocketParams(HostPortPair("www.google.com", 80),
412 false,
413 false,
414 OnHostResolutionCallback()));
415 int rv = handle.Init(
416 "a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog());
417 ASSERT_EQ(ERR_IO_PENDING, rv);
418
419 // The callback is going to request "www.google.com". We want it to complete
420 // synchronously this time.
421 host_resolver_->set_synchronous_mode(true);
422
423 EXPECT_EQ(OK, callback.WaitForResult());
424
425 handle.Reset();
426 }
427
428 // Make sure that pending requests get serviced after active requests get
429 // cancelled.
430 TEST_F(WebSocketTransportClientSocketPoolTest,
431 CancelActiveRequestWithPendingRequests) {
432 client_socket_factory_.set_client_socket_type(
433 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
434
435 // Queue up all the requests
436 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
437 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
438 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
439 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
440 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
441 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
442 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
443 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
444 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
445
446 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
447 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
448 for (int i = 0; i < kMaxSocketsPerGroup; i++)
449 request(i)->handle()->Reset();
450
451 // Let's wait for the rest to complete now.
452 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
453 EXPECT_EQ(OK, request(i)->WaitForResult());
454 request(i)->handle()->Reset();
455 }
456
457 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
458 }
459
460 // Make sure that pending requests get serviced after active requests fail.
461 TEST_F(WebSocketTransportClientSocketPoolTest,
462 FailingActiveRequestWithPendingRequests) {
463 client_socket_factory_.set_client_socket_type(
464 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
465
466 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
467 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
468
469 // Queue up all the requests
470 for (int i = 0; i < kNumRequests; i++)
471 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
472
473 for (int i = 0; i < kNumRequests; i++)
474 EXPECT_EQ(ERR_CONNECTION_FAILED, request(i)->WaitForResult());
475 }
476
477 // The lock on the endpoint is released when a ClientSocketHandle is reset.
478 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
479 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
480 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
481 EXPECT_EQ(OK, request(0)->WaitForResult());
482 EXPECT_FALSE(request(1)->handle()->is_initialized());
483 request(0)->handle()->Reset();
484 base::RunLoop().RunUntilIdle();
485 EXPECT_TRUE(request(1)->handle()->is_initialized());
486 }
487
488 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
489 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
490 TestCompletionCallback callback;
491 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle);
492 int rv = handle->Init(
493 "a", params_, LOW, callback.callback(), &pool_, BoundNetLog());
494 EXPECT_EQ(ERR_IO_PENDING, rv);
495
496 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
497 EXPECT_EQ(OK, callback.WaitForResult());
498 EXPECT_FALSE(request(0)->handle()->is_initialized());
499 handle.reset();
500 base::RunLoop().RunUntilIdle();
501 EXPECT_TRUE(request(0)->handle()->is_initialized());
502 }
503
504 // A new connection is performed when the lock on the previous connection is
505 // explicity released.
506 TEST_F(WebSocketTransportClientSocketPoolTest,
507 ConnectionProceedsOnExplicitRelease) {
508 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
509 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
510 EXPECT_EQ(OK, request(0)->WaitForResult());
511 EXPECT_FALSE(request(1)->handle()->is_initialized());
512 WebSocketTransportClientSocketPool::UnlockEndpoint(request(0)->handle());
513 base::RunLoop().RunUntilIdle();
514 EXPECT_TRUE(request(1)->handle()->is_initialized());
515 }
516
517 // A connection which is cancelled before completion does not block subsequent
518 // connections.
519 TEST_F(WebSocketTransportClientSocketPoolTest,
520 CancelDuringConnectionReleasesLock) {
521 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
522 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
523 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
524
525 client_socket_factory_.set_client_socket_types(case_types,
526 arraysize(case_types));
527
528 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
529 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
530 base::RunLoop().RunUntilIdle();
531 pool_.CancelRequest("a", (request(0))->handle());
532 EXPECT_EQ(OK, request(1)->WaitForResult());
533 }
534
535 // Test the case of the IPv6 address stalling, and falling back to the IPv4
536 // socket which finishes first.
537 TEST_F(WebSocketTransportClientSocketPoolTest,
538 IPv6FallbackSocketIPv4FinishesFirst) {
539 WebSocketTransportClientSocketPool pool(kMaxSockets,
540 kMaxSocketsPerGroup,
541 histograms_.get(),
542 host_resolver_.get(),
543 &client_socket_factory_,
544 NULL);
545
546 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
547 // This is the IPv6 socket.
548 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
549 // This is the IPv4 socket.
550 MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET};
551
552 client_socket_factory_.set_client_socket_types(case_types, 2);
553
554 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
555 host_resolver_->rules()->AddIPLiteralRule(
556 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
557
558 TestCompletionCallback callback;
559 ClientSocketHandle handle;
560 int rv =
561 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
562 EXPECT_EQ(ERR_IO_PENDING, rv);
563 EXPECT_FALSE(handle.is_initialized());
564 EXPECT_FALSE(handle.socket());
565
566 EXPECT_EQ(OK, callback.WaitForResult());
567 EXPECT_TRUE(handle.is_initialized());
568 EXPECT_TRUE(handle.socket());
569 IPEndPoint endpoint;
570 handle.socket()->GetLocalAddress(&endpoint);
571 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
572 EXPECT_EQ(2, client_socket_factory_.allocation_count());
573 }
574
575 // Test the case of the IPv6 address being slow, thus falling back to trying to
576 // connect to the IPv4 address, but having the connect to the IPv6 address
577 // finish first.
578 TEST_F(WebSocketTransportClientSocketPoolTest,
579 IPv6FallbackSocketIPv6FinishesFirst) {
580 WebSocketTransportClientSocketPool pool(kMaxSockets,
581 kMaxSocketsPerGroup,
582 histograms_.get(),
583 host_resolver_.get(),
584 &client_socket_factory_,
585 NULL);
586
587 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
588 // This is the IPv6 socket.
589 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
590 // This is the IPv4 socket.
591 MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET};
592
593 client_socket_factory_.set_client_socket_types(case_types, 2);
594 client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds(
595 TransportConnectJobHelper::kIPv6FallbackTimerInMs + 50));
596
597 // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
598 host_resolver_->rules()->AddIPLiteralRule(
599 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
600
601 TestCompletionCallback callback;
602 ClientSocketHandle handle;
603 int rv =
604 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
605 EXPECT_EQ(ERR_IO_PENDING, rv);
606 EXPECT_FALSE(handle.is_initialized());
607 EXPECT_FALSE(handle.socket());
608
609 EXPECT_EQ(OK, callback.WaitForResult());
610 EXPECT_TRUE(handle.is_initialized());
611 EXPECT_TRUE(handle.socket());
612 IPEndPoint endpoint;
613 handle.socket()->GetLocalAddress(&endpoint);
614 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
615 EXPECT_EQ(2, client_socket_factory_.allocation_count());
616 }
617
618 TEST_F(WebSocketTransportClientSocketPoolTest,
619 IPv6NoIPv4AddressesToFallbackTo) {
620 WebSocketTransportClientSocketPool pool(kMaxSockets,
621 kMaxSocketsPerGroup,
622 histograms_.get(),
623 host_resolver_.get(),
624 &client_socket_factory_,
625 NULL);
626
627 client_socket_factory_.set_client_socket_type(
628 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
629
630 // Resolve an AddressList with only IPv6 addresses.
631 host_resolver_->rules()->AddIPLiteralRule(
632 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
633
634 TestCompletionCallback callback;
635 ClientSocketHandle handle;
636 int rv =
637 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
638 EXPECT_EQ(ERR_IO_PENDING, rv);
639 EXPECT_FALSE(handle.is_initialized());
640 EXPECT_FALSE(handle.socket());
641
642 EXPECT_EQ(OK, callback.WaitForResult());
643 EXPECT_TRUE(handle.is_initialized());
644 EXPECT_TRUE(handle.socket());
645 IPEndPoint endpoint;
646 handle.socket()->GetLocalAddress(&endpoint);
647 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
648 EXPECT_EQ(1, client_socket_factory_.allocation_count());
649 }
650
651 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
652 WebSocketTransportClientSocketPool pool(kMaxSockets,
653 kMaxSocketsPerGroup,
654 histograms_.get(),
655 host_resolver_.get(),
656 &client_socket_factory_,
657 NULL);
658
659 client_socket_factory_.set_client_socket_type(
660 MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
661
662 // Resolve an AddressList with only IPv4 addresses.
663 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
664
665 TestCompletionCallback callback;
666 ClientSocketHandle handle;
667 int rv =
668 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
669 EXPECT_EQ(ERR_IO_PENDING, rv);
670 EXPECT_FALSE(handle.is_initialized());
671 EXPECT_FALSE(handle.socket());
672
673 EXPECT_EQ(OK, callback.WaitForResult());
674 EXPECT_TRUE(handle.is_initialized());
675 EXPECT_TRUE(handle.socket());
676 IPEndPoint endpoint;
677 handle.socket()->GetLocalAddress(&endpoint);
678 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
679 EXPECT_EQ(1, client_socket_factory_.allocation_count());
680 }
681
682 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
683 // proceeed immediately.
684 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
685 WebSocketTransportClientSocketPool pool(kMaxSockets,
686 kMaxSocketsPerGroup,
687 histograms_.get(),
688 host_resolver_.get(),
689 &client_socket_factory_,
690 NULL);
691
692 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
693 // First IPv6 socket.
694 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
695 // Second IPv6 socket.
696 MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET,
697 // This is the IPv4 socket.
698 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET};
699
700 client_socket_factory_.set_client_socket_types(case_types,
701 arraysize(case_types));
702
703 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
704 host_resolver_->rules()->AddIPLiteralRule(
705 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
706 host_resolver_->set_synchronous_mode(true);
707 TestCompletionCallback callback;
708 ClientSocketHandle handle;
709 int rv =
710 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
711 EXPECT_EQ(OK, rv);
712 ASSERT_TRUE(handle.socket());
713
714 IPEndPoint endpoint;
715 handle.socket()->GetPeerAddress(&endpoint);
716 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
717 }
718
719 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
720 // connections proceed immediately.
721 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
722 WebSocketTransportClientSocketPool pool(kMaxSockets,
723 kMaxSocketsPerGroup,
724 histograms_.get(),
725 host_resolver_.get(),
726 &client_socket_factory_,
727 NULL);
728
729 MockTransportClientSocketFactory::ClientSocketType case_types[] = {
730 // First IPv6 socket.
731 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
732 // Second IPv6 socket.
733 MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET,
734 // This is the IPv4 socket.
735 MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET};
736
737 client_socket_factory_.set_client_socket_types(case_types,
738 arraysize(case_types));
739
740 // Resolve an AddressList with two IPv6 addresses and then a IPv4 address.
741 host_resolver_->rules()->AddIPLiteralRule(
742 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
743
744 TestCompletionCallback callback;
745 ClientSocketHandle handle;
746 int rv =
747 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
748 EXPECT_EQ(ERR_IO_PENDING, rv);
749 EXPECT_FALSE(handle.socket());
750
751 base::Time start(base::Time::NowFromSystemTime());
752 EXPECT_EQ(OK, callback.WaitForResult());
753 EXPECT_LT(base::Time::NowFromSystemTime() - start,
754 base::TimeDelta::FromMilliseconds(
755 TransportConnectJobHelper::kIPv6FallbackTimerInMs));
756 ASSERT_TRUE(handle.socket());
757
758 IPEndPoint endpoint;
759 handle.socket()->GetPeerAddress(&endpoint);
760 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
761 }
762
763 // If two sockets connect successfully, the one which connected first wins (this
764 // can only happen if the sockets are different types, since sockets of the same
765 // type do not race).
766 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
767 WebSocketTransportClientSocketPool pool(kMaxSockets,
768 kMaxSocketsPerGroup,
769 histograms_.get(),
770 host_resolver_.get(),
771 &client_socket_factory_,
772 NULL);
773
774 client_socket_factory_.set_client_socket_type(
775 MockTransportClientSocketFactory::MOCK_TRIGGERABLE_CLIENT_SOCKET);
776
777 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
778 host_resolver_->rules()->AddIPLiteralRule(
779 "*", "2:abcd::3:4:ff,2.2.2.2", std::string());
780
781 TestCompletionCallback callback;
782 ClientSocketHandle handle;
783 int rv =
784 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
785 EXPECT_EQ(ERR_IO_PENDING, rv);
786 ASSERT_FALSE(handle.socket());
787
788 base::Closure ipv6_connect_trigger =
789 client_socket_factory_.WaitForTriggerableSocketCreation();
790 base::Closure ipv4_connect_trigger =
791 client_socket_factory_.WaitForTriggerableSocketCreation();
792
793 ipv4_connect_trigger.Run();
794 ipv6_connect_trigger.Run();
795
796 EXPECT_EQ(OK, callback.WaitForResult());
797 ASSERT_TRUE(handle.socket());
798
799 IPEndPoint endpoint;
800 handle.socket()->GetPeerAddress(&endpoint);
801 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
802 }
803
804 // We should not report failure until all connections have failed.
805 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
806 WebSocketTransportClientSocketPool pool(kMaxSockets,
807 kMaxSocketsPerGroup,
808 histograms_.get(),
809 host_resolver_.get(),
810 &client_socket_factory_,
811 NULL);
812
813 client_socket_factory_.set_client_socket_type(
814 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
815 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(
816 TransportConnectJobHelper::kIPv6FallbackTimerInMs / 3);
817 client_socket_factory_.set_delay(delay);
818
819 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 address.
820 host_resolver_->rules()->AddIPLiteralRule("*",
821 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
822 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
823 "1.1.1.1,2.2.2.2",
824 std::string());
825
826 // Expected order of events:
827 // After 100ms: Connect to 1:abcd::3:4:ff times out
828 // After 200ms: Connect to 2:abcd::3:4:ff times out
829 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
830 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
831 // After 500ms: Connect to 2.2.2.2 times out
832
833 TestCompletionCallback callback;
834 ClientSocketHandle handle;
835 base::Time start(base::Time::NowFromSystemTime());
836 int rv =
837 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
838 EXPECT_EQ(ERR_IO_PENDING, rv);
839
840 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
841
842 EXPECT_GE(base::Time::NowFromSystemTime() - start, delay * 5);
843 }
844
845 // Global timeout for all connects applies. This test is disabled by default
846 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
847 // want to run it.
848 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
849 WebSocketTransportClientSocketPool pool(kMaxSockets,
850 kMaxSocketsPerGroup,
851 histograms_.get(),
852 host_resolver_.get(),
853 &client_socket_factory_,
854 NULL);
855 const base::TimeDelta connect_job_timeout = pool.ConnectionTimeout();
856
857 client_socket_factory_.set_client_socket_type(
858 MockTransportClientSocketFactory::MOCK_DELAYED_FAILING_CLIENT_SOCKET);
859 client_socket_factory_.set_delay(base::TimeDelta::FromSeconds(1) +
860 connect_job_timeout / 6);
861
862 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 address.
863 host_resolver_->rules()->AddIPLiteralRule("*",
864 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
865 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
866 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
867 "1.1.1.1,2.2.2.2,3.3.3.3,"
868 "4.4.4.4,5.5.5.5,6.6.6.6",
869 std::string());
870
871 TestCompletionCallback callback;
872 ClientSocketHandle handle;
873
874 int rv =
875 handle.Init("a", params_, LOW, callback.callback(), &pool, BoundNetLog());
876 EXPECT_EQ(ERR_IO_PENDING, rv);
877
878 EXPECT_EQ(ERR_TIMED_OUT, callback.WaitForResult());
879 }
880
881 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) {
882 host_resolver_->set_synchronous_mode(true);
883 for (int i = 0; i < kMaxSockets; ++i) {
884 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
885 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
886 }
887 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
888 }
889
890 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
891 for (int i = 0; i < kMaxSockets + 1; ++i) {
892 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
893 }
894 // Now there are 32 sockets waiting to connect, and one stalled.
895 for (int i = 0; i < kMaxSockets; ++i) {
896 base::RunLoop().RunUntilIdle();
897 EXPECT_TRUE(request(i)->handle()->is_initialized());
898 EXPECT_TRUE(request(i)->handle()->socket());
899 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
900 }
901 // Now there are 32 sockets connected, and one stalled.
902 base::RunLoop().RunUntilIdle();
903 EXPECT_FALSE(request(kMaxSockets)->handle()->is_initialized());
904 EXPECT_FALSE(request(kMaxSockets)->handle()->socket());
905 }
906
907 TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) {
908 host_resolver_->set_synchronous_mode(true);
909 for (int i = 0; i < kMaxSockets; ++i) {
910 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
911 WebSocketTransportClientSocketPool::UnlockEndpoint(request(i)->handle());
912 }
913
914 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
915 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
916 EXPECT_TRUE(request(kMaxSockets)->handle()->is_initialized());
917 EXPECT_TRUE(request(kMaxSockets)->handle()->socket());
918 }
919
920 TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) {
921 for (int i = 0; i < kMaxSockets + 1; ++i) {
922 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
923 }
924 EXPECT_EQ(OK, request(0)->WaitForResult());
925 EXPECT_TRUE(pool_.IsStalled());
926 }
927
928 TEST_F(WebSocketTransportClientSocketPoolTest,
929 CancellingPendingSocketUnstallsStalledSocket) {
930 for (int i = 0; i < kMaxSockets + 1; ++i) {
931 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
932 }
933 EXPECT_EQ(OK, request(0)->WaitForResult());
934 request(1)->handle()->Reset();
935 base::RunLoop().RunUntilIdle();
936 EXPECT_FALSE(pool_.IsStalled());
937 }
938
939 TEST_F(WebSocketTransportClientSocketPoolTest,
940 LoadStateOfStalledSocketIsWaitingForAvailableSocket) {
941 for (int i = 0; i < kMaxSockets + 1; ++i) {
942 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
943 }
944 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
945 pool_.GetLoadState("a", request(kMaxSockets)->handle()));
946 }
947
948 TEST_F(WebSocketTransportClientSocketPoolTest,
949 CancellingStalledSocketUnstallsPool) {
950 for (int i = 0; i < kMaxSockets + 1; ++i) {
951 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
952 }
953 request(kMaxSockets)->handle()->Reset();
954 EXPECT_FALSE(pool_.IsStalled());
955 }
956
957 TEST_F(WebSocketTransportClientSocketPoolTest,
958 FlushWithErrorFlushesPendingConnections) {
959 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
960 pool_.FlushWithError(ERR_FAILED);
961 EXPECT_EQ(ERR_FAILED, request(0)->WaitForResult());
962 }
963
964 TEST_F(WebSocketTransportClientSocketPoolTest,
965 FlushWithErrorFlushesStalledConnections) {
966 for (int i = 0; i < kMaxSockets + 1; ++i) {
967 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
968 }
969 pool_.FlushWithError(ERR_FAILED);
970 EXPECT_EQ(ERR_FAILED, request(kMaxSockets)->WaitForResult());
971 }
972
973 TEST_F(WebSocketTransportClientSocketPoolTest,
974 AfterFlushWithErrorCanMakeNewConnections) {
975 for (int i = 0; i < kMaxSockets + 1; ++i) {
976 EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
977 }
978 pool_.FlushWithError(ERR_FAILED);
979 host_resolver_->set_synchronous_mode(true);
980 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
981 }
982
983 } // namespace
984
985 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698