| Index: ppapi/tests/test_websocket.cc
|
| diff --git a/ppapi/tests/test_websocket.cc b/ppapi/tests/test_websocket.cc
|
| index bf5c0ee15975609b8efe17376ad5c7167c3117ce..1f57d8d651d725cbaa78b0f11a2c3dbbf5e56e96 100644
|
| --- a/ppapi/tests/test_websocket.cc
|
| +++ b/ppapi/tests/test_websocket.cc
|
| @@ -5,6 +5,7 @@
|
| #include "ppapi/tests/test_websocket.h"
|
|
|
| #include <string.h>
|
| +#include <vector>
|
|
|
| #include "ppapi/c/dev/ppb_websocket_dev.h"
|
| #include "ppapi/c/pp_errors.h"
|
| @@ -12,6 +13,7 @@
|
| #include "ppapi/c/pp_completion_callback.h"
|
| #include "ppapi/c/ppb_core.h"
|
| #include "ppapi/c/ppb_var.h"
|
| +#include "ppapi/cpp/dev/websocket_dev.h"
|
| #include "ppapi/cpp/instance.h"
|
| #include "ppapi/cpp/module.h"
|
| #include "ppapi/tests/test_utils.h"
|
| @@ -33,7 +35,118 @@ const char* const kInvalidURLs[] = {
|
| // 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 = 1000;
|
| +const uint16_t kCloseCodeNormalClosure = 1000U;
|
| +
|
| +namespace {
|
| +
|
| +struct WebSocketEvent {
|
| + enum EventType {
|
| + EVENT_OPEN,
|
| + EVENT_MESSAGE,
|
| + EVENT_ERROR,
|
| + EVENT_CLOSE
|
| + };
|
| +
|
| + WebSocketEvent(
|
| + EventType type, bool was_clean, uint16_t code, const pp::Var& var)
|
| + : event_type(type),
|
| + was_clean(was_clean),
|
| + code(code),
|
| + var(var) {}
|
| + EventType event_type;
|
| + bool was_clean;
|
| + uint16_t code;
|
| + pp::Var var;
|
| +};
|
| +
|
| +class TestWebSocketClient : public pp::WebSocket_Dev {
|
| + public:
|
| + TestWebSocketClient(pp::Instance* instance)
|
| + : pp::WebSocket_Dev(instance),
|
| + connected_(false),
|
| + received_(false),
|
| + closed_(false),
|
| + wait_for_connected_(false),
|
| + wait_for_received_(false),
|
| + wait_for_closed_(false),
|
| + instance_(instance->pp_instance()) {}
|
| +
|
| + virtual void OnOpen() {
|
| + events_.push_back(WebSocketEvent(WebSocketEvent::EVENT_OPEN,
|
| + true, 0U, pp::Var()));
|
| + connected_ = true;
|
| + if (wait_for_connected_) {
|
| + GetTestingInterface()->QuitMessageLoop(instance_);
|
| + wait_for_connected_ = false;
|
| + }
|
| + }
|
| +
|
| + virtual void OnMessage(const pp::Var &message) {
|
| + events_.push_back(WebSocketEvent(WebSocketEvent::EVENT_MESSAGE,
|
| + true, 0U, message));
|
| + received_ = true;
|
| + if (wait_for_received_) {
|
| + GetTestingInterface()->QuitMessageLoop(instance_);
|
| + wait_for_received_ = false;
|
| + received_ = false;
|
| + }
|
| + }
|
| +
|
| + virtual void OnError() {
|
| + events_.push_back(WebSocketEvent(WebSocketEvent::EVENT_ERROR,
|
| + true, 0U, pp::Var()));
|
| + }
|
| +
|
| + virtual void OnClose(
|
| + bool was_clean, uint16_t code, const pp::Var& reason) {
|
| + events_.push_back(WebSocketEvent(WebSocketEvent::EVENT_CLOSE,
|
| + was_clean, code, reason));
|
| + connected_ = true;
|
| + closed_ = true;
|
| + if (wait_for_connected_ || wait_for_closed_) {
|
| + GetTestingInterface()->QuitMessageLoop(instance_);
|
| + wait_for_connected_ = false;
|
| + wait_for_closed_ = false;
|
| + }
|
| + }
|
| +
|
| + void WaitForConnected() {
|
| + if (!connected_) {
|
| + wait_for_connected_ = true;
|
| + GetTestingInterface()->RunMessageLoop(instance_);
|
| + }
|
| + }
|
| +
|
| + void WaitForReceived() {
|
| + if (!received_) {
|
| + wait_for_received_ = true;
|
| + GetTestingInterface()->RunMessageLoop(instance_);
|
| + }
|
| + }
|
| +
|
| + void WaitForClosed() {
|
| + if (!closed_) {
|
| + wait_for_closed_ = true;
|
| + GetTestingInterface()->RunMessageLoop(instance_);
|
| + }
|
| + }
|
| +
|
| + const std::vector<WebSocketEvent>& GetSeenEvents() const {
|
| + return events_;
|
| + }
|
| +
|
| + private:
|
| + std::vector<WebSocketEvent> events_;
|
| + bool connected_;
|
| + bool received_;
|
| + bool closed_;
|
| + bool wait_for_connected_;
|
| + bool wait_for_received_;
|
| + bool wait_for_closed_;
|
| + PP_Instance instance_;
|
| +};
|
| +
|
| +} // namespace
|
|
|
| REGISTER_TEST_CASE(WebSocket);
|
|
|
| @@ -60,6 +173,12 @@ void TestWebSocket::RunTests(const std::string& filter) {
|
| RUN_TEST(ValidClose, filter);
|
| RUN_TEST(GetProtocol, filter);
|
| RUN_TEST(TextSendReceive, filter);
|
| +
|
| + RUN_TEST(CcInvalidConnect, filter);
|
| + RUN_TEST(CcGetURL, filter);
|
| + RUN_TEST(CcValidConnect, filter);
|
| + RUN_TEST(CcGetProtocol, filter);
|
| + RUN_TEST(CcTextSendReceive, filter);
|
| }
|
|
|
| PP_Var TestWebSocket::CreateVar(const char* string) {
|
| @@ -95,7 +214,7 @@ PP_Resource TestWebSocket::Connect(
|
| int protocol_count = 0;
|
| if (protocol) {
|
| protocols[0] = CreateVar(protocol);
|
| - protocol_count = 1;
|
| + protocol_count = 1U;
|
| }
|
| *result = websocket_interface_->Connect(
|
| ws, url_var, protocols, protocol_count,
|
| @@ -166,12 +285,12 @@ std::string TestWebSocket::TestInvalidConnect() {
|
|
|
| TestCompletionCallback callback(instance_->pp_instance(), force_async_);
|
| int32_t result = websocket_interface_->Connect(
|
| - ws, PP_MakeUndefined(), protocols, 1,
|
| + 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, 1,
|
| + ws, PP_MakeUndefined(), protocols, 1U,
|
| static_cast<pp::CompletionCallback>(callback).pp_completion_callback());
|
| ASSERT_EQ(PP_ERROR_INPROGRESS, result);
|
|
|
| @@ -380,3 +499,106 @@ std::string TestWebSocket::TestTextSendReceive() {
|
| // TODO(toyoshim): Add tests for didReceiveMessageError().
|
|
|
| // TODO(toyoshim): Add other function tests.
|
| +
|
| +std::string TestWebSocket::TestCcInvalidConnect() {
|
| + const pp::Var protocols[] = { pp::Var() };
|
| +
|
| + TestWebSocketClient websocket(instance_);
|
| + int32_t result = websocket.Connect(pp::Var(), protocols, 1U);
|
| + ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
|
| + ASSERT_EQ(0U, websocket.GetSeenEvents().size());
|
| +
|
| + result = websocket.Connect(pp::Var(), protocols, 1U);
|
| + ASSERT_EQ(PP_ERROR_INPROGRESS, result);
|
| + ASSERT_EQ(0U, websocket.GetSeenEvents().size());
|
| +
|
| + for (int i = 0; kInvalidURLs[i]; ++i) {
|
| + TestWebSocketClient ws(instance_);
|
| + result = ws.Connect(pp::Var(std::string(kInvalidURLs[i])), protocols, 0U);
|
| + ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
|
| + ASSERT_EQ(0U, ws.GetSeenEvents().size());
|
| + }
|
| +
|
| + PASS();
|
| +}
|
| +
|
| +std::string TestWebSocket::TestCcGetURL() {
|
| + const pp::Var protocols[] = { pp::Var() };
|
| +
|
| + for (int i = 0; kInvalidURLs[i]; ++i) {
|
| + TestWebSocketClient websocket(instance_);
|
| + int32_t result = websocket.Connect(
|
| + pp::Var(std::string(kInvalidURLs[i])), protocols, 0U);
|
| + ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
|
| + pp::Var url = websocket.GetURL();
|
| + ASSERT_TRUE(AreEqual(url.pp_var(), kInvalidURLs[i]));
|
| + ASSERT_EQ(0U, websocket.GetSeenEvents().size());
|
| + }
|
| +
|
| + PASS();
|
| +}
|
| +
|
| +std::string TestWebSocket::TestCcValidConnect() {
|
| + const pp::Var protocols[] = { pp::Var() };
|
| + TestWebSocketClient websocket(instance_);
|
| + int32_t result = websocket.Connect(
|
| + pp::Var(std::string(kEchoServerURL)), protocols, 0U);
|
| + ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
|
| + websocket.WaitForConnected();
|
| + const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
|
| + ASSERT_EQ(1U, events.size());
|
| + ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
|
| +
|
| + PASS();
|
| +}
|
| +
|
| +std::string TestWebSocket::TestCcGetProtocol() {
|
| + const std::string protocol("x-chat");
|
| + const pp::Var protocols[] = { pp::Var(protocol) };
|
| + std::string url(kProtocolTestServerURL);
|
| + url += protocol;
|
| + TestWebSocketClient websocket(instance_);
|
| + int32_t result = websocket.Connect(pp::Var(url), protocols, 1U);
|
| + ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
|
| + websocket.WaitForConnected();
|
| + ASSERT_TRUE(AreEqual(websocket.GetProtocol().pp_var(), protocol.c_str()));
|
| + const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
|
| + ASSERT_EQ(1U, events.size());
|
| + ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
|
| +
|
| + PASS();
|
| +}
|
| +
|
| +std::string TestWebSocket::TestCcTextSendReceive() {
|
| + const pp::Var protocols[] = { pp::Var() };
|
| + TestWebSocketClient websocket(instance_);
|
| + int32_t result =
|
| + websocket.Connect(pp::Var(std::string(kEchoServerURL)), protocols, 0U);
|
| + ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
|
| + websocket.WaitForConnected();
|
| +
|
| + // Send 'hello pepper'.
|
| + std::string message1("hello pepper");
|
| + result = websocket.Send(pp::Var(std::string(message1)));
|
| + ASSERT_EQ(PP_OK, result);
|
| +
|
| + // Receive echoed 'hello pepper'.
|
| + websocket.WaitForReceived();
|
| +
|
| + // Send 'goodbye pepper'.
|
| + std::string message2("goodbye pepper");
|
| + result = websocket.Send(pp::Var(std::string(message2)));
|
| +
|
| + // Receive echoed 'goodbye pepper'.
|
| + websocket.WaitForReceived();
|
| +
|
| + const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
|
| + ASSERT_EQ(3U, events.size());
|
| + ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
|
| + ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type);
|
| + ASSERT_TRUE(AreEqual(events[1].var.pp_var(), message1.c_str()));
|
| + ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[2].event_type);
|
| + ASSERT_TRUE(AreEqual(events[2].var.pp_var(), message2.c_str()));
|
| +
|
| + PASS();
|
| +}
|
|
|