// 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 "jingle/glue/chrome_async_socket.h"

#include <deque>
#include <string>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_default.h"
#include "jingle/glue/resolving_client_socket_factory.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/http/transport_security_state.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket.h"
#include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/base/ipaddress.h"
#include "third_party/webrtc/base/sigslot.h"
#include "third_party/webrtc/base/socketaddress.h"

namespace jingle_glue {

namespace {

// Data provider that handles reads/writes for ChromeAsyncSocket.
class AsyncSocketDataProvider : public net::SocketDataProvider {
 public:
  AsyncSocketDataProvider() : has_pending_read_(false) {}

  ~AsyncSocketDataProvider() override {
    EXPECT_TRUE(writes_.empty());
    EXPECT_TRUE(reads_.empty());
  }

  // If there's no read, sets the "has pending read" flag.  Otherwise,
  // pops the next read.
  net::MockRead GetNextRead() override {
    if (reads_.empty()) {
      DCHECK(!has_pending_read_);
      has_pending_read_ = true;
      const net::MockRead pending_read(net::SYNCHRONOUS, net::ERR_IO_PENDING);
      return pending_read;
    }
    net::MockRead mock_read = reads_.front();
    reads_.pop_front();
    return mock_read;
  }

  // Simply pops the next write and, if applicable, compares it to
  // |data|.
  net::MockWriteResult OnWrite(const std::string& data) override {
    DCHECK(!writes_.empty());
    net::MockWrite mock_write = writes_.front();
    writes_.pop_front();
    if (mock_write.result != net::OK) {
      return net::MockWriteResult(mock_write.mode, mock_write.result);
    }
    std::string expected_data(mock_write.data, mock_write.data_len);
    EXPECT_EQ(expected_data, data);
    if (expected_data != data) {
      return net::MockWriteResult(net::SYNCHRONOUS, net::ERR_UNEXPECTED);
    }
    return net::MockWriteResult(mock_write.mode, data.size());
  }

  // We ignore resets so we can pre-load the socket data provider with
  // read/write events.
  void Reset() override {}

  // If there is a pending read, completes it with the given read.
  // Otherwise, queues up the given read.
  void AddRead(const net::MockRead& mock_read) {
    DCHECK_NE(mock_read.result, net::ERR_IO_PENDING);
    if (has_pending_read_) {
      socket()->OnReadComplete(mock_read);
      has_pending_read_ = false;
      return;
    }
    reads_.push_back(mock_read);
  }

  // Simply queues up the given write.
  void AddWrite(const net::MockWrite& mock_write) {
    writes_.push_back(mock_write);
  }

 private:
  std::deque<net::MockRead> reads_;
  bool has_pending_read_;

  std::deque<net::MockWrite> writes_;

  DISALLOW_COPY_AND_ASSIGN(AsyncSocketDataProvider);
};

class MockXmppClientSocketFactory : public ResolvingClientSocketFactory {
 public:
  MockXmppClientSocketFactory(
      net::ClientSocketFactory* mock_client_socket_factory,
      const net::AddressList& address_list)
          : mock_client_socket_factory_(mock_client_socket_factory),
            address_list_(address_list),
            cert_verifier_(new net::MockCertVerifier),
            transport_security_state_(new net::TransportSecurityState) {
  }

  // ResolvingClientSocketFactory implementation.
  scoped_ptr<net::StreamSocket> CreateTransportClientSocket(
      const net::HostPortPair& host_and_port) override {
    return mock_client_socket_factory_->CreateTransportClientSocket(
        address_list_, NULL, net::NetLog::Source());
  }

  scoped_ptr<net::SSLClientSocket> CreateSSLClientSocket(
      scoped_ptr<net::ClientSocketHandle> transport_socket,
      const net::HostPortPair& host_and_port) override {
    net::SSLClientSocketContext context;
    context.cert_verifier = cert_verifier_.get();
    context.transport_security_state = transport_security_state_.get();
    return mock_client_socket_factory_->CreateSSLClientSocket(
        transport_socket.Pass(), host_and_port, ssl_config_, context);
  }

