OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" | 5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" |
6 | 6 |
7 #include "base/message_loop/message_loop.h" | |
8 #include "base/run_loop.h" | |
9 #include "base/strings/string_number_conversions.h" | |
7 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" | 10 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" |
8 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" | 11 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" |
9 #include "net/base/address_list.h" | 12 #include "net/base/address_list.h" |
10 #include "net/base/capturing_net_log.h" | 13 #include "net/base/capturing_net_log.h" |
11 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
12 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
13 #include "net/base/net_log.h" | 16 #include "net/base/net_log.h" |
14 #include "net/socket/socket_test_util.h" | 17 #include "net/socket/socket_test_util.h" |
15 #include "net/socket/ssl_client_socket.h" | 18 #include "net/socket/ssl_client_socket.h" |
16 #include "net/socket/tcp_client_socket.h" | 19 #include "net/socket/tcp_client_socket.h" |
17 #include "net/ssl/ssl_info.h" | 20 #include "net/ssl/ssl_info.h" |
18 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
20 | 23 |
21 using ::testing::_; | 24 using ::testing::_; |
22 using ::testing::A; | 25 using ::testing::A; |
23 using ::testing::DoAll; | 26 using ::testing::DoAll; |
24 using ::testing::Return; | 27 using ::testing::Return; |
25 using ::testing::SaveArg; | 28 using ::testing::SaveArg; |
26 | 29 |
30 namespace { | |
31 const char* kTestData[4] = { | |
32 "Hello, World!", | |
33 "Goodbye, World!", | |
34 "Hello, Sky!", | |
35 "Goodbye, Volcano!", | |
36 }; | |
37 } | |
38 | |
27 namespace extensions { | 39 namespace extensions { |
28 namespace api { | 40 namespace api { |
29 namespace cast_channel { | 41 namespace cast_channel { |
30 | 42 |
31 class MockCastSocketDelegate : public CastSocket::Delegate { | 43 class MockCastSocketDelegate : public CastSocket::Delegate { |
32 public: | 44 public: |
33 MOCK_METHOD2(OnError, void(const CastSocket* socket, | 45 MOCK_METHOD2(OnError, void(const CastSocket* socket, |
34 ChannelError error)); | 46 ChannelError error)); |
35 MOCK_METHOD2(OnMessage, void(const CastSocket* socket, | 47 MOCK_METHOD2(OnMessage, void(const CastSocket* socket, |
36 const MessageInfo& message)); | 48 const MessageInfo& message)); |
37 }; | 49 }; |
38 | 50 |
39 class MockTCPClientSocket : public net::TCPClientSocket { | 51 class MockTCPSocket : public net::TCPClientSocket { |
40 public: | 52 public: |
41 explicit MockTCPClientSocket() : | 53 explicit MockTCPSocket(const net::MockConnect& connect_data) : |
42 TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()) { } | 54 TCPClientSocket(net::AddressList(), NULL, net::NetLog::Source()), |
43 virtual ~MockTCPClientSocket() { } | 55 connect_data_(connect_data) { } |
44 | 56 |
45 MOCK_METHOD1(Connect, int(const net::CompletionCallback& callback)); | 57 virtual int Connect(const net::CompletionCallback& callback) OVERRIDE { |
46 MOCK_METHOD2(SetKeepAlive, bool(bool, int)); | 58 if (connect_data_.mode == net::ASYNC) { |
47 MOCK_METHOD1(SetNoDelay, bool(bool)); | 59 CHECK_NE(connect_data_.result, net::ERR_IO_PENDING); |
48 MOCK_METHOD3(Read, int(net::IOBuffer* buf, int buf_len, | 60 base::MessageLoop::current()->PostTask( |
49 const net::CompletionCallback& callback)); | 61 FROM_HERE, |
50 MOCK_METHOD3(Write, int(net::IOBuffer* buf, int buf_len, | 62 base::Bind(callback, connect_data_.result)); |
51 const net::CompletionCallback& callback)); | 63 return net::ERR_IO_PENDING; |
52 MOCK_METHOD0(Disconnect, void()); | 64 } else { |
53 }; | 65 return connect_data_.result; |
66 } | |
67 } | |
54 | 68 |
55 class MockSSLClientSocket : public net::MockClientSocket { | 69 virtual bool SetKeepAlive(bool a, int b) OVERRIDE { |
56 public: | 70 // Always return true in tests |
Ryan Sleevi
2013/12/12 00:48:14
These comments provide zero value.
Munjal (Google)
2013/12/12 17:53:47
The reason I have these comments is so that the re
| |
57 MockSSLClientSocket() : MockClientSocket(net::BoundNetLog()) { } | 71 return true; |
58 virtual ~MockSSLClientSocket() { } | 72 } |
59 | 73 |
60 MOCK_METHOD1(Connect, int(const net::CompletionCallback& callback)); | 74 virtual bool SetNoDelay(bool b) OVERRIDE { |
61 MOCK_METHOD3(Read, int(net::IOBuffer* buf, int buf_len, | 75 // Always return true in tests |
62 const net::CompletionCallback& callback)); | 76 return true; |
63 MOCK_METHOD3(Write, int(net::IOBuffer* buf, int buf_len, | 77 } |
64 const net::CompletionCallback& callback)); | 78 |
65 MOCK_METHOD0(Disconnect, void()); | 79 virtual int Read(net::IOBuffer* buf, int buf_len, |
66 MOCK_CONST_METHOD0(WasEverUsed, bool()); | 80 const net::CompletionCallback& callback) OVERRIDE { |
67 MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); | 81 // Always return IO_PENDING in tests |
68 MOCK_CONST_METHOD0(WasNpnNegotiated, bool()); | 82 return net::ERR_IO_PENDING; |
69 MOCK_METHOD1(GetSSLInfo, bool(net::SSLInfo*)); | 83 } |
84 | |
85 virtual int Write (net::IOBuffer* buf, int buf_len, | |
86 const net::CompletionCallback& callback) OVERRIDE { | |
87 // Always return IO_PENDING in tests | |
88 return net::ERR_IO_PENDING; | |
89 } | |
Ryan Sleevi
2013/12/12 00:48:14
This behaviour for Read and Write leaves me very u
Munjal (Google)
2013/12/12 17:53:47
Actually the Read/Write methods of the TCP socket
| |
90 | |
91 virtual void Disconnect() OVERRIDE { | |
92 // Do nothing in tests | |
93 } | |
94 | |
95 private: | |
96 net::MockConnect connect_data_; | |
70 }; | 97 }; |
71 | 98 |
72 class CompleteHandler { | 99 class CompleteHandler { |
73 public: | 100 public: |
74 CompleteHandler() {} | 101 CompleteHandler() {} |
75 MOCK_METHOD1(OnCloseComplete, void(int result)); | 102 MOCK_METHOD1(OnCloseComplete, void(int result)); |
76 MOCK_METHOD1(OnConnectComplete, void(int result)); | 103 MOCK_METHOD1(OnConnectComplete, void(int result)); |
77 MOCK_METHOD1(OnWriteComplete, void(int result)); | 104 MOCK_METHOD1(OnWriteComplete, void(int result)); |
78 private: | 105 private: |
79 DISALLOW_COPY_AND_ASSIGN(CompleteHandler); | 106 DISALLOW_COPY_AND_ASSIGN(CompleteHandler); |
80 }; | 107 }; |
81 | 108 |
82 class TestCastSocket : public CastSocket { | 109 class TestCastSocket : public CastSocket { |
83 public: | 110 public: |
84 static scoped_ptr<TestCastSocket> Create( | 111 static scoped_ptr<TestCastSocket> Create( |
85 MockCastSocketDelegate* delegate) { | 112 MockCastSocketDelegate* delegate) { |
86 return scoped_ptr<TestCastSocket>( | 113 return scoped_ptr<TestCastSocket>( |
87 new TestCastSocket(delegate, "cast://192.0.0.1:8009")); | 114 new TestCastSocket(delegate, "cast://192.0.0.1:8009")); |
88 } | 115 } |
89 | 116 |
90 static scoped_ptr<TestCastSocket> CreateSecure( | 117 static scoped_ptr<TestCastSocket> CreateSecure( |
91 MockCastSocketDelegate* delegate) { | 118 MockCastSocketDelegate* delegate) { |
92 return scoped_ptr<TestCastSocket>( | 119 return scoped_ptr<TestCastSocket>( |
93 new TestCastSocket(delegate, "casts://192.0.0.1:8009")); | 120 new TestCastSocket(delegate, "casts://192.0.0.1:8009")); |
94 } | 121 } |
95 | 122 |
96 explicit TestCastSocket(MockCastSocketDelegate* delegate, | 123 explicit TestCastSocket(MockCastSocketDelegate* delegate, |
97 const std::string& url) : | 124 const std::string& url) : |
98 CastSocket("abcdefg", GURL(url), delegate, | 125 CastSocket("abcdefg", GURL(url), delegate, |
99 &capturing_net_log_), | 126 &capturing_net_log_), |
100 mock_tcp_socket_(new MockTCPClientSocket()), | 127 ip_(CreateIPEndPoint()), |
101 mock_ssl_socket_(new MockSSLClientSocket()), | 128 connect_index_(0), |
102 owns_tcp_socket_(true), | 129 extract_cert_result_(true), |
103 owns_ssl_socket_(true), | 130 challenge_reply_result_(true) { |
104 extract_cert_result_(true), | 131 } |
105 send_auth_challenge_result_(net::ERR_IO_PENDING), | 132 |
106 read_auth_challenge_reply_result_(net::ERR_IO_PENDING), | 133 static net::IPEndPoint CreateIPEndPoint() { |
107 challenge_reply_result_(true) { | 134 net::IPAddressNumber number; |
135 number.push_back(192); | |
136 number.push_back(0); | |
137 number.push_back(0); | |
138 number.push_back(1); | |
139 return net::IPEndPoint(number, 8009); | |
108 } | 140 } |
109 | 141 |
110 virtual ~TestCastSocket() { | 142 virtual ~TestCastSocket() { |
111 if (owns_tcp_socket_) { | |
112 DCHECK(mock_tcp_socket_); | |
113 delete mock_tcp_socket_; | |
114 } | |
115 if (owns_ssl_socket_) { | |
116 DCHECK(mock_ssl_socket_); | |
117 delete mock_ssl_socket_; | |
118 } | |
119 } | 143 } |
120 | 144 |
121 virtual void Close(const net::CompletionCallback& callback) OVERRIDE { | 145 // Helpers to set mock results for various operations. |
122 if (!owns_tcp_socket_) | 146 void SetupTcp1Connect(net::IoMode mode, int result) { |
123 mock_tcp_socket_ = NULL; | 147 tcp_connect_data_[0].reset(new net::MockConnect(mode, result)); |
124 if (!owns_ssl_socket_) | |
125 mock_ssl_socket_ = NULL; | |
126 CastSocket::Close(callback); | |
127 } | 148 } |
128 | 149 void SetupSsl1Connect(net::IoMode mode, int result) { |
129 void CreateNewSockets() { | 150 ssl_connect_data_[0].reset(new net::MockConnect(mode, result)); |
130 owns_tcp_socket_ = true; | |
131 mock_tcp_socket_ = new MockTCPClientSocket(); | |
132 owns_ssl_socket_ = true; | |
133 mock_ssl_socket_ = new MockSSLClientSocket(); | |
134 } | 151 } |
135 | 152 void SetupTcp2Connect(net::IoMode mode, int result) { |
153 tcp_connect_data_[1].reset(new net::MockConnect(mode, result)); | |
154 } | |
155 void SetupSsl2Connect(net::IoMode mode, int result) { | |
156 ssl_connect_data_[1].reset(new net::MockConnect(mode, result)); | |
157 } | |
158 void AddWriteResult(const net::MockWrite& write) { | |
159 writes_.push_back(write); | |
160 } | |
161 void AddReadResult(const net::MockRead& read) { | |
162 reads_.push_back(read); | |
163 } | |
136 void SetExtractCertResult(bool value) { | 164 void SetExtractCertResult(bool value) { |
137 extract_cert_result_ = value; | 165 extract_cert_result_ = value; |
138 } | 166 } |
139 | |
140 void SetSendAuthChallengeResult(int result) { | |
141 send_auth_challenge_result_ = result; | |
142 } | |
143 | |
144 void SetReadAuthChallengeReplyResult(int result) { | |
145 read_auth_challenge_reply_result_ = result; | |
146 } | |
147 | |
148 void SetChallengeReplyResult(bool value) { | 167 void SetChallengeReplyResult(bool value) { |
149 challenge_reply_result_ = value; | 168 challenge_reply_result_ = value; |
150 } | 169 } |
151 | 170 |
152 MockTCPClientSocket* mock_tcp_socket_; | |
153 MockSSLClientSocket* mock_ssl_socket_; | |
154 | |
155 protected: | 171 protected: |
156 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket() OVERRIDE { | 172 virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket() OVERRIDE { |
157 owns_tcp_socket_ = false; | 173 net::MockConnect* connect_data = tcp_connect_data_[connect_index_].get(); |
158 return scoped_ptr<net::TCPClientSocket>(mock_tcp_socket_); | 174 connect_data->peer_addr = ip_; |
175 return scoped_ptr<net::TCPClientSocket>(new MockTCPSocket(*connect_data)); | |
159 } | 176 } |
160 | 177 |
161 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket() OVERRIDE { | 178 virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket( |
162 owns_ssl_socket_ = false; | 179 scoped_ptr<net::StreamSocket> socket) OVERRIDE { |
163 return scoped_ptr<net::SSLClientSocket>(mock_ssl_socket_); | 180 net::MockConnect* connect_data = ssl_connect_data_[connect_index_].get(); |
181 connect_data->peer_addr = ip_; | |
182 ++connect_index_; | |
183 | |
184 ssl_data_.reset(new net::StaticSocketDataProvider( | |
185 reads_.data(), reads_.size(), writes_.data(), writes_.size())); | |
186 ssl_data_->set_connect_data(*connect_data); | |
187 return scoped_ptr<net::SSLClientSocket>( | |
188 new net::MockTCPClientSocket( | |
189 net::AddressList(), &capturing_net_log_, ssl_data_.get())); | |
164 } | 190 } |
165 | 191 |
166 virtual bool ExtractPeerCert(std::string* cert) OVERRIDE { | 192 virtual bool ExtractPeerCert(std::string* cert) OVERRIDE { |
167 if (extract_cert_result_) | 193 if (extract_cert_result_) |
168 cert->assign("dummy_test_cert"); | 194 cert->assign("dummy_test_cert"); |
169 return extract_cert_result_; | 195 return extract_cert_result_; |
170 } | 196 } |
171 | 197 |
172 virtual int SendAuthChallenge() OVERRIDE { | |
173 return send_auth_challenge_result_; | |
174 } | |
175 | |
176 virtual int ReadAuthChallengeReply() OVERRIDE { | |
177 return read_auth_challenge_reply_result_; | |
178 } | |
179 | |
180 virtual bool VerifyChallengeReply() OVERRIDE { | 198 virtual bool VerifyChallengeReply() OVERRIDE { |
181 return challenge_reply_result_; | 199 return challenge_reply_result_; |
182 } | 200 } |
183 | 201 |
184 private: | 202 private: |
185 net::CapturingNetLog capturing_net_log_; | 203 net::CapturingNetLog capturing_net_log_; |
186 // Whether this object or the parent owns |mock_tcp_socket_|. | 204 net::IPEndPoint ip_; |
187 bool owns_tcp_socket_; | 205 // Simulated connect data |
188 // Whether this object or the parent owns |mock_ssl_socket_|. | 206 scoped_ptr<net::MockConnect> tcp_connect_data_[2]; |
189 bool owns_ssl_socket_; | 207 scoped_ptr<net::MockConnect> ssl_connect_data_[2]; |
208 // Simulated read / write data | |
209 std::vector<net::MockWrite> writes_; | |
210 std::vector<net::MockRead> reads_; | |
211 scoped_ptr<net::SocketDataProvider> ssl_data_; | |
212 // Number of times Connect method is called | |
213 size_t connect_index_; | |
190 // Simulated result of peer cert extraction. | 214 // Simulated result of peer cert extraction. |
191 bool extract_cert_result_; | 215 bool extract_cert_result_; |
192 // Simulated result to be returned by SendAuthChallenge. | |
193 int send_auth_challenge_result_; | |
194 // Simulated result to be returned by ReadAuthChallengeReply. | |
195 int read_auth_challenge_reply_result_; | |
196 // Simulated result of verifying challenge reply. | 216 // Simulated result of verifying challenge reply. |
197 bool challenge_reply_result_; | 217 bool challenge_reply_result_; |
198 }; | 218 }; |
199 | 219 |
200 class CastSocketTest : public testing::Test { | 220 class CastSocketTest : public testing::Test { |
201 public: | 221 public: |
202 CastSocketTest() {} | 222 CastSocketTest() {} |
203 virtual ~CastSocketTest() {} | 223 virtual ~CastSocketTest() {} |
204 | 224 |
205 virtual void SetUp() OVERRIDE { | 225 virtual void SetUp() OVERRIDE { |
206 test_message_.namespace_ = "urn:test"; | 226 // Create a few test messages |
207 test_message_.source_id = "1"; | 227 for (size_t i = 0; i < arraysize(test_messages_); i++) { |
208 test_message_.destination_id = "2"; | 228 test_messages_[i].namespace_ = "urn:test"; |
209 test_message_.data.reset(new base::StringValue("Hello, World!")); | 229 test_messages_[i].source_id = "1"; |
210 ASSERT_TRUE(MessageInfoToCastMessage(test_message_, &test_proto_)); | 230 test_messages_[i].destination_id = "2"; |
231 test_messages_[i].data.reset(new base::StringValue(kTestData[i])); | |
232 ASSERT_TRUE(MessageInfoToCastMessage( | |
233 test_messages_[i], &test_protos_[i])); | |
234 ASSERT_TRUE(CastSocket::Serialize(test_protos_[i], &test_proto_strs_[i])); | |
235 } | |
236 | |
237 // Create a test auth request. | |
238 CastMessage request; | |
239 CreateAuthChallengeMessage(&request); | |
240 ASSERT_TRUE(CastSocket::Serialize(request, &auth_request_)); | |
241 | |
242 // Create a test auth reply. | |
243 MessageInfo reply; | |
244 reply.namespace_ = "urn:x-cast:com.google.cast.tp.deviceauth"; | |
245 reply.source_id = "sender-0"; | |
246 reply.destination_id = "receiver-0"; | |
247 char D[] = "abcd"; | |
248 reply.data.reset(base::BinaryValue::CreateWithCopiedBuffer(D, sizeof(D))); | |
249 CastMessage reply_msg; | |
250 ASSERT_TRUE(MessageInfoToCastMessage(reply, &reply_msg)); | |
251 ASSERT_TRUE(CastSocket::Serialize(reply_msg, &auth_reply_)); | |
211 } | 252 } |
212 | 253 |
213 virtual void TearDown() OVERRIDE { | 254 virtual void TearDown() OVERRIDE { |
214 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); | 255 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); |
215 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, | 256 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, |
216 base::Unretained(&handler_))); | 257 base::Unretained(&handler_))); |
217 } | 258 } |
218 | 259 |
219 void CreateCastSocket() { | 260 void CreateCastSocket() { |
220 socket_ = TestCastSocket::Create(&mock_delegate_); | 261 socket_ = TestCastSocket::Create(&mock_delegate_); |
221 } | 262 } |
222 | 263 |
223 void CreateCastSocketSecure() { | 264 void CreateCastSocketSecure() { |
224 socket_ = TestCastSocket::CreateSecure(&mock_delegate_); | 265 socket_ = TestCastSocket::CreateSecure(&mock_delegate_); |
225 } | 266 } |
226 | 267 |
227 // Sets an expectation that TCPClientSocket::Connect is called and | 268 // Sets up CastSocket::Connect to succeed. |
228 // returns |result| and stores the callback passed to it in |callback|. | 269 // Connecting the socket also starts the read loop; so we add a mock |
229 void ExpectTcpConnect(net::CompletionCallback* callback, int result) { | 270 // read result that returns IO_PENDING and callback is never fired. |
230 EXPECT_CALL(mock_tcp_socket(), Connect(A<const net::CompletionCallback&>())) | 271 void ConnectHelper() { |
231 .Times(1) | 272 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); |
232 .WillOnce(DoAll(SaveArg<0>(callback), Return(result))); | 273 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::OK); |
233 EXPECT_CALL(mock_tcp_socket(), SetKeepAlive(_, _)) | 274 socket_->AddReadResult(net::MockRead(net::ASYNC, net::ERR_IO_PENDING)); |
234 .WillOnce(Return(true)); | |
235 } | |
236 | 275 |
237 // Same as ExpectTcpConnect but to return net::ERR_IO_PENDING. | |
238 void ExpectTcpConnectPending(net::CompletionCallback* callback) { | |
239 ExpectTcpConnect(callback, net::ERR_IO_PENDING); | |
240 } | |
241 | |
242 // Sets an expectation that SSLClientSocket::Connect is called and | |
243 // returns |result| and stores the callback passed to it in |callback|. | |
244 void ExpectSslConnect(net::CompletionCallback* callback, int result) { | |
245 EXPECT_CALL(mock_ssl_socket(), Connect(A<const net::CompletionCallback&>())) | |
246 .Times(1) | |
247 .WillOnce(DoAll(SaveArg<0>(callback), Return(result))); | |
248 } | |
249 | |
250 // Same as ExpectSslConnect but to return net::ERR_IO_PENDING. | |
251 void ExpectSslConnectPending(net::CompletionCallback* callback) { | |
252 ExpectSslConnect(callback, net::ERR_IO_PENDING); | |
253 } | |
254 | |
255 // Sets an expectation that SSLClientSocket::Read is called |times| number | |
256 // of times and returns net::ERR_IO_PENDING. | |
257 void ExpectSslRead(int times) { | |
258 EXPECT_CALL(mock_ssl_socket(), Read(A<net::IOBuffer*>(), | |
259 A<int>(), | |
260 A<const net::CompletionCallback&>())) | |
261 .Times(times) | |
262 .WillOnce(Return(net::ERR_IO_PENDING)); | |
263 } | |
264 | |
265 // Sets up CastSocket::Connect to succeed. | |
266 // Connecting the socket also starts the read loop; we expect the call to | |
267 // Read(), but never fire the read callback. | |
268 void ConnectHelper() { | |
269 net::CompletionCallback connect_callback1; | |
270 net::CompletionCallback connect_callback2; | |
271 | |
272 ExpectTcpConnect(&connect_callback1, net::OK); | |
273 ExpectSslConnect(&connect_callback2, net::OK); | |
274 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | 276 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); |
275 ExpectSslRead(1); | |
276 | |
277 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 277 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
278 base::Unretained(&handler_))); | 278 base::Unretained(&handler_))); |
279 | 279 RunPendingTasks(); |
280 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
281 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
282 } | 280 } |
283 | 281 |
284 protected: | 282 protected: |
285 MockTCPClientSocket& mock_tcp_socket() { | 283 // Runs all pending tasks in the message loop. |
286 MockTCPClientSocket* mock_socket = socket_->mock_tcp_socket_; | 284 void RunPendingTasks() { |
287 DCHECK(mock_socket); | 285 base::RunLoop run_loop; |
288 return *mock_socket; | 286 run_loop.RunUntilIdle(); |
289 } | 287 } |
290 | 288 |
291 MockSSLClientSocket& mock_ssl_socket() { | 289 base::MessageLoop message_loop_; |
292 MockSSLClientSocket* mock_socket = socket_->mock_ssl_socket_; | |
293 DCHECK(mock_socket); | |
294 return *mock_socket; | |
295 } | |
296 | |
297 void CallOnChallengeEvent(int result) { | |
298 socket_->OnChallengeEvent(result); | |
299 } | |
300 | |
301 MockCastSocketDelegate mock_delegate_; | 290 MockCastSocketDelegate mock_delegate_; |
302 scoped_ptr<TestCastSocket> socket_; | 291 scoped_ptr<TestCastSocket> socket_; |
303 CompleteHandler handler_; | 292 CompleteHandler handler_; |
304 MessageInfo test_message_; | 293 MessageInfo test_messages_[arraysize(kTestData)]; |
305 CastMessage test_proto_; | 294 CastMessage test_protos_[arraysize(kTestData)]; |
295 std::string test_proto_strs_[arraysize(kTestData)]; | |
296 std::string auth_request_; | |
297 std::string auth_reply_; | |
306 }; | 298 }; |
307 | 299 |
308 // Tests URL parsing and validation. | 300 // Tests URL parsing and validation. |
309 TEST_F(CastSocketTest, TestCastURLs) { | 301 TEST_F(CastSocketTest, TestCastURLs) { |
310 CreateCastSocket(); | 302 CreateCastSocket(); |
311 EXPECT_TRUE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1:8009"))); | 303 EXPECT_TRUE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1:8009"))); |
312 EXPECT_FALSE(socket_->auth_required()); | 304 EXPECT_FALSE(socket_->auth_required()); |
313 EXPECT_EQ(socket_->ip_endpoint_.ToString(), "192.0.0.1:8009"); | 305 EXPECT_EQ(socket_->ip_endpoint_.ToString(), "192.0.0.1:8009"); |
314 | 306 |
315 EXPECT_TRUE(socket_->ParseChannelUrl(GURL("casts://192.0.0.1:12345"))); | 307 EXPECT_TRUE(socket_->ParseChannelUrl(GURL("casts://192.0.0.1:12345"))); |
(...skipping 12 matching lines...) Expand all Loading... | |
328 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast::"))); | 320 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast::"))); |
329 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1"))); | 321 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1"))); |
330 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://:"))); | 322 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://:"))); |
331 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1:"))); | 323 EXPECT_FALSE(socket_->ParseChannelUrl(GURL("cast://192.0.0.1:"))); |
332 } | 324 } |
333 | 325 |
334 // Tests connecting and closing the socket. | 326 // Tests connecting and closing the socket. |
335 TEST_F(CastSocketTest, TestConnectAndClose) { | 327 TEST_F(CastSocketTest, TestConnectAndClose) { |
336 CreateCastSocket(); | 328 CreateCastSocket(); |
337 ConnectHelper(); | 329 ConnectHelper(); |
330 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | |
331 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | |
338 | 332 |
339 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); | 333 EXPECT_CALL(handler_, OnCloseComplete(net::OK)); |
340 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, | 334 socket_->Close(base::Bind(&CompleteHandler::OnCloseComplete, |
341 base::Unretained(&handler_))); | 335 base::Unretained(&handler_))); |
342 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | 336 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
343 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 337 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
344 } | 338 } |
345 | 339 |
346 // Tests that the following connection flow works: | 340 // Tests that the following connection flow works: |
347 // - TCP connection succeeds (async) | 341 // - TCP connection succeeds (async) |
348 // - SSL connection succeeds (async) | 342 // - SSL connection succeeds (async) |
349 TEST_F(CastSocketTest, TestConnect) { | 343 TEST_F(CastSocketTest, TestConnect) { |
350 CreateCastSocket(); | 344 CreateCastSocket(); |
345 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
346 socket_->SetupSsl1Connect(net::ASYNC, net::OK); | |
347 socket_->AddReadResult(net::MockRead(net::ASYNC, net::ERR_IO_PENDING)); | |
351 | 348 |
352 net::CompletionCallback connect_callback1; | |
353 net::CompletionCallback connect_callback2; | |
354 | |
355 ExpectTcpConnectPending(&connect_callback1); | |
356 ExpectSslConnectPending(&connect_callback2); | |
357 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | 349 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); |
358 ExpectSslRead(1); | |
359 | |
360 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 350 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
361 base::Unretained(&handler_))); | 351 base::Unretained(&handler_))); |
362 connect_callback1.Run(net::OK); | 352 RunPendingTasks(); |
363 connect_callback2.Run(net::OK); | |
364 | 353 |
365 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 354 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
366 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 355 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
367 } | 356 } |
368 | 357 |
369 // Test that the following connection flow works: | 358 // Test that the following connection flow works: |
370 // - TCP connection succeeds (async) | 359 // - TCP connection succeeds (async) |
371 // - SSL connection fails with cert error (async) | 360 // - SSL connection fails with cert error (async) |
372 // - Cert is extracted successfully | 361 // - Cert is extracted successfully |
373 // - Second TCP connection succeeds (async) | 362 // - Second TCP connection succeeds (async) |
374 // - Second SSL connection succeeds (async) | 363 // - Second SSL connection succeeds (async) |
375 TEST_F(CastSocketTest, TestTwoStepConnect) { | 364 TEST_F(CastSocketTest, TestTwoStepConnect) { |
376 CreateCastSocket(); | 365 CreateCastSocket(); |
366 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
367 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
368 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
369 socket_->SetupSsl2Connect(net::ASYNC, net::OK); | |
370 socket_->AddReadResult(net::MockRead(net::ASYNC, net::ERR_IO_PENDING)); | |
377 | 371 |
378 // Expectations for the initial connect call | 372 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); |
379 net::CompletionCallback tcp_connect_callback1; | |
380 net::CompletionCallback ssl_connect_callback1; | |
381 | |
382 ExpectTcpConnectPending(&tcp_connect_callback1); | |
383 ExpectSslConnectPending(&ssl_connect_callback1); | |
384 | |
385 // Start connect flow | |
386 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 373 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
387 base::Unretained(&handler_))); | 374 base::Unretained(&handler_))); |
388 tcp_connect_callback1.Run(net::OK); | 375 RunPendingTasks(); |
389 | |
390 // Expectations for the second connect call | |
391 socket_->CreateNewSockets(); | |
392 net::CompletionCallback tcp_connect_callback2; | |
393 net::CompletionCallback ssl_connect_callback2; | |
394 ExpectTcpConnectPending(&tcp_connect_callback2); | |
395 ExpectSslConnectPending(&ssl_connect_callback2); | |
396 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
397 ExpectSslRead(1); | |
398 | |
399 // Trigger callbacks for the first connect | |
400 ssl_connect_callback1.Run(net::ERR_CERT_AUTHORITY_INVALID); | |
401 | |
402 // Trigger callbacks for the second connect | |
403 tcp_connect_callback2.Run(net::OK); | |
404 ssl_connect_callback2.Run(net::OK); | |
405 | 376 |
406 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 377 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
407 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 378 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
408 } | 379 } |
409 | 380 |
410 // Test that the following connection flow works: | 381 // Test that the following connection flow works: |
411 // - TCP connection succeeds (async) | 382 // - TCP connection succeeds (async) |
412 // - SSL connection fails with cert error (async) | 383 // - SSL connection fails with cert error (async) |
413 // - Cert is extracted successfully | 384 // - Cert is extracted successfully |
414 // - Second TCP connection succeeds (async) | 385 // - Second TCP connection succeeds (async) |
415 // - Second SSL connection fails (async) | 386 // - Second SSL connection fails (async) |
416 // - The flow should NOT be tried again | 387 // - The flow should NOT be tried again |
417 TEST_F(CastSocketTest, TestMaxTwoConnectAttempts) { | 388 TEST_F(CastSocketTest, TestMaxTwoConnectAttempts) { |
418 CreateCastSocket(); | 389 CreateCastSocket(); |
390 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
391 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
392 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
393 socket_->SetupSsl2Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
419 | 394 |
420 net::CompletionCallback tcp_connect_callback1; | 395 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); |
421 net::CompletionCallback ssl_connect_callback1; | |
422 | |
423 // Expectations for the initial connect call | |
424 ExpectTcpConnectPending(&tcp_connect_callback1); | |
425 ExpectSslConnectPending(&ssl_connect_callback1); | |
426 | |
427 // Start connect flow | |
428 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 396 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
429 base::Unretained(&handler_))); | 397 base::Unretained(&handler_))); |
430 tcp_connect_callback1.Run(net::OK); | 398 RunPendingTasks(); |
431 | |
432 socket_->CreateNewSockets(); | |
433 net::CompletionCallback tcp_connect_callback2; | |
434 net::CompletionCallback ssl_connect_callback2; | |
435 | |
436 // Expectations for the second connect call | |
437 ExpectTcpConnectPending(&tcp_connect_callback2); | |
438 ExpectSslConnectPending(&ssl_connect_callback2); | |
439 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); | |
440 | |
441 // Trigger callbacks for the first connect | |
442 ssl_connect_callback1.Run(net::ERR_CERT_AUTHORITY_INVALID); | |
443 | |
444 // Trigger callbacks for the second connect | |
445 tcp_connect_callback2.Run(net::OK); | |
446 ssl_connect_callback2.Run(net::ERR_CERT_AUTHORITY_INVALID); | |
447 | 399 |
448 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | 400 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
449 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | 401 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); |
450 } | 402 } |
451 | 403 |
452 // Test that when cert extraction fails the connection flow stops. | 404 // Test that when cert extraction fails the connection flow stops. |
453 TEST_F(CastSocketTest, TestCertExtractionFailure) { | 405 TEST_F(CastSocketTest, TestCertExtractionFailure) { |
454 CreateCastSocket(); | 406 CreateCastSocket(); |
407 socket_->SetupTcp1Connect(net::ASYNC, net::OK); | |
408 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); | |
409 // Set cert extraction to fail | |
410 socket_->SetExtractCertResult(false); | |
455 | 411 |
456 net::CompletionCallback connect_callback1; | 412 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); |
457 net::CompletionCallback connect_callback2; | |
458 | |
459 ExpectTcpConnectPending(&connect_callback1); | |
460 ExpectSslConnectPending(&connect_callback2); | |
461 | |
462 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 413 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
463 base::Unretained(&handler_))); | 414 base::Unretained(&handler_))); |
464 connect_callback1.Run(net::OK); | 415 RunPendingTasks(); |
465 | |
466 EXPECT_CALL(handler_, OnConnectComplete(net::ERR_CERT_AUTHORITY_INVALID)); | |
467 | |
468 // Set cert extraction to fail | |
469 socket_->SetExtractCertResult(false); | |
470 // Attempt to connect results in ERR_CERT_AUTHORTY_INVALID | |
471 connect_callback2.Run(net::ERR_CERT_AUTHORITY_INVALID); | |
472 | 416 |
473 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | 417 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
474 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); | 418 EXPECT_EQ(cast_channel::CHANNEL_ERROR_CONNECT_ERROR, socket_->error_state()); |
475 } | 419 } |
476 | 420 |
477 // Tests that the following connection flow works: | 421 // Tests that the following connection flow works: |
478 // - TCP connection succeeds (async) | 422 // - TCP connection succeeds (async) |
479 // - SSL connection fails with cert error (async) | 423 // - SSL connection fails with cert error (async) |
480 // - Cert is extracted successfully | 424 // - Cert is extracted successfully |
481 // - Second TCP connection succeeds (async) | 425 // - Second TCP connection succeeds (async) |
482 // - Second SSL connection succeeds (async) | 426 // - Second SSL connection succeeds (async) |
483 // - Challenge request is sent (async) | 427 // - Challenge request is sent (async) |
484 // - Challenge response is received (async) | 428 // - Challenge response is received (async) |
485 // - Credentials are verified successfuly | 429 // - Credentials are verified successfuly |
486 TEST_F(CastSocketTest, TestFullSecureConnectionFlowAsync) { | 430 TEST_F(CastSocketTest, TestFullSecureConnectionFlowAsync) { |
487 CreateCastSocketSecure(); | 431 CreateCastSocketSecure(); |
488 | 432 |
489 net::CompletionCallback tcp_connect_callback1; | 433 socket_->SetupTcp1Connect(net::ASYNC, net::OK); |
490 net::CompletionCallback ssl_connect_callback1; | 434 socket_->SetupSsl1Connect(net::ASYNC, net::ERR_CERT_AUTHORITY_INVALID); |
435 socket_->SetupTcp2Connect(net::ASYNC, net::OK); | |
436 socket_->SetupSsl2Connect(net::ASYNC, net::OK); | |
437 socket_->AddWriteResult(net::MockWrite(net::ASYNC, auth_request_.size())); | |
438 size_t body_size = auth_reply_.length() - 4; | |
439 const char* reply_data = auth_reply_.c_str(); | |
440 socket_->AddReadResult(net::MockRead(net::ASYNC, reply_data, 4)); | |
441 socket_->AddReadResult(net::MockRead(net::ASYNC, reply_data + 4, body_size)); | |
442 socket_->AddReadResult(net::MockRead(net::ASYNC, net::ERR_IO_PENDING)); | |
491 | 443 |
492 // Expectations for the initial connect call | 444 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); |
493 ExpectTcpConnectPending(&tcp_connect_callback1); | |
494 ExpectSslConnectPending(&ssl_connect_callback1); | |
495 | |
496 // Start connect flow | |
497 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 445 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
498 base::Unretained(&handler_))); | 446 base::Unretained(&handler_))); |
499 tcp_connect_callback1.Run(net::OK); | 447 RunPendingTasks(); |
500 | |
501 socket_->CreateNewSockets(); | |
502 net::CompletionCallback tcp_connect_callback2; | |
503 net::CompletionCallback ssl_connect_callback2; | |
504 | |
505 // Expectations for the second connect call | |
506 ExpectTcpConnectPending(&tcp_connect_callback2); | |
507 ExpectSslConnectPending(&ssl_connect_callback2); | |
508 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
509 | |
510 // Trigger callbacks for the first connect | |
511 ssl_connect_callback1.Run(net::ERR_CERT_AUTHORITY_INVALID); | |
512 | |
513 // Trigger callbacks for the second connect | |
514 tcp_connect_callback2.Run(net::OK); | |
515 ssl_connect_callback2.Run(net::OK); | |
516 | |
517 // Trigger callbacks for auth events. | |
518 CallOnChallengeEvent(net::OK); // Sent challenge | |
519 CallOnChallengeEvent(net::OK); // Received reply | |
520 | 448 |
521 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 449 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
522 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 450 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
523 } | 451 } |
524 | 452 |
525 // Same as TestFullSecureConnectionFlowAsync, but operations are synchronous. | 453 // Same as TestFullSecureConnectionFlowAsync, but operations are synchronous. |
526 TEST_F(CastSocketTest, TestFullSecureConnectionFlowSync) { | 454 TEST_F(CastSocketTest, TestFullSecureConnectionFlowSync) { |
527 CreateCastSocketSecure(); | 455 CreateCastSocketSecure(); |
528 | 456 |
529 net::CompletionCallback tcp_connect_callback; | 457 socket_->SetupTcp1Connect(net::SYNCHRONOUS, net::OK); |
530 net::CompletionCallback ssl_connect_callback; | 458 socket_->SetupSsl1Connect(net::SYNCHRONOUS, net::ERR_CERT_AUTHORITY_INVALID); |
459 socket_->SetupTcp2Connect(net::SYNCHRONOUS, net::OK); | |
460 socket_->SetupSsl2Connect(net::SYNCHRONOUS, net::OK); | |
461 socket_->AddWriteResult(net::MockWrite( | |
462 net::SYNCHRONOUS, auth_request_.size())); | |
463 size_t body_size = auth_reply_.length() - 4; | |
464 const char* reply_data = auth_reply_.c_str(); | |
465 socket_->AddReadResult(net::MockRead(net::SYNCHRONOUS, reply_data, 4)); | |
466 socket_->AddReadResult(net::MockRead( | |
467 net::SYNCHRONOUS, reply_data + 4, body_size)); | |
468 socket_->AddReadResult(net::MockRead(net::ASYNC, net::ERR_IO_PENDING)); | |
531 | 469 |
532 // Expectations for the connect calls | |
533 ExpectTcpConnect(&tcp_connect_callback, net::OK); | |
534 ExpectSslConnect(&ssl_connect_callback, net::OK); | |
535 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | 470 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); |
536 | |
537 socket_->SetSendAuthChallengeResult(net::OK); | |
538 socket_->SetReadAuthChallengeReplyResult(net::OK); | |
539 | |
540 // Start connect flow | |
541 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | 471 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, |
542 base::Unretained(&handler_))); | 472 base::Unretained(&handler_))); |
473 RunPendingTasks(); | |
543 | 474 |
544 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 475 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
545 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 476 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
546 } | 477 } |
547 | 478 |
548 // Tests writing a single message where the completion is signaled via | 479 // Tests writing a single message - asynchronous. |
549 // callback. | 480 TEST_F(CastSocketTest, TestWriteAsync) { |
550 TEST_F(CastSocketTest, TestWriteViaCallback) { | |
551 CreateCastSocket(); | 481 CreateCastSocket(); |
482 | |
483 socket_->AddWriteResult(net::MockWrite(net::ASYNC, 39)); | |
552 ConnectHelper(); | 484 ConnectHelper(); |
553 | 485 |
554 net::CompletionCallback write_callback; | |
555 | |
556 EXPECT_CALL(mock_ssl_socket(), | |
557 Write(A<net::IOBuffer*>(), | |
558 39, | |
559 A<const net::CompletionCallback&>())) | |
560 .Times(1) | |
561 .WillOnce(DoAll(SaveArg<2>(&write_callback), | |
562 Return(net::ERR_IO_PENDING))); | |
563 EXPECT_CALL(handler_, OnWriteComplete(39)); | 486 EXPECT_CALL(handler_, OnWriteComplete(39)); |
564 socket_->SendMessage(test_message_, | 487 socket_->SendMessage(test_messages_[0], |
565 base::Bind(&CompleteHandler::OnWriteComplete, | 488 base::Bind(&CompleteHandler::OnWriteComplete, |
566 base::Unretained(&handler_))); | 489 base::Unretained(&handler_))); |
567 write_callback.Run(39); | 490 RunPendingTasks(); |
491 | |
568 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 492 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
569 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 493 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
570 } | 494 } |
571 | 495 |
572 // Tests writing a single message where the Write() returns directly. | 496 // Tests writing a single message - synchronous. |
573 TEST_F(CastSocketTest, TestWrite) { | 497 TEST_F(CastSocketTest, TestWriteSync) { |
574 CreateCastSocket(); | 498 CreateCastSocket(); |
499 | |
500 const std::string& msg = test_proto_strs_[0]; | |
501 size_t msg_size = msg.size(); | |
502 socket_->AddWriteResult(net::MockWrite(net::SYNCHRONOUS, msg_size)); | |
575 ConnectHelper(); | 503 ConnectHelper(); |
576 | 504 |
577 EXPECT_CALL(mock_ssl_socket(), | 505 EXPECT_CALL(handler_, OnWriteComplete(msg_size)); |
578 Write(A<net::IOBuffer*>(), | 506 socket_->SendMessage(test_messages_[0], |
579 39, | 507 base::Bind(&CompleteHandler::OnWriteComplete, |
580 A<const net::CompletionCallback&>())) | 508 base::Unretained(&handler_))); |
581 .Times(1) | 509 RunPendingTasks(); |
582 .WillOnce(Return(39)); | 510 |
583 EXPECT_CALL(handler_, OnWriteComplete(39)); | |
584 socket_->SendMessage(test_message_, | |
585 base::Bind(&CompleteHandler::OnWriteComplete, | |
586 base::Unretained(&handler_))); | |
587 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 511 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
588 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 512 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
589 } | 513 } |
590 | 514 |
591 // Tests writing multiple messages. | 515 // Tests writing multiple messages - asynchronous. |
592 TEST_F(CastSocketTest, TestWriteMany) { | 516 TEST_F(CastSocketTest, TestWriteMany) { |
593 CreateCastSocket(); | 517 CreateCastSocket(); |
518 | |
519 for (size_t i = 0; i < arraysize(test_messages_); i++) { | |
520 size_t msg_size = test_proto_strs_[i].size(); | |
521 socket_->AddWriteResult(net::MockWrite(net::ASYNC, msg_size)); | |
522 EXPECT_CALL(handler_, OnWriteComplete(msg_size)); | |
523 } | |
594 ConnectHelper(); | 524 ConnectHelper(); |
595 std::string messages[4]; | |
596 messages[0] = "Hello, World!"; | |
597 messages[1] = "Goodbye, World!"; | |
598 messages[2] = "Hello, Sky!"; | |
599 messages[3] = "Goodbye, Volcano!"; | |
600 int sizes[4] = {39, 41, 37, 43}; | |
601 MessageInfo message_info[4]; | |
602 net::CompletionCallback write_callback; | |
603 | 525 |
604 for (int i = 0; i < 4; i++) { | 526 for (size_t i = 0; i < arraysize(test_messages_); i++) { |
605 EXPECT_CALL(mock_ssl_socket(), | 527 socket_->SendMessage(test_messages_[i], |
606 Write(A<net::IOBuffer*>(), | |
607 sizes[i], | |
608 A<const net::CompletionCallback&>())) | |
609 .WillRepeatedly(DoAll(SaveArg<2>(&write_callback), | |
610 Return(net::ERR_IO_PENDING))); | |
611 EXPECT_CALL(handler_, OnWriteComplete(sizes[i])); | |
612 } | |
613 | |
614 for (int i = 0; i < 4; i++) { | |
615 message_info[i].namespace_ = "urn:test"; | |
616 message_info[i].source_id = "1"; | |
617 message_info[i].destination_id = "2"; | |
618 message_info[i].data.reset(new base::StringValue(messages[i])); | |
619 socket_->SendMessage(message_info[i], | |
620 base::Bind(&CompleteHandler::OnWriteComplete, | 528 base::Bind(&CompleteHandler::OnWriteComplete, |
621 base::Unretained(&handler_))); | 529 base::Unretained(&handler_))); |
622 } | 530 } |
623 for (int i = 0; i < 4; i++) { | 531 RunPendingTasks(); |
624 write_callback.Run(sizes[i]); | 532 |
625 } | |
626 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 533 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
627 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 534 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
628 } | 535 } |
629 | 536 |
630 // Tests error on writing. | 537 // Tests error on writing - synchronous. |
631 TEST_F(CastSocketTest, TestWriteError) { | 538 TEST_F(CastSocketTest, TestWriteErrorSync) { |
632 CreateCastSocket(); | 539 CreateCastSocket(); |
540 socket_->AddWriteResult(net::MockWrite(net::SYNCHRONOUS, | |
541 net::ERR_SOCKET_NOT_CONNECTED)); | |
633 ConnectHelper(); | 542 ConnectHelper(); |
634 net::CompletionCallback write_callback; | |
635 | 543 |
636 EXPECT_CALL(mock_ssl_socket(), | |
637 Write(A<net::IOBuffer*>(), | |
638 39, | |
639 A<const net::CompletionCallback&>())) | |
640 .Times(1) | |
641 .WillOnce(DoAll(SaveArg<2>(&write_callback), | |
642 Return(net::ERR_SOCKET_NOT_CONNECTED))); | |
643 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_SOCKET_NOT_CONNECTED)); | 544 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_SOCKET_NOT_CONNECTED)); |
644 EXPECT_CALL(mock_delegate_, | 545 EXPECT_CALL(mock_delegate_, |
645 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | 546 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); |
646 socket_->SendMessage(test_message_, | 547 socket_->SendMessage(test_messages_[0], |
647 base::Bind(&CompleteHandler::OnWriteComplete, | 548 base::Bind(&CompleteHandler::OnWriteComplete, |
648 base::Unretained(&handler_))); | 549 base::Unretained(&handler_))); |
550 RunPendingTasks(); | |
551 | |
552 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
553 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
554 } | |
555 | |
556 // Tests error on writing - asynchronous. | |
557 TEST_F(CastSocketTest, TestWriteErrorAsync) { | |
558 CreateCastSocket(); | |
559 socket_->AddWriteResult(net::MockWrite(net::ASYNC, | |
560 net::ERR_SOCKET_NOT_CONNECTED)); | |
561 ConnectHelper(); | |
562 | |
563 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_SOCKET_NOT_CONNECTED)); | |
564 EXPECT_CALL(mock_delegate_, | |
565 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
566 socket_->SendMessage(test_messages_[0], | |
567 base::Bind(&CompleteHandler::OnWriteComplete, | |
568 base::Unretained(&handler_))); | |
569 RunPendingTasks(); | |
570 | |
571 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | |
572 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | |
573 } | |
574 | |
575 // Test that when an error occurrs in one write, write callback is invoked for | |
576 // all pending writes with the error. | |
577 TEST_F(CastSocketTest, TestWriteErrorWithMultiplePendingWritesAsync) { | |
578 CreateCastSocket(); | |
579 socket_->AddWriteResult(net::MockWrite(net::ASYNC, | |
580 net::ERR_SOCKET_NOT_CONNECTED)); | |
581 ConnectHelper(); | |
582 | |
583 const int num_writes = arraysize(test_messages_); | |
584 EXPECT_CALL(handler_, OnWriteComplete(net::ERR_SOCKET_NOT_CONNECTED)) | |
585 .Times(num_writes); | |
586 EXPECT_CALL(mock_delegate_, | |
587 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | |
588 for (int i = 0; i < num_writes; i++) { | |
589 socket_->SendMessage(test_messages_[i], | |
590 base::Bind(&CompleteHandler::OnWriteComplete, | |
591 base::Unretained(&handler_))); | |
592 } | |
593 RunPendingTasks(); | |
594 | |
649 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | 595 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
650 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | 596 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); |
651 } | 597 } |
652 | 598 |
653 // Tests reading a single message. | 599 // Tests reading a single message. |
654 TEST_F(CastSocketTest, TestRead) { | 600 TEST_F(CastSocketTest, TestRead) { |
655 CreateCastSocket(); | 601 CreateCastSocket(); |
656 | 602 |
657 net::CompletionCallback connect_callback1; | 603 const std::string& message = test_proto_strs_[0]; |
658 net::CompletionCallback connect_callback2; | 604 const char* data = message.c_str(); |
659 net::CompletionCallback read_callback; | 605 size_t body_size = message.size() - 4; |
660 | 606 socket_->AddReadResult(net::MockRead(net::ASYNC, data, 4)); |
661 std::string message_data; | 607 socket_->AddReadResult(net::MockRead(net::ASYNC, data + 4, body_size)); |
662 ASSERT_TRUE(CastSocket::Serialize(test_proto_, &message_data)); | |
663 | |
664 ExpectTcpConnect(&connect_callback1, net::ERR_IO_PENDING); | |
665 ExpectSslConnect(&connect_callback2, net::ERR_IO_PENDING); | |
666 | |
667 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
668 EXPECT_CALL(mock_ssl_socket(), Read(A<net::IOBuffer*>(), | |
669 A<int>(), | |
670 A<const net::CompletionCallback&>())) | |
671 .Times(3) | |
672 .WillRepeatedly(DoAll(SaveArg<2>(&read_callback), | |
673 Return(net::ERR_IO_PENDING))); | |
674 | |
675 // Expect the test message to be read and invoke the delegate. | |
676 EXPECT_CALL(mock_delegate_, | 608 EXPECT_CALL(mock_delegate_, |
677 OnMessage(socket_.get(), A<const MessageInfo&>())); | 609 OnMessage(socket_.get(), A<const MessageInfo&>())); |
678 | 610 |
679 // Connect the socket. | 611 ConnectHelper(); |
680 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
681 base::Unretained(&handler_))); | |
682 connect_callback1.Run(net::OK); | |
683 connect_callback2.Run(net::OK); | |
684 | |
685 // Put the test header and message into the io_buffers and invoke the read | |
686 // callbacks. | |
687 memcpy(socket_->header_read_buffer_->StartOfBuffer(), | |
688 message_data.c_str(), 4); | |
689 read_callback.Run(4); | |
690 memcpy(socket_->body_read_buffer_->StartOfBuffer(), | |
691 message_data.c_str() + 4, 35); | |
692 read_callback.Run(35); | |
693 | 612 |
694 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 613 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
695 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 614 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
696 } | 615 } |
697 | 616 |
698 // Tests reading multiple messages. | 617 // Tests reading multiple messages. |
699 TEST_F(CastSocketTest, TestReadMany) { | 618 TEST_F(CastSocketTest, TestReadMany) { |
700 CreateCastSocket(); | 619 CreateCastSocket(); |
701 | 620 |
702 net::CompletionCallback connect_callback1; | 621 size_t num_reads = arraysize(test_proto_strs_); |
703 net::CompletionCallback connect_callback2; | 622 for (size_t i = 0; i < num_reads; i++) { |
704 net::CompletionCallback read_callback; | 623 const char* data = test_proto_strs_[i].c_str(); |
705 | 624 size_t body_size = test_proto_strs_[i].size() - 4; |
706 std::string messages[4]; | 625 socket_->AddReadResult(net::MockRead(net::ASYNC, data, 4)); |
707 messages[0] = "Hello, World!"; | 626 socket_->AddReadResult(net::MockRead(net::ASYNC, data + 4, body_size)); |
708 messages[1] = "Goodbye, World!"; | |
709 messages[2] = "Hello, Sky!"; | |
710 messages[3] = "Goodbye, Volcano!"; | |
711 int sizes[4] = {35, 37, 33, 39}; | |
712 std::string message_data[4]; | |
713 | |
714 // Set up test data | |
715 for (int i = 0; i < 4; i++) { | |
716 test_proto_.set_payload_utf8(messages[i]); | |
717 ASSERT_TRUE(CastSocket::Serialize(test_proto_, &message_data[i])); | |
718 } | 627 } |
719 | 628 |
720 ExpectTcpConnect(&connect_callback1, net::ERR_IO_PENDING); | 629 EXPECT_CALL(mock_delegate_, |
721 ExpectSslConnect(&connect_callback2, net::ERR_IO_PENDING); | 630 OnMessage(socket_.get(), A<const MessageInfo&>())) |
631 .Times(num_reads); | |
722 | 632 |
723 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | 633 ConnectHelper(); |
724 EXPECT_CALL(mock_ssl_socket(), Read(A<net::IOBuffer*>(), | |
725 A<int>(), | |
726 A<const net::CompletionCallback&>())) | |
727 .Times(9) | |
728 .WillRepeatedly(DoAll(SaveArg<2>(&read_callback), | |
729 Return(net::ERR_IO_PENDING))); | |
730 | |
731 // Expect the test messages to be read and invoke the delegate. | |
732 EXPECT_CALL(mock_delegate_, OnMessage(socket_.get(), | |
733 A<const MessageInfo&>())) | |
734 .Times(4); | |
735 | |
736 // Connect the socket. | |
737 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
738 base::Unretained(&handler_))); | |
739 connect_callback1.Run(net::OK); | |
740 connect_callback2.Run(net::OK); | |
741 | |
742 // Put the test headers and messages into the io_buffer and invoke the read | |
743 // callbacks. | |
744 for (int i = 0; i < 4; i++) { | |
745 memcpy(socket_->header_read_buffer_->StartOfBuffer(), | |
746 message_data[i].c_str(), 4); | |
747 read_callback.Run(4); | |
748 memcpy(socket_->body_read_buffer_->StartOfBuffer(), | |
749 message_data[i].c_str() + 4, sizes[i]); | |
750 read_callback.Run(sizes[i]); | |
751 } | |
752 | 634 |
753 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); | 635 EXPECT_EQ(cast_channel::READY_STATE_OPEN, socket_->ready_state()); |
754 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); | 636 EXPECT_EQ(cast_channel::CHANNEL_ERROR_NONE, socket_->error_state()); |
755 } | 637 } |
756 | 638 |
757 // Tests error on reading. | 639 // Tests error on reading. |
758 TEST_F(CastSocketTest, TestReadError) { | 640 TEST_F(CastSocketTest, TestReadError) { |
759 CreateCastSocket(); | 641 CreateCastSocket(); |
642 socket_->AddReadResult(net::MockRead( | |
643 net::ASYNC, net::ERR_SOCKET_NOT_CONNECTED)); | |
760 | 644 |
761 net::CompletionCallback connect_callback1; | |
762 net::CompletionCallback connect_callback2; | |
763 net::CompletionCallback read_callback; | |
764 | |
765 ExpectTcpConnect(&connect_callback1, net::ERR_IO_PENDING); | |
766 ExpectSslConnect(&connect_callback2, net::ERR_IO_PENDING); | |
767 | |
768 EXPECT_CALL(handler_, OnConnectComplete(net::OK)); | |
769 EXPECT_CALL(mock_ssl_socket(), Read(A<net::IOBuffer*>(), | |
770 A<int>(), | |
771 A<const net::CompletionCallback&>())) | |
772 .WillOnce(DoAll(SaveArg<2>(&read_callback), | |
773 Return(net::ERR_IO_PENDING))); | |
774 EXPECT_CALL(mock_delegate_, | 645 EXPECT_CALL(mock_delegate_, |
775 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); | 646 OnError(socket_.get(), cast_channel::CHANNEL_ERROR_SOCKET_ERROR)); |
776 | 647 ConnectHelper(); |
777 // Connect the socket. | |
778 socket_->Connect(base::Bind(&CompleteHandler::OnConnectComplete, | |
779 base::Unretained(&handler_))); | |
780 connect_callback1.Run(net::OK); | |
781 connect_callback2.Run(net::OK); | |
782 | |
783 // Cause an error. | |
784 read_callback.Run(net::ERR_SOCKET_NOT_CONNECTED); | |
785 | 648 |
786 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); | 649 EXPECT_EQ(cast_channel::READY_STATE_CLOSED, socket_->ready_state()); |
787 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); | 650 EXPECT_EQ(cast_channel::CHANNEL_ERROR_SOCKET_ERROR, socket_->error_state()); |
788 } | 651 } |
789 | 652 |
790 } // namespace cast_channel | 653 } // namespace cast_channel |
791 } // namespace api | 654 } // namespace api |
792 } // namespace extensions | 655 } // namespace extensions |
OLD | NEW |