| OLD | NEW |
| (Empty) |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" | |
| 6 | |
| 7 #include "base/memory/weak_ptr.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "base/run_loop.h" | |
| 10 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/sys_byteorder.h" | |
| 12 #include "base/timer/mock_timer.h" | |
| 13 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" | |
| 14 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" | |
| 15 #include "net/base/address_list.h" | |
| 16 #include "net/base/capturing_net_log.h" | |
| 17 #include "net/base/net_errors.h" | |
| 18 #include "net/base/net_util.h" | |
| 19 #include "net/socket/socket_test_util.h" | |
| 20 #include "net/socket/ssl_client_socket.h" | |
| 21 #include "net/socket/tcp_client_socket.h" | |
| 22 #include "net/ssl/ssl_info.h" | |
| 23 #include "testing/gmock/include/gmock/gmock.h" | |
| 24 #include "testing/gtest/include/gtest/gtest.h" | |
| 25 | |
| 26 const int64 kDistantTimeoutMillis = 100000; // 100 seconds (never hit). | |
| 27 | |
| 28 using ::testing::_; | |
| 29 using ::testing::A; | |
| 30 using ::testing::DoAll; | |
| 31 using ::testing::Return; | |
| 32 using ::testing::SaveArg; | |
| 33 | |
| 34 namespace { | |
| 35 const char* kTestData[4] = { | |
| 36 "Hello, World!", | |
| 37 "Goodbye, World!", | |
| 38 "Hello, Sky!", | |
| 39 "Goodbye, Volcano!", | |
| 40 }; | |
| 41 } // namespace | |
| 42 | |
| 43 namespace extensions { | |
| 44 namespace api { | |
| 45 namespace cast_channel { | |
| 46 | |
| 47 // Fills in |message| with a string message. | |
| 48 static void CreateStringMessage(const std::string& namespace_, | |
| 49 const std::string& source_id, | |
| 50 const std::string& destination_id, | |
| 51 const std::string& data, | |
| 52 MessageInfo* message) { | |
| 53 message->namespace_ = namespace_; | |
| 54 message->source_id = source_id; | |
| 55 message->destination_id = destination_id; | |
| 56 message->data.reset(new base::StringValue(data)); | |
| 57 } | |
| 58 | |
| 59 // Fills in |message| with a binary message. | |
| 60 static void CreateBinaryMessage(const std::string& namespace_, | |
| 61 const std::string& source_id, | |
| 62 const std::string& destination_id, | |
| 63 const std::string& data, | |
| 64 MessageInfo* message) { | |
| 65 message->namespace_ = namespace_; | |
| 66 message->source_id = source_id; | |
| 67 message->destination_id = destination_id; | |
| 68 message->data.reset(base::BinaryValue::CreateWithCopiedBuffer( | |
| 69 data.c_str(), data.size())); | |
| 70 } | |
| 71 | |
| 72 class MockCastSocketDelegate : public CastSocket::Delegate { | |
| 73 public: | |
| 74 MOCK_METHOD2(OnError, void(const CastSocket* socket, | |
| 75 ChannelError error)); | |
| 76 MOCK_METHOD2(OnMessage, void(const CastSocket* socket, | |
| 77 const MessageInfo& message)); | |
| 78 }; | |
| 79 | |
| 80 class MockTCPSocket : public net::TCPClientSocket { | |
| 81 public: | |
| 82 explicit MockTCPSocket(const net::MockConnect& connect_data) : | |
| 83 TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()), | |
| 84 connect_data_(connect_data), | |
| 85 do_nothing_(false) { } | |
| 86 | |
| 87 explicit MockTCPSocket(bool do_nothing) : | |
| 88 TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()) { | |
| 89 CHECK(do_nothing); | |
| 90 do_nothing_ = do_nothing; | |
| 91 } | |
| 92 | |
| 93 virtual int Connect(const net::CompletionCallback& callback) OVERRIDE { | |
| 94 if (do_nothing_) { | |
| 95 // Stall the I/O event loop. | |
| 96 return net::ERR_IO_PENDING; | |
| 97 } | |
| 98 | |
| 99 if (connect_data_.mode == net::ASYNC) { | |
| 100 CHECK_NE(connect_data_.result, net::ERR_IO_PENDING); | |
| 101 base::MessageLoop::current()->PostTask( | |
| 102 FROM_HERE, | |
| 103 base::Bind(callback, connect_data_.result)); | |
| 104 return net::ERR_IO_PENDING; | |
| 105 } else { | |
| 106 return connect_data_.result; | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 virtual bool SetKeepAlive(bool enable, int delay) OVERRIDE { | |
| 111 // Always return true in tests | |
| 112 return true; | |
| 113 } | |
| 114 | |
| 115 virtual bool SetNoDelay(bool no_delay) OVERRIDE { | |
| 116 // Always return true in tests | |
| 117 return true; | |
| 118 } | |
| 119 | |
| 120 MOCK_METHOD3(Read, | |
| 121 int(net::IOBuffer*, int, const net::CompletionCallback&)); | |
| 122 MOCK_METHOD3(Write, | |
| 123 int(net::IOBuffer*, int, const net::CompletionCallback&)); | |
| 124 | |
| 125 virtual void Disconnect() OVERRIDE { | |
| 126 // Do nothing in tests | |
| 127 } | |
| 128 | |
| 129 private: | |
| 130 net::MockConnect connect_data_; | |
| 131 bool do_nothing_; | |
| 132 }; | |
| 133 | |
| 134 class CompleteHandler { | |
| 135 public: | |
| 136 CompleteHandler() {} | |
| 137 MOCK_METHOD1(OnCloseComplete, void(int result)); | |
| 138 MOCK_METHOD1(OnConnectComplete, void(int result)); | |
| 139 MOCK_METHOD1(OnWriteComplete, void(int result)); | |
| 140 private: | |
| 141 DISALLOW_COPY_AND_ASSIGN(CompleteHandler); | |
| 142 }; | |
| 143 | |
| 144 class TestCastSocket : public CastSocket { | |
| 145 public: | |
| 146 static scoped_ptr<TestCastSocket> Create( | |
| 147 MockCastSocketDelegate* delegate) { | |
| 148 return scoped_ptr<TestCastSocket>( | |
| 149 new TestCastSocket(delegate, CreateIPEndPoint(), | |
| 150 CHANNEL_AUTH_TYPE_SSL, | |
| 151 kDistantTimeoutMillis)); | |
| 152 } | |
| 153 | |
| 154 static scoped_ptr<TestCastSocket> CreateSecure( | |
| 155 MockCastSocketDelegate* delegate) { | |
| 156 return scoped_ptr<TestCastSocket>( | |
| 157 new TestCastSocket(delegate, CreateIPEndPoint(), | |
| 158 CHANNEL_AUTH_TYPE_SSL_VERIFIED, | |
| 159 kDistantTimeoutMillis)); | |
| 160 } | |
| 161 | |
| 162 explicit TestCastSocket(MockCastSocketDelegate* delegate, | |
| 163 const net::IPEndPoint& ip_endpoint, | |
| 164 ChannelAuthType channel_auth, | |
| 165 int64 timeout_ms) | |
| 166 : CastSocket("abcdefg", | |
| 167 ip_endpoint, | |
| 168 channel_auth, | |
| 169 delegate, | |
| 170 &capturing_net_log_, | |
| 171 base::TimeDelta::FromMilliseconds(timeout_ms)), | |
| 172 ip_(ip_endpoint), | |
| 173 connect_index_(0), | |
| 174 extract_cert_result_(true), | |
| 175 verify_challenge_result_(true), | |
| 176 tcp_unresponsive_(false), | |
| 177 mock_timer_(new base::MockTimer(false, false)) {} | |
| 178 | |
| 179 static net::IPEndPoint CreateIPEndPoint() { | |
| 180 net::IPAddressNumber number; | |
| 181 number.push_back(192); | |
| 182 number.push_back(0); | |
| 183 number.push_back(0); | |
| 184 number.push_back(1); | |
| 185 return net::IPEndPoint(number, 8009); | |
| 186 } | |
| 187 | |
| 188 // Returns the size of the body (in bytes) of the given serialized message. | |
| 189 static size_t ComputeBodySize(const std::string& msg) { | |
| 190 return msg.length() - CastSocket::MessageHeader::header_size(); | |
| 191 } | |
| 192 | |
| 193 virtual ~TestCastSocket() { | |
| 194 } | |
| 195 | |
| 196 // Helpers to set mock results for various operations. | |
| 197 void SetupTcp1Connect(net::IoMode mode, int result) { | |
| 198 tcp_connect_data_[0].reset(new net::MockConnect(mode, result)); | |
| 199 } | |
| 200 void SetupSsl1Connect(net::IoMode mode, int result) { | |
| 201 ssl_connect_data_[0].reset(new net::MockConnect(mode, result)); | |
| 202 } | |
| 203 void SetupTcp2Connect(net::IoMode mode, int result) { | |
| 204 tcp_connect_data_[1].reset(new net::MockConnect(mode, result)); | |
| 205 } | |
| 206 void SetupSsl2Connect(net::IoMode mode, int result) { | |
| 207 ssl_connect_data_[1].reset(new net::MockConnect(mode, result)); | |
| 208 } | |
| 209 void SetupTcp1ConnectUnresponsive() { | |
| 210 tcp_unresponsive_ = true; | |
| 211 } | |
| 212 void AddWriteResult(const net::MockWrite& write) { | |
| 213 writes_.push_back(write); | |
| 214 } | |
| 215 void AddWriteResult(net::IoMode mode, int result) { | |
| 216 AddWriteResult(net::MockWrite(mode, result)); | |
| 217 } | |
| 218 void AddWriteResultForMessage(net::IoMode mode, const std::string& msg) { | |
| 219 AddWriteResult(mode, msg.size()); | |
| 220 } | |
| 221 void AddWriteResultForMessage(net::IoMode mode, | |
| 222 const std::string& msg, | |
| 223 size_t ch_size) { | |
| 224 size_t msg_size = msg.size(); | |
| 225 for (size_t offset = 0; offset < msg_size; offset += ch_size) { | |
| 226 if (offset + ch_size > msg_size) | |
| 227 ch_size = msg_size - offset; | |
| 228 AddWriteResult(mode, ch_size); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 void AddReadResult(const net::MockRead& read) { | |
| 233 reads_.push_back(read); | |
| 234 } | |
| 235 void AddReadResult(net::IoMode mode, int result) { | |
| 236 AddReadResult(net::MockRead(mode, result)); | |
| 237 } | |
| 238 void AddReadResult(net::IoMode mode, const char* data, int data_len) { | |
| 239 AddReadResult(net::MockRead(mode, data, data_len)); | |
| 240 } | |
| 241 void AddReadResultForMessage(net::IoMode mode, const std::string& msg) { | |
| 242 size_t body_size = ComputeBodySize(msg); | |
| 243 const char* data = msg.c_str(); | |
| 244 AddReadResult(mode, data, MessageHeader::header_size()); | |
| 245 AddReadResult(mode, data + MessageHeader::header_size(), body_size); | |
| 246 } | |
| 247 void AddReadResultForMessage(net::IoMode mode, | |
| 248 const std::string& msg, | |
| 249 size_t ch_size) { | |
| 250 size_t msg_size = msg.size(); | |
| 251 const char* data = msg.c_str(); | |
| 252 for (size_t offset = 0; offset < msg_size; offset += ch_size) { | |
| 253 if (offset + ch_size > msg_size) | |
| 254 ch_size = msg_size - offset; | |
| 255 AddReadResult(mode, data + offset, ch_size); | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 void SetExtractCertResult(bool value) { | |
| 260 extract_cert_result_ = value; | |
| 261 } | |
| 262 void SetVerifyChallengeResult(bool value) { | |
| 263 verify_challenge_result_ = value; | |
| 264 } | |
| 265 | |
| 266 void TriggerTimeout() { | |
| 267 mock_timer_->Fire(); | |
| 268 } | |
| 269 | |
| 270 private: | |
| 271 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket() OVERRIDE { | |
| 272 if (tcp_unresponsive_) { | |
| 273 return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(true)); | |
| 274 } else { | |
| 275 net::MockConnect* connect_data = tcp_connect_data_[connect_index_].get(); | |
| 276 connect_data->peer_addr = ip_; | |
| 277 return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(*connect_data)); | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket( | |
| 282 scoped_ptr<net::StreamSocket> socket) OVERRIDE { | |
| 283 net::MockConnect* connect_data = ssl_connect_data_[connect_index_].get(); | |
| 284 connect_data->peer_addr = ip_; | |
| 285 ++connect_index_; | |
| 286 | |
| 287 ssl_data_.reset(new net::StaticSocketDataProvider( | |
| 288 reads_.data(), reads_.size(), writes_.data(), writes_.size())); | |
| 289 ssl_data_->set_connect_data(*connect_data); | |
| 290 // NOTE: net::MockTCPClientSocket inherits from net::SSLClientSocket !! | |
| 291 return scoped_ptr<net::SSLClientSocket>( | |
| 292 new net::MockTCPClientSocket( | |
| 293 net::AddressList(), &capturing_net_log_, ssl_data_.get())); | |
| 294 } | |
| 295 | |
| 296 virtual bool ExtractPeerCert(std::string* cert) OVERRIDE { | |
| 297 if (extract_cert_result_) | |
| 298 cert->assign("dummy_test_cert"); | |
| 299 return extract_cert_result_; | |
| 300 } | |
| 301 | |
| 302 virtual bool VerifyChallengeReply() OVERRIDE { | |
| 303 return verify_challenge_result_; | |
| 304 } | |
| 305 | |
| 306 virtual base::Timer* GetTimer() OVERRIDE { | |
| 307 return mock_timer_.get(); | |
| 308 } | |
| 309 | |
| 310 net::CapturingNetLog capturing_net_log_; | |
| 311 net::IPEndPoint ip_; | |
| 312 // Simulated connect data | |
| 313 scoped_ptr<net::MockConnect> tcp_connect_data_[2]; | |
| 314 scoped_ptr<net::MockConnect> ssl_connect_data_[2]; | |
| 315 // Simulated read / write data | |
| 316 std::vector<net::MockWrite> writes_; | |
| 317 std::vector<net::MockRead> reads_; | |
| 318 scoped_ptr<net::SocketDataProvider> ssl_data_; | |
| 319 // Number of times Connect method is called | |
| 320 size_t connect_index_; | |
| 321 // Simulated result of peer cert extraction. | |
| 322 bool extract_cert_result_; | |
| 323 // Simulated result of verifying challenge reply. | |
| 324 bool verify_challenge_result_; | |
| 325 // If true, makes TCP connection process stall. For timeout testing. | |
| 326 bool tcp_unresponsive_; | |
| 327 scoped_ptr<base::MockTimer> mock_timer_; | |
| 328 }; | |
| 329 | |
| 330 class CastSocketTest : public testing::Test { | |
| 331 public: | |
| 332 CastSocketTest() {} | |
| 333 virtual ~CastSocketTest() {} | |
| 334 | |
| 335 virtual void SetUp() OVERRIDE { | |
| 336 // Create a few test messages | |
| 337 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
| 338 CreateStringMessage("urn:cast", "1", "2", kTestData[i], | |
| 339 &test_messages_[i]); | |
| 340 ASSERT_TRUE(MessageInfoToCastMessage( | |
| 341 test_messages_[i], &test_protos_[i])); | |
| 342 ASSERT_TRUE(CastSocket::Serialize(test_protos_[i], &test_proto_strs_[i])); | |
| 343 } | |
| 344 | |
| 345 // Create a test auth request. | |
| 346 CastMessage request; | |
| 347 CreateAuthChallengeMessage(&request); | |
| 348 ASSERT_TRUE(CastSocket::Serialize(request, &auth_request_)); | |
| 349 | |
| 350 // Create a test auth reply. | |
| 351 MessageInfo reply; | |
| 352 CreateBinaryMessage("urn:x-cast:com.google.cast.tp.deviceauth", | |
| 353 "sender-0", | |
| 354 "receiver-0", | |
| 355 "abcd", | |
| 356 &reply); | |
| 357 CastMessage reply_msg; | |
| 358 ASSERT_TRUE(MessageInfoToCastMessage(reply, &reply_msg)); | |
| 359 ASSERT_TRUE(CastSocket::Serialize(reply_msg, &auth_reply_)); | |
| 360 } | |
| 361 | |
| 362 virtual void TearDown() OVERRIDE { | |
| 363 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); | |
| 364 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, | |
| 365 base::Unretained(&handler_))); | |
| 366 } | |
| 367 | |
| 368 void CreateCastSocket() { | |
| 369 socket_ = TestCastSocket::Create(&mock_delegate_); | |
| 370 } | |
| 371 | |
| 372 void CreateCastSocketSecure() { | |
| 373 socket_ = TestCastSocket::CreateSecure(&mock_delegate_); | |
| 374 } | |
| 375 | |
| 376 // Sets up CastSocket::Connect to succeed. | |
| 377 // Connecting the socket also starts the read loop; so we add a mock | |
| 378 // read result that returns IO_PENDING and callback is never fired. | |
| 379 void ConnectHelper() { | |
| 380 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 381 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::OK); | |
| 382 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 383 | |
| 384 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
| 385 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 386 base::Unretained(&handler_))); | |
| 387 RunPendingTasks(); | |
| 388 } | |
| 389 | |
| 390 protected: | |
| 391 // Runs all pending tasks in the message loop. | |
| 392 void RunPendingTasks() { | |
| 393 base::RunLoop run_loop; | |
| 394 run_loop.RunUntilIdle(); | |
| 395 } | |
| 396 | |
| 397 base::MessageLoop message_loop_; | |
| 398 MockCastSocketDelegate mock_delegate_; | |
| 399 scoped_ptr<TestCastSocket> socket_; | |
| 400 CompleteHandler handler_; | |
| 401 MessageInfo test_messages_[arraysize(kTestData)]; | |
| 402 CastMessage test_protos_[arraysize(kTestData)]; | |
| 403 std::string test_proto_strs_[arraysize(kTestData)]; | |
| 404 std::string auth_request_; | |
| 405 std::string auth_reply_; | |
| 406 }; | |
| 407 | |
| 408 // Tests connecting and closing the socket. | |
| 409 TEST_F(CastSocketTest, TestConnectAndClose) { | |
| 410 CreateCastSocket(); | |
| 411 ConnectHelper(); | |
| 412 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 413 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 414 | |
| 415 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); | |
| 416 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, | |
| 417 base::Unretained(&handler_))); | |
| 418 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 419 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 420 } | |
| 421 | |
| 422 // Tests that the following connection flow works: | |
| 423 // - TCP connection succeeds (async) | |
| 424 // - SSL connection succeeds (async) | |
| 425 TEST_F(CastSocketTest, TestConnect) { | |
| 426 CreateCastSocket(); | |
| 427 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
| 428 socket_->SetupSsl1Connect(net::ASYNC, net::OK); | |
| 429 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 430 | |
| 431 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
| 432 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 433 base::Unretained(&handler_))); | |
| 434 RunPendingTasks(); | |
| 435 | |
| 436 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 437 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 438 } | |
| 439 | |
| 440 // Test that the following connection flow works: | |
| 441 // - TCP connection succeeds (async) | |
| 442 // - SSL connection fails with cert error (async) | |
| 443 // - Cert is extracted successfully | |
| 444 // - Second TCP connection succeeds (async) | |
| 445 // - Second SSL connection succeeds (async) | |
| 446 TEST_F(CastSocketTest, TestConnectTwoStep) { | |
| 447 CreateCastSocket(); | |
| 448 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
| 449 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
| 450 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
| 451 socket_->SetupSsl2Connect(net::ASYNC, net::OK); | |
| 452 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 453 | |
| 454 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
| 455 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 456 base::Unretained(&handler_))); | |
| 457 RunPendingTasks(); | |
| 458 | |
| 459 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 460 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 461 } | |
| 462 | |
| 463 // Test that the following connection flow works: | |
| 464 // - TCP connection succeeds (async) | |
| 465 // - SSL connection fails with cert error (async) | |
| 466 // - Cert is extracted successfully | |
| 467 // - Second TCP connection succeeds (async) | |
| 468 // - Second SSL connection fails (async) | |
| 469 // - The flow should NOT be tried again | |
| 470 TEST_F(CastSocketTest, TestConnectMaxTwoAttempts) { | |
| 471 CreateCastSocket(); | |
| 472 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
| 473 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
| 474 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
| 475 socket_->SetupSsl2Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
| 476 | |
| 477 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); | |
| 478 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 479 base::Unretained(&handler_))); | |
| 480 RunPendingTasks(); | |
| 481 | |
| 482 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 483 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 484 } | |
| 485 | |
| 486 // Tests that the following connection flow works: | |
| 487 // - TCP connection succeeds (async) | |
| 488 // - SSL connection fails with cert error (async) | |
| 489 // - Cert is extracted successfully | |
| 490 // - Second TCP connection succeeds (async) | |
| 491 // - Second SSL connection succeeds (async) | |
| 492 // - Challenge request is sent (async) | |
| 493 // - Challenge response is received (async) | |
| 494 // - Credentials are verified successfuly | |
| 495 TEST_F(CastSocketTest, TestConnectFullSecureFlowAsync) { | |
| 496 CreateCastSocketSecure(); | |
| 497 | |
| 498 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
| 499 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
| 500 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
| 501 socket_->SetupSsl2Connect(net::ASYNC, net::OK); | |
| 502 socket_->AddWriteResultForMessage(net::ASYNC, auth_request_); | |
| 503 socket_->AddReadResultForMessage(net::ASYNC, auth_reply_); | |
| 504 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 505 | |
| 506 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
| 507 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 508 base::Unretained(&handler_))); | |
| 509 RunPendingTasks(); | |
| 510 | |
| 511 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 512 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 513 } | |
| 514 | |
| 515 // Same as TestFullSecureConnectionFlowAsync, but operations are synchronous. | |
| 516 TEST_F(CastSocketTest, TestConnectFullSecureFlowSync) { | |
| 517 CreateCastSocketSecure(); | |
| 518 | |
| 519 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 520 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::ERR_CERT_AUTHORITY_INVALID); | |
| 521 socket_->SetupTcp2Connect(net::SYNCHRONOUS, net::OK); | |
| 522 socket_->SetupSsl2Connect(net::SYNCHRONOUS, net::OK); | |
| 523 socket_->AddWriteResultForMessage(net::SYNCHRONOUS, auth_request_); | |
| 524 socket_->AddReadResultForMessage(net::SYNCHRONOUS, auth_reply_); | |
| 525 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 526 | |
| 527 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
| 528 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 529 base::Unretained(&handler_))); | |
| 530 RunPendingTasks(); | |
| 531 | |
| 532 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 533 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 534 } | |
| 535 | |
| 536 // Test connection error - TCP connect fails (async) | |
| 537 TEST_F(CastSocketTest, TestConnectTcpConnectErrorAsync) { | |
| 538 CreateCastSocketSecure(); | |
| 539 | |
| 540 socket_->SetupTcp1Connect(net::ASYNC, net::ERR_FAILED); | |
| 541 | |
| 542 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 543 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 544 base::Unretained(&handler_))); | |
| 545 RunPendingTasks(); | |
| 546 | |
| 547 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 548 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 549 } | |
| 550 | |
| 551 // Test connection error - TCP connect fails (sync) | |
| 552 TEST_F(CastSocketTest, TestConnectTcpConnectErrorSync) { | |
| 553 CreateCastSocketSecure(); | |
| 554 | |
| 555 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::ERR_FAILED); | |
| 556 | |
| 557 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 558 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 559 base::Unretained(&handler_))); | |
| 560 RunPendingTasks(); | |
| 561 | |
| 562 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 563 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 564 } | |
| 565 | |
| 566 // Test connection error - timeout | |
| 567 TEST_F(CastSocketTest, TestConnectTcpTimeoutError) { | |
| 568 CreateCastSocketSecure(); | |
| 569 socket_->SetupTcp1ConnectUnresponsive(); | |
| 570 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_TIMED_OUT)); | |
| 571 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 572 base::Unretained(&handler_))); | |
| 573 RunPendingTasks(); | |
| 574 | |
| 575 EXPECT_EQ(cast_channel::READY_STATE_CONNECTING, socket_->ready_state()); | |
| 576 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 577 socket_->TriggerTimeout(); | |
| 578 RunPendingTasks(); | |
| 579 | |
| 580 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 581 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_TIMEOUT, | |
| 582 socket_->error_state()); | |
| 583 } | |
| 584 | |
| 585 // Test connection error - SSL connect fails (async) | |
| 586 TEST_F(CastSocketTest, TestConnectSslConnectErrorAsync) { | |
| 587 CreateCastSocketSecure(); | |
| 588 | |
| 589 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 590 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::ERR_FAILED); | |
| 591 | |
| 592 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 593 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 594 base::Unretained(&handler_))); | |
| 595 RunPendingTasks(); | |
| 596 | |
| 597 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 598 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 599 } | |
| 600 | |
| 601 // Test connection error - SSL connect fails (sync) | |
| 602 TEST_F(CastSocketTest, TestConnectSslConnectErrorSync) { | |
| 603 CreateCastSocketSecure(); | |
| 604 | |
| 605 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 606 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_FAILED); | |
| 607 | |
| 608 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 609 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 610 base::Unretained(&handler_))); | |
| 611 RunPendingTasks(); | |
| 612 | |
| 613 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 614 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 615 } | |
| 616 | |
| 617 // Test connection error - cert extraction error (async) | |
| 618 TEST_F(CastSocketTest, TestConnectCertExtractionErrorAsync) { | |
| 619 CreateCastSocket(); | |
| 620 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
| 621 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
| 622 // Set cert extraction to fail | |
| 623 socket_->SetExtractCertResult(false); | |
| 624 | |
| 625 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); | |
| 626 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 627 base::Unretained(&handler_))); | |
| 628 RunPendingTasks(); | |
| 629 | |
| 630 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 631 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 632 } | |
| 633 | |
| 634 // Test connection error - cert extraction error (sync) | |
| 635 TEST_F(CastSocketTest, TestConnectCertExtractionErrorSync) { | |
| 636 CreateCastSocket(); | |
| 637 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 638 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::ERR_CERT_AUTHORITY_INVALID); | |
| 639 // Set cert extraction to fail | |
| 640 socket_->SetExtractCertResult(false); | |
| 641 | |
| 642 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); | |
| 643 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 644 base::Unretained(&handler_))); | |
| 645 RunPendingTasks(); | |
| 646 | |
| 647 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 648 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 649 } | |
| 650 | |
| 651 // Test connection error - challenge send fails | |
| 652 TEST_F(CastSocketTest, TestConnectChallengeSendError) { | |
| 653 CreateCastSocketSecure(); | |
| 654 | |
| 655 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 656 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::OK); | |
| 657 socket_->AddWriteResult(net::SYNCHRONOUS, net::ERR_FAILED); | |
| 658 | |
| 659 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 660 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 661 base::Unretained(&handler_))); | |
| 662 RunPendingTasks(); | |
| 663 | |
| 664 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 665 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 666 } | |
| 667 | |
| 668 // Test connection error - challenge reply receive fails | |
| 669 TEST_F(CastSocketTest, TestConnectChallengeReplyReceiveError) { | |
| 670 CreateCastSocketSecure(); | |
| 671 | |
| 672 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 673 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::OK); | |
| 674 socket_->AddWriteResultForMessage(net::ASYNC, auth_request_); | |
| 675 socket_->AddReadResult(net::SYNCHRONOUS, net::ERR_FAILED); | |
| 676 | |
| 677 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 678 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 679 base::Unretained(&handler_))); | |
| 680 RunPendingTasks(); | |
| 681 | |
| 682 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 683 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 684 } | |
| 685 | |
| 686 // Test connection error - challenge reply verification fails | |
| 687 TEST_F(CastSocketTest, TestConnectChallengeVerificationFails) { | |
| 688 CreateCastSocketSecure(); | |
| 689 | |
| 690 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); | |
| 691 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::OK); | |
| 692 socket_->AddWriteResultForMessage(net::ASYNC, auth_request_); | |
| 693 socket_->AddReadResultForMessage(net::ASYNC, auth_reply_); | |
| 694 socket_->AddReadResult(net::ASYNC, net::ERR_IO_PENDING); | |
| 695 socket_->SetVerifyChallengeResult(false); | |
| 696 | |
| 697 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_FAILED)); | |
| 698 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
| 699 base::Unretained(&handler_))); | |
| 700 RunPendingTasks(); | |
| 701 | |
| 702 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 703 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | |
| 704 } | |
| 705 | |
| 706 // Test write success - single message (async) | |
| 707 TEST_F(CastSocketTest, TestWriteAsync) { | |
| 708 CreateCastSocket(); | |
| 709 socket_->AddWriteResultForMessage(net::ASYNC, test_proto_strs_[0]); | |
| 710 ConnectHelper(); | |
| 711 | |
| 712 EXPECT_CALL(handler_, OnWriteComplete(test_proto_strs_[0].size())); | |
| 713 socket_->SendMessage(test_messages_[0], | |
| 714 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 715 base::Unretained(&handler_))); | |
| 716 RunPendingTasks(); | |
| 717 | |
| 718 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 719 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 720 } | |
| 721 | |
| 722 // Test write success - single message (sync) | |
| 723 TEST_F(CastSocketTest, TestWriteSync) { | |
| 724 CreateCastSocket(); | |
| 725 socket_->AddWriteResultForMessage(net::SYNCHRONOUS, test_proto_strs_[0]); | |
| 726 ConnectHelper(); | |
| 727 | |
| 728 EXPECT_CALL(handler_, OnWriteComplete(test_proto_strs_[0].size())); | |
| 729 socket_->SendMessage(test_messages_[0], | |
| 730 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 731 base::Unretained(&handler_))); | |
| 732 RunPendingTasks(); | |
| 733 | |
| 734 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 735 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 736 } | |
| 737 | |
| 738 // Test write success - single message sent in multiple chunks (async) | |
| 739 TEST_F(CastSocketTest, TestWriteChunkedAsync) { | |
| 740 CreateCastSocket(); | |
| 741 socket_->AddWriteResultForMessage(net::ASYNC, test_proto_strs_[0], 2); | |
| 742 ConnectHelper(); | |
| 743 | |
| 744 EXPECT_CALL(handler_, OnWriteComplete(test_proto_strs_[0].size())); | |
| 745 socket_->SendMessage(test_messages_[0], | |
| 746 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 747 base::Unretained(&handler_))); | |
| 748 RunPendingTasks(); | |
| 749 | |
| 750 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 751 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 752 } | |
| 753 | |
| 754 // Test write success - single message sent in multiple chunks (sync) | |
| 755 TEST_F(CastSocketTest, TestWriteChunkedSync) { | |
| 756 CreateCastSocket(); | |
| 757 socket_->AddWriteResultForMessage(net::SYNCHRONOUS, test_proto_strs_[0], 2); | |
| 758 ConnectHelper(); | |
| 759 | |
| 760 EXPECT_CALL(handler_, OnWriteComplete(test_proto_strs_[0].size())); | |
| 761 socket_->SendMessage(test_messages_[0], | |
| 762 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 763 base::Unretained(&handler_))); | |
| 764 RunPendingTasks(); | |
| 765 | |
| 766 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 767 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 768 } | |
| 769 | |
| 770 // Test write success - multiple messages (async) | |
| 771 TEST_F(CastSocketTest, TestWriteManyAsync) { | |
| 772 CreateCastSocket(); | |
| 773 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
| 774 size_t msg_size = test_proto_strs_[i].size(); | |
| 775 socket_->AddWriteResult(net::ASYNC, msg_size); | |
| 776 EXPECT_CALL(handler_, OnWriteComplete(msg_size)); | |
| 777 } | |
| 778 ConnectHelper(); | |
| 779 | |
| 780 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
| 781 socket_->SendMessage(test_messages_[i], | |
| 782 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 783 base::Unretained(&handler_))); | |
| 784 } | |
| 785 RunPendingTasks(); | |
| 786 | |
| 787 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 788 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 789 } | |
| 790 | |
| 791 // Test write success - multiple messages (sync) | |
| 792 TEST_F(CastSocketTest, TestWriteManySync) { | |
| 793 CreateCastSocket(); | |
| 794 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
| 795 size_t msg_size = test_proto_strs_[i].size(); | |
| 796 socket_->AddWriteResult(net::SYNCHRONOUS, msg_size); | |
| 797 EXPECT_CALL(handler_, OnWriteComplete(msg_size)); | |
| 798 } | |
| 799 ConnectHelper(); | |
| 800 | |
| 801 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
| 802 socket_->SendMessage(test_messages_[i], | |
| 803 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 804 base::Unretained(&handler_))); | |
| 805 } | |
| 806 RunPendingTasks(); | |
| 807 | |
| 808 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 809 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 810 } | |
| 811 | |
| 812 // Test write error - not connected | |
| 813 TEST_F(CastSocketTest, TestWriteErrorNotConnected) { | |
| 814 CreateCastSocket(); | |
| 815 | |
| 816 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_FAILED)); | |
| 817 socket_->SendMessage(test_messages_[0], | |
| 818 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 819 base::Unretained(&handler_))); | |
| 820 | |
| 821 EXPECT_EQ(cast_channel::READY_STATE_NONE, socket_->ready_state()); | |
| 822 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 823 } | |
| 824 | |
| 825 // Test write error - very large message | |
| 826 TEST_F(CastSocketTest, TestWriteErrorLargeMessage) { | |
| 827 CreateCastSocket(); | |
| 828 ConnectHelper(); | |
| 829 | |
| 830 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_FAILED)); | |
| 831 size_t size = CastSocket::MessageHeader::max_message_size() + 1; | |
| 832 test_messages_[0].data.reset( | |
| 833 new base::StringValue(std::string(size, 'a'))); | |
| 834 socket_->SendMessage(test_messages_[0], | |
| 835 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 836 base::Unretained(&handler_))); | |
| 837 | |
| 838 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 839 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 840 | |
| 841 } | |
| 842 | |
| 843 // Test write error - network error (sync) | |
| 844 TEST_F(CastSocketTest, TestWriteNetworkErrorSync) { | |
| 845 CreateCastSocket(); | |
| 846 socket_->AddWriteResult(net::SYNCHRONOUS, net::ERR_FAILED); | |
| 847 ConnectHelper(); | |
| 848 | |
| 849 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_FAILED)); | |
| 850 EXPECT_CALL(mock_delegate_, | |
| 851 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 852 socket_->SendMessage(test_messages_[0], | |
| 853 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 854 base::Unretained(&handler_))); | |
| 855 RunPendingTasks(); | |
| 856 | |
| 857 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 858 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 859 } | |
| 860 | |
| 861 // Test write error - network error (async) | |
| 862 TEST_F(CastSocketTest, TestWriteErrorAsync) { | |
| 863 CreateCastSocket(); | |
| 864 socket_->AddWriteResult(net::ASYNC, net::ERR_FAILED); | |
| 865 ConnectHelper(); | |
| 866 | |
| 867 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_FAILED)); | |
| 868 EXPECT_CALL(mock_delegate_, | |
| 869 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 870 socket_->SendMessage(test_messages_[0], | |
| 871 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 872 base::Unretained(&handler_))); | |
| 873 RunPendingTasks(); | |
| 874 | |
| 875 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 876 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 877 } | |
| 878 | |
| 879 // Test write error - 0 bytes written should be considered an error | |
| 880 TEST_F(CastSocketTest, TestWriteErrorZeroBytesWritten) { | |
| 881 CreateCastSocket(); | |
| 882 socket_->AddWriteResult(net::SYNCHRONOUS, 0); | |
| 883 ConnectHelper(); | |
| 884 | |
| 885 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_FAILED)); | |
| 886 EXPECT_CALL(mock_delegate_, | |
| 887 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 888 socket_->SendMessage(test_messages_[0], | |
| 889 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 890 base::Unretained(&handler_))); | |
| 891 RunPendingTasks(); | |
| 892 | |
| 893 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 894 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 895 } | |
| 896 | |
| 897 // Test that when an error occurrs in one write, write callback is invoked for | |
| 898 // all pending writes with the error | |
| 899 TEST_F(CastSocketTest, TestWriteErrorWithMultiplePendingWritesAsync) { | |
| 900 CreateCastSocket(); | |
| 901 socket_->AddWriteResult(net::ASYNC, net::ERR_SOCKET_NOT_CONNECTED); | |
| 902 ConnectHelper(); | |
| 903 | |
| 904 const int num_writes = arraysize(test_messages_); | |
| 905 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_SOCKET_NOT_CONNECTED)) | |
| 906 .Times(num_writes); | |
| 907 EXPECT_CALL(mock_delegate_, | |
| 908 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 909 for (int i = 0; i < num_writes; i++) { | |
| 910 socket_->SendMessage(test_messages_[i], | |
| 911 base::Bind(&CompleteHandler::OnWriteComplete, | |
| 912 base::Unretained(&handler_))); | |
| 913 } | |
| 914 RunPendingTasks(); | |
| 915 | |
| 916 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 917 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 918 } | |
| 919 | |
| 920 // Test read success - single message (async) | |
| 921 TEST_F(CastSocketTest, TestReadAsync) { | |
| 922 CreateCastSocket(); | |
| 923 socket_->AddReadResultForMessage(net::ASYNC, test_proto_strs_[0]); | |
| 924 EXPECT_CALL(mock_delegate_, | |
| 925 OnMessage(socket_.get(), A<const MessageInfo&>())); | |
| 926 ConnectHelper(); | |
| 927 | |
| 928 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 929 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 930 } | |
| 931 | |
| 932 // Test read success - single message (sync) | |
| 933 TEST_F(CastSocketTest, TestReadSync) { | |
| 934 CreateCastSocket(); | |
| 935 socket_->AddReadResultForMessage(net::SYNCHRONOUS, test_proto_strs_[0]); | |
| 936 EXPECT_CALL(mock_delegate_, | |
| 937 OnMessage(socket_.get(), A<const MessageInfo&>())); | |
| 938 ConnectHelper(); | |
| 939 | |
| 940 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 941 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 942 } | |
| 943 | |
| 944 // Test read success - single message received in multiple chunks (async) | |
| 945 TEST_F(CastSocketTest, TestReadChunkedAsync) { | |
| 946 CreateCastSocket(); | |
| 947 socket_->AddReadResultForMessage(net::ASYNC, test_proto_strs_[0], 2); | |
| 948 EXPECT_CALL(mock_delegate_, | |
| 949 OnMessage(socket_.get(), A<const MessageInfo&>())); | |
| 950 ConnectHelper(); | |
| 951 | |
| 952 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 953 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 954 } | |
| 955 | |
| 956 // Test read success - single message received in multiple chunks (sync) | |
| 957 TEST_F(CastSocketTest, TestReadChunkedSync) { | |
| 958 CreateCastSocket(); | |
| 959 socket_->AddReadResultForMessage(net::SYNCHRONOUS, test_proto_strs_[0], 2); | |
| 960 EXPECT_CALL(mock_delegate_, | |
| 961 OnMessage(socket_.get(), A<const MessageInfo&>())); | |
| 962 ConnectHelper(); | |
| 963 | |
| 964 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 965 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 966 } | |
| 967 | |
| 968 // Test read success - multiple messages (async) | |
| 969 TEST_F(CastSocketTest, TestReadManyAsync) { | |
| 970 CreateCastSocket(); | |
| 971 size_t num_reads = arraysize(test_proto_strs_); | |
| 972 for (size_t i = 0; i < num_reads; i++) | |
| 973 socket_->AddReadResultForMessage(net::ASYNC, test_proto_strs_[i]); | |
| 974 EXPECT_CALL(mock_delegate_, | |
| 975 OnMessage(socket_.get(), A<const MessageInfo&>())) | |
| 976 .Times(num_reads); | |
| 977 ConnectHelper(); | |
| 978 | |
| 979 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 980 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 981 } | |
| 982 | |
| 983 // Test read success - multiple messages (sync) | |
| 984 TEST_F(CastSocketTest, TestReadManySync) { | |
| 985 CreateCastSocket(); | |
| 986 size_t num_reads = arraysize(test_proto_strs_); | |
| 987 for (size_t i = 0; i < num_reads; i++) | |
| 988 socket_->AddReadResultForMessage(net::SYNCHRONOUS, test_proto_strs_[i]); | |
| 989 EXPECT_CALL(mock_delegate_, | |
| 990 OnMessage(socket_.get(), A<const MessageInfo&>())) | |
| 991 .Times(num_reads); | |
| 992 ConnectHelper(); | |
| 993 | |
| 994 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
| 995 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
| 996 } | |
| 997 | |
| 998 // Test read error - network error (async) | |
| 999 TEST_F(CastSocketTest, TestReadErrorAsync) { | |
| 1000 CreateCastSocket(); | |
| 1001 socket_->AddReadResult(net::ASYNC, net::ERR_SOCKET_NOT_CONNECTED); | |
| 1002 EXPECT_CALL(mock_delegate_, | |
| 1003 OnError(socket_.get(), | |
| 1004 cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 1005 ConnectHelper(); | |
| 1006 | |
| 1007 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 1008 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 1009 } | |
| 1010 | |
| 1011 // Test read error - network error (sync) | |
| 1012 TEST_F(CastSocketTest, TestReadErrorSync) { | |
| 1013 CreateCastSocket(); | |
| 1014 socket_->AddReadResult(net::SYNCHRONOUS, net::ERR_SOCKET_NOT_CONNECTED); | |
| 1015 EXPECT_CALL(mock_delegate_, | |
| 1016 OnError(socket_.get(), | |
| 1017 cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
| 1018 ConnectHelper(); | |
| 1019 | |
| 1020 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 1021 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
| 1022 } | |
| 1023 | |
| 1024 // Test read error - header parse error | |
| 1025 TEST_F(CastSocketTest, TestReadHeaderParseError) { | |
| 1026 CreateCastSocket(); | |
| 1027 uint32 body_size = base::HostToNet32( | |
| 1028 CastSocket::MessageHeader::max_message_size() + 1); | |
| 1029 // TODO(munjal): Add a method to cast_message_util.h to serialize messages | |
| 1030 char header[sizeof(body_size)]; | |
| 1031 memcpy(&header, &body_size, arraysize(header)); | |
| 1032 socket_->AddReadResult(net::SYNCHRONOUS, header, arraysize(header)); | |
| 1033 EXPECT_CALL(mock_delegate_, | |
| 1034 OnError(socket_.get(), | |
| 1035 cast_channel::CHANNEL_ERROR_INVALID_MESSAGE)); | |
| 1036 ConnectHelper(); | |
| 1037 | |
| 1038 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 1039 EXPECT_EQ(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, | |
| 1040 socket_->error_state()); | |
| 1041 } | |
| 1042 | |
| 1043 // Test read error - body parse error | |
| 1044 TEST_F(CastSocketTest, TestReadBodyParseError) { | |
| 1045 CreateCastSocket(); | |
| 1046 char body[] = "some body"; | |
| 1047 uint32 body_size = base::HostToNet32(arraysize(body)); | |
| 1048 char header[sizeof(body_size)]; | |
| 1049 memcpy(&header, &body_size, arraysize(header)); | |
| 1050 socket_->AddReadResult(net::SYNCHRONOUS, header, arraysize(header)); | |
| 1051 socket_->AddReadResult(net::SYNCHRONOUS, body, arraysize(body)); | |
| 1052 EXPECT_CALL(mock_delegate_, | |
| 1053 OnError(socket_.get(), | |
| 1054 cast_channel::CHANNEL_ERROR_INVALID_MESSAGE)); | |
| 1055 ConnectHelper(); | |
| 1056 | |
| 1057 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
| 1058 EXPECT_EQ(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE, | |
| 1059 socket_->error_state()); | |
| 1060 } | |
| 1061 | |
| 1062 } // namespace cast_channel | |
| 1063 } // namespace api | |
| 1064 } // namespace extensions | |
| OLD | NEW |