blob: a5ac27dba49f35d915e12965bdd03bcc1397a554 [file] [log] [blame]
[email protected]810f8a02012-01-12 07:03:501// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]081d147b2011-11-18 05:51:542// 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
avie029c4132015-12-23 06:45:227#include <stddef.h>
[email protected]bedf8742012-03-16 16:44:118#include <stdio.h>
[email protected]31c1a7e2011-11-26 03:45:309#include <string.h>
[email protected]68eae852012-04-16 16:48:0510
[email protected]fade7dbc2012-03-13 22:48:0711#include <algorithm>
[email protected]68eae852012-04-16 16:48:0512#include <memory>
[email protected]fade7dbc2012-03-13 22:48:0713#include <string>
[email protected]3e919cb2011-12-16 07:28:2114#include <vector>
[email protected]31c1a7e2011-11-26 03:45:3015
[email protected]fade7dbc2012-03-13 22:48:0716#include "ppapi/c/pp_bool.h"
[email protected]31c1a7e2011-11-26 03:45:3017#include "ppapi/c/pp_completion_callback.h"
[email protected]fade7dbc2012-03-13 22:48:0718#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]31c1a7e2011-11-26 03:45:3022#include "ppapi/c/ppb_core.h"
23#include "ppapi/c/ppb_var.h"
[email protected]9c6e0de2012-01-27 04:55:5524#include "ppapi/c/ppb_var_array_buffer.h"
[email protected]53508222012-01-27 09:42:4125#include "ppapi/c/ppb_websocket.h"
[email protected]7310b162013-11-25 22:39:1526#include "ppapi/c/private/ppb_testing_private.h"
[email protected]081d147b2011-11-18 05:51:5427#include "ppapi/cpp/instance.h"
28#include "ppapi/cpp/module.h"
[email protected]2785cb92012-02-29 20:22:0929#include "ppapi/cpp/var_array_buffer.h"
[email protected]53508222012-01-27 09:42:4130#include "ppapi/cpp/websocket.h"
[email protected]31c1a7e2011-11-26 03:45:3031#include "ppapi/tests/test_utils.h"
[email protected]081d147b2011-11-18 05:51:5432#include "ppapi/tests/testing_instance.h"
[email protected]2785cb92012-02-29 20:22:0933#include "ppapi/utility/websocket/websocket_api.h"
[email protected]081d147b2011-11-18 05:51:5434
[email protected]ce7d0cbc2013-05-03 18:57:2235// net::SpawnedTestServer serves WebSocket service for testing.
[email protected]13d22df12012-10-24 04:26:3836// Following URLs are handled by pywebsocket handlers in
[email protected]4b187da2012-11-06 00:05:2937// net/data/websocket/*_wsh.py.
[email protected]033fb2d2012-10-17 08:40:4138const char kEchoServerURL[] = "echo-with-no-extension";
[email protected]033fb2d2012-10-17 08:40:4139const char kCloseServerURL[] = "close";
[email protected]033fb2d2012-10-17 08:40:4140const char kCloseWithCodeAndReasonServerURL[] = "close-code-and-reason";
[email protected]033fb2d2012-10-17 08:40:4141const char kProtocolTestServerURL[] = "protocol-test?protocol=";
[email protected]65f6b002011-12-01 07:44:1142
Matt Menke9710afc2018-07-20 15:23:4243const 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]65f6b002011-12-01 07:44:1147
[email protected]bff494d2012-01-12 10:53:5848// Internal packet sizes.
[email protected]bff494d2012-01-12 10:53:5849const uint64_t kMessageFrameOverhead = 6;
50
[email protected]2785cb92012-02-29 20:22:0951namespace {
52
53struct 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]fade7dbc2012-03-13 22:48:0768 var(var) {
69 }
[email protected]2785cb92012-02-29 20:22:0970 EventType event_type;
71 bool was_clean;
72 uint16_t close_code;
73 pp::Var var;
74};
75
[email protected]cc2386c42012-06-29 04:41:4276class 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]2785cb92012-02-29 20:22:0995class 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]fade7dbc2012-03-13 22:48:07105 instance_(instance->pp_instance()) {
106 }
[email protected]2785cb92012-02-29 20:22:09107
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]081d147b2011-11-18 05:51:54185REGISTER_TEST_CASE(WebSocket);
186
187bool TestWebSocket::Init() {
[email protected]53508222012-01-27 09:42:41188 websocket_interface_ = static_cast<const PPB_WebSocket*>(
189 pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_INTERFACE));
[email protected]31c1a7e2011-11-26 03:45:30190 var_interface_ = static_cast<const PPB_Var*>(
191 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
[email protected]9c6e0de2012-01-27 04:55:55192 arraybuffer_interface_ = static_cast<const PPB_VarArrayBuffer*>(
[email protected]e18637f2011-12-28 05:51:32193 pp::Module::Get()->GetBrowserInterface(
[email protected]9c6e0de2012-01-27 04:55:55194 PPB_VAR_ARRAY_BUFFER_INTERFACE));
[email protected]31c1a7e2011-11-26 03:45:30195 core_interface_ = static_cast<const PPB_Core*>(
196 pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
[email protected]e18637f2011-12-28 05:51:32197 if (!websocket_interface_ || !var_interface_ || !arraybuffer_interface_ ||
198 !core_interface_)
[email protected]31c1a7e2011-11-26 03:45:30199 return false;
200
[email protected]a732cec2011-12-22 08:35:52201 return CheckTestingInterface();
[email protected]081d147b2011-11-18 05:51:54202}
203
204void TestWebSocket::RunTests(const std::string& filter) {
[email protected]2117f252011-12-15 06:43:11205 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]91d01b52013-07-26 08:47:48215 RUN_TEST_BACKGROUND(TestWebSocket, TextSendReceiveTwice, filter);
[email protected]e18637f2011-12-28 05:51:32216 RUN_TEST_WITH_REFERENCE_CHECK(BinarySendReceive, filter);
[email protected]3f915fae2012-03-26 11:13:29217 RUN_TEST_WITH_REFERENCE_CHECK(StressedSendReceive, filter);
[email protected]bff494d2012-01-12 10:53:58218 RUN_TEST_WITH_REFERENCE_CHECK(BufferedAmount, filter);
[email protected]2f3cf602012-10-22 07:59:31219 // 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);
yhiranoc4118032014-08-27 16:47:16226 RUN_TEST_WITH_REFERENCE_CHECK(ClosedFromServerWhileSending, filter);
[email protected]3e919cb2011-12-16 07:28:21227
228 RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter);
[email protected]2785cb92012-02-29 20:22:09229
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]081d147b2011-11-18 05:51:54240}
241
[email protected]bedf8742012-03-16 16:44:11242std::string TestWebSocket::GetFullURL(const char* url) {
[email protected]21de9cb22013-02-14 13:07:34243 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]bedf8742012-03-16 16:44:11250 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]fade7dbc2012-03-13 22:48:07260PP_Var TestWebSocket::CreateVarString(const std::string& string) {
brettw669d47b12015-02-13 21:17:38261 return var_interface_->VarFromUtf8(string.c_str(),
262 static_cast<uint32_t>(string.size()));
[email protected]31c1a7e2011-11-26 03:45:30263}
[email protected]081d147b2011-11-18 05:51:54264
[email protected]fade7dbc2012-03-13 22:48:07265PP_Var TestWebSocket::CreateVarBinary(const std::vector<uint8_t>& binary) {
brettw669d47b12015-02-13 21:17:38266 PP_Var var =
267 arraybuffer_interface_->Create(static_cast<uint32_t>(binary.size()));
[email protected]fade7dbc2012-03-13 22:48:07268 uint8_t* var_data = static_cast<uint8_t*>(arraybuffer_interface_->Map(var));
269 std::copy(binary.begin(), binary.end(), var_data);
[email protected]e18637f2011-12-28 05:51:32270 return var;
271}
272
[email protected]31c1a7e2011-11-26 03:45:30273void TestWebSocket::ReleaseVar(const PP_Var& var) {
274 var_interface_->Release(var);
275}
276
[email protected]fade7dbc2012-03-13 22:48:07277bool TestWebSocket::AreEqualWithString(const PP_Var& var,
278 const std::string& string) {
[email protected]31c1a7e2011-11-26 03:45:30279 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]fade7dbc2012-03-13 22:48:07283 if (utf8_length != string.size())
[email protected]31c1a7e2011-11-26 03:45:30284 return false;
[email protected]fade7dbc2012-03-13 22:48:07285 if (string.compare(utf8))
[email protected]31c1a7e2011-11-26 03:45:30286 return false;
287 return true;
288}
289
[email protected]e18637f2011-12-28 05:51:32290bool TestWebSocket::AreEqualWithBinary(const PP_Var& var,
[email protected]fade7dbc2012-03-13 22:48:07291 const std::vector<uint8_t>& binary) {
[email protected]47ef6142012-01-26 21:04:10292 uint32_t buffer_size = 0;
293 PP_Bool success = arraybuffer_interface_->ByteLength(var, &buffer_size);
[email protected]fade7dbc2012-03-13 22:48:07294 if (!success || buffer_size != binary.size())
[email protected]e18637f2011-12-28 05:51:32295 return false;
[email protected]fade7dbc2012-03-13 22:48:07296 if (!std::equal(binary.begin(), binary.end(),
297 static_cast<uint8_t*>(arraybuffer_interface_->Map(var))))
[email protected]e18637f2011-12-28 05:51:32298 return false;
299 return true;
300}
301
[email protected]fade7dbc2012-03-13 22:48:07302PP_Resource TestWebSocket::Connect(const std::string& url,
303 int32_t* result,
304 const std::string& protocol) {
[email protected]31c1a7e2011-11-26 03:45:30305 PP_Var protocols[] = { PP_MakeUndefined() };
306 PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
307 if (!ws)
308 return 0;
[email protected]e18637f2011-12-28 05:51:32309 PP_Var url_var = CreateVarString(url);
[email protected]69d22382012-05-14 09:31:37310 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]32b05b12011-12-09 04:26:28311 uint32_t protocol_count = 0U;
[email protected]fade7dbc2012-03-13 22:48:07312 if (protocol.size()) {
[email protected]e18637f2011-12-28 05:51:32313 protocols[0] = CreateVarString(protocol);
[email protected]32b05b12011-12-09 04:26:28314 protocol_count = 1U;
[email protected]65f6b002011-12-01 07:44:11315 }
[email protected]69d22382012-05-14 09:31:37316 callback.WaitForResult(websocket_interface_->Connect(
[email protected]65f6b002011-12-01 07:44:11317 ws, url_var, protocols, protocol_count,
[email protected]69d22382012-05-14 09:31:37318 callback.GetCallback().pp_completion_callback()));
[email protected]65f6b002011-12-01 07:44:11319 ReleaseVar(url_var);
[email protected]fade7dbc2012-03-13 22:48:07320 if (protocol.size())
[email protected]65f6b002011-12-01 07:44:11321 ReleaseVar(protocols[0]);
[email protected]69d22382012-05-14 09:31:37322 *result = callback.result();
[email protected]31c1a7e2011-11-26 03:45:30323 return ws;
[email protected]081d147b2011-11-18 05:51:54324}
325
[email protected]91d01b52013-07-26 08:47:48326void 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]081d147b2011-11-18 05:51:54333std::string TestWebSocket::TestIsWebSocket() {
334 // Test that a NULL resource isn't a websocket.
335 pp::Resource null_resource;
[email protected]31c1a7e2011-11-26 03:45:30336 PP_Bool result =
337 websocket_interface_->IsWebSocket(null_resource.pp_resource());
338 ASSERT_FALSE(result);
[email protected]081d147b2011-11-18 05:51:54339
340 PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
[email protected]31c1a7e2011-11-26 03:45:30341 ASSERT_TRUE(ws);
342
343 result = websocket_interface_->IsWebSocket(ws);
344 ASSERT_TRUE(result);
345
346 core_interface_->ReleaseResource(ws);
[email protected]081d147b2011-11-18 05:51:54347
348 PASS();
349}
[email protected]31c1a7e2011-11-26 03:45:30350
[email protected]a1cff782011-12-06 18:06:34351std::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]32b05b12011-12-09 04:26:28356 ASSERT_EQ(0U, bufferedAmount);
[email protected]a1cff782011-12-06 18:06:34357
358 uint16_t close_code = websocket_interface_->GetCloseCode(ws);
[email protected]32b05b12011-12-09 04:26:28359 ASSERT_EQ(0U, close_code);
[email protected]a1cff782011-12-06 18:06:34360
361 PP_Var close_reason = websocket_interface_->GetCloseReason(ws);
[email protected]007b3f82013-04-09 08:46:45362 ASSERT_TRUE(AreEqualWithString(close_reason, std::string()));
[email protected]2117f252011-12-15 06:43:11363 ReleaseVar(close_reason);
[email protected]a1cff782011-12-06 18:06:34364
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]007b3f82013-04-09 08:46:45369 ASSERT_TRUE(AreEqualWithString(extensions, std::string()));
[email protected]2117f252011-12-15 06:43:11370 ReleaseVar(extensions);
[email protected]a1cff782011-12-06 18:06:34371
372 PP_Var protocol = websocket_interface_->GetProtocol(ws);
[email protected]007b3f82013-04-09 08:46:45373 ASSERT_TRUE(AreEqualWithString(protocol, std::string()));
[email protected]2117f252011-12-15 06:43:11374 ReleaseVar(protocol);
[email protected]a1cff782011-12-06 18:06:34375
[email protected]53508222012-01-27 09:42:41376 PP_WebSocketReadyState ready_state =
[email protected]a1cff782011-12-06 18:06:34377 websocket_interface_->GetReadyState(ws);
[email protected]53508222012-01-27 09:42:41378 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ready_state);
[email protected]a1cff782011-12-06 18:06:34379
380 PP_Var url = websocket_interface_->GetURL(ws);
[email protected]007b3f82013-04-09 08:46:45381 ASSERT_TRUE(AreEqualWithString(url, std::string()));
[email protected]2117f252011-12-15 06:43:11382 ReleaseVar(url);
383
384 core_interface_->ReleaseResource(ws);
[email protected]a1cff782011-12-06 18:06:34385
386 PASS();
387}
[email protected]65f6b002011-12-01 07:44:11388
[email protected]31c1a7e2011-11-26 03:45:30389std::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]69d22382012-05-14 09:31:37395 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
396 callback.WaitForResult(websocket_interface_->Connect(
[email protected]32b05b12011-12-09 04:26:28397 ws, PP_MakeUndefined(), protocols, 1U,
[email protected]69d22382012-05-14 09:31:37398 callback.GetCallback().pp_completion_callback()));
399 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
[email protected]31c1a7e2011-11-26 03:45:30400
[email protected]69d22382012-05-14 09:31:37401 callback.WaitForResult(websocket_interface_->Connect(
[email protected]32b05b12011-12-09 04:26:28402 ws, PP_MakeUndefined(), protocols, 1U,
[email protected]69d22382012-05-14 09:31:37403 callback.GetCallback().pp_completion_callback()));
404 ASSERT_EQ(PP_ERROR_INPROGRESS, callback.result());
[email protected]31c1a7e2011-11-26 03:45:30405
406 core_interface_->ReleaseResource(ws);
407
[email protected]65f6b002011-12-01 07:44:11408 for (int i = 0; kInvalidURLs[i]; ++i) {
[email protected]69d22382012-05-14 09:31:37409 int32_t result;
[email protected]007b3f82013-04-09 08:46:45410 ws = Connect(kInvalidURLs[i], &result, std::string());
[email protected]31c1a7e2011-11-26 03:45:30411 ASSERT_TRUE(ws);
[email protected]31c1a7e2011-11-26 03:45:30412 ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
[email protected]65f6b002011-12-01 07:44:11413
414 core_interface_->ReleaseResource(ws);
[email protected]31c1a7e2011-11-26 03:45:30415 }
416
[email protected]32b05b12011-12-09 04:26:28417 PASS();
418}
419
420std::string TestWebSocket::TestProtocols() {
[email protected]bedf8742012-03-16 16:44:11421 PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str());
[email protected]e18637f2011-12-28 05:51:32422 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]32b05b12011-12-09 04:26:28430
431 PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
432 ASSERT_TRUE(ws);
[email protected]69d22382012-05-14 09:31:37433 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
434 callback.WaitForResult(websocket_interface_->Connect(
[email protected]9082aa5b2012-01-19 08:44:47435 ws, url, bad_protocols, 2U,
[email protected]69d22382012-05-14 09:31:37436 callback.GetCallback().pp_completion_callback()));
437 ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
[email protected]32b05b12011-12-09 04:26:28438 core_interface_->ReleaseResource(ws);
439
440 ws = websocket_interface_->Create(instance_->pp_instance());
441 ASSERT_TRUE(ws);
[email protected]69d22382012-05-14 09:31:37442 int32_t result = websocket_interface_->Connect(
[email protected]32b05b12011-12-09 04:26:28443 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]31c1a7e2011-11-26 03:45:30453
454 PASS();
455}
456
[email protected]65f6b002011-12-01 07:44:11457std::string TestWebSocket::TestGetURL() {
458 for (int i = 0; kInvalidURLs[i]; ++i) {
459 int32_t result;
[email protected]007b3f82013-04-09 08:46:45460 PP_Resource ws = Connect(kInvalidURLs[i], &result, std::string());
[email protected]65f6b002011-12-01 07:44:11461 ASSERT_TRUE(ws);
462 PP_Var url = websocket_interface_->GetURL(ws);
[email protected]e18637f2011-12-28 05:51:32463 ASSERT_TRUE(AreEqualWithString(url, kInvalidURLs[i]));
[email protected]65f6b002011-12-01 07:44:11464 ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
465
466 ReleaseVar(url);
467 core_interface_->ReleaseResource(ws);
468 }
469
470 PASS();
471}
[email protected]31c1a7e2011-11-26 03:45:30472
473std::string TestWebSocket::TestValidConnect() {
[email protected]65f6b002011-12-01 07:44:11474 int32_t result;
[email protected]007b3f82013-04-09 08:46:45475 PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]65f6b002011-12-01 07:44:11476 ASSERT_TRUE(ws);
[email protected]31c1a7e2011-11-26 03:45:30477 ASSERT_EQ(PP_OK, result);
[email protected]51f660c2012-03-10 00:41:57478 PP_Var extensions = websocket_interface_->GetExtensions(ws);
[email protected]007b3f82013-04-09 08:46:45479 ASSERT_TRUE(AreEqualWithString(extensions, std::string()));
[email protected]31c1a7e2011-11-26 03:45:30480 core_interface_->ReleaseResource(ws);
[email protected]8ced4f3f2013-02-04 16:53:07481 ReleaseVar(extensions);
[email protected]31c1a7e2011-11-26 03:45:30482
483 PASS();
484}
485
[email protected]5cf0fb12011-12-06 18:33:11486std::string TestWebSocket::TestInvalidClose() {
[email protected]e18637f2011-12-28 05:51:32487 PP_Var reason = CreateVarString("close for test");
[email protected]69d22382012-05-14 09:31:37488 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
489 TestCompletionCallback async_callback(instance_->pp_instance(), PP_REQUIRED);
[email protected]5cf0fb12011-12-06 18:33:11490
491 // Close before connect.
492 PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
[email protected]69d22382012-05-14 09:31:37493 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]5cf0fb12011-12-06 18:33:11497 core_interface_->ReleaseResource(ws);
498
499 // Close with bad arguments.
[email protected]69d22382012-05-14 09:31:37500 int32_t result;
[email protected]007b3f82013-04-09 08:46:45501 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]5cf0fb12011-12-06 18:33:11502 ASSERT_TRUE(ws);
503 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37504 callback.WaitForResult(websocket_interface_->Close(
505 ws, 1U, reason, callback.GetCallback().pp_completion_callback()));
506 ASSERT_EQ(PP_ERROR_NOACCESS, callback.result());
[email protected]5cf0fb12011-12-06 18:33:11507 core_interface_->ReleaseResource(ws);
508
[email protected]2c32b2602012-04-24 08:06:49509 // Close with PP_VARTYPE_NULL.
[email protected]007b3f82013-04-09 08:46:45510 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]2c32b2602012-04-24 08:06:49511 ASSERT_TRUE(ws);
512 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37513 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]2c32b2602012-04-24 08:06:49517 core_interface_->ReleaseResource(ws);
518
519 // Close with PP_VARTYPE_NULL and ongoing receive message.
[email protected]007b3f82013-04-09 08:46:45520 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]2c32b2602012-04-24 08:06:49521 ASSERT_TRUE(ws);
522 ASSERT_EQ(PP_OK, result);
523 PP_Var receive_message_var;
[email protected]69d22382012-05-14 09:31:37524 result = websocket_interface_->ReceiveMessage(
525 ws, &receive_message_var,
526 async_callback.GetCallback().pp_completion_callback());
[email protected]2c32b2602012-04-24 08:06:49527 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37528 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]2c32b2602012-04-24 08:06:49532 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]69d22382012-05-14 09:31:37537 async_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
538 ASSERT_EQ(PP_OK, async_callback.result());
[email protected]2c32b2602012-04-24 08:06:49539 ASSERT_TRUE(AreEqualWithString(receive_message_var, send_message));
540 ReleaseVar(receive_message_var);
541 core_interface_->ReleaseResource(ws);
542
[email protected]9c8b2fd2012-04-25 11:39:07543 // Close twice.
[email protected]007b3f82013-04-09 08:46:45544 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]9c8b2fd2012-04-25 11:39:07545 ASSERT_TRUE(ws);
546 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37547 result = websocket_interface_->Close(
548 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
549 async_callback.GetCallback().pp_completion_callback());
[email protected]9c8b2fd2012-04-25 11:39:07550 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
551 // Call another Close() before previous one is in progress.
[email protected]69d22382012-05-14 09:31:37552 result = websocket_interface_->Close(
553 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
554 callback.GetCallback().pp_completion_callback());
[email protected]9c8b2fd2012-04-25 11:39:07555 ASSERT_EQ(PP_ERROR_INPROGRESS, result);
[email protected]69d22382012-05-14 09:31:37556 async_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
557 ASSERT_EQ(PP_OK, async_callback.result());
[email protected]9c8b2fd2012-04-25 11:39:07558 // Call another Close() after previous one is completed.
559 // This Close() must do nothing and reports no error.
[email protected]69d22382012-05-14 09:31:37560 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]9c8b2fd2012-04-25 11:39:07564 core_interface_->ReleaseResource(ws);
565
[email protected]5cf0fb12011-12-06 18:33:11566 ReleaseVar(reason);
567
568 PASS();
569}
570
[email protected]8b1aa2d2014-07-29 09:35:59571// TODO(tyoshino): Consider splitting this test into smaller ones.
572// http://crbug.com/397035
[email protected]5cf0fb12011-12-06 18:33:11573std::string TestWebSocket::TestValidClose() {
[email protected]e18637f2011-12-28 05:51:32574 PP_Var reason = CreateVarString("close for test");
[email protected]69d22382012-05-14 09:31:37575 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
576 TestCompletionCallback another_callback(
577 instance_->pp_instance(), callback_type());
[email protected]5cf0fb12011-12-06 18:33:11578
579 // Close.
580 int32_t result;
[email protected]007b3f82013-04-09 08:46:45581 PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]5cf0fb12011-12-06 18:33:11582 ASSERT_TRUE(ws);
583 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37584 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]5cf0fb12011-12-06 18:33:11589 core_interface_->ReleaseResource(ws);
590
[email protected]b6b90fe2012-05-31 09:25:45591 // Close without code and reason.
[email protected]007b3f82013-04-09 08:46:45592 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]b6b90fe2012-05-31 09:25:45593 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]8b1aa2d2014-07-29 09:35:59598 CHECK_CALLBACK_BEHAVIOR(callback);
[email protected]b6b90fe2012-05-31 09:25:45599 ASSERT_EQ(PP_OK, callback.result());
600 core_interface_->ReleaseResource(ws);
601
[email protected]2c32b2602012-04-24 08:06:49602 // Close with PP_VARTYPE_UNDEFINED.
[email protected]007b3f82013-04-09 08:46:45603 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]2c32b2602012-04-24 08:06:49604 ASSERT_TRUE(ws);
605 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37606 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]2c32b2602012-04-24 08:06:49611 core_interface_->ReleaseResource(ws);
612
[email protected]8b1aa2d2014-07-29 09:35:59613 // Close in CONNECTING state.
614 // The ongoing Connect() fails with PP_ERROR_ABORTED, then the Close()
615 // completes successfully.
[email protected]5cf0fb12011-12-06 18:33:11616 ws = websocket_interface_->Create(instance_->pp_instance());
[email protected]8b1aa2d2014-07-29 09:35:59617 PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str());
618 PP_Var protocols[] = { PP_MakeUndefined() };
[email protected]69d22382012-05-14 09:31:37619 result = websocket_interface_->Connect(
620 ws, url, protocols, 0U, callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11621 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37622 result = websocket_interface_->Close(
623 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
[email protected]3ab61272012-04-07 00:09:08624 another_callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11625 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37626 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]5cf0fb12011-12-06 18:33:11630 core_interface_->ReleaseResource(ws);
[email protected]8b1aa2d2014-07-29 09:35:59631 ReleaseVar(url);
[email protected]5cf0fb12011-12-06 18:33:11632
[email protected]8b1aa2d2014-07-29 09:35:59633 // Close while already closing.
634 // The first Close will succeed, and the second one will synchronously fail
635 // with PP_ERROR_INPROGRESS.
[email protected]007b3f82013-04-09 08:46:45636 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]5cf0fb12011-12-06 18:33:11637 ASSERT_TRUE(ws);
638 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37639 result = websocket_interface_->Close(
640 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
[email protected]3ab61272012-04-07 00:09:08641 callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11642 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37643 result = websocket_interface_->Close(
644 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
[email protected]3ab61272012-04-07 00:09:08645 another_callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11646 ASSERT_EQ(PP_ERROR_INPROGRESS, result);
[email protected]69d22382012-05-14 09:31:37647 callback.WaitForResult(PP_OK_COMPLETIONPENDING);
648 ASSERT_EQ(PP_OK, callback.result());
[email protected]5cf0fb12011-12-06 18:33:11649 core_interface_->ReleaseResource(ws);
650
[email protected]8b1aa2d2014-07-29 09:35:59651 // Close with ongoing ReceiveMessage.
[email protected]007b3f82013-04-09 08:46:45652 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]5cf0fb12011-12-06 18:33:11653 ASSERT_TRUE(ws);
654 ASSERT_EQ(PP_OK, result);
655 PP_Var receive_message_var;
[email protected]69d22382012-05-14 09:31:37656 result = websocket_interface_->ReceiveMessage(
657 ws, &receive_message_var,
[email protected]3ab61272012-04-07 00:09:08658 callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11659 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37660 result = websocket_interface_->Close(
661 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
[email protected]3ab61272012-04-07 00:09:08662 another_callback.GetCallback().pp_completion_callback());
[email protected]5cf0fb12011-12-06 18:33:11663 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37664 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]5cf0fb12011-12-06 18:33:11668 core_interface_->ReleaseResource(ws);
669
[email protected]8b1aa2d2014-07-29 09:35:59670 // Close with PP_VARTYPE_UNDEFINED for reason and ongoing ReceiveMessage.
[email protected]007b3f82013-04-09 08:46:45671 ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
[email protected]2c32b2602012-04-24 08:06:49672 ASSERT_TRUE(ws);
673 ASSERT_EQ(PP_OK, result);
[email protected]69d22382012-05-14 09:31:37674 result = websocket_interface_->ReceiveMessage(
675 ws, &receive_message_var,
[email protected]2c32b2602012-04-24 08:06:49676 callback.GetCallback().pp_completion_callback());
677 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37678 result = websocket_interface_->Close(
679 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(),
[email protected]2c32b2602012-04-24 08:06:49680 another_callback.GetCallback().pp_completion_callback());
681 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]69d22382012-05-14 09:31:37682 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]2c32b2602012-04-24 08:06:49686 core_interface_->ReleaseResource(ws);
687
[email protected]9885a102012-05-14 05:52:12688 // Server initiated closing handshake.
[email protected]007b3f82013-04-09 08:46:45689 ws = Connect(
690 GetFullURL(kCloseWithCodeAndReasonServerURL), &result, std::string());
[email protected]9885a102012-05-14 05:52:12691 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]5cf0fb12011-12-06 18:33:11704 ReleaseVar(reason);
[email protected]5cf0fb12011-12-06 18:33:11705
706 PASS();
707}
708
[email protected]65f6b002011-12-01 07:44:11709std::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]bedf8742012-03-16 16:44:11716 std::string url(GetFullURL(kProtocolTestServerURL));
[email protected]65f6b002011-12-01 07:44:11717 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]e18637f2011-12-28 05:51:32724 ASSERT_TRUE(AreEqualWithString(protocol, expected_protocols[i]));
[email protected]65f6b002011-12-01 07:44:11725
726 ReleaseVar(protocol);
727 core_interface_->ReleaseResource(ws);
728 }
729
730 PASS();
731}
[email protected]31c1a7e2011-11-26 03:45:30732
733std::string TestWebSocket::TestTextSendReceive() {
734 // Connect to test echo server.
[email protected]65f6b002011-12-01 07:44:11735 int32_t connect_result;
[email protected]007b3f82013-04-09 08:46:45736 PP_Resource ws =
737 Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
[email protected]31c1a7e2011-11-26 03:45:30738 ASSERT_TRUE(ws);
[email protected]65f6b002011-12-01 07:44:11739 ASSERT_EQ(PP_OK, connect_result);
[email protected]31c1a7e2011-11-26 03:45:30740
741 // Send 'hello pepper' text message.
742 const char* message = "hello pepper";
[email protected]e18637f2011-12-28 05:51:32743 PP_Var message_var = CreateVarString(message);
[email protected]31c1a7e2011-11-26 03:45:30744 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]69d22382012-05-14 09:31:37749 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]31c1a7e2011-11-26 03:45:30750 PP_Var received_message;
[email protected]69d22382012-05-14 09:31:37751 callback.WaitForResult(websocket_interface_->ReceiveMessage(
752 ws, &received_message, callback.GetCallback().pp_completion_callback()));
753 ASSERT_EQ(PP_OK, callback.result());
[email protected]e18637f2011-12-28 05:51:32754 ASSERT_TRUE(AreEqualWithString(received_message, message));
755 ReleaseVar(received_message);
756 core_interface_->ReleaseResource(ws);
757
758 PASS();
759}
760
[email protected]91d01b52013-07-26 08:47:48761// Run as a BACKGROUND test.
762std::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]e18637f2011-12-28 05:51:32810std::string TestWebSocket::TestBinarySendReceive() {
811 // Connect to test echo server.
812 int32_t connect_result;
[email protected]007b3f82013-04-09 08:46:45813 PP_Resource ws =
814 Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
[email protected]e18637f2011-12-28 05:51:32815 ASSERT_TRUE(ws);
816 ASSERT_EQ(PP_OK, connect_result);
817
818 // Send binary message.
[email protected]fade7dbc2012-03-13 22:48:07819 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]e18637f2011-12-28 05:51:32823 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]69d22382012-05-14 09:31:37828 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]e18637f2011-12-28 05:51:32829 PP_Var received_message;
[email protected]69d22382012-05-14 09:31:37830 callback.WaitForResult(websocket_interface_->ReceiveMessage(
831 ws, &received_message, callback.GetCallback().pp_completion_callback()));
832 ASSERT_EQ(PP_OK, callback.result());
[email protected]fade7dbc2012-03-13 22:48:07833 ASSERT_TRUE(AreEqualWithBinary(received_message, binary));
[email protected]31c1a7e2011-11-26 03:45:30834 ReleaseVar(received_message);
835 core_interface_->ReleaseResource(ws);
836
837 PASS();
838}
839
[email protected]3f915fae2012-03-26 11:13:29840std::string TestWebSocket::TestStressedSendReceive() {
841 // Connect to test echo server.
842 int32_t connect_result;
[email protected]007b3f82013-04-09 08:46:45843 PP_Resource ws =
844 Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
[email protected]3f915fae2012-03-26 11:13:29845 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]68eae852012-04-16 16:48:05855 // 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]3f915fae2012-03-26 11:13:29864
865 // Send many messages.
[email protected]68eae852012-04-16 16:48:05866 int32_t result;
[email protected]3f915fae2012-03-26 11:13:29867 for (int i = 0; i < 256; ++i) {
[email protected]68eae852012-04-16 16:48:05868 result = websocket_interface_->SendMessage(ws, text_var);
[email protected]3f915fae2012-03-26 11:13:29869 ASSERT_EQ(PP_OK, result);
870 result = websocket_interface_->SendMessage(ws, binary_var);
871 ASSERT_EQ(PP_OK, result);
872 }
[email protected]68eae852012-04-16 16:48:05873 result = websocket_interface_->SendMessage(ws, large_binary_var);
874 ASSERT_EQ(PP_OK, result);
[email protected]3f915fae2012-03-26 11:13:29875 ReleaseVar(text_var);
876 ReleaseVar(binary_var);
[email protected]68eae852012-04-16 16:48:05877 ReleaseVar(large_binary_var);
[email protected]3f915fae2012-03-26 11:13:29878
879 // Receive echoed data.
[email protected]69d22382012-05-14 09:31:37880 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]68eae852012-04-16 16:48:05881 for (int i = 0; i <= 512; ++i) {
[email protected]3f915fae2012-03-26 11:13:29882 PP_Var received_message;
[email protected]69d22382012-05-14 09:31:37883 callback.WaitForResult(websocket_interface_->ReceiveMessage(
884 ws, &received_message,
885 callback.GetCallback().pp_completion_callback()));
886 ASSERT_EQ(PP_OK, callback.result());
[email protected]68eae852012-04-16 16:48:05887 if (i == 512) {
888 ASSERT_TRUE(AreEqualWithBinary(received_message, large_binary));
889 } else if (i & 1) {
[email protected]3f915fae2012-03-26 11:13:29890 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]bff494d2012-01-12 10:53:58901std::string TestWebSocket::TestBufferedAmount() {
902 // Connect to test echo server.
903 int32_t connect_result;
[email protected]007b3f82013-04-09 08:46:45904 PP_Resource ws =
905 Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
[email protected]bff494d2012-01-12 10:53:58906 ASSERT_TRUE(ws);
907 ASSERT_EQ(PP_OK, connect_result);
[email protected]25a9f652011-12-01 06:55:37908
[email protected]bff494d2012-01-12 10:53:58909 // Prepare a large message that is not aligned with the internal buffer
910 // sizes.
[email protected]fade7dbc2012-03-13 22:48:07911 std::string message(8193, 'x');
[email protected]bff494d2012-01-12 10:53:58912 PP_Var message_var = CreateVarString(message);
[email protected]a9718acb2011-12-02 23:57:31913
[email protected]bff494d2012-01-12 10:53:58914 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]69d22382012-05-14 09:31:37928 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
929 result = websocket_interface_->Close(
930 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
[email protected]3ab61272012-04-07 00:09:08931 callback.GetCallback().pp_completion_callback());
[email protected]bff494d2012-01-12 10:53:58932 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]53508222012-01-27 09:42:41933 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING,
[email protected]bff494d2012-01-12 10:53:58934 websocket_interface_->GetReadyState(ws));
935
[email protected]69d22382012-05-14 09:31:37936 callback.WaitForResult(result);
937 ASSERT_EQ(PP_OK, callback.result());
[email protected]53508222012-01-27 09:42:41938 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED,
[email protected]bff494d2012-01-12 10:53:58939 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]007b3f82013-04-09 08:46:45945 PP_Var empty_string = CreateVarString(std::string());
[email protected]bff494d2012-01-12 10:53:58946 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]3e919cb2011-12-16 07:28:21965
[email protected]2f3cf602012-10-22 07:59:31966// Test abort behaviors where a WebSocket PP_Resource is released while each
967// function is in-flight on the WebSocket PP_Resource.
968std::string TestWebSocket::TestAbortCallsWithCallback() {
[email protected]68eae852012-04-16 16:48:05969 // Following tests make sure the behavior for functions which require a
970 // callback. The callback must get a PP_ERROR_ABORTED.
[email protected]2f3cf602012-10-22 07:59:31971
[email protected]68eae852012-04-16 16:48:05972 // Test the behavior for Connect().
[email protected]2f3cf602012-10-22 07:59:31973 PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
[email protected]68eae852012-04-16 16:48:05974 ASSERT_TRUE(ws);
[email protected]2f3cf602012-10-22 07:59:31975 std::string url = GetFullURL(kEchoServerURL);
[email protected]68eae852012-04-16 16:48:05976 PP_Var url_var = CreateVarString(url);
977 TestCompletionCallback connect_callback(
[email protected]69d22382012-05-14 09:31:37978 instance_->pp_instance(), callback_type());
[email protected]2f3cf602012-10-22 07:59:31979 int32_t result = websocket_interface_->Connect(
[email protected]69d22382012-05-14 09:31:37980 ws, url_var, NULL, 0,
[email protected]68eae852012-04-16 16:48:05981 connect_callback.GetCallback().pp_completion_callback());
982 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
983 core_interface_->ReleaseResource(ws);
[email protected]69d22382012-05-14 09:31:37984 connect_callback.WaitForResult(result);
985 ASSERT_EQ(PP_ERROR_ABORTED, connect_callback.result());
[email protected]68eae852012-04-16 16:48:05986
987 // Test the behavior for Close().
[email protected]007b3f82013-04-09 08:46:45988 ws = Connect(url, &result, std::string());
[email protected]68eae852012-04-16 16:48:05989 ASSERT_TRUE(ws);
990 ASSERT_EQ(PP_OK, result);
991 PP_Var reason_var = CreateVarString("abort");
992 TestCompletionCallback close_callback(
[email protected]69d22382012-05-14 09:31:37993 instance_->pp_instance(), callback_type());
994 result = websocket_interface_->Close(
995 ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason_var,
[email protected]68eae852012-04-16 16:48:05996 close_callback.GetCallback().pp_completion_callback());
997 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
998 core_interface_->ReleaseResource(ws);
[email protected]69d22382012-05-14 09:31:37999 close_callback.WaitForResult(result);
1000 ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result());
[email protected]68eae852012-04-16 16:48:051001 ReleaseVar(reason_var);
1002
1003 // Test the behavior for ReceiveMessage().
[email protected]2f3cf602012-10-22 07:59:311004 // Make sure the simplest case to wait for data which never arrives, here.
[email protected]007b3f82013-04-09 08:46:451005 ws = Connect(url, &result, std::string());
[email protected]68eae852012-04-16 16:48:051006 ASSERT_TRUE(ws);
1007 ASSERT_EQ(PP_OK, result);
1008 PP_Var receive_var;
1009 TestCompletionCallback receive_callback(
[email protected]69d22382012-05-14 09:31:371010 instance_->pp_instance(), callback_type());
1011 result = websocket_interface_->ReceiveMessage(
1012 ws, &receive_var,
[email protected]68eae852012-04-16 16:48:051013 receive_callback.GetCallback().pp_completion_callback());
1014 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
1015 core_interface_->ReleaseResource(ws);
[email protected]69d22382012-05-14 09:31:371016 receive_callback.WaitForResult(result);
1017 ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result());
[email protected]68eae852012-04-16 16:48:051018
[email protected]cc2386c42012-06-29 04:41:421019 // Release the resource in the aborting receive completion callback which is
1020 // introduced by calling Close().
[email protected]007b3f82013-04-09 08:46:451021 ws = Connect(url, &result, std::string());
[email protected]cc2386c42012-06-29 04:41:421022 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]2f3cf602012-10-22 07:59:311041 ReleaseVar(url_var);
1042
1043 PASS();
1044}
1045
1046std::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]007b3f82013-04-09 08:46:451055 PP_Resource ws = Connect(url, &result, std::string());
[email protected]2f3cf602012-10-22 07:59:311056 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
1066std::string TestWebSocket::TestAbortCloseCall() {
1067 // Release the resource in the close completion callback.
1068 int32_t result;
1069 std::string url = GetFullURL(kEchoServerURL);
[email protected]007b3f82013-04-09 08:46:451070 PP_Resource ws = Connect(url, &result, std::string());
[email protected]2f3cf602012-10-22 07:59:311071 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
1087std::string TestWebSocket::TestAbortReceiveMessageCall() {
[email protected]68eae852012-04-16 16:48:051088 // Test the behavior where receive process might be in-flight.
[email protected]2f3cf602012-10-22 07:59:311089 std::vector<uint8_t> large_binary(65 * 1024);
1090 PP_Var large_var = CreateVarBinary(large_binary);
[email protected]68eae852012-04-16 16:48:051091 const char* text = "yukarin";
1092 PP_Var text_var = CreateVarString(text);
1093
[email protected]2f3cf602012-10-22 07:59:311094 std::string url = GetFullURL(kEchoServerURL);
1095 int32_t result;
1096 PP_Resource ws;
1097
[email protected]13d22df12012-10-24 04:26:381098 // 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]007b3f82013-04-09 08:46:451103 ws = Connect(url, &result, std::string());
[email protected]68eae852012-04-16 16:48:051104 ASSERT_TRUE(ws);
1105 ASSERT_EQ(PP_OK, result);
[email protected]13d22df12012-10-24 04:26:381106 for (int i = 0; i <= trial_count; ++i) {
[email protected]68eae852012-04-16 16:48:051107 result = websocket_interface_->SendMessage(ws, text_var);
1108 ASSERT_EQ(PP_OK, result);
1109 }
[email protected]69d22382012-05-14 09:31:371110 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]68eae852012-04-16 16:48:051111 PP_Var var;
1112 for (int i = 0; i < trial; ++i) {
[email protected]69d22382012-05-14 09:31:371113 callback.WaitForResult(websocket_interface_->ReceiveMessage(
1114 ws, &var, callback.GetCallback().pp_completion_callback()));
1115 ASSERT_EQ(PP_OK, callback.result());
[email protected]68eae852012-04-16 16:48:051116 ASSERT_TRUE(AreEqualWithString(var, text));
1117 ReleaseVar(var);
1118 }
1119 result = websocket_interface_->ReceiveMessage(
[email protected]69d22382012-05-14 09:31:371120 ws, &var, callback.GetCallback().pp_completion_callback());
[email protected]68eae852012-04-16 16:48:051121 core_interface_->ReleaseResource(ws);
1122 if (result != PP_OK) {
[email protected]69d22382012-05-14 09:31:371123 callback.WaitForResult(result);
1124 ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
[email protected]68eae852012-04-16 16:48:051125 }
1126 }
1127 // Same test, but the last receiving message is large message over 64KiB.
[email protected]13d22df12012-10-24 04:26:381128 for (int trial = 1; trial <= trial_count; trial++) {
[email protected]007b3f82013-04-09 08:46:451129 ws = Connect(url, &result, std::string());
[email protected]68eae852012-04-16 16:48:051130 ASSERT_TRUE(ws);
1131 ASSERT_EQ(PP_OK, result);
[email protected]13d22df12012-10-24 04:26:381132 for (int i = 0; i <= trial_count; ++i) {
[email protected]68eae852012-04-16 16:48:051133 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]69d22382012-05-14 09:31:371139 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
[email protected]68eae852012-04-16 16:48:051140 PP_Var var;
1141 for (int i = 0; i < trial; ++i) {
[email protected]69d22382012-05-14 09:31:371142 callback.WaitForResult(websocket_interface_->ReceiveMessage(
1143 ws, &var, callback.GetCallback().pp_completion_callback()));
1144 ASSERT_EQ(PP_OK, callback.result());
[email protected]68eae852012-04-16 16:48:051145 ASSERT_TRUE(AreEqualWithString(var, text));
1146 ReleaseVar(var);
1147 }
1148 result = websocket_interface_->ReceiveMessage(
[email protected]69d22382012-05-14 09:31:371149 ws, &var, callback.GetCallback().pp_completion_callback());
[email protected]68eae852012-04-16 16:48:051150 core_interface_->ReleaseResource(ws);
1151 if (result != PP_OK) {
[email protected]69d22382012-05-14 09:31:371152 callback.WaitForResult(result);
1153 ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
[email protected]68eae852012-04-16 16:48:051154 }
1155 }
1156
1157 ReleaseVar(large_var);
1158 ReleaseVar(text_var);
1159
1160 PASS();
1161}
1162
yhiranoc4118032014-08-27 16:47:161163std::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]3e919cb2011-12-16 07:28:211190std::string TestWebSocket::TestCcInterfaces() {
[email protected]1364c9c2011-12-20 08:57:361191 // C++ bindings is simple straightforward, then just verifies interfaces work
1192 // as a interface bridge fine.
[email protected]53508222012-01-27 09:42:411193 pp::WebSocket ws(instance_);
[email protected]3e919cb2011-12-16 07:28:211194
1195 // Check uninitialized properties access.
1196 ASSERT_EQ(0, ws.GetBufferedAmount());
1197 ASSERT_EQ(0, ws.GetCloseCode());
[email protected]007b3f82013-04-09 08:46:451198 ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), std::string()));
[email protected]6d852862014-01-24 01:10:231199 ASSERT_FALSE(ws.GetCloseWasClean());
[email protected]007b3f82013-04-09 08:46:451200 ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), std::string()));
1201 ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string()));
[email protected]53508222012-01-27 09:42:411202 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ws.GetReadyState());
[email protected]007b3f82013-04-09 08:46:451203 ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), std::string()));
[email protected]3e919cb2011-12-16 07:28:211204
1205 // Check communication interfaces (connect, send, receive, and close).
[email protected]69d22382012-05-14 09:31:371206 TestCompletionCallback connect_callback(
1207 instance_->pp_instance(), callback_type());
1208 connect_callback.WaitForResult(ws.Connect(
[email protected]599aeffdc2013-03-15 11:06:231209 pp::Var(GetFullURL(kCloseServerURL)), NULL, 0U,
1210 connect_callback.GetCallback()));
[email protected]69d22382012-05-14 09:31:371211 CHECK_CALLBACK_BEHAVIOR(connect_callback);
1212 ASSERT_EQ(PP_OK, connect_callback.result());
[email protected]3e919cb2011-12-16 07:28:211213
[email protected]e18637f2011-12-28 05:51:321214 std::string text_message("hello C++");
[email protected]69d22382012-05-14 09:31:371215 int32_t result = ws.SendMessage(pp::Var(text_message));
[email protected]3e919cb2011-12-16 07:28:211216 ASSERT_EQ(PP_OK, result);
1217
[email protected]fade7dbc2012-03-13 22:48:071218 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]3e919cb2011-12-16 07:28:211223 ASSERT_EQ(PP_OK, result);
[email protected]e18637f2011-12-28 05:51:321224
1225 pp::Var text_receive_var;
[email protected]69d22382012-05-14 09:31:371226 TestCompletionCallback text_receive_callback(
1227 instance_->pp_instance(), callback_type());
1228 text_receive_callback.WaitForResult(
[email protected]599aeffdc2013-03-15 11:06:231229 ws.ReceiveMessage(&text_receive_var,
1230 text_receive_callback.GetCallback()));
[email protected]69d22382012-05-14 09:31:371231 ASSERT_EQ(PP_OK, text_receive_callback.result());
[email protected]e18637f2011-12-28 05:51:321232 ASSERT_TRUE(
1233 AreEqualWithString(text_receive_var.pp_var(), text_message.c_str()));
1234
1235 pp::Var binary_receive_var;
[email protected]69d22382012-05-14 09:31:371236 TestCompletionCallback binary_receive_callback(
1237 instance_->pp_instance(), callback_type());
1238 binary_receive_callback.WaitForResult(
[email protected]599aeffdc2013-03-15 11:06:231239 ws.ReceiveMessage(&binary_receive_var,
1240 binary_receive_callback.GetCallback()));
[email protected]69d22382012-05-14 09:31:371241 ASSERT_EQ(PP_OK, binary_receive_callback.result());
[email protected]fade7dbc2012-03-13 22:48:071242 ASSERT_TRUE(AreEqualWithBinary(binary_receive_var.pp_var(), binary));
[email protected]3e919cb2011-12-16 07:28:211243
[email protected]69d22382012-05-14 09:31:371244 TestCompletionCallback close_callback(
1245 instance_->pp_instance(), callback_type());
[email protected]3e919cb2011-12-16 07:28:211246 std::string reason("bye");
[email protected]69d22382012-05-14 09:31:371247 close_callback.WaitForResult(ws.Close(
[email protected]599aeffdc2013-03-15 11:06:231248 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason),
1249 close_callback.GetCallback()));
[email protected]69d22382012-05-14 09:31:371250 CHECK_CALLBACK_BEHAVIOR(close_callback);
1251 ASSERT_EQ(PP_OK, close_callback.result());
[email protected]3e919cb2011-12-16 07:28:211252
1253 // Check initialized properties access.
1254 ASSERT_EQ(0, ws.GetBufferedAmount());
[email protected]fae1ecd2012-03-03 01:10:591255 ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, ws.GetCloseCode());
[email protected]69d22382012-05-14 09:31:371256 ASSERT_TRUE(
1257 AreEqualWithString(ws.GetCloseReason().pp_var(), reason.c_str()));
[email protected]3e919cb2011-12-16 07:28:211258 ASSERT_EQ(true, ws.GetCloseWasClean());
[email protected]007b3f82013-04-09 08:46:451259 ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string()));
[email protected]53508222012-01-27 09:42:411260 ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, ws.GetReadyState());
[email protected]69d22382012-05-14 09:31:371261 ASSERT_TRUE(AreEqualWithString(
1262 ws.GetURL().pp_var(), GetFullURL(kCloseServerURL).c_str()));
[email protected]3e919cb2011-12-16 07:28:211263
1264 PASS();
1265}
[email protected]2785cb92012-02-29 20:22:091266
1267std::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]9d5eadf2012-10-09 03:43:481282 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]2785cb92012-02-29 20:22:091292 }
1293
1294 PASS();
1295}
1296
1297std::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]bedf8742012-03-16 16:44:111306 pp::Var(GetFullURL(kEchoServerURL)), bad_protocols, 2U);
[email protected]2785cb92012-02-29 20:22:091307 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]bedf8742012-03-16 16:44:111314 pp::Var(GetFullURL(kEchoServerURL)), good_protocols, 2U);
[email protected]2785cb92012-02-29 20:22:091315 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
1330std::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]9d5eadf2012-10-09 03:43:481337 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]2785cb92012-02-29 20:22:091347 pp::Var url = websocket.GetURL();
1348 ASSERT_TRUE(AreEqualWithString(url.pp_var(), kInvalidURLs[i]));
[email protected]2785cb92012-02-29 20:22:091349 }
1350
1351 PASS();
1352}
1353
1354std::string TestWebSocket::TestUtilityValidConnect() {
1355 const pp::Var protocols[] = { pp::Var() };
1356 TestWebSocketAPI websocket(instance_);
1357 int32_t result = websocket.Connect(
[email protected]bedf8742012-03-16 16:44:111358 pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
[email protected]2785cb92012-02-29 20:22:091359 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]007b3f82013-04-09 08:46:451364 ASSERT_TRUE(
1365 AreEqualWithString(websocket.GetExtensions().pp_var(), std::string()));
[email protected]2785cb92012-02-29 20:22:091366
1367 PASS();
1368}
1369
1370std::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]fae1ecd2012-03-03 01:10:591376 int32_t result = websocket.Close(
1377 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason);
[email protected]2785cb92012-02-29 20:22:091378 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]bedf8742012-03-16 16:44:111385 int32_t result = websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)),
[email protected]2785cb92012-02-29 20:22:091386 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
1399std::string TestWebSocket::TestUtilityValidClose() {
1400 std::string reason("close for test");
[email protected]bedf8742012-03-16 16:44:111401 pp::Var url = pp::Var(GetFullURL(kCloseServerURL));
[email protected]2785cb92012-02-29 20:22:091402
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]fae1ecd2012-03-03 01:10:591409 result = websocket.Close(
1410 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091411 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]fae1ecd2012-03-03 01:10:591418 ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, events[1].close_code);
[email protected]2785cb92012-02-29 20:22:091419 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]fae1ecd2012-03-03 01:10:591429 result = websocket.Close(
1430 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091431 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]fae1ecd2012-03-03 01:10:591449 result = websocket.Close(
1450 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091451 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
[email protected]fae1ecd2012-03-03 01:10:591452 result = websocket.Close(
1453 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091454 ASSERT_EQ(PP_ERROR_INPROGRESS, result);
1455 websocket.WaitForClosed();
1456 const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
[email protected]7e8ce782013-04-04 08:31:541457 ASSERT_TRUE(events.size() == 2 || events.size() == 3);
[email protected]2785cb92012-02-29 20:22:091458 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
1469std::string TestWebSocket::TestUtilityGetProtocol() {
1470 const std::string protocol("x-chat");
1471 const pp::Var protocols[] = { pp::Var(protocol) };
[email protected]bedf8742012-03-16 16:44:111472 std::string url(GetFullURL(kProtocolTestServerURL));
[email protected]2785cb92012-02-29 20:22:091473 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]2785cb92012-02-29 20:22:091488
1489 PASS();
1490}
1491
1492std::string TestWebSocket::TestUtilityTextSendReceive() {
1493 const pp::Var protocols[] = { pp::Var() };
1494 TestWebSocketAPI websocket(instance_);
1495 int32_t result =
[email protected]bedf8742012-03-16 16:44:111496 websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
[email protected]2785cb92012-02-29 20:22:091497 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
1526std::string TestWebSocket::TestUtilityBinarySendReceive() {
1527 const pp::Var protocols[] = { pp::Var() };
1528 TestWebSocketAPI websocket(instance_);
1529 int32_t result =
[email protected]bedf8742012-03-16 16:44:111530 websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
[email protected]2785cb92012-02-29 20:22:091531 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
1532 websocket.WaitForConnected();
1533
1534 // Send binary message.
[email protected]fade7dbc2012-03-13 22:48:071535 uint32_t len = 256;
1536 std::vector<uint8_t> binary(len);
[email protected]2785cb92012-02-29 20:22:091537 for (uint32_t i = 0; i < len; ++i)
[email protected]fade7dbc2012-03-13 22:48:071538 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]2785cb92012-02-29 20:22:091542 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]fade7dbc2012-03-13 22:48:071552 ASSERT_TRUE(AreEqualWithBinary(events[1].var.pp_var(), binary));
[email protected]2785cb92012-02-29 20:22:091553
1554 PASS();
1555}
1556
1557std::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]bedf8742012-03-16 16:44:111562 websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
[email protected]2785cb92012-02-29 20:22:091563 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]fade7dbc2012-03-13 22:48:071568 std::string message(8193, 'x');
[email protected]2785cb92012-02-29 20:22:091569 uint64_t buffered_amount = 0;
1570 uint32_t sent;
1571 for (sent = 0; sent < 100; sent++) {
[email protected]fade7dbc2012-03-13 22:48:071572 result = websocket.Send(pp::Var(message));
[email protected]2785cb92012-02-29 20:22:091573 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]fade7dbc2012-03-13 22:48:071581 std::string reason = "close while busy";
[email protected]fae1ecd2012-03-03 01:10:591582 result = websocket.Close(
[email protected]fade7dbc2012-03-13 22:48:071583 PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091584 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]007b3f82013-04-09 08:46:451593 result = websocket.Send(pp::Var(std::string()));
[email protected]2785cb92012-02-29 20:22:091594 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]fade7dbc2012-03-13 22:48:071599 result = websocket.Send(pp::Var(reason));
[email protected]2785cb92012-02-29 20:22:091600 ASSERT_EQ(PP_ERROR_FAILED, result);
1601 buffered_amount = websocket.GetBufferedAmount();
[email protected]fade7dbc2012-03-13 22:48:071602 uint64_t reason_frame_size = kMessageFrameOverhead + reason.length();
[email protected]2785cb92012-02-29 20:22:091603 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]fade7dbc2012-03-13 22:48:071611 ASSERT_TRUE(AreEqualWithString(events[i].var.pp_var(), message));
[email protected]2785cb92012-02-29 20:22:091612 }
1613 ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[last_event].event_type);
1614 ASSERT_TRUE(events[last_event].was_clean);
1615
1616 PASS();
1617}