Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / extensions / browser / api / alarms / alarms_api_unittest.cc
blob541b8ff5976fd539cd078c83b3f2befe24c6c92c
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
3 // found in the LICENSE file.
5 // This file tests the chrome.alarms extension API.
7 #include "base/test/simple_test_clock.h"
8 #include "base/values.h"
9 #include "content/public/browser/web_contents.h"
10 #include "content/public/test/mock_render_process_host.h"
11 #include "extensions/browser/api/alarms/alarm_manager.h"
12 #include "extensions/browser/api/alarms/alarms_api.h"
13 #include "extensions/browser/api_test_utils.h"
14 #include "extensions/browser/api_unittest.h"
15 #include "extensions/common/extension_messages.h"
16 #include "ipc/ipc_test_sink.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 typedef extensions::core_api::alarms::Alarm JsAlarm;
22 namespace extensions {
24 namespace utils = api_test_utils;
26 namespace {
28 // Test delegate which quits the message loop when an alarm fires.
29 class AlarmDelegate : public AlarmManager::Delegate {
30 public:
31 ~AlarmDelegate() override {}
32 void OnAlarm(const std::string& extension_id, const Alarm& alarm) override {
33 alarms_seen.push_back(alarm.js_alarm->name);
34 if (base::MessageLoop::current()->is_running())
35 base::MessageLoop::current()->Quit();
38 std::vector<std::string> alarms_seen;
41 } // namespace
43 void RunScheduleNextPoll(AlarmManager* alarm_manager) {
44 alarm_manager->ScheduleNextPoll();
47 class ExtensionAlarmsTest : public ApiUnitTest {
48 public:
49 using ApiUnitTest::RunFunction;
51 void SetUp() override {
52 ApiUnitTest::SetUp();
54 test_clock_ = new base::SimpleTestClock();
55 alarm_manager_ = AlarmManager::Get(browser_context());
56 alarm_manager_->SetClockForTesting(test_clock_);
58 alarm_delegate_ = new AlarmDelegate();
59 alarm_manager_->set_delegate(alarm_delegate_);
61 // Make sure there's a RenderViewHost for alarms to warn into.
62 CreateBackgroundPage();
64 test_clock_->SetNow(base::Time::FromDoubleT(10));
67 void CreateAlarm(const std::string& args) {
68 RunFunction(new AlarmsCreateFunction(test_clock_), args);
71 // Takes a JSON result from a function and converts it to a vector of
72 // JsAlarms.
73 std::vector<linked_ptr<JsAlarm>> ToAlarmList(base::ListValue* value) {
74 std::vector<linked_ptr<JsAlarm>> list;
75 for (size_t i = 0; i < value->GetSize(); ++i) {
76 linked_ptr<JsAlarm> alarm(new JsAlarm);
77 base::DictionaryValue* alarm_value;
78 if (!value->GetDictionary(i, &alarm_value)) {
79 ADD_FAILURE() << "Expected a list of Alarm objects.";
80 return list;
82 EXPECT_TRUE(JsAlarm::Populate(*alarm_value, alarm.get()));
83 list.push_back(alarm);
85 return list;
88 // Creates up to 3 alarms using the extension API.
89 void CreateAlarms(size_t num_alarms) {
90 CHECK_LE(num_alarms, 3U);
92 const char* const kCreateArgs[] = {
93 "[null, {\"periodInMinutes\": 0.001}]",
94 "[\"7\", {\"periodInMinutes\": 7}]",
95 "[\"0\", {\"delayInMinutes\": 0}]",
97 for (size_t i = 0; i < num_alarms; ++i) {
98 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
99 new AlarmsCreateFunction(test_clock_), kCreateArgs[i]));
100 EXPECT_FALSE(result.get());
104 base::SimpleTestClock* test_clock_;
105 AlarmManager* alarm_manager_;
106 AlarmDelegate* alarm_delegate_;
109 void ExtensionAlarmsTestGetAllAlarmsCallback(
110 const AlarmManager::AlarmList* alarms) {
111 // Ensure the alarm is gone.
112 ASSERT_FALSE(alarms);
115 void ExtensionAlarmsTestGetAlarmCallback(ExtensionAlarmsTest* test,
116 Alarm* alarm) {
117 ASSERT_TRUE(alarm);
118 EXPECT_EQ("", alarm->js_alarm->name);
119 EXPECT_DOUBLE_EQ(10000, alarm->js_alarm->scheduled_time);
120 EXPECT_FALSE(alarm->js_alarm->period_in_minutes.get());
122 // Now wait for the alarm to fire. Our test delegate will quit the
123 // MessageLoop when that happens.
124 base::MessageLoop::current()->Run();
126 ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
127 EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
129 // Ensure the alarm is gone.
130 test->alarm_manager_->GetAllAlarms(
131 test->extension()->id(),
132 base::Bind(ExtensionAlarmsTestGetAllAlarmsCallback));
135 TEST_F(ExtensionAlarmsTest, Create) {
136 test_clock_->SetNow(base::Time::FromDoubleT(10));
137 // Create 1 non-repeating alarm.
138 CreateAlarm("[null, {\"delayInMinutes\": 0}]");
140 alarm_manager_->GetAlarm(
141 extension()->id(), std::string(),
142 base::Bind(ExtensionAlarmsTestGetAlarmCallback, this));
145 void ExtensionAlarmsTestCreateRepeatingGetAlarmCallback(
146 ExtensionAlarmsTest* test,
147 Alarm* alarm) {
148 ASSERT_TRUE(alarm);
149 EXPECT_EQ("", alarm->js_alarm->name);
150 EXPECT_DOUBLE_EQ(10060, alarm->js_alarm->scheduled_time);
151 EXPECT_THAT(alarm->js_alarm->period_in_minutes,
152 testing::Pointee(testing::DoubleEq(0.001)));
154 test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
155 // Now wait for the alarm to fire. Our test delegate will quit the
156 // MessageLoop when that happens.
157 base::MessageLoop::current()->Run();
159 test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
160 // Wait again, and ensure the alarm fires again.
161 RunScheduleNextPoll(test->alarm_manager_);
162 base::MessageLoop::current()->Run();
164 ASSERT_EQ(2u, test->alarm_delegate_->alarms_seen.size());
165 EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
168 TEST_F(ExtensionAlarmsTest, CreateRepeating) {
169 test_clock_->SetNow(base::Time::FromDoubleT(10));
171 // Create 1 repeating alarm.
172 CreateAlarm("[null, {\"periodInMinutes\": 0.001}]");
174 alarm_manager_->GetAlarm(
175 extension()->id(), std::string(),
176 base::Bind(ExtensionAlarmsTestCreateRepeatingGetAlarmCallback, this));
179 void ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback(
180 ExtensionAlarmsTest* test,
181 Alarm* alarm) {
182 ASSERT_FALSE(alarm);
184 ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
185 EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
188 void ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback(
189 ExtensionAlarmsTest* test,
190 Alarm* alarm) {
191 ASSERT_TRUE(alarm);
192 EXPECT_EQ("", alarm->js_alarm->name);
193 EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
194 EXPECT_THAT(alarm->js_alarm->period_in_minutes, testing::IsNull());
196 test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
197 // Now wait for the alarm to fire. Our test delegate will quit the
198 // MessageLoop when that happens.
199 base::MessageLoop::current()->Run();
201 test->alarm_manager_->GetAlarm(
202 test->extension()->id(), std::string(),
203 base::Bind(ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback, test));
206 TEST_F(ExtensionAlarmsTest, CreateAbsolute) {
207 test_clock_->SetNow(base::Time::FromDoubleT(9.99));
208 CreateAlarm("[null, {\"when\": 10001}]");
210 alarm_manager_->GetAlarm(
211 extension()->id(), std::string(),
212 base::Bind(ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback, this));
215 void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback(
216 ExtensionAlarmsTest* test,
217 Alarm* alarm) {
218 ASSERT_TRUE(alarm);
219 EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre("", ""));
222 void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback(
223 ExtensionAlarmsTest* test,
224 Alarm* alarm) {
225 ASSERT_TRUE(alarm);
226 EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre(""));
228 test->test_clock_->SetNow(base::Time::FromDoubleT(10.7));
229 base::MessageLoop::current()->Run();
231 test->alarm_manager_->GetAlarm(
232 test->extension()->id(), std::string(),
233 base::Bind(
234 ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback,
235 test));
238 void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback(
239 ExtensionAlarmsTest* test,
240 Alarm* alarm) {
241 ASSERT_TRUE(alarm);
242 EXPECT_EQ("", alarm->js_alarm->name);
243 EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
244 EXPECT_THAT(alarm->js_alarm->period_in_minutes,
245 testing::Pointee(testing::DoubleEq(0.001)));
247 test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
248 // Now wait for the alarm to fire. Our test delegate will quit the
249 // MessageLoop when that happens.
250 base::MessageLoop::current()->Run();
252 test->alarm_manager_->GetAlarm(
253 test->extension()->id(), std::string(),
254 base::Bind(
255 ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback,
256 test));
259 TEST_F(ExtensionAlarmsTest, CreateRepeatingWithQuickFirstCall) {
260 test_clock_->SetNow(base::Time::FromDoubleT(9.99));
261 CreateAlarm("[null, {\"when\": 10001, \"periodInMinutes\": 0.001}]");
263 alarm_manager_->GetAlarm(
264 extension()->id(), std::string(),
265 base::Bind(
266 ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback,
267 this));
270 void ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback(
271 const AlarmManager::AlarmList* alarms) {
272 ASSERT_TRUE(alarms);
273 EXPECT_EQ(1u, alarms->size());
274 EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time);
277 TEST_F(ExtensionAlarmsTest, CreateDupe) {
278 test_clock_->SetNow(base::Time::FromDoubleT(10));
280 // Create 2 duplicate alarms. The first should be overridden.
281 CreateAlarm("[\"dup\", {\"delayInMinutes\": 1}]");
282 CreateAlarm("[\"dup\", {\"delayInMinutes\": 7}]");
284 alarm_manager_->GetAllAlarms(
285 extension()->id(),
286 base::Bind(ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback));
289 TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) {
290 // Create an alarm with delay below the minimum accepted value.
291 CreateAlarm("[\"negative\", {\"delayInMinutes\": -0.2}]");
292 IPC::TestSink& sink =
293 static_cast<content::MockRenderProcessHost*>(
294 contents()->GetRenderViewHost()->GetProcess())->sink();
295 const IPC::Message* warning =
296 sink.GetUniqueMessageMatching(ExtensionMsg_AddMessageToConsole::ID);
297 ASSERT_TRUE(warning);
298 ExtensionMsg_AddMessageToConsole::Param params;
299 ExtensionMsg_AddMessageToConsole::Read(warning, &params);
300 content::ConsoleMessageLevel level = get<0>(params);
301 std::string message = get<1>(params);
302 EXPECT_EQ(content::CONSOLE_MESSAGE_LEVEL_WARNING, level);
303 EXPECT_THAT(message, testing::HasSubstr("delay is less than minimum of 1"));
306 TEST_F(ExtensionAlarmsTest, Get) {
307 test_clock_->SetNow(base::Time::FromDoubleT(4));
309 // Create 2 alarms, and make sure we can query them.
310 CreateAlarms(2);
312 // Get the default one.
314 JsAlarm alarm;
315 scoped_ptr<base::DictionaryValue> result(
316 RunFunctionAndReturnDictionary(new AlarmsGetFunction(), "[null]"));
317 ASSERT_TRUE(result.get());
318 EXPECT_TRUE(JsAlarm::Populate(*result, &alarm));
319 EXPECT_EQ("", alarm.name);
320 EXPECT_DOUBLE_EQ(4060, alarm.scheduled_time);
321 EXPECT_THAT(alarm.period_in_minutes,
322 testing::Pointee(testing::DoubleEq(0.001)));
325 // Get "7".
327 JsAlarm alarm;
328 scoped_ptr<base::DictionaryValue> result(
329 RunFunctionAndReturnDictionary(new AlarmsGetFunction(), "[\"7\"]"));
330 ASSERT_TRUE(result.get());
331 EXPECT_TRUE(JsAlarm::Populate(*result, &alarm));
332 EXPECT_EQ("7", alarm.name);
333 EXPECT_EQ(424000, alarm.scheduled_time);
334 EXPECT_THAT(alarm.period_in_minutes, testing::Pointee(7));
337 // Get a non-existent one.
339 scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
340 new AlarmsGetFunction(), "[\"nobody\"]"));
341 ASSERT_FALSE(result.get());
345 TEST_F(ExtensionAlarmsTest, GetAll) {
346 // Test getAll with 0 alarms.
348 scoped_ptr<base::ListValue> result(
349 RunFunctionAndReturnList(new AlarmsGetAllFunction(), "[]"));
350 std::vector<linked_ptr<JsAlarm>> alarms = ToAlarmList(result.get());
351 EXPECT_EQ(0u, alarms.size());
354 // Create 2 alarms, and make sure we can query them.
355 CreateAlarms(2);
358 scoped_ptr<base::ListValue> result(
359 RunFunctionAndReturnList(new AlarmsGetAllFunction(), "[null]"));
360 std::vector<linked_ptr<JsAlarm>> alarms = ToAlarmList(result.get());
361 EXPECT_EQ(2u, alarms.size());
363 // Test the "7" alarm.
364 JsAlarm* alarm = alarms[0].get();
365 if (alarm->name != "7")
366 alarm = alarms[1].get();
367 EXPECT_EQ("7", alarm->name);
368 EXPECT_THAT(alarm->period_in_minutes, testing::Pointee(7));
372 void ExtensionAlarmsTestClearGetAllAlarms2Callback(
373 const AlarmManager::AlarmList* alarms) {
374 // Ensure the 0.001-minute alarm is still there, since it's repeating.
375 ASSERT_TRUE(alarms);
376 EXPECT_EQ(1u, alarms->size());
377 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
378 testing::Pointee(0.001));
381 void ExtensionAlarmsTestClearGetAllAlarms1Callback(
382 ExtensionAlarmsTest* test,
383 const AlarmManager::AlarmList* alarms) {
384 ASSERT_TRUE(alarms);
385 EXPECT_EQ(1u, alarms->size());
386 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
387 testing::Pointee(0.001));
389 // Now wait for the alarms to fire, and ensure the cancelled alarms don't
390 // fire.
391 test->test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
392 RunScheduleNextPoll(test->alarm_manager_);
393 base::MessageLoop::current()->Run();
395 ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
396 EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
398 // Ensure the 0.001-minute alarm is still there, since it's repeating.
399 test->alarm_manager_->GetAllAlarms(
400 test->extension()->id(),
401 base::Bind(ExtensionAlarmsTestClearGetAllAlarms2Callback));
404 TEST_F(ExtensionAlarmsTest, Clear) {
405 // Clear a non-existent one.
407 scoped_ptr<base::Value> result(
408 RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"nobody\"]"));
409 bool copy_bool_result = false;
410 ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
411 EXPECT_FALSE(copy_bool_result);
414 // Create 3 alarms.
415 CreateAlarms(3);
417 // Clear all but the 0.001-minute alarm.
419 scoped_ptr<base::Value> result(
420 RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"7\"]"));
421 bool copy_bool_result = false;
422 ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
423 EXPECT_TRUE(copy_bool_result);
426 scoped_ptr<base::Value> result(
427 RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"0\"]"));
428 bool copy_bool_result = false;
429 ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
430 EXPECT_TRUE(copy_bool_result);
433 alarm_manager_->GetAllAlarms(
434 extension()->id(),
435 base::Bind(ExtensionAlarmsTestClearGetAllAlarms1Callback, this));
438 void ExtensionAlarmsTestClearAllGetAllAlarms2Callback(
439 const AlarmManager::AlarmList* alarms) {
440 ASSERT_FALSE(alarms);
443 void ExtensionAlarmsTestClearAllGetAllAlarms1Callback(
444 ExtensionAlarmsTest* test,
445 const AlarmManager::AlarmList* alarms) {
446 ASSERT_TRUE(alarms);
447 EXPECT_EQ(3u, alarms->size());
449 // Clear them.
450 test->RunFunction(new AlarmsClearAllFunction(), "[]");
451 test->alarm_manager_->GetAllAlarms(
452 test->extension()->id(),
453 base::Bind(ExtensionAlarmsTestClearAllGetAllAlarms2Callback));
456 TEST_F(ExtensionAlarmsTest, ClearAll) {
457 // ClearAll with no alarms set.
459 scoped_ptr<base::Value> result(
460 RunFunctionAndReturnValue(new AlarmsClearAllFunction(), "[]"));
461 bool copy_bool_result = false;
462 ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
463 EXPECT_TRUE(copy_bool_result);
466 // Create 3 alarms.
467 CreateAlarms(3);
468 alarm_manager_->GetAllAlarms(
469 extension()->id(),
470 base::Bind(ExtensionAlarmsTestClearAllGetAllAlarms1Callback, this));
473 class ExtensionAlarmsSchedulingTest : public ExtensionAlarmsTest {
474 void GetAlarmCallback(Alarm* alarm) {
475 CHECK(alarm);
476 const base::Time scheduled_time =
477 base::Time::FromJsTime(alarm->js_alarm->scheduled_time);
478 EXPECT_EQ(scheduled_time, alarm_manager_->next_poll_time_);
481 static void RemoveAlarmCallback(bool success) { EXPECT_TRUE(success); }
482 static void RemoveAllAlarmsCallback() {}
484 public:
485 // Get the time that the alarm named is scheduled to run.
486 void VerifyScheduledTime(const std::string& alarm_name) {
487 alarm_manager_->GetAlarm(
488 extension()->id(), alarm_name,
489 base::Bind(&ExtensionAlarmsSchedulingTest::GetAlarmCallback,
490 base::Unretained(this)));
493 void RemoveAlarm(const std::string& name) {
494 alarm_manager_->RemoveAlarm(
495 extension()->id(), name,
496 base::Bind(&ExtensionAlarmsSchedulingTest::RemoveAlarmCallback));
499 void RemoveAllAlarms() {
500 alarm_manager_->RemoveAllAlarms(
501 extension()->id(),
502 base::Bind(&ExtensionAlarmsSchedulingTest::RemoveAllAlarmsCallback));
506 TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
508 CreateAlarm("[\"a\", {\"periodInMinutes\": 6}]");
509 CreateAlarm("[\"bb\", {\"periodInMinutes\": 8}]");
510 VerifyScheduledTime("a");
511 RemoveAllAlarms();
514 CreateAlarm("[\"a\", {\"delayInMinutes\": 10}]");
515 CreateAlarm("[\"bb\", {\"delayInMinutes\": 21}]");
516 VerifyScheduledTime("a");
517 RemoveAllAlarms();
520 test_clock_->SetNow(base::Time::FromDoubleT(10));
521 CreateAlarm("[\"a\", {\"periodInMinutes\": 10}]");
522 Alarm alarm;
523 alarm.js_alarm->name = "bb";
524 alarm.js_alarm->scheduled_time = 30 * 60000;
525 alarm.js_alarm->period_in_minutes.reset(new double(30));
526 alarm_manager_->AddAlarmImpl(extension()->id(), alarm);
527 VerifyScheduledTime("a");
528 RemoveAllAlarms();
531 test_clock_->SetNow(base::Time::FromDoubleT(3 * 60 + 1));
532 Alarm alarm;
533 alarm.js_alarm->name = "bb";
534 alarm.js_alarm->scheduled_time = 3 * 60000;
535 alarm.js_alarm->period_in_minutes.reset(new double(3));
536 alarm_manager_->AddAlarmImpl(extension()->id(), alarm);
537 base::MessageLoop::current()->Run();
538 EXPECT_EQ(
539 base::Time::FromJsTime(3 * 60000) + base::TimeDelta::FromMinutes(3),
540 alarm_manager_->next_poll_time_);
541 RemoveAllAlarms();
544 test_clock_->SetNow(base::Time::FromDoubleT(4 * 60 + 1));
545 CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
546 RemoveAlarm("a");
547 Alarm alarm2;
548 alarm2.js_alarm->name = "bb";
549 alarm2.js_alarm->scheduled_time = 4 * 60000;
550 alarm2.js_alarm->period_in_minutes.reset(new double(4));
551 alarm_manager_->AddAlarmImpl(extension()->id(), alarm2);
552 Alarm alarm3;
553 alarm3.js_alarm->name = "ccc";
554 alarm3.js_alarm->scheduled_time = 25 * 60000;
555 alarm3.js_alarm->period_in_minutes.reset(new double(25));
556 alarm_manager_->AddAlarmImpl(extension()->id(), alarm3);
557 base::MessageLoop::current()->Run();
558 EXPECT_EQ(
559 base::Time::FromJsTime(4 * 60000) + base::TimeDelta::FromMinutes(4),
560 alarm_manager_->next_poll_time_);
561 RemoveAllAlarms();
565 TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) {
566 set_extension(
567 utils::CreateEmptyExtensionWithLocation(extensions::Manifest::INTERNAL));
568 test_clock_->SetNow(base::Time::FromJsTime(300000));
569 CreateAlarm("[\"a\", {\"when\": 300010}]");
570 CreateAlarm("[\"b\", {\"when\": 340000}]");
572 // On startup (when there's no "last poll"), we let alarms fire as
573 // soon as they're scheduled.
574 EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime());
576 alarm_manager_->last_poll_time_ = base::Time::FromJsTime(290000);
577 // In released extensions, we set the granularity to at least 1
578 // minute, which makes AddAlarm schedule the next poll after the
579 // extension requested.
580 alarm_manager_->ScheduleNextPoll();
581 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
582 base::TimeDelta::FromMinutes(1)).ToJsTime(),
583 alarm_manager_->next_poll_time_.ToJsTime());
586 TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) {
587 EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
588 CreateAlarm("[\"a\", {\"delayInMinutes\": 0.001}]");
589 EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
590 test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
591 base::MessageLoop::current()->Run();
592 EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
593 CreateAlarm("[\"bb\", {\"delayInMinutes\": 10}]");
594 EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
595 RemoveAllAlarms();
596 EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
599 TEST_F(ExtensionAlarmsSchedulingTest, MinimumGranularity) {
600 set_extension(
601 utils::CreateEmptyExtensionWithLocation(extensions::Manifest::INTERNAL));
602 test_clock_->SetNow(base::Time::FromJsTime(0));
603 CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
604 test_clock_->Advance(base::TimeDelta::FromSeconds(1));
605 CreateAlarm("[\"b\", {\"periodInMinutes\": 2}]");
606 test_clock_->Advance(base::TimeDelta::FromMinutes(2));
608 alarm_manager_->last_poll_time_ = base::Time::FromJsTime(2 * 60000);
609 // In released extensions, we set the granularity to at least 1
610 // minute, which makes scheduler set it to 1 minute, rather than
611 // 1 second later (when b is supposed to go off).
612 alarm_manager_->ScheduleNextPoll();
613 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
614 base::TimeDelta::FromMinutes(1)).ToJsTime(),
615 alarm_manager_->next_poll_time_.ToJsTime());
618 TEST_F(ExtensionAlarmsSchedulingTest, DifferentMinimumGranularities) {
619 test_clock_->SetNow(base::Time::FromJsTime(0));
620 // Create an alarm to go off in 12 seconds. This uses the default, unpacked
621 // extension - so there is no minimum granularity.
622 CreateAlarm("[\"a\", {\"periodInMinutes\": 0.2}]"); // 12 seconds.
624 // Create a new extension, which is packed, and has a granularity of 1 minute.
625 // CreateAlarm() uses extension_, so keep a ref of the old one around, and
626 // repopulate extension_.
627 scoped_refptr<Extension> extension2(extension_ref());
628 set_extension(
629 utils::CreateEmptyExtensionWithLocation(extensions::Manifest::INTERNAL));
631 CreateAlarm("[\"b\", {\"periodInMinutes\": 2}]");
633 alarm_manager_->last_poll_time_ = base::Time::FromJsTime(0);
634 alarm_manager_->ScheduleNextPoll();
636 // The next poll time should be 12 seconds from now - the time at which the
637 // first alarm should go off.
638 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
639 base::TimeDelta::FromSeconds(12)).ToJsTime(),
640 alarm_manager_->next_poll_time_.ToJsTime());
643 // Test that scheduled alarms go off at set intervals, even if their actual
644 // trigger is off.
645 TEST_F(ExtensionAlarmsSchedulingTest, RepeatingAlarmsScheduledPredictably) {
646 test_clock_->SetNow(base::Time::FromJsTime(0));
647 CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
649 alarm_manager_->last_poll_time_ = base::Time::FromJsTime(0);
650 alarm_manager_->ScheduleNextPoll();
652 // We expect the first poll to happen two minutes from the start.
653 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
654 base::TimeDelta::FromSeconds(120)).ToJsTime(),
655 alarm_manager_->next_poll_time_.ToJsTime());
657 // Poll more than two minutes later.
658 test_clock_->Advance(base::TimeDelta::FromSeconds(125));
659 alarm_manager_->PollAlarms();
661 // The alarm should have triggered once.
662 EXPECT_EQ(1u, alarm_delegate_->alarms_seen.size());
664 // The next poll should still be scheduled for four minutes from the start,
665 // even though this is less than two minutes since the last alarm.
666 // Last poll was at 125 seconds; next poll should be at 240 seconds.
667 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
668 base::TimeDelta::FromSeconds(115)).ToJsTime(),
669 alarm_manager_->next_poll_time_.ToJsTime());
671 // Completely miss a scheduled trigger.
672 test_clock_->Advance(base::TimeDelta::FromSeconds(255)); // Total Time: 380s
673 alarm_manager_->PollAlarms();
675 // The alarm should have triggered again at this last poll.
676 EXPECT_EQ(2u, alarm_delegate_->alarms_seen.size());
678 // The next poll should be the first poll that hasn't happened and is in-line
679 // with the original scheduling.
680 // Last poll was at 380 seconds; next poll should be at 480 seconds.
681 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
682 base::TimeDelta::FromSeconds(100)).ToJsTime(),
683 alarm_manager_->next_poll_time_.ToJsTime());
686 } // namespace extensions