OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "jingle/notifier/base/chrome_async_socket.h" | |
6 | |
7 #include <deque> | |
8 #include <string> | |
9 | |
10 #include "base/basictypes.h" | |
11 #include "base/logging.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/message_loop.h" | |
14 #include "jingle/notifier/base/resolving_client_socket_factory.h" | |
15 #include "net/base/address_list.h" | |
16 #include "net/base/mock_cert_verifier.h" | |
17 #include "net/base/net_errors.h" | |
18 #include "net/base/net_util.h" | |
19 #include "net/base/ssl_config_service.h" | |
20 #include "net/socket/socket_test_util.h" | |
21 #include "net/socket/ssl_client_socket.h" | |
22 #include "net/url_request/url_request_context_getter.h" | |
23 #include "talk/base/sigslot.h" | |
24 #include "talk/base/ipaddress.h" | |
25 #include "talk/base/socketaddress.h" | |
26 #include "testing/gtest/include/gtest/gtest.h" | |
27 | |
28 namespace notifier { | |
29 | |
30 namespace { | |
31 | |
32 // Data provider that handles reads/writes for ChromeAsyncSocket. | |
33 class AsyncSocketDataProvider : public net::SocketDataProvider { | |
34 public: | |
35 AsyncSocketDataProvider() : has_pending_read_(false) {} | |
36 | |
37 virtual ~AsyncSocketDataProvider() { | |
38 EXPECT_TRUE(writes_.empty()); | |
39 EXPECT_TRUE(reads_.empty()); | |
40 } | |
41 | |
42 // If there's no read, sets the "has pending read" flag. Otherwise, | |
43 // pops the next read. | |
44 virtual net::MockRead GetNextRead() { | |
45 if (reads_.empty()) { | |
46 DCHECK(!has_pending_read_); | |
47 has_pending_read_ = true; | |
48 const net::MockRead pending_read(net::SYNCHRONOUS, net::ERR_IO_PENDING); | |
49 return pending_read; | |
50 } | |
51 net::MockRead mock_read = reads_.front(); | |
52 reads_.pop_front(); | |
53 return mock_read; | |
54 } | |
55 | |
56 // Simply pops the next write and, if applicable, compares it to | |
57 // |data|. | |
58 virtual net::MockWriteResult OnWrite(const std::string& data) { | |
59 DCHECK(!writes_.empty()); | |
60 net::MockWrite mock_write = writes_.front(); | |
61 writes_.pop_front(); | |
62 if (mock_write.result != net::OK) { | |
63 return net::MockWriteResult(mock_write.mode, mock_write.result); | |
64 } | |
65 std::string expected_data(mock_write.data, mock_write.data_len); | |
66 EXPECT_EQ(expected_data, data); | |
67 if (expected_data != data) { | |
68 return net::MockWriteResult(net::SYNCHRONOUS, net::ERR_UNEXPECTED); | |
69 } | |
70 return net::MockWriteResult(mock_write.mode, data.size()); | |
71 } | |
72 | |
73 // We ignore resets so we can pre-load the socket data provider with | |
74 // read/write events. | |
75 virtual void Reset() {} | |
76 | |
77 // If there is a pending read, completes it with the given read. | |
78 // Otherwise, queues up the given read. | |
79 void AddRead(const net::MockRead& mock_read) { | |
80 DCHECK_NE(mock_read.result, net::ERR_IO_PENDING); | |
81 if (has_pending_read_) { | |
82 socket()->OnReadComplete(mock_read); | |
83 has_pending_read_ = false; | |
84 return; | |
85 } | |
86 reads_.push_back(mock_read); | |
87 } | |
88 | |
89 // Simply queues up the given write. | |
90 void AddWrite(const net::MockWrite& mock_write) { | |
91 writes_.push_back(mock_write); | |
92 } | |
93 | |
94 private: | |
95 std::deque<net::MockRead> reads_; | |
96 bool has_pending_read_; | |
97 | |
98 std::deque<net::MockWrite> writes_; | |
99 | |
100 DISALLOW_COPY_AND_ASSIGN(AsyncSocketDataProvider); | |
101 }; | |
102 | |
103 class MockXmppClientSocketFactory : public ResolvingClientSocketFactory { | |
104 public: | |
105 MockXmppClientSocketFactory( | |
106 net::ClientSocketFactory* mock_client_socket_factory, | |
107 const net::AddressList& address_list) | |
108 : mock_client_socket_factory_(mock_client_socket_factory), | |
109 address_list_(address_list), | |
110 cert_verifier_(new net::MockCertVerifier) { | |
111 } | |
112 | |
113 // ResolvingClientSocketFactory implementation. | |
114 virtual net::StreamSocket* CreateTransportClientSocket( | |
115 const net::HostPortPair& host_and_port) { | |
116 return mock_client_socket_factory_->CreateTransportClientSocket( | |
117 address_list_, NULL, net::NetLog::Source()); | |
118 } | |
119 | |
120 virtual net::SSLClientSocket* CreateSSLClientSocket( | |
121 net::ClientSocketHandle* transport_socket, | |
122 const net::HostPortPair& host_and_port) { | |
123 net::SSLClientSocketContext context; | |
124 context.cert_verifier = cert_verifier_.get(); | |
125 return mock_client_socket_factory_->CreateSSLClientSocket( | |
126 transport_socket, host_and_port, ssl_config_, context); | |
127 } | |
128 | |
129 private: | |
130 scoped_ptr<net::ClientSocketFactory> mock_client_socket_factory_; | |
131 net::AddressList address_list_; | |
132 net::SSLConfig ssl_config_; | |
133 scoped_ptr<net::CertVerifier> cert_verifier_; | |
134 }; | |
135 | |
136 class ChromeAsyncSocketTest | |
137 : public testing::Test, | |
138 public sigslot::has_slots<> { | |
139 protected: | |
140 ChromeAsyncSocketTest() | |
141 : ssl_socket_data_provider_(net::ASYNC, net::OK), | |
142 addr_("localhost", 35) {} | |
143 | |
144 virtual ~ChromeAsyncSocketTest() {} | |
145 | |
146 virtual void SetUp() { | |
147 scoped_ptr<net::MockClientSocketFactory> mock_client_socket_factory( | |
148 new net::MockClientSocketFactory()); | |
149 mock_client_socket_factory->AddSocketDataProvider( | |
150 &async_socket_data_provider_); | |
151 mock_client_socket_factory->AddSSLSocketDataProvider( | |
152 &ssl_socket_data_provider_); | |
153 | |
154 // Fake DNS resolution for |addr_| and pass it to the factory. | |
155 net::IPAddressNumber resolved_addr; | |
156 EXPECT_TRUE(net::ParseIPLiteralToNumber("127.0.0.1", &resolved_addr)); | |
157 const net::AddressList address_list = | |
158 net::AddressList::CreateFromIPAddress(resolved_addr, addr_.port()); | |
159 scoped_ptr<MockXmppClientSocketFactory> mock_xmpp_client_socket_factory( | |
160 new MockXmppClientSocketFactory( | |
161 mock_client_socket_factory.release(), | |
162 address_list)); | |
163 chrome_async_socket_.reset( | |
164 new ChromeAsyncSocket(mock_xmpp_client_socket_factory.release(), | |
165 14, 20)), | |
166 | |
167 chrome_async_socket_->SignalConnected.connect( | |
168 this, &ChromeAsyncSocketTest::OnConnect); | |
169 chrome_async_socket_->SignalSSLConnected.connect( | |
170 this, &ChromeAsyncSocketTest::OnSSLConnect); | |
171 chrome_async_socket_->SignalClosed.connect( | |
172 this, &ChromeAsyncSocketTest::OnClose); | |
173 chrome_async_socket_->SignalRead.connect( | |
174 this, &ChromeAsyncSocketTest::OnRead); | |
175 chrome_async_socket_->SignalError.connect( | |
176 this, &ChromeAsyncSocketTest::OnError); | |
177 } | |
178 | |
179 virtual void TearDown() { | |
180 // Run any tasks that we forgot to pump. | |
181 message_loop_.RunAllPending(); | |
182 ExpectClosed(); | |
183 ExpectNoSignal(); | |
184 chrome_async_socket_.reset(); | |
185 } | |
186 | |
187 enum Signal { | |
188 SIGNAL_CONNECT, | |
189 SIGNAL_SSL_CONNECT, | |
190 SIGNAL_CLOSE, | |
191 SIGNAL_READ, | |
192 SIGNAL_ERROR, | |
193 }; | |
194 | |
195 // Helper struct that records the state at the time of a signal. | |
196 | |
197 struct SignalSocketState { | |
198 SignalSocketState() | |
199 : signal(SIGNAL_ERROR), | |
200 state(ChromeAsyncSocket::STATE_CLOSED), | |
201 error(ChromeAsyncSocket::ERROR_NONE), | |
202 net_error(net::OK) {} | |
203 | |
204 SignalSocketState( | |
205 Signal signal, | |
206 ChromeAsyncSocket::State state, | |
207 ChromeAsyncSocket::Error error, | |
208 net::Error net_error) | |
209 : signal(signal), | |
210 state(state), | |
211 error(error), | |
212 net_error(net_error) {} | |
213 | |
214 bool IsEqual(const SignalSocketState& other) const { | |
215 return | |
216 (signal == other.signal) && | |
217 (state == other.state) && | |
218 (error == other.error) && | |
219 (net_error == other.net_error); | |
220 } | |
221 | |
222 static SignalSocketState FromAsyncSocket( | |
223 Signal signal, | |
224 buzz::AsyncSocket* async_socket) { | |
225 return SignalSocketState(signal, | |
226 async_socket->state(), | |
227 async_socket->error(), | |
228 static_cast<net::Error>( | |
229 async_socket->GetError())); | |
230 } | |
231 | |
232 static SignalSocketState NoError( | |
233 Signal signal, buzz::AsyncSocket::State state) { | |
234 return SignalSocketState(signal, state, | |
235 buzz::AsyncSocket::ERROR_NONE, | |
236 net::OK); | |
237 } | |
238 | |
239 Signal signal; | |
240 ChromeAsyncSocket::State state; | |
241 ChromeAsyncSocket::Error error; | |
242 net::Error net_error; | |
243 }; | |
244 | |
245 void CaptureSocketState(Signal signal) { | |
246 signal_socket_states_.push_back( | |
247 SignalSocketState::FromAsyncSocket( | |
248 signal, chrome_async_socket_.get())); | |
249 } | |
250 | |
251 void OnConnect() { | |
252 CaptureSocketState(SIGNAL_CONNECT); | |
253 } | |
254 | |
255 void OnSSLConnect() { | |
256 CaptureSocketState(SIGNAL_SSL_CONNECT); | |
257 } | |
258 | |
259 void OnClose() { | |
260 CaptureSocketState(SIGNAL_CLOSE); | |
261 } | |
262 | |
263 void OnRead() { | |
264 CaptureSocketState(SIGNAL_READ); | |
265 } | |
266 | |
267 void OnError() { | |
268 ADD_FAILURE(); | |
269 } | |
270 | |
271 // State expect functions. | |
272 | |
273 void ExpectState(ChromeAsyncSocket::State state, | |
274 ChromeAsyncSocket::Error error, | |
275 net::Error net_error) { | |
276 EXPECT_EQ(state, chrome_async_socket_->state()); | |
277 EXPECT_EQ(error, chrome_async_socket_->error()); | |
278 EXPECT_EQ(net_error, chrome_async_socket_->GetError()); | |
279 } | |
280 | |
281 void ExpectNonErrorState(ChromeAsyncSocket::State state) { | |
282 ExpectState(state, ChromeAsyncSocket::ERROR_NONE, net::OK); | |
283 } | |
284 | |
285 void ExpectErrorState(ChromeAsyncSocket::State state, | |
286 ChromeAsyncSocket::Error error) { | |
287 ExpectState(state, error, net::OK); | |
288 } | |
289 | |
290 void ExpectClosed() { | |
291 ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); | |
292 } | |
293 | |
294 // Signal expect functions. | |
295 | |
296 void ExpectNoSignal() { | |
297 if (!signal_socket_states_.empty()) { | |
298 ADD_FAILURE() << signal_socket_states_.front().signal; | |
299 } | |
300 } | |
301 | |
302 void ExpectSignalSocketState( | |
303 SignalSocketState expected_signal_socket_state) { | |
304 if (signal_socket_states_.empty()) { | |
305 ADD_FAILURE() << expected_signal_socket_state.signal; | |
306 return; | |
307 } | |
308 EXPECT_TRUE(expected_signal_socket_state.IsEqual( | |
309 signal_socket_states_.front())) | |
310 << signal_socket_states_.front().signal; | |
311 signal_socket_states_.pop_front(); | |
312 } | |
313 | |
314 void ExpectReadSignal() { | |
315 ExpectSignalSocketState( | |
316 SignalSocketState::NoError( | |
317 SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN)); | |
318 } | |
319 | |
320 void ExpectSSLConnectSignal() { | |
321 ExpectSignalSocketState( | |
322 SignalSocketState::NoError(SIGNAL_SSL_CONNECT, | |
323 ChromeAsyncSocket::STATE_TLS_OPEN)); | |
324 } | |
325 | |
326 void ExpectSSLReadSignal() { | |
327 ExpectSignalSocketState( | |
328 SignalSocketState::NoError( | |
329 SIGNAL_READ, ChromeAsyncSocket::STATE_TLS_OPEN)); | |
330 } | |
331 | |
332 // Open/close utility functions. | |
333 | |
334 void DoOpenClosed() { | |
335 ExpectClosed(); | |
336 async_socket_data_provider_.set_connect_data( | |
337 net::MockConnect(net::SYNCHRONOUS, net::OK)); | |
338 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
339 ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); | |
340 | |
341 message_loop_.RunAllPending(); | |
342 // We may not necessarily be open; may have been other events | |
343 // queued up. | |
344 ExpectSignalSocketState( | |
345 SignalSocketState::NoError( | |
346 SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); | |
347 } | |
348 | |
349 void DoCloseOpened(SignalSocketState expected_signal_socket_state) { | |
350 // We may be in an error state, so just compare state(). | |
351 EXPECT_EQ(ChromeAsyncSocket::STATE_OPEN, chrome_async_socket_->state()); | |
352 EXPECT_TRUE(chrome_async_socket_->Close()); | |
353 ExpectSignalSocketState(expected_signal_socket_state); | |
354 ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); | |
355 } | |
356 | |
357 void DoCloseOpenedNoError() { | |
358 DoCloseOpened( | |
359 SignalSocketState::NoError( | |
360 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
361 } | |
362 | |
363 void DoSSLOpenClosed() { | |
364 const char kDummyData[] = "dummy_data"; | |
365 async_socket_data_provider_.AddRead(net::MockRead(kDummyData)); | |
366 DoOpenClosed(); | |
367 ExpectReadSignal(); | |
368 EXPECT_EQ(kDummyData, DrainRead(1)); | |
369 | |
370 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
371 message_loop_.RunAllPending(); | |
372 ExpectSSLConnectSignal(); | |
373 ExpectNoSignal(); | |
374 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); | |
375 } | |
376 | |
377 void DoSSLCloseOpened(SignalSocketState expected_signal_socket_state) { | |
378 // We may be in an error state, so just compare state(). | |
379 EXPECT_EQ(ChromeAsyncSocket::STATE_TLS_OPEN, | |
380 chrome_async_socket_->state()); | |
381 EXPECT_TRUE(chrome_async_socket_->Close()); | |
382 ExpectSignalSocketState(expected_signal_socket_state); | |
383 ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); | |
384 } | |
385 | |
386 void DoSSLCloseOpenedNoError() { | |
387 DoSSLCloseOpened( | |
388 SignalSocketState::NoError( | |
389 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
390 } | |
391 | |
392 // Read utility fucntions. | |
393 | |
394 std::string DrainRead(size_t buf_size) { | |
395 std::string read; | |
396 scoped_array<char> buf(new char[buf_size]); | |
397 size_t len_read; | |
398 while (true) { | |
399 bool success = | |
400 chrome_async_socket_->Read(buf.get(), buf_size, &len_read); | |
401 if (!success) { | |
402 ADD_FAILURE(); | |
403 break; | |
404 } | |
405 if (len_read == 0U) { | |
406 break; | |
407 } | |
408 read.append(buf.get(), len_read); | |
409 } | |
410 return read; | |
411 } | |
412 | |
413 // ChromeAsyncSocket expects a message loop. | |
414 MessageLoop message_loop_; | |
415 | |
416 AsyncSocketDataProvider async_socket_data_provider_; | |
417 net::SSLSocketDataProvider ssl_socket_data_provider_; | |
418 | |
419 scoped_ptr<ChromeAsyncSocket> chrome_async_socket_; | |
420 std::deque<SignalSocketState> signal_socket_states_; | |
421 const talk_base::SocketAddress addr_; | |
422 | |
423 private: | |
424 DISALLOW_COPY_AND_ASSIGN(ChromeAsyncSocketTest); | |
425 }; | |
426 | |
427 TEST_F(ChromeAsyncSocketTest, InitialState) { | |
428 ExpectClosed(); | |
429 ExpectNoSignal(); | |
430 } | |
431 | |
432 TEST_F(ChromeAsyncSocketTest, EmptyClose) { | |
433 ExpectClosed(); | |
434 EXPECT_TRUE(chrome_async_socket_->Close()); | |
435 ExpectClosed(); | |
436 } | |
437 | |
438 TEST_F(ChromeAsyncSocketTest, ImmediateConnectAndClose) { | |
439 DoOpenClosed(); | |
440 | |
441 ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN); | |
442 | |
443 DoCloseOpenedNoError(); | |
444 } | |
445 | |
446 // After this, no need to test immediate successful connect and | |
447 // Close() so thoroughly. | |
448 | |
449 TEST_F(ChromeAsyncSocketTest, DoubleClose) { | |
450 DoOpenClosed(); | |
451 | |
452 EXPECT_TRUE(chrome_async_socket_->Close()); | |
453 ExpectClosed(); | |
454 ExpectSignalSocketState( | |
455 SignalSocketState::NoError( | |
456 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
457 | |
458 EXPECT_TRUE(chrome_async_socket_->Close()); | |
459 ExpectClosed(); | |
460 } | |
461 | |
462 TEST_F(ChromeAsyncSocketTest, NoHostnameConnect) { | |
463 talk_base::IPAddress ip_address; | |
464 EXPECT_TRUE(talk_base::IPFromString("127.0.0.1", &ip_address)); | |
465 const talk_base::SocketAddress no_hostname_addr(ip_address, addr_.port()); | |
466 EXPECT_FALSE(chrome_async_socket_->Connect(no_hostname_addr)); | |
467 ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, | |
468 ChromeAsyncSocket::ERROR_DNS); | |
469 | |
470 EXPECT_TRUE(chrome_async_socket_->Close()); | |
471 ExpectClosed(); | |
472 } | |
473 | |
474 TEST_F(ChromeAsyncSocketTest, ZeroPortConnect) { | |
475 const talk_base::SocketAddress zero_port_addr(addr_.hostname(), 0); | |
476 EXPECT_FALSE(chrome_async_socket_->Connect(zero_port_addr)); | |
477 ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, | |
478 ChromeAsyncSocket::ERROR_DNS); | |
479 | |
480 EXPECT_TRUE(chrome_async_socket_->Close()); | |
481 ExpectClosed(); | |
482 } | |
483 | |
484 TEST_F(ChromeAsyncSocketTest, DoubleConnect) { | |
485 EXPECT_DEBUG_DEATH({ | |
486 DoOpenClosed(); | |
487 | |
488 EXPECT_FALSE(chrome_async_socket_->Connect(addr_)); | |
489 ExpectErrorState(ChromeAsyncSocket::STATE_OPEN, | |
490 ChromeAsyncSocket::ERROR_WRONGSTATE); | |
491 | |
492 DoCloseOpened( | |
493 SignalSocketState(SIGNAL_CLOSE, | |
494 ChromeAsyncSocket::STATE_CLOSED, | |
495 ChromeAsyncSocket::ERROR_WRONGSTATE, | |
496 net::OK)); | |
497 }, "non-closed socket"); | |
498 } | |
499 | |
500 TEST_F(ChromeAsyncSocketTest, ImmediateConnectCloseBeforeRead) { | |
501 DoOpenClosed(); | |
502 | |
503 EXPECT_TRUE(chrome_async_socket_->Close()); | |
504 ExpectClosed(); | |
505 ExpectSignalSocketState( | |
506 SignalSocketState::NoError( | |
507 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
508 | |
509 message_loop_.RunAllPending(); | |
510 } | |
511 | |
512 TEST_F(ChromeAsyncSocketTest, HangingConnect) { | |
513 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
514 ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); | |
515 ExpectNoSignal(); | |
516 | |
517 EXPECT_TRUE(chrome_async_socket_->Close()); | |
518 ExpectClosed(); | |
519 ExpectSignalSocketState( | |
520 SignalSocketState::NoError( | |
521 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
522 } | |
523 | |
524 TEST_F(ChromeAsyncSocketTest, PendingConnect) { | |
525 async_socket_data_provider_.set_connect_data( | |
526 net::MockConnect(net::ASYNC, net::OK)); | |
527 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
528 ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); | |
529 ExpectNoSignal(); | |
530 | |
531 message_loop_.RunAllPending(); | |
532 ExpectNonErrorState(ChromeAsyncSocket::STATE_OPEN); | |
533 ExpectSignalSocketState( | |
534 SignalSocketState::NoError( | |
535 SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); | |
536 ExpectNoSignal(); | |
537 | |
538 message_loop_.RunAllPending(); | |
539 | |
540 DoCloseOpenedNoError(); | |
541 } | |
542 | |
543 // After this no need to test successful pending connect so | |
544 // thoroughly. | |
545 | |
546 TEST_F(ChromeAsyncSocketTest, PendingConnectCloseBeforeRead) { | |
547 async_socket_data_provider_.set_connect_data( | |
548 net::MockConnect(net::ASYNC, net::OK)); | |
549 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
550 | |
551 message_loop_.RunAllPending(); | |
552 ExpectSignalSocketState( | |
553 SignalSocketState::NoError( | |
554 SIGNAL_CONNECT, ChromeAsyncSocket::STATE_OPEN)); | |
555 | |
556 DoCloseOpenedNoError(); | |
557 | |
558 message_loop_.RunAllPending(); | |
559 } | |
560 | |
561 TEST_F(ChromeAsyncSocketTest, PendingConnectError) { | |
562 async_socket_data_provider_.set_connect_data( | |
563 net::MockConnect(net::ASYNC, net::ERR_TIMED_OUT)); | |
564 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
565 | |
566 message_loop_.RunAllPending(); | |
567 | |
568 ExpectSignalSocketState( | |
569 SignalSocketState( | |
570 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
571 ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); | |
572 } | |
573 | |
574 // After this we can assume Connect() and Close() work as expected. | |
575 | |
576 TEST_F(ChromeAsyncSocketTest, EmptyRead) { | |
577 DoOpenClosed(); | |
578 | |
579 char buf[4096]; | |
580 size_t len_read = 10000U; | |
581 EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); | |
582 EXPECT_EQ(0U, len_read); | |
583 | |
584 DoCloseOpenedNoError(); | |
585 } | |
586 | |
587 TEST_F(ChromeAsyncSocketTest, WrongRead) { | |
588 EXPECT_DEBUG_DEATH({ | |
589 async_socket_data_provider_.set_connect_data( | |
590 net::MockConnect(net::ASYNC, net::OK)); | |
591 EXPECT_TRUE(chrome_async_socket_->Connect(addr_)); | |
592 ExpectNonErrorState(ChromeAsyncSocket::STATE_CONNECTING); | |
593 ExpectNoSignal(); | |
594 | |
595 char buf[4096]; | |
596 size_t len_read; | |
597 EXPECT_FALSE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); | |
598 ExpectErrorState(ChromeAsyncSocket::STATE_CONNECTING, | |
599 ChromeAsyncSocket::ERROR_WRONGSTATE); | |
600 EXPECT_TRUE(chrome_async_socket_->Close()); | |
601 ExpectSignalSocketState( | |
602 SignalSocketState( | |
603 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
604 ChromeAsyncSocket::ERROR_WRONGSTATE, net::OK)); | |
605 }, "non-open"); | |
606 } | |
607 | |
608 TEST_F(ChromeAsyncSocketTest, WrongReadClosed) { | |
609 char buf[4096]; | |
610 size_t len_read; | |
611 EXPECT_FALSE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); | |
612 ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, | |
613 ChromeAsyncSocket::ERROR_WRONGSTATE); | |
614 EXPECT_TRUE(chrome_async_socket_->Close()); | |
615 } | |
616 | |
617 const char kReadData[] = "mydatatoread"; | |
618 | |
619 TEST_F(ChromeAsyncSocketTest, Read) { | |
620 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
621 DoOpenClosed(); | |
622 | |
623 ExpectReadSignal(); | |
624 ExpectNoSignal(); | |
625 | |
626 EXPECT_EQ(kReadData, DrainRead(1)); | |
627 | |
628 message_loop_.RunAllPending(); | |
629 | |
630 DoCloseOpenedNoError(); | |
631 } | |
632 | |
633 TEST_F(ChromeAsyncSocketTest, ReadTwice) { | |
634 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
635 DoOpenClosed(); | |
636 | |
637 ExpectReadSignal(); | |
638 ExpectNoSignal(); | |
639 | |
640 EXPECT_EQ(kReadData, DrainRead(1)); | |
641 | |
642 message_loop_.RunAllPending(); | |
643 | |
644 const char kReadData2[] = "mydatatoread2"; | |
645 async_socket_data_provider_.AddRead(net::MockRead(kReadData2)); | |
646 | |
647 ExpectReadSignal(); | |
648 ExpectNoSignal(); | |
649 | |
650 EXPECT_EQ(kReadData2, DrainRead(1)); | |
651 | |
652 DoCloseOpenedNoError(); | |
653 } | |
654 | |
655 TEST_F(ChromeAsyncSocketTest, ReadError) { | |
656 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
657 DoOpenClosed(); | |
658 | |
659 ExpectReadSignal(); | |
660 ExpectNoSignal(); | |
661 | |
662 EXPECT_EQ(kReadData, DrainRead(1)); | |
663 | |
664 message_loop_.RunAllPending(); | |
665 | |
666 async_socket_data_provider_.AddRead( | |
667 net::MockRead(net::SYNCHRONOUS, net::ERR_TIMED_OUT)); | |
668 | |
669 ExpectSignalSocketState( | |
670 SignalSocketState( | |
671 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
672 ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); | |
673 } | |
674 | |
675 TEST_F(ChromeAsyncSocketTest, ReadEmpty) { | |
676 async_socket_data_provider_.AddRead(net::MockRead("")); | |
677 DoOpenClosed(); | |
678 | |
679 ExpectSignalSocketState( | |
680 SignalSocketState::NoError( | |
681 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
682 } | |
683 | |
684 TEST_F(ChromeAsyncSocketTest, PendingRead) { | |
685 DoOpenClosed(); | |
686 | |
687 ExpectNoSignal(); | |
688 | |
689 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
690 | |
691 ExpectSignalSocketState( | |
692 SignalSocketState::NoError( | |
693 SIGNAL_READ, ChromeAsyncSocket::STATE_OPEN)); | |
694 ExpectNoSignal(); | |
695 | |
696 EXPECT_EQ(kReadData, DrainRead(1)); | |
697 | |
698 message_loop_.RunAllPending(); | |
699 | |
700 DoCloseOpenedNoError(); | |
701 } | |
702 | |
703 TEST_F(ChromeAsyncSocketTest, PendingEmptyRead) { | |
704 DoOpenClosed(); | |
705 | |
706 ExpectNoSignal(); | |
707 | |
708 async_socket_data_provider_.AddRead(net::MockRead("")); | |
709 | |
710 ExpectSignalSocketState( | |
711 SignalSocketState::NoError( | |
712 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED)); | |
713 } | |
714 | |
715 TEST_F(ChromeAsyncSocketTest, PendingReadError) { | |
716 DoOpenClosed(); | |
717 | |
718 ExpectNoSignal(); | |
719 | |
720 async_socket_data_provider_.AddRead( | |
721 net::MockRead(net::ASYNC, net::ERR_TIMED_OUT)); | |
722 | |
723 ExpectSignalSocketState( | |
724 SignalSocketState( | |
725 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
726 ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); | |
727 } | |
728 | |
729 // After this we can assume non-SSL Read() works as expected. | |
730 | |
731 TEST_F(ChromeAsyncSocketTest, WrongWrite) { | |
732 EXPECT_DEBUG_DEATH({ | |
733 std::string data("foo"); | |
734 EXPECT_FALSE(chrome_async_socket_->Write(data.data(), data.size())); | |
735 ExpectErrorState(ChromeAsyncSocket::STATE_CLOSED, | |
736 ChromeAsyncSocket::ERROR_WRONGSTATE); | |
737 EXPECT_TRUE(chrome_async_socket_->Close()); | |
738 }, "non-open"); | |
739 } | |
740 | |
741 const char kWriteData[] = "mydatatowrite"; | |
742 | |
743 TEST_F(ChromeAsyncSocketTest, SyncWrite) { | |
744 async_socket_data_provider_.AddWrite( | |
745 net::MockWrite(net::SYNCHRONOUS, kWriteData, 3)); | |
746 async_socket_data_provider_.AddWrite( | |
747 net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5)); | |
748 async_socket_data_provider_.AddWrite( | |
749 net::MockWrite(net::SYNCHRONOUS, | |
750 kWriteData + 8, arraysize(kWriteData) - 8)); | |
751 DoOpenClosed(); | |
752 | |
753 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
754 message_loop_.RunAllPending(); | |
755 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5)); | |
756 message_loop_.RunAllPending(); | |
757 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8, | |
758 arraysize(kWriteData) - 8)); | |
759 message_loop_.RunAllPending(); | |
760 | |
761 ExpectNoSignal(); | |
762 | |
763 DoCloseOpenedNoError(); | |
764 } | |
765 | |
766 TEST_F(ChromeAsyncSocketTest, AsyncWrite) { | |
767 DoOpenClosed(); | |
768 | |
769 async_socket_data_provider_.AddWrite( | |
770 net::MockWrite(net::ASYNC, kWriteData, 3)); | |
771 async_socket_data_provider_.AddWrite( | |
772 net::MockWrite(net::ASYNC, kWriteData + 3, 5)); | |
773 async_socket_data_provider_.AddWrite( | |
774 net::MockWrite(net::ASYNC, kWriteData + 8, arraysize(kWriteData) - 8)); | |
775 | |
776 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
777 message_loop_.RunAllPending(); | |
778 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5)); | |
779 message_loop_.RunAllPending(); | |
780 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8, | |
781 arraysize(kWriteData) - 8)); | |
782 message_loop_.RunAllPending(); | |
783 | |
784 ExpectNoSignal(); | |
785 | |
786 DoCloseOpenedNoError(); | |
787 } | |
788 | |
789 TEST_F(ChromeAsyncSocketTest, AsyncWriteError) { | |
790 DoOpenClosed(); | |
791 | |
792 async_socket_data_provider_.AddWrite( | |
793 net::MockWrite(net::ASYNC, kWriteData, 3)); | |
794 async_socket_data_provider_.AddWrite( | |
795 net::MockWrite(net::ASYNC, kWriteData + 3, 5)); | |
796 async_socket_data_provider_.AddWrite( | |
797 net::MockWrite(net::ASYNC, net::ERR_TIMED_OUT)); | |
798 | |
799 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
800 message_loop_.RunAllPending(); | |
801 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5)); | |
802 message_loop_.RunAllPending(); | |
803 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8, | |
804 arraysize(kWriteData) - 8)); | |
805 message_loop_.RunAllPending(); | |
806 | |
807 ExpectSignalSocketState( | |
808 SignalSocketState( | |
809 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
810 ChromeAsyncSocket::ERROR_WINSOCK, net::ERR_TIMED_OUT)); | |
811 } | |
812 | |
813 TEST_F(ChromeAsyncSocketTest, LargeWrite) { | |
814 EXPECT_DEBUG_DEATH({ | |
815 DoOpenClosed(); | |
816 | |
817 std::string large_data(100, 'x'); | |
818 EXPECT_FALSE(chrome_async_socket_->Write(large_data.data(), | |
819 large_data.size())); | |
820 ExpectState(ChromeAsyncSocket::STATE_OPEN, | |
821 ChromeAsyncSocket::ERROR_WINSOCK, | |
822 net::ERR_INSUFFICIENT_RESOURCES); | |
823 DoCloseOpened( | |
824 SignalSocketState( | |
825 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
826 ChromeAsyncSocket::ERROR_WINSOCK, | |
827 net::ERR_INSUFFICIENT_RESOURCES)); | |
828 }, "exceed the max write buffer"); | |
829 } | |
830 | |
831 TEST_F(ChromeAsyncSocketTest, LargeAccumulatedWrite) { | |
832 EXPECT_DEBUG_DEATH({ | |
833 DoOpenClosed(); | |
834 | |
835 std::string data(15, 'x'); | |
836 EXPECT_TRUE(chrome_async_socket_->Write(data.data(), data.size())); | |
837 EXPECT_FALSE(chrome_async_socket_->Write(data.data(), data.size())); | |
838 ExpectState(ChromeAsyncSocket::STATE_OPEN, | |
839 ChromeAsyncSocket::ERROR_WINSOCK, | |
840 net::ERR_INSUFFICIENT_RESOURCES); | |
841 DoCloseOpened( | |
842 SignalSocketState( | |
843 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
844 ChromeAsyncSocket::ERROR_WINSOCK, | |
845 net::ERR_INSUFFICIENT_RESOURCES)); | |
846 }, "exceed the max write buffer"); | |
847 } | |
848 | |
849 // After this we can assume non-SSL I/O works as expected. | |
850 | |
851 TEST_F(ChromeAsyncSocketTest, HangingSSLConnect) { | |
852 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
853 DoOpenClosed(); | |
854 ExpectReadSignal(); | |
855 | |
856 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
857 ExpectNoSignal(); | |
858 | |
859 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING); | |
860 EXPECT_TRUE(chrome_async_socket_->Close()); | |
861 ExpectSignalSocketState( | |
862 SignalSocketState::NoError(SIGNAL_CLOSE, | |
863 ChromeAsyncSocket::STATE_CLOSED)); | |
864 ExpectNonErrorState(ChromeAsyncSocket::STATE_CLOSED); | |
865 } | |
866 | |
867 TEST_F(ChromeAsyncSocketTest, ImmediateSSLConnect) { | |
868 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
869 DoOpenClosed(); | |
870 ExpectReadSignal(); | |
871 | |
872 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
873 message_loop_.RunAllPending(); | |
874 ExpectSSLConnectSignal(); | |
875 ExpectNoSignal(); | |
876 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); | |
877 | |
878 DoSSLCloseOpenedNoError(); | |
879 } | |
880 | |
881 TEST_F(ChromeAsyncSocketTest, DoubleSSLConnect) { | |
882 EXPECT_DEBUG_DEATH({ | |
883 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
884 DoOpenClosed(); | |
885 ExpectReadSignal(); | |
886 | |
887 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
888 message_loop_.RunAllPending(); | |
889 ExpectSSLConnectSignal(); | |
890 ExpectNoSignal(); | |
891 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); | |
892 | |
893 EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com")); | |
894 | |
895 DoSSLCloseOpened( | |
896 SignalSocketState(SIGNAL_CLOSE, | |
897 ChromeAsyncSocket::STATE_CLOSED, | |
898 ChromeAsyncSocket::ERROR_WRONGSTATE, | |
899 net::OK)); | |
900 }, "wrong state"); | |
901 } | |
902 | |
903 TEST_F(ChromeAsyncSocketTest, FailedSSLConnect) { | |
904 ssl_socket_data_provider_.connect = | |
905 net::MockConnect(net::ASYNC, net::ERR_CERT_COMMON_NAME_INVALID), | |
906 | |
907 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
908 DoOpenClosed(); | |
909 ExpectReadSignal(); | |
910 | |
911 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
912 message_loop_.RunAllPending(); | |
913 ExpectSignalSocketState( | |
914 SignalSocketState( | |
915 SIGNAL_CLOSE, ChromeAsyncSocket::STATE_CLOSED, | |
916 ChromeAsyncSocket::ERROR_WINSOCK, | |
917 net::ERR_CERT_COMMON_NAME_INVALID)); | |
918 | |
919 EXPECT_TRUE(chrome_async_socket_->Close()); | |
920 ExpectClosed(); | |
921 } | |
922 | |
923 TEST_F(ChromeAsyncSocketTest, ReadDuringSSLConnecting) { | |
924 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
925 DoOpenClosed(); | |
926 ExpectReadSignal(); | |
927 EXPECT_EQ(kReadData, DrainRead(1)); | |
928 | |
929 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
930 ExpectNoSignal(); | |
931 | |
932 // Shouldn't do anything. | |
933 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
934 | |
935 char buf[4096]; | |
936 size_t len_read = 10000U; | |
937 EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); | |
938 EXPECT_EQ(0U, len_read); | |
939 | |
940 message_loop_.RunAllPending(); | |
941 ExpectSSLConnectSignal(); | |
942 ExpectSSLReadSignal(); | |
943 ExpectNoSignal(); | |
944 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_OPEN); | |
945 | |
946 len_read = 10000U; | |
947 EXPECT_TRUE(chrome_async_socket_->Read(buf, sizeof(buf), &len_read)); | |
948 EXPECT_EQ(kReadData, std::string(buf, len_read)); | |
949 | |
950 DoSSLCloseOpenedNoError(); | |
951 } | |
952 | |
953 TEST_F(ChromeAsyncSocketTest, WriteDuringSSLConnecting) { | |
954 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
955 DoOpenClosed(); | |
956 ExpectReadSignal(); | |
957 | |
958 EXPECT_TRUE(chrome_async_socket_->StartTls("fakedomain.com")); | |
959 ExpectNoSignal(); | |
960 ExpectNonErrorState(ChromeAsyncSocket::STATE_TLS_CONNECTING); | |
961 | |
962 async_socket_data_provider_.AddWrite( | |
963 net::MockWrite(net::ASYNC, kWriteData, 3)); | |
964 | |
965 // Shouldn't do anything. | |
966 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
967 | |
968 // TODO(akalin): Figure out how to test that the write happens | |
969 // *after* the SSL connect. | |
970 | |
971 message_loop_.RunAllPending(); | |
972 ExpectSSLConnectSignal(); | |
973 ExpectNoSignal(); | |
974 | |
975 message_loop_.RunAllPending(); | |
976 | |
977 DoSSLCloseOpenedNoError(); | |
978 } | |
979 | |
980 TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPendingRead) { | |
981 EXPECT_DEBUG_DEATH({ | |
982 DoOpenClosed(); | |
983 | |
984 EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com")); | |
985 | |
986 DoCloseOpened( | |
987 SignalSocketState(SIGNAL_CLOSE, | |
988 ChromeAsyncSocket::STATE_CLOSED, | |
989 ChromeAsyncSocket::ERROR_WRONGSTATE, | |
990 net::OK)); | |
991 }, "wrong state"); | |
992 } | |
993 | |
994 TEST_F(ChromeAsyncSocketTest, SSLConnectDuringPostedWrite) { | |
995 EXPECT_DEBUG_DEATH({ | |
996 DoOpenClosed(); | |
997 | |
998 async_socket_data_provider_.AddWrite( | |
999 net::MockWrite(net::ASYNC, kWriteData, 3)); | |
1000 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
1001 | |
1002 EXPECT_FALSE(chrome_async_socket_->StartTls("fakedomain.com")); | |
1003 | |
1004 message_loop_.RunAllPending(); | |
1005 | |
1006 DoCloseOpened( | |
1007 SignalSocketState(SIGNAL_CLOSE, | |
1008 ChromeAsyncSocket::STATE_CLOSED, | |
1009 ChromeAsyncSocket::ERROR_WRONGSTATE, | |
1010 net::OK)); | |
1011 }, "wrong state"); | |
1012 } | |
1013 | |
1014 // After this we can assume SSL connect works as expected. | |
1015 | |
1016 TEST_F(ChromeAsyncSocketTest, SSLRead) { | |
1017 DoSSLOpenClosed(); | |
1018 async_socket_data_provider_.AddRead(net::MockRead(kReadData)); | |
1019 message_loop_.RunAllPending(); | |
1020 | |
1021 ExpectSSLReadSignal(); | |
1022 ExpectNoSignal(); | |
1023 | |
1024 EXPECT_EQ(kReadData, DrainRead(1)); | |
1025 | |
1026 message_loop_.RunAllPending(); | |
1027 | |
1028 DoSSLCloseOpenedNoError(); | |
1029 } | |
1030 | |
1031 TEST_F(ChromeAsyncSocketTest, SSLSyncWrite) { | |
1032 async_socket_data_provider_.AddWrite( | |
1033 net::MockWrite(net::SYNCHRONOUS, kWriteData, 3)); | |
1034 async_socket_data_provider_.AddWrite( | |
1035 net::MockWrite(net::SYNCHRONOUS, kWriteData + 3, 5)); | |
1036 async_socket_data_provider_.AddWrite( | |
1037 net::MockWrite(net::SYNCHRONOUS, | |
1038 kWriteData + 8, arraysize(kWriteData) - 8)); | |
1039 DoSSLOpenClosed(); | |
1040 | |
1041 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
1042 message_loop_.RunAllPending(); | |
1043 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5)); | |
1044 message_loop_.RunAllPending(); | |
1045 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8, | |
1046 arraysize(kWriteData) - 8)); | |
1047 message_loop_.RunAllPending(); | |
1048 | |
1049 ExpectNoSignal(); | |
1050 | |
1051 DoSSLCloseOpenedNoError(); | |
1052 } | |
1053 | |
1054 TEST_F(ChromeAsyncSocketTest, SSLAsyncWrite) { | |
1055 DoSSLOpenClosed(); | |
1056 | |
1057 async_socket_data_provider_.AddWrite( | |
1058 net::MockWrite(net::ASYNC, kWriteData, 3)); | |
1059 async_socket_data_provider_.AddWrite( | |
1060 net::MockWrite(net::ASYNC, kWriteData + 3, 5)); | |
1061 async_socket_data_provider_.AddWrite( | |
1062 net::MockWrite(net::ASYNC, kWriteData + 8, arraysize(kWriteData) - 8)); | |
1063 | |
1064 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData, 3)); | |
1065 message_loop_.RunAllPending(); | |
1066 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 3, 5)); | |
1067 message_loop_.RunAllPending(); | |
1068 EXPECT_TRUE(chrome_async_socket_->Write(kWriteData + 8, | |
1069 arraysize(kWriteData) - 8)); | |
1070 message_loop_.RunAllPending(); | |
1071 | |
1072 ExpectNoSignal(); | |
1073 | |
1074 DoSSLCloseOpenedNoError(); | |
1075 } | |
1076 | |
1077 } // namespace | |
1078 | |
1079 } // namespace notifier | |
OLD | NEW |