Update ASan/Android runtime and setup script to LLVM r200682.
[chromium-blink-merge.git] / google_apis / gcm / engine / connection_handler_impl_unittest.cc
blobd9f381ba2ac23fc91ba948038a0057837852ed90
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "google_apis/gcm/engine/connection_handler_impl.h"
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/test/test_timeouts.h"
12 #include "google/protobuf/io/coded_stream.h"
13 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
14 #include "google_apis/gcm/base/mcs_util.h"
15 #include "google_apis/gcm/base/socket_stream.h"
16 #include "google_apis/gcm/protocol/mcs.pb.h"
17 #include "net/socket/socket_test_util.h"
18 #include "net/socket/stream_socket.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 namespace gcm {
22 namespace {
24 typedef scoped_ptr<google::protobuf::MessageLite> ScopedMessage;
25 typedef std::vector<net::MockRead> ReadList;
26 typedef std::vector<net::MockWrite> WriteList;
28 const uint64 kAuthId = 54321;
29 const uint64 kAuthToken = 12345;
30 const char kMCSVersion = 38; // The protocol version.
31 const int kMCSPort = 5228; // The server port.
32 const char kDataMsgFrom[] = "data_from";
33 const char kDataMsgCategory[] = "data_category";
34 const char kDataMsgFrom2[] = "data_from2";
35 const char kDataMsgCategory2[] = "data_category2";
36 const char kDataMsgFromLong[] =
37 "this is a long from that will result in a message > 128 bytes";
38 const char kDataMsgCategoryLong[] =
39 "this is a long category that will result in a message > 128 bytes";
40 const char kDataMsgFromLong2[] =
41 "this is a second long from that will result in a message > 128 bytes";
42 const char kDataMsgCategoryLong2[] =
43 "this is a second long category that will result in a message > 128 bytes";
45 // ---- Helpers for building messages. ----
47 // Encode a protobuf packet with protobuf type |tag| and serialized protobuf
48 // bytes |proto| into the MCS message form (tag + varint size + bytes).
49 std::string EncodePacket(uint8 tag, const std::string& proto) {
50 std::string result;
51 google::protobuf::io::StringOutputStream string_output_stream(&result);
53 google::protobuf::io::CodedOutputStream coded_output_stream(
54 &string_output_stream);
55 const unsigned char tag_byte[1] = { tag };
56 coded_output_stream.WriteRaw(tag_byte, 1);
57 coded_output_stream.WriteVarint32(proto.size());
58 coded_output_stream.WriteRaw(proto.c_str(), proto.size());
59 // ~CodedOutputStream must run before the move constructor at the
60 // return statement. http://crbug.com/338962
62 return result;
65 // Encode a handshake request into the MCS message form.
66 std::string EncodeHandshakeRequest() {
67 std::string result;
68 const char version_byte[1] = {kMCSVersion};
69 result.append(version_byte, 1);
70 std::vector<int64> user_serial_numbers;
71 ScopedMessage login_request(
72 BuildLoginRequest(kAuthId, kAuthToken, user_serial_numbers));
73 result.append(EncodePacket(kLoginRequestTag,
74 login_request->SerializeAsString()));
75 return result;
78 // Build a serialized login response protobuf.
79 std::string BuildLoginResponse() {
80 std::string result;
81 mcs_proto::LoginResponse login_response;
82 login_response.set_id("id");
83 result.append(login_response.SerializeAsString());
84 return result;
87 // Encoode a handshake response into the MCS message form.
88 std::string EncodeHandshakeResponse() {
89 std::string result;
90 const char version_byte[1] = {kMCSVersion};
91 result.append(version_byte, 1);
92 result.append(EncodePacket(kLoginResponseTag, BuildLoginResponse()));
93 return result;
96 // Build a serialized data message stanza protobuf.
97 std::string BuildDataMessage(const std::string& from,
98 const std::string& category) {
99 std::string result;
100 mcs_proto::DataMessageStanza data_message;
101 data_message.set_from(from);
102 data_message.set_category(category);
103 return data_message.SerializeAsString();
106 class GCMConnectionHandlerImplTest : public testing::Test {
107 public:
108 GCMConnectionHandlerImplTest();
109 virtual ~GCMConnectionHandlerImplTest();
111 net::StreamSocket* BuildSocket(const ReadList& read_list,
112 const WriteList& write_list);
114 // Pump |message_loop_|, resetting |run_loop_| after completion.
115 void PumpLoop();
117 ConnectionHandlerImpl* connection_handler() {
118 return connection_handler_.get();
120 base::MessageLoop* message_loop() { return &message_loop_; };
121 net::DelayedSocketData* data_provider() { return data_provider_.get(); }
122 int last_error() const { return last_error_; }
124 // Initialize the connection handler, setting |dst_proto| as the destination
125 // for any received messages.
126 void Connect(ScopedMessage* dst_proto);
128 // Runs the message loop until a message is received.
129 void WaitForMessage();
131 private:
132 void ReadContinuation(ScopedMessage* dst_proto, ScopedMessage new_proto);
133 void WriteContinuation();
134 void ConnectionContinuation(int error);
136 // SocketStreams and their data provider.
137 ReadList mock_reads_;
138 WriteList mock_writes_;
139 scoped_ptr<net::DelayedSocketData> data_provider_;
140 scoped_ptr<SocketInputStream> socket_input_stream_;
141 scoped_ptr<SocketOutputStream> socket_output_stream_;
143 // The connection handler being tested.
144 scoped_ptr<ConnectionHandlerImpl> connection_handler_;
146 // The last connection error received.
147 int last_error_;
149 // net:: components.
150 scoped_ptr<net::StreamSocket> socket_;
151 net::MockClientSocketFactory socket_factory_;
152 net::AddressList address_list_;
154 base::MessageLoopForIO message_loop_;
155 scoped_ptr<base::RunLoop> run_loop_;
158 GCMConnectionHandlerImplTest::GCMConnectionHandlerImplTest()
159 : last_error_(0) {
160 net::IPAddressNumber ip_number;
161 net::ParseIPLiteralToNumber("127.0.0.1", &ip_number);
162 address_list_ = net::AddressList::CreateFromIPAddress(ip_number, kMCSPort);
165 GCMConnectionHandlerImplTest::~GCMConnectionHandlerImplTest() {
168 net::StreamSocket* GCMConnectionHandlerImplTest::BuildSocket(
169 const ReadList& read_list,
170 const WriteList& write_list) {
171 mock_reads_ = read_list;
172 mock_writes_ = write_list;
173 data_provider_.reset(
174 new net::DelayedSocketData(0,
175 &(mock_reads_[0]), mock_reads_.size(),
176 &(mock_writes_[0]), mock_writes_.size()));
177 socket_factory_.AddSocketDataProvider(data_provider_.get());
179 socket_ = socket_factory_.CreateTransportClientSocket(
180 address_list_, NULL, net::NetLog::Source());
181 socket_->Connect(net::CompletionCallback());
183 run_loop_.reset(new base::RunLoop());
184 PumpLoop();
186 DCHECK(socket_->IsConnected());
187 return socket_.get();
190 void GCMConnectionHandlerImplTest::PumpLoop() {
191 run_loop_->RunUntilIdle();
192 run_loop_.reset(new base::RunLoop());
195 void GCMConnectionHandlerImplTest::Connect(
196 ScopedMessage* dst_proto) {
197 connection_handler_.reset(new ConnectionHandlerImpl(
198 TestTimeouts::tiny_timeout(),
199 base::Bind(&GCMConnectionHandlerImplTest::ReadContinuation,
200 base::Unretained(this),
201 dst_proto),
202 base::Bind(&GCMConnectionHandlerImplTest::WriteContinuation,
203 base::Unretained(this)),
204 base::Bind(&GCMConnectionHandlerImplTest::ConnectionContinuation,
205 base::Unretained(this))));
206 EXPECT_FALSE(connection_handler()->CanSendMessage());
207 std::vector<int64> user_serial_numbers;
208 connection_handler_->Init(
209 *BuildLoginRequest(kAuthId, kAuthToken, user_serial_numbers),
210 socket_.get());
213 void GCMConnectionHandlerImplTest::ReadContinuation(
214 ScopedMessage* dst_proto,
215 ScopedMessage new_proto) {
216 *dst_proto = new_proto.Pass();
217 run_loop_->Quit();
220 void GCMConnectionHandlerImplTest::WaitForMessage() {
221 run_loop_->Run();
222 run_loop_.reset(new base::RunLoop());
225 void GCMConnectionHandlerImplTest::WriteContinuation() {
226 run_loop_->Quit();
229 void GCMConnectionHandlerImplTest::ConnectionContinuation(int error) {
230 last_error_ = error;
231 run_loop_->Quit();
234 // Initialize the connection handler and ensure the handshake completes
235 // successfully.
236 TEST_F(GCMConnectionHandlerImplTest, Init) {
237 std::string handshake_request = EncodeHandshakeRequest();
238 WriteList write_list(1, net::MockWrite(net::ASYNC,
239 handshake_request.c_str(),
240 handshake_request.size()));
241 std::string handshake_response = EncodeHandshakeResponse();
242 ReadList read_list(1, net::MockRead(net::ASYNC,
243 handshake_response.c_str(),
244 handshake_response.size()));
245 BuildSocket(read_list, write_list);
247 ScopedMessage received_message;
248 Connect(&received_message);
249 EXPECT_FALSE(connection_handler()->CanSendMessage());
250 WaitForMessage(); // The login send.
251 WaitForMessage(); // The login response.
252 ASSERT_TRUE(received_message.get());
253 EXPECT_EQ(BuildLoginResponse(), received_message->SerializeAsString());
254 EXPECT_TRUE(connection_handler()->CanSendMessage());
257 // Simulate the handshake response returning an older version. Initialization
258 // should fail.
259 TEST_F(GCMConnectionHandlerImplTest, InitFailedVersionCheck) {
260 std::string handshake_request = EncodeHandshakeRequest();
261 WriteList write_list(1, net::MockWrite(net::ASYNC,
262 handshake_request.c_str(),
263 handshake_request.size()));
264 std::string handshake_response = EncodeHandshakeResponse();
265 // Overwrite the version byte.
266 handshake_response[0] = 37;
267 ReadList read_list(1, net::MockRead(net::ASYNC,
268 handshake_response.c_str(),
269 handshake_response.size()));
270 BuildSocket(read_list, write_list);
272 ScopedMessage received_message;
273 Connect(&received_message);
274 WaitForMessage(); // The login send.
275 WaitForMessage(); // The login response. Should result in a connection error.
276 EXPECT_FALSE(received_message.get());
277 EXPECT_FALSE(connection_handler()->CanSendMessage());
278 EXPECT_EQ(net::ERR_FAILED, last_error());
281 // Attempt to initialize, but receive no server response, resulting in a time
282 // out.
283 TEST_F(GCMConnectionHandlerImplTest, InitTimeout) {
284 std::string handshake_request = EncodeHandshakeRequest();
285 WriteList write_list(1, net::MockWrite(net::ASYNC,
286 handshake_request.c_str(),
287 handshake_request.size()));
288 ReadList read_list(1, net::MockRead(net::SYNCHRONOUS,
289 net::ERR_IO_PENDING));
290 BuildSocket(read_list, write_list);
292 ScopedMessage received_message;
293 Connect(&received_message);
294 WaitForMessage(); // The login send.
295 WaitForMessage(); // The login response. Should result in a connection error.
296 EXPECT_FALSE(received_message.get());
297 EXPECT_FALSE(connection_handler()->CanSendMessage());
298 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
301 // Attempt to initialize, but receive an incomplete server response, resulting
302 // in a time out.
303 TEST_F(GCMConnectionHandlerImplTest, InitIncompleteTimeout) {
304 std::string handshake_request = EncodeHandshakeRequest();
305 WriteList write_list(1, net::MockWrite(net::ASYNC,
306 handshake_request.c_str(),
307 handshake_request.size()));
308 std::string handshake_response = EncodeHandshakeResponse();
309 ReadList read_list;
310 read_list.push_back(net::MockRead(net::ASYNC,
311 handshake_response.c_str(),
312 handshake_response.size() / 2));
313 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
314 net::ERR_IO_PENDING));
315 BuildSocket(read_list, write_list);
317 ScopedMessage received_message;
318 Connect(&received_message);
319 WaitForMessage(); // The login send.
320 WaitForMessage(); // The login response. Should result in a connection error.
321 EXPECT_FALSE(received_message.get());
322 EXPECT_FALSE(connection_handler()->CanSendMessage());
323 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
326 // Reinitialize the connection handler after failing to initialize.
327 TEST_F(GCMConnectionHandlerImplTest, ReInit) {
328 std::string handshake_request = EncodeHandshakeRequest();
329 WriteList write_list(1, net::MockWrite(net::ASYNC,
330 handshake_request.c_str(),
331 handshake_request.size()));
332 ReadList read_list(1, net::MockRead(net::SYNCHRONOUS,
333 net::ERR_IO_PENDING));
334 BuildSocket(read_list, write_list);
336 ScopedMessage received_message;
337 Connect(&received_message);
338 WaitForMessage(); // The login send.
339 WaitForMessage(); // The login response. Should result in a connection error.
340 EXPECT_FALSE(received_message.get());
341 EXPECT_FALSE(connection_handler()->CanSendMessage());
342 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
344 // Build a new socket and reconnect, successfully this time.
345 std::string handshake_response = EncodeHandshakeResponse();
346 read_list[0] = net::MockRead(net::ASYNC,
347 handshake_response.c_str(),
348 handshake_response.size());
349 BuildSocket(read_list, write_list);
350 Connect(&received_message);
351 EXPECT_FALSE(connection_handler()->CanSendMessage());
352 WaitForMessage(); // The login send.
353 WaitForMessage(); // The login response.
354 ASSERT_TRUE(received_message.get());
355 EXPECT_EQ(BuildLoginResponse(), received_message->SerializeAsString());
356 EXPECT_TRUE(connection_handler()->CanSendMessage());
359 // Verify that messages can be received after initialization.
360 TEST_F(GCMConnectionHandlerImplTest, RecvMsg) {
361 std::string handshake_request = EncodeHandshakeRequest();
362 WriteList write_list(1, net::MockWrite(net::ASYNC,
363 handshake_request.c_str(),
364 handshake_request.size()));
365 std::string handshake_response = EncodeHandshakeResponse();
367 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
368 kDataMsgCategory);
369 std::string data_message_pkt =
370 EncodePacket(kDataMessageStanzaTag, data_message_proto);
371 ReadList read_list;
372 read_list.push_back(net::MockRead(net::ASYNC,
373 handshake_response.c_str(),
374 handshake_response.size()));
375 read_list.push_back(net::MockRead(net::ASYNC,
376 data_message_pkt.c_str(),
377 data_message_pkt.size()));
378 BuildSocket(read_list, write_list);
380 ScopedMessage received_message;
381 Connect(&received_message);
382 WaitForMessage(); // The login send.
383 WaitForMessage(); // The login response.
384 WaitForMessage(); // The data message.
385 ASSERT_TRUE(received_message.get());
386 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
389 // Verify that if two messages arrive at once, they're treated appropriately.
390 TEST_F(GCMConnectionHandlerImplTest, Recv2Msgs) {
391 std::string handshake_request = EncodeHandshakeRequest();
392 WriteList write_list(1, net::MockWrite(net::ASYNC,
393 handshake_request.c_str(),
394 handshake_request.size()));
395 std::string handshake_response = EncodeHandshakeResponse();
397 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
398 kDataMsgCategory);
399 std::string data_message_proto2 = BuildDataMessage(kDataMsgFrom2,
400 kDataMsgCategory2);
401 std::string data_message_pkt =
402 EncodePacket(kDataMessageStanzaTag, data_message_proto);
403 data_message_pkt += EncodePacket(kDataMessageStanzaTag, data_message_proto2);
404 ReadList read_list;
405 read_list.push_back(net::MockRead(net::ASYNC,
406 handshake_response.c_str(),
407 handshake_response.size()));
408 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
409 data_message_pkt.c_str(),
410 data_message_pkt.size()));
411 BuildSocket(read_list, write_list);
413 ScopedMessage received_message;
414 Connect(&received_message);
415 WaitForMessage(); // The login send.
416 WaitForMessage(); // The login response.
417 WaitForMessage(); // The first data message.
418 ASSERT_TRUE(received_message.get());
419 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
420 received_message.reset();
421 WaitForMessage(); // The second data message.
422 ASSERT_TRUE(received_message.get());
423 EXPECT_EQ(data_message_proto2, received_message->SerializeAsString());
426 // Receive a long (>128 bytes) message.
427 TEST_F(GCMConnectionHandlerImplTest, RecvLongMsg) {
428 std::string handshake_request = EncodeHandshakeRequest();
429 WriteList write_list(1, net::MockWrite(net::ASYNC,
430 handshake_request.c_str(),
431 handshake_request.size()));
432 std::string handshake_response = EncodeHandshakeResponse();
434 std::string data_message_proto =
435 BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
436 std::string data_message_pkt =
437 EncodePacket(kDataMessageStanzaTag, data_message_proto);
438 DCHECK_GT(data_message_pkt.size(), 128U);
439 ReadList read_list;
440 read_list.push_back(net::MockRead(net::ASYNC,
441 handshake_response.c_str(),
442 handshake_response.size()));
443 read_list.push_back(net::MockRead(net::ASYNC,
444 data_message_pkt.c_str(),
445 data_message_pkt.size()));
446 BuildSocket(read_list, write_list);
448 ScopedMessage received_message;
449 Connect(&received_message);
450 WaitForMessage(); // The login send.
451 WaitForMessage(); // The login response.
452 WaitForMessage(); // The data message.
453 ASSERT_TRUE(received_message.get());
454 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
457 // Receive two long (>128 bytes) message.
458 TEST_F(GCMConnectionHandlerImplTest, Recv2LongMsgs) {
459 std::string handshake_request = EncodeHandshakeRequest();
460 WriteList write_list(1, net::MockWrite(net::ASYNC,
461 handshake_request.c_str(),
462 handshake_request.size()));
463 std::string handshake_response = EncodeHandshakeResponse();
465 std::string data_message_proto =
466 BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
467 std::string data_message_proto2 =
468 BuildDataMessage(kDataMsgFromLong2, kDataMsgCategoryLong2);
469 std::string data_message_pkt =
470 EncodePacket(kDataMessageStanzaTag, data_message_proto);
471 data_message_pkt += EncodePacket(kDataMessageStanzaTag, data_message_proto2);
472 DCHECK_GT(data_message_pkt.size(), 256U);
473 ReadList read_list;
474 read_list.push_back(net::MockRead(net::ASYNC,
475 handshake_response.c_str(),
476 handshake_response.size()));
477 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
478 data_message_pkt.c_str(),
479 data_message_pkt.size()));
480 BuildSocket(read_list, write_list);
482 ScopedMessage received_message;
483 Connect(&received_message);
484 WaitForMessage(); // The login send.
485 WaitForMessage(); // The login response.
486 WaitForMessage(); // The first data message.
487 ASSERT_TRUE(received_message.get());
488 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
489 received_message.reset();
490 WaitForMessage(); // The second data message.
491 ASSERT_TRUE(received_message.get());
492 EXPECT_EQ(data_message_proto2, received_message->SerializeAsString());
495 // Simulate a message where the end of the data does not arrive in time and the
496 // read times out.
497 TEST_F(GCMConnectionHandlerImplTest, ReadTimeout) {
498 std::string handshake_request = EncodeHandshakeRequest();
499 WriteList write_list(1, net::MockWrite(net::ASYNC,
500 handshake_request.c_str(),
501 handshake_request.size()));
502 std::string handshake_response = EncodeHandshakeResponse();
504 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
505 kDataMsgCategory);
506 std::string data_message_pkt =
507 EncodePacket(kDataMessageStanzaTag, data_message_proto);
508 int bytes_in_first_message = data_message_pkt.size() / 2;
509 ReadList read_list;
510 read_list.push_back(net::MockRead(net::ASYNC,
511 handshake_response.c_str(),
512 handshake_response.size()));
513 read_list.push_back(net::MockRead(net::ASYNC,
514 data_message_pkt.c_str(),
515 bytes_in_first_message));
516 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
517 net::ERR_IO_PENDING));
518 read_list.push_back(net::MockRead(net::ASYNC,
519 data_message_pkt.c_str() +
520 bytes_in_first_message,
521 data_message_pkt.size() -
522 bytes_in_first_message));
523 BuildSocket(read_list, write_list);
525 ScopedMessage received_message;
526 Connect(&received_message);
527 WaitForMessage(); // The login send.
528 WaitForMessage(); // The login response.
529 received_message.reset();
530 WaitForMessage(); // Should time out.
531 EXPECT_FALSE(received_message.get());
532 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
533 EXPECT_FALSE(connection_handler()->CanSendMessage());
535 // Finish the socket read. Should have no effect.
536 data_provider()->ForceNextRead();
539 // Receive a message with zero data bytes.
540 TEST_F(GCMConnectionHandlerImplTest, RecvMsgNoData) {
541 std::string handshake_request = EncodeHandshakeRequest();
542 WriteList write_list(1, net::MockWrite(net::ASYNC,
543 handshake_request.c_str(),
544 handshake_request.size()));
545 std::string handshake_response = EncodeHandshakeResponse();
547 std::string data_message_pkt = EncodePacket(kHeartbeatPingTag, "");
548 ASSERT_EQ(data_message_pkt.size(), 2U);
549 ReadList read_list;
550 read_list.push_back(net::MockRead(net::ASYNC,
551 handshake_response.c_str(),
552 handshake_response.size()));
553 read_list.push_back(net::MockRead(net::ASYNC,
554 data_message_pkt.c_str(),
555 data_message_pkt.size()));
556 BuildSocket(read_list, write_list);
558 ScopedMessage received_message;
559 Connect(&received_message);
560 WaitForMessage(); // The login send.
561 WaitForMessage(); // The login response.
562 received_message.reset();
563 WaitForMessage(); // The heartbeat ping.
564 EXPECT_TRUE(received_message.get());
565 EXPECT_EQ(GetMCSProtoTag(*received_message), kHeartbeatPingTag);
566 EXPECT_EQ(net::OK, last_error());
567 EXPECT_TRUE(connection_handler()->CanSendMessage());
570 // Send a message after performing the handshake.
571 TEST_F(GCMConnectionHandlerImplTest, SendMsg) {
572 mcs_proto::DataMessageStanza data_message;
573 data_message.set_from(kDataMsgFrom);
574 data_message.set_category(kDataMsgCategory);
575 std::string handshake_request = EncodeHandshakeRequest();
576 std::string data_message_pkt =
577 EncodePacket(kDataMessageStanzaTag, data_message.SerializeAsString());
578 WriteList write_list;
579 write_list.push_back(net::MockWrite(net::ASYNC,
580 handshake_request.c_str(),
581 handshake_request.size()));
582 write_list.push_back(net::MockWrite(net::ASYNC,
583 data_message_pkt.c_str(),
584 data_message_pkt.size()));
585 std::string handshake_response = EncodeHandshakeResponse();
586 ReadList read_list;
587 read_list.push_back(net::MockRead(net::ASYNC,
588 handshake_response.c_str(),
589 handshake_response.size()));
590 read_list.push_back(net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING));
591 BuildSocket(read_list, write_list);
593 ScopedMessage received_message;
594 Connect(&received_message);
595 WaitForMessage(); // The login send.
596 WaitForMessage(); // The login response.
597 EXPECT_TRUE(connection_handler()->CanSendMessage());
598 connection_handler()->SendMessage(data_message);
599 EXPECT_FALSE(connection_handler()->CanSendMessage());
600 WaitForMessage(); // The message send.
601 EXPECT_TRUE(connection_handler()->CanSendMessage());
604 // Attempt to send a message after the socket is disconnected due to a timeout.
605 TEST_F(GCMConnectionHandlerImplTest, SendMsgSocketDisconnected) {
606 std::string handshake_request = EncodeHandshakeRequest();
607 WriteList write_list;
608 write_list.push_back(net::MockWrite(net::ASYNC,
609 handshake_request.c_str(),
610 handshake_request.size()));
611 std::string handshake_response = EncodeHandshakeResponse();
612 ReadList read_list;
613 read_list.push_back(net::MockRead(net::ASYNC,
614 handshake_response.c_str(),
615 handshake_response.size()));
616 read_list.push_back(net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING));
617 net::StreamSocket* socket = BuildSocket(read_list, write_list);
619 ScopedMessage received_message;
620 Connect(&received_message);
621 WaitForMessage(); // The login send.
622 WaitForMessage(); // The login response.
623 EXPECT_TRUE(connection_handler()->CanSendMessage());
624 socket->Disconnect();
625 mcs_proto::DataMessageStanza data_message;
626 data_message.set_from(kDataMsgFrom);
627 data_message.set_category(kDataMsgCategory);
628 connection_handler()->SendMessage(data_message);
629 EXPECT_FALSE(connection_handler()->CanSendMessage());
630 WaitForMessage(); // The message send. Should result in an error
631 EXPECT_FALSE(connection_handler()->CanSendMessage());
632 EXPECT_EQ(net::ERR_CONNECTION_CLOSED, last_error());
635 } // namespace
636 } // namespace gcm