Chromium Code Reviews| OLD | NEW |
|---|---|
| (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/heartbeat_manager.h" | |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "base/time/time.h" | |
| 9 #include "google_apis/gcm/protocol/mcs.pb.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace gcm { | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 mcs_proto::HeartbeatConfig BuildHeartbeatConfig(int interval_ms) { | |
| 17 mcs_proto::HeartbeatConfig config; | |
| 18 config.set_interval_ms(interval_ms); | |
| 19 return config; | |
| 20 } | |
| 21 | |
| 22 class TestHeartbeatManager : public HeartbeatManager { | |
| 23 public: | |
| 24 TestHeartbeatManager() {} | |
| 25 virtual ~TestHeartbeatManager() {} | |
| 26 | |
| 27 // Bypass the heartbeat timer, and send the heartbeat now. | |
| 28 void TriggerHearbeat(); | |
| 29 }; | |
| 30 | |
| 31 void TestHeartbeatManager::TriggerHearbeat() { | |
| 32 OnHeartbeatTriggered(); | |
| 33 } | |
| 34 | |
| 35 class HeartbeatManagerTest : public testing::Test { | |
| 36 public: | |
| 37 HeartbeatManagerTest(); | |
| 38 virtual ~HeartbeatManagerTest() {} | |
| 39 | |
| 40 TestHeartbeatManager* manager() { return manager_.get(); } | |
|
jianli
2013/12/20 23:10:03
nit: const modifier
Nicolas Zea
2013/12/26 22:55:02
Done.
| |
| 41 int heartbeats_sent() { return heartbeats_sent_; } | |
| 42 int reconnects_triggered() { return reconnects_triggered_; } | |
| 43 | |
| 44 // Starts the heartbeat manager. | |
| 45 void StartManager(); | |
| 46 | |
| 47 private: | |
| 48 // Helper functions for verifying heartbeat manager effects. | |
| 49 void SendHeartbeatClosure(); | |
| 50 void TriggerReconnectClosure(); | |
| 51 | |
| 52 scoped_ptr<TestHeartbeatManager> manager_; | |
| 53 | |
| 54 int heartbeats_sent_; | |
| 55 int reconnects_triggered_; | |
| 56 | |
| 57 base::MessageLoop message_loop_; | |
| 58 }; | |
| 59 | |
| 60 HeartbeatManagerTest::HeartbeatManagerTest() | |
| 61 : manager_(new TestHeartbeatManager()), | |
| 62 heartbeats_sent_(0), | |
| 63 reconnects_triggered_(0) { | |
| 64 } | |
| 65 | |
| 66 void HeartbeatManagerTest::StartManager() { | |
| 67 manager_->Start(base::Bind(&HeartbeatManagerTest::SendHeartbeatClosure, | |
| 68 base::Unretained(this)), | |
| 69 base::Bind(&HeartbeatManagerTest::TriggerReconnectClosure, | |
| 70 base::Unretained(this))); | |
| 71 } | |
| 72 | |
| 73 void HeartbeatManagerTest::SendHeartbeatClosure() { | |
| 74 heartbeats_sent_++; | |
| 75 } | |
| 76 | |
| 77 void HeartbeatManagerTest::TriggerReconnectClosure() { | |
| 78 reconnects_triggered_++; | |
| 79 } | |
| 80 | |
| 81 // Basic initialization. No heartbeat should be pending. | |
| 82 TEST_F(HeartbeatManagerTest, Init) { | |
| 83 EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null()); | |
| 84 } | |
| 85 | |
| 86 // Acknowledging a heartbeat before starting the manager should have no effect. | |
| 87 TEST_F(HeartbeatManagerTest, AckBeforeStart) { | |
| 88 manager()->OnHeartbeatAcked(); | |
| 89 EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null()); | |
| 90 } | |
| 91 | |
| 92 // Starting the manager should start the heartbeat timer. | |
| 93 TEST_F(HeartbeatManagerTest, Start) { | |
| 94 StartManager(); | |
| 95 EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now()); | |
| 96 EXPECT_EQ(0, heartbeats_sent()); | |
| 97 EXPECT_EQ(0, reconnects_triggered()); | |
| 98 } | |
| 99 | |
| 100 // Acking the heartbeat should trigger a new heartbeat timer. | |
| 101 TEST_F(HeartbeatManagerTest, AckedHeartbeat) { | |
| 102 StartManager(); | |
| 103 manager()->TriggerHearbeat(); | |
| 104 base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime(); | |
| 105 EXPECT_GT(heartbeat, base::TimeTicks::Now()); | |
| 106 EXPECT_EQ(1, heartbeats_sent()); | |
| 107 EXPECT_EQ(0, reconnects_triggered()); | |
| 108 | |
| 109 manager()->OnHeartbeatAcked(); | |
| 110 EXPECT_LT(heartbeat, manager()->GetNextHeartbeatTime()); | |
| 111 EXPECT_EQ(1, heartbeats_sent()); | |
| 112 EXPECT_EQ(0, reconnects_triggered()); | |
| 113 | |
| 114 manager()->TriggerHearbeat(); | |
| 115 EXPECT_EQ(2, heartbeats_sent()); | |
| 116 EXPECT_EQ(0, reconnects_triggered()); | |
| 117 } | |
| 118 | |
| 119 // Trigger a heartbeat when one was outstanding should reset the connection. | |
| 120 TEST_F(HeartbeatManagerTest, UnackedHeartbeat) { | |
| 121 StartManager(); | |
| 122 manager()->TriggerHearbeat(); | |
| 123 EXPECT_EQ(1, heartbeats_sent()); | |
| 124 EXPECT_EQ(0, reconnects_triggered()); | |
| 125 | |
| 126 manager()->TriggerHearbeat(); | |
| 127 EXPECT_EQ(1, heartbeats_sent()); | |
| 128 EXPECT_EQ(1, reconnects_triggered()); | |
| 129 } | |
| 130 | |
| 131 // Updating the heartbeat interval before starting should result in the new | |
| 132 // interval being used at Start time. | |
| 133 TEST_F(HeartbeatManagerTest, UpdateIntervalThenStart) { | |
| 134 const int kIntervalMs = 60 * 1000; // 60 seconds. | |
| 135 manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs)); | |
| 136 EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null()); | |
| 137 StartManager(); | |
| 138 EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(), | |
| 139 base::TimeDelta::FromMilliseconds(kIntervalMs)); | |
| 140 } | |
| 141 | |
| 142 // Updating the heartbeat interval after starting should only use the new | |
| 143 // interval on the next heartbeat. | |
| 144 TEST_F(HeartbeatManagerTest, StartThenUpdateInterval) { | |
| 145 const int kIntervalMs = 60 * 1000; // 60 seconds. | |
| 146 StartManager(); | |
| 147 base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime(); | |
| 148 EXPECT_GT(heartbeat - base::TimeTicks::Now(), | |
| 149 base::TimeDelta::FromMilliseconds(kIntervalMs)); | |
| 150 | |
| 151 // Updating the interval should not affect an outstanding heartbeat. | |
| 152 manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs)); | |
| 153 EXPECT_EQ(heartbeat, manager()->GetNextHeartbeatTime()); | |
| 154 | |
| 155 // Triggering and acking the heartbeat should result in a heartbeat being | |
| 156 // posted with the new interval. | |
| 157 manager()->TriggerHearbeat(); | |
| 158 manager()->OnHeartbeatAcked(); | |
| 159 | |
| 160 EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(), | |
| 161 base::TimeDelta::FromMilliseconds(kIntervalMs)); | |
| 162 EXPECT_NE(heartbeat, manager()->GetNextHeartbeatTime()); | |
| 163 } | |
| 164 | |
| 165 // Stopping the manager should reset the heartbeat timer. | |
| 166 TEST_F(HeartbeatManagerTest, Stop) { | |
| 167 StartManager(); | |
| 168 EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now()); | |
| 169 | |
| 170 manager()->Stop(); | |
| 171 EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null()); | |
| 172 } | |
| 173 | |
| 174 } // namespace | |
| 175 | |
| 176 } // namespace gcm | |
| OLD | NEW |