// 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 <stddef.h>
#include <stdio.h>
#include <string.h>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/c/ppb_var_array_buffer.h"
#include "ppapi/c/ppb_websocket.h"
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var_array_buffer.h"
#include "ppapi/cpp/websocket.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
#include "ppapi/utility/websocket/websocket_api.h"

// net::SpawnedTestServer serves WebSocket service for testing.
// Following URLs are handled by pywebsocket handlers in
// net/data/websocket/*_wsh.py.
const char kEchoServerURL[] = "echo-with-no-extension";
const char kCloseServerURL[] = "close";
const char kCloseWithCodeAndReasonServerURL[] = "close-code-and-reason";
const char kProtocolTestServerURL[] = "protocol-test?protocol=";

const char* const kInvalidURLs[] = {"http://www.google.com/invalid_scheme",
                                    "ws://www.google.com/invalid#fragment",
                                    "ws://www.google.com:7/invalid_port",
                                    NULL};

// Internal packet sizes.
const uint64_t kMessageFrameOverhead = 6;

namespace {

struct WebSocketEvent {
  enum EventType {
    EVENT_OPEN,
    EVENT_MESSAGE,
    EVENT_ERROR,
    EVENT_CLOSE
  };

  WebSocketEvent(EventType type,
                 bool was_clean,
                 uint16_t close_code,
                 const pp::Var& var)
      : event_type(type),
        was_clean(was_clean),
        close_code(close_code),
        var(var) {
  }
  EventType event_type;
  bool was_clean;
  uint16_t close_code;
  pp::Var var;
};

class ReleaseResourceDelegate : public TestCompletionCallback::Delegate {
 public:
  explicit ReleaseResourceDelegate(const PPB_Core* core_interface,
                                   PP_Resource resource)
      : core_interface_(core_interface),
        resource_(resource) {
  }

  // TestCompletionCallback::Delegate implementation.
  virtual void OnCallback(void* user_data, int32_t result) {
    if (resource_)
      core_interface_->ReleaseResource(resource_);
  }

