websocket_dispatcher_host_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/browser/renderer_host/websocket_dispatcher_host.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <vector>
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind_helpers.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/memory/ref_counted.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/browser/renderer_host/websocket_host.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/common/websocket.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/common/websocket_messages.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ipc/ipc_message.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "url/gurl.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "url/origin.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace content {
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// This number is unlikely to occur by chance.
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)static const int kMagicRenderProcessId = 506116062;
2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A mock of WebsocketHost which records received messages.
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class MockWebSocketHost : public WebSocketHost {
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public:
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MockWebSocketHost(int routing_id,
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    WebSocketDispatcherHost* dispatcher,
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    net::URLRequestContext* url_request_context)
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      : WebSocketHost(routing_id, dispatcher, url_request_context) {
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual ~MockWebSocketHost() {}
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE{
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    received_messages_.push_back(message);
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<IPC::Message> received_messages_;
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class WebSocketDispatcherHostTest : public ::testing::Test {
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public:
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketDispatcherHostTest() {
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dispatcher_host_ = new WebSocketDispatcherHost(
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        kMagicRenderProcessId,
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&WebSocketDispatcherHostTest::OnGetRequestContext,
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   base::Unretained(this)),
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&WebSocketDispatcherHostTest::CreateWebSocketHost,
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   base::Unretained(this)));
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual ~WebSocketDispatcherHostTest() {}
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) protected:
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<WebSocketDispatcherHost> dispatcher_host_;
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Stores allocated MockWebSocketHost instances. Doesn't take ownership of
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // them.
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<MockWebSocketHost*> mock_hosts_;
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) private:
668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::URLRequestContext* OnGetRequestContext() {
678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return NULL;
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketHost* CreateWebSocketHost(int routing_id) {
718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MockWebSocketHost* host =
728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new MockWebSocketHost(routing_id, dispatcher_host_.get(), NULL);
738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    mock_hosts_.push_back(host);
748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return host;
758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, Construct) {
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Do nothing.
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, UnrelatedMessage) {
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  IPC::Message message;
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(dispatcher_host_->OnMessageReceived(message));
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, RenderProcessIdGetter) {
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(kMagicRenderProcessId, dispatcher_host_->render_process_id());
8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, AddChannelRequest) {
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int routing_id = 123;
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GURL socket_url("ws://example.com/test");
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<std::string> requested_protocols;
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  requested_protocols.push_back("hello");
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  url::Origin origin("http://example.com/test");
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int render_frame_id = -2;
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketHostMsg_AddChannelRequest message(
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      routing_id, socket_url, requested_protocols, origin, render_frame_id);
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(dispatcher_host_->OnMessageReceived(message));
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ASSERT_EQ(1U, mock_hosts_.size());
1048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MockWebSocketHost* host = mock_hosts_[0];
1058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ASSERT_EQ(1U, host->received_messages_.size());
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const IPC::Message& forwarded_message = host->received_messages_[0];
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(WebSocketHostMsg_AddChannelRequest::ID, forwarded_message.type());
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(routing_id, forwarded_message.routing_id());
1108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, SendFrameButNoHostYet) {
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int routing_id = 123;
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<char> data;
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketMsg_SendFrame message(
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      routing_id, true, WEB_SOCKET_MESSAGE_TYPE_TEXT, data);
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Expected to be ignored.
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(dispatcher_host_->OnMessageReceived(message));
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ(0U, mock_hosts_.size());
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(WebSocketDispatcherHostTest, SendFrame) {
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int routing_id = 123;
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  GURL socket_url("ws://example.com/test");
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<std::string> requested_protocols;
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  requested_protocols.push_back("hello");
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  url::Origin origin("http://example.com/test");
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  int render_frame_id = -2;
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketHostMsg_AddChannelRequest add_channel_message(
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      routing_id, socket_url, requested_protocols, origin, render_frame_id);
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ASSERT_TRUE(dispatcher_host_->OnMessageReceived(add_channel_message));
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::vector<char> data;
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  WebSocketMsg_SendFrame send_frame_message(
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      routing_id, true, WEB_SOCKET_MESSAGE_TYPE_TEXT, data);
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(dispatcher_host_->OnMessageReceived(send_frame_message));
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ASSERT_EQ(1U, mock_hosts_.size());
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MockWebSocketHost* host = mock_hosts_[0];
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ASSERT_EQ(2U, host->received_messages_.size());
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  {
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const IPC::Message& forwarded_message = host->received_messages_[0];
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(WebSocketHostMsg_AddChannelRequest::ID, forwarded_message.type());
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(routing_id, forwarded_message.routing_id());
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  {
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const IPC::Message& forwarded_message = host->received_messages_[1];
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(WebSocketMsg_SendFrame::ID, forwarded_message.type());
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    EXPECT_EQ(routing_id, forwarded_message.routing_id());
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace content
161