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

Unified Diff: google_apis/gcm/engine/heartbeat_manager_unittest.cc

Issue 118133003: [GCM] Add heartbeat manager and reconnection logic due to heartbeat failure (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments 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 side-by-side diff with in-line comments
Download patch
Index: google_apis/gcm/engine/heartbeat_manager_unittest.cc
diff --git a/google_apis/gcm/engine/heartbeat_manager_unittest.cc b/google_apis/gcm/engine/heartbeat_manager_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e17e1b7154f3d0fe1fc1791f4a23ac2712a0631f
--- /dev/null
+++ b/google_apis/gcm/engine/heartbeat_manager_unittest.cc
@@ -0,0 +1,176 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "google_apis/gcm/engine/heartbeat_manager.h"
+
+#include "base/message_loop/message_loop.h"
+#include "base/time/time.h"
+#include "google_apis/gcm/protocol/mcs.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gcm {
+
+namespace {
+
+mcs_proto::HeartbeatConfig BuildHeartbeatConfig(int interval_ms) {
+ mcs_proto::HeartbeatConfig config;
+ config.set_interval_ms(interval_ms);
+ return config;
+}
+
+class TestHeartbeatManager : public HeartbeatManager {
+ public:
+ TestHeartbeatManager() {}
+ virtual ~TestHeartbeatManager() {}
+
+ // Bypass the heartbeat timer, and send the heartbeat now.
+ void TriggerHearbeat();
+};
+
+void TestHeartbeatManager::TriggerHearbeat() {
+ OnHeartbeatTriggered();
+}
+
+class HeartbeatManagerTest : public testing::Test {
+ public:
+ HeartbeatManagerTest();
+ virtual ~HeartbeatManagerTest() {}
+
+ TestHeartbeatManager* manager() { return manager_.get(); }
jianli 2013/12/20 23:10:03 nit: const modifier
Nicolas Zea 2013/12/26 22:55:02 Done.
+ int heartbeats_sent() { return heartbeats_sent_; }
+ int reconnects_triggered() { return reconnects_triggered_; }
+
+ // Starts the heartbeat manager.
+ void StartManager();
+
+ private:
+ // Helper functions for verifying heartbeat manager effects.
+ void SendHeartbeatClosure();
+ void TriggerReconnectClosure();
+
+ scoped_ptr<TestHeartbeatManager> manager_;
+
+ int heartbeats_sent_;
+ int reconnects_triggered_;
+
+ base::MessageLoop message_loop_;
+};
+
+HeartbeatManagerTest::HeartbeatManagerTest()
+ : manager_(new TestHeartbeatManager()),
+ heartbeats_sent_(0),
+ reconnects_triggered_(0) {
+}
+
+void HeartbeatManagerTest::StartManager() {
+ manager_->Start(base::Bind(&HeartbeatManagerTest::SendHeartbeatClosure,
+ base::Unretained(this)),
+ base::Bind(&HeartbeatManagerTest::TriggerReconnectClosure,
+ base::Unretained(this)));
+}
+
+void HeartbeatManagerTest::SendHeartbeatClosure() {
+ heartbeats_sent_++;
+}
+
+void HeartbeatManagerTest::TriggerReconnectClosure() {
+ reconnects_triggered_++;
+}
+
+// Basic initialization. No heartbeat should be pending.
+TEST_F(HeartbeatManagerTest, Init) {
+ EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
+}
+
+// Acknowledging a heartbeat before starting the manager should have no effect.
+TEST_F(HeartbeatManagerTest, AckBeforeStart) {
+ manager()->OnHeartbeatAcked();
+ EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
+}
+
+// Starting the manager should start the heartbeat timer.
+TEST_F(HeartbeatManagerTest, Start) {
+ StartManager();
+ EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now());
+ EXPECT_EQ(0, heartbeats_sent());
+ EXPECT_EQ(0, reconnects_triggered());
+}
+
+// Acking the heartbeat should trigger a new heartbeat timer.
+TEST_F(HeartbeatManagerTest, AckedHeartbeat) {
+ StartManager();
+ manager()->TriggerHearbeat();
+ base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime();
+ EXPECT_GT(heartbeat, base::TimeTicks::Now());
+ EXPECT_EQ(1, heartbeats_sent());
+ EXPECT_EQ(0, reconnects_triggered());
+
+ manager()->OnHeartbeatAcked();
+ EXPECT_LT(heartbeat, manager()->GetNextHeartbeatTime());
+ EXPECT_EQ(1, heartbeats_sent());
+ EXPECT_EQ(0, reconnects_triggered());
+
+ manager()->TriggerHearbeat();
+ EXPECT_EQ(2, heartbeats_sent());
+ EXPECT_EQ(0, reconnects_triggered());
+}
+
+// Trigger a heartbeat when one was outstanding should reset the connection.
+TEST_F(HeartbeatManagerTest, UnackedHeartbeat) {
+ StartManager();
+ manager()->TriggerHearbeat();
+ EXPECT_EQ(1, heartbeats_sent());
+ EXPECT_EQ(0, reconnects_triggered());
+
+ manager()->TriggerHearbeat();
+ EXPECT_EQ(1, heartbeats_sent());
+ EXPECT_EQ(1, reconnects_triggered());
+}
+
+// Updating the heartbeat interval before starting should result in the new
+// interval being used at Start time.
+TEST_F(HeartbeatManagerTest, UpdateIntervalThenStart) {
+ const int kIntervalMs = 60 * 1000; // 60 seconds.
+ manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs));
+ EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
+ StartManager();
+ EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(),
+ base::TimeDelta::FromMilliseconds(kIntervalMs));
+}
+
+// Updating the heartbeat interval after starting should only use the new
+// interval on the next heartbeat.
+TEST_F(HeartbeatManagerTest, StartThenUpdateInterval) {
+ const int kIntervalMs = 60 * 1000; // 60 seconds.
+ StartManager();
+ base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime();
+ EXPECT_GT(heartbeat - base::TimeTicks::Now(),
+ base::TimeDelta::FromMilliseconds(kIntervalMs));
+
+ // Updating the interval should not affect an outstanding heartbeat.
+ manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs));
+ EXPECT_EQ(heartbeat, manager()->GetNextHeartbeatTime());
+
+ // Triggering and acking the heartbeat should result in a heartbeat being
+ // posted with the new interval.
+ manager()->TriggerHearbeat();
+ manager()->OnHeartbeatAcked();
+
+ EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(),
+ base::TimeDelta::FromMilliseconds(kIntervalMs));
+ EXPECT_NE(heartbeat, manager()->GetNextHeartbeatTime());
+}
+
+// Stopping the manager should reset the heartbeat timer.
+TEST_F(HeartbeatManagerTest, Stop) {
+ StartManager();
+ EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now());
+
+ manager()->Stop();
+ EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
+}
+
+} // namespace
+
+} // namespace gcm

Powered by Google App Engine
This is Rietveld 408576698