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 "google_apis/gcm/engine/mcs_client.h" | 5 #include "google_apis/gcm/engine/mcs_client.h" |
6 | 6 |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 const int kTTLValue = 5 * 60; // 5 minutes. | 36 const int kTTLValue = 5 * 60; // 5 minutes. |
37 | 37 |
38 // Helper for building arbitrary data messages. | 38 // Helper for building arbitrary data messages. |
39 MCSMessage BuildDataMessage(const std::string& from, | 39 MCSMessage BuildDataMessage(const std::string& from, |
40 const std::string& category, | 40 const std::string& category, |
41 const std::string& message_id, | 41 const std::string& message_id, |
42 int last_stream_id_received, | 42 int last_stream_id_received, |
43 const std::string& persistent_id, | 43 const std::string& persistent_id, |
44 int ttl, | 44 int ttl, |
45 uint64 sent, | 45 uint64 sent, |
46 int queued) { | 46 int queued, |
| 47 const std::string& token, |
| 48 const uint64& user_id) { |
47 mcs_proto::DataMessageStanza data_message; | 49 mcs_proto::DataMessageStanza data_message; |
48 data_message.set_id(message_id); | 50 data_message.set_id(message_id); |
49 data_message.set_from(from); | 51 data_message.set_from(from); |
50 data_message.set_category(category); | 52 data_message.set_category(category); |
51 data_message.set_last_stream_id_received(last_stream_id_received); | 53 data_message.set_last_stream_id_received(last_stream_id_received); |
52 if (!persistent_id.empty()) | 54 if (!persistent_id.empty()) |
53 data_message.set_persistent_id(persistent_id); | 55 data_message.set_persistent_id(persistent_id); |
54 data_message.set_ttl(ttl); | 56 data_message.set_ttl(ttl); |
55 data_message.set_sent(sent); | 57 data_message.set_sent(sent); |
56 data_message.set_queued(queued); | 58 data_message.set_queued(queued); |
| 59 data_message.set_token(token); |
| 60 data_message.set_device_user_id(user_id); |
57 return MCSMessage(kDataMessageStanzaTag, data_message); | 61 return MCSMessage(kDataMessageStanzaTag, data_message); |
58 } | 62 } |
59 | 63 |
60 // MCSClient with overriden exposed persistent id logic. | 64 // MCSClient with overriden exposed persistent id logic. |
61 class TestMCSClient : public MCSClient { | 65 class TestMCSClient : public MCSClient { |
62 public: | 66 public: |
63 TestMCSClient(base::Clock* clock, | 67 TestMCSClient(base::Clock* clock, |
64 ConnectionFactory* connection_factory, | 68 ConnectionFactory* connection_factory, |
65 GCMStore* gcm_store) | 69 GCMStore* gcm_store) |
66 : MCSClient(clock, connection_factory, gcm_store), | 70 : MCSClient(clock, connection_factory, gcm_store), |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 EXPECT_FALSE(connection_factory()->IsEndpointReachable()); | 283 EXPECT_FALSE(connection_factory()->IsEndpointReachable()); |
280 EXPECT_FALSE(init_success()); | 284 EXPECT_FALSE(init_success()); |
281 EXPECT_FALSE(received_message()); | 285 EXPECT_FALSE(received_message()); |
282 } | 286 } |
283 | 287 |
284 // Send a message without RMQ support. | 288 // Send a message without RMQ support. |
285 TEST_F(MCSClientTest, SendMessageNoRMQ) { | 289 TEST_F(MCSClientTest, SendMessageNoRMQ) { |
286 BuildMCSClient(); | 290 BuildMCSClient(); |
287 InitializeClient(); | 291 InitializeClient(); |
288 LoginClient(std::vector<std::string>()); | 292 LoginClient(std::vector<std::string>()); |
289 MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0)); | 293 MCSMessage message( |
| 294 BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); |
290 GetFakeHandler()->ExpectOutgoingMessage(message); | 295 GetFakeHandler()->ExpectOutgoingMessage(message); |
291 mcs_client()->SendMessage(message); | 296 mcs_client()->SendMessage(message); |
292 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 297 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
293 } | 298 } |
294 | 299 |
295 // Send a message without RMQ support while disconnected. Message send should | 300 // Send a message without RMQ support while disconnected. Message send should |
296 // fail immediately, invoking callback. | 301 // fail immediately, invoking callback. |
297 TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) { | 302 TEST_F(MCSClientTest, SendMessageNoRMQWhileDisconnected) { |
298 BuildMCSClient(); | 303 BuildMCSClient(); |
299 InitializeClient(); | 304 InitializeClient(); |
300 | 305 |
301 EXPECT_TRUE(sent_message_id().empty()); | 306 EXPECT_TRUE(sent_message_id().empty()); |
302 MCSMessage message(BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0)); | 307 MCSMessage message( |
| 308 BuildDataMessage("from", "category", "X", 1, "", 0, 1, 0, "", 0)); |
303 mcs_client()->SendMessage(message); | 309 mcs_client()->SendMessage(message); |
304 | 310 |
305 // Message sent callback should be invoked, but no message should actually | 311 // Message sent callback should be invoked, but no message should actually |
306 // be sent. | 312 // be sent. |
307 EXPECT_EQ("X", sent_message_id()); | 313 EXPECT_EQ("X", sent_message_id()); |
308 EXPECT_EQ(MCSClient::NO_CONNECTION_ON_ZERO_TTL, message_send_status()); | 314 EXPECT_EQ(MCSClient::NO_CONNECTION_ON_ZERO_TTL, message_send_status()); |
309 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 315 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
310 } | 316 } |
311 | 317 |
312 // Send a message with RMQ support. | 318 // Send a message with RMQ support. |
313 TEST_F(MCSClientTest, SendMessageRMQ) { | 319 TEST_F(MCSClientTest, SendMessageRMQ) { |
314 BuildMCSClient(); | 320 BuildMCSClient(); |
315 InitializeClient(); | 321 InitializeClient(); |
316 LoginClient(std::vector<std::string>()); | 322 LoginClient(std::vector<std::string>()); |
317 MCSMessage message( | 323 MCSMessage message(BuildDataMessage( |
318 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 324 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
319 GetFakeHandler()->ExpectOutgoingMessage(message); | 325 GetFakeHandler()->ExpectOutgoingMessage(message); |
320 mcs_client()->SendMessage(message); | 326 mcs_client()->SendMessage(message); |
321 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 327 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
322 } | 328 } |
323 | 329 |
324 // Send a message with RMQ support while disconnected. On reconnect, the message | 330 // Send a message with RMQ support while disconnected. On reconnect, the message |
325 // should be resent. | 331 // should be resent. |
326 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { | 332 TEST_F(MCSClientTest, SendMessageRMQWhileDisconnected) { |
327 BuildMCSClient(); | 333 BuildMCSClient(); |
328 InitializeClient(); | 334 InitializeClient(); |
329 LoginClient(std::vector<std::string>()); | 335 LoginClient(std::vector<std::string>()); |
330 GetFakeHandler()->set_fail_send(true); | 336 GetFakeHandler()->set_fail_send(true); |
331 MCSMessage message( | 337 MCSMessage message(BuildDataMessage( |
332 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 338 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
333 | 339 |
334 // The initial (failed) send. | 340 // The initial (failed) send. |
335 GetFakeHandler()->ExpectOutgoingMessage(message); | 341 GetFakeHandler()->ExpectOutgoingMessage(message); |
336 // The login request. | 342 // The login request. |
337 GetFakeHandler()->ExpectOutgoingMessage( | 343 GetFakeHandler()->ExpectOutgoingMessage( |
338 MCSMessage(kLoginRequestTag, | 344 MCSMessage(kLoginRequestTag, |
339 BuildLoginRequest(kAndroidId, kSecurityToken). | 345 BuildLoginRequest(kAndroidId, kSecurityToken). |
340 PassAs<const google::protobuf::MessageLite>())); | 346 PassAs<const google::protobuf::MessageLite>())); |
341 // The second (re)send. | 347 // The second (re)send. |
342 MCSMessage message2(BuildDataMessage("from", | 348 MCSMessage message2(BuildDataMessage( |
343 "category", | 349 "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); |
344 "X", | |
345 1, | |
346 "1", | |
347 kTTLValue, | |
348 1, | |
349 kTTLValue - 1)); | |
350 GetFakeHandler()->ExpectOutgoingMessage(message2); | 350 GetFakeHandler()->ExpectOutgoingMessage(message2); |
351 mcs_client()->SendMessage(message); | 351 mcs_client()->SendMessage(message); |
352 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 352 EXPECT_FALSE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
353 GetFakeHandler()->set_fail_send(false); | 353 GetFakeHandler()->set_fail_send(false); |
354 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); | 354 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); |
355 connection_factory()->Connect(); | 355 connection_factory()->Connect(); |
356 WaitForMCSEvent(); // Wait for the login to finish. | 356 WaitForMCSEvent(); // Wait for the login to finish. |
357 PumpLoop(); // Wait for the send to happen. | 357 PumpLoop(); // Wait for the send to happen. |
358 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 358 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
359 } | 359 } |
360 | 360 |
361 // Send a message with RMQ support without receiving an acknowledgement. On | 361 // Send a message with RMQ support without receiving an acknowledgement. On |
362 // restart the message should be resent. | 362 // restart the message should be resent. |
363 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { | 363 TEST_F(MCSClientTest, SendMessageRMQOnRestart) { |
364 BuildMCSClient(); | 364 BuildMCSClient(); |
365 InitializeClient(); | 365 InitializeClient(); |
366 LoginClient(std::vector<std::string>()); | 366 LoginClient(std::vector<std::string>()); |
367 GetFakeHandler()->set_fail_send(true); | 367 GetFakeHandler()->set_fail_send(true); |
368 MCSMessage message( | 368 MCSMessage message(BuildDataMessage( |
369 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 369 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
370 | 370 |
371 // The initial (failed) send. | 371 // The initial (failed) send. |
372 GetFakeHandler()->ExpectOutgoingMessage(message); | 372 GetFakeHandler()->ExpectOutgoingMessage(message); |
373 GetFakeHandler()->set_fail_send(false); | 373 GetFakeHandler()->set_fail_send(false); |
374 mcs_client()->SendMessage(message); | 374 mcs_client()->SendMessage(message); |
375 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 375 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
376 | 376 |
377 // Rebuild the client, which should resend the old message. | 377 // Rebuild the client, which should resend the old message. |
378 StoreCredentials(); | 378 StoreCredentials(); |
379 BuildMCSClient(); | 379 BuildMCSClient(); |
380 InitializeClient(); | 380 InitializeClient(); |
381 | 381 |
382 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); | 382 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue - 1)); |
383 MCSMessage message2(BuildDataMessage("from", | 383 MCSMessage message2(BuildDataMessage( |
384 "category", | 384 "from", "category", "X", 1, "1", kTTLValue, 1, kTTLValue - 1, "", 0)); |
385 "X", | |
386 1, | |
387 "1", | |
388 kTTLValue, | |
389 1, | |
390 kTTLValue - 1)); | |
391 LoginClient(std::vector<std::string>()); | 385 LoginClient(std::vector<std::string>()); |
392 GetFakeHandler()->ExpectOutgoingMessage(message2); | 386 GetFakeHandler()->ExpectOutgoingMessage(message2); |
393 PumpLoop(); | 387 PumpLoop(); |
394 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 388 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
395 } | 389 } |
396 | 390 |
397 // Send messages with RMQ support, followed by receiving a stream ack. On | 391 // Send messages with RMQ support, followed by receiving a stream ack. On |
398 // restart nothing should be recent. | 392 // restart nothing should be recent. |
399 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { | 393 TEST_F(MCSClientTest, SendMessageRMQWithStreamAck) { |
400 BuildMCSClient(); | 394 BuildMCSClient(); |
401 InitializeClient(); | 395 InitializeClient(); |
402 LoginClient(std::vector<std::string>()); | 396 LoginClient(std::vector<std::string>()); |
403 | 397 |
404 // Send some messages. | 398 // Send some messages. |
405 for (int i = 1; i <= kMessageBatchSize; ++i) { | 399 for (int i = 1; i <= kMessageBatchSize; ++i) { |
406 MCSMessage message( | 400 MCSMessage message(BuildDataMessage("from", |
407 BuildDataMessage("from", | 401 "category", |
408 "category", | 402 "X", |
409 "X", | 403 1, |
410 1, | 404 base::IntToString(i), |
411 base::IntToString(i), | 405 kTTLValue, |
412 kTTLValue, | 406 1, |
413 1, | 407 0, |
414 0)); | 408 "", |
| 409 0)); |
415 GetFakeHandler()->ExpectOutgoingMessage(message); | 410 GetFakeHandler()->ExpectOutgoingMessage(message); |
416 mcs_client()->SendMessage(message); | 411 mcs_client()->SendMessage(message); |
417 } | 412 } |
418 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 413 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
419 | 414 |
420 // Receive the ack. | 415 // Receive the ack. |
421 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 416 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
422 ack->set_last_stream_id_received(kMessageBatchSize + 1); | 417 ack->set_last_stream_id_received(kMessageBatchSize + 1); |
423 GetFakeHandler()->ReceiveMessage( | 418 GetFakeHandler()->ReceiveMessage( |
424 MCSMessage(kIqStanzaTag, | 419 MCSMessage(kIqStanzaTag, |
(...skipping 12 matching lines...) Expand all Loading... |
437 // the login response. No messages should be resent. | 432 // the login response. No messages should be resent. |
438 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { | 433 TEST_F(MCSClientTest, SendMessageRMQAckOnReconnect) { |
439 BuildMCSClient(); | 434 BuildMCSClient(); |
440 InitializeClient(); | 435 InitializeClient(); |
441 LoginClient(std::vector<std::string>()); | 436 LoginClient(std::vector<std::string>()); |
442 | 437 |
443 // Send some messages. | 438 // Send some messages. |
444 std::vector<std::string> id_list; | 439 std::vector<std::string> id_list; |
445 for (int i = 1; i <= kMessageBatchSize; ++i) { | 440 for (int i = 1; i <= kMessageBatchSize; ++i) { |
446 id_list.push_back(base::IntToString(i)); | 441 id_list.push_back(base::IntToString(i)); |
447 MCSMessage message( | 442 MCSMessage message(BuildDataMessage("from", |
448 BuildDataMessage("from", | 443 "category", |
449 "category", | 444 id_list.back(), |
450 id_list.back(), | 445 1, |
451 1, | 446 id_list.back(), |
452 id_list.back(), | 447 kTTLValue, |
453 kTTLValue, | 448 1, |
454 1, | 449 0, |
455 0)); | 450 "", |
| 451 0)); |
456 GetFakeHandler()->ExpectOutgoingMessage(message); | 452 GetFakeHandler()->ExpectOutgoingMessage(message); |
457 mcs_client()->SendMessage(message); | 453 mcs_client()->SendMessage(message); |
458 } | 454 } |
459 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 455 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
460 | 456 |
461 // Rebuild the client, and receive an acknowledgment for the messages as | 457 // Rebuild the client, and receive an acknowledgment for the messages as |
462 // part of the login response. | 458 // part of the login response. |
463 StoreCredentials(); | 459 StoreCredentials(); |
464 BuildMCSClient(); | 460 BuildMCSClient(); |
465 InitializeClient(); | 461 InitializeClient(); |
(...skipping 10 matching lines...) Expand all Loading... |
476 // be resent. | 472 // be resent. |
477 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { | 473 TEST_F(MCSClientTest, SendMessageRMQPartialAckOnReconnect) { |
478 BuildMCSClient(); | 474 BuildMCSClient(); |
479 InitializeClient(); | 475 InitializeClient(); |
480 LoginClient(std::vector<std::string>()); | 476 LoginClient(std::vector<std::string>()); |
481 | 477 |
482 // Send some messages. | 478 // Send some messages. |
483 std::vector<std::string> id_list; | 479 std::vector<std::string> id_list; |
484 for (int i = 1; i <= kMessageBatchSize; ++i) { | 480 for (int i = 1; i <= kMessageBatchSize; ++i) { |
485 id_list.push_back(base::IntToString(i)); | 481 id_list.push_back(base::IntToString(i)); |
486 MCSMessage message( | 482 MCSMessage message(BuildDataMessage("from", |
487 BuildDataMessage("from", | 483 "category", |
488 "category", | 484 id_list.back(), |
489 id_list.back(), | 485 1, |
490 1, | 486 id_list.back(), |
491 id_list.back(), | 487 kTTLValue, |
492 kTTLValue, | 488 1, |
493 1, | 489 0, |
494 0)); | 490 "", |
| 491 0)); |
495 GetFakeHandler()->ExpectOutgoingMessage(message); | 492 GetFakeHandler()->ExpectOutgoingMessage(message); |
496 mcs_client()->SendMessage(message); | 493 mcs_client()->SendMessage(message); |
497 } | 494 } |
498 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 495 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
499 | 496 |
500 // Rebuild the client, and receive an acknowledgment for the messages as | 497 // Rebuild the client, and receive an acknowledgment for the messages as |
501 // part of the login response. | 498 // part of the login response. |
502 StoreCredentials(); | 499 StoreCredentials(); |
503 BuildMCSClient(); | 500 BuildMCSClient(); |
504 InitializeClient(); | 501 InitializeClient(); |
505 LoginClient(std::vector<std::string>()); | 502 LoginClient(std::vector<std::string>()); |
506 | 503 |
507 std::vector<std::string> acked_ids, remaining_ids; | 504 std::vector<std::string> acked_ids, remaining_ids; |
508 acked_ids.insert(acked_ids.end(), | 505 acked_ids.insert(acked_ids.end(), |
509 id_list.begin(), | 506 id_list.begin(), |
510 id_list.begin() + kMessageBatchSize / 2); | 507 id_list.begin() + kMessageBatchSize / 2); |
511 remaining_ids.insert(remaining_ids.end(), | 508 remaining_ids.insert(remaining_ids.end(), |
512 id_list.begin() + kMessageBatchSize / 2, | 509 id_list.begin() + kMessageBatchSize / 2, |
513 id_list.end()); | 510 id_list.end()); |
514 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { | 511 for (int i = 1; i <= kMessageBatchSize / 2; ++i) { |
515 MCSMessage message( | 512 MCSMessage message(BuildDataMessage("from", |
516 BuildDataMessage("from", | 513 "category", |
517 "category", | 514 remaining_ids[i - 1], |
518 remaining_ids[i - 1], | 515 2, |
519 2, | 516 remaining_ids[i - 1], |
520 remaining_ids[i - 1], | 517 kTTLValue, |
521 kTTLValue, | 518 1, |
522 1, 0)); | 519 0, |
| 520 "", |
| 521 0)); |
523 GetFakeHandler()->ExpectOutgoingMessage(message); | 522 GetFakeHandler()->ExpectOutgoingMessage(message); |
524 } | 523 } |
525 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); | 524 scoped_ptr<mcs_proto::IqStanza> ack(BuildSelectiveAck(acked_ids)); |
526 GetFakeHandler()->ReceiveMessage( | 525 GetFakeHandler()->ReceiveMessage( |
527 MCSMessage(kIqStanzaTag, | 526 MCSMessage(kIqStanzaTag, |
528 ack.PassAs<const google::protobuf::MessageLite>())); | 527 ack.PassAs<const google::protobuf::MessageLite>())); |
529 WaitForMCSEvent(); | 528 WaitForMCSEvent(); |
530 PumpLoop(); | 529 PumpLoop(); |
531 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 530 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
532 } | 531 } |
533 | 532 |
534 // Receive some messages. On restart, the login request should contain the | 533 // Receive some messages. On restart, the login request should contain the |
535 // appropriate acknowledged ids. | 534 // appropriate acknowledged ids. |
536 TEST_F(MCSClientTest, AckOnLogin) { | 535 TEST_F(MCSClientTest, AckOnLogin) { |
537 BuildMCSClient(); | 536 BuildMCSClient(); |
538 InitializeClient(); | 537 InitializeClient(); |
539 LoginClient(std::vector<std::string>()); | 538 LoginClient(std::vector<std::string>()); |
540 | 539 |
541 // Receive some messages. | 540 // Receive some messages. |
542 std::vector<std::string> id_list; | 541 std::vector<std::string> id_list; |
543 for (int i = 1; i <= kMessageBatchSize; ++i) { | 542 for (int i = 1; i <= kMessageBatchSize; ++i) { |
544 id_list.push_back(base::IntToString(i)); | 543 id_list.push_back(base::IntToString(i)); |
545 MCSMessage message( | 544 MCSMessage message(BuildDataMessage( |
546 BuildDataMessage("from", | 545 "from", "category", "X", 1, id_list.back(), kTTLValue, 1, 0, "", 0)); |
547 "category", | |
548 "X", | |
549 1, | |
550 id_list.back(), | |
551 kTTLValue, | |
552 1, | |
553 0)); | |
554 GetFakeHandler()->ReceiveMessage(message); | 546 GetFakeHandler()->ReceiveMessage(message); |
555 WaitForMCSEvent(); | 547 WaitForMCSEvent(); |
556 PumpLoop(); | 548 PumpLoop(); |
557 } | 549 } |
558 | 550 |
559 // Restart the client. | 551 // Restart the client. |
560 StoreCredentials(); | 552 StoreCredentials(); |
561 BuildMCSClient(); | 553 BuildMCSClient(); |
562 InitializeClient(); | 554 InitializeClient(); |
563 LoginClient(id_list); | 555 LoginClient(id_list); |
564 } | 556 } |
565 | 557 |
566 // Receive some messages. On the next send, the outgoing message should contain | 558 // Receive some messages. On the next send, the outgoing message should contain |
567 // the appropriate last stream id received field to ack the received messages. | 559 // the appropriate last stream id received field to ack the received messages. |
568 TEST_F(MCSClientTest, AckOnSend) { | 560 TEST_F(MCSClientTest, AckOnSend) { |
569 BuildMCSClient(); | 561 BuildMCSClient(); |
570 InitializeClient(); | 562 InitializeClient(); |
571 LoginClient(std::vector<std::string>()); | 563 LoginClient(std::vector<std::string>()); |
572 | 564 |
573 // Receive some messages. | 565 // Receive some messages. |
574 std::vector<std::string> id_list; | 566 std::vector<std::string> id_list; |
575 for (int i = 1; i <= kMessageBatchSize; ++i) { | 567 for (int i = 1; i <= kMessageBatchSize; ++i) { |
576 id_list.push_back(base::IntToString(i)); | 568 id_list.push_back(base::IntToString(i)); |
577 MCSMessage message( | 569 MCSMessage message(BuildDataMessage("from", |
578 BuildDataMessage("from", | 570 "category", |
579 "category", | 571 id_list.back(), |
580 id_list.back(), | 572 1, |
581 1, | 573 id_list.back(), |
582 id_list.back(), | 574 kTTLValue, |
583 kTTLValue, | 575 1, |
584 1, | 576 0, |
585 0)); | 577 "", |
| 578 0)); |
586 GetFakeHandler()->ReceiveMessage(message); | 579 GetFakeHandler()->ReceiveMessage(message); |
587 PumpLoop(); | 580 PumpLoop(); |
588 } | 581 } |
589 | 582 |
590 // Trigger a message send, which should acknowledge via stream ack. | 583 // Trigger a message send, which should acknowledge via stream ack. |
591 MCSMessage message( | 584 MCSMessage message(BuildDataMessage("from", |
592 BuildDataMessage("from", | 585 "category", |
593 "category", | 586 "X", |
594 "X", | 587 kMessageBatchSize + 1, |
595 kMessageBatchSize + 1, | 588 "1", |
596 "1", | 589 kTTLValue, |
597 kTTLValue, | 590 1, |
598 1, 0)); | 591 0, |
| 592 "", |
| 593 0)); |
599 GetFakeHandler()->ExpectOutgoingMessage(message); | 594 GetFakeHandler()->ExpectOutgoingMessage(message); |
600 mcs_client()->SendMessage(message); | 595 mcs_client()->SendMessage(message); |
601 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 596 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
602 } | 597 } |
603 | 598 |
604 // Receive the ack limit in messages, which should trigger an automatic | 599 // Receive the ack limit in messages, which should trigger an automatic |
605 // stream ack. Receive a heartbeat to confirm the ack. | 600 // stream ack. Receive a heartbeat to confirm the ack. |
606 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { | 601 TEST_F(MCSClientTest, AckWhenLimitReachedWithHeartbeat) { |
607 BuildMCSClient(); | 602 BuildMCSClient(); |
608 InitializeClient(); | 603 InitializeClient(); |
609 LoginClient(std::vector<std::string>()); | 604 LoginClient(std::vector<std::string>()); |
610 | 605 |
611 // The stream ack. | 606 // The stream ack. |
612 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); | 607 scoped_ptr<mcs_proto::IqStanza> ack = BuildStreamAck(); |
613 ack->set_last_stream_id_received(kAckLimitSize + 1); | 608 ack->set_last_stream_id_received(kAckLimitSize + 1); |
614 GetFakeHandler()->ExpectOutgoingMessage( | 609 GetFakeHandler()->ExpectOutgoingMessage( |
615 MCSMessage(kIqStanzaTag, | 610 MCSMessage(kIqStanzaTag, |
616 ack.PassAs<const google::protobuf::MessageLite>())); | 611 ack.PassAs<const google::protobuf::MessageLite>())); |
617 | 612 |
618 // Receive some messages. | 613 // Receive some messages. |
619 std::vector<std::string> id_list; | 614 std::vector<std::string> id_list; |
620 for (int i = 1; i <= kAckLimitSize; ++i) { | 615 for (int i = 1; i <= kAckLimitSize; ++i) { |
621 id_list.push_back(base::IntToString(i)); | 616 id_list.push_back(base::IntToString(i)); |
622 MCSMessage message( | 617 MCSMessage message(BuildDataMessage("from", |
623 BuildDataMessage("from", | 618 "category", |
624 "category", | 619 id_list.back(), |
625 id_list.back(), | 620 1, |
626 1, | 621 id_list.back(), |
627 id_list.back(), | 622 kTTLValue, |
628 kTTLValue, | 623 1, |
629 1, | 624 0, |
630 0)); | 625 "", |
| 626 0)); |
631 GetFakeHandler()->ReceiveMessage(message); | 627 GetFakeHandler()->ReceiveMessage(message); |
632 WaitForMCSEvent(); | 628 WaitForMCSEvent(); |
633 PumpLoop(); | 629 PumpLoop(); |
634 } | 630 } |
635 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 631 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
636 | 632 |
637 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). | 633 // Receive a heartbeat confirming the ack (and receive the heartbeat ack). |
638 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( | 634 scoped_ptr<mcs_proto::HeartbeatPing> heartbeat( |
639 new mcs_proto::HeartbeatPing()); | 635 new mcs_proto::HeartbeatPing()); |
640 heartbeat->set_last_stream_id_received(2); | 636 heartbeat->set_last_stream_id_received(2); |
(...skipping 18 matching lines...) Expand all Loading... |
659 LoginClient(std::vector<std::string>()); | 655 LoginClient(std::vector<std::string>()); |
660 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 656 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
661 } | 657 } |
662 | 658 |
663 // If a message's TTL has expired by the time it reaches the front of the send | 659 // If a message's TTL has expired by the time it reaches the front of the send |
664 // queue, it should be dropped. | 660 // queue, it should be dropped. |
665 TEST_F(MCSClientTest, ExpiredTTLOnSend) { | 661 TEST_F(MCSClientTest, ExpiredTTLOnSend) { |
666 BuildMCSClient(); | 662 BuildMCSClient(); |
667 InitializeClient(); | 663 InitializeClient(); |
668 LoginClient(std::vector<std::string>()); | 664 LoginClient(std::vector<std::string>()); |
669 MCSMessage message( | 665 MCSMessage message(BuildDataMessage( |
670 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 666 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
671 | 667 |
672 // Advance time to after the TTL. | 668 // Advance time to after the TTL. |
673 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); | 669 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); |
674 EXPECT_TRUE(sent_message_id().empty()); | 670 EXPECT_TRUE(sent_message_id().empty()); |
675 mcs_client()->SendMessage(message); | 671 mcs_client()->SendMessage(message); |
676 | 672 |
677 // No messages should be sent, but the callback should still be invoked. | 673 // No messages should be sent, but the callback should still be invoked. |
678 EXPECT_EQ("X", sent_message_id()); | 674 EXPECT_EQ("X", sent_message_id()); |
679 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); | 675 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); |
680 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 676 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
681 } | 677 } |
682 | 678 |
683 TEST_F(MCSClientTest, ExpiredTTLOnRestart) { | 679 TEST_F(MCSClientTest, ExpiredTTLOnRestart) { |
684 BuildMCSClient(); | 680 BuildMCSClient(); |
685 InitializeClient(); | 681 InitializeClient(); |
686 LoginClient(std::vector<std::string>()); | 682 LoginClient(std::vector<std::string>()); |
687 GetFakeHandler()->set_fail_send(true); | 683 GetFakeHandler()->set_fail_send(true); |
688 MCSMessage message( | 684 MCSMessage message(BuildDataMessage( |
689 BuildDataMessage("from", "category", "X", 1, "1", kTTLValue, 1, 0)); | 685 "from", "category", "X", 1, "1", kTTLValue, 1, 0, "", 0)); |
690 | 686 |
691 // The initial (failed) send. | 687 // The initial (failed) send. |
692 GetFakeHandler()->ExpectOutgoingMessage(message); | 688 GetFakeHandler()->ExpectOutgoingMessage(message); |
693 GetFakeHandler()->set_fail_send(false); | 689 GetFakeHandler()->set_fail_send(false); |
694 mcs_client()->SendMessage(message); | 690 mcs_client()->SendMessage(message); |
695 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 691 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
696 | 692 |
697 // Move the clock forward and rebuild the client, which should fail the | 693 // Move the clock forward and rebuild the client, which should fail the |
698 // message send on restart. | 694 // message send on restart. |
699 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); | 695 clock()->Advance(base::TimeDelta::FromSeconds(kTTLValue + 2)); |
700 StoreCredentials(); | 696 StoreCredentials(); |
701 BuildMCSClient(); | 697 BuildMCSClient(); |
702 InitializeClient(); | 698 InitializeClient(); |
703 LoginClient(std::vector<std::string>()); | 699 LoginClient(std::vector<std::string>()); |
704 PumpLoop(); | 700 PumpLoop(); |
705 EXPECT_EQ("X", sent_message_id()); | 701 EXPECT_EQ("X", sent_message_id()); |
706 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); | 702 EXPECT_EQ(MCSClient::TTL_EXCEEDED, message_send_status()); |
707 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); | 703 EXPECT_TRUE(GetFakeHandler()->AllOutgoingMessagesReceived()); |
708 } | 704 } |
709 | 705 |
| 706 // Sending two messages with the same collapse key and same app id while |
| 707 // disconnected should only send the latter of the two on reconnection. |
| 708 TEST_F(MCSClientTest, CollapseKeysSameApp) { |
| 709 BuildMCSClient(); |
| 710 InitializeClient(); |
| 711 MCSMessage message(BuildDataMessage( |
| 712 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 713 mcs_client()->SendMessage(message); |
| 714 |
| 715 MCSMessage message2(BuildDataMessage( |
| 716 "from", "app", "message id 2", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 717 mcs_client()->SendMessage(message2); |
| 718 |
| 719 LoginClient(std::vector<std::string>()); |
| 720 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 721 PumpLoop(); |
| 722 } |
| 723 |
| 724 // Sending two messages with the same collapse key and different app id while |
| 725 // disconnected should not perform any collapsing. |
| 726 TEST_F(MCSClientTest, CollapseKeysDifferentApp) { |
| 727 BuildMCSClient(); |
| 728 InitializeClient(); |
| 729 MCSMessage message(BuildDataMessage( |
| 730 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 731 mcs_client()->SendMessage(message); |
| 732 |
| 733 MCSMessage message2(BuildDataMessage("from", |
| 734 "app 2", |
| 735 "message id 2", |
| 736 1, |
| 737 "2", |
| 738 kTTLValue, |
| 739 1, |
| 740 0, |
| 741 "token", |
| 742 0)); |
| 743 mcs_client()->SendMessage(message2); |
| 744 |
| 745 LoginClient(std::vector<std::string>()); |
| 746 GetFakeHandler()->ExpectOutgoingMessage(message); |
| 747 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 748 PumpLoop(); |
| 749 } |
| 750 |
| 751 // Sending two messages with the same collapse key and app id, but different |
| 752 // user, while disconnected, should not perform any collapsing. |
| 753 TEST_F(MCSClientTest, CollapseKeysDifferentUser) { |
| 754 BuildMCSClient(); |
| 755 InitializeClient(); |
| 756 MCSMessage message(BuildDataMessage( |
| 757 "from", "app", "message id 1", 1, "1", kTTLValue, 1, 0, "token", 0)); |
| 758 mcs_client()->SendMessage(message); |
| 759 |
| 760 MCSMessage message2(BuildDataMessage("from", |
| 761 "app", |
| 762 "message id 2", |
| 763 1, |
| 764 "2", |
| 765 kTTLValue, |
| 766 1, |
| 767 0, |
| 768 "token", |
| 769 1)); |
| 770 mcs_client()->SendMessage(message2); |
| 771 |
| 772 LoginClient(std::vector<std::string>()); |
| 773 GetFakeHandler()->ExpectOutgoingMessage(message); |
| 774 GetFakeHandler()->ExpectOutgoingMessage(message2); |
| 775 PumpLoop(); |
| 776 } |
| 777 |
710 } // namespace | 778 } // namespace |
711 | 779 |
712 } // namespace gcm | 780 } // namespace gcm |
OLD | NEW |