15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/transport_client_socket_pool.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/capturing_net_log.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info_test_util.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_histograms.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "net/socket/transport_client_socket_pool_test_util.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using internal::ClientSocketPoolBaseHelper;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSockets = 32;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxSocketsPerGroup = 6;
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst RequestPriority kDefaultPriority = LOW;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TransportClientSocketPoolTest : public testing::Test {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPoolTest()
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : connect_backup_jobs_enabled_(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true)),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        params_(
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            new TransportSocketParams(
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                HostPortPair("www.google.com", 80),
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                false,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                false,
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                OnHostResolutionCallback(),
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        histograms_(new ClientSocketPoolHistograms("TCPUnitTest")),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        host_resolver_(new MockHostResolver),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        client_socket_factory_(&net_log_),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pool_(kMaxSockets,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              kMaxSocketsPerGroup,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              histograms_.get(),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_resolver_.get(),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &client_socket_factory_,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              NULL) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TransportClientSocketPoolTest() {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    internal::ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        connect_backup_jobs_enabled_);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TransportSocketParams> CreateParamsForTCPFastOpen() {
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return new TransportSocketParams(HostPortPair("www.google.com", 80),
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          false, false, OnHostResolutionCallback(),
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED);
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int StartRequest(const std::string& group_name, RequestPriority priority) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<TransportSocketParams> params(new TransportSocketParams(
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        HostPortPair("www.google.com", 80), false, false,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        OnHostResolutionCallback(),
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_base_.StartRequestUsingPool(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &pool_, group_name, priority, params);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetOrderOfRequest(size_t index) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_base_.GetOrderOfRequest(index);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return test_base_.ReleaseOneConnection(keep_alive);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_base_.ReleaseAllConnections(keep_alive);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<TestSocketRequest>* requests() { return test_base_.requests(); }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t completion_count() const { return test_base_.completion_count(); }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool connect_backup_jobs_enabled_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> params_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ClientSocketPoolHistograms> histograms_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockHostResolver> host_resolver_;
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory client_socket_factory_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool pool_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolTest test_base_;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TransportClientSocketPoolTest);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip_number;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint addrlist_v4_1(ip_number, 80);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint addrlist_v4_2(ip_number, 80);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint addrlist_v6_1(ip_number, 80);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint addrlist_v6_2(ip_number, 80);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test 1: IPv4 only.  Expect no change.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.clear();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_1);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_2);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, addrlist.size());
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[0].GetFamily());
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[1].GetFamily());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test 2: IPv6 only.  Expect no change.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.clear();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_1);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_2);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, addrlist.size());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[0].GetFamily());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[1].GetFamily());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test 3: IPv4 then IPv6.  Expect no change.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.clear();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_1);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_2);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_1);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_2);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, addrlist.size());
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[0].GetFamily());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[1].GetFamily());
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[2].GetFamily());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[3].GetFamily());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test 4: IPv6, IPv4, IPv6, IPv4.  Expect first IPv6 moved to the end.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.clear();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_1);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_1);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_2);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_2);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, addrlist.size());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[0].GetFamily());
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[1].GetFamily());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[2].GetFamily());
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[3].GetFamily());
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test 5: IPv6, IPv6, IPv4, IPv4.  Expect first two IPv6's moved to the end.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.clear();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_1);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v6_2);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_1);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  addrlist.push_back(addrlist_v4_2);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportConnectJob::MakeAddressListStartWithIPv4(&addrlist);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(4u, addrlist.size());
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[0].GetFamily());
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV4, addrlist[1].GetFamily());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[2].GetFamily());
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ADDRESS_FAMILY_IPV6, addrlist[3].GetFamily());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, Basic) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool_,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingInfoConnectedNotReused(handle);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that TransportConnectJob passes on its priority to its
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// HostResolver request on Init.
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, SetResolvePriorityOnInit) {
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RequestPriority priority = static_cast<RequestPriority>(i);
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    TestCompletionCallback callback;
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ClientSocketHandle handle;
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              handle.Init("a", params_, priority, callback.callback(), &pool_,
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          BoundNetLog()));
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_EQ(priority, host_resolver_->last_request_priority());
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name");
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("unresolvable.host.name", 80);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      host_port_pair, false, false, OnHostResolutionCallback(),
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", dest, kDefaultPriority, callback.callback(),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback.WaitForResult());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) {
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback.callback(),
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the host resolutions complete synchronously this time.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_FAILED,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback.callback(),
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, PendingRequests) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request finishes asynchronously.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all subsequent host resolutions complete synchronously.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rest of them finish synchronously, until we reach the per-group limit.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The rest are pending since we've used all active sockets.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kMaxSocketsPerGroup, client_socket_factory_.allocation_count());
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One initial asynchronous request and then 10 pending requests.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11U, completion_count());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First part of requests, all with the same priority, finishes in FIFO order.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, GetOrderOfRequest(1));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, GetOrderOfRequest(2));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, GetOrderOfRequest(3));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, GetOrderOfRequest(4));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, GetOrderOfRequest(5));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, GetOrderOfRequest(6));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that rest of the requests complete in the order of priority.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7, GetOrderOfRequest(7));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14, GetOrderOfRequest(8));
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(15, GetOrderOfRequest(9));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, GetOrderOfRequest(10));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, GetOrderOfRequest(11));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, GetOrderOfRequest(12));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(16, GetOrderOfRequest(13));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, GetOrderOfRequest(14));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, GetOrderOfRequest(15));
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9, GetOrderOfRequest(16));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we test order of all requests made.
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(17));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request finishes asynchronously.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all subsequent host resolutions complete synchronously.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Rest of them finish synchronously, until we reach the per-group limit.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The rest are pending since we've used all active sockets.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The pending requests should finish successfully.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[6]->WaitForResult());
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[7]->WaitForResult());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[8]->WaitForResult());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[9]->WaitForResult());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[10]->WaitForResult());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<int>(requests()->size()),
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client_socket_factory_.allocation_count());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First asynchronous request, and then last 5 pending requests.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6U, completion_count());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test will start up a RequestSocket() and then immediately Cancel() it.
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The pending host resolution will eventually complete, and destroy the
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPool which will crash if the group was not cleared properly.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, CancelRequestClearGroup) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback.callback(),
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, TwoRequestsCancelOne) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle2;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback.callback(),
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle2.Init("a", params_, kDefaultPriority, callback2.callback(),
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         &pool_, BoundNetLog()));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle2.Reset();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) {
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback.callback(),
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            handle.Init("a", params_, kDefaultPriority, callback2.callback(),
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        &pool_, BoundNetLog()));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At this point, handle has two ConnectingSockets out for it.  Due to the
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // setting the mock resolver into synchronous mode, the host resolution for
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // both will return in the same loop of the MessageLoop.  The client socket
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is a pending socket, so the Connect() will asynchronously complete on the
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // next loop of the MessageLoop.  That means that the first
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ConnectingSocket will enter OnIOComplete, and then the second one will.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the first one is not cancelled, it will advance the load state, and
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then the second one will crash.
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(callback.have_result());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, CancelRequest) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First request finishes asynchronously.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, (*requests())[0]->WaitForResult());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make all subsequent host resolutions complete synchronously.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, StartRequest("a", kDefaultPriority));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reached per-group limit, queue up requests.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", MEDIUM));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", HIGHEST));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOW));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", LOWEST));
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel a request.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t index_to_cancel = kMaxSocketsPerGroup + 2;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE((*requests())[index_to_cancel]->handle()->is_initialized());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*requests())[index_to_cancel]->handle()->Reset();
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kMaxSocketsPerGroup,
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            client_socket_factory_.allocation_count());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, GetOrderOfRequest(1));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, GetOrderOfRequest(2));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, GetOrderOfRequest(3));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(4, GetOrderOfRequest(4));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, GetOrderOfRequest(5));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(6, GetOrderOfRequest(6));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(14, GetOrderOfRequest(7));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(7, GetOrderOfRequest(8));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetOrderOfRequest(9));  // Canceled request.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9, GetOrderOfRequest(10));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, GetOrderOfRequest(11));
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(11, GetOrderOfRequest(12));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, GetOrderOfRequest(13));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, GetOrderOfRequest(14));
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, GetOrderOfRequest(15));
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(15, GetOrderOfRequest(16));
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure we test order of all requests made.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(17));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RequestSocketCallback : public TestCompletionCallbackBase {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestSocketCallback(ClientSocketHandle* handle,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        TransportClientSocketPool* pool)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : handle_(handle),
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pool_(pool),
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        within_callback_(false),
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        callback_(base::Bind(&RequestSocketCallback::OnComplete,
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             base::Unretained(this))) {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~RequestSocketCallback() {}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CompletionCallback& callback() const { return callback_; }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnComplete(int result) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetResult(result);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(OK, result);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!within_callback_) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't allow reuse of the socket.  Disconnect it and then release it and
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // run through the MessageLoop once to get it completely released.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      handle_->socket()->Disconnect();
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      handle_->Reset();
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::MessageLoop::ScopedNestableTaskAllower allow(
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            base::MessageLoop::current());
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::MessageLoop::current()->RunUntilIdle();
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      within_callback_ = true;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          HostPortPair("www.google.com", 80), false, false,
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          OnHostResolutionCallback(),
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv = handle_->Init("a", dest, LOWEST, callback(), pool_,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             BoundNetLog());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(OK, rv);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle* const handle_;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* const pool_;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool within_callback_;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompletionCallback callback_;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RequestSocketCallback);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, RequestTwice) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RequestSocketCallback callback(&handle, &pool_);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TransportSocketParams> dest(new TransportSocketParams(
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostPortPair("www.google.com", 80), false, false,
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OnHostResolutionCallback(),
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = handle.Init("a", dest, LOWEST, callback.callback(), &pool_,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback is going to request "www.google.com". We want it to complete
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // synchronously this time.
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that pending requests get serviced after active requests get
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cancelled.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, CancelActiveRequestWithPendingRequests) {
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Queue up all the requests
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, kMaxSocketsPerGroup requests should be active.  Let's cancel them.
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxSocketsPerGroup; i++)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*requests())[i]->handle()->Reset();
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let's wait for the rest to complete now.
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, (*requests())[i]->WaitForResult());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*requests())[i]->handle()->Reset();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that pending requests get serviced after active requests fail.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, FailingActiveRequestWithPendingRequests) {
559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
560116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_PENDING_FAILING_CLIENT_SOCKET);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LE(kNumRequests, kMaxSockets);  // Otherwise the test will hang.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Queue up all the requests
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumRequests; i++)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, StartRequest("a", kDefaultPriority));
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumRequests; i++)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CONNECTION_FAILED, (*requests())[i]->WaitForResult());
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClientSocketHandle handle;
5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool_,
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       BoundNetLog());
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(handle.socket());
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(handle.socket());
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingInfoConnectedNotReused(handle);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  handle.Reset();
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Need to run all pending to release the socket back to the pool.
58990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now we should have 1 idle socket.
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, pool_.IdleSocketCount());
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = handle.Init("a", params_, LOW, callback.callback(), &pool_,
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   BoundNetLog());
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, pool_.IdleSocketCount());
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingInfoConnectedReused(handle);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, ResetIdleSocketsOnIPAddressChange) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
6043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool_,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to run all pending to release the socket back to the pool.
61790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now we should have 1 idle socket.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, pool_.IdleSocketCount());
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After an IP address change, we should have 0 idle sockets.
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
62490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();  // Notification happens async.
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, pool_.IdleSocketCount());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Case 1 tests the first socket stalling, and the backup connecting.
631116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case1_types[] = {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first socket will not connect.
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The second socket will connect more quickly.
635116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_CLIENT_SOCKET
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Case 2 tests the first socket being slow, so that we start the
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second connect, but the second connect stalls, and we still
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complete the first.
641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case2_types[] = {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first socket will connect, although delayed.
643116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The second socket will not connect.
645116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
648116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType* cases[2] = {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case1_types,
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case2_types
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < arraysize(cases); ++index) {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    client_socket_factory_.set_client_socket_types(cases[index], 2);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, pool_.IdleSocketCount());
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketHandle handle;
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int rv = handle.Init("b", params_, LOW, callback.callback(), &pool_,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         BoundNetLog());
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.is_initialized());
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.socket());
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the first socket, set the timer.
66790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wait for the backup socket timer to fire.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ClientSocketPool::kMaxConnectRetryIntervalMs + 50));
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let the appropriate socket connect.
67490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, callback.WaitForResult());
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handle.is_initialized());
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handle.socket());
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // One socket is stalled, the other is active.
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, pool_.IdleSocketCount());
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle.Reset();
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Close all pending connect jobs and existing sockets.
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pool_.FlushWithError(ERR_NETWORK_CHANGED);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where a socket took long enough to start the creation
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the backup socket, but then we cancelled the request after that.
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, BackupSocketCancel) {
692116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
693116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum { CANCEL_BEFORE_WAIT, CANCEL_AFTER_WAIT };
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int index = CANCEL_BEFORE_WAIT; index < CANCEL_AFTER_WAIT; ++index) {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, pool_.IdleSocketCount());
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSocketHandle handle;
7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int rv = handle.Init("c", params_, LOW, callback.callback(), &pool_,
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         BoundNetLog());
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.is_initialized());
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.socket());
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create the first socket, set the timer.
70990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (index == CANCEL_AFTER_WAIT) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Wait for the backup socket timer to fire.
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ClientSocketPool::kMaxConnectRetryIntervalMs));
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Let the appropriate socket connect.
71890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle.Reset();
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(callback.have_result());
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.is_initialized());
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handle.socket());
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // One socket is stalled, the other is active.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, pool_.IdleSocketCount());
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where a socket took long enough to start the creation
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the backup socket and never completes, and then the backup
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection fails.
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterStall) {
735116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first socket will not connect.
737116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The second socket will fail immediately.
739116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_client_socket_types(case_types, 2);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, pool_.IdleSocketCount());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("b", params_, LOW, callback.callback(), &pool_,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the first socket, set the timer.
75590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the backup socket timer to fire.
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientSocketPool::kMaxConnectRetryIntervalMs));
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the second connect be synchronous. Otherwise, the emulated
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // host resolution takes an extra trip through the message loop.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the appropriate socket connect.
76690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, pool_.IdleSocketCount());
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset for the next case.
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(false);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case where a socket took long enough to start the creation
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the backup socket and eventually completes, but the backup socket
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fails.
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) {
782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The first socket will connect, although delayed.
784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The second socket will not connect.
786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_client_socket_types(case_types, 2);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_delay(base::TimeDelta::FromSeconds(5));
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, pool_.IdleSocketCount());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
7963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("b", params_, LOW, callback.callback(), &pool_,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the first socket, set the timer.
80390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the backup socket timer to fire.
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientSocketPool::kMaxConnectRetryIntervalMs));
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the second connect be synchronous. Otherwise, the emulated
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // host resolution takes an extra trip through the message loop.
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(true);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the appropriate socket connect.
81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.Reset();
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset for the next case.
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_resolver_->set_synchronous_mode(false);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case of the IPv6 address stalling, and falling back to the IPv4
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// socket which finishes first.
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a pool without backup jobs.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool pool(kMaxSockets,
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMaxSocketsPerGroup,
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 histograms_.get(),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 host_resolver_.get(),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &client_socket_factory_,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
837116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is the IPv6 socket.
839116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is the IPv4 socket.
841116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_client_socket_types(case_types, 2);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver_->rules()
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string());
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool,
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.socket()->GetLocalAddress(&endpoint);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client_socket_factory_.allocation_count());
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case of the IPv6 address being slow, thus falling back to trying to
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connect to the IPv4 address, but having the connect to the IPv6 address
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// finish first.
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a pool without backup jobs.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool pool(kMaxSockets,
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMaxSocketsPerGroup,
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 histograms_.get(),
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 host_resolver_.get(),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &client_socket_factory_,
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
880116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is the IPv6 socket.
882116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET,
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is the IPv4 socket.
884116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_client_socket_types(case_types, 2);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  client_socket_factory_.set_delay(base::TimeDelta::FromMilliseconds(
889116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      TransportConnectJobHelper::kIPv6FallbackTimerInMs + 50));
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver_->rules()
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string());
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
8973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool,
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.socket()->GetLocalAddress(&endpoint);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, client_socket_factory_.allocation_count());
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) {
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a pool without backup jobs.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool pool(kMaxSockets,
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMaxSocketsPerGroup,
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 histograms_.get(),
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 host_resolver_.get(),
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &client_socket_factory_,
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
923116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resolve an AddressList with only IPv6 addresses.
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver_->rules()
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
9313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool,
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.socket()->GetLocalAddress(&endpoint);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client_socket_factory_.allocation_count());
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TransportClientSocketPoolTest, IPv4HasNoFallback) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a pool without backup jobs.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool pool(kMaxSockets,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 kMaxSocketsPerGroup,
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 histograms_.get(),
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 host_resolver_.get(),
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &client_socket_factory_,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  client_socket_factory_.set_default_client_socket_type(
957116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resolve an AddressList with only IPv4 addresses.
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketHandle handle;
9643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int rv = handle.Init("a", params_, LOW, callback.callback(), &pool,
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       BoundNetLog());
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.is_initialized());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle.socket());
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.is_initialized());
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(handle.socket());
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint endpoint;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handle.socket()->GetLocalAddress(&endpoint);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, client_socket_factory_.allocation_count());
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test that if TCP FastOpen is enabled, it is set on the socket
9801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// when we have only an IPv4 address.
9811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv4WithNoFallback) {
9821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a pool without backup jobs.
9831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
9841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TransportClientSocketPool pool(kMaxSockets,
9851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 kMaxSocketsPerGroup,
9861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 histograms_.get(),
9871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 host_resolver_.get(),
9881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &client_socket_factory_,
9891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL);
9901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_socket_factory_.set_default_client_socket_type(
9911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
9921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Resolve an AddressList with only IPv4 addresses.
9931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
9941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
9951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestCompletionCallback callback;
9961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketHandle handle;
9971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enable TCP FastOpen in TransportSocketParams.
9981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
9991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog());
10001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, callback.WaitForResult());
10011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(handle.socket()->UsingTCPFastOpen());
10021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
10031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test that if TCP FastOpen is enabled, it is set on the socket
10051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// when we have only IPv6 addresses.
10061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv6WithNoFallback) {
10071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a pool without backup jobs.
10081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
10091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TransportClientSocketPool pool(kMaxSockets,
10101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 kMaxSocketsPerGroup,
10111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 histograms_.get(),
10121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 host_resolver_.get(),
10131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &client_socket_factory_,
10141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL);
10151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_socket_factory_.set_default_client_socket_type(
10161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET);
10171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Resolve an AddressList with only IPv6 addresses.
10181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_resolver_->rules()
10191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
10201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestCompletionCallback callback;
10221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketHandle handle;
10231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enable TCP FastOpen in TransportSocketParams.
10241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
10251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog());
10261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, callback.WaitForResult());
10271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(handle.socket()->UsingTCPFastOpen());
10281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
10291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test that if TCP FastOpen is enabled, it does not do anything when there
10311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// is a IPv6 address with fallback to an IPv4 address. This test tests the case
10321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// when the IPv6 connect fails and the IPv4 one succeeds.
10331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TransportClientSocketPoolTest,
10341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           NoTCPFastOpenOnIPv6FailureWithIPv4Fallback) {
10351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a pool without backup jobs.
10361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
10371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TransportClientSocketPool pool(kMaxSockets,
10381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 kMaxSocketsPerGroup,
10391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 histograms_.get(),
10401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 host_resolver_.get(),
10411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &client_socket_factory_,
10421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL);
10431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
10451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This is the IPv6 socket.
10461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET,
10471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This is the IPv4 socket.
10481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
10491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
10501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_socket_factory_.set_client_socket_types(case_types, 2);
10511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
10521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_resolver_->rules()
10531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string());
10541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestCompletionCallback callback;
10561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketHandle handle;
10571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enable TCP FastOpen in TransportSocketParams.
10581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
10591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog());
10601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, callback.WaitForResult());
10611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that the socket used is connected to the fallback IPv4 address.
10621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IPEndPoint endpoint;
10631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.socket()->GetLocalAddress(&endpoint);
10641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kIPv4AddressSize, endpoint.address().size());
10651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(2, client_socket_factory_.allocation_count());
10661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that TCP FastOpen was not turned on for the socket.
10671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(handle.socket()->UsingTCPFastOpen());
10681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
10691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Test that if TCP FastOpen is enabled, it does not do anything when there
10711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// is a IPv6 address with fallback to an IPv4 address. This test tests the case
10721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// when the IPv6 connect succeeds.
10731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TransportClientSocketPoolTest,
10741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           NoTCPFastOpenOnIPv6SuccessWithIPv4Fallback) {
10751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a pool without backup jobs.
10761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false);
10771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TransportClientSocketPool pool(kMaxSockets,
10781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 kMaxSocketsPerGroup,
10791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 histograms_.get(),
10801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 host_resolver_.get(),
10811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &client_socket_factory_,
10821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 NULL);
10831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MockTransportClientSocketFactory::ClientSocketType case_types[] = {
10851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This is the IPv6 socket.
10861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET,
10871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This is the IPv4 socket.
10881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET
10891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
10901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_socket_factory_.set_client_socket_types(case_types, 2);
10911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Resolve an AddressList with a IPv6 address first and then a IPv4 address.
10921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  host_resolver_->rules()
10931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string());
10941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
10951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestCompletionCallback callback;
10961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ClientSocketHandle handle;
10971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enable TCP FastOpen in TransportSocketParams.
10981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen();
10991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog());
11001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(OK, callback.WaitForResult());
11011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that the socket used is connected to the IPv6 address.
11021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  IPEndPoint endpoint;
11031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  handle.socket()->GetLocalAddress(&endpoint);
11041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kIPv6AddressSize, endpoint.address().size());
11051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1, client_socket_factory_.allocation_count());
11061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that TCP FastOpen was not turned on for the socket.
11071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(handle.socket()->UsingTCPFastOpen());
11081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
11091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1113