diff options
author | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 08:19:34 +0000 |
---|---|---|
committer | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 08:19:34 +0000 |
commit | c83658c33bdf286c7d4cf8f766616e297624daec (patch) | |
tree | 2435c853fe8b55dead3197e8863eb666c384b869 /net/socket/tcp_client_socket_pool_unittest.cc | |
parent | db4791c48136f73181a337e4469578e2e45dba60 (diff) | |
download | chromium_src-c83658c33bdf286c7d4cf8f766616e297624daec.zip chromium_src-c83658c33bdf286c7d4cf8f766616e297624daec.tar.gz chromium_src-c83658c33bdf286c7d4cf8f766616e297624daec.tar.bz2 |
Fix to bug 39063.
The problem was the backup connect job was failed; and we didn't
properly track the backup_job in the group jobs list.
BUG=39063
TEST=TCPClientSocketPoolTest.BackupConnectFail
Review URL: http://codereview.chromium.org/1262001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42440 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/tcp_client_socket_pool_unittest.cc')
-rw-r--r-- | net/socket/tcp_client_socket_pool_unittest.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/net/socket/tcp_client_socket_pool_unittest.cc b/net/socket/tcp_client_socket_pool_unittest.cc index 4ef6b98..e7c8a9f 100644 --- a/net/socket/tcp_client_socket_pool_unittest.cc +++ b/net/socket/tcp_client_socket_pool_unittest.cc @@ -228,6 +228,7 @@ class MockClientSocketFactory : public ClientSocketFactory { // Set a list of ClientSocketTypes to be used. void set_client_socket_types(ClientSocketType* type_list) { client_socket_types_ = type_list; + client_socket_index_ = 0; } private: @@ -750,6 +751,97 @@ TEST_F(TCPClientSocketPoolTest, BackupSocketCancel) { } } +// Test the case where a socket took long enough to start the creation +// of the backup socket and never completes, and then the backup +// connection fails. +TEST_F(TCPClientSocketPoolTest, BackupSocketFailAfterStall) { + MockClientSocketFactory::ClientSocketType case_types[] = { + // The first socket will not connect. + MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, + // The second socket will fail immediately. + MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET + }; + + client_socket_factory_.set_client_socket_types(case_types); + + EXPECT_EQ(0, pool_->IdleSocketCount()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + TCPSocketParams dest("www.google.com", 80, LOW, GURL(), false); + int rv = handle.Init("b", dest, LOW, &callback, pool_, NULL); + EXPECT_EQ(ERR_IO_PENDING, rv); + EXPECT_FALSE(handle.is_initialized()); + EXPECT_FALSE(handle.socket()); + + // Create the first socket, set the timer. + MessageLoop::current()->RunAllPending(); + + // Wait for the backup socket timer to fire. + PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs); + + // Let the second connect be synchronous. Otherwise, the emulated + // host resolution takes an extra trip through the message loop. + host_resolver_->set_synchronous_mode(true); + + // Let the appropriate socket connect. + MessageLoop::current()->RunAllPending(); + + EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); + EXPECT_FALSE(handle.is_initialized()); + EXPECT_FALSE(handle.socket()); + EXPECT_EQ(0, pool_->IdleSocketCount()); + handle.Reset(); + + // Reset for the next case. + host_resolver_->set_synchronous_mode(false); +} + +// Test the case where a socket took long enough to start the creation +// of the backup socket and eventually completes, but the backup socket +// fails. +TEST_F(TCPClientSocketPoolTest, BackupSocketFailAfterDelay) { + MockClientSocketFactory::ClientSocketType case_types[] = { + // The first socket will connect, although delayed. + MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET, + // The second socket will not connect. + MockClientSocketFactory::MOCK_FAILING_CLIENT_SOCKET + }; + + client_socket_factory_.set_client_socket_types(case_types); + + EXPECT_EQ(0, pool_->IdleSocketCount()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + TCPSocketParams dest("www.google.com", 80, LOW, GURL(), false); + int rv = handle.Init("b", dest, LOW, &callback, pool_, NULL); + EXPECT_EQ(ERR_IO_PENDING, rv); + EXPECT_FALSE(handle.is_initialized()); + EXPECT_FALSE(handle.socket()); + + // Create the first socket, set the timer. + MessageLoop::current()->RunAllPending(); + + // Wait for the backup socket timer to fire. + PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs); + + // Let the second connect be synchronous. Otherwise, the emulated + // host resolution takes an extra trip through the message loop. + host_resolver_->set_synchronous_mode(true); + + // Let the appropriate socket connect. + MessageLoop::current()->RunAllPending(); + + EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); + EXPECT_FALSE(handle.is_initialized()); + EXPECT_FALSE(handle.socket()); + handle.Reset(); + + // Reset for the next case. + host_resolver_->set_synchronous_mode(false); +} + } // namespace } // namespace net |