Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: google_apis/gcm/engine/connection_handler_unittest.cc

Issue 54743007: [GCM] Add connection factory for creating MCS connections (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « google_apis/gcm/engine/connection_handler_impl_unittest.cc ('k') | google_apis/gcm/gcm.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "google_apis/gcm/engine/connection_handler.h"
6
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"
20
21 namespace gcm {
22 namespace {
23
24 typedef scoped_ptr<google::protobuf::MessageLite> ScopedMessage;
25 typedef std::vector<net::MockRead> ReadList;
26 typedef std::vector<net::MockWrite> WriteList;
27
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";
44
45 // ---- Helpers for building messages. ----
46
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);
52 google::protobuf::io::CodedOutputStream coded_output_stream(
53 &string_output_stream);
54 const unsigned char tag_byte[1] = {tag};
55 coded_output_stream.WriteRaw(tag_byte, 1);
56 coded_output_stream.WriteVarint32(proto.size());
57 coded_output_stream.WriteRaw(proto.c_str(), proto.size());
58 return result;
59 }
60
61 // Encode a handshake request into the MCS message form.
62 std::string EncodeHandshakeRequest() {
63 std::string result;
64 const char version_byte[1] = {kMCSVersion};
65 result.append(version_byte, 1);
66 ScopedMessage login_request(BuildLoginRequest(kAuthId, kAuthToken));
67 result.append(EncodePacket(kLoginRequestTag,
68 login_request->SerializeAsString()));
69 return result;
70 }
71
72 // Build a serialized login response protobuf.
73 std::string BuildLoginResponse() {
74 std::string result;
75 mcs_proto::LoginResponse login_response;
76 login_response.set_id("id");
77 result.append(login_response.SerializeAsString());
78 return result;
79 }
80
81 // Encoode a handshake response into the MCS message form.
82 std::string EncodeHandshakeResponse() {
83 std::string result;
84 const char version_byte[1] = {kMCSVersion};
85 result.append(version_byte, 1);
86 result.append(EncodePacket(kLoginResponseTag, BuildLoginResponse()));
87 return result;
88 }
89
90 // Build a serialized data message stanza protobuf.
91 std::string BuildDataMessage(const std::string& from,
92 const std::string& category) {
93 std::string result;
94 mcs_proto::DataMessageStanza data_message;
95 data_message.set_from(from);
96 data_message.set_category(category);
97 return data_message.SerializeAsString();
98 }
99
100 class GCMConnectionHandlerTest : public testing::Test {
101 public:
102 GCMConnectionHandlerTest();
103 virtual ~GCMConnectionHandlerTest();
104
105 net::StreamSocket* BuildSocket(const ReadList& read_list,
106 const WriteList& write_list);
107
108 // Pump |message_loop_|, resetting |run_loop_| after completion.
109 void PumpLoop();
110
111 ConnectionHandler* connection_handler() { return &connection_handler_; }
112 base::MessageLoop* message_loop() { return &message_loop_; };
113 net::DelayedSocketData* data_provider() { return data_provider_.get(); }
114 int last_error() const { return last_error_; }
115
116 // Initialize the connection handler, setting |dst_proto| as the destination
117 // for any received messages.
118 void Connect(ScopedMessage* dst_proto);
119
120 // Runs the message loop until a message is received.
121 void WaitForMessage();
122
123 private:
124 void ReadContinuation(ScopedMessage* dst_proto, ScopedMessage new_proto);
125 void WriteContinuation();
126 void ConnectionContinuation(int error);
127
128 // SocketStreams and their data provider.
129 ReadList mock_reads_;
130 WriteList mock_writes_;
131 scoped_ptr<net::DelayedSocketData> data_provider_;
132 scoped_ptr<SocketInputStream> socket_input_stream_;
133 scoped_ptr<SocketOutputStream> socket_output_stream_;
134
135 // The connection handler being tested.
136 ConnectionHandler connection_handler_;
137
138 // The last connection error received.
139 int last_error_;
140
141 // net:: components.
142 scoped_ptr<net::StreamSocket> socket_;
143 net::MockClientSocketFactory socket_factory_;
144 net::AddressList address_list_;
145
146 base::MessageLoopForIO message_loop_;
147 scoped_ptr<base::RunLoop> run_loop_;
148 };
149
150 GCMConnectionHandlerTest::GCMConnectionHandlerTest()
151 : connection_handler_(TestTimeouts::tiny_timeout()),
152 last_error_(0) {
153 net::IPAddressNumber ip_number;
154 net::ParseIPLiteralToNumber("127.0.0.1", &ip_number);
155 address_list_ = net::AddressList::CreateFromIPAddress(ip_number, kMCSPort);
156 }
157
158 GCMConnectionHandlerTest::~GCMConnectionHandlerTest() {
159 }
160
161 net::StreamSocket* GCMConnectionHandlerTest::BuildSocket(
162 const ReadList& read_list,
163 const WriteList& write_list) {
164 mock_reads_ = read_list;
165 mock_writes_ = write_list;
166 data_provider_.reset(
167 new net::DelayedSocketData(0,
168 &(mock_reads_[0]), mock_reads_.size(),
169 &(mock_writes_[0]), mock_writes_.size()));
170 socket_factory_.AddSocketDataProvider(data_provider_.get());
171
172 socket_ = socket_factory_.CreateTransportClientSocket(
173 address_list_, NULL, net::NetLog::Source());
174 socket_->Connect(net::CompletionCallback());
175
176 run_loop_.reset(new base::RunLoop());
177 PumpLoop();
178
179 DCHECK(socket_->IsConnected());
180 return socket_.get();
181 }
182
183 void GCMConnectionHandlerTest::PumpLoop() {
184 run_loop_->RunUntilIdle();
185 run_loop_.reset(new base::RunLoop());
186 }
187
188 void GCMConnectionHandlerTest::Connect(
189 ScopedMessage* dst_proto) {
190 connection_handler_.Init(
191 socket_.Pass(),
192 *BuildLoginRequest(kAuthId, kAuthToken),
193 base::Bind(&GCMConnectionHandlerTest::ReadContinuation,
194 base::Unretained(this),
195 dst_proto),
196 base::Bind(&GCMConnectionHandlerTest::WriteContinuation,
197 base::Unretained(this)),
198 base::Bind(&GCMConnectionHandlerTest::ConnectionContinuation,
199 base::Unretained(this)));
200 }
201
202 void GCMConnectionHandlerTest::ReadContinuation(
203 ScopedMessage* dst_proto,
204 ScopedMessage new_proto) {
205 *dst_proto = new_proto.Pass();
206 run_loop_->Quit();
207 }
208
209 void GCMConnectionHandlerTest::WaitForMessage() {
210 run_loop_->Run();
211 run_loop_.reset(new base::RunLoop());
212 }
213
214 void GCMConnectionHandlerTest::WriteContinuation() {
215 run_loop_->Quit();
216 }
217
218 void GCMConnectionHandlerTest::ConnectionContinuation(int error) {
219 last_error_ = error;
220 run_loop_->Quit();
221 }
222
223 // Initialize the connection handler and ensure the handshake completes
224 // successfully.
225 TEST_F(GCMConnectionHandlerTest, Init) {
226 std::string handshake_request = EncodeHandshakeRequest();
227 WriteList write_list(1, net::MockWrite(net::ASYNC,
228 handshake_request.c_str(),
229 handshake_request.size()));
230 std::string handshake_response = EncodeHandshakeResponse();
231 ReadList read_list(1, net::MockRead(net::ASYNC,
232 handshake_response.c_str(),
233 handshake_response.size()));
234 BuildSocket(read_list, write_list);
235
236 ScopedMessage received_message;
237 EXPECT_FALSE(connection_handler()->CanSendMessage());
238 Connect(&received_message);
239 EXPECT_FALSE(connection_handler()->CanSendMessage());
240 WaitForMessage(); // The login send.
241 WaitForMessage(); // The login response.
242 ASSERT_TRUE(received_message.get());
243 EXPECT_EQ(BuildLoginResponse(), received_message->SerializeAsString());
244 EXPECT_TRUE(connection_handler()->CanSendMessage());
245 }
246
247 // Simulate the handshake response returning an older version. Initialization
248 // should fail.
249 TEST_F(GCMConnectionHandlerTest, InitFailedVersionCheck) {
250 std::string handshake_request = EncodeHandshakeRequest();
251 WriteList write_list(1, net::MockWrite(net::ASYNC,
252 handshake_request.c_str(),
253 handshake_request.size()));
254 std::string handshake_response = EncodeHandshakeResponse();
255 // Overwrite the version byte.
256 handshake_response[0] = 37;
257 ReadList read_list(1, net::MockRead(net::ASYNC,
258 handshake_response.c_str(),
259 handshake_response.size()));
260 BuildSocket(read_list, write_list);
261
262 ScopedMessage received_message;
263 Connect(&received_message);
264 WaitForMessage(); // The login send.
265 WaitForMessage(); // The login response. Should result in a connection error.
266 EXPECT_FALSE(received_message.get());
267 EXPECT_FALSE(connection_handler()->CanSendMessage());
268 EXPECT_EQ(net::ERR_FAILED, last_error());
269 }
270
271 // Attempt to initialize, but receive no server response, resulting in a time
272 // out.
273 TEST_F(GCMConnectionHandlerTest, InitTimeout) {
274 std::string handshake_request = EncodeHandshakeRequest();
275 WriteList write_list(1, net::MockWrite(net::ASYNC,
276 handshake_request.c_str(),
277 handshake_request.size()));
278 ReadList read_list(1, net::MockRead(net::SYNCHRONOUS,
279 net::ERR_IO_PENDING));
280 BuildSocket(read_list, write_list);
281
282 ScopedMessage received_message;
283 Connect(&received_message);
284 WaitForMessage(); // The login send.
285 WaitForMessage(); // The login response. Should result in a connection error.
286 EXPECT_FALSE(received_message.get());
287 EXPECT_FALSE(connection_handler()->CanSendMessage());
288 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
289 }
290
291 // Attempt to initialize, but receive an incomplete server response, resulting
292 // in a time out.
293 TEST_F(GCMConnectionHandlerTest, InitIncompleteTimeout) {
294 std::string handshake_request = EncodeHandshakeRequest();
295 WriteList write_list(1, net::MockWrite(net::ASYNC,
296 handshake_request.c_str(),
297 handshake_request.size()));
298 std::string handshake_response = EncodeHandshakeResponse();
299 ReadList read_list;
300 read_list.push_back(net::MockRead(net::ASYNC,
301 handshake_response.c_str(),
302 handshake_response.size() / 2));
303 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
304 net::ERR_IO_PENDING));
305 BuildSocket(read_list, write_list);
306
307 ScopedMessage received_message;
308 Connect(&received_message);
309 WaitForMessage(); // The login send.
310 WaitForMessage(); // The login response. Should result in a connection error.
311 EXPECT_FALSE(received_message.get());
312 EXPECT_FALSE(connection_handler()->CanSendMessage());
313 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
314 }
315
316 // Reinitialize the connection handler after failing to initialize.
317 TEST_F(GCMConnectionHandlerTest, ReInit) {
318 std::string handshake_request = EncodeHandshakeRequest();
319 WriteList write_list(1, net::MockWrite(net::ASYNC,
320 handshake_request.c_str(),
321 handshake_request.size()));
322 ReadList read_list(1, net::MockRead(net::SYNCHRONOUS,
323 net::ERR_IO_PENDING));
324 BuildSocket(read_list, write_list);
325
326 ScopedMessage received_message;
327 Connect(&received_message);
328 WaitForMessage(); // The login send.
329 WaitForMessage(); // The login response. Should result in a connection error.
330 EXPECT_FALSE(received_message.get());
331 EXPECT_FALSE(connection_handler()->CanSendMessage());
332 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
333
334 // Build a new socket and reconnect, successfully this time.
335 std::string handshake_response = EncodeHandshakeResponse();
336 read_list[0] = net::MockRead(net::ASYNC,
337 handshake_response.c_str(),
338 handshake_response.size());
339 BuildSocket(read_list, write_list);
340 Connect(&received_message);
341 EXPECT_FALSE(connection_handler()->CanSendMessage());
342 WaitForMessage(); // The login send.
343 WaitForMessage(); // The login response.
344 ASSERT_TRUE(received_message.get());
345 EXPECT_EQ(BuildLoginResponse(), received_message->SerializeAsString());
346 EXPECT_TRUE(connection_handler()->CanSendMessage());
347 }
348
349 // Verify that messages can be received after initialization.
350 TEST_F(GCMConnectionHandlerTest, RecvMsg) {
351 std::string handshake_request = EncodeHandshakeRequest();
352 WriteList write_list(1, net::MockWrite(net::ASYNC,
353 handshake_request.c_str(),
354 handshake_request.size()));
355 std::string handshake_response = EncodeHandshakeResponse();
356
357 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
358 kDataMsgCategory);
359 std::string data_message_pkt =
360 EncodePacket(kDataMessageStanzaTag, data_message_proto);
361 ReadList read_list;
362 read_list.push_back(net::MockRead(net::ASYNC,
363 handshake_response.c_str(),
364 handshake_response.size()));
365 read_list.push_back(net::MockRead(net::ASYNC,
366 data_message_pkt.c_str(),
367 data_message_pkt.size()));
368 BuildSocket(read_list, write_list);
369
370 ScopedMessage received_message;
371 Connect(&received_message);
372 WaitForMessage(); // The login send.
373 WaitForMessage(); // The login response.
374 WaitForMessage(); // The data message.
375 ASSERT_TRUE(received_message.get());
376 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
377 }
378
379 // Verify that if two messages arrive at once, they're treated appropriately.
380 TEST_F(GCMConnectionHandlerTest, Recv2Msgs) {
381 std::string handshake_request = EncodeHandshakeRequest();
382 WriteList write_list(1, net::MockWrite(net::ASYNC,
383 handshake_request.c_str(),
384 handshake_request.size()));
385 std::string handshake_response = EncodeHandshakeResponse();
386
387 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
388 kDataMsgCategory);
389 std::string data_message_proto2 = BuildDataMessage(kDataMsgFrom2,
390 kDataMsgCategory2);
391 std::string data_message_pkt =
392 EncodePacket(kDataMessageStanzaTag, data_message_proto);
393 data_message_pkt += EncodePacket(kDataMessageStanzaTag, data_message_proto2);
394 ReadList read_list;
395 read_list.push_back(net::MockRead(net::ASYNC,
396 handshake_response.c_str(),
397 handshake_response.size()));
398 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
399 data_message_pkt.c_str(),
400 data_message_pkt.size()));
401 BuildSocket(read_list, write_list);
402
403 ScopedMessage received_message;
404 Connect(&received_message);
405 WaitForMessage(); // The login send.
406 WaitForMessage(); // The login response.
407 WaitForMessage(); // The first data message.
408 ASSERT_TRUE(received_message.get());
409 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
410 received_message.reset();
411 WaitForMessage(); // The second data message.
412 ASSERT_TRUE(received_message.get());
413 EXPECT_EQ(data_message_proto2, received_message->SerializeAsString());
414 }
415
416 // Receive a long (>128 bytes) message.
417 TEST_F(GCMConnectionHandlerTest, RecvLongMsg) {
418 std::string handshake_request = EncodeHandshakeRequest();
419 WriteList write_list(1, net::MockWrite(net::ASYNC,
420 handshake_request.c_str(),
421 handshake_request.size()));
422 std::string handshake_response = EncodeHandshakeResponse();
423
424 std::string data_message_proto =
425 BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
426 std::string data_message_pkt =
427 EncodePacket(kDataMessageStanzaTag, data_message_proto);
428 DCHECK_GT(data_message_pkt.size(), 128U);
429 ReadList read_list;
430 read_list.push_back(net::MockRead(net::ASYNC,
431 handshake_response.c_str(),
432 handshake_response.size()));
433 read_list.push_back(net::MockRead(net::ASYNC,
434 data_message_pkt.c_str(),
435 data_message_pkt.size()));
436 BuildSocket(read_list, write_list);
437
438 ScopedMessage received_message;
439 Connect(&received_message);
440 WaitForMessage(); // The login send.
441 WaitForMessage(); // The login response.
442 WaitForMessage(); // The data message.
443 ASSERT_TRUE(received_message.get());
444 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
445 }
446
447 // Receive two long (>128 bytes) message.
448 TEST_F(GCMConnectionHandlerTest, Recv2LongMsgs) {
449 std::string handshake_request = EncodeHandshakeRequest();
450 WriteList write_list(1, net::MockWrite(net::ASYNC,
451 handshake_request.c_str(),
452 handshake_request.size()));
453 std::string handshake_response = EncodeHandshakeResponse();
454
455 std::string data_message_proto =
456 BuildDataMessage(kDataMsgFromLong, kDataMsgCategoryLong);
457 std::string data_message_proto2 =
458 BuildDataMessage(kDataMsgFromLong2, kDataMsgCategoryLong2);
459 std::string data_message_pkt =
460 EncodePacket(kDataMessageStanzaTag, data_message_proto);
461 data_message_pkt += EncodePacket(kDataMessageStanzaTag, data_message_proto2);
462 DCHECK_GT(data_message_pkt.size(), 256U);
463 ReadList read_list;
464 read_list.push_back(net::MockRead(net::ASYNC,
465 handshake_response.c_str(),
466 handshake_response.size()));
467 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
468 data_message_pkt.c_str(),
469 data_message_pkt.size()));
470 BuildSocket(read_list, write_list);
471
472 ScopedMessage received_message;
473 Connect(&received_message);
474 WaitForMessage(); // The login send.
475 WaitForMessage(); // The login response.
476 WaitForMessage(); // The first data message.
477 ASSERT_TRUE(received_message.get());
478 EXPECT_EQ(data_message_proto, received_message->SerializeAsString());
479 received_message.reset();
480 WaitForMessage(); // The second data message.
481 ASSERT_TRUE(received_message.get());
482 EXPECT_EQ(data_message_proto2, received_message->SerializeAsString());
483 }
484
485 // Simulate a message where the end of the data does not arrive in time and the
486 // read times out.
487 TEST_F(GCMConnectionHandlerTest, ReadTimeout) {
488 std::string handshake_request = EncodeHandshakeRequest();
489 WriteList write_list(1, net::MockWrite(net::ASYNC,
490 handshake_request.c_str(),
491 handshake_request.size()));
492 std::string handshake_response = EncodeHandshakeResponse();
493
494 std::string data_message_proto = BuildDataMessage(kDataMsgFrom,
495 kDataMsgCategory);
496 std::string data_message_pkt =
497 EncodePacket(kDataMessageStanzaTag, data_message_proto);
498 int bytes_in_first_message = data_message_pkt.size() / 2;
499 ReadList read_list;
500 read_list.push_back(net::MockRead(net::ASYNC,
501 handshake_response.c_str(),
502 handshake_response.size()));
503 read_list.push_back(net::MockRead(net::ASYNC,
504 data_message_pkt.c_str(),
505 bytes_in_first_message));
506 read_list.push_back(net::MockRead(net::SYNCHRONOUS,
507 net::ERR_IO_PENDING));
508 read_list.push_back(net::MockRead(net::ASYNC,
509 data_message_pkt.c_str() +
510 bytes_in_first_message,
511 data_message_pkt.size() -
512 bytes_in_first_message));
513 BuildSocket(read_list, write_list);
514
515 ScopedMessage received_message;
516 Connect(&received_message);
517 WaitForMessage(); // The login send.
518 WaitForMessage(); // The login response.
519 received_message.reset();
520 WaitForMessage(); // Should time out.
521 EXPECT_FALSE(received_message.get());
522 EXPECT_EQ(net::ERR_TIMED_OUT, last_error());
523 EXPECT_FALSE(connection_handler()->CanSendMessage());
524
525 // Finish the socket read. Should have no effect.
526 data_provider()->ForceNextRead();
527 }
528
529 // Receive a message with zero data bytes.
530 TEST_F(GCMConnectionHandlerTest, RecvMsgNoData) {
531 std::string handshake_request = EncodeHandshakeRequest();
532 WriteList write_list(1, net::MockWrite(net::ASYNC,
533 handshake_request.c_str(),
534 handshake_request.size()));
535 std::string handshake_response = EncodeHandshakeResponse();
536
537 std::string data_message_pkt = EncodePacket(kHeartbeatPingTag, "");
538 ASSERT_EQ(data_message_pkt.size(), 2U);
539 ReadList read_list;
540 read_list.push_back(net::MockRead(net::ASYNC,
541 handshake_response.c_str(),
542 handshake_response.size()));
543 read_list.push_back(net::MockRead(net::ASYNC,
544 data_message_pkt.c_str(),
545 data_message_pkt.size()));
546 BuildSocket(read_list, write_list);
547
548 ScopedMessage received_message;
549 Connect(&received_message);
550 WaitForMessage(); // The login send.
551 WaitForMessage(); // The login response.
552 received_message.reset();
553 WaitForMessage(); // The heartbeat ping.
554 EXPECT_TRUE(received_message.get());
555 EXPECT_EQ(GetMCSProtoTag(*received_message), kHeartbeatPingTag);
556 EXPECT_EQ(net::OK, last_error());
557 EXPECT_TRUE(connection_handler()->CanSendMessage());
558 }
559
560 // Send a message after performing the handshake.
561 TEST_F(GCMConnectionHandlerTest, SendMsg) {
562 mcs_proto::DataMessageStanza data_message;
563 data_message.set_from(kDataMsgFrom);
564 data_message.set_category(kDataMsgCategory);
565 std::string handshake_request = EncodeHandshakeRequest();
566 std::string data_message_pkt =
567 EncodePacket(kDataMessageStanzaTag, data_message.SerializeAsString());
568 WriteList write_list;
569 write_list.push_back(net::MockWrite(net::ASYNC,
570 handshake_request.c_str(),
571 handshake_request.size()));
572 write_list.push_back(net::MockWrite(net::ASYNC,
573 data_message_pkt.c_str(),
574 data_message_pkt.size()));
575 std::string handshake_response = EncodeHandshakeResponse();
576 ReadList read_list;
577 read_list.push_back(net::MockRead(net::ASYNC,
578 handshake_response.c_str(),
579 handshake_response.size()));
580 read_list.push_back(net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING));
581 BuildSocket(read_list, write_list);
582
583 ScopedMessage received_message;
584 Connect(&received_message);
585 WaitForMessage(); // The login send.
586 WaitForMessage(); // The login response.
587 EXPECT_TRUE(connection_handler()->CanSendMessage());
588 connection_handler()->SendMessage(data_message);
589 EXPECT_FALSE(connection_handler()->CanSendMessage());
590 WaitForMessage(); // The message send.
591 EXPECT_TRUE(connection_handler()->CanSendMessage());
592 }
593
594 // Attempt to send a message after the socket is disconnected due to a timeout.
595 TEST_F(GCMConnectionHandlerTest, SendMsgSocketDisconnected) {
596 std::string handshake_request = EncodeHandshakeRequest();
597 WriteList write_list;
598 write_list.push_back(net::MockWrite(net::ASYNC,
599 handshake_request.c_str(),
600 handshake_request.size()));
601 std::string handshake_response = EncodeHandshakeResponse();
602 ReadList read_list;
603 read_list.push_back(net::MockRead(net::ASYNC,
604 handshake_response.c_str(),
605 handshake_response.size()));
606 read_list.push_back(net::MockRead(net::SYNCHRONOUS, net::ERR_IO_PENDING));
607 net::StreamSocket* socket = BuildSocket(read_list, write_list);
608
609 ScopedMessage received_message;
610 Connect(&received_message);
611 WaitForMessage(); // The login send.
612 WaitForMessage(); // The login response.
613 EXPECT_TRUE(connection_handler()->CanSendMessage());
614 socket->Disconnect();
615 mcs_proto::DataMessageStanza data_message;
616 data_message.set_from(kDataMsgFrom);
617 data_message.set_category(kDataMsgCategory);
618 connection_handler()->SendMessage(data_message);
619 EXPECT_FALSE(connection_handler()->CanSendMessage());
620 WaitForMessage(); // The message send. Should result in an error
621 EXPECT_FALSE(connection_handler()->CanSendMessage());
622 EXPECT_EQ(net::ERR_CONNECTION_CLOSED, last_error());
623 }
624
625 } // namespace
626 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/connection_handler_impl_unittest.cc ('k') | google_apis/gcm/gcm.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698