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 |