 private:
  scoped_ptr<net::ClientSocketFactory> mock_client_socket_factory_;
  net::AddressList address_list_;
  net::SSLConfig ssl_config_;
  scoped_ptr<net::CertVerifier> cert_verifier_;
  scoped_ptr<net::TransportSecurityState> transport_security_state_;
};

class ChromeAsyncSocketTest
    : public testing::Test,
      public sigslot::has_slots<> {
 protected:
  ChromeAsyncSocketTest()
      : ssl_socket_data_provider_(net::ASYNC, net::OK),
        addr_("localhost", 35) {
    // GTest death tests execute in a fork()ed but not exec()ed process.
    // On OS X a CoreFoundation-backed message loop will exit with a
    // __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__
    // when called.
    // Explicitly create a MessagePumpDefault which can run in this enivronment.
    scoped_ptr<base::MessagePump> pump(new base::MessagePumpDefault());
    message_loop_.reset(new base::MessageLoop(pump.Pass()));
  }

  ~ChromeAsyncSocketTest() override {}

  void SetUp() override {
    scoped_ptr<net::MockClientSocketFactory> mock_client_socket_factory(
        new net::MockClientSocketFactory());
    mock_client_socket_factory->AddSocketDataProvider(
        &async_socket_data_provider_);
    mock_client_socket_factory->AddSSLSocketDataProvider(
        &ssl_socket_data_provider_);

    // Fake DNS resolution for |addr_| and pass it to the factory.
    net::IPAddressNumber resolved_addr;
    EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &resolved_addr));
    const net::AddressList address_list =
        net::AddressList::CreateFromIPAddress(resolved_addr, addr_.port());
    scoped_ptr<MockXmppClientSocketFactory> mock_xmpp_client_socket_factory(
        new MockXmppClientSocketFactory(
            mock_client_socket_factory.release(),
            address_list));
    chrome_async_socket_.reset(
        new ChromeAsyncSocket(mock_xmpp_client_socket_factory.release(),
                              14, 20)),

    chrome_async_socket_->SignalConnected.connect(
        this, &ChromeAsyncSocketTest::OnConnect);
    chrome_async_socket_->SignalSSLConnected.connect(
        this, &ChromeAsyncSocketTest::OnSSLConnect);
    chrome_async_socket_->SignalClosed.connect(
        this, &ChromeAsyncSocketTest::OnClose);
    chrome_async_socket_->SignalRead.connect(
        this, &ChromeAsyncSocketTest::OnRead);
    chrome_async_socket_->SignalError.connect(
        this, &ChromeAsyncSocketTest::OnError);
  }

  void TearDown() override {
    // Run any tasks that we forgot to pump.
    message_loop_->RunUntilIdle();
    ExpectClosed();
    ExpectNoSignal();
    chrome_async_socket_.reset();
  }

  enum Signal {
    SIGNAL_CONNECT,
    SIGNAL_SSL_CONNECT,
    SIGNAL_CLOSE,
    SIGNAL_READ,
    SIGNAL_ERROR,
  };

  // Helper struct that records the state at the time of a signal.

  struct SignalSocketState {
    SignalSocketState()
        : signal(SIGNAL_ERROR),
          state(ChromeAsyncSocket::STATE_CLOSED),
          error(ChromeAsyncSocket::ERROR_NONE),
          net_error(net::OK) {}

    SignalSocketState(
        Signal signal,
        ChromeAsyncSocket::State state,
        ChromeAsyncSocket::Error error,
        net::Error net_error)
        : signal(signal),
          state(state),
          error(error),
          net_error(net_error) {}

    bool IsEqual(const SignalSocketState& other) const {
      return
          (signal == other.signal) &&
          (state == other.state) &&
          (error == other.error) &&
          (net_error == other.net_error);
    }

    static SignalSocketState FromAsyncSocket(
        Signal signal,
        buzz::AsyncSocket* async_socket) {
      return SignalSocketState(signal,
                               async_socket->state(),
                               async_socket->error(),
                               static_cast<net::Error>(
                                   async_socket->GetError()));
    }

    static SignalSocketState NoError(
        Signal signal, buzz::AsyncSocket::State state) {
        return SignalSocketState(signal, state,
                                 buzz::AsyncSocket::ERROR_NONE,
                                 net::OK);
    }

    Signal signal;
    ChromeAsyncSocket::State state;
    ChromeAsyncSocket::Error error;
    net::Error net_error;
  };

