Chromium Code Reviews| Index: chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc |
| diff --git a/chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc b/chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc |
| index d9e4aee5f49dbc0b3e828c00602002a071065b54..1374428447546f0bf4b0893fe3deaaa49deb5038 100644 |
| --- a/chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc |
| +++ b/chrome/browser/extensions/api/cast_channel/cast_socket_unittest.cc |
| @@ -4,10 +4,12 @@ |
| #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" |
| +#include "base/memory/weak_ptr.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/sys_byteorder.h" |
| +#include "base/timer/mock_timer.h" |
| #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" |
| #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" |
| #include "net/base/address_list.h" |
| @@ -21,6 +23,8 @@ |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| +const int64 kDistantTimeoutMillis = 100000; // 100 seconds (never hit). |
| + |
| using ::testing::_; |
| using ::testing::A; |
| using ::testing::DoAll; |
| @@ -79,7 +83,18 @@ class MockTCPSocket : public net::TCPClientSocket { |
| TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()), |
| connect_data_(connect_data) { } |
| + explicit MockTCPSocket(bool do_nothing) : |
| + TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()) { |
| + CHECK(do_nothing); |
| + do_nothing_ = true; |
| + } |
| + |
| virtual int Connect(const net::CompletionCallback& callback) OVERRIDE { |
| + if (do_nothing_) { |
| + // Stall the I/O event loop. |
| + return net::ERR_IO_PENDING; |
| + } |
| + |
| if (connect_data_.mode == net::ASYNC) { |
| CHECK_NE(connect_data_.result, net::ERR_IO_PENDING); |
| base::MessageLoop::current()->PostTask( |
| @@ -112,6 +127,7 @@ class MockTCPSocket : public net::TCPClientSocket { |
| private: |
| net::MockConnect connect_data_; |
| + bool do_nothing_; |
| }; |
| class CompleteHandler { |
| @@ -130,25 +146,33 @@ class TestCastSocket : public CastSocket { |
| MockCastSocketDelegate* delegate) { |
| return scoped_ptr<TestCastSocket>( |
| new TestCastSocket(delegate, CreateIPEndPoint(), |
| - CHANNEL_AUTH_TYPE_SSL)); |
| + CHANNEL_AUTH_TYPE_SSL, |
| + kDistantTimeoutMillis)); |
| } |
| static scoped_ptr<TestCastSocket> CreateSecure( |
| MockCastSocketDelegate* delegate) { |
| return scoped_ptr<TestCastSocket>( |
| new TestCastSocket(delegate, CreateIPEndPoint(), |
| - CHANNEL_AUTH_TYPE_SSL_VERIFIED)); |
| + CHANNEL_AUTH_TYPE_SSL_VERIFIED, |
| + kDistantTimeoutMillis)); |
| } |
| explicit TestCastSocket(MockCastSocketDelegate* delegate, |
| const net::IPEndPoint& ip_endpoint, |
| - ChannelAuthType channel_auth) : |
| + ChannelAuthType channel_auth, |
| + int64 timeout_ms) : |
| CastSocket("abcdefg", ip_endpoint, channel_auth, delegate, |
| - &capturing_net_log_), |
| + &capturing_net_log_, timeout_ms), |
| ip_(ip_endpoint), |
| connect_index_(0), |
| extract_cert_result_(true), |
| - verify_challenge_result_(true) { |
| + verify_challenge_result_(true), |
| + tcp_unresponsive_(false) { |
| + scoped_ptr<base::MockTimer> connect_timeout_timer_owned( |
| + new base::MockTimer(false, false)); |
| + connect_timeout_timer_ = connect_timeout_timer_owned.get(); |
|
mark a. foltz
2014/07/17 23:56:49
You are creating a shared ownership of the timer b
Kevin M
2014/07/22 18:51:49
Done.
|
| + InjectTimerForTesting(connect_timeout_timer_owned.PassAs<base::Timer>()); |
| } |
| static net::IPEndPoint CreateIPEndPoint() { |
| @@ -181,6 +205,9 @@ class TestCastSocket : public CastSocket { |
| void SetupSsl2Connect(net::IoMode mode, int result) { |
| ssl_connect_data_[1].reset(new net::MockConnect(mode, result)); |
| } |
| + void SetupTcp1ConnectUnresponsive() { |
| + tcp_unresponsive_ = true; |
| + } |
| void AddWriteResult(const net::MockWrite& write) { |
| writes_.push_back(write); |
| } |
| @@ -235,11 +262,19 @@ class TestCastSocket : public CastSocket { |
| verify_challenge_result_ = value; |
| } |
| + void TriggerTimeout() { |
| + connect_timeout_timer_->Fire(); |
| + } |
| + |
| private: |
| virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket() OVERRIDE { |
| - net::MockConnect* connect_data = tcp_connect_data_[connect_index_].get(); |
| - connect_data->peer_addr = ip_; |
| - return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(*connect_data)); |
| + if (tcp_unresponsive_) { |
| + return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(true)); |
| + } else { |
| + net::MockConnect* connect_data = tcp_connect_data_[connect_index_].get(); |
| + connect_data->peer_addr = ip_; |
| + return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(*connect_data)); |
| + } |
| } |
| virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket( |
| @@ -282,6 +317,9 @@ class TestCastSocket : public CastSocket { |
| bool extract_cert_result_; |
| // Simulated result of verifying challenge reply. |
| bool verify_challenge_result_; |
| + // If true, makes TCP connection process stall. For timeout testing. |
| + bool tcp_unresponsive_; |
| + base::MockTimer* connect_timeout_timer_; |
| }; |
| class CastSocketTest : public testing::Test { |
| @@ -520,6 +558,28 @@ TEST_F(CastSocketTest, TestConnectTcpConnectErrorSync) { |
| EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); |
| } |
| +// Test connection error - timeout |
| +TEST_F(CastSocketTest, TestConnectTcpTimeoutError) { |
| + CreateCastSocketSecure(); |
| + socket_->SetupTcp1ConnectUnresponsive(); |
| + EXPECT_CALL(handler_, OnConnectComplete(net::ERR_TIMED_OUT)); |
| + EXPECT_CALL(mock_delegate_, |
| + OnError(socket_.get(), |
| + cast_channel::CHANNEL_ERROR_CONNECT_TIMEOUT)); |
| + socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
| + base::Unretained(&handler_))); |
| + RunPendingTasks(); |
| + |
| + EXPECT_EQ(cast_channel::READY_STATE_CONNECTING, socket_->ready_state()); |
| + EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
| + socket_->TriggerTimeout(); |
| + RunPendingTasks(); |
| + |
| + EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
| + EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_TIMEOUT, |
| + socket_->error_state()); |
| +} |
| + |
| // Test connection error - SSL connect fails (async) |
| TEST_F(CastSocketTest, TestConnectSslConnectErrorAsync) { |
| CreateCastSocketSecure(); |
| @@ -536,7 +596,7 @@ TEST_F(CastSocketTest, TestConnectSslConnectErrorAsync) { |
| EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); |
| } |
| -// Test connection error - SSL connect fails (async) |
| +// Test connection error - SSL connect fails (sync) |
| TEST_F(CastSocketTest, TestConnectSslConnectErrorSync) { |
| CreateCastSocketSecure(); |