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/plugin_message_filter.h"
     12 #include "ppapi/proxy/ppapi_messages.h"
     13 #include "ppapi/proxy/ppapi_proxy_test.h"
     14 #include "ppapi/proxy/websocket_resource.h"
     15 #include "ppapi/shared_impl/ppapi_globals.h"
     16 #include "ppapi/shared_impl/ppb_var_shared.h"
     17 #include "ppapi/shared_impl/proxy_lock.h"
     18 #include "ppapi/shared_impl/resource_tracker.h"
     19 #include "ppapi/shared_impl/scoped_pp_resource.h"
     20 #include "ppapi/shared_impl/scoped_pp_var.h"
     21 #include "ppapi/shared_impl/tracked_callback.h"
     22 #include "ppapi/shared_impl/var.h"
     23 #include "ppapi/thunk/thunk.h"
     24 
     25 namespace ppapi {
     26 namespace proxy {
     27 
     28 namespace {
     29 
     30 typedef PluginProxyTest WebSocketResourceTest;
     31 
     32 bool g_callback_called;
     33 int32_t g_callback_result;
     34 const PPB_Var* ppb_var_ = NULL;
     35 
     36 void Callback(void* user_data, int32_t result) {
     37   g_callback_called = true;
     38   g_callback_result = result;
     39 }
     40 
     41 PP_CompletionCallback MakeCallback() {
     42   g_callback_called = false;
     43   g_callback_result = PP_OK;
     44   return PP_MakeCompletionCallback(Callback, NULL);
     45 }
     46 
     47 PP_Var MakeStringVar(const std::string& string) {
     48   if (!ppb_var_)
     49     ppb_var_ = ppapi::PPB_Var_Shared::GetVarInterface1_1();
     50   return ppb_var_->VarFromUtf8(string.c_str(), string.length());
     51 }
     52 
     53 }  // namespace
     54 
     55 
     56 // Does a test of Connect().
     57 TEST_F(WebSocketResourceTest, Connect) {
     58   const PPB_WebSocket_1_0* websocket_iface =
     59       thunk::GetPPB_WebSocket_1_0_Thunk();
     60 
     61   std::string url("ws://ws.google.com");
     62   std::string protocol0("x-foo");
     63   std::string protocol1("x-bar");
     64   PP_Var url_var = MakeStringVar(url);
     65   PP_Var protocols[] = { MakeStringVar(protocol0), MakeStringVar(protocol1) };
     66 
     67   LockingResourceReleaser res(websocket_iface->Create(pp_instance()));
     68 
     69   int32_t result = websocket_iface->Connect(res.get(), url_var, protocols, 2,
     70                                             MakeCallback());
     71   ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
     72 
     73   // Should be sent a "Connect" message.
     74   ResourceMessageCallParams params;
     75   IPC::Message msg;
     76   ASSERT_TRUE(sink().GetFirstResourceCallMatching(
     77       PpapiHostMsg_WebSocket_Connect::ID, &params, &msg));
     78   PpapiHostMsg_WebSocket_Connect::Schema::Param p;
     79   PpapiHostMsg_WebSocket_Connect::Read(&msg, &p);
     80   EXPECT_EQ(url, p.a);
     81   EXPECT_EQ(protocol0, p.b[0]);
     82   EXPECT_EQ(protocol1, p.b[1]);
     83 
     84   // Synthesize a response.
     85   ResourceMessageReplyParams reply_params(params.pp_resource(),
     86                                           params.sequence());
     87   reply_params.set_result(PP_OK);
     88   PluginMessageFilter::DispatchResourceReplyForTest(
     89       reply_params, 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   PluginMessageFilter::DispatchResourceReplyForTest(
    106       reply_params, PpapiPluginMsg_WebSocket_BufferedAmountReply(19760227u));
    107 
    108   uint64_t amount = websocket_iface->GetBufferedAmount(res.get());
    109   EXPECT_EQ(19760227u, amount);
    110 
    111   // Check if StateReply is handled.
    112   PluginMessageFilter::DispatchResourceReplyForTest(
    113       reply_params,
    114       PpapiPluginMsg_WebSocket_StateReply(
    115           static_cast<int32_t>(PP_WEBSOCKETREADYSTATE_CLOSING)));
    116 
    117   PP_WebSocketReadyState state = websocket_iface->GetReadyState(res.get());
    118   EXPECT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, state);
    119 }
    120 
    121 TEST_F(WebSocketResourceTest, MessageError) {
    122   const PPB_WebSocket_1_0* websocket_iface =
    123       thunk::GetPPB_WebSocket_1_0_Thunk();
    124 
    125   std::string url("ws://ws.google.com");
    126   PP_Var url_var = MakeStringVar(url);
    127 
    128   LockingResourceReleaser res(websocket_iface->Create(pp_instance()));
    129 
    130   // Establish the connection virtually.
    131   int32_t result =
    132       websocket_iface->Connect(res.get(), url_var, NULL, 0, MakeCallback());
    133   ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    134 
    135   ResourceMessageCallParams params;
    136   IPC::Message msg;
    137   ASSERT_TRUE(sink().GetFirstResourceCallMatching(
    138       PpapiHostMsg_WebSocket_Connect::ID, &params, &msg));
    139 
    140   ResourceMessageReplyParams connect_reply_params(params.pp_resource(),
    141                                                   params.sequence());
    142   connect_reply_params.set_result(PP_OK);
    143   PluginMessageFilter::DispatchResourceReplyForTest(
    144       connect_reply_params,
    145       PpapiPluginMsg_WebSocket_ConnectReply(url, std::string()));
    146 
    147   EXPECT_EQ(PP_OK, g_callback_result);
    148   EXPECT_TRUE(g_callback_called);
    149 
    150   PP_Var message;
    151   result = websocket_iface->ReceiveMessage(res.get(), &message, MakeCallback());
    152   EXPECT_FALSE(g_callback_called);
    153 
    154   // Synthesize a WebSocket_ErrorReply message.
    155   ResourceMessageReplyParams error_reply_params(res.get(), 0);
    156   error_reply_params.set_result(PP_OK);
    157   PluginMessageFilter::DispatchResourceReplyForTest(
    158       error_reply_params, PpapiPluginMsg_WebSocket_ErrorReply());
    159 
    160   EXPECT_EQ(PP_ERROR_FAILED, g_callback_result);
    161   EXPECT_TRUE(g_callback_called);
    162 }
    163 
    164 }  // namespace proxy
    165 }  // namespace ppapi
    166