websocket_resource_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/memory/ref_counted.h"
6#include "base/message_loop.h"
7#include "ppapi/c/pp_errors.h"
8#include "ppapi/c/ppb_websocket.h"
9#include "ppapi/c/ppb_var.h"
10#include "ppapi/proxy/locking_resource_releaser.h"
11#include "ppapi/proxy/websocket_resource.h"
12#include "ppapi/proxy/ppapi_messages.h"
13#include "ppapi/proxy/ppapi_proxy_test.h"
14#include "ppapi/shared_impl/ppapi_globals.h"
15#include "ppapi/shared_impl/ppb_var_shared.h"
16#include "ppapi/shared_impl/proxy_lock.h"
17#include "ppapi/shared_impl/resource_tracker.h"
18#include "ppapi/shared_impl/scoped_pp_resource.h"
19#include "ppapi/shared_impl/scoped_pp_var.h"
20#include "ppapi/shared_impl/tracked_callback.h"
21#include "ppapi/shared_impl/var.h"
22#include "ppapi/thunk/thunk.h"
23
24namespace ppapi {
25namespace proxy {
26
27namespace {
28
29typedef PluginProxyTest WebSocketResourceTest;
30
31bool g_callback_called;
32int32_t g_callback_result;
33const PPB_Var* ppb_var_ = NULL;
34
35void Callback(void* user_data, int32_t result) {
36  g_callback_called = true;
37  g_callback_result = result;
38}
39
40PP_CompletionCallback MakeCallback() {
41  g_callback_called = false;
42  g_callback_result = PP_OK;
43  return PP_MakeCompletionCallback(Callback, NULL);
44}
45
46PP_Var MakeStringVar(const std::string& string) {
47  if (!ppb_var_)
48    ppb_var_ = ppapi::PPB_Var_Shared::GetVarInterface1_1();
49  return ppb_var_->VarFromUtf8(string.c_str(), string.length());
50}
51
52}  // namespace
53
54
55// Does a test of Connect().
56TEST_F(WebSocketResourceTest, Connect) {
57  const PPB_WebSocket_1_0* websocket_iface =
58      thunk::GetPPB_WebSocket_1_0_Thunk();
59
60  std::string url("ws://ws.google.com");
61  std::string protocol0("x-foo");
62  std::string protocol1("x-bar");
63  PP_Var url_var = MakeStringVar(url);
64  PP_Var protocols[] = { MakeStringVar(protocol0), MakeStringVar(protocol1) };
65
66  LockingResourceReleaser res(websocket_iface->Create(pp_instance()));
67
68  int32_t result = websocket_iface->Connect(res.get(), url_var, protocols, 2,
69                                            MakeCallback());
70  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
71
72  // Should be sent a "Connect" message.
73  ResourceMessageCallParams params;
74  IPC::Message msg;
75  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
76      PpapiHostMsg_WebSocket_Connect::ID, &params, &msg));
77  PpapiHostMsg_WebSocket_Connect::Schema::Param p;
78  PpapiHostMsg_WebSocket_Connect::Read(&msg, &p);
79  EXPECT_EQ(url, p.a);
80  EXPECT_EQ(protocol0, p.b[0]);
81  EXPECT_EQ(protocol1, p.b[1]);
82
83  // Synthesize a response.
84  ResourceMessageReplyParams reply_params(params.pp_resource(),
85                                          params.sequence());
86  reply_params.set_result(PP_OK);
87  ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
88      PpapiPluginMsg_ResourceReply(reply_params,
89          PpapiPluginMsg_WebSocket_ConnectReply(url, protocol1))));
90
91  EXPECT_EQ(PP_OK, g_callback_result);
92  EXPECT_EQ(true, g_callback_called);
93}
94
95// Does a test for unsolicited replies.
96TEST_F(WebSocketResourceTest, UnsolicitedReplies) {
97  const PPB_WebSocket_1_0* websocket_iface =
98      thunk::GetPPB_WebSocket_1_0_Thunk();
99
100  LockingResourceReleaser res(websocket_iface->Create(pp_instance()));
101
102  // Check if BufferedAmountReply is handled.
103  ResourceMessageReplyParams reply_params(res.get(), 0);
104  reply_params.set_result(PP_OK);
105  ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
106      PpapiPluginMsg_ResourceReply(
107          reply_params,
108          PpapiPluginMsg_WebSocket_BufferedAmountReply(19760227u))));
109
110  uint64_t amount = websocket_iface->GetBufferedAmount(res.get());
111  EXPECT_EQ(19760227u, amount);
112
113  // Check if StateReply is handled.
114  ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
115      PpapiPluginMsg_ResourceReply(
116          reply_params,
117          PpapiPluginMsg_WebSocket_StateReply(
118              static_cast<int32_t>(PP_WEBSOCKETREADYSTATE_CLOSING)))));
119
120  PP_WebSocketReadyState state = websocket_iface->GetReadyState(res.get());
121  EXPECT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, state);
122}
123
124TEST_F(WebSocketResourceTest, MessageError) {
125  const PPB_WebSocket_1_0* websocket_iface =
126      thunk::GetPPB_WebSocket_1_0_Thunk();
127
128  std::string url("ws://ws.google.com");
129  PP_Var url_var = MakeStringVar(url);
130
131  LockingResourceReleaser res(websocket_iface->Create(pp_instance()));
132
133  // Establish the connection virtually.
134  int32_t result =
135      websocket_iface->Connect(res.get(), url_var, NULL, 0, MakeCallback());
136  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
137
138  ResourceMessageCallParams params;
139  IPC::Message msg;
140  ASSERT_TRUE(sink().GetFirstResourceCallMatching(
141      PpapiHostMsg_WebSocket_Connect::ID, &params, &msg));
142
143  ResourceMessageReplyParams connect_reply_params(params.pp_resource(),
144                                                  params.sequence());
145  connect_reply_params.set_result(PP_OK);
146  ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
147      PpapiPluginMsg_ResourceReply(connect_reply_params,
148          PpapiPluginMsg_WebSocket_ConnectReply(url, std::string()))));
149
150  EXPECT_EQ(PP_OK, g_callback_result);
151  EXPECT_TRUE(g_callback_called);
152
153  PP_Var message;
154  result = websocket_iface->ReceiveMessage(res.get(), &message, MakeCallback());
155  EXPECT_FALSE(g_callback_called);
156
157  // Synthesize a WebSocket_ErrorReply message.
158  ResourceMessageReplyParams error_reply_params(res.get(), 0);
159  error_reply_params.set_result(PP_OK);
160  ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
161      PpapiPluginMsg_ResourceReply(error_reply_params,
162          PpapiPluginMsg_WebSocket_ErrorReply())));
163
164  EXPECT_EQ(PP_ERROR_FAILED, g_callback_result);
165  EXPECT_TRUE(g_callback_called);
166}
167
168}  // namespace proxy
169}  // namespace ppapi
170