 private:
  const PPB_Core* core_interface_;
  PP_Resource resource_;
};

class TestWebSocketAPI : public pp::WebSocketAPI {
 public:
  explicit TestWebSocketAPI(pp::Instance* instance)
      : pp::WebSocketAPI(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 WebSocketDidOpen() {
    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 WebSocketDidClose(
      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;
    }
  }

  virtual void HandleWebSocketMessage(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 HandleWebSocketError() {
    events_.push_back(
        WebSocketEvent(WebSocketEvent::EVENT_ERROR, true, 0U, pp::Var()));
  }

  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);

bool TestWebSocket::Init() {
  websocket_interface_ = static_cast<const PPB_WebSocket*>(
      pp::Module::Get()->GetBrowserInterface(PPB_WEBSOCKET_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_BACKGROUND(TestWebSocket, TextSendReceiveTwice, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(BinarySendReceive, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(StressedSendReceive, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(BufferedAmount, filter);
  // PP_Resource for WebSocket may be released later because of an internal
  // reference for asynchronous IPC handling. So, suppress reference check on
  // the following AbortCallsWithCallback test.
  RUN_TEST(AbortCallsWithCallback, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(AbortSendMessageCall, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(AbortCloseCall, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(AbortReceiveMessageCall, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(ClosedFromServerWhileSending, filter);

  RUN_TEST_WITH_REFERENCE_CHECK(CcInterfaces, filter);

  RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidConnect, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityProtocols, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetURL, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidConnect, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityInvalidClose, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityValidClose, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityGetProtocol, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityTextSendReceive, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityBinarySendReceive, filter);
  RUN_TEST_WITH_REFERENCE_CHECK(UtilityBufferedAmount, filter);
}

std::string TestWebSocket::GetFullURL(const char* url) {
  std::string rv = "ws://";
  // Some WebSocket tests don't start the server so there'll be no host and
  // port.
  if (instance_->websocket_host().empty())
    rv += "127.0.0.1";
  else
    rv += instance_->websocket_host();
  if (instance_->websocket_port() != -1) {
    char buffer[10];
    sprintf(buffer, ":%d", instance_->websocket_port());
    rv += std::string(buffer);
  }
  rv += "/";
  rv += url;
  return rv;
}

PP_Var TestWebSocket::CreateVarString(const std::string& string) {
  return var_interface_->VarFromUtf8(string.c_str(),
                                     static_cast<uint32_t>(string.size()));
}

PP_Var TestWebSocket::CreateVarBinary(const std::vector<uint8_t>& binary) {
  PP_Var var =
      arraybuffer_interface_->Create(static_cast<uint32_t>(binary.size()));
  uint8_t* var_data = static_cast<uint8_t*>(arraybuffer_interface_->Map(var));
  std::copy(binary.begin(), binary.end(), var_data);
  return var;
}

void TestWebSocket::ReleaseVar(const PP_Var& var) {
  var_interface_->Release(var);
}

bool TestWebSocket::AreEqualWithString(const PP_Var& var,
                                       const std::string& string) {
  if (var.type != PP_VARTYPE_STRING)
    return false;
  uint32_t utf8_length;
  const char* utf8 = var_interface_->VarToUtf8(var, &utf8_length);
  if (utf8_length != string.size())
    return false;
  if (string.compare(utf8))
    return false;
  return true;
}

bool TestWebSocket::AreEqualWithBinary(const PP_Var& var,
                                       const std::vector<uint8_t>& binary) {
  uint32_t buffer_size = 0;
  PP_Bool success = arraybuffer_interface_->ByteLength(var, &buffer_size);
  if (!success || buffer_size != binary.size())
    return false;
  if (!std::equal(binary.begin(), binary.end(),
      static_cast<uint8_t*>(arraybuffer_interface_->Map(var))))
    return false;
  return true;
}

PP_Resource TestWebSocket::Connect(const std::string& url,
                                   int32_t* result,
                                   const std::string& 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(), callback_type());
  uint32_t protocol_count = 0U;
  if (protocol.size()) {
    protocols[0] = CreateVarString(protocol);
    protocol_count = 1U;
  }
  callback.WaitForResult(websocket_interface_->Connect(
      ws, url_var, protocols, protocol_count,
      callback.GetCallback().pp_completion_callback()));
  ReleaseVar(url_var);
  if (protocol.size())
    ReleaseVar(protocols[0]);
  *result = callback.result();
  return ws;
}

void TestWebSocket::Send(int32_t /* result */, PP_Resource ws,
                         const std::string& message) {
  PP_Var message_var = CreateVarString(message);
  websocket_interface_->SendMessage(ws, message_var);
  ReleaseVar(message_var);
}

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, std::string()));
  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, std::string()));
  ReleaseVar(extensions);

  PP_Var protocol = websocket_interface_->GetProtocol(ws);
  ASSERT_TRUE(AreEqualWithString(protocol, std::string()));
  ReleaseVar(protocol);

  PP_WebSocketReadyState ready_state =
      websocket_interface_->GetReadyState(ws);
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ready_state);

  PP_Var url = websocket_interface_->GetURL(ws);
  ASSERT_TRUE(AreEqualWithString(url, std::string()));
  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(), callback_type());
  callback.WaitForResult(websocket_interface_->Connect(
      ws, PP_MakeUndefined(), protocols, 1U,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());

  callback.WaitForResult(websocket_interface_->Connect(
      ws, PP_MakeUndefined(), protocols, 1U,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_INPROGRESS, callback.result());

  core_interface_->ReleaseResource(ws);

  for (int i = 0; kInvalidURLs[i]; ++i) {
    int32_t result;
    ws = Connect(kInvalidURLs[i], &result, std::string());
    ASSERT_TRUE(ws);
    ASSERT_EQ(PP_ERROR_BADARGUMENT, result);

    core_interface_->ReleaseResource(ws);
  }

  PASS();
}

std::string TestWebSocket::TestProtocols() {
  PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str());
  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(), callback_type());
  callback.WaitForResult(websocket_interface_->Connect(
      ws, url, bad_protocols, 2U,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
  core_interface_->ReleaseResource(ws);

  ws = websocket_interface_->Create(instance_->pp_instance());
  ASSERT_TRUE(ws);
  int32_t 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, std::string());
    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(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  PP_Var extensions = websocket_interface_->GetExtensions(ws);
  ASSERT_TRUE(AreEqualWithString(extensions, std::string()));
  core_interface_->ReleaseResource(ws);
  ReleaseVar(extensions);

  PASS();
}

std::string TestWebSocket::TestInvalidClose() {
  PP_Var reason = CreateVarString("close for test");
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  TestCompletionCallback async_callback(instance_->pp_instance(), PP_REQUIRED);

  // Close before connect.
  PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_FAILED, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with bad arguments.
  int32_t result;
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, 1U, reason, callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_NOACCESS, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with PP_VARTYPE_NULL.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(),
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with PP_VARTYPE_NULL and ongoing receive message.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  PP_Var receive_message_var;
  result = websocket_interface_->ReceiveMessage(
      ws, &receive_message_var,
      async_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeNull(),
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
  const char* send_message = "hi";
  PP_Var send_message_var = CreateVarString(send_message);
  result = websocket_interface_->SendMessage(ws, send_message_var);
  ReleaseVar(send_message_var);
  ASSERT_EQ(PP_OK, result);
  async_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, async_callback.result());
  ASSERT_TRUE(AreEqualWithString(receive_message_var, send_message));
  ReleaseVar(receive_message_var);
  core_interface_->ReleaseResource(ws);

  // Close twice.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      async_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  // Call another Close() before previous one is in progress.
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_ERROR_INPROGRESS, result);
  async_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, async_callback.result());
  // Call another Close() after previous one is completed.
  // This Close() must do nothing and reports no error.
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_OK, callback.result());
  core_interface_->ReleaseResource(ws);

  ReleaseVar(reason);

  PASS();
}

// TODO(tyoshino): Consider splitting this test into smaller ones.
// http://crbug.com/397035
std::string TestWebSocket::TestValidClose() {
  PP_Var reason = CreateVarString("close for test");
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  TestCompletionCallback another_callback(
      instance_->pp_instance(), callback_type());

  // Close.
  int32_t result;
  PP_Resource ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close without code and reason.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED, reason,
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with PP_VARTYPE_UNDEFINED.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  callback.WaitForResult(websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(),
      callback.GetCallback().pp_completion_callback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close in CONNECTING state.
  // The ongoing Connect() fails with PP_ERROR_ABORTED, then the Close()
  // completes successfully.
  ws = websocket_interface_->Create(instance_->pp_instance());
  PP_Var url = CreateVarString(GetFullURL(kEchoServerURL).c_str());
  PP_Var protocols[] = { PP_MakeUndefined() };
  result = websocket_interface_->Connect(
      ws, url, protocols, 0U, callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      another_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
  another_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, another_callback.result());
  core_interface_->ReleaseResource(ws);
  ReleaseVar(url);

  // Close while already closing.
  // The first Close will succeed, and the second one will synchronously fail
  // with PP_ERROR_INPROGRESS.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      another_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_ERROR_INPROGRESS, result);
  callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with ongoing ReceiveMessage.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  PP_Var receive_message_var;
  result = websocket_interface_->ReceiveMessage(
      ws, &receive_message_var,
      callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      another_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
  another_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, another_callback.result());
  core_interface_->ReleaseResource(ws);

  // Close with PP_VARTYPE_UNDEFINED for reason and ongoing ReceiveMessage.
  ws = Connect(GetFullURL(kEchoServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  result = websocket_interface_->ReceiveMessage(
      ws, &receive_message_var,
      callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(),
      another_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
  another_callback.WaitForResult(PP_OK_COMPLETIONPENDING);
  ASSERT_EQ(PP_OK, another_callback.result());
  core_interface_->ReleaseResource(ws);

  // Server initiated closing handshake.
  ws = Connect(
      GetFullURL(kCloseWithCodeAndReasonServerURL), &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  // Text messsage "1000 bye" requests the server to initiate closing handshake
  // with code being 1000 and reason being "bye".
  PP_Var close_request_var = CreateVarString("1000 bye");
  result = websocket_interface_->SendMessage(ws, close_request_var);
  ReleaseVar(close_request_var);
  callback.WaitForResult(websocket_interface_->ReceiveMessage(
      ws, &receive_message_var,
      callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_ERROR_FAILED, callback.result());
  core_interface_->ReleaseResource(ws);

  ReleaseVar(reason);

  PASS();
}

std::string TestWebSocket::TestGetProtocol() {
  const char* expected_protocols[] = {
    "x-chat",
    "hoehoe",
    NULL
  };
  for (int i = 0; expected_protocols[i]; ++i) {
    std::string url(GetFullURL(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(GetFullURL(kEchoServerURL), &connect_result, std::string());
  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(), callback_type());
  PP_Var received_message;
  callback.WaitForResult(websocket_interface_->ReceiveMessage(
      ws, &received_message, callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_OK, callback.result());
  ASSERT_TRUE(AreEqualWithString(received_message, message));
  ReleaseVar(received_message);
  core_interface_->ReleaseResource(ws);

  PASS();
}

// Run as a BACKGROUND test.
std::string TestWebSocket::TestTextSendReceiveTwice() {
  // Connect to test echo server.
  int32_t connect_result;
  PP_Resource ws =
      Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, connect_result);
  pp::MessageLoop message_loop = pp::MessageLoop::GetCurrent();
  pp::CompletionCallbackFactory<TestWebSocket> factory(this);

  message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send,
                                            ws, std::string("hello")));
  // When the server receives 'Goodbye', it closes the session.
  message_loop.PostWork(factory.NewCallback(&TestWebSocket::Send,
                                            ws, std::string("Goodbye")));
  message_loop.PostQuit(false);
  message_loop.Run();

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  PP_Var received_message;
  int32_t result = websocket_interface_->ReceiveMessage(
      ws, &received_message, callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK, result);
  // Since we don't run the message loop, the callback will stay
  // "pending and scheduled to run" state.

  // Waiting for the connection close which will be done by the server.
  while (true) {
    PP_WebSocketReadyState ready_state =
        websocket_interface_->GetReadyState(ws);
    if (ready_state != PP_WEBSOCKETREADYSTATE_CONNECTING &&
        ready_state != PP_WEBSOCKETREADYSTATE_OPEN) {
      break;
    }
    PlatformSleep(100);  // 100ms
  }

  // Cleanup the message loop
  message_loop.PostQuit(false);
  message_loop.Run();

  ASSERT_EQ(PP_OK, callback.result());
  ASSERT_TRUE(AreEqualWithString(received_message, "hello"));
  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(GetFullURL(kEchoServerURL), &connect_result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, connect_result);

  // Send binary message.
  std::vector<uint8_t> binary(256);
  for (uint32_t i = 0; i < binary.size(); ++i)
    binary[i] = i;
  PP_Var message_var = CreateVarBinary(binary);
  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(), callback_type());
  PP_Var received_message;
  callback.WaitForResult(websocket_interface_->ReceiveMessage(
      ws, &received_message, callback.GetCallback().pp_completion_callback()));
  ASSERT_EQ(PP_OK, callback.result());
  ASSERT_TRUE(AreEqualWithBinary(received_message, binary));
  ReleaseVar(received_message);
  core_interface_->ReleaseResource(ws);

  PASS();
}

std::string TestWebSocket::TestStressedSendReceive() {
  // Connect to test echo server.
  int32_t connect_result;
  PP_Resource ws =
      Connect(GetFullURL(kEchoServerURL), &connect_result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, connect_result);

  // Prepare PP_Var objects to send.
  const char* text = "hello pepper";
  PP_Var text_var = CreateVarString(text);
  std::vector<uint8_t> binary(256);
  for (uint32_t i = 0; i < binary.size(); ++i)
    binary[i] = i;
  PP_Var binary_var = CreateVarBinary(binary);
  // Prepare very large binary data over 64KiB. Object serializer in
  // ppapi_proxy has a limitation of 64KiB as maximum return PP_Var data size
  // to SRPC. In case received data over 64KiB exists, a specific code handles
  // this large data via asynchronous callback from main thread. This data
  // intends to test the code.
  std::vector<uint8_t> large_binary(65 * 1024);
  for (uint32_t i = 0; i < large_binary.size(); ++i)
    large_binary[i] = i & 0xff;
  PP_Var large_binary_var = CreateVarBinary(large_binary);

  // Send many messages.
  int32_t result;
  for (int i = 0; i < 256; ++i) {
    result = websocket_interface_->SendMessage(ws, text_var);
    ASSERT_EQ(PP_OK, result);
    result = websocket_interface_->SendMessage(ws, binary_var);
    ASSERT_EQ(PP_OK, result);
  }
  result = websocket_interface_->SendMessage(ws, large_binary_var);
  ASSERT_EQ(PP_OK, result);
  ReleaseVar(text_var);
  ReleaseVar(binary_var);
  ReleaseVar(large_binary_var);

  // Receive echoed data.
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  for (int i = 0; i <= 512; ++i) {
    PP_Var received_message;
    callback.WaitForResult(websocket_interface_->ReceiveMessage(
        ws, &received_message,
        callback.GetCallback().pp_completion_callback()));
    ASSERT_EQ(PP_OK, callback.result());
    if (i == 512) {
      ASSERT_TRUE(AreEqualWithBinary(received_message, large_binary));
    } else if (i & 1) {
      ASSERT_TRUE(AreEqualWithBinary(received_message, binary));
    } else {
      ASSERT_TRUE(AreEqualWithString(received_message, text));
    }
    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(GetFullURL(kEchoServerURL), &connect_result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, connect_result);

  // Prepare a large message that is not aligned with the internal buffer
  // sizes.
  std::string message(8193, 'x');
  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(), callback_type());
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason,
      callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING,
      websocket_interface_->GetReadyState(ws));

  callback.WaitForResult(result);
  ASSERT_EQ(PP_OK, callback.result());
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED,
      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(std::string());
  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();
}

// Test abort behaviors where a WebSocket PP_Resource is released while each
// function is in-flight on the WebSocket PP_Resource.
std::string TestWebSocket::TestAbortCallsWithCallback() {
  // Following tests make sure the behavior for functions which require a
  // callback. The callback must get a PP_ERROR_ABORTED.

  // Test the behavior for Connect().
  PP_Resource ws = websocket_interface_->Create(instance_->pp_instance());
  ASSERT_TRUE(ws);
  std::string url = GetFullURL(kEchoServerURL);
  PP_Var url_var = CreateVarString(url);
  TestCompletionCallback connect_callback(
      instance_->pp_instance(), callback_type());
  int32_t result = websocket_interface_->Connect(
      ws, url_var, NULL, 0,
      connect_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  core_interface_->ReleaseResource(ws);
  connect_callback.WaitForResult(result);
  ASSERT_EQ(PP_ERROR_ABORTED, connect_callback.result());

  // Test the behavior for Close().
  ws = Connect(url, &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  PP_Var reason_var = CreateVarString("abort");
  TestCompletionCallback close_callback(
      instance_->pp_instance(), callback_type());
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason_var,
      close_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  core_interface_->ReleaseResource(ws);
  close_callback.WaitForResult(result);
  ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result());
  ReleaseVar(reason_var);

  // Test the behavior for ReceiveMessage().
  // Make sure the simplest case to wait for data which never arrives, here.
  ws = Connect(url, &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  PP_Var receive_var;
  TestCompletionCallback receive_callback(
      instance_->pp_instance(), callback_type());
  result = websocket_interface_->ReceiveMessage(
      ws, &receive_var,
      receive_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  core_interface_->ReleaseResource(ws);
  receive_callback.WaitForResult(result);
  ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result());

  // Release the resource in the aborting receive completion callback which is
  // introduced by calling Close().
  ws = Connect(url, &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  result = websocket_interface_->ReceiveMessage(
      ws, &receive_var,
      receive_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  ReleaseResourceDelegate receive_delegate(core_interface_, ws);
  receive_callback.SetDelegate(&receive_delegate);
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(),
      close_callback.GetCallback().pp_completion_callback());
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  receive_callback.WaitForResult(result);
  CHECK_CALLBACK_BEHAVIOR(receive_callback);
  ASSERT_EQ(PP_ERROR_ABORTED, receive_callback.result());
  close_callback.WaitForResult(result);
  CHECK_CALLBACK_BEHAVIOR(close_callback);
  ASSERT_EQ(PP_ERROR_ABORTED, close_callback.result());

  ReleaseVar(url_var);

  PASS();
}

std::string TestWebSocket::TestAbortSendMessageCall() {
  // Test the behavior for SendMessage().
  // This function doesn't require a callback, but operation will be done
  // asynchronously in WebKit and browser process.
  std::vector<uint8_t> large_binary(65 * 1024);
  PP_Var large_var = CreateVarBinary(large_binary);

  int32_t result;
  std::string url = GetFullURL(kEchoServerURL);
  PP_Resource ws = Connect(url, &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  result = websocket_interface_->SendMessage(ws, large_var);
  ASSERT_EQ(PP_OK, result);
  core_interface_->ReleaseResource(ws);
  ReleaseVar(large_var);

  PASS();
}

std::string TestWebSocket::TestAbortCloseCall() {
  // Release the resource in the close completion callback.
  int32_t result;
  std::string url = GetFullURL(kEchoServerURL);
  PP_Resource ws = Connect(url, &result, std::string());
  ASSERT_TRUE(ws);
  ASSERT_EQ(PP_OK, result);
  TestCompletionCallback close_callback(
      instance_->pp_instance(), callback_type());
  result = websocket_interface_->Close(
      ws, PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, PP_MakeUndefined(),
      close_callback.GetCallback().pp_completion_callback());
  ReleaseResourceDelegate close_delegate(core_interface_, ws);
  close_callback.SetDelegate(&close_delegate);
  close_callback.WaitForResult(result);
  CHECK_CALLBACK_BEHAVIOR(close_callback);
  ASSERT_EQ(PP_OK, close_callback.result());

  PASS();
}

std::string TestWebSocket::TestAbortReceiveMessageCall() {
  // Test the behavior where receive process might be in-flight.
  std::vector<uint8_t> large_binary(65 * 1024);
  PP_Var large_var = CreateVarBinary(large_binary);
  const char* text = "yukarin";
  PP_Var text_var = CreateVarString(text);

  std::string url = GetFullURL(kEchoServerURL);
  int32_t result;
  PP_Resource ws;

  // Each trial sends |trial_count| + 1 messages and receives just |trial|
  // number of message(s) before releasing the WebSocket. The WebSocket is
  // released while the next message is going to be received.
  const int trial_count = 8;
  for (int trial = 1; trial <= trial_count; trial++) {
    ws = Connect(url, &result, std::string());
    ASSERT_TRUE(ws);
    ASSERT_EQ(PP_OK, result);
    for (int i = 0; i <= trial_count; ++i) {
      result = websocket_interface_->SendMessage(ws, text_var);
      ASSERT_EQ(PP_OK, result);
    }
    TestCompletionCallback callback(instance_->pp_instance(), callback_type());
    PP_Var var;
    for (int i = 0; i < trial; ++i) {
      callback.WaitForResult(websocket_interface_->ReceiveMessage(
          ws, &var, callback.GetCallback().pp_completion_callback()));
      ASSERT_EQ(PP_OK, callback.result());
      ASSERT_TRUE(AreEqualWithString(var, text));
      ReleaseVar(var);
    }
    result = websocket_interface_->ReceiveMessage(
        ws, &var, callback.GetCallback().pp_completion_callback());
    core_interface_->ReleaseResource(ws);
    if (result != PP_OK) {
      callback.WaitForResult(result);
      ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
    }
  }
  // Same test, but the last receiving message is large message over 64KiB.
  for (int trial = 1; trial <= trial_count; trial++) {
    ws = Connect(url, &result, std::string());
    ASSERT_TRUE(ws);
    ASSERT_EQ(PP_OK, result);
    for (int i = 0; i <= trial_count; ++i) {
      if (i == trial)
        result = websocket_interface_->SendMessage(ws, large_var);
      else
        result = websocket_interface_->SendMessage(ws, text_var);
      ASSERT_EQ(PP_OK, result);
    }
    TestCompletionCallback callback(instance_->pp_instance(), callback_type());
    PP_Var var;
    for (int i = 0; i < trial; ++i) {
      callback.WaitForResult(websocket_interface_->ReceiveMessage(
          ws, &var, callback.GetCallback().pp_completion_callback()));
      ASSERT_EQ(PP_OK, callback.result());
      ASSERT_TRUE(AreEqualWithString(var, text));
      ReleaseVar(var);
    }
    result = websocket_interface_->ReceiveMessage(
        ws, &var, callback.GetCallback().pp_completion_callback());
    core_interface_->ReleaseResource(ws);
    if (result != PP_OK) {
      callback.WaitForResult(result);
      ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
    }
  }

  ReleaseVar(large_var);
  ReleaseVar(text_var);

  PASS();
}

std::string TestWebSocket::TestClosedFromServerWhileSending() {
  // Connect to test echo server.
  const pp::Var protocols[] = { pp::Var() };
  TestWebSocketAPI websocket(instance_);
  int32_t result =
      websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  websocket.WaitForConnected();

  result = websocket.Send(pp::Var("hello"));
  ASSERT_EQ(PP_OK, result);
  result = websocket.Send(pp::Var("Goodbye"));
  // We send many messages so that PepperWebSocketHost::SendText is called
  // after PepperWebSocketHost::didClose is called.
  // Note: We must not wait for CLOSED event here because
  // WebSocketResource::SendMessage doesn't call PepperWebSocketHost::SendText
  // when its internal state is CLOSING or CLOSED. We want to test if the
  // pepper WebSocket works well when WebSocketResource is OPEN and
  // PepperWebSocketHost is CLOSED.
  for (size_t i = 0; i < 10000; ++i) {
    result = websocket.Send(pp::Var(""));
    ASSERT_EQ(PP_OK, result);
  }

  PASS();
}

std::string TestWebSocket::TestCcInterfaces() {
  // C++ bindings is simple straightforward, then just verifies interfaces work
  // as a interface bridge fine.
  pp::WebSocket ws(instance_);

  // Check uninitialized properties access.
  ASSERT_EQ(0, ws.GetBufferedAmount());
  ASSERT_EQ(0, ws.GetCloseCode());
  ASSERT_TRUE(AreEqualWithString(ws.GetCloseReason().pp_var(), std::string()));
  ASSERT_FALSE(ws.GetCloseWasClean());
  ASSERT_TRUE(AreEqualWithString(ws.GetExtensions().pp_var(), std::string()));
  ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string()));
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_INVALID, ws.GetReadyState());
  ASSERT_TRUE(AreEqualWithString(ws.GetURL().pp_var(), std::string()));

  // Check communication interfaces (connect, send, receive, and close).
  TestCompletionCallback connect_callback(
      instance_->pp_instance(), callback_type());
  connect_callback.WaitForResult(ws.Connect(
      pp::Var(GetFullURL(kCloseServerURL)), NULL, 0U,
              connect_callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(connect_callback);
  ASSERT_EQ(PP_OK, connect_callback.result());

  std::string text_message("hello C++");
  int32_t result = ws.SendMessage(pp::Var(text_message));
  ASSERT_EQ(PP_OK, result);

  std::vector<uint8_t> binary(256);
  for (uint32_t i = 0; i < binary.size(); ++i)
    binary[i] = i;
  result = ws.SendMessage(
      pp::Var(pp::PASS_REF, CreateVarBinary(binary)));
  ASSERT_EQ(PP_OK, result);

  pp::Var text_receive_var;
  TestCompletionCallback text_receive_callback(
      instance_->pp_instance(), callback_type());
  text_receive_callback.WaitForResult(
      ws.ReceiveMessage(&text_receive_var,
                        text_receive_callback.GetCallback()));
  ASSERT_EQ(PP_OK, text_receive_callback.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(), callback_type());
  binary_receive_callback.WaitForResult(
      ws.ReceiveMessage(&binary_receive_var,
                        binary_receive_callback.GetCallback()));
  ASSERT_EQ(PP_OK, binary_receive_callback.result());
  ASSERT_TRUE(AreEqualWithBinary(binary_receive_var.pp_var(), binary));

  TestCompletionCallback close_callback(
      instance_->pp_instance(), callback_type());
  std::string reason("bye");
  close_callback.WaitForResult(ws.Close(
      PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason),
      close_callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(close_callback);
  ASSERT_EQ(PP_OK, close_callback.result());

  // Check initialized properties access.
  ASSERT_EQ(0, ws.GetBufferedAmount());
  ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, ws.GetCloseCode());
  ASSERT_TRUE(
      AreEqualWithString(ws.GetCloseReason().pp_var(), reason.c_str()));
  ASSERT_EQ(true, ws.GetCloseWasClean());
  ASSERT_TRUE(AreEqualWithString(ws.GetProtocol().pp_var(), std::string()));
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, ws.GetReadyState());
  ASSERT_TRUE(AreEqualWithString(
      ws.GetURL().pp_var(), GetFullURL(kCloseServerURL).c_str()));

  PASS();
}

std::string TestWebSocket::TestUtilityInvalidConnect() {
  const pp::Var protocols[] = { pp::Var() };

  TestWebSocketAPI 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) {
    TestWebSocketAPI ws(instance_);
    result = ws.Connect(pp::Var(std::string(kInvalidURLs[i])), protocols, 0U);
    if (result == PP_OK_COMPLETIONPENDING) {
      ws.WaitForClosed();
      const std::vector<WebSocketEvent>& events = ws.GetSeenEvents();
      ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type);
      ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type);
      ASSERT_EQ(2U, ws.GetSeenEvents().size());
    } else {
      ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
      ASSERT_EQ(0U, ws.GetSeenEvents().size());
    }
  }

  PASS();
}

std::string TestWebSocket::TestUtilityProtocols() {
  const pp::Var bad_protocols[] = {
      pp::Var(std::string("x-test")), pp::Var(std::string("x-test")) };
  const pp::Var good_protocols[] = {
      pp::Var(std::string("x-test")), pp::Var(std::string("x-yatest")) };

  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(
        pp::Var(GetFullURL(kEchoServerURL)), bad_protocols, 2U);
    ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
    ASSERT_EQ(0U, websocket.GetSeenEvents().size());
  }

  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(
        pp::Var(GetFullURL(kEchoServerURL)), good_protocols, 2U);
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    websocket.WaitForConnected();
    const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
    // Protocol arguments are valid, but this test run without a WebSocket
    // server. As a result, OnError() and OnClose() are invoked because of
    // a connection establishment failure.
    ASSERT_EQ(2U, events.size());
    ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type);
    ASSERT_FALSE(events[1].was_clean);
  }

  PASS();
}

std::string TestWebSocket::TestUtilityGetURL() {
  const pp::Var protocols[] = { pp::Var() };

  for (int i = 0; kInvalidURLs[i]; ++i) {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(
        pp::Var(std::string(kInvalidURLs[i])), protocols, 0U);
    if (result == PP_OK_COMPLETIONPENDING) {
      websocket.WaitForClosed();
      const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
      ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[0].event_type);
      ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type);
      ASSERT_EQ(2U, events.size());
    } else {
      ASSERT_EQ(PP_ERROR_BADARGUMENT, result);
      ASSERT_EQ(0U, websocket.GetSeenEvents().size());
    }
    pp::Var url = websocket.GetURL();
    ASSERT_TRUE(AreEqualWithString(url.pp_var(), kInvalidURLs[i]));
  }

