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

Unified Diff: net/websockets/websocket_stream_test.cc

Issue 565573002: Implement handshake timeout on WebSocket (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());

Powered by Google App Engine
This is Rietveld 408576698