  void CaptureSocketState(Signal signal) {
    signal_socket_states_.push_back(
        SignalSocketState::FromAsyncSocket(
            signal, chrome_async_socket_.get()));
  }

  void OnConnect() {
    CaptureSocketState(SIGNAL_CONNECT);
  }

  void OnSSLConnect() {
    CaptureSocketState(SIGNAL_SSL_CONNECT);
  }

  void OnClose() {
    CaptureSocketState(SIGNAL_CLOSE);
  }

  void OnRead() {
    CaptureSocketState(SIGNAL_READ);
  }

  void OnError() {
    ADD_FAILURE();
  }

  // State expect functions.

  void ExpectState(ChromeAsyncSocket::State state,
                   ChromeAsyncSocket::Error error,
                   net::Error net_error) {
    EXPECT_EQ(state, chrome_async_socket_->state());
    EXPECT_EQ(error, chrome_async_socket_->error());
    EXPECT_EQ(net_error, chrome_async_socket_->GetError());
  }

  void ExpectNonErrorState(ChromeAsyncSocket::State state) {
    ExpectState(state, ChromeAsyncSocket::ERROR_NONE, net::OK);
  }

  void ExpectErrorState(ChromeAsyncSocket::State state,
                        ChromeAsyncSocket::Error error) {
    ExpectState(state, error, net::OK);
  }

  void ExpectClosed() {
    ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED);
  }

  // Signal expect functions.

  void ExpectNoSignal() {
    if (!signal_socket_states_.empty()) {
      ADD_FAILURE() << signal_socket_states_.front().signal;
    }
  }

  void ExpectSignalSocketState(
      SignalSocketState expected_signal_socket_state) {
    if (signal_socket_states_.empty()) {
      ADD_FAILURE() << expected_signal_socket_state.signal;
      return;
    }
    EXPECT_TRUE(expected_signal_socket_state.IsEqual(
        signal_socket_states_.front()))
        << signal_socket_states_.front().signal;
    signal_socket_states_.pop_front();
  }

  void ExpectReadSignal() {
    ExpectSignalSocketState(
        SignalSocketState::NoError(
            SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN));
  }

  void ExpectSSLConnectSignal() {
    ExpectSignalSocketState(
        SignalSocketState::NoError(SIGNAL_SSL_CONNECT,
                                   ChromeAsyncSocket::STATE_TLS_OPEN));
  }

  void ExpectSSLReadSignal() {
    ExpectSignalSocketState(
        SignalSocketState::NoError(
            SIGNAL_READ, ChromeAsyncSocket::STATE_TLS_OPEN));
  }

  // Open/close utility functions.

  void DoOpenClosed() {
    ExpectClosed();
    async_socket_data_provider_.set_connect_data(
        net::MockConnect(net::SYNCHRONOUS, net::OK));
    EXPECT_TRUE(chrome_async_socket_->Connect(addr_));
    ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);

    message_loop_->RunUntilIdle();
    // We may not necessarily be open; may have been other events
    // queued up.
    ExpectSignalSocketState(
        SignalSocketState::NoError(
            SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN));
  }

  void DoCloseOpened(SignalSocketState expected_signal_socket_state) {
    // We may be in an error state, so just compare state().
    EXPECT_EQ(ChromeAsyncSocket::STATE_OPEN, chrome_async_socket_->state());
    EXPECT_TRUE(chrome_async_socket_->Close());
    ExpectSignalSocketState(expected_signal_socket_state);
    ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED);
  }

  void DoCloseOpenedNoError() {
    DoCloseOpened(
        SignalSocketState::NoError(
            SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));
  }

  void DoSSLOpenClosed() {
    const char kDummyData[] = "dummy_data";
    async_socket_data_provider_.AddRead(net::MockRead(kDummyData));
    DoOpenClosed();
    ExpectReadSignal();
    EXPECT_EQ(kDummyData, DrainRead(1));

    EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
    message_loop_->RunUntilIdle();
    ExpectSSLConnectSignal();
    ExpectNoSignal();
    ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN);
  }

  void DoSSLCloseOpened(SignalSocketState expected_signal_socket_state) {
    // We may be in an error state, so just compare state().
    EXPECT_EQ(ChromeAsyncSocket::STATE_TLS_OPEN,
              chrome_async_socket_->state());
    EXPECT_TRUE(chrome_async_socket_->Close());
    ExpectSignalSocketState(expected_signal_socket_state);
    ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED);
  }

  void DoSSLCloseOpenedNoError() {
    DoSSLCloseOpened(
        SignalSocketState::NoError(
            SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));
  }

  // Read utility fucntions.

  std::string DrainRead(size_t buf_size) {
    std::string read;
    scoped_ptr<char[]> buf(new char[buf_size]);
    size_t len_read;
    while (true) {
      bool success =
          chrome_async_socket_->Read(buf.get(), buf_size, &len_read);
      if (!success) {
        ADD_FAILURE();
        break;
      }
      if (len_read == 0U) {
        break;
      }
      read.append(buf.get(), len_read);
    }
    return read;
  }

  // ChromeAsyncSocket expects a message loop.
  scoped_ptr<base::MessageLoop> message_loop_;

  AsyncSocketDataProvider async_socket_data_provider_;
  net::SSLSocketDataProvider ssl_socket_data_provider_;

  scoped_ptr<ChromeAsyncSocket> chrome_async_socket_;
  std::deque<SignalSocketState> signal_socket_states_;
  const rtc::SocketAddress addr_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeAsyncSocketTest);
};

