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