  PASS();
}

std::string TestWebSocket::TestUtilityValidConnect() {
  const pp::Var protocols[] = { pp::Var() };
  TestWebSocketAPI websocket(instance_);
  int32_t result = websocket.Connect(
      pp::Var(GetFullURL(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);
  ASSERT_TRUE(
      AreEqualWithString(websocket.GetExtensions().pp_var(), std::string()));

  PASS();
}

std::string TestWebSocket::TestUtilityInvalidClose() {
  const pp::Var reason = pp::Var(std::string("close for test"));

  // Close before connect.
  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Close(
        PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, reason);
    ASSERT_EQ(PP_ERROR_FAILED, result);
    ASSERT_EQ(0U, websocket.GetSeenEvents().size());
  }

  // Close with bad arguments.
  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)),
        NULL, 0);
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    websocket.WaitForConnected();
    result = websocket.Close(1U, reason);
    ASSERT_EQ(PP_ERROR_NOACCESS, result);
    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::TestUtilityValidClose() {
  std::string reason("close for test");
  pp::Var url = pp::Var(GetFullURL(kCloseServerURL));

  // Close.
  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(url, NULL, 0U);
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    websocket.WaitForConnected();
    result = websocket.Close(
        PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    websocket.WaitForClosed();
    const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
    ASSERT_EQ(2U, events.size());
    ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[1].event_type);
    ASSERT_TRUE(events[1].was_clean);
    ASSERT_EQ(PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, events[1].close_code);
    ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), reason.c_str()));
  }

  // Close in connecting.
  // The ongoing connect failed with PP_ERROR_ABORTED, then the close is done
  // successfully.
  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(url, NULL, 0U);
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    result = websocket.Close(
        PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    websocket.WaitForClosed();
    const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
    ASSERT_TRUE(events.size() == 2 || events.size() == 3);
    int index = 0;
    if (events.size() == 3)
      ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type);
    ASSERT_FALSE(events[index].was_clean);
  }

  // Close in closing.
  // The first close will be done successfully, then the second one failed with
  // with PP_ERROR_INPROGRESS immediately.
  {
    TestWebSocketAPI websocket(instance_);
    int32_t result = websocket.Connect(url, NULL, 0U);
    result = websocket.Close(
        PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
    ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
    result = websocket.Close(
        PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
    ASSERT_EQ(PP_ERROR_INPROGRESS, result);
    websocket.WaitForClosed();
    const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
    ASSERT_TRUE(events.size() == 2 || events.size() == 3);
    int index = 0;
    if (events.size() == 3)
      ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[index++].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_ERROR, events[index++].event_type);
    ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[index].event_type);
    ASSERT_FALSE(events[index].was_clean);
  }

  PASS();
}