TEST_F(ChromeAsyncSocketTest, InitialState) {
  ExpectClosed();
  ExpectNoSignal();
}

TEST_F(ChromeAsyncSocketTest, EmptyClose) {
  ExpectClosed();
  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
}

TEST_F(ChromeAsyncSocketTest, ImmediateConnectAndClose) {
  DoOpenClosed();

  ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN);

  DoCloseOpenedNoError();
}

// After this, no need to test immediate successful connect and
// Close() so thoroughly.

TEST_F(ChromeAsyncSocketTest, DoubleClose) {
  DoOpenClosed();

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
}

TEST_F(ChromeAsyncSocketTest, NoHostnameConnect) {
  rtc::IPAddress ip_address;
  EXPECT_TRUE(rtc::IPFromString("127.0.0.1", &ip_address));
  const rtc::SocketAddress no_hostname_addr(ip_address, addr_.port());
  EXPECT_FALSE(chrome_async_socket_->Connect(no_hostname_addr));
  ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED,
                   ChromeAsyncSocket::ERROR_DNS);

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
}

TEST_F(ChromeAsyncSocketTest, ZeroPortConnect) {
  const rtc::SocketAddress zero_port_addr(addr_.hostname(), 0);
  EXPECT_FALSE(chrome_async_socket_->Connect(zero_port_addr));
  ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED,
                   ChromeAsyncSocket::ERROR_DNS);

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
}

TEST_F(ChromeAsyncSocketTest, DoubleConnect) {
  EXPECT_DEBUG_DEATH({
    DoOpenClosed();

    EXPECT_FALSE(chrome_async_socket_->Connect(addr_));
    ExpectErrorState(ChromeAsyncSocket::STATE_OPEN,
                     ChromeAsyncSocket::ERROR_WRONGSTATE);

    DoCloseOpened(
        SignalSocketState(SIGNAL_CLOSE,
                          ChromeAsyncSocket::STATE_CLOSED,
                          ChromeAsyncSocket::ERROR_WRONGSTATE,
                          net::OK));
  }, "non-closed socket");
}

TEST_F(ChromeAsyncSocketTest, ImmediateConnectCloseBeforeRead) {
  DoOpenClosed();

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));

  message_loop_->RunUntilIdle();
}

TEST_F(ChromeAsyncSocketTest, HangingConnect) {
  EXPECT_TRUE(chrome_async_socket_->Connect(addr_));
  ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);
  ExpectNoSignal();

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));
}

TEST_F(ChromeAsyncSocketTest, PendingConnect) {
  async_socket_data_provider_.set_connect_data(
      net::MockConnect(net::ASYNC, net::OK));
  EXPECT_TRUE(chrome_async_socket_->Connect(addr_));
  ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);
  ExpectNoSignal();

  message_loop_->RunUntilIdle();
  ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN);
  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN));
  ExpectNoSignal();

  message_loop_->RunUntilIdle();

  DoCloseOpenedNoError();
}

// After this no need to test successful pending connect so
// thoroughly.

