15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_websocket.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <memory> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_bool.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_completion_callback.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_resource.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_core.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_var.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_var_array_buffer.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_websocket.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ppapi/c/private/ppb_testing_private.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/instance.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/module.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/var_array_buffer.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/cpp/websocket.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/utility/websocket/websocket_api.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// net::SpawnedTestServer serves WebSocket service for testing. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Following URLs are handled by pywebsocket handlers in 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// net/data/websocket/*_wsh.py. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEchoServerURL[] = "echo-with-no-extension"; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCloseServerURL[] = "close"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCloseWithCodeAndReasonServerURL[] = "close-code-and-reason"; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kProtocolTestServerURL[] = "protocol-test?protocol="; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kInvalidURLs[] = { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://www.google.com/invalid_scheme", 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ws://www.google.com/invalid#fragment", 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ws://www.google.com:65535/invalid_port", 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal packet sizes. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint64_t kMessageFrameOverhead = 6; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WebSocketEvent { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum EventType { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_OPEN, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_MESSAGE, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_ERROR, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EVENT_CLOSE 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketEvent(EventType type, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_clean, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t close_code, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var& var) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : event_type(type), 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) was_clean(was_clean), 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_code(close_code), 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var(var) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EventType event_type; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_clean; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t close_code; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var var; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReleaseResourceDelegate : public TestCompletionCallback::Delegate { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ReleaseResourceDelegate(const PPB_Core* core_interface, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource resource) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : core_interface_(core_interface), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource_(resource) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TestCompletionCallback::Delegate implementation. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCallback(void* user_data, int32_t result) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resource_) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(resource_); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_Core* core_interface_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource resource_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWebSocketAPI : public pp::WebSocketAPI { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TestWebSocketAPI(pp::Instance* instance) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pp::WebSocketAPI(instance), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_(false), 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_(false), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closed_(false), 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_connected_(false), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_received_(false), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_closed_(false), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_(instance->pp_instance()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WebSocketDidOpen() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketEvent(WebSocketEvent::EVENT_OPEN, true, 0U, pp::Var())); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_ = true; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_for_connected_) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->QuitMessageLoop(instance_); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_connected_ = false; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void WebSocketDidClose( 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool was_clean, uint16_t code, const pp::Var& reason) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketEvent(WebSocketEvent::EVENT_CLOSE, was_clean, code, reason)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connected_ = true; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closed_ = true; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_for_connected_ || wait_for_closed_) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->QuitMessageLoop(instance_); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_connected_ = false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_closed_ = false; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void HandleWebSocketMessage(const pp::Var &message) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketEvent(WebSocketEvent::EVENT_MESSAGE, true, 0U, message)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_ = true; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wait_for_received_) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->QuitMessageLoop(instance_); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_received_ = false; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_ = false; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void HandleWebSocketError() { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_.push_back( 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSocketEvent(WebSocketEvent::EVENT_ERROR, true, 0U, pp::Var())); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForConnected() { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connected_) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_connected_ = true; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->RunMessageLoop(instance_); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForReceived() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!received_) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_received_ = true; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->RunMessageLoop(instance_); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForClosed() { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!closed_) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_closed_ = true; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTestingInterface()->RunMessageLoop(instance_); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& GetSeenEvents() const { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<WebSocketEvent> events_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool connected_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool received_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool closed_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait_for_connected_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait_for_received_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool wait_for_closed_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Instance instance_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(WebSocket); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestWebSocket::Init() { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket_interface_ = static_cast<const PPB_WebSocket*>( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_INTERFACE)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_ = static_cast<const PPB_Var*>( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraybuffer_interface_ = static_cast<const PPB_VarArrayBuffer*>( 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->GetBrowserInterface( 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPB_VAR_ARRAY_BUFFER_INTERFACE)); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_ = static_cast<const PPB_Core*>( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!websocket_interface_ || !var_interface_ || !arraybuffer_interface_ || 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !core_interface_) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CheckTestingInterface(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestWebSocket::RunTests(const std::string& filter) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(IsWebSocket, filter); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UninitializedPropertiesAccess, filter); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(InvalidConnect, filter); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(Protocols, filter); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(GetURL, filter); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(ValidConnect, filter); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(InvalidClose, filter); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter); 216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch RUN_TEST_BACKGROUND(TestWebSocket, TextSendReceiveTwice, filter); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(BinarySendReceive, filter); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(StressedSendReceive, filter); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(BufferedAmount, filter); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PP_Resource for WebSocket may be released later because of an internal 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference for asynchronous IPC handling. So, suppress reference check on 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the following AbortCallsWithCallback test. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST(AbortCallsWithCallback, filter); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(AbortSendMessageCall, filter); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(AbortCloseCall, filter); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(AbortReceiveMessageCall, filter); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidConnect, filter); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityProtocols, filter); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetURL, filter); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidConnect, filter); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidClose, filter); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidClose, filter); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetProtocol, filter); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityTextSendReceive, filter); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityBinarySendReceive, filter); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RUN_TEST_WITH_REFERENCE_CHECK(UtilityBufferedAmount, filter); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::GetFullURL(const char* url) { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string rv = "ws://"; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Some WebSocket tests don't start the server so there'll be no host and 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // port. 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (instance_->websocket_host().empty()) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv += "127.0.0.1"; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rv += instance_->websocket_host(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance_->websocket_port() != -1) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[10]; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf(buffer, ":%d", instance_->websocket_port()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv += std::string(buffer); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv += "/"; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv += url; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var TestWebSocket::CreateVarString(const std::string& string) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return var_interface_->VarFromUtf8(string.c_str(), string.size()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var TestWebSocket::CreateVarBinary(const std::vector<uint8_t>& binary) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var var = arraybuffer_interface_->Create(binary.size()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t* var_data = static_cast<uint8_t*>(arraybuffer_interface_->Map(var)); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(binary.begin(), binary.end(), var_data); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return var; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestWebSocket::ReleaseVar(const PP_Var& var) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var_interface_->Release(var); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestWebSocket::AreEqualWithString(const PP_Var& var, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& string) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (var.type != PP_VARTYPE_STRING) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t utf8_length; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* utf8 = var_interface_->VarToUtf8(var, &utf8_length); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (utf8_length != string.size()) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (string.compare(utf8)) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestWebSocket::AreEqualWithBinary(const PP_Var& var, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<uint8_t>& binary) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t buffer_size = 0; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool success = arraybuffer_interface_->ByteLength(var, &buffer_size); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success || buffer_size != binary.size()) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!std::equal(binary.begin(), binary.end(), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<uint8_t*>(arraybuffer_interface_->Map(var)))) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource TestWebSocket::Connect(const std::string& url, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t* result, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& protocol) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var protocols[] = { PP_MakeUndefined() }; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ws) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url_var = CreateVarString(url); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t protocol_count = 0U; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (protocol.size()) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocols[0] = CreateVarString(protocol); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_count = 1U; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Connect( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, url_var, protocols, protocol_count, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url_var); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (protocol.size()) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(protocols[0]); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = callback.result(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ws; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid TestWebSocket::Send(int32_t /* result */, PP_Resource ws, 325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const std::string& message) { 326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PP_Var message_var = CreateVarString(message); 327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch websocket_interface_->SendMessage(ws, message_var); 328558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ReleaseVar(message_var); 329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestIsWebSocket() { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that a NULL resource isn't a websocket. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Resource null_resource; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool result = 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket_interface_->IsWebSocket(null_resource.pp_resource()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(result); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->IsWebSocket(ws); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUninitializedPropertiesAccess() { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t bufferedAmount = websocket_interface_->GetBufferedAmount(ws); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, bufferedAmount); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t close_code = websocket_interface_->GetCloseCode(ws); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, close_code); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var close_reason = websocket_interface_->GetCloseReason(ws); 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(close_reason, std::string())); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(close_reason); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool close_was_clean = websocket_interface_->GetCloseWasClean(ws); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_FALSE, close_was_clean); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var extensions = websocket_interface_->GetExtensions(ws); 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(extensions, std::string())); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(extensions); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var protocol = websocket_interface_->GetProtocol(ws); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(protocol, std::string())); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(protocol); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WebSocketReadyState ready_state = 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket_interface_->GetReadyState(ws); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ready_state); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url = websocket_interface_->GetURL(ws); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(url, std::string())); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestInvalidConnect() { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var protocols[] = { PP_MakeUndefined() }; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Connect( 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_MakeUndefined(), protocols, 1U, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Connect( 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_MakeUndefined(), protocols, 1U, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, callback.result()); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; kInvalidURLs[i]; ++i) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(kInvalidURLs[i], &result, std::string()); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestProtocols() { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str()); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var bad_protocols[] = { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateVarString("x-test"), 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateVarString("x-test") 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var good_protocols[] = { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateVarString("x-test"), 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateVarString("x-yatest") 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Connect( 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, url, bad_protocols, 2U, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws = websocket_interface_->Create(instance_->pp_instance()); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket_interface_->Connect( 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, url, good_protocols, 2U, PP_BlockUntilComplete()); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, result); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(bad_protocols[i]); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(good_protocols[i]); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestGetURL() { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; kInvalidURLs[i]; ++i) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = Connect(kInvalidURLs[i], &result, std::string()); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url = websocket_interface_->GetURL(ws); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(url, kInvalidURLs[i])); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestValidConnect() { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var extensions = websocket_interface_->GetExtensions(ws); 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(extensions, std::string())); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReleaseVar(extensions); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestInvalidClose() { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var reason = CreateVarString("close for test"); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback async_callback(instance_->pp_instance(), PP_REQUIRED); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close before connect. 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with bad arguments. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, 1U, reason, callback.GetCallback().pp_completion_callback())); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_NOACCESS, callback.result()); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with PP_VARTYPE_NULL. 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(), 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with PP_VARTYPE_NULL and ongoing receive message. 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var receive_message_var; 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_message_var, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_callback.GetCallback().pp_completion_callback()); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(), 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* send_message = "hi"; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var send_message_var = CreateVarString(send_message); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, send_message_var); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(send_message_var); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_callback.WaitForResult(PP_OK_COMPLETIONPENDING); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, async_callback.result()); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(receive_message_var, send_message)); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(receive_message_var); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close twice. 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_callback.GetCallback().pp_completion_callback()); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call another Close() before previous one is in progress. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, result); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_callback.WaitForResult(PP_OK_COMPLETIONPENDING); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, async_callback.result()); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Call another Close() after previous one is completed. 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This Close() must do nothing and reports no error. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(reason); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestValidClose() { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var reason = CreateVarString("close for test"); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str()); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var protocols[] = { PP_MakeUndefined() }; 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback another_callback( 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close without code and reason. 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED, reason, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with PP_VARTYPE_UNDEFINED. 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->Close( 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close in connecting. 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ongoing connect failed with PP_ERROR_ABORTED, then the close is done 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // successfully. 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws = websocket_interface_->Create(instance_->pp_instance()); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Connect( 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, url, protocols, 0U, callback.GetCallback().pp_completion_callback()); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.GetCallback().pp_completion_callback()); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, another_callback.result()); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close in closing. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first close will be done successfully, then the second one failed with 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with PP_ERROR_INPROGRESS immediately. 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback()); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.GetCallback().pp_completion_callback()); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, result); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with ongoing receive message. 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var receive_message_var; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_message_var, 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback()); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.GetCallback().pp_completion_callback()); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, another_callback.result()); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with PP_VARTYPE_UNDEFINED and ongoing receive message. 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_message_var, 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.GetCallback().pp_completion_callback()); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, another_callback.result()); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server initiated closing handshake. 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect( 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetFullURL(kCloseWithCodeAndReasonServerURL), &result, std::string()); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Text messsage "1000 bye" requests the server to initiate closing handshake 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with code being 1000 and reason being "bye". 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var close_request_var = CreateVarString("1000 bye"); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, close_request_var); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(close_request_var); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_message_var, 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(reason); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestGetProtocol() { 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* expected_protocols[] = { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "x-chat", 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "hoehoe", 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; expected_protocols[i]; ++i) { 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url(GetFullURL(kProtocolTestServerURL)); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url += expected_protocols[i]; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = Connect(url.c_str(), &result, expected_protocols[i]); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var protocol = websocket_interface_->GetProtocol(ws); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(protocol, expected_protocols[i])); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(protocol); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestTextSendReceive() { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to test echo server. 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t connect_result; 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, connect_result); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send 'hello pepper' text message. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* message = "hello pepper"; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var message_var = CreateVarString(message); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket_interface_->SendMessage(ws, message_var); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(message_var); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed 'hello pepper'. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var received_message; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &received_message, callback.GetCallback().pp_completion_callback())); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(received_message, message)); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(received_message); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 756558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Run as a BACKGROUND test. 757558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstd::string TestWebSocket::TestTextSendReceiveTwice() { 758558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Connect to test echo server. 759558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int32_t connect_result; 760558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PP_Resource ws = 761558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); 762558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_TRUE(ws); 763558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_EQ(PP_OK, connect_result); 764558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch pp::MessageLoop message_loop = pp::MessageLoop::GetCurrent(); 765558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch pp::CompletionCallbackFactory<TestWebSocket> factory(this); 766558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 767558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send, 768558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ws, std::string("hello"))); 769558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // When the server receives 'Goodbye', it closes the session. 770558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send, 771558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ws, std::string("Goodbye"))); 772558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.PostQuit(false); 773558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.Run(); 774558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 775558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 776558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PP_Var received_message; 777558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int32_t result = websocket_interface_->ReceiveMessage( 778558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ws, &received_message, callback.GetCallback().pp_completion_callback()); 779558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_EQ(PP_OK, result); 780558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Since we don't run the message loop, the callback will stay 781558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // "pending and scheduled to run" state. 782558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 783558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Waiting for the connection close which will be done by the server. 784558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch while (true) { 785558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PP_WebSocketReadyState ready_state = 786558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch websocket_interface_->GetReadyState(ws); 787558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (ready_state != PP_WEBSOCKETREADYSTATE_CONNECTING && 788558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ready_state != PP_WEBSOCKETREADYSTATE_OPEN) { 789558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch break; 790558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 791558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PlatformSleep(100); // 100ms 792558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 793558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 794558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Cleanup the message loop 795558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.PostQuit(false); 796558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch message_loop.Run(); 797558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 798558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_EQ(PP_OK, callback.result()); 799558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_TRUE(AreEqualWithString(received_message, "hello")); 800558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ReleaseVar(received_message); 801558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch core_interface_->ReleaseResource(ws); 802558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PASS(); 803558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 804558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestBinarySendReceive() { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to test echo server. 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t connect_result; 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, connect_result); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send binary message. 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> binary(256); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < binary.size(); ++i) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) binary[i] = i; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var message_var = CreateVarBinary(binary); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket_interface_->SendMessage(ws, message_var); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(message_var); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed binary. 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var received_message; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &received_message, callback.GetCallback().pp_completion_callback())); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithBinary(received_message, binary)); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(received_message); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestStressedSendReceive() { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to test echo server. 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t connect_result; 838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = 839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, connect_result); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare PP_Var objects to send. 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* text = "hello pepper"; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var text_var = CreateVarString(text); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> binary(256); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < binary.size(); ++i) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) binary[i] = i; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var binary_var = CreateVarBinary(binary); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare very large binary data over 64KiB. Object serializer in 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ppapi_proxy has a limitation of 64KiB as maximum return PP_Var data size 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to SRPC. In case received data over 64KiB exists, a specific code handles 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this large data via asynchronous callback from main thread. This data 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // intends to test the code. 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> large_binary(65 * 1024); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < large_binary.size(); ++i) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) large_binary[i] = i & 0xff; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var large_binary_var = CreateVarBinary(large_binary); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send many messages. 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 256; ++i) { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, text_var); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, binary_var); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, large_binary_var); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(text_var); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(binary_var); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(large_binary_var); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed data. 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= 512; ++i) { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var received_message; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &received_message, 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback())); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == 512) { 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithBinary(received_message, large_binary)); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (i & 1) { 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithBinary(received_message, binary)); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(received_message, text)); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(received_message); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestBufferedAmount() { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to test echo server. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t connect_result; 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, connect_result); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare a large message that is not aligned with the internal buffer 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sizes. 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message(8193, 'x'); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var message_var = CreateVarString(message); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t buffered_amount = 0; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 100; i++) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, message_var); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket_interface_->GetBufferedAmount(ws); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffered amount size 262144 is too big for the internal buffer size. 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffered_amount > 262144) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close connection. 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reason_str = "close while busy"; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var reason = CreateVarString(reason_str.c_str()); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.GetCallback().pp_completion_callback()); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket_interface_->GetReadyState(ws)); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(result); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket_interface_->GetReadyState(ws)); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t base_buffered_amount = websocket_interface_->GetBufferedAmount(ws); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After connection closure, all sending requests fail and just increase 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the bufferedAmount property. 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Var empty_string = CreateVarString(std::string()); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, empty_string); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, result); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket_interface_->GetBufferedAmount(ws); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_buffered_amount = buffered_amount; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, reason); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, result); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket_interface_->GetBufferedAmount(ws); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t reason_frame_size = kMessageFrameOverhead + reason_str.length(); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(message_var); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(reason); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(empty_string); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test abort behaviors where a WebSocket PP_Resource is released while each 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function is in-flight on the WebSocket PP_Resource. 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestAbortCallsWithCallback() { 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Following tests make sure the behavior for functions which require a 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback. The callback must get a PP_ERROR_ABORTED. 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the behavior for Connect(). 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = GetFullURL(kEchoServerURL); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var url_var = CreateVarString(url); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback connect_callback( 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket_interface_->Connect( 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, url_var, NULL, 0, 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connect_callback.GetCallback().pp_completion_callback()); 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connect_callback.WaitForResult(result); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, connect_callback.result()); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the behavior for Close(). 983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(url, &result, std::string()); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var reason_var = CreateVarString("abort"); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback close_callback( 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason_var, 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.GetCallback().pp_completion_callback()); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.WaitForResult(result); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result()); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(reason_var); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the behavior for ReceiveMessage(). 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the simplest case to wait for data which never arrives, here. 1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(url, &result, std::string()); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var receive_var; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback receive_callback( 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_var, 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_callback.GetCallback().pp_completion_callback()); 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_callback.WaitForResult(result); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result()); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the resource in the aborting receive completion callback which is 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // introduced by calling Close(). 1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(url, &result, std::string()); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &receive_var, 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_callback.GetCallback().pp_completion_callback()); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseResourceDelegate receive_delegate(core_interface_, ws); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_callback.SetDelegate(&receive_delegate); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.GetCallback().pp_completion_callback()); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_callback.WaitForResult(result); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(receive_callback); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result()); 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.WaitForResult(result); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(close_callback); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result()); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(url_var); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestAbortSendMessageCall() { 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the behavior for SendMessage(). 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function doesn't require a callback, but operation will be done 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronously in WebKit and browser process. 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> large_binary(65 * 1024); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var large_var = CreateVarBinary(large_binary); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = GetFullURL(kEchoServerURL); 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = Connect(url, &result, std::string()); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, large_var); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(large_var); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestAbortCloseCall() { 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release the resource in the close completion callback. 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = GetFullURL(kEchoServerURL); 1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PP_Resource ws = Connect(url, &result, std::string()); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback close_callback( 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->Close( 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.GetCallback().pp_completion_callback()); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseResourceDelegate close_delegate(core_interface_, ws); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.SetDelegate(&close_delegate); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.WaitForResult(result); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(close_callback); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, close_callback.result()); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestAbortReceiveMessageCall() { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the behavior where receive process might be in-flight. 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> large_binary(65 * 1024); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var large_var = CreateVarBinary(large_binary); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* text = "yukarin"; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var text_var = CreateVarString(text); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url = GetFullURL(kEchoServerURL); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result; 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Resource ws; 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each trial sends |trial_count| + 1 messages and receives just |trial| 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of message(s) before releasing the WebSocket. The WebSocket is 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // released while the next message is going to be received. 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int trial_count = 8; 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int trial = 1; trial <= trial_count; trial++) { 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(url, &result, std::string()); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= trial_count; ++i) { 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, text_var); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var var; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < trial; ++i) { 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &var, callback.GetCallback().pp_completion_callback())); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(var, text)); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(var); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &var, callback.GetCallback().pp_completion_callback()); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PP_OK) { 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(result); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same test, but the last receiving message is large message over 64KiB. 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int trial = 1; trial <= trial_count; trial++) { 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ws = Connect(url, &result, std::string()); 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ws); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i <= trial_count; ++i) { 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == trial) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, large_var); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->SendMessage(ws, text_var); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Var var; 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < trial; ++i) { 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(websocket_interface_->ReceiveMessage( 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &var, callback.GetCallback().pp_completion_callback())); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(var, text)); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(var); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket_interface_->ReceiveMessage( 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws, &var, callback.GetCallback().pp_completion_callback()); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_interface_->ReleaseResource(ws); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != PP_OK) { 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.WaitForResult(result); 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(large_var); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseVar(text_var); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestCcInterfaces() { 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // C++ bindings is simple straightforward, then just verifies interfaces work 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as a interface bridge fine. 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::WebSocket ws(instance_); 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check uninitialized properties access. 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, ws.GetBufferedAmount()); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, ws.GetCloseCode()); 1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), std::string())); 11675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_FALSE(ws.GetCloseWasClean()); 1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), std::string())); 1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string())); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ws.GetReadyState()); 1171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), std::string())); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check communication interfaces (connect, send, receive, and close). 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback connect_callback( 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connect_callback.WaitForResult(ws.Connect( 11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pp::Var(GetFullURL(kCloseServerURL)), NULL, 0U, 11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) connect_callback.GetCallback())); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(connect_callback); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, connect_callback.result()); 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string text_message("hello C++"); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = ws.SendMessage(pp::Var(text_message)); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> binary(256); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < binary.size(); ++i) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) binary[i] = i; 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ws.SendMessage( 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(pp::PASS_REF, CreateVarBinary(binary))); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var text_receive_var; 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback text_receive_callback( 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text_receive_callback.WaitForResult( 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ws.ReceiveMessage(&text_receive_var, 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) text_receive_callback.GetCallback())); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, text_receive_callback.result()); 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE( 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AreEqualWithString(text_receive_var.pp_var(), text_message.c_str())); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var binary_receive_var; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback binary_receive_callback( 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) binary_receive_callback.WaitForResult( 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ws.ReceiveMessage(&binary_receive_var, 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) binary_receive_callback.GetCallback())); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, binary_receive_callback.result()); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithBinary(binary_receive_var.pp_var(), binary)); 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCompletionCallback close_callback( 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance_->pp_instance(), callback_type()); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reason("bye"); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_callback.WaitForResult(ws.Close( 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason), 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_callback.GetCallback())); 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(close_callback); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, close_callback.result()); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check initialized properties access. 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, ws.GetBufferedAmount()); 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, ws.GetCloseCode()); 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE( 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AreEqualWithString(ws.GetCloseReason().pp_var(), reason.c_str())); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(true, ws.GetCloseWasClean()); 1227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string())); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, ws.GetReadyState()); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString( 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws.GetURL().pp_var(), GetFullURL(kCloseServerURL).c_str())); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityInvalidConnect() { 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(pp::Var(), protocols, 1U); 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, websocket.GetSeenEvents().size()); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Connect(pp::Var(), protocols, 1U); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, result); 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, websocket.GetSeenEvents().size()); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; kInvalidURLs[i]; ++i) { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI ws(instance_); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = ws.Connect(pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == PP_OK_COMPLETIONPENDING) { 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ws.WaitForClosed(); 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = ws.GetSeenEvents(); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, ws.GetSeenEvents().size()); 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, ws.GetSeenEvents().size()); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityProtocols() { 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var bad_protocols[] = { 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(std::string("x-test")), pp::Var(std::string("x-test")) }; 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var good_protocols[] = { 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(std::string("x-test")), pp::Var(std::string("x-yatest")) }; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect( 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(GetFullURL(kEchoServerURL)), bad_protocols, 2U); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, websocket.GetSeenEvents().size()); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect( 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(GetFullURL(kEchoServerURL)), good_protocols, 2U); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Protocol arguments are valid, but this test run without a WebSocket 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server. As a result, OnError() and OnClose() are invoked because of 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a connection establishment failure. 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, events.size()); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(events[1].was_clean); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityGetURL() { 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; kInvalidURLs[i]; ++i) { 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect( 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == PP_OK_COMPLETIONPENDING) { 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForClosed(); 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, events.size()); 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, result); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, websocket.GetSeenEvents().size()); 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var url = websocket.GetURL(); 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(url.pp_var(), kInvalidURLs[i])); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityValidConnect() { 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect( 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1U, events.size()); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE( 1333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AreEqualWithString(websocket.GetExtensions().pp_var(), std::string())); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityInvalidClose() { 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var reason = pp::Var(std::string("close for test")); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close before connect. 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Close( 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason); 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, result); 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0U, websocket.GetSeenEvents().size()); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close with bad arguments. 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 0); 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close(1U, reason); 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_NOACCESS, result); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1U, events.size()); 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityValidClose() { 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reason("close for test"); 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::Var url = pp::Var(GetFullURL(kCloseServerURL)); 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close. 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(url, NULL, 0U); 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close( 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForClosed(); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, events.size()); 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(events[1].was_clean); 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, events[1].close_code); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), reason.c_str())); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close in connecting. 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ongoing connect failed with PP_ERROR_ABORTED, then the close is done 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // successfully. 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(url, NULL, 0U); 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close( 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForClosed(); 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(events.size() == 2 || events.size() == 3); 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = 0; 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.size() == 3) 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(events[index].was_clean); 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close in closing. 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first close will be done successfully, then the second one failed with 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with PP_ERROR_INPROGRESS immediately. 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(url, NULL, 0U); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close( 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close( 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_INPROGRESS, result); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForClosed(); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(events.size() == 2 || events.size() == 3); 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = 0; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.size() == 3) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(events[index].was_clean); 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityGetProtocol() { 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string protocol("x-chat"); 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var(protocol) }; 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string url(GetFullURL(kProtocolTestServerURL)); 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url += protocol; 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = websocket.Connect(pp::Var(url), protocols, 1U); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForReceived(); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString( 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.GetProtocol().pp_var(), protocol.c_str())); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The server to which this test connect returns the decided protocol as a 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // text frame message. So the WebSocketEvent records EVENT_MESSAGE event 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after EVENT_OPEN event. 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, events.size()); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), protocol.c_str())); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityTextSendReceive() { 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send 'hello pepper'. 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message1("hello pepper"); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Send(pp::Var(std::string(message1))); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed 'hello pepper'. 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForReceived(); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send 'goodbye pepper'. 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message2("goodbye pepper"); 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Send(pp::Var(std::string(message2))); 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed 'goodbye pepper'. 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForReceived(); 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(3U, events.size()); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), message1.c_str())); 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[2].event_type); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(events[2].var.pp_var(), message2.c_str())); 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityBinarySendReceive() { 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send binary message. 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t len = 256; 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8_t> binary(len); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 0; i < len; ++i) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) binary[i] = i; 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pp::VarArrayBuffer message(len); 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t* var_data = static_cast<uint8_t*>(message.Map()); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(binary.begin(), binary.end(), var_data); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Send(message); 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Receive echoed binary message. 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForReceived(); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2U, events.size()); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithBinary(events[1].var.pp_var(), binary)); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestWebSocket::TestUtilityBufferedAmount() { 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Connect to test echo server. 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const pp::Var protocols[] = { pp::Var() }; 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWebSocketAPI websocket(instance_); 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForConnected(); 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare a large message that is not aligned with the internal buffer 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sizes. 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string message(8193, 'x'); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t buffered_amount = 0; 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sent; 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (sent = 0; sent < 100; sent++) { 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Send(pp::Var(message)); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK, result); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket.GetBufferedAmount(); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffered amount size 262144 is too big for the internal buffer size. 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffered_amount > 262144) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close connection. 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reason = "close while busy"; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Close( 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, websocket.GetReadyState()); 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) websocket.WaitForClosed(); 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, websocket.GetReadyState()); 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t base_buffered_amount = websocket.GetBufferedAmount(); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t events_on_closed = websocket.GetSeenEvents().size(); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // After connection closure, all sending requests fail and just increase 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the bufferedAmount property. 1561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result = websocket.Send(pp::Var(std::string())); 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, result); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket.GetBufferedAmount(); 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_buffered_amount = buffered_amount; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = websocket.Send(pp::Var(reason)); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_ERROR_FAILED, result); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffered_amount = websocket.GetBufferedAmount(); 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64_t reason_frame_size = kMessageFrameOverhead + reason.length(); 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(events_on_closed, events.size()); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t last_event = events_on_closed - 1; 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t i = 1; i < last_event; ++i) { 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[i].event_type); 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(AreEqualWithString(events[i].var.pp_var(), message)); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[last_event].event_type); 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(events[last_event].was_clean); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PASS(); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1586