[email protected] | 810f8a0 | 2012-01-12 07:03:50 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "ppapi/tests/test_websocket.h" |
| 6 | |
avi | e029c413 | 2015-12-23 06:45:22 | [diff] [blame] | 7 | #include <stddef.h> |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 8 | #include <stdio.h> |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 9 | #include <string.h> |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 10 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 11 | #include <algorithm> |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 12 | #include <memory> |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 13 | #include <string> |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 14 | #include <vector> |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 15 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 16 | #include "ppapi/c/pp_bool.h" |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 17 | #include "ppapi/c/pp_completion_callback.h" |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 18 | #include "ppapi/c/pp_errors.h" |
| 19 | #include "ppapi/c/pp_instance.h" |
| 20 | #include "ppapi/c/pp_resource.h" |
| 21 | #include "ppapi/c/pp_var.h" |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 22 | #include "ppapi/c/ppb_core.h" |
| 23 | #include "ppapi/c/ppb_var.h" |
[email protected] | 9c6e0de | 2012-01-27 04:55:55 | [diff] [blame] | 24 | #include "ppapi/c/ppb_var_array_buffer.h" |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 25 | #include "ppapi/c/ppb_websocket.h" |
[email protected] | 7310b16 | 2013-11-25 22:39:15 | [diff] [blame] | 26 | #include "ppapi/c/private/ppb_testing_private.h" |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 27 | #include "ppapi/cpp/instance.h" |
| 28 | #include "ppapi/cpp/module.h" |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 29 | #include "ppapi/cpp/var_array_buffer.h" |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 30 | #include "ppapi/cpp/websocket.h" |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 31 | #include "ppapi/tests/test_utils.h" |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 32 | #include "ppapi/tests/testing_instance.h" |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 33 | #include "ppapi/utility/websocket/websocket_api.h" |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 34 | |
[email protected] | ce7d0cbc | 2013-05-03 18:57:22 | [diff] [blame] | 35 | // net::SpawnedTestServer serves WebSocket service for testing. |
[email protected] | 13d22df1 | 2012-10-24 04:26:38 | [diff] [blame] | 36 | // Following URLs are handled by pywebsocket handlers in |
[email protected] | 4b187da | 2012-11-06 00:05:29 | [diff] [blame] | 37 | // net/data/websocket/*_wsh.py. |
[email protected] | 033fb2d | 2012-10-17 08:40:41 | [diff] [blame] | 38 | const char kEchoServerURL[] = "echo-with-no-extension"; |
[email protected] | 033fb2d | 2012-10-17 08:40:41 | [diff] [blame] | 39 | const char kCloseServerURL[] = "close"; |
[email protected] | 033fb2d | 2012-10-17 08:40:41 | [diff] [blame] | 40 | const char kCloseWithCodeAndReasonServerURL[] = "close-code-and-reason"; |
[email protected] | 033fb2d | 2012-10-17 08:40:41 | [diff] [blame] | 41 | const char kProtocolTestServerURL[] = "protocol-test?protocol="; |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 42 | |
Matt Menke | 9710afc | 2018-07-20 15:23:42 | [diff] [blame] | 43 | const char* const kInvalidURLs[] = {"http://www.google.com/invalid_scheme", |
| 44 | "ws://www.google.com/invalid#fragment", |
| 45 | "ws://www.google.com:7/invalid_port", |
| 46 | NULL}; |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 47 | |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 48 | // Internal packet sizes. |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 49 | const uint64_t kMessageFrameOverhead = 6; |
| 50 | |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 51 | namespace { |
| 52 | |
| 53 | struct WebSocketEvent { |
| 54 | enum EventType { |
| 55 | EVENT_OPEN, |
| 56 | EVENT_MESSAGE, |
| 57 | EVENT_ERROR, |
| 58 | EVENT_CLOSE |
| 59 | }; |
| 60 | |
| 61 | WebSocketEvent(EventType type, |
| 62 | bool was_clean, |
| 63 | uint16_t close_code, |
| 64 | const pp::Var& var) |
| 65 | : event_type(type), |
| 66 | was_clean(was_clean), |
| 67 | close_code(close_code), |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 68 | var(var) { |
| 69 | } |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 70 | EventType event_type; |
| 71 | bool was_clean; |
| 72 | uint16_t close_code; |
| 73 | pp::Var var; |
| 74 | }; |
| 75 | |
[email protected] | cc2386c4 | 2012-06-29 04:41:42 | [diff] [blame] | 76 | class ReleaseResourceDelegate : public TestCompletionCallback::Delegate { |
| 77 | public: |
| 78 | explicit ReleaseResourceDelegate(const PPB_Core* core_interface, |
| 79 | PP_Resource resource) |
| 80 | : core_interface_(core_interface), |
| 81 | resource_(resource) { |
| 82 | } |
| 83 | |
| 84 | // TestCompletionCallback::Delegate implementation. |
| 85 | virtual void OnCallback(void* user_data, int32_t result) { |
| 86 | if (resource_) |
| 87 | core_interface_->ReleaseResource(resource_); |
| 88 | } |
| 89 | |
| 90 | private: |
| 91 | const PPB_Core* core_interface_; |
| 92 | PP_Resource resource_; |
| 93 | }; |
| 94 | |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 95 | class TestWebSocketAPI : public pp::WebSocketAPI { |
| 96 | public: |
| 97 | explicit TestWebSocketAPI(pp::Instance* instance) |
| 98 | : pp::WebSocketAPI(instance), |
| 99 | connected_(false), |
| 100 | received_(false), |
| 101 | closed_(false), |
| 102 | wait_for_connected_(false), |
| 103 | wait_for_received_(false), |
| 104 | wait_for_closed_(false), |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 105 | instance_(instance->pp_instance()) { |
| 106 | } |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 107 | |
| 108 | virtual void WebSocketDidOpen() { |
| 109 | events_.push_back( |
| 110 | WebSocketEvent(WebSocketEvent::EVENT_OPEN, true, 0U, pp::Var())); |
| 111 | connected_ = true; |
| 112 | if (wait_for_connected_) { |
| 113 | GetTestingInterface()->QuitMessageLoop(instance_); |
| 114 | wait_for_connected_ = false; |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | virtual void WebSocketDidClose( |
| 119 | bool was_clean, uint16_t code, const pp::Var& reason) { |
| 120 | events_.push_back( |
| 121 | WebSocketEvent(WebSocketEvent::EVENT_CLOSE, was_clean, code, reason)); |
| 122 | connected_ = true; |
| 123 | closed_ = true; |
| 124 | if (wait_for_connected_ || wait_for_closed_) { |
| 125 | GetTestingInterface()->QuitMessageLoop(instance_); |
| 126 | wait_for_connected_ = false; |
| 127 | wait_for_closed_ = false; |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | virtual void HandleWebSocketMessage(const pp::Var &message) { |
| 132 | events_.push_back( |
| 133 | WebSocketEvent(WebSocketEvent::EVENT_MESSAGE, true, 0U, message)); |
| 134 | received_ = true; |
| 135 | if (wait_for_received_) { |
| 136 | GetTestingInterface()->QuitMessageLoop(instance_); |
| 137 | wait_for_received_ = false; |
| 138 | received_ = false; |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | virtual void HandleWebSocketError() { |
| 143 | events_.push_back( |
| 144 | WebSocketEvent(WebSocketEvent::EVENT_ERROR, true, 0U, pp::Var())); |
| 145 | } |
| 146 | |
| 147 | void WaitForConnected() { |
| 148 | if (!connected_) { |
| 149 | wait_for_connected_ = true; |
| 150 | GetTestingInterface()->RunMessageLoop(instance_); |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | void WaitForReceived() { |
| 155 | if (!received_) { |
| 156 | wait_for_received_ = true; |
| 157 | GetTestingInterface()->RunMessageLoop(instance_); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | void WaitForClosed() { |
| 162 | if (!closed_) { |
| 163 | wait_for_closed_ = true; |
| 164 | GetTestingInterface()->RunMessageLoop(instance_); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | const std::vector<WebSocketEvent>& GetSeenEvents() const { |
| 169 | return events_; |
| 170 | } |
| 171 | |
| 172 | private: |
| 173 | std::vector<WebSocketEvent> events_; |
| 174 | bool connected_; |
| 175 | bool received_; |
| 176 | bool closed_; |
| 177 | bool wait_for_connected_; |
| 178 | bool wait_for_received_; |
| 179 | bool wait_for_closed_; |
| 180 | PP_Instance instance_; |
| 181 | }; |
| 182 | |
| 183 | } // namespace |
| 184 | |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 185 | REGISTER_TEST_CASE(WebSocket); |
| 186 | |
| 187 | bool TestWebSocket::Init() { |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 188 | websocket_interface_ = static_cast<const PPB_WebSocket*>( |
| 189 | pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_INTERFACE)); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 190 | var_interface_ = static_cast<const PPB_Var*>( |
| 191 | pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); |
[email protected] | 9c6e0de | 2012-01-27 04:55:55 | [diff] [blame] | 192 | arraybuffer_interface_ = static_cast<const PPB_VarArrayBuffer*>( |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 193 | pp::Module::Get()->GetBrowserInterface( |
[email protected] | 9c6e0de | 2012-01-27 04:55:55 | [diff] [blame] | 194 | PPB_VAR_ARRAY_BUFFER_INTERFACE)); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 195 | core_interface_ = static_cast<const PPB_Core*>( |
| 196 | pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE)); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 197 | if (!websocket_interface_ || !var_interface_ || !arraybuffer_interface_ || |
| 198 | !core_interface_) |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 199 | return false; |
| 200 | |
[email protected] | a732cec | 2011-12-22 08:35:52 | [diff] [blame] | 201 | return CheckTestingInterface(); |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 202 | } |
| 203 | |
| 204 | void TestWebSocket::RunTests(const std::string& filter) { |
[email protected] | 2117f25 | 2011-12-15 06:43:11 | [diff] [blame] | 205 | RUN_TEST_WITH_REFERENCE_CHECK(IsWebSocket, filter); |
| 206 | RUN_TEST_WITH_REFERENCE_CHECK(UninitializedPropertiesAccess, filter); |
| 207 | RUN_TEST_WITH_REFERENCE_CHECK(InvalidConnect, filter); |
| 208 | RUN_TEST_WITH_REFERENCE_CHECK(Protocols, filter); |
| 209 | RUN_TEST_WITH_REFERENCE_CHECK(GetURL, filter); |
| 210 | RUN_TEST_WITH_REFERENCE_CHECK(ValidConnect, filter); |
| 211 | RUN_TEST_WITH_REFERENCE_CHECK(InvalidClose, filter); |
| 212 | RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter); |
| 213 | RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter); |
| 214 | RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter); |
[email protected] | 91d01b5 | 2013-07-26 08:47:48 | [diff] [blame] | 215 | RUN_TEST_BACKGROUND(TestWebSocket, TextSendReceiveTwice, filter); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 216 | RUN_TEST_WITH_REFERENCE_CHECK(BinarySendReceive, filter); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 217 | RUN_TEST_WITH_REFERENCE_CHECK(StressedSendReceive, filter); |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 218 | RUN_TEST_WITH_REFERENCE_CHECK(BufferedAmount, filter); |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 219 | // PP_Resource for WebSocket may be released later because of an internal |
| 220 | // reference for asynchronous IPC handling. So, suppress reference check on |
| 221 | // the following AbortCallsWithCallback test. |
| 222 | RUN_TEST(AbortCallsWithCallback, filter); |
| 223 | RUN_TEST_WITH_REFERENCE_CHECK(AbortSendMessageCall, filter); |
| 224 | RUN_TEST_WITH_REFERENCE_CHECK(AbortCloseCall, filter); |
| 225 | RUN_TEST_WITH_REFERENCE_CHECK(AbortReceiveMessageCall, filter); |
yhirano | c411803 | 2014-08-27 16:47:16 | [diff] [blame] | 226 | RUN_TEST_WITH_REFERENCE_CHECK(ClosedFromServerWhileSending, filter); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 227 | |
| 228 | RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 229 | |
| 230 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidConnect, filter); |
| 231 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityProtocols, filter); |
| 232 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetURL, filter); |
| 233 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidConnect, filter); |
| 234 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidClose, filter); |
| 235 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidClose, filter); |
| 236 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetProtocol, filter); |
| 237 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityTextSendReceive, filter); |
| 238 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityBinarySendReceive, filter); |
| 239 | RUN_TEST_WITH_REFERENCE_CHECK(UtilityBufferedAmount, filter); |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 240 | } |
| 241 | |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 242 | std::string TestWebSocket::GetFullURL(const char* url) { |
[email protected] | 21de9cb2 | 2013-02-14 13:07:34 | [diff] [blame] | 243 | std::string rv = "ws://"; |
| 244 | // Some WebSocket tests don't start the server so there'll be no host and |
| 245 | // port. |
| 246 | if (instance_->websocket_host().empty()) |
| 247 | rv += "127.0.0.1"; |
| 248 | else |
| 249 | rv += instance_->websocket_host(); |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 250 | if (instance_->websocket_port() != -1) { |
| 251 | char buffer[10]; |
| 252 | sprintf(buffer, ":%d", instance_->websocket_port()); |
| 253 | rv += std::string(buffer); |
| 254 | } |
| 255 | rv += "/"; |
| 256 | rv += url; |
| 257 | return rv; |
| 258 | } |
| 259 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 260 | PP_Var TestWebSocket::CreateVarString(const std::string& string) { |
brettw | 669d47b1 | 2015-02-13 21:17:38 | [diff] [blame] | 261 | return var_interface_->VarFromUtf8(string.c_str(), |
| 262 | static_cast<uint32_t>(string.size())); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 263 | } |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 264 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 265 | PP_Var TestWebSocket::CreateVarBinary(const std::vector<uint8_t>& binary) { |
brettw | 669d47b1 | 2015-02-13 21:17:38 | [diff] [blame] | 266 | PP_Var var = |
| 267 | arraybuffer_interface_->Create(static_cast<uint32_t>(binary.size())); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 268 | uint8_t* var_data = static_cast<uint8_t*>(arraybuffer_interface_->Map(var)); |
| 269 | std::copy(binary.begin(), binary.end(), var_data); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 270 | return var; |
| 271 | } |
| 272 | |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 273 | void TestWebSocket::ReleaseVar(const PP_Var& var) { |
| 274 | var_interface_->Release(var); |
| 275 | } |
| 276 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 277 | bool TestWebSocket::AreEqualWithString(const PP_Var& var, |
| 278 | const std::string& string) { |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 279 | if (var.type != PP_VARTYPE_STRING) |
| 280 | return false; |
| 281 | uint32_t utf8_length; |
| 282 | const char* utf8 = var_interface_->VarToUtf8(var, &utf8_length); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 283 | if (utf8_length != string.size()) |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 284 | return false; |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 285 | if (string.compare(utf8)) |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 286 | return false; |
| 287 | return true; |
| 288 | } |
| 289 | |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 290 | bool TestWebSocket::AreEqualWithBinary(const PP_Var& var, |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 291 | const std::vector<uint8_t>& binary) { |
[email protected] | 47ef614 | 2012-01-26 21:04:10 | [diff] [blame] | 292 | uint32_t buffer_size = 0; |
| 293 | PP_Bool success = arraybuffer_interface_->ByteLength(var, &buffer_size); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 294 | if (!success || buffer_size != binary.size()) |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 295 | return false; |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 296 | if (!std::equal(binary.begin(), binary.end(), |
| 297 | static_cast<uint8_t*>(arraybuffer_interface_->Map(var)))) |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 298 | return false; |
| 299 | return true; |
| 300 | } |
| 301 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 302 | PP_Resource TestWebSocket::Connect(const std::string& url, |
| 303 | int32_t* result, |
| 304 | const std::string& protocol) { |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 305 | PP_Var protocols[] = { PP_MakeUndefined() }; |
| 306 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
| 307 | if (!ws) |
| 308 | return 0; |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 309 | PP_Var url_var = CreateVarString(url); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 310 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 311 | uint32_t protocol_count = 0U; |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 312 | if (protocol.size()) { |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 313 | protocols[0] = CreateVarString(protocol); |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 314 | protocol_count = 1U; |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 315 | } |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 316 | callback.WaitForResult(websocket_interface_->Connect( |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 317 | ws, url_var, protocols, protocol_count, |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 318 | callback.GetCallback().pp_completion_callback())); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 319 | ReleaseVar(url_var); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 320 | if (protocol.size()) |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 321 | ReleaseVar(protocols[0]); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 322 | *result = callback.result(); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 323 | return ws; |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 324 | } |
| 325 | |
[email protected] | 91d01b5 | 2013-07-26 08:47:48 | [diff] [blame] | 326 | void TestWebSocket::Send(int32_t /* result */, PP_Resource ws, |
| 327 | const std::string& message) { |
| 328 | PP_Var message_var = CreateVarString(message); |
| 329 | websocket_interface_->SendMessage(ws, message_var); |
| 330 | ReleaseVar(message_var); |
| 331 | } |
| 332 | |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 333 | std::string TestWebSocket::TestIsWebSocket() { |
| 334 | // Test that a NULL resource isn't a websocket. |
| 335 | pp::Resource null_resource; |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 336 | PP_Bool result = |
| 337 | websocket_interface_->IsWebSocket(null_resource.pp_resource()); |
| 338 | ASSERT_FALSE(result); |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 339 | |
| 340 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 341 | ASSERT_TRUE(ws); |
| 342 | |
| 343 | result = websocket_interface_->IsWebSocket(ws); |
| 344 | ASSERT_TRUE(result); |
| 345 | |
| 346 | core_interface_->ReleaseResource(ws); |
[email protected] | 081d147b | 2011-11-18 05:51:54 | [diff] [blame] | 347 | |
| 348 | PASS(); |
| 349 | } |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 350 | |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 351 | std::string TestWebSocket::TestUninitializedPropertiesAccess() { |
| 352 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
| 353 | ASSERT_TRUE(ws); |
| 354 | |
| 355 | uint64_t bufferedAmount = websocket_interface_->GetBufferedAmount(ws); |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 356 | ASSERT_EQ(0U, bufferedAmount); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 357 | |
| 358 | uint16_t close_code = websocket_interface_->GetCloseCode(ws); |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 359 | ASSERT_EQ(0U, close_code); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 360 | |
| 361 | PP_Var close_reason = websocket_interface_->GetCloseReason(ws); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 362 | ASSERT_TRUE(AreEqualWithString(close_reason, std::string())); |
[email protected] | 2117f25 | 2011-12-15 06:43:11 | [diff] [blame] | 363 | ReleaseVar(close_reason); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 364 | |
| 365 | PP_Bool close_was_clean = websocket_interface_->GetCloseWasClean(ws); |
| 366 | ASSERT_EQ(PP_FALSE, close_was_clean); |
| 367 | |
| 368 | PP_Var extensions = websocket_interface_->GetExtensions(ws); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 369 | ASSERT_TRUE(AreEqualWithString(extensions, std::string())); |
[email protected] | 2117f25 | 2011-12-15 06:43:11 | [diff] [blame] | 370 | ReleaseVar(extensions); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 371 | |
| 372 | PP_Var protocol = websocket_interface_->GetProtocol(ws); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 373 | ASSERT_TRUE(AreEqualWithString(protocol, std::string())); |
[email protected] | 2117f25 | 2011-12-15 06:43:11 | [diff] [blame] | 374 | ReleaseVar(protocol); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 375 | |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 376 | PP_WebSocketReadyState ready_state = |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 377 | websocket_interface_->GetReadyState(ws); |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 378 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ready_state); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 379 | |
| 380 | PP_Var url = websocket_interface_->GetURL(ws); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 381 | ASSERT_TRUE(AreEqualWithString(url, std::string())); |
[email protected] | 2117f25 | 2011-12-15 06:43:11 | [diff] [blame] | 382 | ReleaseVar(url); |
| 383 | |
| 384 | core_interface_->ReleaseResource(ws); |
[email protected] | a1cff78 | 2011-12-06 18:06:34 | [diff] [blame] | 385 | |
| 386 | PASS(); |
| 387 | } |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 388 | |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 389 | std::string TestWebSocket::TestInvalidConnect() { |
| 390 | PP_Var protocols[] = { PP_MakeUndefined() }; |
| 391 | |
| 392 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
| 393 | ASSERT_TRUE(ws); |
| 394 | |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 395 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 396 | callback.WaitForResult(websocket_interface_->Connect( |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 397 | ws, PP_MakeUndefined(), protocols, 1U, |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 398 | callback.GetCallback().pp_completion_callback())); |
| 399 | ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 400 | |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 401 | callback.WaitForResult(websocket_interface_->Connect( |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 402 | ws, PP_MakeUndefined(), protocols, 1U, |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 403 | callback.GetCallback().pp_completion_callback())); |
| 404 | ASSERT_EQ(PP_ERROR_INPROGRESS, callback.result()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 405 | |
| 406 | core_interface_->ReleaseResource(ws); |
| 407 | |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 408 | for (int i = 0; kInvalidURLs[i]; ++i) { |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 409 | int32_t result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 410 | ws = Connect(kInvalidURLs[i], &result, std::string()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 411 | ASSERT_TRUE(ws); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 412 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 413 | |
| 414 | core_interface_->ReleaseResource(ws); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 415 | } |
| 416 | |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 417 | PASS(); |
| 418 | } |
| 419 | |
| 420 | std::string TestWebSocket::TestProtocols() { |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 421 | PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str()); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 422 | PP_Var bad_protocols[] = { |
| 423 | CreateVarString("x-test"), |
| 424 | CreateVarString("x-test") |
| 425 | }; |
| 426 | PP_Var good_protocols[] = { |
| 427 | CreateVarString("x-test"), |
| 428 | CreateVarString("x-yatest") |
| 429 | }; |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 430 | |
| 431 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
| 432 | ASSERT_TRUE(ws); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 433 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 434 | callback.WaitForResult(websocket_interface_->Connect( |
[email protected] | 9082aa5b | 2012-01-19 08:44:47 | [diff] [blame] | 435 | ws, url, bad_protocols, 2U, |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 436 | callback.GetCallback().pp_completion_callback())); |
| 437 | ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 438 | core_interface_->ReleaseResource(ws); |
| 439 | |
| 440 | ws = websocket_interface_->Create(instance_->pp_instance()); |
| 441 | ASSERT_TRUE(ws); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 442 | int32_t result = websocket_interface_->Connect( |
[email protected] | 32b05b1 | 2011-12-09 04:26:28 | [diff] [blame] | 443 | ws, url, good_protocols, 2U, PP_BlockUntilComplete()); |
| 444 | ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, result); |
| 445 | core_interface_->ReleaseResource(ws); |
| 446 | |
| 447 | ReleaseVar(url); |
| 448 | for (int i = 0; i < 2; ++i) { |
| 449 | ReleaseVar(bad_protocols[i]); |
| 450 | ReleaseVar(good_protocols[i]); |
| 451 | } |
| 452 | core_interface_->ReleaseResource(ws); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 453 | |
| 454 | PASS(); |
| 455 | } |
| 456 | |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 457 | std::string TestWebSocket::TestGetURL() { |
| 458 | for (int i = 0; kInvalidURLs[i]; ++i) { |
| 459 | int32_t result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 460 | PP_Resource ws = Connect(kInvalidURLs[i], &result, std::string()); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 461 | ASSERT_TRUE(ws); |
| 462 | PP_Var url = websocket_interface_->GetURL(ws); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 463 | ASSERT_TRUE(AreEqualWithString(url, kInvalidURLs[i])); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 464 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 465 | |
| 466 | ReleaseVar(url); |
| 467 | core_interface_->ReleaseResource(ws); |
| 468 | } |
| 469 | |
| 470 | PASS(); |
| 471 | } |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 472 | |
| 473 | std::string TestWebSocket::TestValidConnect() { |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 474 | int32_t result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 475 | PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 476 | ASSERT_TRUE(ws); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 477 | ASSERT_EQ(PP_OK, result); |
[email protected] | 51f660c | 2012-03-10 00:41:57 | [diff] [blame] | 478 | PP_Var extensions = websocket_interface_->GetExtensions(ws); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 479 | ASSERT_TRUE(AreEqualWithString(extensions, std::string())); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 480 | core_interface_->ReleaseResource(ws); |
[email protected] | 8ced4f3f | 2013-02-04 16:53:07 | [diff] [blame] | 481 | ReleaseVar(extensions); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 482 | |
| 483 | PASS(); |
| 484 | } |
| 485 | |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 486 | std::string TestWebSocket::TestInvalidClose() { |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 487 | PP_Var reason = CreateVarString("close for test"); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 488 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 489 | TestCompletionCallback async_callback(instance_->pp_instance(), PP_REQUIRED); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 490 | |
| 491 | // Close before connect. |
| 492 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 493 | callback.WaitForResult(websocket_interface_->Close( |
| 494 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
| 495 | callback.GetCallback().pp_completion_callback())); |
| 496 | ASSERT_EQ(PP_ERROR_FAILED, callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 497 | core_interface_->ReleaseResource(ws); |
| 498 | |
| 499 | // Close with bad arguments. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 500 | int32_t result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 501 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 502 | ASSERT_TRUE(ws); |
| 503 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 504 | callback.WaitForResult(websocket_interface_->Close( |
| 505 | ws, 1U, reason, callback.GetCallback().pp_completion_callback())); |
| 506 | ASSERT_EQ(PP_ERROR_NOACCESS, callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 507 | core_interface_->ReleaseResource(ws); |
| 508 | |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 509 | // Close with PP_VARTYPE_NULL. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 510 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 511 | ASSERT_TRUE(ws); |
| 512 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 513 | callback.WaitForResult(websocket_interface_->Close( |
| 514 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(), |
| 515 | callback.GetCallback().pp_completion_callback())); |
| 516 | ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 517 | core_interface_->ReleaseResource(ws); |
| 518 | |
| 519 | // Close with PP_VARTYPE_NULL and ongoing receive message. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 520 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 521 | ASSERT_TRUE(ws); |
| 522 | ASSERT_EQ(PP_OK, result); |
| 523 | PP_Var receive_message_var; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 524 | result = websocket_interface_->ReceiveMessage( |
| 525 | ws, &receive_message_var, |
| 526 | async_callback.GetCallback().pp_completion_callback()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 527 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 528 | callback.WaitForResult(websocket_interface_->Close( |
| 529 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(), |
| 530 | callback.GetCallback().pp_completion_callback())); |
| 531 | ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 532 | const char* send_message = "hi"; |
| 533 | PP_Var send_message_var = CreateVarString(send_message); |
| 534 | result = websocket_interface_->SendMessage(ws, send_message_var); |
| 535 | ReleaseVar(send_message_var); |
| 536 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 537 | async_callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 538 | ASSERT_EQ(PP_OK, async_callback.result()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 539 | ASSERT_TRUE(AreEqualWithString(receive_message_var, send_message)); |
| 540 | ReleaseVar(receive_message_var); |
| 541 | core_interface_->ReleaseResource(ws); |
| 542 | |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 543 | // Close twice. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 544 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 545 | ASSERT_TRUE(ws); |
| 546 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 547 | result = websocket_interface_->Close( |
| 548 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
| 549 | async_callback.GetCallback().pp_completion_callback()); |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 550 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 551 | // Call another Close() before previous one is in progress. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 552 | result = websocket_interface_->Close( |
| 553 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
| 554 | callback.GetCallback().pp_completion_callback()); |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 555 | ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 556 | async_callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 557 | ASSERT_EQ(PP_OK, async_callback.result()); |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 558 | // Call another Close() after previous one is completed. |
| 559 | // This Close() must do nothing and reports no error. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 560 | callback.WaitForResult(websocket_interface_->Close( |
| 561 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
| 562 | callback.GetCallback().pp_completion_callback())); |
| 563 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 9c8b2fd | 2012-04-25 11:39:07 | [diff] [blame] | 564 | core_interface_->ReleaseResource(ws); |
| 565 | |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 566 | ReleaseVar(reason); |
| 567 | |
| 568 | PASS(); |
| 569 | } |
| 570 | |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 571 | // TODO(tyoshino): Consider splitting this test into smaller ones. |
| 572 | // http://crbug.com/397035 |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 573 | std::string TestWebSocket::TestValidClose() { |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 574 | PP_Var reason = CreateVarString("close for test"); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 575 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 576 | TestCompletionCallback another_callback( |
| 577 | instance_->pp_instance(), callback_type()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 578 | |
| 579 | // Close. |
| 580 | int32_t result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 581 | PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 582 | ASSERT_TRUE(ws); |
| 583 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 584 | callback.WaitForResult(websocket_interface_->Close( |
| 585 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
| 586 | callback.GetCallback().pp_completion_callback())); |
| 587 | CHECK_CALLBACK_BEHAVIOR(callback); |
| 588 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 589 | core_interface_->ReleaseResource(ws); |
| 590 | |
[email protected] | b6b90fe | 2012-05-31 09:25:45 | [diff] [blame] | 591 | // Close without code and reason. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 592 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | b6b90fe | 2012-05-31 09:25:45 | [diff] [blame] | 593 | ASSERT_TRUE(ws); |
| 594 | ASSERT_EQ(PP_OK, result); |
| 595 | callback.WaitForResult(websocket_interface_->Close( |
| 596 | ws, PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED, reason, |
| 597 | callback.GetCallback().pp_completion_callback())); |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 598 | CHECK_CALLBACK_BEHAVIOR(callback); |
[email protected] | b6b90fe | 2012-05-31 09:25:45 | [diff] [blame] | 599 | ASSERT_EQ(PP_OK, callback.result()); |
| 600 | core_interface_->ReleaseResource(ws); |
| 601 | |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 602 | // Close with PP_VARTYPE_UNDEFINED. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 603 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 604 | ASSERT_TRUE(ws); |
| 605 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 606 | callback.WaitForResult(websocket_interface_->Close( |
| 607 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), |
| 608 | callback.GetCallback().pp_completion_callback())); |
| 609 | CHECK_CALLBACK_BEHAVIOR(callback); |
| 610 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 611 | core_interface_->ReleaseResource(ws); |
| 612 | |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 613 | // Close in CONNECTING state. |
| 614 | // The ongoing Connect() fails with PP_ERROR_ABORTED, then the Close() |
| 615 | // completes successfully. |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 616 | ws = websocket_interface_->Create(instance_->pp_instance()); |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 617 | PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str()); |
| 618 | PP_Var protocols[] = { PP_MakeUndefined() }; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 619 | result = websocket_interface_->Connect( |
| 620 | ws, url, protocols, 0U, callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 621 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 622 | result = websocket_interface_->Close( |
| 623 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 624 | another_callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 625 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 626 | callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 627 | ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); |
| 628 | another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 629 | ASSERT_EQ(PP_OK, another_callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 630 | core_interface_->ReleaseResource(ws); |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 631 | ReleaseVar(url); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 632 | |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 633 | // Close while already closing. |
| 634 | // The first Close will succeed, and the second one will synchronously fail |
| 635 | // with PP_ERROR_INPROGRESS. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 636 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 637 | ASSERT_TRUE(ws); |
| 638 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 639 | result = websocket_interface_->Close( |
| 640 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 641 | callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 642 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 643 | result = websocket_interface_->Close( |
| 644 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 645 | another_callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 646 | ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 647 | callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 648 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 649 | core_interface_->ReleaseResource(ws); |
| 650 | |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 651 | // Close with ongoing ReceiveMessage. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 652 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 653 | ASSERT_TRUE(ws); |
| 654 | ASSERT_EQ(PP_OK, result); |
| 655 | PP_Var receive_message_var; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 656 | result = websocket_interface_->ReceiveMessage( |
| 657 | ws, &receive_message_var, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 658 | callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 659 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 660 | result = websocket_interface_->Close( |
| 661 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 662 | another_callback.GetCallback().pp_completion_callback()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 663 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 664 | callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 665 | ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); |
| 666 | another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 667 | ASSERT_EQ(PP_OK, another_callback.result()); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 668 | core_interface_->ReleaseResource(ws); |
| 669 | |
[email protected] | 8b1aa2d | 2014-07-29 09:35:59 | [diff] [blame] | 670 | // Close with PP_VARTYPE_UNDEFINED for reason and ongoing ReceiveMessage. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 671 | ws = Connect(GetFullURL(kEchoServerURL), &result, std::string()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 672 | ASSERT_TRUE(ws); |
| 673 | ASSERT_EQ(PP_OK, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 674 | result = websocket_interface_->ReceiveMessage( |
| 675 | ws, &receive_message_var, |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 676 | callback.GetCallback().pp_completion_callback()); |
| 677 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 678 | result = websocket_interface_->Close( |
| 679 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 680 | another_callback.GetCallback().pp_completion_callback()); |
| 681 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 682 | callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 683 | ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); |
| 684 | another_callback.WaitForResult(PP_OK_COMPLETIONPENDING); |
| 685 | ASSERT_EQ(PP_OK, another_callback.result()); |
[email protected] | 2c32b260 | 2012-04-24 08:06:49 | [diff] [blame] | 686 | core_interface_->ReleaseResource(ws); |
| 687 | |
[email protected] | 9885a10 | 2012-05-14 05:52:12 | [diff] [blame] | 688 | // Server initiated closing handshake. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 689 | ws = Connect( |
| 690 | GetFullURL(kCloseWithCodeAndReasonServerURL), &result, std::string()); |
[email protected] | 9885a10 | 2012-05-14 05:52:12 | [diff] [blame] | 691 | ASSERT_TRUE(ws); |
| 692 | ASSERT_EQ(PP_OK, result); |
| 693 | // Text messsage "1000 bye" requests the server to initiate closing handshake |
| 694 | // with code being 1000 and reason being "bye". |
| 695 | PP_Var close_request_var = CreateVarString("1000 bye"); |
| 696 | result = websocket_interface_->SendMessage(ws, close_request_var); |
| 697 | ReleaseVar(close_request_var); |
| 698 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 699 | ws, &receive_message_var, |
| 700 | callback.GetCallback().pp_completion_callback())); |
| 701 | ASSERT_EQ(PP_ERROR_FAILED, callback.result()); |
| 702 | core_interface_->ReleaseResource(ws); |
| 703 | |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 704 | ReleaseVar(reason); |
[email protected] | 5cf0fb1 | 2011-12-06 18:33:11 | [diff] [blame] | 705 | |
| 706 | PASS(); |
| 707 | } |
| 708 | |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 709 | std::string TestWebSocket::TestGetProtocol() { |
| 710 | const char* expected_protocols[] = { |
| 711 | "x-chat", |
| 712 | "hoehoe", |
| 713 | NULL |
| 714 | }; |
| 715 | for (int i = 0; expected_protocols[i]; ++i) { |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 716 | std::string url(GetFullURL(kProtocolTestServerURL)); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 717 | url += expected_protocols[i]; |
| 718 | int32_t result; |
| 719 | PP_Resource ws = Connect(url.c_str(), &result, expected_protocols[i]); |
| 720 | ASSERT_TRUE(ws); |
| 721 | ASSERT_EQ(PP_OK, result); |
| 722 | |
| 723 | PP_Var protocol = websocket_interface_->GetProtocol(ws); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 724 | ASSERT_TRUE(AreEqualWithString(protocol, expected_protocols[i])); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 725 | |
| 726 | ReleaseVar(protocol); |
| 727 | core_interface_->ReleaseResource(ws); |
| 728 | } |
| 729 | |
| 730 | PASS(); |
| 731 | } |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 732 | |
| 733 | std::string TestWebSocket::TestTextSendReceive() { |
| 734 | // Connect to test echo server. |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 735 | int32_t connect_result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 736 | PP_Resource ws = |
| 737 | Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 738 | ASSERT_TRUE(ws); |
[email protected] | 65f6b00 | 2011-12-01 07:44:11 | [diff] [blame] | 739 | ASSERT_EQ(PP_OK, connect_result); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 740 | |
| 741 | // Send 'hello pepper' text message. |
| 742 | const char* message = "hello pepper"; |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 743 | PP_Var message_var = CreateVarString(message); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 744 | int32_t result = websocket_interface_->SendMessage(ws, message_var); |
| 745 | ReleaseVar(message_var); |
| 746 | ASSERT_EQ(PP_OK, result); |
| 747 | |
| 748 | // Receive echoed 'hello pepper'. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 749 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 750 | PP_Var received_message; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 751 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 752 | ws, &received_message, callback.GetCallback().pp_completion_callback())); |
| 753 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 754 | ASSERT_TRUE(AreEqualWithString(received_message, message)); |
| 755 | ReleaseVar(received_message); |
| 756 | core_interface_->ReleaseResource(ws); |
| 757 | |
| 758 | PASS(); |
| 759 | } |
| 760 | |
[email protected] | 91d01b5 | 2013-07-26 08:47:48 | [diff] [blame] | 761 | // Run as a BACKGROUND test. |
| 762 | std::string TestWebSocket::TestTextSendReceiveTwice() { |
| 763 | // Connect to test echo server. |
| 764 | int32_t connect_result; |
| 765 | PP_Resource ws = |
| 766 | Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); |
| 767 | ASSERT_TRUE(ws); |
| 768 | ASSERT_EQ(PP_OK, connect_result); |
| 769 | pp::MessageLoop message_loop = pp::MessageLoop::GetCurrent(); |
| 770 | pp::CompletionCallbackFactory<TestWebSocket> factory(this); |
| 771 | |
| 772 | message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send, |
| 773 | ws, std::string("hello"))); |
| 774 | // When the server receives 'Goodbye', it closes the session. |
| 775 | message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send, |
| 776 | ws, std::string("Goodbye"))); |
| 777 | message_loop.PostQuit(false); |
| 778 | message_loop.Run(); |
| 779 | |
| 780 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 781 | PP_Var received_message; |
| 782 | int32_t result = websocket_interface_->ReceiveMessage( |
| 783 | ws, &received_message, callback.GetCallback().pp_completion_callback()); |
| 784 | ASSERT_EQ(PP_OK, result); |
| 785 | // Since we don't run the message loop, the callback will stay |
| 786 | // "pending and scheduled to run" state. |
| 787 | |
| 788 | // Waiting for the connection close which will be done by the server. |
| 789 | while (true) { |
| 790 | PP_WebSocketReadyState ready_state = |
| 791 | websocket_interface_->GetReadyState(ws); |
| 792 | if (ready_state != PP_WEBSOCKETREADYSTATE_CONNECTING && |
| 793 | ready_state != PP_WEBSOCKETREADYSTATE_OPEN) { |
| 794 | break; |
| 795 | } |
| 796 | PlatformSleep(100); // 100ms |
| 797 | } |
| 798 | |
| 799 | // Cleanup the message loop |
| 800 | message_loop.PostQuit(false); |
| 801 | message_loop.Run(); |
| 802 | |
| 803 | ASSERT_EQ(PP_OK, callback.result()); |
| 804 | ASSERT_TRUE(AreEqualWithString(received_message, "hello")); |
| 805 | ReleaseVar(received_message); |
| 806 | core_interface_->ReleaseResource(ws); |
| 807 | PASS(); |
| 808 | } |
| 809 | |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 810 | std::string TestWebSocket::TestBinarySendReceive() { |
| 811 | // Connect to test echo server. |
| 812 | int32_t connect_result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 813 | PP_Resource ws = |
| 814 | Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 815 | ASSERT_TRUE(ws); |
| 816 | ASSERT_EQ(PP_OK, connect_result); |
| 817 | |
| 818 | // Send binary message. |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 819 | std::vector<uint8_t> binary(256); |
| 820 | for (uint32_t i = 0; i < binary.size(); ++i) |
| 821 | binary[i] = i; |
| 822 | PP_Var message_var = CreateVarBinary(binary); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 823 | int32_t result = websocket_interface_->SendMessage(ws, message_var); |
| 824 | ReleaseVar(message_var); |
| 825 | ASSERT_EQ(PP_OK, result); |
| 826 | |
| 827 | // Receive echoed binary. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 828 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 829 | PP_Var received_message; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 830 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 831 | ws, &received_message, callback.GetCallback().pp_completion_callback())); |
| 832 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 833 | ASSERT_TRUE(AreEqualWithBinary(received_message, binary)); |
[email protected] | 31c1a7e | 2011-11-26 03:45:30 | [diff] [blame] | 834 | ReleaseVar(received_message); |
| 835 | core_interface_->ReleaseResource(ws); |
| 836 | |
| 837 | PASS(); |
| 838 | } |
| 839 | |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 840 | std::string TestWebSocket::TestStressedSendReceive() { |
| 841 | // Connect to test echo server. |
| 842 | int32_t connect_result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 843 | PP_Resource ws = |
| 844 | Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 845 | ASSERT_TRUE(ws); |
| 846 | ASSERT_EQ(PP_OK, connect_result); |
| 847 | |
| 848 | // Prepare PP_Var objects to send. |
| 849 | const char* text = "hello pepper"; |
| 850 | PP_Var text_var = CreateVarString(text); |
| 851 | std::vector<uint8_t> binary(256); |
| 852 | for (uint32_t i = 0; i < binary.size(); ++i) |
| 853 | binary[i] = i; |
| 854 | PP_Var binary_var = CreateVarBinary(binary); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 855 | // Prepare very large binary data over 64KiB. Object serializer in |
| 856 | // ppapi_proxy has a limitation of 64KiB as maximum return PP_Var data size |
| 857 | // to SRPC. In case received data over 64KiB exists, a specific code handles |
| 858 | // this large data via asynchronous callback from main thread. This data |
| 859 | // intends to test the code. |
| 860 | std::vector<uint8_t> large_binary(65 * 1024); |
| 861 | for (uint32_t i = 0; i < large_binary.size(); ++i) |
| 862 | large_binary[i] = i & 0xff; |
| 863 | PP_Var large_binary_var = CreateVarBinary(large_binary); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 864 | |
| 865 | // Send many messages. |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 866 | int32_t result; |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 867 | for (int i = 0; i < 256; ++i) { |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 868 | result = websocket_interface_->SendMessage(ws, text_var); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 869 | ASSERT_EQ(PP_OK, result); |
| 870 | result = websocket_interface_->SendMessage(ws, binary_var); |
| 871 | ASSERT_EQ(PP_OK, result); |
| 872 | } |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 873 | result = websocket_interface_->SendMessage(ws, large_binary_var); |
| 874 | ASSERT_EQ(PP_OK, result); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 875 | ReleaseVar(text_var); |
| 876 | ReleaseVar(binary_var); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 877 | ReleaseVar(large_binary_var); |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 878 | |
| 879 | // Receive echoed data. |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 880 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 881 | for (int i = 0; i <= 512; ++i) { |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 882 | PP_Var received_message; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 883 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 884 | ws, &received_message, |
| 885 | callback.GetCallback().pp_completion_callback())); |
| 886 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 887 | if (i == 512) { |
| 888 | ASSERT_TRUE(AreEqualWithBinary(received_message, large_binary)); |
| 889 | } else if (i & 1) { |
[email protected] | 3f915fae | 2012-03-26 11:13:29 | [diff] [blame] | 890 | ASSERT_TRUE(AreEqualWithBinary(received_message, binary)); |
| 891 | } else { |
| 892 | ASSERT_TRUE(AreEqualWithString(received_message, text)); |
| 893 | } |
| 894 | ReleaseVar(received_message); |
| 895 | } |
| 896 | core_interface_->ReleaseResource(ws); |
| 897 | |
| 898 | PASS(); |
| 899 | } |
| 900 | |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 901 | std::string TestWebSocket::TestBufferedAmount() { |
| 902 | // Connect to test echo server. |
| 903 | int32_t connect_result; |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 904 | PP_Resource ws = |
| 905 | Connect(GetFullURL(kEchoServerURL), &connect_result, std::string()); |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 906 | ASSERT_TRUE(ws); |
| 907 | ASSERT_EQ(PP_OK, connect_result); |
[email protected] | 25a9f65 | 2011-12-01 06:55:37 | [diff] [blame] | 908 | |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 909 | // Prepare a large message that is not aligned with the internal buffer |
| 910 | // sizes. |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 911 | std::string message(8193, 'x'); |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 912 | PP_Var message_var = CreateVarString(message); |
[email protected] | a9718acb | 2011-12-02 23:57:31 | [diff] [blame] | 913 | |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 914 | uint64_t buffered_amount = 0; |
| 915 | int32_t result; |
| 916 | for (int i = 0; i < 100; i++) { |
| 917 | result = websocket_interface_->SendMessage(ws, message_var); |
| 918 | ASSERT_EQ(PP_OK, result); |
| 919 | buffered_amount = websocket_interface_->GetBufferedAmount(ws); |
| 920 | // Buffered amount size 262144 is too big for the internal buffer size. |
| 921 | if (buffered_amount > 262144) |
| 922 | break; |
| 923 | } |
| 924 | |
| 925 | // Close connection. |
| 926 | std::string reason_str = "close while busy"; |
| 927 | PP_Var reason = CreateVarString(reason_str.c_str()); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 928 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
| 929 | result = websocket_interface_->Close( |
| 930 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason, |
[email protected] | 3ab6127 | 2012-04-07 00:09:08 | [diff] [blame] | 931 | callback.GetCallback().pp_completion_callback()); |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 932 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 933 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 934 | websocket_interface_->GetReadyState(ws)); |
| 935 | |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 936 | callback.WaitForResult(result); |
| 937 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 938 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 939 | websocket_interface_->GetReadyState(ws)); |
| 940 | |
| 941 | uint64_t base_buffered_amount = websocket_interface_->GetBufferedAmount(ws); |
| 942 | |
| 943 | // After connection closure, all sending requests fail and just increase |
| 944 | // the bufferedAmount property. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 945 | PP_Var empty_string = CreateVarString(std::string()); |
[email protected] | bff494d | 2012-01-12 10:53:58 | [diff] [blame] | 946 | result = websocket_interface_->SendMessage(ws, empty_string); |
| 947 | ASSERT_EQ(PP_ERROR_FAILED, result); |
| 948 | buffered_amount = websocket_interface_->GetBufferedAmount(ws); |
| 949 | ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount); |
| 950 | base_buffered_amount = buffered_amount; |
| 951 | |
| 952 | result = websocket_interface_->SendMessage(ws, reason); |
| 953 | ASSERT_EQ(PP_ERROR_FAILED, result); |
| 954 | buffered_amount = websocket_interface_->GetBufferedAmount(ws); |
| 955 | uint64_t reason_frame_size = kMessageFrameOverhead + reason_str.length(); |
| 956 | ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount); |
| 957 | |
| 958 | ReleaseVar(message_var); |
| 959 | ReleaseVar(reason); |
| 960 | ReleaseVar(empty_string); |
| 961 | core_interface_->ReleaseResource(ws); |
| 962 | |
| 963 | PASS(); |
| 964 | } |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 965 | |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 966 | // Test abort behaviors where a WebSocket PP_Resource is released while each |
| 967 | // function is in-flight on the WebSocket PP_Resource. |
| 968 | std::string TestWebSocket::TestAbortCallsWithCallback() { |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 969 | // Following tests make sure the behavior for functions which require a |
| 970 | // callback. The callback must get a PP_ERROR_ABORTED. |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 971 | |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 972 | // Test the behavior for Connect(). |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 973 | PP_Resource ws = websocket_interface_->Create(instance_->pp_instance()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 974 | ASSERT_TRUE(ws); |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 975 | std::string url = GetFullURL(kEchoServerURL); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 976 | PP_Var url_var = CreateVarString(url); |
| 977 | TestCompletionCallback connect_callback( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 978 | instance_->pp_instance(), callback_type()); |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 979 | int32_t result = websocket_interface_->Connect( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 980 | ws, url_var, NULL, 0, |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 981 | connect_callback.GetCallback().pp_completion_callback()); |
| 982 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 983 | core_interface_->ReleaseResource(ws); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 984 | connect_callback.WaitForResult(result); |
| 985 | ASSERT_EQ(PP_ERROR_ABORTED, connect_callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 986 | |
| 987 | // Test the behavior for Close(). |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 988 | ws = Connect(url, &result, std::string()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 989 | ASSERT_TRUE(ws); |
| 990 | ASSERT_EQ(PP_OK, result); |
| 991 | PP_Var reason_var = CreateVarString("abort"); |
| 992 | TestCompletionCallback close_callback( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 993 | instance_->pp_instance(), callback_type()); |
| 994 | result = websocket_interface_->Close( |
| 995 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason_var, |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 996 | close_callback.GetCallback().pp_completion_callback()); |
| 997 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 998 | core_interface_->ReleaseResource(ws); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 999 | close_callback.WaitForResult(result); |
| 1000 | ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1001 | ReleaseVar(reason_var); |
| 1002 | |
| 1003 | // Test the behavior for ReceiveMessage(). |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1004 | // Make sure the simplest case to wait for data which never arrives, here. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1005 | ws = Connect(url, &result, std::string()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1006 | ASSERT_TRUE(ws); |
| 1007 | ASSERT_EQ(PP_OK, result); |
| 1008 | PP_Var receive_var; |
| 1009 | TestCompletionCallback receive_callback( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1010 | instance_->pp_instance(), callback_type()); |
| 1011 | result = websocket_interface_->ReceiveMessage( |
| 1012 | ws, &receive_var, |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1013 | receive_callback.GetCallback().pp_completion_callback()); |
| 1014 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1015 | core_interface_->ReleaseResource(ws); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1016 | receive_callback.WaitForResult(result); |
| 1017 | ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1018 | |
[email protected] | cc2386c4 | 2012-06-29 04:41:42 | [diff] [blame] | 1019 | // Release the resource in the aborting receive completion callback which is |
| 1020 | // introduced by calling Close(). |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1021 | ws = Connect(url, &result, std::string()); |
[email protected] | cc2386c4 | 2012-06-29 04:41:42 | [diff] [blame] | 1022 | ASSERT_TRUE(ws); |
| 1023 | ASSERT_EQ(PP_OK, result); |
| 1024 | result = websocket_interface_->ReceiveMessage( |
| 1025 | ws, &receive_var, |
| 1026 | receive_callback.GetCallback().pp_completion_callback()); |
| 1027 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1028 | ReleaseResourceDelegate receive_delegate(core_interface_, ws); |
| 1029 | receive_callback.SetDelegate(&receive_delegate); |
| 1030 | result = websocket_interface_->Close( |
| 1031 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), |
| 1032 | close_callback.GetCallback().pp_completion_callback()); |
| 1033 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1034 | receive_callback.WaitForResult(result); |
| 1035 | CHECK_CALLBACK_BEHAVIOR(receive_callback); |
| 1036 | ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result()); |
| 1037 | close_callback.WaitForResult(result); |
| 1038 | CHECK_CALLBACK_BEHAVIOR(close_callback); |
| 1039 | ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result()); |
| 1040 | |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1041 | ReleaseVar(url_var); |
| 1042 | |
| 1043 | PASS(); |
| 1044 | } |
| 1045 | |
| 1046 | std::string TestWebSocket::TestAbortSendMessageCall() { |
| 1047 | // Test the behavior for SendMessage(). |
| 1048 | // This function doesn't require a callback, but operation will be done |
| 1049 | // asynchronously in WebKit and browser process. |
| 1050 | std::vector<uint8_t> large_binary(65 * 1024); |
| 1051 | PP_Var large_var = CreateVarBinary(large_binary); |
| 1052 | |
| 1053 | int32_t result; |
| 1054 | std::string url = GetFullURL(kEchoServerURL); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1055 | PP_Resource ws = Connect(url, &result, std::string()); |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1056 | ASSERT_TRUE(ws); |
| 1057 | ASSERT_EQ(PP_OK, result); |
| 1058 | result = websocket_interface_->SendMessage(ws, large_var); |
| 1059 | ASSERT_EQ(PP_OK, result); |
| 1060 | core_interface_->ReleaseResource(ws); |
| 1061 | ReleaseVar(large_var); |
| 1062 | |
| 1063 | PASS(); |
| 1064 | } |
| 1065 | |
| 1066 | std::string TestWebSocket::TestAbortCloseCall() { |
| 1067 | // Release the resource in the close completion callback. |
| 1068 | int32_t result; |
| 1069 | std::string url = GetFullURL(kEchoServerURL); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1070 | PP_Resource ws = Connect(url, &result, std::string()); |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1071 | ASSERT_TRUE(ws); |
| 1072 | ASSERT_EQ(PP_OK, result); |
| 1073 | TestCompletionCallback close_callback( |
| 1074 | instance_->pp_instance(), callback_type()); |
| 1075 | result = websocket_interface_->Close( |
| 1076 | ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(), |
| 1077 | close_callback.GetCallback().pp_completion_callback()); |
| 1078 | ReleaseResourceDelegate close_delegate(core_interface_, ws); |
| 1079 | close_callback.SetDelegate(&close_delegate); |
| 1080 | close_callback.WaitForResult(result); |
| 1081 | CHECK_CALLBACK_BEHAVIOR(close_callback); |
| 1082 | ASSERT_EQ(PP_OK, close_callback.result()); |
| 1083 | |
| 1084 | PASS(); |
| 1085 | } |
| 1086 | |
| 1087 | std::string TestWebSocket::TestAbortReceiveMessageCall() { |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1088 | // Test the behavior where receive process might be in-flight. |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1089 | std::vector<uint8_t> large_binary(65 * 1024); |
| 1090 | PP_Var large_var = CreateVarBinary(large_binary); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1091 | const char* text = "yukarin"; |
| 1092 | PP_Var text_var = CreateVarString(text); |
| 1093 | |
[email protected] | 2f3cf60 | 2012-10-22 07:59:31 | [diff] [blame] | 1094 | std::string url = GetFullURL(kEchoServerURL); |
| 1095 | int32_t result; |
| 1096 | PP_Resource ws; |
| 1097 | |
[email protected] | 13d22df1 | 2012-10-24 04:26:38 | [diff] [blame] | 1098 | // Each trial sends |trial_count| + 1 messages and receives just |trial| |
| 1099 | // number of message(s) before releasing the WebSocket. The WebSocket is |
| 1100 | // released while the next message is going to be received. |
| 1101 | const int trial_count = 8; |
| 1102 | for (int trial = 1; trial <= trial_count; trial++) { |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1103 | ws = Connect(url, &result, std::string()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1104 | ASSERT_TRUE(ws); |
| 1105 | ASSERT_EQ(PP_OK, result); |
[email protected] | 13d22df1 | 2012-10-24 04:26:38 | [diff] [blame] | 1106 | for (int i = 0; i <= trial_count; ++i) { |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1107 | result = websocket_interface_->SendMessage(ws, text_var); |
| 1108 | ASSERT_EQ(PP_OK, result); |
| 1109 | } |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1110 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1111 | PP_Var var; |
| 1112 | for (int i = 0; i < trial; ++i) { |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1113 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 1114 | ws, &var, callback.GetCallback().pp_completion_callback())); |
| 1115 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1116 | ASSERT_TRUE(AreEqualWithString(var, text)); |
| 1117 | ReleaseVar(var); |
| 1118 | } |
| 1119 | result = websocket_interface_->ReceiveMessage( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1120 | ws, &var, callback.GetCallback().pp_completion_callback()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1121 | core_interface_->ReleaseResource(ws); |
| 1122 | if (result != PP_OK) { |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1123 | callback.WaitForResult(result); |
| 1124 | ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1125 | } |
| 1126 | } |
| 1127 | // Same test, but the last receiving message is large message over 64KiB. |
[email protected] | 13d22df1 | 2012-10-24 04:26:38 | [diff] [blame] | 1128 | for (int trial = 1; trial <= trial_count; trial++) { |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1129 | ws = Connect(url, &result, std::string()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1130 | ASSERT_TRUE(ws); |
| 1131 | ASSERT_EQ(PP_OK, result); |
[email protected] | 13d22df1 | 2012-10-24 04:26:38 | [diff] [blame] | 1132 | for (int i = 0; i <= trial_count; ++i) { |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1133 | if (i == trial) |
| 1134 | result = websocket_interface_->SendMessage(ws, large_var); |
| 1135 | else |
| 1136 | result = websocket_interface_->SendMessage(ws, text_var); |
| 1137 | ASSERT_EQ(PP_OK, result); |
| 1138 | } |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1139 | TestCompletionCallback callback(instance_->pp_instance(), callback_type()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1140 | PP_Var var; |
| 1141 | for (int i = 0; i < trial; ++i) { |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1142 | callback.WaitForResult(websocket_interface_->ReceiveMessage( |
| 1143 | ws, &var, callback.GetCallback().pp_completion_callback())); |
| 1144 | ASSERT_EQ(PP_OK, callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1145 | ASSERT_TRUE(AreEqualWithString(var, text)); |
| 1146 | ReleaseVar(var); |
| 1147 | } |
| 1148 | result = websocket_interface_->ReceiveMessage( |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1149 | ws, &var, callback.GetCallback().pp_completion_callback()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1150 | core_interface_->ReleaseResource(ws); |
| 1151 | if (result != PP_OK) { |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1152 | callback.WaitForResult(result); |
| 1153 | ASSERT_EQ(PP_ERROR_ABORTED, callback.result()); |
[email protected] | 68eae85 | 2012-04-16 16:48:05 | [diff] [blame] | 1154 | } |
| 1155 | } |
| 1156 | |
| 1157 | ReleaseVar(large_var); |
| 1158 | ReleaseVar(text_var); |
| 1159 | |
| 1160 | PASS(); |
| 1161 | } |
| 1162 | |
yhirano | c411803 | 2014-08-27 16:47:16 | [diff] [blame] | 1163 | std::string TestWebSocket::TestClosedFromServerWhileSending() { |
| 1164 | // Connect to test echo server. |
| 1165 | const pp::Var protocols[] = { pp::Var() }; |
| 1166 | TestWebSocketAPI websocket(instance_); |
| 1167 | int32_t result = |
| 1168 | websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); |
| 1169 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1170 | websocket.WaitForConnected(); |
| 1171 | |
| 1172 | result = websocket.Send(pp::Var("hello")); |
| 1173 | ASSERT_EQ(PP_OK, result); |
| 1174 | result = websocket.Send(pp::Var("Goodbye")); |
| 1175 | // We send many messages so that PepperWebSocketHost::SendText is called |
| 1176 | // after PepperWebSocketHost::didClose is called. |
| 1177 | // Note: We must not wait for CLOSED event here because |
| 1178 | // WebSocketResource::SendMessage doesn't call PepperWebSocketHost::SendText |
| 1179 | // when its internal state is CLOSING or CLOSED. We want to test if the |
| 1180 | // pepper WebSocket works well when WebSocketResource is OPEN and |
| 1181 | // PepperWebSocketHost is CLOSED. |
| 1182 | for (size_t i = 0; i < 10000; ++i) { |
| 1183 | result = websocket.Send(pp::Var("")); |
| 1184 | ASSERT_EQ(PP_OK, result); |
| 1185 | } |
| 1186 | |
| 1187 | PASS(); |
| 1188 | } |
| 1189 | |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1190 | std::string TestWebSocket::TestCcInterfaces() { |
[email protected] | 1364c9c | 2011-12-20 08:57:36 | [diff] [blame] | 1191 | // C++ bindings is simple straightforward, then just verifies interfaces work |
| 1192 | // as a interface bridge fine. |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 1193 | pp::WebSocket ws(instance_); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1194 | |
| 1195 | // Check uninitialized properties access. |
| 1196 | ASSERT_EQ(0, ws.GetBufferedAmount()); |
| 1197 | ASSERT_EQ(0, ws.GetCloseCode()); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1198 | ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), std::string())); |
[email protected] | 6d85286 | 2014-01-24 01:10:23 | [diff] [blame] | 1199 | ASSERT_FALSE(ws.GetCloseWasClean()); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1200 | ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), std::string())); |
| 1201 | ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string())); |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 1202 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ws.GetReadyState()); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1203 | ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), std::string())); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1204 | |
| 1205 | // Check communication interfaces (connect, send, receive, and close). |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1206 | TestCompletionCallback connect_callback( |
| 1207 | instance_->pp_instance(), callback_type()); |
| 1208 | connect_callback.WaitForResult(ws.Connect( |
[email protected] | 599aeffdc | 2013-03-15 11:06:23 | [diff] [blame] | 1209 | pp::Var(GetFullURL(kCloseServerURL)), NULL, 0U, |
| 1210 | connect_callback.GetCallback())); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1211 | CHECK_CALLBACK_BEHAVIOR(connect_callback); |
| 1212 | ASSERT_EQ(PP_OK, connect_callback.result()); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1213 | |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 1214 | std::string text_message("hello C++"); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1215 | int32_t result = ws.SendMessage(pp::Var(text_message)); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1216 | ASSERT_EQ(PP_OK, result); |
| 1217 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1218 | std::vector<uint8_t> binary(256); |
| 1219 | for (uint32_t i = 0; i < binary.size(); ++i) |
| 1220 | binary[i] = i; |
| 1221 | result = ws.SendMessage( |
| 1222 | pp::Var(pp::PASS_REF, CreateVarBinary(binary))); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1223 | ASSERT_EQ(PP_OK, result); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 1224 | |
| 1225 | pp::Var text_receive_var; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1226 | TestCompletionCallback text_receive_callback( |
| 1227 | instance_->pp_instance(), callback_type()); |
| 1228 | text_receive_callback.WaitForResult( |
[email protected] | 599aeffdc | 2013-03-15 11:06:23 | [diff] [blame] | 1229 | ws.ReceiveMessage(&text_receive_var, |
| 1230 | text_receive_callback.GetCallback())); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1231 | ASSERT_EQ(PP_OK, text_receive_callback.result()); |
[email protected] | e18637f | 2011-12-28 05:51:32 | [diff] [blame] | 1232 | ASSERT_TRUE( |
| 1233 | AreEqualWithString(text_receive_var.pp_var(), text_message.c_str())); |
| 1234 | |
| 1235 | pp::Var binary_receive_var; |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1236 | TestCompletionCallback binary_receive_callback( |
| 1237 | instance_->pp_instance(), callback_type()); |
| 1238 | binary_receive_callback.WaitForResult( |
[email protected] | 599aeffdc | 2013-03-15 11:06:23 | [diff] [blame] | 1239 | ws.ReceiveMessage(&binary_receive_var, |
| 1240 | binary_receive_callback.GetCallback())); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1241 | ASSERT_EQ(PP_OK, binary_receive_callback.result()); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1242 | ASSERT_TRUE(AreEqualWithBinary(binary_receive_var.pp_var(), binary)); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1243 | |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1244 | TestCompletionCallback close_callback( |
| 1245 | instance_->pp_instance(), callback_type()); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1246 | std::string reason("bye"); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1247 | close_callback.WaitForResult(ws.Close( |
[email protected] | 599aeffdc | 2013-03-15 11:06:23 | [diff] [blame] | 1248 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason), |
| 1249 | close_callback.GetCallback())); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1250 | CHECK_CALLBACK_BEHAVIOR(close_callback); |
| 1251 | ASSERT_EQ(PP_OK, close_callback.result()); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1252 | |
| 1253 | // Check initialized properties access. |
| 1254 | ASSERT_EQ(0, ws.GetBufferedAmount()); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1255 | ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, ws.GetCloseCode()); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1256 | ASSERT_TRUE( |
| 1257 | AreEqualWithString(ws.GetCloseReason().pp_var(), reason.c_str())); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1258 | ASSERT_EQ(true, ws.GetCloseWasClean()); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1259 | ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string())); |
[email protected] | 5350822 | 2012-01-27 09:42:41 | [diff] [blame] | 1260 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, ws.GetReadyState()); |
[email protected] | 69d2238 | 2012-05-14 09:31:37 | [diff] [blame] | 1261 | ASSERT_TRUE(AreEqualWithString( |
| 1262 | ws.GetURL().pp_var(), GetFullURL(kCloseServerURL).c_str())); |
[email protected] | 3e919cb | 2011-12-16 07:28:21 | [diff] [blame] | 1263 | |
| 1264 | PASS(); |
| 1265 | } |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1266 | |
| 1267 | std::string TestWebSocket::TestUtilityInvalidConnect() { |
| 1268 | const pp::Var protocols[] = { pp::Var() }; |
| 1269 | |
| 1270 | TestWebSocketAPI websocket(instance_); |
| 1271 | int32_t result = websocket.Connect(pp::Var(), protocols, 1U); |
| 1272 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 1273 | ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 1274 | |
| 1275 | result = websocket.Connect(pp::Var(), protocols, 1U); |
| 1276 | ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
| 1277 | ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 1278 | |
| 1279 | for (int i = 0; kInvalidURLs[i]; ++i) { |
| 1280 | TestWebSocketAPI ws(instance_); |
| 1281 | result = ws.Connect(pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); |
[email protected] | 9d5eadf | 2012-10-09 03:43:48 | [diff] [blame] | 1282 | if (result == PP_OK_COMPLETIONPENDING) { |
| 1283 | ws.WaitForClosed(); |
| 1284 | const std::vector<WebSocketEvent>& events = ws.GetSeenEvents(); |
| 1285 | ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); |
| 1286 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 1287 | ASSERT_EQ(2U, ws.GetSeenEvents().size()); |
| 1288 | } else { |
| 1289 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 1290 | ASSERT_EQ(0U, ws.GetSeenEvents().size()); |
| 1291 | } |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1292 | } |
| 1293 | |
| 1294 | PASS(); |
| 1295 | } |
| 1296 | |
| 1297 | std::string TestWebSocket::TestUtilityProtocols() { |
| 1298 | const pp::Var bad_protocols[] = { |
| 1299 | pp::Var(std::string("x-test")), pp::Var(std::string("x-test")) }; |
| 1300 | const pp::Var good_protocols[] = { |
| 1301 | pp::Var(std::string("x-test")), pp::Var(std::string("x-yatest")) }; |
| 1302 | |
| 1303 | { |
| 1304 | TestWebSocketAPI websocket(instance_); |
| 1305 | int32_t result = websocket.Connect( |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1306 | pp::Var(GetFullURL(kEchoServerURL)), bad_protocols, 2U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1307 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 1308 | ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 1309 | } |
| 1310 | |
| 1311 | { |
| 1312 | TestWebSocketAPI websocket(instance_); |
| 1313 | int32_t result = websocket.Connect( |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1314 | pp::Var(GetFullURL(kEchoServerURL)), good_protocols, 2U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1315 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1316 | websocket.WaitForConnected(); |
| 1317 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1318 | // Protocol arguments are valid, but this test run without a WebSocket |
| 1319 | // server. As a result, OnError() and OnClose() are invoked because of |
| 1320 | // a connection establishment failure. |
| 1321 | ASSERT_EQ(2U, events.size()); |
| 1322 | ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); |
| 1323 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 1324 | ASSERT_FALSE(events[1].was_clean); |
| 1325 | } |
| 1326 | |
| 1327 | PASS(); |
| 1328 | } |
| 1329 | |
| 1330 | std::string TestWebSocket::TestUtilityGetURL() { |
| 1331 | const pp::Var protocols[] = { pp::Var() }; |
| 1332 | |
| 1333 | for (int i = 0; kInvalidURLs[i]; ++i) { |
| 1334 | TestWebSocketAPI websocket(instance_); |
| 1335 | int32_t result = websocket.Connect( |
| 1336 | pp::Var(std::string(kInvalidURLs[i])), protocols, 0U); |
[email protected] | 9d5eadf | 2012-10-09 03:43:48 | [diff] [blame] | 1337 | if (result == PP_OK_COMPLETIONPENDING) { |
| 1338 | websocket.WaitForClosed(); |
| 1339 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1340 | ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type); |
| 1341 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 1342 | ASSERT_EQ(2U, events.size()); |
| 1343 | } else { |
| 1344 | ASSERT_EQ(PP_ERROR_BADARGUMENT, result); |
| 1345 | ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 1346 | } |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1347 | pp::Var url = websocket.GetURL(); |
| 1348 | ASSERT_TRUE(AreEqualWithString(url.pp_var(), kInvalidURLs[i])); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1349 | } |
| 1350 | |
| 1351 | PASS(); |
| 1352 | } |
| 1353 | |
| 1354 | std::string TestWebSocket::TestUtilityValidConnect() { |
| 1355 | const pp::Var protocols[] = { pp::Var() }; |
| 1356 | TestWebSocketAPI websocket(instance_); |
| 1357 | int32_t result = websocket.Connect( |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1358 | pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1359 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1360 | websocket.WaitForConnected(); |
| 1361 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1362 | ASSERT_EQ(1U, events.size()); |
| 1363 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1364 | ASSERT_TRUE( |
| 1365 | AreEqualWithString(websocket.GetExtensions().pp_var(), std::string())); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1366 | |
| 1367 | PASS(); |
| 1368 | } |
| 1369 | |
| 1370 | std::string TestWebSocket::TestUtilityInvalidClose() { |
| 1371 | const pp::Var reason = pp::Var(std::string("close for test")); |
| 1372 | |
| 1373 | // Close before connect. |
| 1374 | { |
| 1375 | TestWebSocketAPI websocket(instance_); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1376 | int32_t result = websocket.Close( |
| 1377 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1378 | ASSERT_EQ(PP_ERROR_FAILED, result); |
| 1379 | ASSERT_EQ(0U, websocket.GetSeenEvents().size()); |
| 1380 | } |
| 1381 | |
| 1382 | // Close with bad arguments. |
| 1383 | { |
| 1384 | TestWebSocketAPI websocket(instance_); |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1385 | int32_t result = websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1386 | NULL, 0); |
| 1387 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1388 | websocket.WaitForConnected(); |
| 1389 | result = websocket.Close(1U, reason); |
| 1390 | ASSERT_EQ(PP_ERROR_NOACCESS, result); |
| 1391 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1392 | ASSERT_EQ(1U, events.size()); |
| 1393 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1394 | } |
| 1395 | |
| 1396 | PASS(); |
| 1397 | } |
| 1398 | |
| 1399 | std::string TestWebSocket::TestUtilityValidClose() { |
| 1400 | std::string reason("close for test"); |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1401 | pp::Var url = pp::Var(GetFullURL(kCloseServerURL)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1402 | |
| 1403 | // Close. |
| 1404 | { |
| 1405 | TestWebSocketAPI websocket(instance_); |
| 1406 | int32_t result = websocket.Connect(url, NULL, 0U); |
| 1407 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1408 | websocket.WaitForConnected(); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1409 | result = websocket.Close( |
| 1410 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1411 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1412 | websocket.WaitForClosed(); |
| 1413 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1414 | ASSERT_EQ(2U, events.size()); |
| 1415 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1416 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type); |
| 1417 | ASSERT_TRUE(events[1].was_clean); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1418 | ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, events[1].close_code); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1419 | ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), reason.c_str())); |
| 1420 | } |
| 1421 | |
| 1422 | // Close in connecting. |
| 1423 | // The ongoing connect failed with PP_ERROR_ABORTED, then the close is done |
| 1424 | // successfully. |
| 1425 | { |
| 1426 | TestWebSocketAPI websocket(instance_); |
| 1427 | int32_t result = websocket.Connect(url, NULL, 0U); |
| 1428 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1429 | result = websocket.Close( |
| 1430 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1431 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1432 | websocket.WaitForClosed(); |
| 1433 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1434 | ASSERT_TRUE(events.size() == 2 || events.size() == 3); |
| 1435 | int index = 0; |
| 1436 | if (events.size() == 3) |
| 1437 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); |
| 1438 | ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); |
| 1439 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); |
| 1440 | ASSERT_FALSE(events[index].was_clean); |
| 1441 | } |
| 1442 | |
| 1443 | // Close in closing. |
| 1444 | // The first close will be done successfully, then the second one failed with |
| 1445 | // with PP_ERROR_INPROGRESS immediately. |
| 1446 | { |
| 1447 | TestWebSocketAPI websocket(instance_); |
| 1448 | int32_t result = websocket.Connect(url, NULL, 0U); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1449 | result = websocket.Close( |
| 1450 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1451 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1452 | result = websocket.Close( |
| 1453 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1454 | ASSERT_EQ(PP_ERROR_INPROGRESS, result); |
| 1455 | websocket.WaitForClosed(); |
| 1456 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
[email protected] | 7e8ce78 | 2013-04-04 08:31:54 | [diff] [blame] | 1457 | ASSERT_TRUE(events.size() == 2 || events.size() == 3); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1458 | int index = 0; |
| 1459 | if (events.size() == 3) |
| 1460 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type); |
| 1461 | ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type); |
| 1462 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type); |
| 1463 | ASSERT_FALSE(events[index].was_clean); |
| 1464 | } |
| 1465 | |
| 1466 | PASS(); |
| 1467 | } |
| 1468 | |
| 1469 | std::string TestWebSocket::TestUtilityGetProtocol() { |
| 1470 | const std::string protocol("x-chat"); |
| 1471 | const pp::Var protocols[] = { pp::Var(protocol) }; |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1472 | std::string url(GetFullURL(kProtocolTestServerURL)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1473 | url += protocol; |
| 1474 | TestWebSocketAPI websocket(instance_); |
| 1475 | int32_t result = websocket.Connect(pp::Var(url), protocols, 1U); |
| 1476 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1477 | websocket.WaitForReceived(); |
| 1478 | ASSERT_TRUE(AreEqualWithString( |
| 1479 | websocket.GetProtocol().pp_var(), protocol.c_str())); |
| 1480 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1481 | // The server to which this test connect returns the decided protocol as a |
| 1482 | // text frame message. So the WebSocketEvent records EVENT_MESSAGE event |
| 1483 | // after EVENT_OPEN event. |
| 1484 | ASSERT_EQ(2U, events.size()); |
| 1485 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1486 | ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); |
| 1487 | ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), protocol.c_str())); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1488 | |
| 1489 | PASS(); |
| 1490 | } |
| 1491 | |
| 1492 | std::string TestWebSocket::TestUtilityTextSendReceive() { |
| 1493 | const pp::Var protocols[] = { pp::Var() }; |
| 1494 | TestWebSocketAPI websocket(instance_); |
| 1495 | int32_t result = |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1496 | websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1497 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1498 | websocket.WaitForConnected(); |
| 1499 | |
| 1500 | // Send 'hello pepper'. |
| 1501 | std::string message1("hello pepper"); |
| 1502 | result = websocket.Send(pp::Var(std::string(message1))); |
| 1503 | ASSERT_EQ(PP_OK, result); |
| 1504 | |
| 1505 | // Receive echoed 'hello pepper'. |
| 1506 | websocket.WaitForReceived(); |
| 1507 | |
| 1508 | // Send 'goodbye pepper'. |
| 1509 | std::string message2("goodbye pepper"); |
| 1510 | result = websocket.Send(pp::Var(std::string(message2))); |
| 1511 | |
| 1512 | // Receive echoed 'goodbye pepper'. |
| 1513 | websocket.WaitForReceived(); |
| 1514 | |
| 1515 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1516 | ASSERT_EQ(3U, events.size()); |
| 1517 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1518 | ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); |
| 1519 | ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), message1.c_str())); |
| 1520 | ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[2].event_type); |
| 1521 | ASSERT_TRUE(AreEqualWithString(events[2].var.pp_var(), message2.c_str())); |
| 1522 | |
| 1523 | PASS(); |
| 1524 | } |
| 1525 | |
| 1526 | std::string TestWebSocket::TestUtilityBinarySendReceive() { |
| 1527 | const pp::Var protocols[] = { pp::Var() }; |
| 1528 | TestWebSocketAPI websocket(instance_); |
| 1529 | int32_t result = |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1530 | websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1531 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1532 | websocket.WaitForConnected(); |
| 1533 | |
| 1534 | // Send binary message. |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1535 | uint32_t len = 256; |
| 1536 | std::vector<uint8_t> binary(len); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1537 | for (uint32_t i = 0; i < len; ++i) |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1538 | binary[i] = i; |
| 1539 | pp::VarArrayBuffer message(len); |
| 1540 | uint8_t* var_data = static_cast<uint8_t*>(message.Map()); |
| 1541 | std::copy(binary.begin(), binary.end(), var_data); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1542 | result = websocket.Send(message); |
| 1543 | ASSERT_EQ(PP_OK, result); |
| 1544 | |
| 1545 | // Receive echoed binary message. |
| 1546 | websocket.WaitForReceived(); |
| 1547 | |
| 1548 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1549 | ASSERT_EQ(2U, events.size()); |
| 1550 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1551 | ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1552 | ASSERT_TRUE(AreEqualWithBinary(events[1].var.pp_var(), binary)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1553 | |
| 1554 | PASS(); |
| 1555 | } |
| 1556 | |
| 1557 | std::string TestWebSocket::TestUtilityBufferedAmount() { |
| 1558 | // Connect to test echo server. |
| 1559 | const pp::Var protocols[] = { pp::Var() }; |
| 1560 | TestWebSocketAPI websocket(instance_); |
| 1561 | int32_t result = |
[email protected] | bedf874 | 2012-03-16 16:44:11 | [diff] [blame] | 1562 | websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1563 | ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); |
| 1564 | websocket.WaitForConnected(); |
| 1565 | |
| 1566 | // Prepare a large message that is not aligned with the internal buffer |
| 1567 | // sizes. |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1568 | std::string message(8193, 'x'); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1569 | uint64_t buffered_amount = 0; |
| 1570 | uint32_t sent; |
| 1571 | for (sent = 0; sent < 100; sent++) { |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1572 | result = websocket.Send(pp::Var(message)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1573 | ASSERT_EQ(PP_OK, result); |
| 1574 | buffered_amount = websocket.GetBufferedAmount(); |
| 1575 | // Buffered amount size 262144 is too big for the internal buffer size. |
| 1576 | if (buffered_amount > 262144) |
| 1577 | break; |
| 1578 | } |
| 1579 | |
| 1580 | // Close connection. |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1581 | std::string reason = "close while busy"; |
[email protected] | fae1ecd | 2012-03-03 01:10:59 | [diff] [blame] | 1582 | result = websocket.Close( |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1583 | PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1584 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, websocket.GetReadyState()); |
| 1585 | websocket.WaitForClosed(); |
| 1586 | ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, websocket.GetReadyState()); |
| 1587 | |
| 1588 | uint64_t base_buffered_amount = websocket.GetBufferedAmount(); |
| 1589 | size_t events_on_closed = websocket.GetSeenEvents().size(); |
| 1590 | |
| 1591 | // After connection closure, all sending requests fail and just increase |
| 1592 | // the bufferedAmount property. |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 1593 | result = websocket.Send(pp::Var(std::string())); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1594 | ASSERT_EQ(PP_ERROR_FAILED, result); |
| 1595 | buffered_amount = websocket.GetBufferedAmount(); |
| 1596 | ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount); |
| 1597 | base_buffered_amount = buffered_amount; |
| 1598 | |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1599 | result = websocket.Send(pp::Var(reason)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1600 | ASSERT_EQ(PP_ERROR_FAILED, result); |
| 1601 | buffered_amount = websocket.GetBufferedAmount(); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1602 | uint64_t reason_frame_size = kMessageFrameOverhead + reason.length(); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1603 | ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount); |
| 1604 | |
| 1605 | const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents(); |
| 1606 | ASSERT_EQ(events_on_closed, events.size()); |
| 1607 | ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type); |
| 1608 | size_t last_event = events_on_closed - 1; |
| 1609 | for (uint32_t i = 1; i < last_event; ++i) { |
| 1610 | ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[i].event_type); |
[email protected] | fade7dbc | 2012-03-13 22:48:07 | [diff] [blame] | 1611 | ASSERT_TRUE(AreEqualWithString(events[i].var.pp_var(), message)); |
[email protected] | 2785cb9 | 2012-02-29 20:22:09 | [diff] [blame] | 1612 | } |
| 1613 | ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[last_event].event_type); |
| 1614 | ASSERT_TRUE(events[last_event].was_clean); |
| 1615 | |
| 1616 | PASS(); |
| 1617 | } |