TEST_F(ChromeAsyncSocketTest, PendingConnectCloseBeforeRead) {
  async_socket_data_provider_.set_connect_data(
      net::MockConnect(net::ASYNC, net::OK));
  EXPECT_TRUE(chrome_async_socket_->Connect(addr_));

  message_loop_->RunUntilIdle();
  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN));

  DoCloseOpenedNoError();

  message_loop_->RunUntilIdle();
}

TEST_F(ChromeAsyncSocketTest, PendingConnectError) {
  async_socket_data_provider_.set_connect_data(
      net::MockConnect(net::ASYNC, net::ERR_TIMED_OUT));
  EXPECT_TRUE(chrome_async_socket_->Connect(addr_));

  message_loop_->RunUntilIdle();

  ExpectSignalSocketState(
      SignalSocketState(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
          ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
}

// After this we can assume Connect() and Close() work as expected.

TEST_F(ChromeAsyncSocketTest, EmptyRead) {
  DoOpenClosed();

  char buf[4096];
  size_t len_read = 10000U;
  EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read));
  EXPECT_EQ(0U, len_read);

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, WrongRead) {
  EXPECT_DEBUG_DEATH({
    async_socket_data_provider_.set_connect_data(
        net::MockConnect(net::ASYNC, net::OK));
    EXPECT_TRUE(chrome_async_socket_->Connect(addr_));
    ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);
    ExpectNoSignal();

    char buf[4096];
    size_t len_read;
    EXPECT_FALSE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read));
    ExpectErrorState(ChromeAsyncSocket::STATE_CONNECTING,
                     ChromeAsyncSocket::ERROR_WRONGSTATE);
    EXPECT_TRUE(chrome_async_socket_->Close());
    ExpectSignalSocketState(
        SignalSocketState(
            SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
            ChromeAsyncSocket::ERROR_WRONGSTATE, net::OK));
  }, "non-open");
}

TEST_F(ChromeAsyncSocketTest, WrongReadClosed) {
  char buf[4096];
  size_t len_read;
  EXPECT_FALSE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read));
  ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED,
                   ChromeAsyncSocket::ERROR_WRONGSTATE);
  EXPECT_TRUE(chrome_async_socket_->Close());
}

const char kReadData[] = "mydatatoread";

TEST_F(ChromeAsyncSocketTest, Read) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();

  ExpectReadSignal();
  ExpectNoSignal();

  EXPECT_EQ(kReadData, DrainRead(1));

  message_loop_->RunUntilIdle();

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, ReadTwice) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();

  ExpectReadSignal();
  ExpectNoSignal();

  EXPECT_EQ(kReadData, DrainRead(1));

  message_loop_->RunUntilIdle();

  const char kReadData2[] = "mydatatoread2";
  async_socket_data_provider_.AddRead(net::MockRead(kReadData2));

  ExpectReadSignal();
  ExpectNoSignal();

  EXPECT_EQ(kReadData2, DrainRead(1));

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, ReadError) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();

  ExpectReadSignal();
  ExpectNoSignal();

  EXPECT_EQ(kReadData, DrainRead(1));

  message_loop_->RunUntilIdle();

  async_socket_data_provider_.AddRead(
      net::MockRead(net::SYNCHRONOUS, net::ERR_TIMED_OUT));

  ExpectSignalSocketState(
      SignalSocketState(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
          ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
}

TEST_F(ChromeAsyncSocketTest, ReadEmpty) {
  async_socket_data_provider_.AddRead(net::MockRead(""));
  DoOpenClosed();

  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));
}

TEST_F(ChromeAsyncSocketTest, PendingRead) {
  DoOpenClosed();

  ExpectNoSignal();

  async_socket_data_provider_.AddRead(net::MockRead(kReadData));

  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN));
  ExpectNoSignal();

  EXPECT_EQ(kReadData, DrainRead(1));

  message_loop_->RunUntilIdle();

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, PendingEmptyRead) {
  DoOpenClosed();

  ExpectNoSignal();

  async_socket_data_provider_.AddRead(net::MockRead(""));

  ExpectSignalSocketState(
      SignalSocketState::NoError(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED));
}

