blob: 91f637917db016bb8be3d11f4f05e017aa293746 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/tests/test_websocket.h"
#include <string.h>
#include <vector>
#include "ppapi/c/dev/ppb_testing_dev.h"
#include "ppapi/c/dev/ppb_websocket_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/ppb_var_array_buffer.h"
#include "ppapi/cpp/dev/websocket_dev.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
const char kEchoServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/echo";
const char kCloseServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/close";
const char kProtocolTestServerURL[] =
"ws://localhost:8880/websocket/tests/hybi/protocol-test?protocol=";
const char* const kInvalidURLs[] = {
"http://www.google.com/invalid_scheme",
"ws://www.google.com/invalid#fragment",
"ws://www.google.com:65535/invalid_port",
NULL
};
// Connection close code is defined in WebSocket protocol specification.
// The magic number 1000 means gracefull closure without any error.
// See section 7.4.1. of RFC 6455.
const uint16_t kCloseCodeNormalClosure = 1000U;
// Internal packet sizes.
const uint64_t kCloseFrameSize = 6;
const uint64_t kMessageFrameOverhead = 6;
REGISTER_TEST_CASE(WebSocket);
bool TestWebSocket::Init() {
websocket_interface_ = static_cast<const PPB_WebSocket_Dev*>(
pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_DEV_INTERFACE));
var_interface_ = static_cast<const PPB_Var*>(
pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
arraybuffer_interface_ = static_cast<const PPB_VarArrayBuffer*>(
pp::Module::Get()->GetBrowserInterface(
PPB_VAR_ARRAY_BUFFER_INTERFACE));
core_interface_ = static_cast<const PPB_Core*>(
pp::Module::Get()->GetBrowserInterface(PPB_CORE_INTERFACE));
if (!websocket_interface_ || !var_interface_ || !arraybuffer_interface_ ||
!core_interface_)
return false;
return CheckTestingInterface();
}
void TestWebSocket::RunTests(const std::string& filter) {
RUN_TEST_WITH_REFERENCE_CHECK(IsWebSocket, filter);
RUN_TEST_WITH_REFERENCE_CHECK(UninitializedPropertiesAccess, filter);
RUN_TEST_WITH_REFERENCE_CHECK(InvalidConnect, filter);
RUN_TEST_WITH_REFERENCE_CHECK(Protocols, filter);
RUN_TEST_WITH_REFERENCE_CHECK(GetURL, filter);
RUN_TEST_WITH_REFERENCE_CHECK(ValidConnect, filter);
RUN_TEST_WITH_REFERENCE_CHECK(InvalidClose, filter);
RUN_TEST_WITH_REFERENCE_CHECK(ValidClose, filter);
RUN_TEST_WITH_REFERENCE_CHECK(GetProtocol, filter);
RUN_TEST_WITH_REFERENCE_CHECK(TextSendReceive, filter);
RUN_TEST_WITH_REFERENCE_CHECK(BinarySendReceive, filter);
RUN_TEST_WITH_REFERENCE_CHECK(BufferedAmount, filter);
RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter);
}
PP_Var TestWebSocket::CreateVarString(const char* string) {
return var_interface_->VarFromUtf8(string, strlen(string));
}
PP_Var TestWebSocket::CreateVarBinary(const uint8_t* data, uint32_t size) {
PP_Var var = arraybuffer_interface_->Create(size);
void* var_data = arraybuffer_interface_->Map(var);
memcpy(var_data, data, size);
return var;
}
void TestWebSocket::ReleaseVar(const PP_Var& var) {
var_interface_->Release(var);
}
bool TestWebSocket::AreEqualWithString(const PP_Var& var, const char* string) {
if (var.type != PP_VARTYPE_STRING)
return false;
uint32_t utf8_length;
const char* utf8 = var_interface_->VarToUtf8(var, &utf8_length);
uint32_t string_length = strlen(string);
if (utf8_length != string_length)
return false;
if (strncmp(utf8, string, utf8_length))
return false;
return true;
}
bool TestWebSocket::AreEqualWithBinary(const PP_Var& var,
const uint8_t* data,
uint32_t size) {
uint32_t buffer_size = 0;
PP_Bool success = arraybuffer_interface_->ByteLength(var, &buffer_size);
if (!success || buffer_size != size)
return false;
if (memcmp(arraybuffer_interface_->Map(var), data, size))
return false;
return true;
}
PP_Resource TestWebSocket::Connect(
const char* url, int32_t* result, const char* protocol) {
PP_Var protocols[] = { PP_MakeUndefined() };
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
if (!ws)
return 0;
PP_Var url_var = CreateVarString(url);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
uint32_t protocol_count = 0U;
if (protocol) {
protocols[0] = CreateVarString(protocol);
protocol_count = 1U;
}
*result = websocket_interface_->Connect(
ws, url_var, protocols, protocol_count,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ReleaseVar(url_var);
if (protocol)
ReleaseVar(protocols[0]);
if (*result == PP_OK_COMPLETIONPENDING)
*result = callback.WaitForResult();
return ws;
}
std::string TestWebSocket::TestIsWebSocket() {
// Test that a NULL resource isn't a websocket.
pp::Resource null_resource;
PP_Bool result =
websocket_interface_->IsWebSocket(null_resource.pp_resource());
ASSERT_FALSE(result);
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
result = websocket_interface_->IsWebSocket(ws);
ASSERT_TRUE(result);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestUninitializedPropertiesAccess() {
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
uint64_t bufferedAmount = websocket_interface_->GetBufferedAmount(ws);
ASSERT_EQ(0U, bufferedAmount);
uint16_t close_code = websocket_interface_->GetCloseCode(ws);
ASSERT_EQ(0U, close_code);
PP_Var close_reason = websocket_interface_->GetCloseReason(ws);
ASSERT_TRUE(AreEqualWithString(close_reason, ""));
ReleaseVar(close_reason);
PP_Bool close_was_clean = websocket_interface_->GetCloseWasClean(ws);
ASSERT_EQ(PP_FALSE, close_was_clean);
PP_Var extensions = websocket_interface_->GetExtensions(ws);
ASSERT_TRUE(AreEqualWithString(extensions, ""));
ReleaseVar(extensions);
PP_Var protocol = websocket_interface_->GetProtocol(ws);
ASSERT_TRUE(AreEqualWithString(protocol, ""));
ReleaseVar(protocol);
PP_WebSocketReadyState_Dev ready_state =
websocket_interface_->GetReadyState(ws);
ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID_DEV, ready_state);
PP_Var url = websocket_interface_->GetURL(ws);
ASSERT_TRUE(AreEqualWithString(url, ""));
ReleaseVar(url);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestInvalidConnect() {
PP_Var protocols[] = { PP_MakeUndefined() };
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t result = websocket_interface_->Connect(
ws, PP_MakeUndefined(), protocols, 1U,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
result = websocket_interface_->Connect(
ws, PP_MakeUndefined(), protocols, 1U,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_INPROGRESS, result);
core_interface_->ReleaseResource(ws);
for (int i = 0; kInvalidURLs[i]; ++i) {
ws = Connect(kInvalidURLs[i], &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
core_interface_->ReleaseResource(ws);
}
PASS();
}
std::string TestWebSocket::TestProtocols() {
PP_Var url = CreateVarString(kEchoServerURL);
PP_Var bad_protocols[] = {
CreateVarString("x-test"),
CreateVarString("x-test")
};
PP_Var good_protocols[] = {
CreateVarString("x-test"),
CreateVarString("x-yatest")
};
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
int32_t result = websocket_interface_->Connect(
ws, url, bad_protocols, 2U,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
if (result == PP_OK_COMPLETIONPENDING)
result = callback.WaitForResult();
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
core_interface_->ReleaseResource(ws);
ws = websocket_interface_->Create(instance_->pp_instance());
ASSERT_TRUE(ws);
result = websocket_interface_->Connect(
ws, url, good_protocols, 2U, PP_BlockUntilComplete());
ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, result);
core_interface_->ReleaseResource(ws);
ReleaseVar(url);
for (int i = 0; i < 2; ++i) {
ReleaseVar(bad_protocols[i]);
ReleaseVar(good_protocols[i]);
}
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestGetURL() {
for (int i = 0; kInvalidURLs[i]; ++i) {
int32_t result;
PP_Resource ws = Connect(kInvalidURLs[i], &result, NULL);
ASSERT_TRUE(ws);
PP_Var url = websocket_interface_->GetURL(ws);
ASSERT_TRUE(AreEqualWithString(url, kInvalidURLs[i]));
ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
ReleaseVar(url);
core_interface_->ReleaseResource(ws);
}
PASS();
}
std::string TestWebSocket::TestValidConnect() {
int32_t result;
PP_Resource ws = Connect(kEchoServerURL, &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestInvalidClose() {
PP_Var reason = CreateVarString("close for test");
TestCompletionCallback callback(instance_->pp_instance());
// Close before connect.
PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
int32_t result = websocket_interface_->Close(
ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_FAILED, result);
core_interface_->ReleaseResource(ws);
// Close with bad arguments.
ws = Connect(kEchoServerURL, &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
result = websocket_interface_->Close(ws, 1U, reason,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_NOACCESS, result);
core_interface_->ReleaseResource(ws);
ReleaseVar(reason);
PASS();
}
std::string TestWebSocket::TestValidClose() {
PP_Var reason = CreateVarString("close for test");
PP_Var url = CreateVarString(kEchoServerURL);
PP_Var protocols[] = { PP_MakeUndefined() };
TestCompletionCallback callback(instance_->pp_instance());
TestCompletionCallback another_callback(instance_->pp_instance());
// Close.
int32_t result;
PP_Resource ws = Connect(kEchoServerURL, &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
// Close in connecting.
// The ongoing connect failed with PP_ERROR_ABORTED, then the close is done
// successfully.
ws = websocket_interface_->Create(instance_->pp_instance());
result = websocket_interface_->Connect(ws, url, protocols, 0U,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(
another_callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = callback.WaitForResult();
ASSERT_EQ(PP_ERROR_ABORTED, result);
result = another_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
// Close in closing.
// The first close will be done successfully, then the second one failed with
// with PP_ERROR_INPROGRESS immediately.
ws = Connect(kEchoServerURL, &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(
another_callback).pp_completion_callback());
ASSERT_EQ(PP_ERROR_INPROGRESS, result);
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
// Close with ongoing receive message.
ws = Connect(kEchoServerURL, &result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
PP_Var receive_message_var;
result = websocket_interface_->ReceiveMessage(ws, &receive_message_var,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(
another_callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = callback.WaitForResult();
ASSERT_EQ(PP_ERROR_ABORTED, result);
result = another_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
core_interface_->ReleaseResource(ws);
ReleaseVar(reason);
ReleaseVar(url);
PASS();
}
std::string TestWebSocket::TestGetProtocol() {
const char* expected_protocols[] = {
"x-chat",
"hoehoe",
NULL
};
for (int i = 0; expected_protocols[i]; ++i) {
std::string url(kProtocolTestServerURL);
url += expected_protocols[i];
int32_t result;
PP_Resource ws = Connect(url.c_str(), &result, expected_protocols[i]);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, result);
PP_Var protocol = websocket_interface_->GetProtocol(ws);
ASSERT_TRUE(AreEqualWithString(protocol, expected_protocols[i]));
ReleaseVar(protocol);
core_interface_->ReleaseResource(ws);
}
PASS();
}
std::string TestWebSocket::TestTextSendReceive() {
// Connect to test echo server.
int32_t connect_result;
PP_Resource ws = Connect(kEchoServerURL, &connect_result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, connect_result);
// Send 'hello pepper' text message.
const char* message = "hello pepper";
PP_Var message_var = CreateVarString(message);
int32_t result = websocket_interface_->SendMessage(ws, message_var);
ReleaseVar(message_var);
ASSERT_EQ(PP_OK, result);
// Receive echoed 'hello pepper'.
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
PP_Var received_message;
result = websocket_interface_->ReceiveMessage(ws, &received_message,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_FALSE(result != PP_OK && result != PP_OK_COMPLETIONPENDING);
if (result == PP_OK_COMPLETIONPENDING)
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_TRUE(AreEqualWithString(received_message, message));
ReleaseVar(received_message);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestBinarySendReceive() {
// Connect to test echo server.
int32_t connect_result;
PP_Resource ws = Connect(kEchoServerURL, &connect_result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, connect_result);
// Send binary message.
uint32_t len = 256;
uint8_t data[256];
for (uint32_t i = 0; i < len; ++i)
data[i] = i;
PP_Var message_var = CreateVarBinary(data, len);
int32_t result = websocket_interface_->SendMessage(ws, message_var);
ReleaseVar(message_var);
ASSERT_EQ(PP_OK, result);
// Receive echoed binary.
TestCompletionCallback callback(instance_->pp_instance(), force_async_);
PP_Var received_message;
result = websocket_interface_->ReceiveMessage(ws, &received_message,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_TRUE(result == PP_OK || result == PP_OK_COMPLETIONPENDING);
if (result == PP_OK_COMPLETIONPENDING)
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_TRUE(AreEqualWithBinary(received_message, data, len));
ReleaseVar(received_message);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestBufferedAmount() {
// Connect to test echo server.
int32_t connect_result;
PP_Resource ws = Connect(kEchoServerURL, &connect_result, NULL);
ASSERT_TRUE(ws);
ASSERT_EQ(PP_OK, connect_result);
// Prepare a large message that is not aligned with the internal buffer
// sizes.
char message[8194];
memset(message, 'x', 8193);
message[8193] = 0;
PP_Var message_var = CreateVarString(message);
uint64_t buffered_amount = 0;
int32_t result;
for (int i = 0; i < 100; i++) {
result = websocket_interface_->SendMessage(ws, message_var);
ASSERT_EQ(PP_OK, result);
buffered_amount = websocket_interface_->GetBufferedAmount(ws);
// Buffered amount size 262144 is too big for the internal buffer size.
if (buffered_amount > 262144)
break;
}
// Close connection.
std::string reason_str = "close while busy";
PP_Var reason = CreateVarString(reason_str.c_str());
TestCompletionCallback callback(instance_->pp_instance());
result = websocket_interface_->Close(ws, kCloseCodeNormalClosure, reason,
static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING_DEV,
websocket_interface_->GetReadyState(ws));
result = callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED_DEV,
websocket_interface_->GetReadyState(ws));
uint64_t base_buffered_amount = websocket_interface_->GetBufferedAmount(ws);
// After connection closure, all sending requests fail and just increase
// the bufferedAmount property.
PP_Var empty_string = CreateVarString("");
result = websocket_interface_->SendMessage(ws, empty_string);
ASSERT_EQ(PP_ERROR_FAILED, result);
buffered_amount = websocket_interface_->GetBufferedAmount(ws);
ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount);
base_buffered_amount = buffered_amount;
result = websocket_interface_->SendMessage(ws, reason);
ASSERT_EQ(PP_ERROR_FAILED, result);
buffered_amount = websocket_interface_->GetBufferedAmount(ws);
uint64_t reason_frame_size = kMessageFrameOverhead + reason_str.length();
ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount);
ReleaseVar(message_var);
ReleaseVar(reason);
ReleaseVar(empty_string);
core_interface_->ReleaseResource(ws);
PASS();
}
std::string TestWebSocket::TestCcInterfaces() {
// C++ bindings is simple straightforward, then just verifies interfaces work
// as a interface bridge fine.
pp::WebSocket_Dev ws(instance_);
// Check uninitialized properties access.
ASSERT_EQ(0, ws.GetBufferedAmount());
ASSERT_EQ(0, ws.GetCloseCode());
ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), ""));
ASSERT_EQ(false, ws.GetCloseWasClean());
ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), ""));
ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), ""));
ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID_DEV, ws.GetReadyState());
ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), ""));
// Check communication interfaces (connect, send, receive, and close).
TestCompletionCallback connect_callback(instance_->pp_instance());
int32_t result = ws.Connect(pp::Var(std::string(kCloseServerURL)), NULL, 0U,
connect_callback);
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = connect_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
std::string text_message("hello C++");
result = ws.SendMessage(pp::Var(text_message));
ASSERT_EQ(PP_OK, result);
uint32_t binary_length = 256;
uint8_t binary_message[256];
for (uint32_t i = 0; i < binary_length; ++i)
binary_message[i] = i;
result = ws.SendMessage(pp::Var(
pp::Var::PassRef(), CreateVarBinary(binary_message, binary_length)));
ASSERT_EQ(PP_OK, result);
pp::Var text_receive_var;
TestCompletionCallback text_receive_callback(instance_->pp_instance());
result = ws.ReceiveMessage(&text_receive_var, text_receive_callback);
if (result == PP_OK_COMPLETIONPENDING)
result = text_receive_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_TRUE(
AreEqualWithString(text_receive_var.pp_var(), text_message.c_str()));
pp::Var binary_receive_var;
TestCompletionCallback binary_receive_callback(instance_->pp_instance());
result = ws.ReceiveMessage(&binary_receive_var, binary_receive_callback);
if (result == PP_OK_COMPLETIONPENDING)
result = binary_receive_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
ASSERT_TRUE(AreEqualWithBinary(
binary_receive_var.pp_var(), binary_message, binary_length));
TestCompletionCallback close_callback(instance_->pp_instance());
std::string reason("bye");
result = ws.Close(kCloseCodeNormalClosure, pp::Var(reason), close_callback);
ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
result = close_callback.WaitForResult();
ASSERT_EQ(PP_OK, result);
// Check initialized properties access.
ASSERT_EQ(0, ws.GetBufferedAmount());
ASSERT_EQ(kCloseCodeNormalClosure, ws.GetCloseCode());
ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), reason.c_str()));
ASSERT_EQ(true, ws.GetCloseWasClean());
ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), ""));
ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), ""));
ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED_DEV, ws.GetReadyState());
ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), kCloseServerURL));
PASS();
}