| Index: chrome/browser/sync/tools/chrome_async_socket_unittest.cc
|
| diff --git a/chrome/browser/sync/tools/chrome_async_socket_unittest.cc b/chrome/browser/sync/tools/chrome_async_socket_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..225a215af52b02cda10e5ad600e8534ed02f0cf6
|
| --- /dev/null
|
| +++ b/chrome/browser/sync/tools/chrome_async_socket_unittest.cc
|
| @@ -0,0 +1,981 @@
|
| +// Copyright (c) 2010 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 "chrome/browser/sync/tools/chrome_async_socket.h"
|
| +
|
| +#include <deque>
|
| +#include <string>
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/logging.h"
|
| +#include "base/message_loop.h"
|
| +#include "net/base/ssl_config_service.h"
|
| +#include "net/base/capturing_net_log.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/socket/socket_test_util.h"
|
| +#include "talk/base/sigslot.h"
|
| +#include "talk/base/socketaddress.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace sync_tools {
|
| +
|
| +namespace {
|
| +
|
| +// Data provider that handles reads/writes for ChromeAsyncSocket.
|
| +class AsyncSocketDataProvider : public net::SocketDataProvider {
|
| + public:
|
| + AsyncSocketDataProvider() : has_pending_read_(false) {}
|
| +
|
| + virtual ~AsyncSocketDataProvider() {
|
| + EXPECT_TRUE(writes_.empty());
|
| + EXPECT_TRUE(reads_.empty());
|
| + }
|
| +
|
| + // If there's no read, sets the "has pending read" flag. Otherwise,
|
| + // pops the next read.
|
| + virtual net::MockRead GetNextRead() {
|
| + if (reads_.empty()) {
|
| + DCHECK(!has_pending_read_);
|
| + has_pending_read_ = true;
|
| + const net::MockRead pending_read(false, 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|.
|
| + virtual net::MockWriteResult OnWrite(const std::string& data) {
|
| + DCHECK(!writes_.empty());
|
| + net::MockWrite mock_write = writes_.front();
|
| + writes_.pop_front();
|
| + if (mock_write.result != net::OK) {
|
| + return net::MockWriteResult(mock_write.async, 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(false, net::ERR_UNEXPECTED);
|
| + }
|
| + return net::MockWriteResult(mock_write.async, data.size());
|
| + }
|
| +
|
| + // We ignore resets so we can pre-load the socket data provider with
|
| + // read/write events.
|
| + virtual void Reset() {}
|
| +
|
| + // 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 ChromeAsyncSocketTest
|
| + : public testing::Test,
|
| + public sigslot::has_slots<> {
|
| + protected:
|
| + // TODO(akalin): test SSL states other than connection success.
|
| + ChromeAsyncSocketTest()
|
| + : ssl_socket_data_provider_(true, net::OK),
|
| + capturing_net_log_(net::CapturingNetLog::kUnbounded),
|
| + chrome_async_socket_(&mock_client_socket_factory_,
|
| + ssl_config_, 14, 20, &capturing_net_log_),
|
| + addr_(0xaabbccdd, 35) {}
|
| +
|
| + virtual ~ChromeAsyncSocketTest() {}
|
| +
|
| + virtual void SetUp() {
|
| + mock_client_socket_factory_.AddSocketDataProvider(
|
| + &async_socket_data_provider_);
|
| + mock_client_socket_factory_.AddSSLSocketDataProvider(
|
| + &ssl_socket_data_provider_);
|
| +
|
| + 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);
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + // Run any tasks that we forgot to pump.
|
| + message_loop_.RunAllPending();
|
| + ExpectClosed();
|
| + ExpectNoSignal();
|
| + chrome_async_socket_.SignalConnected.disconnect(this);
|
| + chrome_async_socket_.SignalSSLConnected.disconnect(this);
|
| + chrome_async_socket_.SignalClosed.disconnect(this);
|
| + chrome_async_socket_.SignalRead.disconnect(this);
|
| + chrome_async_socket_.SignalError.disconnect(this);
|
| + }
|
| +
|
| + 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_));
|
| + }
|
| +
|
| + 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(false, net::OK));
|
| + EXPECT_TRUE(chrome_async_socket_.Connect(addr_));
|
| + ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);
|
| +
|
| + message_loop_.RunAllPending();
|
| + // 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_.RunAllPending();
|
| + 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_array<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 == 0) {
|
| + break;
|
| + }
|
| + read.append(buf.get(), len_read);
|
| + }
|
| + return read;
|
| + }
|
| +
|
| + // ChromeAsyncSocket expects a message loop.
|
| + MessageLoop message_loop_;
|
| +
|
| + net::MockClientSocketFactory mock_client_socket_factory_;
|
| + AsyncSocketDataProvider async_socket_data_provider_;
|
| + net::SSLSocketDataProvider ssl_socket_data_provider_;
|
| +
|
| + net::CapturingNetLog capturing_net_log_;
|
| + net::SSLConfig ssl_config_;
|
| + ChromeAsyncSocket chrome_async_socket_;
|
| + std::deque<SignalSocketState> signal_socket_states_;
|
| + const talk_base::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, UnresolvedConnect) {
|
| + const talk_base::SocketAddress unresolved_addr(0, 0);
|
| + EXPECT_FALSE(chrome_async_socket_.Connect(unresolved_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_.RunAllPending();
|
| +}
|
| +
|
| +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(true, net::OK));
|
| + EXPECT_TRUE(chrome_async_socket_.Connect(addr_));
|
| + ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING);
|
| + ExpectNoSignal();
|
| +
|
| + message_loop_.RunAllPending();
|
| + ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN);
|
| + ExpectSignalSocketState(
|
| + SignalSocketState::NoError(
|
| + SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN));
|
| + ExpectNoSignal();
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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(true, net::OK));
|
| + EXPECT_TRUE(chrome_async_socket_.Connect(addr_));
|
| +
|
| + message_loop_.RunAllPending();
|
| + ExpectSignalSocketState(
|
| + SignalSocketState::NoError(
|
| + SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN));
|
| +
|
| + DoCloseOpenedNoError();
|
| +
|
| + message_loop_.RunAllPending();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, PendingConnectError) {
|
| + async_socket_data_provider_.set_connect_data(
|
| + net::MockConnect(true, net::ERR_TIMED_OUT));
|
| + EXPECT_TRUE(chrome_async_socket_.Connect(addr_));
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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 = 10000;
|
| + EXPECT_TRUE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read));
|
| + EXPECT_EQ(0, len_read);
|
| +
|
| + DoCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, WrongRead) {
|
| + EXPECT_DEBUG_DEATH({
|
| + 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());
|
| + }, "non-open");
|
| +}
|
| +
|
| +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_.RunAllPending();
|
| +
|
| + DoCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, ReadTwice) {
|
| + async_socket_data_provider_.AddRead(net::MockRead(kReadData));
|
| + DoOpenClosed();
|
| +
|
| + ExpectReadSignal();
|
| + ExpectNoSignal();
|
| +
|
| + EXPECT_EQ(kReadData, DrainRead(1));
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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_.RunAllPending();
|
| +
|
| + async_socket_data_provider_.AddRead(
|
| + net::MockRead(false, 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_.RunAllPending();
|
| +
|
| + 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(true, 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(false, kWriteData, 3));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(false, kWriteData + 3, 5));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(false, kWriteData + 8, arraysize(kWriteData) - 8));
|
| + DoOpenClosed();
|
| +
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8,
|
| + arraysize(kWriteData) - 8));
|
| + message_loop_.RunAllPending();
|
| +
|
| + ExpectNoSignal();
|
| +
|
| + DoCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, AsyncWrite) {
|
| + DoOpenClosed();
|
| +
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData, 3));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData + 3, 5));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData + 8, arraysize(kWriteData) - 8));
|
| +
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8,
|
| + arraysize(kWriteData) - 8));
|
| + message_loop_.RunAllPending();
|
| +
|
| + ExpectNoSignal();
|
| +
|
| + DoCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, AsyncWriteError) {
|
| + DoOpenClosed();
|
| +
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData, 3));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData + 3, 5));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, net::ERR_TIMED_OUT));
|
| +
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8,
|
| + arraysize(kWriteData) - 8));
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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_.RunAllPending();
|
| + 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_.RunAllPending();
|
| + 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, 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 = 10000;
|
| + EXPECT_TRUE(chrome_async_socket_.Read(buf, sizeof(buf), &len_read));
|
| + EXPECT_EQ(0, len_read);
|
| +
|
| + message_loop_.RunAllPending();
|
| + ExpectSSLConnectSignal();
|
| + ExpectSSLReadSignal();
|
| + ExpectNoSignal();
|
| + ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN);
|
| +
|
| + len_read = 10000;
|
| + 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(true, 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_.RunAllPending();
|
| + ExpectSSLConnectSignal();
|
| + ExpectNoSignal();
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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(true, kWriteData, 3));
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| +
|
| + EXPECT_FALSE(chrome_async_socket_.StartTls("fakedomain.com"));
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + 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_.RunAllPending();
|
| +
|
| + ExpectSSLReadSignal();
|
| + ExpectNoSignal();
|
| +
|
| + EXPECT_EQ(kReadData, DrainRead(1));
|
| +
|
| + message_loop_.RunAllPending();
|
| +
|
| + DoSSLCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, SSLSyncWrite) {
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(false, kWriteData, 3));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(false, kWriteData + 3, 5));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(false, kWriteData + 8, arraysize(kWriteData) - 8));
|
| + DoSSLOpenClosed();
|
| +
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8,
|
| + arraysize(kWriteData) - 8));
|
| + message_loop_.RunAllPending();
|
| +
|
| + ExpectNoSignal();
|
| +
|
| + DoSSLCloseOpenedNoError();
|
| +}
|
| +
|
| +TEST_F(ChromeAsyncSocketTest, SSLAsyncWrite) {
|
| + DoSSLOpenClosed();
|
| +
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData, 3));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData + 3, 5));
|
| + async_socket_data_provider_.AddWrite(
|
| + net::MockWrite(true, kWriteData + 8, arraysize(kWriteData) - 8));
|
| +
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData, 3));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 3, 5));
|
| + message_loop_.RunAllPending();
|
| + EXPECT_TRUE(chrome_async_socket_.Write(kWriteData + 8,
|
| + arraysize(kWriteData) - 8));
|
| + message_loop_.RunAllPending();
|
| +
|
| + ExpectNoSignal();
|
| +
|
| + DoSSLCloseOpenedNoError();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace sync_tools
|
|
|