Home | History | Annotate | Download | only in proxy
      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/message_loop.h"
      7 #include "ppapi/c/pp_errors.h"
      8 #include "ppapi/c/ppb_var.h"
      9 #include "ppapi/c/ppb_websocket.h"
     10 #include "ppapi/proxy/locking_resource_releaser.h"
     11 #include "ppapi/proxy/ppapi_messages.h"
     12 #include "ppapi/proxy/ppapi_proxy_test.h"
     13 #include "ppapi/proxy/websocket_resource.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 
     24 namespace ppapi {
     25 namespace proxy {
     26 
     27 namespace {
     28 
     29 typedef PluginProxyTest WebSocketResourceTest;
     30 
     31 bool g_callback_called;
     32 int32_t g_callback_result;
     33 const PPB_Var* ppb_var_ = NULL;
     34 
     35 void Callback(void* user_data, int32_t result) {
     36   g_callback_called = true;
     37   g_callback_result = result;
     38 }
     39 
     40 PP_CompletionCallback MakeCallback() {
     41   g_callback_called = false;
     42   g_callback_result = PP_OK;
     43   return PP_MakeCompletionCallback(Callback, NULL);
     44 }
     45 
     46 PP_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().
     56 TEST_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.
     96 TEST_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 
    124 TEST_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