std::string TestWebSocket::TestUtilityGetProtocol() {
  const std::string protocol("x-chat");
  const pp::Var protocols[] = { pp::Var(protocol) };
  std::string url(GetFullURL(kProtocolTestServerURL));
  url += protocol;
  TestWebSocketAPI websocket(instance_);
  int32_t result = websocket.Connect(pp::Var(url), protocols, 1U);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  websocket.WaitForReceived();
  ASSERT_TRUE(AreEqualWithString(
      websocket.GetProtocol().pp_var(), protocol.c_str()));
  const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
  // The server to which this test connect returns the decided protocol as a
  // text frame message. So the WebSocketEvent records EVENT_MESSAGE event
  // after EVENT_OPEN event.
  ASSERT_EQ(2U, events.size());
  ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
  ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type);
  ASSERT_TRUE(AreEqualWithString(events[1].var.pp_var(), protocol.c_str()));

  PASS();
}

std::string TestWebSocket::TestUtilityTextSendReceive() {
  const pp::Var protocols[] = { pp::Var() };
  TestWebSocketAPI websocket(instance_);
  int32_t result =
      websocket.Connect(pp::Var(GetFullURL(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(AreEqualWithString(events[1].var.pp_var(), message1.c_str()));
  ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[2].event_type);
  ASSERT_TRUE(AreEqualWithString(events[2].var.pp_var(), message2.c_str()));

  PASS();
}

std::string TestWebSocket::TestUtilityBinarySendReceive() {
  const pp::Var protocols[] = { pp::Var() };
  TestWebSocketAPI websocket(instance_);
  int32_t result =
      websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  websocket.WaitForConnected();

  // Send binary message.
  uint32_t len = 256;
  std::vector<uint8_t> binary(len);
  for (uint32_t i = 0; i < len; ++i)
    binary[i] = i;
  pp::VarArrayBuffer message(len);
  uint8_t* var_data = static_cast<uint8_t*>(message.Map());
  std::copy(binary.begin(), binary.end(), var_data);
  result = websocket.Send(message);
  ASSERT_EQ(PP_OK, result);

  // Receive echoed binary message.
  websocket.WaitForReceived();

  const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
  ASSERT_EQ(2U, events.size());
  ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
  ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[1].event_type);
  ASSERT_TRUE(AreEqualWithBinary(events[1].var.pp_var(), binary));

  PASS();
}

std::string TestWebSocket::TestUtilityBufferedAmount() {
  // Connect to test echo server.
  const pp::Var protocols[] = { pp::Var() };
  TestWebSocketAPI websocket(instance_);
  int32_t result =
      websocket.Connect(pp::Var(GetFullURL(kEchoServerURL)), protocols, 0U);
  ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
  websocket.WaitForConnected();

  // Prepare a large message that is not aligned with the internal buffer
  // sizes.
  std::string message(8193, 'x');
  uint64_t buffered_amount = 0;
  uint32_t sent;
  for (sent = 0; sent < 100; sent++) {
    result = websocket.Send(pp::Var(message));
    ASSERT_EQ(PP_OK, result);
    buffered_amount = websocket.GetBufferedAmount();
    // Buffered amount size 262144 is too big for the internal buffer size.
    if (buffered_amount > 262144)
      break;
  }

  // Close connection.
  std::string reason = "close while busy";
  result = websocket.Close(
      PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE, pp::Var(reason));
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSING, websocket.GetReadyState());
  websocket.WaitForClosed();
  ASSERT_EQ(PP_WEBSOCKETREADYSTATE_CLOSED, websocket.GetReadyState());

  uint64_t base_buffered_amount = websocket.GetBufferedAmount();
  size_t events_on_closed = websocket.GetSeenEvents().size();

  // After connection closure, all sending requests fail and just increase
  // the bufferedAmount property.
  result = websocket.Send(pp::Var(std::string()));
  ASSERT_EQ(PP_ERROR_FAILED, result);
  buffered_amount = websocket.GetBufferedAmount();
  ASSERT_EQ(base_buffered_amount + kMessageFrameOverhead, buffered_amount);
  base_buffered_amount = buffered_amount;

  result = websocket.Send(pp::Var(reason));
  ASSERT_EQ(PP_ERROR_FAILED, result);
  buffered_amount = websocket.GetBufferedAmount();
  uint64_t reason_frame_size = kMessageFrameOverhead + reason.length();
  ASSERT_EQ(base_buffered_amount + reason_frame_size, buffered_amount);

  const std::vector<WebSocketEvent>& events = websocket.GetSeenEvents();
  ASSERT_EQ(events_on_closed, events.size());
  ASSERT_EQ(WebSocketEvent::EVENT_OPEN, events[0].event_type);
  size_t last_event = events_on_closed - 1;
  for (uint32_t i = 1; i < last_event; ++i) {
    ASSERT_EQ(WebSocketEvent::EVENT_MESSAGE, events[i].event_type);
    ASSERT_TRUE(AreEqualWithString(events[i].var.pp_var(), message));
  }
  ASSERT_EQ(WebSocketEvent::EVENT_CLOSE, events[last_event].event_type);
  ASSERT_TRUE(events[last_event].was_clean);

  PASS();
}
