Index: net/websockets/websocket_stream_test.cc |
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc |
index 5526741deb13a1422d9122bf88618fe0b8eda517..8226cd93770c0f5c502cd374b9028130c7c8f59f 100644 |
--- a/net/websockets/websocket_stream_test.cc |
+++ b/net/websockets/websocket_stream_test.cc |
@@ -16,6 +16,8 @@ |
#include "base/metrics/statistics_recorder.h" |
#include "base/run_loop.h" |
#include "base/strings/stringprintf.h" |
+#include "base/timer/mock_timer.h" |
+#include "base/timer/timer.h" |
#include "net/base/net_errors.h" |
#include "net/base/test_data_directory.h" |
#include "net/http/http_request_headers.h" |
@@ -79,6 +81,13 @@ scoped_ptr<DeterministicSocketData> BuildNullSocketData() { |
return make_scoped_ptr(new DeterministicSocketData(NULL, 0, NULL, 0)); |
} |
+class MockWeakTimer : public base::MockTimer, |
+ public base::SupportsWeakPtr<MockWeakTimer> { |
+ public: |
+ MockWeakTimer(bool retain_user_task, bool is_repeating) |
+ : MockTimer(retain_user_task, is_repeating) {} |
+}; |
+ |
// A sub-class of WebSocketHandshakeStreamCreateHelper which always sets a |
// deterministic key to use in the WebSocket handshake. |
class DeterministicKeyWebSocketHandshakeStreamCreateHelper |
@@ -105,11 +114,12 @@ class WebSocketStreamCreateTest : public ::testing::Test { |
const std::vector<std::string>& sub_protocols, |
const std::string& origin, |
const std::string& extra_request_headers, |
- const std::string& response_body) { |
+ const std::string& response_body, |
+ scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
url_request_context_host_.SetExpectations( |
WebSocketStandardRequest(socket_path, origin, extra_request_headers), |
response_body); |
- CreateAndConnectStream(socket_url, sub_protocols, origin); |
+ CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
} |
// |extra_request_headers| and |extra_response_headers| must end in "\r\n" or |
@@ -119,23 +129,27 @@ class WebSocketStreamCreateTest : public ::testing::Test { |
const std::vector<std::string>& sub_protocols, |
const std::string& origin, |
const std::string& extra_request_headers, |
- const std::string& extra_response_headers) { |
+ const std::string& extra_response_headers, |
+ scoped_ptr<base::Timer> timer = |
+ scoped_ptr<base::Timer>()) { |
CreateAndConnectCustomResponse( |
socket_url, |
socket_path, |
sub_protocols, |
origin, |
extra_request_headers, |
- WebSocketStandardResponse(extra_response_headers)); |
+ WebSocketStandardResponse(extra_response_headers), |
+ timer.Pass()); |
} |
void CreateAndConnectRawExpectations( |
const std::string& socket_url, |
const std::vector<std::string>& sub_protocols, |
const std::string& origin, |
- scoped_ptr<DeterministicSocketData> socket_data) { |
+ scoped_ptr<DeterministicSocketData> socket_data, |
+ scoped_ptr<base::Timer> timer = scoped_ptr<base::Timer>()) { |
AddRawExpectations(socket_data.Pass()); |
- CreateAndConnectStream(socket_url, sub_protocols, origin); |
+ CreateAndConnectStream(socket_url, sub_protocols, origin, timer.Pass()); |
} |
// Add additional raw expectations for sockets created before the final one. |
@@ -147,7 +161,8 @@ class WebSocketStreamCreateTest : public ::testing::Test { |
// parameters. |
void CreateAndConnectStream(const std::string& socket_url, |
const std::vector<std::string>& sub_protocols, |
- const std::string& origin) { |
+ const std::string& origin, |
+ scoped_ptr<base::Timer> timer) { |
for (size_t i = 0; i < ssl_data_.size(); ++i) { |
scoped_ptr<SSLSocketDataProvider> ssl_data(ssl_data_[i]); |
ssl_data_[i] = NULL; |
@@ -166,7 +181,9 @@ class WebSocketStreamCreateTest : public ::testing::Test { |
url::Origin(origin), |
url_request_context_host_.GetURLRequestContext(), |
BoundNetLog(), |
- connect_delegate.Pass()); |
+ connect_delegate.Pass(), |
+ timer ? timer.Pass() : scoped_ptr<base::Timer>( |
+ new base::Timer(false, false))); |
} |
static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); } |
@@ -404,15 +421,24 @@ class WebSocketStreamCreateUMATest : public ::testing::Test { |
// Confirm that the basic case works as expected. |
TEST_F(WebSocketStreamCreateTest, SimpleSuccess) { |
+ scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
Adam Rice
2014/09/11 07:52:42
You should create a separate test that the timer r
yhirano
2014/09/11 08:45:36
Done.
|
+ base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
+ |
CreateAndConnectStandard( |
- "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", ""); |
+ "ws://localhost/", "/", NoSubProtocols(), "http://localhost", "", "", |
+ timer.PassAs<base::Timer>()); |
EXPECT_FALSE(request_info_); |
EXPECT_FALSE(response_info_); |
+ ASSERT_TRUE(weak_timer); |
+ EXPECT_TRUE(weak_timer->IsRunning()); |
+ |
RunUntilIdle(); |
EXPECT_FALSE(has_failed()); |
EXPECT_TRUE(stream_); |
EXPECT_TRUE(request_info_); |
EXPECT_TRUE(response_info_); |
+ ASSERT_TRUE(weak_timer); |
+ EXPECT_FALSE(weak_timer->IsRunning()); |
} |
TEST_F(WebSocketStreamCreateTest, HandshakeInfo) { |
@@ -1075,14 +1101,22 @@ TEST_F(WebSocketStreamCreateTest, ConnectionFailure) { |
scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
socket_data->set_connect_data( |
MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); |
+ scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
+ base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
- "http://localhost", socket_data.Pass()); |
+ "http://localhost", socket_data.Pass(), |
+ timer.PassAs<base::Timer>()); |
+ ASSERT_TRUE(weak_timer.get()); |
+ EXPECT_TRUE(weak_timer->IsRunning()); |
+ |
RunUntilIdle(); |
EXPECT_TRUE(has_failed()); |
EXPECT_EQ("Error in connection establishment: net::ERR_CONNECTION_REFUSED", |
failure_message()); |
EXPECT_FALSE(request_info_); |
EXPECT_FALSE(response_info_); |
+ ASSERT_TRUE(weak_timer.get()); |
+ EXPECT_FALSE(weak_timer->IsRunning()); |
} |
// Connect timeout must look just like any other failure. |
@@ -1098,6 +1132,28 @@ TEST_F(WebSocketStreamCreateTest, ConnectionTimeout) { |
failure_message()); |
} |
+// The server doesn't respond to the opening handshake. |
+TEST_F(WebSocketStreamCreateTest, HandshakeTimeout) { |
+ scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |
+ socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); |
+ scoped_ptr<MockWeakTimer> timer(new MockWeakTimer(false, false)); |
+ base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); |
+ CreateAndConnectRawExpectations("ws://localhost/", NoSubProtocols(), |
+ "http://localhost", socket_data.Pass(), |
+ timer.PassAs<base::Timer>()); |
+ EXPECT_FALSE(has_failed()); |
+ ASSERT_TRUE(weak_timer.get()); |
+ EXPECT_TRUE(weak_timer->IsRunning()); |
+ |
+ weak_timer->Fire(); |
+ RunUntilIdle(); |
+ |
+ EXPECT_TRUE(has_failed()); |
+ EXPECT_EQ("WebSocket opening handshake timed out", failure_message()); |
+ ASSERT_TRUE(weak_timer.get()); |
+ EXPECT_FALSE(weak_timer->IsRunning()); |
+} |
+ |
// Cancellation during connect works. |
TEST_F(WebSocketStreamCreateTest, CancellationDuringConnect) { |
scoped_ptr<DeterministicSocketData> socket_data(BuildNullSocketData()); |