// 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:65535/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();
}