TEST_F(ChromeAsyncSocketTest, PendingReadError) {
  DoOpenClosed();

  ExpectNoSignal();

  async_socket_data_provider_.AddRead(
      net::MockRead(net::ASYNC, net::ERR_TIMED_OUT));

  ExpectSignalSocketState(
      SignalSocketState(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
          ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
}

// After this we can assume non-SSL Read() works as expected.

TEST_F(ChromeAsyncSocketTest, WrongWrite) {
  EXPECT_DEBUG_DEATH({
    std::string data("foo");
    EXPECT_FALSE(chrome_async_socket_->Write(data.data(), data.size()));
    ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED,
                     ChromeAsyncSocket::ERROR_WRONGSTATE);
    EXPECT_TRUE(chrome_async_socket_->Close());
  }, "non-open");
}

const char kWriteData[] = "mydatatowrite";

TEST_F(ChromeAsyncSocketTest, SyncWrite) {
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS, kWriteData, 3));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS,
                     kWriteData + 8, arraysize(kWriteData) - 8));
  DoOpenClosed();

  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8,
                                          arraysize(kWriteData) - 8));
  message_loop_->RunUntilIdle();

  ExpectNoSignal();

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, AsyncWrite) {
  DoOpenClosed();

  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData, 3));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData + 8, arraysize(kWriteData) - 8));

  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8,
                                          arraysize(kWriteData) - 8));
  message_loop_->RunUntilIdle();

  ExpectNoSignal();

  DoCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, AsyncWriteError) {
  DoOpenClosed();

  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData, 3));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, net::ERR_TIMED_OUT));

  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8,
                                          arraysize(kWriteData) - 8));
  message_loop_->RunUntilIdle();

  ExpectSignalSocketState(
      SignalSocketState(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
          ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT));
}

TEST_F(ChromeAsyncSocketTest, LargeWrite) {
  EXPECT_DEBUG_DEATH({
    DoOpenClosed();

    std::string large_data(100, 'x');
    EXPECT_FALSE(chrome_async_socket_->Write(large_data.data(),
                                             large_data.size()));
    ExpectState(ChromeAsyncSocket::STATE_OPEN,
                ChromeAsyncSocket::ERROR_WINSOCK,
                net::ERR_INSUFFICIENT_RESOURCES);
    DoCloseOpened(
        SignalSocketState(
            SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
            ChromeAsyncSocket::ERROR_WINSOCK,
            net::ERR_INSUFFICIENT_RESOURCES));
    }, "exceed the max write buffer");
}

TEST_F(ChromeAsyncSocketTest, LargeAccumulatedWrite) {
  EXPECT_DEBUG_DEATH({
    DoOpenClosed();

    std::string data(15, 'x');
    EXPECT_TRUE(chrome_async_socket_->Write(data.data(), data.size()));
    EXPECT_FALSE(chrome_async_socket_->Write(data.data(), data.size()));
    ExpectState(ChromeAsyncSocket::STATE_OPEN,
                ChromeAsyncSocket::ERROR_WINSOCK,
                net::ERR_INSUFFICIENT_RESOURCES);
    DoCloseOpened(
        SignalSocketState(
            SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
            ChromeAsyncSocket::ERROR_WINSOCK,
            net::ERR_INSUFFICIENT_RESOURCES));
    }, "exceed the max write buffer");
}

// After this we can assume non-SSL I/O works as expected.

TEST_F(ChromeAsyncSocketTest, HangingSSLConnect) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();
  ExpectReadSignal();

  EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
  ExpectNoSignal();

  ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING);
  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectSignalSocketState(
      SignalSocketState::NoError(SIGNAL_CLOSE,
                                 ChromeAsyncSocket::STATE_CLOSED));
  ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED);
}

TEST_F(ChromeAsyncSocketTest, ImmediateSSLConnect) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();
  ExpectReadSignal();

  EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
  message_loop_->RunUntilIdle();
  ExpectSSLConnectSignal();
  ExpectNoSignal();
  ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN);

  DoSSLCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, DoubleSSLConnect) {
  EXPECT_DEBUG_DEATH({
    async_socket_data_provider_.AddRead(net::MockRead(kReadData));
    DoOpenClosed();
    ExpectReadSignal();

    EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
    message_loop_->RunUntilIdle();
    ExpectSSLConnectSignal();
    ExpectNoSignal();
    ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN);

    EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com"));

    DoSSLCloseOpened(
        SignalSocketState(SIGNAL_CLOSE,
                          ChromeAsyncSocket::STATE_CLOSED,
                          ChromeAsyncSocket::ERROR_WRONGSTATE,
                          net::OK));
  }, "wrong state");
}

