| Index: net/websockets/websocket_unittest.cc
|
| ===================================================================
|
| --- net/websockets/websocket_unittest.cc (revision 95449)
|
| +++ net/websockets/websocket_unittest.cc (working copy)
|
| @@ -1,348 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/websockets/websocket.h"
|
| -
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/callback.h"
|
| -#include "net/base/completion_callback.h"
|
| -#include "net/base/io_buffer.h"
|
| -#include "net/base/mock_host_resolver.h"
|
| -#include "net/base/test_completion_callback.h"
|
| -#include "net/socket/socket_test_util.h"
|
| -#include "net/url_request/url_request_test_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/platform_test.h"
|
| -
|
| -struct WebSocketEvent {
|
| - enum EventType {
|
| - EVENT_OPEN, EVENT_MESSAGE, EVENT_ERROR, EVENT_CLOSE,
|
| - };
|
| -
|
| - WebSocketEvent(EventType type, net::WebSocket* websocket,
|
| - const std::string& websocket_msg, bool websocket_flag)
|
| - : event_type(type), socket(websocket), msg(websocket_msg),
|
| - flag(websocket_flag) {}
|
| -
|
| - EventType event_type;
|
| - net::WebSocket* socket;
|
| - std::string msg;
|
| - bool flag;
|
| -};
|
| -
|
| -class WebSocketEventRecorder : public net::WebSocketDelegate {
|
| - public:
|
| - explicit WebSocketEventRecorder(net::CompletionCallback* callback)
|
| - : callback_(callback) {}
|
| - virtual ~WebSocketEventRecorder() {}
|
| -
|
| - void SetOnOpen(const base::Callback<void(WebSocketEvent*)>& callback) {
|
| - onopen_ = callback;
|
| - }
|
| - void SetOnMessage(const base::Callback<void(WebSocketEvent*)>& callback) {
|
| - onmessage_ = callback;
|
| - }
|
| - void SetOnClose(const base::Callback<void(WebSocketEvent*)>& callback) {
|
| - onclose_ = callback;
|
| - }
|
| -
|
| - virtual void OnOpen(net::WebSocket* socket) {
|
| - events_.push_back(
|
| - WebSocketEvent(WebSocketEvent::EVENT_OPEN, socket,
|
| - std::string(), false));
|
| - if (!onopen_.is_null())
|
| - onopen_.Run(&events_.back());
|
| - }
|
| -
|
| - virtual void OnMessage(net::WebSocket* socket, const std::string& msg) {
|
| - events_.push_back(
|
| - WebSocketEvent(WebSocketEvent::EVENT_MESSAGE, socket, msg, false));
|
| - if (!onmessage_.is_null())
|
| - onmessage_.Run(&events_.back());
|
| - }
|
| - virtual void OnError(net::WebSocket* socket) {
|
| - events_.push_back(
|
| - WebSocketEvent(WebSocketEvent::EVENT_ERROR, socket,
|
| - std::string(), false));
|
| - if (!onerror_.is_null())
|
| - onerror_.Run(&events_.back());
|
| - }
|
| - virtual void OnClose(net::WebSocket* socket, bool was_clean) {
|
| - events_.push_back(
|
| - WebSocketEvent(WebSocketEvent::EVENT_CLOSE, socket,
|
| - std::string(), was_clean));
|
| - if (!onclose_.is_null())
|
| - onclose_.Run(&events_.back());
|
| - if (callback_)
|
| - callback_->Run(net::OK);
|
| - }
|
| -
|
| - void DoClose(WebSocketEvent* event) {
|
| - event->socket->Close();
|
| - }
|
| -
|
| - const std::vector<WebSocketEvent>& GetSeenEvents() const {
|
| - return events_;
|
| - }
|
| -
|
| - private:
|
| - std::vector<WebSocketEvent> events_;
|
| - base::Callback<void(WebSocketEvent*)> onopen_;
|
| - base::Callback<void(WebSocketEvent*)> onmessage_;
|
| - base::Callback<void(WebSocketEvent*)> onerror_;
|
| - base::Callback<void(WebSocketEvent*)> onclose_;
|
| - net::CompletionCallback* callback_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(WebSocketEventRecorder);
|
| -};
|
| -
|
| -namespace net {
|
| -
|
| -class WebSocketTest : public PlatformTest {
|
| - protected:
|
| - void InitReadBuf(WebSocket* websocket) {
|
| - // Set up |current_read_buf_|.
|
| - websocket->current_read_buf_ = new GrowableIOBuffer();
|
| - }
|
| - void SetReadConsumed(WebSocket* websocket, int consumed) {
|
| - websocket->read_consumed_len_ = consumed;
|
| - }
|
| - void AddToReadBuf(WebSocket* websocket, const char* data, int len) {
|
| - websocket->AddToReadBuffer(data, len);
|
| - }
|
| -
|
| - void TestProcessFrameData(WebSocket* websocket,
|
| - const char* expected_remaining_data,
|
| - int expected_remaining_len) {
|
| - websocket->ProcessFrameData();
|
| -
|
| - const char* actual_remaining_data =
|
| - websocket->current_read_buf_->StartOfBuffer()
|
| - + websocket->read_consumed_len_;
|
| - int actual_remaining_len =
|
| - websocket->current_read_buf_->offset() - websocket->read_consumed_len_;
|
| -
|
| - EXPECT_EQ(expected_remaining_len, actual_remaining_len);
|
| - EXPECT_TRUE(!memcmp(expected_remaining_data, actual_remaining_data,
|
| - expected_remaining_len));
|
| - }
|
| -};
|
| -
|
| -TEST_F(WebSocketTest, Connect) {
|
| - MockClientSocketFactory mock_socket_factory;
|
| - MockRead data_reads[] = {
|
| - MockRead("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
|
| - "Upgrade: WebSocket\r\n"
|
| - "Connection: Upgrade\r\n"
|
| - "WebSocket-Origin: http://example.com\r\n"
|
| - "WebSocket-Location: ws://example.com/demo\r\n"
|
| - "WebSocket-Protocol: sample\r\n"
|
| - "\r\n"),
|
| - // Server doesn't close the connection after handshake.
|
| - MockRead(true, ERR_IO_PENDING),
|
| - };
|
| - MockWrite data_writes[] = {
|
| - MockWrite("GET /demo HTTP/1.1\r\n"
|
| - "Upgrade: WebSocket\r\n"
|
| - "Connection: Upgrade\r\n"
|
| - "Host: example.com\r\n"
|
| - "Origin: http://example.com\r\n"
|
| - "WebSocket-Protocol: sample\r\n"
|
| - "\r\n"),
|
| - };
|
| - StaticSocketDataProvider data(data_reads, arraysize(data_reads),
|
| - data_writes, arraysize(data_writes));
|
| - mock_socket_factory.AddSocketDataProvider(&data);
|
| - MockHostResolver host_resolver;
|
| -
|
| - WebSocket::Request* request(
|
| - new WebSocket::Request(GURL("ws://example.com/demo"),
|
| - "sample",
|
| - "http://example.com",
|
| - "ws://example.com/demo",
|
| - WebSocket::DRAFT75,
|
| - new TestURLRequestContext()));
|
| - request->SetHostResolver(&host_resolver);
|
| - request->SetClientSocketFactory(&mock_socket_factory);
|
| -
|
| - TestCompletionCallback callback;
|
| -
|
| - scoped_ptr<WebSocketEventRecorder> delegate(
|
| - new WebSocketEventRecorder(&callback));
|
| - delegate->SetOnOpen(base::Bind(&WebSocketEventRecorder::DoClose,
|
| - base::Unretained(delegate.get())));
|
| -
|
| - scoped_refptr<WebSocket> websocket(
|
| - new WebSocket(request, delegate.get()));
|
| -
|
| - EXPECT_EQ(WebSocket::INITIALIZED, websocket->ready_state());
|
| - websocket->Connect();
|
| -
|
| - callback.WaitForResult();
|
| -
|
| - const std::vector<WebSocketEvent>& events = delegate->GetSeenEvents();
|
| - EXPECT_EQ(2U, events.size());
|
| -
|
| - EXPECT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
|
| - EXPECT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type);
|
| -}
|
| -
|
| -TEST_F(WebSocketTest, ServerSentData) {
|
| - MockClientSocketFactory mock_socket_factory;
|
| - static const char kMessage[] = "Hello";
|
| - static const char kFrame[] = "\x00Hello\xff";
|
| - static const int kFrameLen = sizeof(kFrame) - 1;
|
| - MockRead data_reads[] = {
|
| - MockRead("HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
|
| - "Upgrade: WebSocket\r\n"
|
| - "Connection: Upgrade\r\n"
|
| - "WebSocket-Origin: http://example.com\r\n"
|
| - "WebSocket-Location: ws://example.com/demo\r\n"
|
| - "WebSocket-Protocol: sample\r\n"
|
| - "\r\n"),
|
| - MockRead(true, kFrame, kFrameLen),
|
| - // Server doesn't close the connection after handshake.
|
| - MockRead(true, ERR_IO_PENDING),
|
| - };
|
| - MockWrite data_writes[] = {
|
| - MockWrite("GET /demo HTTP/1.1\r\n"
|
| - "Upgrade: WebSocket\r\n"
|
| - "Connection: Upgrade\r\n"
|
| - "Host: example.com\r\n"
|
| - "Origin: http://example.com\r\n"
|
| - "WebSocket-Protocol: sample\r\n"
|
| - "\r\n"),
|
| - };
|
| - StaticSocketDataProvider data(data_reads, arraysize(data_reads),
|
| - data_writes, arraysize(data_writes));
|
| - mock_socket_factory.AddSocketDataProvider(&data);
|
| - MockHostResolver host_resolver;
|
| -
|
| - WebSocket::Request* request(
|
| - new WebSocket::Request(GURL("ws://example.com/demo"),
|
| - "sample",
|
| - "http://example.com",
|
| - "ws://example.com/demo",
|
| - WebSocket::DRAFT75,
|
| - new TestURLRequestContext()));
|
| - request->SetHostResolver(&host_resolver);
|
| - request->SetClientSocketFactory(&mock_socket_factory);
|
| -
|
| - TestCompletionCallback callback;
|
| -
|
| - scoped_ptr<WebSocketEventRecorder> delegate(
|
| - new WebSocketEventRecorder(&callback));
|
| - delegate->SetOnMessage(base::Bind(&WebSocketEventRecorder::DoClose,
|
| - base::Unretained(delegate.get())));
|
| -
|
| - scoped_refptr<WebSocket> websocket(
|
| - new WebSocket(request, delegate.get()));
|
| -
|
| - EXPECT_EQ(WebSocket::INITIALIZED, websocket->ready_state());
|
| - websocket->Connect();
|
| -
|
| - callback.WaitForResult();
|
| -
|
| - const std::vector<WebSocketEvent>& events = delegate->GetSeenEvents();
|
| - EXPECT_EQ(3U, events.size());
|
| -
|
| - EXPECT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
|
| - EXPECT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type);
|
| - EXPECT_EQ(kMessage, events[1].msg);
|
| - EXPECT_EQ(WebSocketEvent::EVENT_CLOSE, events[2].event_type);
|
| -}
|
| -
|
| -TEST_F(WebSocketTest, ProcessFrameDataForLengthCalculation) {
|
| - WebSocket::Request* request(
|
| - new WebSocket::Request(GURL("ws://example.com/demo"),
|
| - "sample",
|
| - "http://example.com",
|
| - "ws://example.com/demo",
|
| - WebSocket::DRAFT75,
|
| - new TestURLRequestContext()));
|
| - TestCompletionCallback callback;
|
| - scoped_ptr<WebSocketEventRecorder> delegate(
|
| - new WebSocketEventRecorder(&callback));
|
| -
|
| - scoped_refptr<WebSocket> websocket(
|
| - new WebSocket(request, delegate.get()));
|
| -
|
| - // Frame data: skip length 1 ('x'), and try to skip length 129
|
| - // (1 * 128 + 1) bytes after \x81\x01, but buffer is too short to skip.
|
| - static const char kTestLengthFrame[] =
|
| - "\x80\x01x\x80\x81\x01\x01\x00unexpected data\xFF";
|
| - const int kTestLengthFrameLength = sizeof(kTestLengthFrame) - 1;
|
| - InitReadBuf(websocket.get());
|
| - AddToReadBuf(websocket.get(), kTestLengthFrame, kTestLengthFrameLength);
|
| - SetReadConsumed(websocket.get(), 0);
|
| -
|
| - static const char kExpectedRemainingFrame[] =
|
| - "\x80\x81\x01\x01\x00unexpected data\xFF";
|
| - const int kExpectedRemainingLength = sizeof(kExpectedRemainingFrame) - 1;
|
| - TestProcessFrameData(websocket.get(),
|
| - kExpectedRemainingFrame, kExpectedRemainingLength);
|
| - // No onmessage event expected.
|
| - const std::vector<WebSocketEvent>& events = delegate->GetSeenEvents();
|
| - EXPECT_EQ(1U, events.size());
|
| -
|
| - EXPECT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type);
|
| -
|
| - websocket->DetachDelegate();
|
| -}
|
| -
|
| -TEST_F(WebSocketTest, ProcessFrameDataForUnterminatedString) {
|
| - WebSocket::Request* request(
|
| - new WebSocket::Request(GURL("ws://example.com/demo"),
|
| - "sample",
|
| - "http://example.com",
|
| - "ws://example.com/demo",
|
| - WebSocket::DRAFT75,
|
| - new TestURLRequestContext()));
|
| - TestCompletionCallback callback;
|
| - scoped_ptr<WebSocketEventRecorder> delegate(
|
| - new WebSocketEventRecorder(&callback));
|
| -
|
| - scoped_refptr<WebSocket> websocket(
|
| - new WebSocket(request, delegate.get()));
|
| -
|
| - static const char kTestUnterminatedFrame[] =
|
| - "\x00unterminated frame";
|
| - const int kTestUnterminatedFrameLength = sizeof(kTestUnterminatedFrame) - 1;
|
| - InitReadBuf(websocket.get());
|
| - AddToReadBuf(websocket.get(), kTestUnterminatedFrame,
|
| - kTestUnterminatedFrameLength);
|
| - SetReadConsumed(websocket.get(), 0);
|
| - TestProcessFrameData(websocket.get(),
|
| - kTestUnterminatedFrame, kTestUnterminatedFrameLength);
|
| - {
|
| - // No onmessage event expected.
|
| - const std::vector<WebSocketEvent>& events = delegate->GetSeenEvents();
|
| - EXPECT_EQ(0U, events.size());
|
| - }
|
| -
|
| - static const char kTestTerminateFrame[] = " is terminated in next read\xff";
|
| - const int kTestTerminateFrameLength = sizeof(kTestTerminateFrame) - 1;
|
| - AddToReadBuf(websocket.get(), kTestTerminateFrame,
|
| - kTestTerminateFrameLength);
|
| - TestProcessFrameData(websocket.get(), "", 0);
|
| -
|
| - static const char kExpectedMsg[] =
|
| - "unterminated frame is terminated in next read";
|
| - {
|
| - const std::vector<WebSocketEvent>& events = delegate->GetSeenEvents();
|
| - EXPECT_EQ(1U, events.size());
|
| -
|
| - EXPECT_EQ(WebSocketEvent::EVENT_MESSAGE, events[0].event_type);
|
| - EXPECT_EQ(kExpectedMsg, events[0].msg);
|
| - }
|
| -
|
| - websocket->DetachDelegate();
|
| -}
|
| -
|
| -} // namespace net
|
|
|