Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / google_apis / gcm / engine / heartbeat_manager_unittest.cc
1 // Copyright 2014 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/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/time/time.h"
11 #include "base/timer/timer.h"
12 #include "google_apis/gcm/protocol/mcs.pb.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace gcm {
16
17 namespace {
18
19 mcs_proto::HeartbeatConfig BuildHeartbeatConfig(int interval_ms) {
20   mcs_proto::HeartbeatConfig config;
21   config.set_interval_ms(interval_ms);
22   return config;
23 }
24
25 class TestHeartbeatManager : public HeartbeatManager {
26  public:
27   TestHeartbeatManager()
28       : HeartbeatManager(make_scoped_ptr(
29             new base::Timer(true, /* retain user task */
30                             false /* non repeating */))) {}
31   virtual ~TestHeartbeatManager() {}
32
33   // Bypass the heartbeat timer, and send the heartbeat now.
34   void TriggerHearbeat();
35
36   // Check for a missed heartbeat now.
37   void TriggerMissedHeartbeatCheck();
38 };
39
40 void TestHeartbeatManager::TriggerHearbeat() {
41   OnHeartbeatTriggered();
42 }
43
44 void TestHeartbeatManager::TriggerMissedHeartbeatCheck() {
45   CheckForMissedHeartbeat();
46 }
47
48 class HeartbeatManagerTest : public testing::Test {
49  public:
50   HeartbeatManagerTest();
51   virtual ~HeartbeatManagerTest() {}
52
53   TestHeartbeatManager* manager() const { return manager_.get(); }
54   int heartbeats_sent() const { return heartbeats_sent_; }
55   int reconnects_triggered() const { return reconnects_triggered_; }
56
57   // Starts the heartbeat manager.
58   void StartManager();
59
60  private:
61   // Helper functions for verifying heartbeat manager effects.
62   void SendHeartbeatClosure();
63   void TriggerReconnectClosure();
64
65   scoped_ptr<TestHeartbeatManager> manager_;
66
67   int heartbeats_sent_;
68   int reconnects_triggered_;
69
70   base::MessageLoop message_loop_;
71 };
72
73 HeartbeatManagerTest::HeartbeatManagerTest()
74     : manager_(new TestHeartbeatManager()),
75       heartbeats_sent_(0),
76       reconnects_triggered_(0) {
77 }
78
79 void HeartbeatManagerTest::StartManager() {
80   manager_->Start(base::Bind(&HeartbeatManagerTest::SendHeartbeatClosure,
81                              base::Unretained(this)),
82                   base::Bind(&HeartbeatManagerTest::TriggerReconnectClosure,
83                              base::Unretained(this)));
84 }
85
86 void HeartbeatManagerTest::SendHeartbeatClosure() {
87   heartbeats_sent_++;
88 }
89
90 void HeartbeatManagerTest::TriggerReconnectClosure() {
91   reconnects_triggered_++;
92 }
93
94 // Basic initialization. No heartbeat should be pending.
95 TEST_F(HeartbeatManagerTest, Init) {
96   EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
97 }
98
99 // Acknowledging a heartbeat before starting the manager should have no effect.
100 TEST_F(HeartbeatManagerTest, AckBeforeStart) {
101   manager()->OnHeartbeatAcked();
102   EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
103 }
104
105 // Starting the manager should start the heartbeat timer.
106 TEST_F(HeartbeatManagerTest, Start) {
107   StartManager();
108   EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now());
109   EXPECT_EQ(0, heartbeats_sent());
110   EXPECT_EQ(0, reconnects_triggered());
111 }
112
113 // Acking the heartbeat should trigger a new heartbeat timer.
114 TEST_F(HeartbeatManagerTest, AckedHeartbeat) {
115   StartManager();
116   manager()->TriggerHearbeat();
117   base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime();
118   EXPECT_GT(heartbeat, base::TimeTicks::Now());
119   EXPECT_EQ(1, heartbeats_sent());
120   EXPECT_EQ(0, reconnects_triggered());
121
122   manager()->OnHeartbeatAcked();
123   EXPECT_LT(heartbeat, manager()->GetNextHeartbeatTime());
124   EXPECT_EQ(1, heartbeats_sent());
125   EXPECT_EQ(0, reconnects_triggered());
126
127   manager()->TriggerHearbeat();
128   EXPECT_EQ(2, heartbeats_sent());
129   EXPECT_EQ(0, reconnects_triggered());
130 }
131
132 // Trigger a heartbeat when one was outstanding should reset the connection.
133 TEST_F(HeartbeatManagerTest, UnackedHeartbeat) {
134   StartManager();
135   manager()->TriggerHearbeat();
136   EXPECT_EQ(1, heartbeats_sent());
137   EXPECT_EQ(0, reconnects_triggered());
138
139   manager()->TriggerHearbeat();
140   EXPECT_EQ(1, heartbeats_sent());
141   EXPECT_EQ(1, reconnects_triggered());
142 }
143
144 // Updating the heartbeat interval before starting should result in the new
145 // interval being used at Start time.
146 TEST_F(HeartbeatManagerTest, UpdateIntervalThenStart) {
147   const int kIntervalMs = 60 * 1000;  // 60 seconds.
148   manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs));
149   EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
150   StartManager();
151   EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(),
152             base::TimeDelta::FromMilliseconds(kIntervalMs));
153 }
154
155 // Updating the heartbeat interval after starting should only use the new
156 // interval on the next heartbeat.
157 TEST_F(HeartbeatManagerTest, StartThenUpdateInterval) {
158   const int kIntervalMs = 60 * 1000;  // 60 seconds.
159   StartManager();
160   base::TimeTicks heartbeat = manager()->GetNextHeartbeatTime();
161   EXPECT_GT(heartbeat - base::TimeTicks::Now(),
162             base::TimeDelta::FromMilliseconds(kIntervalMs));
163
164   // Updating the interval should not affect an outstanding heartbeat.
165   manager()->UpdateHeartbeatConfig(BuildHeartbeatConfig(kIntervalMs));
166   EXPECT_EQ(heartbeat, manager()->GetNextHeartbeatTime());
167
168   // Triggering and acking the heartbeat should result in a heartbeat being
169   // posted with the new interval.
170   manager()->TriggerHearbeat();
171   manager()->OnHeartbeatAcked();
172
173   EXPECT_LE(manager()->GetNextHeartbeatTime() - base::TimeTicks::Now(),
174             base::TimeDelta::FromMilliseconds(kIntervalMs));
175   EXPECT_NE(heartbeat, manager()->GetNextHeartbeatTime());
176 }
177
178 // Stopping the manager should reset the heartbeat timer.
179 TEST_F(HeartbeatManagerTest, Stop) {
180   StartManager();
181   EXPECT_GT(manager()->GetNextHeartbeatTime(), base::TimeTicks::Now());
182
183   manager()->Stop();
184   EXPECT_TRUE(manager()->GetNextHeartbeatTime().is_null());
185 }
186
187 // Simulate missing a heartbeat by manually invoking the check method. The
188 // heartbeat should only be triggered once, and only if the heartbeat timer
189 // is running. Because the period is several minutes, none should fire.
190 TEST_F(HeartbeatManagerTest, MissedHeartbeat) {
191   // Do nothing while stopped.
192   manager()->TriggerMissedHeartbeatCheck();
193   StartManager();
194   EXPECT_EQ(0, heartbeats_sent());
195
196   // Do nothing before the period is reached.
197   manager()->TriggerMissedHeartbeatCheck();
198   EXPECT_EQ(0, heartbeats_sent());
199 }
200
201 }  // namespace
202
203 }  // namespace gcm