TEST_F(ChromeAsyncSocketTest, FailedSSLConnect) {
  ssl_socket_data_provider_.connect =
      net::MockConnect(net::ASYNC, net::ERR_CERT_COMMON_NAME_INVALID),

  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();
  ExpectReadSignal();

  EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
  message_loop_->RunUntilIdle();
  ExpectSignalSocketState(
      SignalSocketState(
          SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED,
          ChromeAsyncSocket::ERROR_WINSOCK,
          net::ERR_CERT_COMMON_NAME_INVALID));

  EXPECT_TRUE(chrome_async_socket_->Close());
  ExpectClosed();
}

TEST_F(ChromeAsyncSocketTest, ReadDuringSSLConnecting) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();
  ExpectReadSignal();
  EXPECT_EQ(kReadData, DrainRead(1));

  EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
  ExpectNoSignal();

  // Shouldn't do anything.
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));

  char buf[4096];
  size_t len_read = 10000U;
  EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read));
  EXPECT_EQ(0U, len_read);

  message_loop_->RunUntilIdle();
  ExpectSSLConnectSignal();
  ExpectSSLReadSignal();
  ExpectNoSignal();
  ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN);

  len_read = 10000U;
  EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read));
  EXPECT_EQ(kReadData, std::string(buf, len_read));

  DoSSLCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, WriteDuringSSLConnecting) {
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  DoOpenClosed();
  ExpectReadSignal();

  EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com"));
  ExpectNoSignal();
  ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING);

  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData, 3));

  // Shouldn't do anything.
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));

  // TODO(akalin): Figure out how to test that the write happens
  // *after* the SSL connect.

  message_loop_->RunUntilIdle();
  ExpectSSLConnectSignal();
  ExpectNoSignal();

  message_loop_->RunUntilIdle();

  DoSSLCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPendingRead) {
  EXPECT_DEBUG_DEATH({
    DoOpenClosed();

    EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com"));

    DoCloseOpened(
        SignalSocketState(SIGNAL_CLOSE,
                          ChromeAsyncSocket::STATE_CLOSED,
                          ChromeAsyncSocket::ERROR_WRONGSTATE,
                          net::OK));
  }, "wrong state");
}

TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPostedWrite) {
  EXPECT_DEBUG_DEATH({
    DoOpenClosed();

    async_socket_data_provider_.AddWrite(
        net::MockWrite(net::ASYNC, kWriteData, 3));
    EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));

    EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com"));

    message_loop_->RunUntilIdle();

    DoCloseOpened(
        SignalSocketState(SIGNAL_CLOSE,
                          ChromeAsyncSocket::STATE_CLOSED,
                          ChromeAsyncSocket::ERROR_WRONGSTATE,
                          net::OK));
  }, "wrong state");
}

// After this we can assume SSL connect works as expected.

TEST_F(ChromeAsyncSocketTest, SSLRead) {
  DoSSLOpenClosed();
  async_socket_data_provider_.AddRead(net::MockRead(kReadData));
  message_loop_->RunUntilIdle();

  ExpectSSLReadSignal();
  ExpectNoSignal();

  EXPECT_EQ(kReadData, DrainRead(1));

  message_loop_->RunUntilIdle();

  DoSSLCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, SSLSyncWrite) {
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS, kWriteData, 3));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::SYNCHRONOUS,
                     kWriteData + 8, arraysize(kWriteData) - 8));
  DoSSLOpenClosed();

  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8,
                                          arraysize(kWriteData) - 8));
  message_loop_->RunUntilIdle();

  ExpectNoSignal();

  DoSSLCloseOpenedNoError();
}

TEST_F(ChromeAsyncSocketTest, SSLAsyncWrite) {
  DoSSLOpenClosed();

  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData, 3));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData + 3, 5));
  async_socket_data_provider_.AddWrite(
      net::MockWrite(net::ASYNC, kWriteData + 8, arraysize(kWriteData) - 8));

  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5));
  message_loop_->RunUntilIdle();
  EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8,
                                          arraysize(kWriteData) - 8));
  message_loop_->RunUntilIdle();

  ExpectNoSignal();

  DoSSLCloseOpenedNoError();
}

}  // namespace

}  // namespace jingle_glue
