summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/websockets/websocket_stream.cc19
-rw-r--r--net/websockets/websocket_stream_test.cc107
2 files changed, 123 insertions, 3 deletions
diff --git a/net/websockets/websocket_stream.cc b/net/websockets/websocket_stream.cc
index 48135d1..399b8f0 100644
--- a/net/websockets/websocket_stream.cc
+++ b/net/websockets/websocket_stream.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/metrics/histogram.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request.h"
@@ -25,8 +26,19 @@ class StreamRequestImpl;
class Delegate : public URLRequest::Delegate {
public:
- explicit Delegate(StreamRequestImpl* owner) : owner_(owner) {}
- virtual ~Delegate() {}
+ enum HandshakeResult {
+ INCOMPLETE,
+ CONNECTED,
+ FAILED,
+ NUM_HANDSHAKE_RESULT_TYPES,
+ };
+
+ explicit Delegate(StreamRequestImpl* owner)
+ : owner_(owner), result_(INCOMPLETE) {}
+ virtual ~Delegate() {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Net.WebSocket.HandshakeResult", result_, NUM_HANDSHAKE_RESULT_TYPES);
+ }
// Implementation of URLRequest::Delegate methods.
virtual void OnResponseStarted(URLRequest* request) OVERRIDE;
@@ -46,6 +58,7 @@ class Delegate : public URLRequest::Delegate {
private:
StreamRequestImpl* owner_;
+ HandshakeResult result_;
};
class StreamRequestImpl : public WebSocketStreamRequest {
@@ -110,6 +123,7 @@ class StreamRequestImpl : public WebSocketStreamRequest {
void Delegate::OnResponseStarted(URLRequest* request) {
switch (request->GetResponseCode()) {
case HTTP_SWITCHING_PROTOCOLS:
+ result_ = CONNECTED;
owner_->PerformUpgrade();
return;
@@ -118,6 +132,7 @@ void Delegate::OnResponseStarted(URLRequest* request) {
return;
default:
+ result_ = FAILED;
owner_->ReportFailure();
}
}
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc
index 8947d33..4ea8538 100644
--- a/net/websockets/websocket_stream_test.cc
+++ b/net/websockets/websocket_stream_test.cc
@@ -10,6 +10,9 @@
#include <vector>
#include "base/memory/scoped_vector.h"
+#include "base/metrics/histogram.h"
+#include "base/metrics/histogram_samples.h"
+#include "base/metrics/statistics_recorder.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "net/base/net_errors.h"
@@ -75,7 +78,7 @@ class DeterministicKeyWebSocketHandshakeStreamCreateHelper
};
class WebSocketStreamCreateTest : public ::testing::Test {
- protected:
+ public:
WebSocketStreamCreateTest(): has_failed_(false) {}
void CreateAndConnectCustomResponse(
@@ -208,6 +211,28 @@ class WebSocketStreamCreateExtensionTest : public WebSocketStreamCreateTest {
}
};
+class WebSocketStreamCreateUMATest : public ::testing::Test {
+ public:
+ // This enum should match with the enum in Delegate in websocket_stream.cc.
+ enum HandshakeResult {
+ INCOMPLETE,
+ CONNECTED,
+ FAILED,
+ NUM_HANDSHAKE_RESULT_TYPES,
+ };
+
+ class StreamCreation : public WebSocketStreamCreateTest {
+ virtual void TestBody() OVERRIDE {}
+ };
+
+ scoped_ptr<base::HistogramSamples> GetSamples(const std::string& name) {
+ base::HistogramBase* histogram =
+ base::StatisticsRecorder::FindHistogram(name);
+ return histogram ? histogram->SnapshotSamples()
+ : scoped_ptr<base::HistogramSamples>();
+ }
+};
+
// Confirm that the basic case works as expected.
TEST_F(WebSocketStreamCreateTest, SimpleSuccess) {
CreateAndConnectStandard(
@@ -1007,5 +1032,85 @@ TEST_F(WebSocketStreamCreateTest, NoResponse) {
failure_message());
}
+TEST_F(WebSocketStreamCreateUMATest, Incomplete) {
+ const std::string name("Net.WebSocket.HandshakeResult");
+ scoped_ptr<base::HistogramSamples> original(GetSamples(name));
+
+ {
+ StreamCreation creation;
+ creation.CreateAndConnectStandard("ws://localhost/",
+ "/",
+ creation.NoSubProtocols(),
+ "http://localhost",
+ "",
+ "");
+ }
+
+ scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
+ ASSERT_TRUE(samples);
+ if (original) {
+ samples->Subtract(*original); // Cancel the original values.
+ }
+ EXPECT_EQ(1, samples->GetCount(INCOMPLETE));
+ EXPECT_EQ(0, samples->GetCount(CONNECTED));
+ EXPECT_EQ(0, samples->GetCount(FAILED));
+}
+
+TEST_F(WebSocketStreamCreateUMATest, Connected) {
+ const std::string name("Net.WebSocket.HandshakeResult");
+ scoped_ptr<base::HistogramSamples> original(GetSamples(name));
+
+ {
+ StreamCreation creation;
+ creation.CreateAndConnectStandard("ws://localhost/",
+ "/",
+ creation.NoSubProtocols(),
+ "http://localhost",
+ "",
+ "");
+ creation.RunUntilIdle();
+ }
+
+ scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
+ ASSERT_TRUE(samples);
+ if (original) {
+ samples->Subtract(*original); // Cancel the original values.
+ }
+ EXPECT_EQ(0, samples->GetCount(INCOMPLETE));
+ EXPECT_EQ(1, samples->GetCount(CONNECTED));
+ EXPECT_EQ(0, samples->GetCount(FAILED));
+}
+
+TEST_F(WebSocketStreamCreateUMATest, Failed) {
+ const std::string name("Net.WebSocket.HandshakeResult");
+ scoped_ptr<base::HistogramSamples> original(GetSamples(name));
+
+ {
+ StreamCreation creation;
+ static const char kInvalidStatusCodeResponse[] =
+ "HTTP/1.1 200 OK\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n"
+ "\r\n";
+ creation.CreateAndConnectCustomResponse("ws://localhost/",
+ "/",
+ creation.NoSubProtocols(),
+ "http://localhost",
+ "",
+ kInvalidStatusCodeResponse);
+ creation.RunUntilIdle();
+ }
+
+ scoped_ptr<base::HistogramSamples> samples(GetSamples(name));
+ ASSERT_TRUE(samples);
+ if (original) {
+ samples->Subtract(*original); // Cancel the original values.
+ }
+ EXPECT_EQ(0, samples->GetCount(INCOMPLETE));
+ EXPECT_EQ(0, samples->GetCount(CONNECTED));
+ EXPECT_EQ(1, samples->GetCount(FAILED));
+}
+
} // namespace
} // namespace net