Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(882)

Unified Diff: extensions/browser/api/cast_channel/cast_socket_unittest.cc

Issue 2926313002: Revert of [cast_channel] Move cast_channel related files from //extensions to //components (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/browser/api/cast_channel/cast_socket_unittest.cc
diff --git a/extensions/browser/api/cast_channel/cast_socket_unittest.cc b/extensions/browser/api/cast_channel/cast_socket_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bbd47674826a99dd24f0d33787ed300dfb7a6bf1
--- /dev/null
+++ b/extensions/browser/api/cast_channel/cast_socket_unittest.cc
@@ -0,0 +1,794 @@
+// Copyright 2014 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 "extensions/browser/api/cast_channel/cast_socket.h"
+
+#include <stdint.h>
+
+#include <utility>
+#include <vector>
+
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/sys_byteorder.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/timer/mock_timer.h"
+#include "extensions/browser/api/cast_channel/cast_auth_util.h"
+#include "extensions/browser/api/cast_channel/cast_framer.h"
+#include "extensions/browser/api/cast_channel/cast_message_util.h"
+#include "extensions/browser/api/cast_channel/cast_test_util.h"
+#include "extensions/browser/api/cast_channel/cast_transport.h"
+#include "extensions/browser/api/cast_channel/logger.h"
+#include "extensions/common/api/cast_channel/cast_channel.pb.h"
+#include "extensions/common/api/cast_channel/logging.pb.h"
+#include "net/base/address_list.h"
+#include "net/base/net_errors.h"
+#include "net/log/test_net_log.h"
+#include "net/socket/socket_test_util.h"
+#include "net/socket/ssl_client_socket.h"
+#include "net/socket/tcp_client_socket.h"
+#include "net/ssl/ssl_info.h"
+#include "net/test/cert_test_util.h"
+#include "net/test/test_data_directory.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+const int64_t kDistantTimeoutMillis = 100000; // 100 seconds (never hit).
+
+using ::cast_channel::ChannelError;
+using ::cast_channel::ChannelAuthType;
+using ::cast_channel::ReadyState;
+using ::testing::_;
+using ::testing::A;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::InvokeArgument;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::SaveArg;
+
+namespace extensions {
+namespace api {
+namespace cast_channel {
+const char kAuthNamespace[] = "urn:x-cast:com.google.cast.tp.deviceauth";
+
+// Returns an auth challenge message inline.
+CastMessage CreateAuthChallenge() {
+ CastMessage output;
+ CreateAuthChallengeMessage(&output, AuthContext::Create());
+ return output;
+}
+
+// Returns an auth challenge response message inline.
+CastMessage CreateAuthReply() {
+ CastMessage output;
+ output.set_protocol_version(CastMessage::CASTV2_1_0);
+ output.set_source_id("sender-0");
+ output.set_destination_id("receiver-0");
+ output.set_payload_type(CastMessage::BINARY);
+ output.set_payload_binary("abcd");
+ output.set_namespace_(kAuthNamespace);
+ return output;
+}
+
+CastMessage CreateTestMessage() {
+ CastMessage test_message;
+ test_message.set_protocol_version(CastMessage::CASTV2_1_0);
+ test_message.set_namespace_("ns");
+ test_message.set_source_id("source");
+ test_message.set_destination_id("dest");
+ test_message.set_payload_type(CastMessage::STRING);
+ test_message.set_payload_utf8("payload");
+ return test_message;
+}
+
+class MockTCPSocket : public net::TCPClientSocket {
+ public:
+ explicit MockTCPSocket(const net::MockConnect& connect_data)
+ : TCPClientSocket(net::AddressList(),
+ nullptr,
+ nullptr,
+ net::NetLogSource()),
+ connect_data_(connect_data),
+ do_nothing_(false) {}
+
+ explicit MockTCPSocket(bool do_nothing)
+ : TCPClientSocket(net::AddressList(),
+ nullptr,
+ nullptr,
+ net::NetLogSource()) {
+ CHECK(do_nothing);
+ do_nothing_ = do_nothing;
+ }
+
+ virtual int Connect(const net::CompletionCallback& callback) {
+ if (do_nothing_) {
+ // Stall the I/O event loop.
+ return net::ERR_IO_PENDING;
+ }
+
+ if (connect_data_.mode == net::ASYNC) {
+ CHECK_NE(connect_data_.result, net::ERR_IO_PENDING);
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(callback, connect_data_.result));
+ return net::ERR_IO_PENDING;
+ } else {
+ return connect_data_.result;
+ }
+ }
+
+ virtual bool SetKeepAlive(bool enable, int delay) {
+ // Always return true in tests
+ return true;
+ }
+
+ virtual bool SetNoDelay(bool no_delay) {
+ // Always return true in tests
+ return true;
+ }
+
+ MOCK_METHOD3(Read,
+ int(net::IOBuffer*, int, const net::CompletionCallback&));
+ MOCK_METHOD3(Write,
+ int(net::IOBuffer*, int, const net::CompletionCallback&));
+
+ virtual void Disconnect() {
+ // Do nothing in tests
+ }
+
+ private:
+ net::MockConnect connect_data_;
+ bool do_nothing_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockTCPSocket);
+};
+
+class MockDelegate : public CastTransport::Delegate {
+ public:
+ MockDelegate() {}
+ virtual ~MockDelegate() {}
+ MOCK_METHOD1(OnError, void(ChannelError error_state));
+ MOCK_METHOD1(OnMessage, void(const CastMessage& message));
+ MOCK_METHOD0(Start, void());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockDelegate);
+};
+
+class CompleteHandler {
+ public:
+ CompleteHandler() {}
+ MOCK_METHOD1(OnCloseComplete, void(int result));
+ MOCK_METHOD1(OnConnectComplete, void(ChannelError error_state));
+ MOCK_METHOD1(OnWriteComplete, void(int result));
+ MOCK_METHOD1(OnReadComplete, void(int result));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CompleteHandler);
+};
+
+class TestCastSocket : public CastSocketImpl {
+ public:
+ static std::unique_ptr<TestCastSocket> CreateSecure(
+ Logger* logger,
+ uint64_t device_capabilities = cast_channel::CastDeviceCapability::NONE) {
+ return std::unique_ptr<TestCastSocket>(new TestCastSocket(
+ CreateIPEndPointForTest(), ChannelAuthType::SSL_VERIFIED,
+ kDistantTimeoutMillis, logger, device_capabilities));
+ }
+
+ TestCastSocket(const net::IPEndPoint& ip_endpoint,
+ ChannelAuthType channel_auth,
+ int64_t timeout_ms,
+ Logger* logger,
+ uint64_t device_capabilities)
+ : TestCastSocket(ip_endpoint,
+ channel_auth,
+ timeout_ms,
+ logger,
+ new net::TestNetLog(),
+ device_capabilities) {}
+
+ TestCastSocket(const net::IPEndPoint& ip_endpoint,
+ ChannelAuthType channel_auth,
+ int64_t timeout_ms,
+ Logger* logger,
+ net::TestNetLog* capturing_net_log,
+ uint64_t device_capabilities)
+ : CastSocketImpl("some_extension_id",
+ ip_endpoint,
+ channel_auth,
+ capturing_net_log,
+ base::TimeDelta::FromMilliseconds(timeout_ms),
+ false,
+ logger,
+ device_capabilities,
+ AuthContext::Create()),
+ capturing_net_log_(capturing_net_log),
+ ip_(ip_endpoint),
+ extract_cert_result_(true),
+ verify_challenge_result_(true),
+ verify_challenge_disallow_(false),
+ tcp_unresponsive_(false),
+ mock_timer_(new base::MockTimer(false, false)),
+ mock_transport_(nullptr) {}
+
+ ~TestCastSocket() override {}
+
+ void SetupMockTransport() {
+ mock_transport_ = new MockCastTransport;
+ SetTransportForTesting(base::WrapUnique(mock_transport_));
+ }
+
+ // Socket connection helpers.
+ void SetupTcpConnect(net::IoMode mode, int result) {
+ tcp_connect_data_.reset(new net::MockConnect(mode, result));
+ }
+ void SetupSslConnect(net::IoMode mode, int result) {
+ ssl_connect_data_.reset(new net::MockConnect(mode, result));
+ }
+
+ // Socket I/O helpers.
+ void AddWriteResult(const net::MockWrite& write) {
+ writes_.push_back(write);
+ }
+ void AddWriteResult(net::IoMode mode, int result) {
+ AddWriteResult(net::MockWrite(mode, result));
+ }
+ void AddWriteResultForData(net::IoMode mode, const std::string& msg) {
+ AddWriteResult(mode, msg.size());
+ }
+ void AddReadResult(const net::MockRead& read) {
+ reads_.push_back(read);
+ }
+ void AddReadResult(net::IoMode mode, int result) {
+ AddReadResult(net::MockRead(mode, result));
+ }
+ void AddReadResultForData(net::IoMode mode, const std::string& data) {
+ AddReadResult(net::MockRead(mode, data.c_str(), data.size()));
+ }
+
+ // Helpers for modifying other connection-related behaviors.
+ void SetupTcpConnectUnresponsive() { tcp_unresponsive_ = true; }
+
+ void SetExtractCertResult(bool value) {
+ extract_cert_result_ = value;
+ }
+
+ void SetVerifyChallengeResult(bool value) {
+ verify_challenge_result_ = value;
+ }
+
+ void TriggerTimeout() {
+ mock_timer_->Fire();
+ }
+
+ bool TestVerifyChannelPolicyNone() {
+ AuthResult authResult;
+ return VerifyChannelPolicy(authResult);
+ }
+
+ bool TestVerifyChannelPolicyAudioOnly() {
+ AuthResult authResult;
+ authResult.channel_policies |= AuthResult::POLICY_AUDIO_ONLY;
+ return VerifyChannelPolicy(authResult);
+ }
+
+ void DisallowVerifyChallengeResult() { verify_challenge_disallow_ = true; }
+
+ MockCastTransport* GetMockTransport() {
+ CHECK(mock_transport_);
+ return mock_transport_;
+ }
+
+ private:
+ std::unique_ptr<net::TCPClientSocket> CreateTcpSocket() override {
+ if (tcp_unresponsive_) {
+ return std::unique_ptr<net::TCPClientSocket>(new MockTCPSocket(true));
+ } else {
+ net::MockConnect* connect_data = tcp_connect_data_.get();
+ connect_data->peer_addr = ip_;
+ return std::unique_ptr<net::TCPClientSocket>(
+ new MockTCPSocket(*connect_data));
+ }
+ }
+
+ std::unique_ptr<net::SSLClientSocket> CreateSslSocket(
+ std::unique_ptr<net::StreamSocket> socket) override {
+ net::MockConnect* connect_data = ssl_connect_data_.get();
+ connect_data->peer_addr = ip_;
+
+ ssl_data_.reset(new net::StaticSocketDataProvider(
+ reads_.data(), reads_.size(), writes_.data(), writes_.size()));
+ ssl_data_->set_connect_data(*connect_data);
+ // NOTE: net::MockTCPClientSocket inherits from net::SSLClientSocket !!
+ return std::unique_ptr<net::SSLClientSocket>(new net::MockTCPClientSocket(
+ net::AddressList(), capturing_net_log_.get(), ssl_data_.get()));
+ }
+
+ scoped_refptr<net::X509Certificate> ExtractPeerCert() override {
+ return extract_cert_result_
+ ? net::ImportCertFromFile(net::GetTestCertsDirectory(),
+ "ok_cert.pem")
+ : nullptr;
+ }
+
+ bool VerifyChallengeReply() override {
+ EXPECT_FALSE(verify_challenge_disallow_);
+ return verify_challenge_result_;
+ }
+
+ base::Timer* GetTimer() override { return mock_timer_.get(); }
+
+ std::unique_ptr<net::TestNetLog> capturing_net_log_;
+ net::IPEndPoint ip_;
+ // Simulated connect data
+ std::unique_ptr<net::MockConnect> tcp_connect_data_;
+ std::unique_ptr<net::MockConnect> ssl_connect_data_;
+ // Simulated read / write data
+ std::vector<net::MockWrite> writes_;
+ std::vector<net::MockRead> reads_;
+ std::unique_ptr<net::SocketDataProvider> ssl_data_;
+ // Simulated result of peer cert extraction.
+ bool extract_cert_result_;
+ // Simulated result of verifying challenge reply.
+ bool verify_challenge_result_;
+ bool verify_challenge_disallow_;
+ // If true, makes TCP connection process stall. For timeout testing.
+ bool tcp_unresponsive_;
+ std::unique_ptr<base::MockTimer> mock_timer_;
+ MockCastTransport* mock_transport_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCastSocket);
+};
+
+class CastSocketTest : public testing::Test {
+ public:
+ CastSocketTest() : logger_(new Logger()), delegate_(new MockDelegate) {}
+ ~CastSocketTest() override {}
+
+ void SetUp() override { EXPECT_CALL(*delegate_, OnMessage(_)).Times(0); }
+
+ void TearDown() override {
+ if (socket_.get()) {
+ EXPECT_CALL(handler_, OnCloseComplete(net::OK));
+ socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete,
+ base::Unretained(&handler_)));
+ }
+ }
+
+ void CreateCastSocketSecure() {
+ socket_ = TestCastSocket::CreateSecure(logger_);
+ }
+
+ void HandleAuthHandshake() {
+ socket_->SetupMockTransport();
+ CastMessage challenge_proto = CreateAuthChallenge();
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(challenge_proto), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::OK));
+ EXPECT_CALL(*socket_->GetMockTransport(), Start());
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ socket_->GetMockTransport()->current_delegate()->OnMessage(
+ CreateAuthReply());
+ RunPendingTasks();
+ }
+
+ protected:
+ // Runs all pending tasks in the message loop.
+ void RunPendingTasks() {
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ }
+
+ base::MessageLoop message_loop_;
+ Logger* logger_;
+ std::unique_ptr<TestCastSocket> socket_;
+ CompleteHandler handler_;
+ std::unique_ptr<MockDelegate> delegate_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CastSocketTest);
+};
+
+// Tests that the following connection flow works:
+// - TCP connection succeeds (async)
+// - SSL connection succeeds (async)
+// - Cert is extracted successfully
+// - Challenge request is sent (async)
+// - Challenge response is received (async)
+// - Credentials are verified successfuly
+TEST_F(CastSocketTest, TestConnectFullSecureFlowAsync) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnect(net::ASYNC, net::OK);
+ socket_->SetupSslConnect(net::ASYNC, net::OK);
+
+ HandleAuthHandshake();
+
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+}
+
+// Tests that the following connection flow works:
+// - TCP connection succeeds (sync)
+// - SSL connection succeeds (sync)
+// - Cert is extracted successfully
+// - Challenge request is sent (sync)
+// - Challenge response is received (sync)
+// - Credentials are verified successfuly
+TEST_F(CastSocketTest, TestConnectFullSecureFlowSync) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
+
+ HandleAuthHandshake();
+
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+}
+
+// Test that an AuthMessage with a mangled namespace triggers cancelation
+// of the connection event loop.
+TEST_F(CastSocketTest, TestConnectAuthMessageCorrupted) {
+ CreateCastSocketSecure();
+ socket_->SetupMockTransport();
+
+ socket_->SetupTcpConnect(net::ASYNC, net::OK);
+ socket_->SetupSslConnect(net::ASYNC, net::OK);
+
+ CastMessage challenge_proto = CreateAuthChallenge();
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(challenge_proto), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::OK));
+ EXPECT_CALL(*socket_->GetMockTransport(), Start());
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::TRANSPORT_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ CastMessage mangled_auth_reply = CreateAuthReply();
+ mangled_auth_reply.set_namespace_("BOGUS_NAMESPACE");
+
+ socket_->GetMockTransport()->current_delegate()->OnMessage(
+ mangled_auth_reply);
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::TRANSPORT_ERROR, socket_->error_state());
+
+ // Verifies that the CastSocket's resources were torn down during channel
+ // close. (see http://crbug.com/504078)
+ EXPECT_EQ(nullptr, socket_->transport());
+}
+
+// Test connection error - TCP connect fails (async)
+TEST_F(CastSocketTest, TestConnectTcpConnectErrorAsync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
+}
+
+// Test connection error - TCP connect fails (sync)
+TEST_F(CastSocketTest, TestConnectTcpConnectErrorSync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_FAILED);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
+}
+
+// Test connection error - timeout
+TEST_F(CastSocketTest, TestConnectTcpTimeoutError) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnectUnresponsive();
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT));
+ EXPECT_CALL(*delegate_, OnError(ChannelError::CONNECT_TIMEOUT));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CONNECTING, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+ socket_->TriggerTimeout();
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
+}
+
+// Test connection error - TCP socket returns timeout
+TEST_F(CastSocketTest, TestConnectTcpSocketTimeoutError) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_CONNECTION_TIMED_OUT);
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT));
+ EXPECT_CALL(*delegate_, OnError(ChannelError::CONNECT_TIMEOUT));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
+ EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
+ logger_->GetLastErrors(socket_->id()).net_return_value);
+}
+
+// Test connection error - SSL connect fails (async)
+TEST_F(CastSocketTest, TestConnectSslConnectErrorAsync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
+}
+
+// Test connection error - SSL connect fails (sync)
+TEST_F(CastSocketTest, TestConnectSslConnectErrorSync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
+ EXPECT_EQ(net::ERR_FAILED,
+ logger_->GetLastErrors(socket_->id()).net_return_value);
+}
+
+// Test connection error - SSL connect times out (sync)
+TEST_F(CastSocketTest, TestConnectSslConnectTimeoutSync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::ERR_CONNECTION_TIMED_OUT);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
+ EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
+ logger_->GetLastErrors(socket_->id()).net_return_value);
+}
+
+// Test connection error - SSL connect times out (async)
+TEST_F(CastSocketTest, TestConnectSslConnectTimeoutAsync) {
+ CreateCastSocketSecure();
+
+ socket_->SetupTcpConnect(net::ASYNC, net::OK);
+ socket_->SetupSslConnect(net::ASYNC, net::ERR_CONNECTION_TIMED_OUT);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CONNECT_TIMEOUT));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
+}
+
+// Test connection error - challenge send fails
+TEST_F(CastSocketTest, TestConnectChallengeSendError) {
+ CreateCastSocketSecure();
+ socket_->SetupMockTransport();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(CreateAuthChallenge()), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CAST_SOCKET_ERROR));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
+}
+
+// Test connection error - connection is destroyed after the challenge is
+// sent, with the async result still lurking in the task queue.
+TEST_F(CastSocketTest, TestConnectDestroyedAfterChallengeSent) {
+ CreateCastSocketSecure();
+ socket_->SetupMockTransport();
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(CreateAuthChallenge()), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ socket_.reset();
+ RunPendingTasks();
+}
+
+// Test connection error - challenge reply receive fails
+TEST_F(CastSocketTest, TestConnectChallengeReplyReceiveError) {
+ CreateCastSocketSecure();
+ socket_->SetupMockTransport();
+
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(CreateAuthChallenge()), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::OK));
+ socket_->AddReadResult(net::SYNCHRONOUS, net::ERR_FAILED);
+ EXPECT_CALL(*delegate_, OnError(ChannelError::CAST_SOCKET_ERROR));
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::CAST_SOCKET_ERROR));
+ EXPECT_CALL(*socket_->GetMockTransport(), Start());
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ socket_->GetMockTransport()->current_delegate()->OnError(
+ ChannelError::CAST_SOCKET_ERROR);
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
+}
+
+TEST_F(CastSocketTest, TestConnectChallengeVerificationFails) {
+ CreateCastSocketSecure();
+ socket_->SetupMockTransport();
+ socket_->SetupTcpConnect(net::ASYNC, net::OK);
+ socket_->SetupSslConnect(net::ASYNC, net::OK);
+ socket_->SetVerifyChallengeResult(false);
+
+ EXPECT_CALL(*delegate_, OnError(ChannelError::AUTHENTICATION_ERROR));
+ CastMessage challenge_proto = CreateAuthChallenge();
+ EXPECT_CALL(*socket_->GetMockTransport(),
+ SendMessage(EqualsProto(challenge_proto), _))
+ .WillOnce(PostCompletionCallbackTask<1>(net::OK));
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::AUTHENTICATION_ERROR));
+ EXPECT_CALL(*socket_->GetMockTransport(), Start());
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ socket_->GetMockTransport()->current_delegate()->OnMessage(CreateAuthReply());
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
+ EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
+}
+
+// Sends message data through an actual non-mocked CastTransport object,
+// testing the two components in integration.
+TEST_F(CastSocketTest, TestConnectEndToEndWithRealTransportAsync) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnect(net::ASYNC, net::OK);
+ socket_->SetupSslConnect(net::ASYNC, net::OK);
+
+ // Set low-level auth challenge expectations.
+ CastMessage challenge = CreateAuthChallenge();
+ std::string challenge_str;
+ EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
+ socket_->AddWriteResultForData(net::ASYNC, challenge_str);
+
+ // Set low-level auth reply expectations.
+ CastMessage reply = CreateAuthReply();
+ std::string reply_str;
+ EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
+ socket_->AddReadResultForData(net::ASYNC, reply_str);
+ socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
+
+ CastMessage test_message = CreateTestMessage();
+ std::string test_message_str;
+ EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
+ socket_->AddWriteResultForData(net::ASYNC, test_message_str);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+
+ // Send the test message through a real transport object.
+ EXPECT_CALL(handler_, OnWriteComplete(net::OK));
+ socket_->transport()->SendMessage(
+ test_message, base::Bind(&CompleteHandler::OnWriteComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+}
+
+// Same as TestConnectEndToEndWithRealTransportAsync, except synchronous.
+TEST_F(CastSocketTest, TestConnectEndToEndWithRealTransportSync) {
+ CreateCastSocketSecure();
+ socket_->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
+ socket_->SetupSslConnect(net::SYNCHRONOUS, net::OK);
+
+ // Set low-level auth challenge expectations.
+ CastMessage challenge = CreateAuthChallenge();
+ std::string challenge_str;
+ EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
+ socket_->AddWriteResultForData(net::SYNCHRONOUS, challenge_str);
+
+ // Set low-level auth reply expectations.
+ CastMessage reply = CreateAuthReply();
+ std::string reply_str;
+ EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
+ socket_->AddReadResultForData(net::SYNCHRONOUS, reply_str);
+ socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
+
+ CastMessage test_message = CreateTestMessage();
+ std::string test_message_str;
+ EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
+ socket_->AddWriteResultForData(net::SYNCHRONOUS, test_message_str);
+
+ EXPECT_CALL(handler_, OnConnectComplete(ChannelError::NONE));
+ socket_->Connect(std::move(delegate_),
+ base::Bind(&CompleteHandler::OnConnectComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+
+ // Send the test message through a real transport object.
+ EXPECT_CALL(handler_, OnWriteComplete(net::OK));
+ socket_->transport()->SendMessage(
+ test_message, base::Bind(&CompleteHandler::OnWriteComplete,
+ base::Unretained(&handler_)));
+ RunPendingTasks();
+
+ EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
+ EXPECT_EQ(ChannelError::NONE, socket_->error_state());
+}
+
+} // namespace cast_channel
+} // namespace api
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698