OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file tests the chrome.alarms extension API. | 5 // This file tests the chrome.alarms extension API. |
6 | 6 |
7 #include "base/values.h" | 7 #include "base/values.h" |
| 8 #include "base/test/mock_time_provider.h" |
8 #include "chrome/browser/browser_process_impl.h" | 9 #include "chrome/browser/browser_process_impl.h" |
9 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" | 10 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" |
10 #include "chrome/browser/extensions/api/alarms/alarms_api.h" | 11 #include "chrome/browser/extensions/api/alarms/alarms_api.h" |
11 #include "chrome/browser/extensions/extension_function_test_utils.h" | 12 #include "chrome/browser/extensions/extension_function_test_utils.h" |
12 #include "chrome/browser/extensions/test_extension_system.h" | 13 #include "chrome/browser/extensions/test_extension_system.h" |
13 #include "chrome/browser/profiles/profile_manager.h" | 14 #include "chrome/browser/profiles/profile_manager.h" |
14 #include "chrome/test/base/browser_with_test_window_test.h" | 15 #include "chrome/test/base/browser_with_test_window_test.h" |
15 #include "chrome/test/base/testing_browser_process.h" | 16 #include "chrome/test/base/testing_browser_process.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
| 20 typedef extensions::api::alarms::Alarm JsAlarm; |
| 21 |
18 namespace utils = extension_function_test_utils; | 22 namespace utils = extension_function_test_utils; |
19 | 23 |
20 namespace extensions { | 24 namespace extensions { |
21 | 25 |
22 namespace { | 26 namespace { |
23 | 27 |
24 // Test delegate which quits the message loop when an alarm fires. | 28 // Test delegate which quits the message loop when an alarm fires. |
25 class AlarmDelegate : public AlarmManager::Delegate { | 29 class AlarmDelegate : public AlarmManager::Delegate { |
26 public: | 30 public: |
27 virtual ~AlarmDelegate() {} | 31 virtual ~AlarmDelegate() {} |
28 virtual void OnAlarm(const std::string& extension_id, | 32 virtual void OnAlarm(const std::string& extension_id, |
29 const AlarmManager::Alarm& alarm) { | 33 const Alarm& alarm) { |
30 alarms_seen.push_back(alarm.name); | 34 alarms_seen.push_back(alarm.js_alarm->name); |
31 MessageLoop::current()->Quit(); | 35 MessageLoop::current()->Quit(); |
32 } | 36 } |
33 | 37 |
34 std::vector<std::string> alarms_seen; | 38 std::vector<std::string> alarms_seen; |
35 }; | 39 }; |
36 | 40 |
37 } // namespace | 41 } // namespace |
38 | 42 |
39 class ExtensionAlarmsTest : public BrowserWithTestWindowTest { | 43 class ExtensionAlarmsTest : public BrowserWithTestWindowTest { |
40 public: | 44 public: |
41 virtual void SetUp() { | 45 virtual void SetUp() { |
42 BrowserWithTestWindowTest::SetUp(); | 46 BrowserWithTestWindowTest::SetUp(); |
43 | 47 |
44 TestExtensionSystem* system = static_cast<TestExtensionSystem*>( | 48 TestExtensionSystem* system = static_cast<TestExtensionSystem*>( |
45 ExtensionSystem::Get(browser()->profile())); | 49 ExtensionSystem::Get(browser()->profile())); |
46 system->CreateAlarmManager(); | 50 system->CreateAlarmManager(&base::MockTimeProvider::StaticNow); |
47 alarm_manager_ = system->alarm_manager(); | 51 alarm_manager_ = system->alarm_manager(); |
48 | 52 |
49 alarm_delegate_ = new AlarmDelegate(); | 53 alarm_delegate_ = new AlarmDelegate(); |
50 alarm_manager_->set_delegate(alarm_delegate_); | 54 alarm_manager_->set_delegate(alarm_delegate_); |
51 | 55 |
52 extension_ = utils::CreateEmptyExtensionWithLocation( | 56 extension_ = utils::CreateEmptyExtensionWithLocation( |
53 extensions::Extension::LOAD); | 57 extensions::Extension::LOAD); |
| 58 |
| 59 current_time_ = base::Time::FromDoubleT(10); |
| 60 ON_CALL(mock_time_, Now()) |
| 61 .WillByDefault(testing::ReturnPointee(¤t_time_)); |
54 } | 62 } |
55 | 63 |
56 base::Value* RunFunctionWithExtension( | 64 base::Value* RunFunctionWithExtension( |
57 UIThreadExtensionFunction* function, const std::string& args) { | 65 UIThreadExtensionFunction* function, const std::string& args) { |
58 function->set_extension(extension_.get()); | 66 function->set_extension(extension_.get()); |
59 return utils::RunFunctionAndReturnResult(function, args, browser()); | 67 return utils::RunFunctionAndReturnResult(function, args, browser()); |
60 } | 68 } |
61 | 69 |
62 base::DictionaryValue* RunFunctionAndReturnDict( | 70 base::DictionaryValue* RunFunctionAndReturnDict( |
63 UIThreadExtensionFunction* function, const std::string& args) { | 71 UIThreadExtensionFunction* function, const std::string& args) { |
(...skipping 11 matching lines...) Expand all Loading... |
75 const std::string& args) { | 83 const std::string& args) { |
76 scoped_ptr<base::Value> result(RunFunctionWithExtension(function, args)); | 84 scoped_ptr<base::Value> result(RunFunctionWithExtension(function, args)); |
77 } | 85 } |
78 | 86 |
79 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 87 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, |
80 const std::string& args) { | 88 const std::string& args) { |
81 function->set_extension(extension_.get()); | 89 function->set_extension(extension_.get()); |
82 return utils::RunFunctionAndReturnError(function, args, browser()); | 90 return utils::RunFunctionAndReturnError(function, args, browser()); |
83 } | 91 } |
84 | 92 |
| 93 void CreateOneShotAlarm(const std::string& args) { |
| 94 RunFunction( |
| 95 new AlarmsCreateOneShotFunction(&base::MockTimeProvider::StaticNow), |
| 96 args); |
| 97 } |
| 98 void CreateRepeatingAlarm(const std::string& args) { |
| 99 RunFunction( |
| 100 new AlarmsCreateRepeatingFunction(&base::MockTimeProvider::StaticNow), |
| 101 args); |
| 102 } |
| 103 |
85 // Takes a JSON result from a function and converts it to a vector of | 104 // Takes a JSON result from a function and converts it to a vector of |
86 // Alarms. | 105 // JsAlarms. |
87 AlarmManager::AlarmList ToAlarmList(base::ListValue* value) { | 106 std::vector<linked_ptr<JsAlarm> > ToAlarmList(base::ListValue* value) { |
88 AlarmManager::AlarmList list; | 107 std::vector<linked_ptr<JsAlarm> > list; |
89 for (size_t i = 0; i < value->GetSize(); ++i) { | 108 for (size_t i = 0; i < value->GetSize(); ++i) { |
90 linked_ptr<AlarmManager::Alarm> alarm(new AlarmManager::Alarm); | 109 linked_ptr<JsAlarm> alarm(new JsAlarm); |
91 base::DictionaryValue* alarm_value; | 110 base::DictionaryValue* alarm_value; |
92 if (!value->GetDictionary(i, &alarm_value)) { | 111 if (!value->GetDictionary(i, &alarm_value)) { |
93 ADD_FAILURE() << "Expected a list of Alarm objects."; | 112 ADD_FAILURE() << "Expected a list of Alarm objects."; |
94 return list; | 113 return list; |
95 } | 114 } |
96 EXPECT_TRUE(AlarmManager::Alarm::Populate(*alarm_value, alarm.get())); | 115 EXPECT_TRUE(JsAlarm::Populate(*alarm_value, alarm.get())); |
97 list.push_back(alarm); | 116 list.push_back(alarm); |
98 } | 117 } |
99 return list; | 118 return list; |
100 } | 119 } |
101 | 120 |
102 // Creates up to 3 alarms using the extension API. | 121 // Creates up to 3 alarms using the extension API. |
103 void CreateAlarms(size_t num_alarms) { | 122 void CreateAlarms(size_t num_alarms) { |
104 CHECK(num_alarms <= 3); | 123 CHECK(num_alarms <= 3); |
105 | 124 |
106 const char* kCreateArgs[] = { | 125 struct { |
107 "[null, {\"delayInMinutes\": 0.001, \"repeating\": true}]", | 126 const char* args; |
108 "[\"7\", {\"delayInMinutes\": 7, \"repeating\": true}]", | 127 bool repeating; |
109 "[\"0\", {\"delayInMinutes\": 0}]" | 128 } kCreateArgs[] = { |
| 129 {"[null, {\"periodInMinutes\": 0.001}]", true}, |
| 130 {"[\"7\", {\"periodInMinutes\": 7}]", true}, |
| 131 {"[\"0\", {\"delayInMinutes\": 0}]", false}, |
110 }; | 132 }; |
111 for (size_t i = 0; i < num_alarms; ++i) { | 133 for (size_t i = 0; i < num_alarms; ++i) { |
112 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( | 134 if (kCreateArgs[i].repeating) { |
113 new AlarmsCreateFunction(), kCreateArgs[i])); | 135 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( |
114 EXPECT_FALSE(result.get()); | 136 new AlarmsCreateRepeatingFunction( |
| 137 &base::MockTimeProvider::StaticNow), |
| 138 kCreateArgs[i].args)); |
| 139 EXPECT_FALSE(result.get()); |
| 140 } else { |
| 141 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( |
| 142 new AlarmsCreateOneShotFunction(&base::MockTimeProvider::StaticNow), |
| 143 kCreateArgs[i].args)); |
| 144 EXPECT_FALSE(result.get()); |
| 145 } |
115 } | 146 } |
116 } | 147 } |
117 | 148 |
118 protected: | 149 protected: |
| 150 base::Time current_time_; |
| 151 testing::NiceMock<base::MockTimeProvider> mock_time_; |
119 AlarmManager* alarm_manager_; | 152 AlarmManager* alarm_manager_; |
120 AlarmDelegate* alarm_delegate_; | 153 AlarmDelegate* alarm_delegate_; |
121 scoped_refptr<extensions::Extension> extension_; | 154 scoped_refptr<extensions::Extension> extension_; |
122 }; | 155 }; |
123 | 156 |
124 TEST_F(ExtensionAlarmsTest, Create) { | 157 TEST_F(ExtensionAlarmsTest, Create) { |
| 158 current_time_ = base::Time::FromDoubleT(10); |
125 // Create 1 non-repeating alarm. | 159 // Create 1 non-repeating alarm. |
126 RunFunction(new AlarmsCreateFunction(), "[null, {\"delayInMinutes\": 0}]"); | 160 CreateOneShotAlarm("[null, {\"delayInMinutes\": 0}]"); |
127 | 161 |
128 const AlarmManager::Alarm* alarm = | 162 const Alarm* alarm = |
129 alarm_manager_->GetAlarm(extension_->id(), ""); | 163 alarm_manager_->GetAlarm(extension_->id(), ""); |
130 ASSERT_TRUE(alarm); | 164 ASSERT_TRUE(alarm); |
131 EXPECT_EQ("", alarm->name); | 165 EXPECT_EQ("", alarm->js_alarm->name); |
132 EXPECT_EQ(0, alarm->delay_in_minutes); | 166 EXPECT_DOUBLE_EQ(10000, alarm->js_alarm->scheduled_time); |
133 EXPECT_FALSE(alarm->repeating); | 167 EXPECT_FALSE(alarm->js_alarm->period_in_minutes.get()); |
134 | 168 |
135 // Now wait for the alarm to fire. Our test delegate will quit the | 169 // Now wait for the alarm to fire. Our test delegate will quit the |
136 // MessageLoop when that happens. | 170 // MessageLoop when that happens. |
137 MessageLoop::current()->Run(); | 171 MessageLoop::current()->Run(); |
138 | 172 |
139 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); | 173 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); |
140 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); | 174 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
141 | 175 |
142 // Ensure the alarm is gone. | 176 // Ensure the alarm is gone. |
143 { | 177 { |
144 const AlarmManager::AlarmList* alarms = | 178 const AlarmManager::AlarmList* alarms = |
145 alarm_manager_->GetAllAlarms(extension_->id()); | 179 alarm_manager_->GetAllAlarms(extension_->id()); |
146 ASSERT_FALSE(alarms); | 180 ASSERT_FALSE(alarms); |
147 } | 181 } |
148 } | 182 } |
149 | 183 |
150 TEST_F(ExtensionAlarmsTest, CreateRepeating) { | 184 TEST_F(ExtensionAlarmsTest, CreateRepeating) { |
| 185 current_time_ = base::Time::FromDoubleT(10); |
| 186 |
151 // Create 1 repeating alarm. | 187 // Create 1 repeating alarm. |
152 RunFunction(new AlarmsCreateFunction(), | 188 CreateRepeatingAlarm("[null, {\"periodInMinutes\": 0.001}]"); |
153 "[null, {\"delayInMinutes\": 0.001, \"repeating\": true}]"); | |
154 | 189 |
155 const AlarmManager::Alarm* alarm = | 190 const Alarm* alarm = |
156 alarm_manager_->GetAlarm(extension_->id(), ""); | 191 alarm_manager_->GetAlarm(extension_->id(), ""); |
157 ASSERT_TRUE(alarm); | 192 ASSERT_TRUE(alarm); |
158 EXPECT_EQ("", alarm->name); | 193 EXPECT_EQ("", alarm->js_alarm->name); |
159 EXPECT_EQ(0.001, alarm->delay_in_minutes); | 194 EXPECT_DOUBLE_EQ(10060, alarm->js_alarm->scheduled_time); |
160 EXPECT_TRUE(alarm->repeating); | 195 EXPECT_THAT(alarm->js_alarm->period_in_minutes, |
| 196 testing::Pointee(testing::DoubleEq(0.001))); |
161 | 197 |
| 198 current_time_ += base::TimeDelta::FromSeconds(1); |
162 // Now wait for the alarm to fire. Our test delegate will quit the | 199 // Now wait for the alarm to fire. Our test delegate will quit the |
163 // MessageLoop when that happens. | 200 // MessageLoop when that happens. |
164 MessageLoop::current()->Run(); | 201 MessageLoop::current()->Run(); |
165 | 202 |
| 203 current_time_ += base::TimeDelta::FromSeconds(1); |
166 // Wait again, and ensure the alarm fires again. | 204 // Wait again, and ensure the alarm fires again. |
167 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); | 205 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); |
168 MessageLoop::current()->Run(); | 206 MessageLoop::current()->Run(); |
169 | 207 |
170 ASSERT_EQ(2u, alarm_delegate_->alarms_seen.size()); | 208 ASSERT_EQ(2u, alarm_delegate_->alarms_seen.size()); |
171 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); | 209 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
172 } | 210 } |
173 | 211 |
| 212 TEST_F(ExtensionAlarmsTest, CreateAbsolute) { |
| 213 current_time_ = base::Time::FromDoubleT(9.99); |
| 214 CreateOneShotAlarm("[null, {\"timeToFire\": 10001}]"); |
| 215 |
| 216 const Alarm* alarm = |
| 217 alarm_manager_->GetAlarm(extension_->id(), ""); |
| 218 ASSERT_TRUE(alarm); |
| 219 EXPECT_EQ("", alarm->js_alarm->name); |
| 220 EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time); |
| 221 EXPECT_THAT(alarm->js_alarm->period_in_minutes, |
| 222 testing::IsNull()); |
| 223 |
| 224 current_time_ = base::Time::FromDoubleT(10.1); |
| 225 // Now wait for the alarm to fire. Our test delegate will quit the |
| 226 // MessageLoop when that happens. |
| 227 MessageLoop::current()->Run(); |
| 228 |
| 229 ASSERT_FALSE(alarm_manager_->GetAlarm(extension_->id(), "")); |
| 230 |
| 231 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); |
| 232 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
| 233 } |
| 234 |
174 TEST_F(ExtensionAlarmsTest, CreateDupe) { | 235 TEST_F(ExtensionAlarmsTest, CreateDupe) { |
| 236 current_time_ = base::Time::FromDoubleT(10); |
| 237 |
175 // Create 2 duplicate alarms. The first should be overridden. | 238 // Create 2 duplicate alarms. The first should be overridden. |
176 RunFunction(new AlarmsCreateFunction(), "[\"dup\", {\"delayInMinutes\": 1}]"); | 239 CreateOneShotAlarm("[\"dup\", {\"delayInMinutes\": 1}]"); |
177 RunFunction(new AlarmsCreateFunction(), "[\"dup\", {\"delayInMinutes\": 7}]"); | 240 CreateOneShotAlarm("[\"dup\", {\"delayInMinutes\": 7}]"); |
178 | 241 |
179 { | 242 { |
180 const AlarmManager::AlarmList* alarms = | 243 const AlarmManager::AlarmList* alarms = |
181 alarm_manager_->GetAllAlarms(extension_->id()); | 244 alarm_manager_->GetAllAlarms(extension_->id()); |
182 ASSERT_TRUE(alarms); | 245 ASSERT_TRUE(alarms); |
183 EXPECT_EQ(1u, alarms->size()); | 246 EXPECT_EQ(1u, alarms->size()); |
184 EXPECT_EQ(7, (*alarms)[0]->delay_in_minutes); | 247 EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time); |
185 } | 248 } |
186 } | 249 } |
187 | 250 |
188 TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) { | 251 TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) { |
189 // Create an alarm with delay below the minimum accepted value. | 252 // Create an alarm with delay below the minimum accepted value. |
190 std::string error = RunFunctionAndReturnError(new AlarmsCreateFunction(), | 253 std::string error = RunFunctionAndReturnError( |
| 254 new AlarmsCreateOneShotFunction(&base::MockTimeProvider::StaticNow), |
191 "[\"negative\", {\"delayInMinutes\": -0.2}]"); | 255 "[\"negative\", {\"delayInMinutes\": -0.2}]"); |
192 EXPECT_FALSE(error.empty()); | 256 EXPECT_FALSE(error.empty()); |
193 } | 257 } |
194 | 258 |
195 TEST_F(ExtensionAlarmsTest, Get) { | 259 TEST_F(ExtensionAlarmsTest, Get) { |
| 260 current_time_ = base::Time::FromDoubleT(4); |
| 261 |
196 // Create 2 alarms, and make sure we can query them. | 262 // Create 2 alarms, and make sure we can query them. |
197 CreateAlarms(2); | 263 CreateAlarms(2); |
198 | 264 |
199 // Get the default one. | 265 // Get the default one. |
200 { | 266 { |
201 AlarmManager::Alarm alarm; | 267 JsAlarm alarm; |
202 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( | 268 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( |
203 new AlarmsGetFunction(), "[null]")); | 269 new AlarmsGetFunction(), "[null]")); |
204 ASSERT_TRUE(result.get()); | 270 ASSERT_TRUE(result.get()); |
205 EXPECT_TRUE(AlarmManager::Alarm::Populate(*result, &alarm)); | 271 EXPECT_TRUE(JsAlarm::Populate(*result, &alarm)); |
206 EXPECT_EQ("", alarm.name); | 272 EXPECT_EQ("", alarm.name); |
207 EXPECT_EQ(0.001, alarm.delay_in_minutes); | 273 EXPECT_DOUBLE_EQ(4060, alarm.scheduled_time); |
208 EXPECT_TRUE(alarm.repeating); | 274 EXPECT_THAT(alarm.period_in_minutes, |
| 275 testing::Pointee(testing::DoubleEq(0.001))); |
209 } | 276 } |
210 | 277 |
211 // Get "7". | 278 // Get "7". |
212 { | 279 { |
213 AlarmManager::Alarm alarm; | 280 JsAlarm alarm; |
214 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( | 281 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDict( |
215 new AlarmsGetFunction(), "[\"7\"]")); | 282 new AlarmsGetFunction(), "[\"7\"]")); |
216 ASSERT_TRUE(result.get()); | 283 ASSERT_TRUE(result.get()); |
217 EXPECT_TRUE(AlarmManager::Alarm::Populate(*result, &alarm)); | 284 EXPECT_TRUE(JsAlarm::Populate(*result, &alarm)); |
218 EXPECT_EQ("7", alarm.name); | 285 EXPECT_EQ("7", alarm.name); |
219 EXPECT_EQ(7, alarm.delay_in_minutes); | 286 EXPECT_EQ(424000, alarm.scheduled_time); |
220 EXPECT_TRUE(alarm.repeating); | 287 EXPECT_THAT(alarm.period_in_minutes, testing::Pointee(7)); |
221 } | 288 } |
222 | 289 |
223 // Get a non-existent one. | 290 // Get a non-existent one. |
224 { | 291 { |
225 std::string error = RunFunctionAndReturnError( | 292 std::string error = RunFunctionAndReturnError( |
226 new AlarmsGetFunction(), "[\"nobody\"]"); | 293 new AlarmsGetFunction(), "[\"nobody\"]"); |
227 EXPECT_FALSE(error.empty()); | 294 EXPECT_FALSE(error.empty()); |
228 } | 295 } |
229 } | 296 } |
230 | 297 |
231 TEST_F(ExtensionAlarmsTest, GetAll) { | 298 TEST_F(ExtensionAlarmsTest, GetAll) { |
232 // Test getAll with 0 alarms. | 299 // Test getAll with 0 alarms. |
233 { | 300 { |
234 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList( | 301 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList( |
235 new AlarmsGetAllFunction(), "[]")); | 302 new AlarmsGetAllFunction(), "[]")); |
236 AlarmManager::AlarmList alarms = ToAlarmList(result.get()); | 303 std::vector<linked_ptr<JsAlarm> > alarms = ToAlarmList(result.get()); |
237 EXPECT_EQ(0u, alarms.size()); | 304 EXPECT_EQ(0u, alarms.size()); |
238 } | 305 } |
239 | 306 |
240 // Create 2 alarms, and make sure we can query them. | 307 // Create 2 alarms, and make sure we can query them. |
241 CreateAlarms(2); | 308 CreateAlarms(2); |
242 | 309 |
243 { | 310 { |
244 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList( | 311 scoped_ptr<base::ListValue> result(RunFunctionAndReturnList( |
245 new AlarmsGetAllFunction(), "[null]")); | 312 new AlarmsGetAllFunction(), "[null]")); |
246 AlarmManager::AlarmList alarms = ToAlarmList(result.get()); | 313 std::vector<linked_ptr<JsAlarm> > alarms = ToAlarmList(result.get()); |
247 EXPECT_EQ(2u, alarms.size()); | 314 EXPECT_EQ(2u, alarms.size()); |
248 | 315 |
249 // Test the "7" alarm. | 316 // Test the "7" alarm. |
250 AlarmManager::Alarm* alarm = alarms[0].get(); | 317 JsAlarm* alarm = alarms[0].get(); |
251 if (alarm->name != "7") | 318 if (alarm->name != "7") |
252 alarm = alarms[1].get(); | 319 alarm = alarms[1].get(); |
253 EXPECT_EQ("7", alarm->name); | 320 EXPECT_EQ("7", alarm->name); |
254 EXPECT_EQ(7, alarm->delay_in_minutes); | 321 EXPECT_THAT(alarm->period_in_minutes, testing::Pointee(7)); |
255 EXPECT_TRUE(alarm->repeating); | |
256 } | 322 } |
257 } | 323 } |
258 | 324 |
259 TEST_F(ExtensionAlarmsTest, Clear) { | 325 TEST_F(ExtensionAlarmsTest, Clear) { |
260 // Clear a non-existent one. | 326 // Clear a non-existent one. |
261 { | 327 { |
262 std::string error = RunFunctionAndReturnError( | 328 std::string error = RunFunctionAndReturnError( |
263 new AlarmsClearFunction(), "[\"nobody\"]"); | 329 new AlarmsClearFunction(), "[\"nobody\"]"); |
264 EXPECT_FALSE(error.empty()); | 330 EXPECT_FALSE(error.empty()); |
265 } | 331 } |
266 | 332 |
267 // Create 3 alarms. | 333 // Create 3 alarms. |
268 CreateAlarms(3); | 334 CreateAlarms(3); |
269 | 335 |
270 // Clear all but the 0.001-minute alarm. | 336 // Clear all but the 0.001-minute alarm. |
271 { | 337 { |
272 RunFunction(new AlarmsClearFunction(), "[\"7\"]"); | 338 RunFunction(new AlarmsClearFunction(), "[\"7\"]"); |
273 RunFunction(new AlarmsClearFunction(), "[\"0\"]"); | 339 RunFunction(new AlarmsClearFunction(), "[\"0\"]"); |
274 | 340 |
275 const AlarmManager::AlarmList* alarms = | 341 const AlarmManager::AlarmList* alarms = |
276 alarm_manager_->GetAllAlarms(extension_->id()); | 342 alarm_manager_->GetAllAlarms(extension_->id()); |
277 ASSERT_TRUE(alarms); | 343 ASSERT_TRUE(alarms); |
278 EXPECT_EQ(1u, alarms->size()); | 344 EXPECT_EQ(1u, alarms->size()); |
279 EXPECT_EQ(0.001, (*alarms)[0]->delay_in_minutes); | 345 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes, |
| 346 testing::Pointee(0.001)); |
280 } | 347 } |
281 | 348 |
282 // Now wait for the alarms to fire, and ensure the cancelled alarms don't | 349 // Now wait for the alarms to fire, and ensure the cancelled alarms don't |
283 // fire. | 350 // fire. |
284 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); | 351 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); |
285 MessageLoop::current()->Run(); | 352 MessageLoop::current()->Run(); |
286 | 353 |
287 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); | 354 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); |
288 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); | 355 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
289 | 356 |
290 // Ensure the 0.001-minute alarm is still there, since it's repeating. | 357 // Ensure the 0.001-minute alarm is still there, since it's repeating. |
291 { | 358 { |
292 const AlarmManager::AlarmList* alarms = | 359 const AlarmManager::AlarmList* alarms = |
293 alarm_manager_->GetAllAlarms(extension_->id()); | 360 alarm_manager_->GetAllAlarms(extension_->id()); |
294 ASSERT_TRUE(alarms); | 361 ASSERT_TRUE(alarms); |
295 EXPECT_EQ(1u, alarms->size()); | 362 EXPECT_EQ(1u, alarms->size()); |
296 EXPECT_EQ(0.001, (*alarms)[0]->delay_in_minutes); | 363 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes, |
| 364 testing::Pointee(0.001)); |
297 } | 365 } |
298 } | 366 } |
299 | 367 |
300 TEST_F(ExtensionAlarmsTest, ClearAll) { | 368 TEST_F(ExtensionAlarmsTest, ClearAll) { |
301 // ClearAll with no alarms set. | 369 // ClearAll with no alarms set. |
302 { | 370 { |
303 scoped_ptr<base::Value> result(RunFunctionWithExtension( | 371 scoped_ptr<base::Value> result(RunFunctionWithExtension( |
304 new AlarmsClearAllFunction(), "[]")); | 372 new AlarmsClearAllFunction(), "[]")); |
305 EXPECT_FALSE(result.get()); | 373 EXPECT_FALSE(result.get()); |
306 } | 374 } |
(...skipping 13 matching lines...) Expand all Loading... |
320 const AlarmManager::AlarmList* alarms = | 388 const AlarmManager::AlarmList* alarms = |
321 alarm_manager_->GetAllAlarms(extension_->id()); | 389 alarm_manager_->GetAllAlarms(extension_->id()); |
322 ASSERT_FALSE(alarms); | 390 ASSERT_FALSE(alarms); |
323 } | 391 } |
324 } | 392 } |
325 | 393 |
326 class ExtensionAlarmsSchedulingTest : public ExtensionAlarmsTest { | 394 class ExtensionAlarmsSchedulingTest : public ExtensionAlarmsTest { |
327 public: | 395 public: |
328 // Get the time that the alarm named is scheduled to run. | 396 // Get the time that the alarm named is scheduled to run. |
329 base::Time GetScheduledTime(const std::string& alarm_name) { | 397 base::Time GetScheduledTime(const std::string& alarm_name) { |
330 const extensions::AlarmManager::Alarm* alarm = | 398 const extensions::Alarm* alarm = |
331 alarm_manager_->GetAlarm(extension_->id(), alarm_name); | 399 alarm_manager_->GetAlarm(extension_->id(), alarm_name); |
332 CHECK(alarm); | 400 CHECK(alarm); |
333 return alarm_manager_->scheduled_times_[alarm].time; | 401 return base::Time::FromJsTime(alarm->js_alarm->scheduled_time); |
334 } | 402 } |
335 }; | 403 }; |
336 | 404 |
337 TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) { | 405 TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) { |
338 { | 406 { |
339 RunFunction(new AlarmsCreateFunction(), | 407 CreateRepeatingAlarm("[\"a\", {\"periodInMinutes\": 6}]"); |
340 "[\"a\", {\"delayInMinutes\": 6, \"repeating\": true}]"); | 408 CreateRepeatingAlarm("[\"bb\", {\"periodInMinutes\": 8}]"); |
341 RunFunction(new AlarmsCreateFunction(), | |
342 "[\"bb\", {\"delayInMinutes\": 8, \"repeating\": true}]"); | |
343 EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_); | 409 EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_); |
344 alarm_manager_->RemoveAllAlarms(extension_->id()); | 410 alarm_manager_->RemoveAllAlarms(extension_->id()); |
345 } | 411 } |
346 { | 412 { |
347 RunFunction(new AlarmsCreateFunction(), | 413 CreateOneShotAlarm("[\"a\", {\"delayInMinutes\": 10}]"); |
348 "[\"a\", {\"delayInMinutes\": 10}]"); | 414 CreateOneShotAlarm("[\"bb\", {\"delayInMinutes\": 21}]"); |
349 RunFunction(new AlarmsCreateFunction(), | |
350 "[\"bb\", {\"delayInMinutes\": 21}]"); | |
351 EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_); | 415 EXPECT_EQ(GetScheduledTime("a"), alarm_manager_->next_poll_time_); |
352 alarm_manager_->RemoveAllAlarms(extension_->id()); | 416 alarm_manager_->RemoveAllAlarms(extension_->id()); |
353 } | 417 } |
354 { | 418 { |
355 RunFunction(new AlarmsCreateFunction(), | 419 current_time_ = base::Time::FromDoubleT(10); |
356 "[\"a\", {\"delayInMinutes\": 10, \"repeating\": true}]"); | 420 CreateRepeatingAlarm("[\"a\", {\"periodInMinutes\": 10}]"); |
357 linked_ptr<AlarmManager::Alarm> alarm(new AlarmManager::Alarm()); | 421 Alarm alarm; |
358 alarm->name = "bb"; | 422 alarm.js_alarm->name = "bb"; |
359 alarm->delay_in_minutes = 30; | 423 alarm.js_alarm->scheduled_time = 30 * 60000; |
360 alarm->repeating = true; | 424 alarm.js_alarm->period_in_minutes.reset(new double(30)); |
361 alarm_manager_->AddAlarmImpl(extension_->id(), alarm, | 425 alarm_manager_->AddAlarmImpl(extension_->id(), alarm); |
362 base::TimeDelta::FromMinutes(3)); | 426 EXPECT_DOUBLE_EQ(GetScheduledTime("a").ToDoubleT(), |
363 EXPECT_EQ(GetScheduledTime("bb"), alarm_manager_->next_poll_time_); | 427 alarm_manager_->next_poll_time_.ToDoubleT()); |
364 alarm_manager_->RemoveAllAlarms(extension_->id()); | 428 alarm_manager_->RemoveAllAlarms(extension_->id()); |
365 } | 429 } |
366 { | 430 { |
367 linked_ptr<AlarmManager::Alarm> alarm(new AlarmManager::Alarm()); | 431 current_time_ = base::Time::FromDoubleT(3 * 60 + 1); |
368 alarm->name = "bb"; | 432 Alarm alarm; |
369 alarm->delay_in_minutes = 3; | 433 alarm.js_alarm->name = "bb"; |
370 alarm->repeating = true; | 434 alarm.js_alarm->scheduled_time = 3 * 60000; |
371 alarm_manager_->AddAlarmImpl(extension_->id(), alarm, | 435 alarm.js_alarm->period_in_minutes.reset(new double(3)); |
372 base::TimeDelta::FromSeconds(0)); | 436 alarm_manager_->AddAlarmImpl(extension_->id(), alarm); |
373 MessageLoop::current()->Run(); | 437 MessageLoop::current()->Run(); |
374 EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(3), | 438 EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(3), |
375 alarm_manager_->next_poll_time_); | 439 alarm_manager_->next_poll_time_); |
376 alarm_manager_->RemoveAllAlarms(extension_->id()); | 440 alarm_manager_->RemoveAllAlarms(extension_->id()); |
377 } | 441 } |
378 { | 442 { |
379 RunFunction(new AlarmsCreateFunction(), | 443 current_time_ = base::Time::FromDoubleT(4 * 60 + 1); |
380 "[\"a\", {\"delayInMinutes\": 2, \"repeating\": true}]"); | 444 CreateRepeatingAlarm("[\"a\", {\"periodInMinutes\": 2}]"); |
381 alarm_manager_->RemoveAlarm(extension_->id(), "a"); | 445 alarm_manager_->RemoveAlarm(extension_->id(), "a"); |
382 linked_ptr<AlarmManager::Alarm> alarm2(new AlarmManager::Alarm()); | 446 Alarm alarm2; |
383 alarm2->name = "bb"; | 447 alarm2.js_alarm->name = "bb"; |
384 alarm2->delay_in_minutes = 4; | 448 alarm2.js_alarm->scheduled_time = 4 * 60000; |
385 alarm2->repeating = true; | 449 alarm2.js_alarm->period_in_minutes.reset(new double(4)); |
386 alarm_manager_->AddAlarmImpl(extension_->id(), alarm2, | 450 alarm_manager_->AddAlarmImpl(extension_->id(), alarm2); |
387 base::TimeDelta::FromMinutes(3)); | 451 Alarm alarm3; |
388 linked_ptr<AlarmManager::Alarm> alarm3(new AlarmManager::Alarm()); | 452 alarm3.js_alarm->name = "ccc"; |
389 alarm3->name = "ccc"; | 453 alarm3.js_alarm->scheduled_time = 25 * 60000; |
390 alarm3->delay_in_minutes = 25; | 454 alarm3.js_alarm->period_in_minutes.reset(new double(25)); |
391 alarm3->repeating = true; | 455 alarm_manager_->AddAlarmImpl(extension_->id(), alarm3); |
392 alarm_manager_->AddAlarmImpl(extension_->id(), alarm3, | |
393 base::TimeDelta::FromSeconds(0)); | |
394 MessageLoop::current()->Run(); | 456 MessageLoop::current()->Run(); |
395 EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(4), | 457 EXPECT_EQ(alarm_manager_->last_poll_time_ + base::TimeDelta::FromMinutes(4), |
396 alarm_manager_->next_poll_time_); | 458 alarm_manager_->next_poll_time_); |
397 alarm_manager_->RemoveAllAlarms(extension_->id()); | 459 alarm_manager_->RemoveAllAlarms(extension_->id()); |
398 } | 460 } |
399 } | 461 } |
400 | 462 |
| 463 TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) { |
| 464 extension_ = utils::CreateEmptyExtensionWithLocation( |
| 465 extensions::Extension::INTERNAL); |
| 466 current_time_ = base::Time::FromJsTime(300000); |
| 467 CreateOneShotAlarm("[\"a\", {\"timeToFire\": 300010}]"); |
| 468 CreateOneShotAlarm("[\"b\", {\"timeToFire\": 360000}]"); |
| 469 |
| 470 // In released extensions, we set the granularity to at least 5 |
| 471 // minutes, but AddAlarm schedules its next poll precisely. |
| 472 EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime()); |
| 473 |
| 474 // Run an iteration to see the effect of the granularity. |
| 475 current_time_ = base::Time::FromJsTime(300020); |
| 476 MessageLoop::current()->Run(); |
| 477 EXPECT_DOUBLE_EQ(300020, alarm_manager_->last_poll_time_.ToJsTime()); |
| 478 EXPECT_DOUBLE_EQ(600020, alarm_manager_->next_poll_time_.ToJsTime()); |
| 479 } |
| 480 |
401 TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) { | 481 TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) { |
402 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 482 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
403 RunFunction(new AlarmsCreateFunction(), | 483 CreateOneShotAlarm("[\"a\", {\"delayInMinutes\": 0.001}]"); |
404 "[\"a\", {\"delayInMinutes\": 0.001}]"); | |
405 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); | 484 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); |
406 MessageLoop::current()->Run(); | 485 MessageLoop::current()->Run(); |
407 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 486 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
408 RunFunction(new AlarmsCreateFunction(), | 487 CreateOneShotAlarm("[\"bb\", {\"delayInMinutes\": 10}]"); |
409 "[\"bb\", {\"delayInMinutes\": 10}]"); | |
410 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); | 488 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); |
411 alarm_manager_->RemoveAllAlarms(extension_->id()); | 489 alarm_manager_->RemoveAllAlarms(extension_->id()); |
412 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 490 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
413 } | 491 } |
414 | 492 |
415 } // namespace extensions | 493 } // namespace extensions |
OLD | NEW |