15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file tests the chrome.alarms extension API.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/test/simple_test_clock.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/alarms/alarm_manager.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/alarms/alarms_api.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_api_unittest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function_test_utils.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/mock_render_process_host.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_test_sink.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef extensions::api::alarms::Alarm JsAlarm;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace utils = extension_function_test_utils;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test delegate which quits the message loop when an alarm fires.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AlarmDelegate : public AlarmManager::Delegate {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AlarmDelegate() {}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnAlarm(const std::string& extension_id,
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const Alarm& alarm) OVERRIDE {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarms_seen.push_back(alarm.js_alarm->name);
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (base::MessageLoop::current()->is_running())
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::MessageLoop::current()->Quit();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> alarms_seen;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void RunScheduleNextPoll(AlarmManager* alarm_manager) {
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  alarm_manager->ScheduleNextPoll();
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ExtensionAlarmsTest : public ExtensionApiUnittest {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  using ExtensionApiUnittest::RunFunction;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ExtensionApiUnittest::SetUp();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_clock_ = new base::SimpleTestClock();
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    alarm_manager_ = AlarmManager::Get(browser()->profile());
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    alarm_manager_->SetClockForTesting(test_clock_);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm_delegate_ = new AlarmDelegate();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm_manager_->set_delegate(alarm_delegate_);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Make sure there's a RenderViewHost for alarms to warn into.
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CreateBackgroundPage();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_clock_->SetNow(base::Time::FromDoubleT(10));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateAlarm(const std::string& args) {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunFunction(new AlarmsCreateFunction(test_clock_), args);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes a JSON result from a function and converts it to a vector of
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JsAlarms.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<linked_ptr<JsAlarm> > ToAlarmList(base::ListValue* value) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<linked_ptr<JsAlarm> > list;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < value->GetSize(); ++i) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      linked_ptr<JsAlarm> alarm(new JsAlarm);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DictionaryValue* alarm_value;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!value->GetDictionary(i, &alarm_value)) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ADD_FAILURE() << "Expected a list of Alarm objects.";
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return list;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(JsAlarm::Populate(*alarm_value, alarm.get()));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list.push_back(alarm);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return list;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates up to 3 alarms using the extension API.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateAlarms(size_t num_alarms) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(num_alarms <= 3);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* kCreateArgs[] = {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[null, {\"periodInMinutes\": 0.001}]",
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[\"7\", {\"periodInMinutes\": 7}]",
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[\"0\", {\"delayInMinutes\": 0}]",
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < num_alarms; ++i) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          new AlarmsCreateFunction(test_clock_), kCreateArgs[i]));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(result.get());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::SimpleTestClock* test_clock_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AlarmManager* alarm_manager_;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AlarmDelegate* alarm_delegate_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestGetAllAlarmsCallback(
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AlarmManager::AlarmList* alarms) {
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Ensure the alarm is gone.
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(alarms);
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestGetAlarmCallback(
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(alarm);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", alarm->js_alarm->name);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(10000, alarm->js_alarm->scheduled_time);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(alarm->js_alarm->period_in_minutes.get());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now wait for the alarm to fire. Our test delegate will quit the
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop when that happens.
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the alarm is gone.
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test->alarm_manager_->GetAllAlarms(test->extension()->id(), base::Bind(
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestGetAllAlarmsCallback));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, Create) {
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(10));
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create 1 non-repeating alarm.
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[null, {\"delayInMinutes\": 0}]");
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAlarm(extension()->id(), std::string(), base::Bind(
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestGetAlarmCallback, this));
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateRepeatingGetAlarmCallback(
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(alarm);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", alarm->js_alarm->name);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(10060, alarm->js_alarm->scheduled_time);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(alarm->js_alarm->period_in_minutes,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              testing::Pointee(testing::DoubleEq(0.001)));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now wait for the alarm to fire. Our test delegate will quit the
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop when that happens.
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->Advance(base::TimeDelta::FromSeconds(1));
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait again, and ensure the alarm fires again.
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunScheduleNextPoll(test->alarm_manager_);
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(2u, test->alarm_delegate_->alarms_seen.size());
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, CreateRepeating) {
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(10));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create 1 repeating alarm.
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[null, {\"periodInMinutes\": 0.001}]");
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAlarm(extension()->id(), std::string(), base::Bind(
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestCreateRepeatingGetAlarmCallback, this));
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback(
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(alarm);
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback(
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(alarm);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", alarm->js_alarm->name);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(alarm->js_alarm->period_in_minutes,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              testing::IsNull());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now wait for the alarm to fire. Our test delegate will quit the
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop when that happens.
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->alarm_manager_->GetAlarm(
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test->extension()->id(), std::string(), base::Bind(
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          ExtensionAlarmsTestCreateAbsoluteGetAlarm2Callback, test));
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, CreateAbsolute) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(9.99));
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[null, {\"when\": 10001}]");
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAlarm(extension()->id(), std::string(), base::Bind(
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestCreateAbsoluteGetAlarm1Callback, this));
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback(
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarm);
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre("", ""));
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback(
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarm);
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_THAT(test->alarm_delegate_->alarms_seen, testing::ElementsAre(""));
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->SetNow(base::Time::FromDoubleT(10.7));
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::MessageLoop::current()->Run();
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->alarm_manager_->GetAlarm(
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test->extension()->id(), std::string(), base::Bind(
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm3Callback,
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          test));
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback(
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, Alarm* alarm) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(alarm);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", alarm->js_alarm->name);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_DOUBLE_EQ(10001, alarm->js_alarm->scheduled_time);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(alarm->js_alarm->period_in_minutes,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              testing::Pointee(testing::DoubleEq(0.001)));
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->SetNow(base::Time::FromDoubleT(10.1));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now wait for the alarm to fire. Our test delegate will quit the
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MessageLoop when that happens.
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->alarm_manager_->GetAlarm(
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test->extension()->id(), std::string(), base::Bind(
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm2Callback,
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          test));
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, CreateRepeatingWithQuickFirstCall) {
2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(9.99));
2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[null, {\"when\": 10001, \"periodInMinutes\": 0.001}]");
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAlarm(extension()->id(), std::string(), base::Bind(
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestCreateRepeatingWithQuickFirstCallGetAlarm1Callback,
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      this));
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback(
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AlarmManager::AlarmList* alarms) {
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarms);
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1u, alarms->size());
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, CreateDupe) {
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(10));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 2 duplicate alarms. The first should be overridden.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"dup\", {\"delayInMinutes\": 1}]");
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"dup\", {\"delayInMinutes\": 7}]");
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAllAlarms(extension()->id(), base::Bind(
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestCreateDupeGetAllAlarmsCallback));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an alarm with delay below the minimum accepted value.
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CreateAlarm("[\"negative\", {\"delayInMinutes\": -0.2}]");
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC::TestSink& sink = static_cast<content::MockRenderProcessHost*>(
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      contents()->GetRenderViewHost()->GetProcess())->sink();
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const IPC::Message* warning = sink.GetUniqueMessageMatching(
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionMsg_AddMessageToConsole::ID);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(warning);
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionMsg_AddMessageToConsole::Param params;
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionMsg_AddMessageToConsole::Read(warning, &params);
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::ConsoleMessageLevel level = params.a;
289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string message = params.b;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(content::CONSOLE_MESSAGE_LEVEL_WARNING, level);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_THAT(message, testing::HasSubstr("delay is less than minimum of 1"));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, Get) {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test_clock_->SetNow(base::Time::FromDoubleT(4));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 2 alarms, and make sure we can query them.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarms(2);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the default one.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JsAlarm alarm;
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AlarmsGetFunction(), "[null]"));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(result.get());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(JsAlarm::Populate(*result, &alarm));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("", alarm.name);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_DOUBLE_EQ(4060, alarm.scheduled_time);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_THAT(alarm.period_in_minutes,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                testing::Pointee(testing::DoubleEq(0.001)));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get "7".
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JsAlarm alarm;
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AlarmsGetFunction(), "[\"7\"]"));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(result.get());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(JsAlarm::Populate(*result, &alarm));
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("7", alarm.name);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(424000, alarm.scheduled_time);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_THAT(alarm.period_in_minutes, testing::Pointee(7));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get a non-existent one.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<base::DictionaryValue> result(RunFunctionAndReturnDictionary(
3285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        new AlarmsGetFunction(), "[\"nobody\"]"));
3295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ASSERT_FALSE(result.get());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, GetAll) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test getAll with 0 alarms.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::ListValue> result(RunFunctionAndReturnList(
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AlarmsGetAllFunction(), "[]"));
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<linked_ptr<JsAlarm> > alarms = ToAlarmList(result.get());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0u, alarms.size());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 2 alarms, and make sure we can query them.
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarms(2);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<base::ListValue> result(RunFunctionAndReturnList(
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AlarmsGetAllFunction(), "[null]"));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<linked_ptr<JsAlarm> > alarms = ToAlarmList(result.get());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2u, alarms.size());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Test the "7" alarm.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JsAlarm* alarm = alarms[0].get();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (alarm->name != "7")
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      alarm = alarms[1].get();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("7", alarm->name);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_THAT(alarm->period_in_minutes, testing::Pointee(7));
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestClearGetAllAlarms2Callback(
3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AlarmManager::AlarmList* alarms) {
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Ensure the 0.001-minute alarm is still there, since it's repeating.
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarms);
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1u, alarms->size());
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              testing::Pointee(0.001));
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestClearGetAllAlarms1Callback(
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, const AlarmManager::AlarmList* alarms) {
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarms);
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1u, alarms->size());
3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes,
3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              testing::Pointee(0.001));
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Now wait for the alarms to fire, and ensure the cancelled alarms don't
3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // fire.
3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunScheduleNextPoll(test->alarm_manager_);
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::MessageLoop::current()->Run();
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(1u, test->alarm_delegate_->alarms_seen.size());
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("", test->alarm_delegate_->alarms_seen[0]);
3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Ensure the 0.001-minute alarm is still there, since it's repeating.
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test->alarm_manager_->GetAllAlarms(test->extension()->id(), base::Bind(
3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestClearGetAllAlarms2Callback));
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, Clear) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear a non-existent one.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
39323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<base::Value> result(
39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"nobody\"]"));
39523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool copy_bool_result = false;
39623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
39723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EXPECT_FALSE(copy_bool_result);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 3 alarms.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarms(3);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear all but the 0.001-minute alarm.
40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  {
40523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<base::Value> result(
40623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"7\"]"));
40723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool copy_bool_result = false;
40823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
40923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EXPECT_TRUE(copy_bool_result);
41023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
41123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  {
41223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    scoped_ptr<base::Value> result(
41323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        RunFunctionAndReturnValue(new AlarmsClearFunction(), "[\"0\"]"));
41423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool copy_bool_result = false;
41523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
41623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EXPECT_TRUE(copy_bool_result);
41723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAllAlarms(extension()->id(), base::Bind(
4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestClearGetAllAlarms1Callback, this));
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestClearAllGetAllAlarms2Callback(
4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const AlarmManager::AlarmList* alarms) {
4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(alarms);
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ExtensionAlarmsTestClearAllGetAllAlarms1Callback(
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionAlarmsTest* test, const AlarmManager::AlarmList* alarms) {
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(alarms);
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(3u, alarms->size());
4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Clear them.
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->RunFunction(new AlarmsClearAllFunction(), "[]");
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test->alarm_manager_->GetAllAlarms(
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      test->extension()->id(), base::Bind(
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          ExtensionAlarmsTestClearAllGetAllAlarms2Callback));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsTest, ClearAll) {
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClearAll with no alarms set.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::Value> result(RunFunctionAndReturnValue(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new AlarmsClearAllFunction(), "[]"));
44523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    bool copy_bool_result = false;
44623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(result->GetAsBoolean(&copy_bool_result));
44723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    EXPECT_TRUE(copy_bool_result);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create 3 alarms.
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarms(3);
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->GetAllAlarms(extension()->id(), base::Bind(
4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ExtensionAlarmsTestClearAllGetAllAlarms1Callback, this));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionAlarmsSchedulingTest : public ExtensionAlarmsTest {
4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void GetAlarmCallback(Alarm* alarm) {
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(alarm);
4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::Time scheduled_time =
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Time::FromJsTime(alarm->js_alarm->scheduled_time);
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(scheduled_time, alarm_manager_->next_poll_time_);
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static void RemoveAlarmCallback (bool success) { EXPECT_TRUE(success); }
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static void RemoveAllAlarmsCallback () {}
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the time that the alarm named is scheduled to run.
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void VerifyScheduledTime(const std::string& alarm_name) {
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->GetAlarm(extension()->id(), alarm_name, base::Bind(
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        &ExtensionAlarmsSchedulingTest::GetAlarmCallback,
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Unretained(this)));
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void RemoveAlarm(const std::string& name) {
4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    alarm_manager_->RemoveAlarm(
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        extension()->id(),
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        name,
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        base::Bind(&ExtensionAlarmsSchedulingTest::RemoveAlarmCallback));
4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void RemoveAllAlarms () {
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->RemoveAllAlarms(extension()->id(), base::Bind(
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        &ExtensionAlarmsSchedulingTest::RemoveAllAlarmsCallback));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, PollScheduling) {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"a\", {\"periodInMinutes\": 6}]");
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"bb\", {\"periodInMinutes\": 8}]");
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    VerifyScheduledTime("a");
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAllAlarms();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"a\", {\"delayInMinutes\": 10}]");
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"bb\", {\"delayInMinutes\": 21}]");
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    VerifyScheduledTime("a");
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAllAlarms();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_clock_->SetNow(base::Time::FromDoubleT(10));
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"a\", {\"periodInMinutes\": 10}]");
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Alarm alarm;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->name = "bb";
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->scheduled_time = 30 * 60000;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->period_in_minutes.reset(new double(30));
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->AddAlarmImpl(extension()->id(), alarm);
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    VerifyScheduledTime("a");
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAllAlarms();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_clock_->SetNow(base::Time::FromDoubleT(3 * 60 + 1));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Alarm alarm;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->name = "bb";
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->scheduled_time = 3 * 60000;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm.js_alarm->period_in_minutes.reset(new double(3));
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->AddAlarmImpl(extension()->id(), alarm);
51890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::Time::FromJsTime(3 * 60000) +
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::TimeDelta::FromMinutes(3),
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              alarm_manager_->next_poll_time_);
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAllAlarms();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_clock_->SetNow(base::Time::FromDoubleT(4 * 60 + 1));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAlarm("a");
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Alarm alarm2;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm2.js_alarm->name = "bb";
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm2.js_alarm->scheduled_time = 4 * 60000;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm2.js_alarm->period_in_minutes.reset(new double(4));
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->AddAlarmImpl(extension()->id(), alarm2);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Alarm alarm3;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm3.js_alarm->name = "ccc";
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm3.js_alarm->scheduled_time = 25 * 60000;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    alarm3.js_alarm->period_in_minutes.reset(new double(25));
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    alarm_manager_->AddAlarmImpl(extension()->id(), alarm3);
53890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Run();
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(base::Time::FromJsTime(4 * 60000) +
5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::TimeDelta::FromMinutes(4),
5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              alarm_manager_->next_poll_time_);
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RemoveAllAlarms();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) {
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_extension(utils::CreateEmptyExtensionWithLocation(
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::Manifest::INTERNAL));
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  test_clock_->SetNow(base::Time::FromJsTime(300000));
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"a\", {\"when\": 300010}]");
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"b\", {\"when\": 340000}]");
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // On startup (when there's no "last poll"), we let alarms fire as
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // soon as they're scheduled.
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alarm_manager_->last_poll_time_ = base::Time::FromJsTime(290000);
5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // In released extensions, we set the granularity to at least 1
5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // minute, which makes AddAlarm schedule the next poll after the
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // extension requested.
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  alarm_manager_->ScheduleNextPoll();
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    base::TimeDelta::FromMinutes(1)).ToJsTime(),
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    alarm_manager_->next_poll_time_.ToJsTime());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"a\", {\"delayInMinutes\": 0.001}]");
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->Advance(base::TimeDelta::FromMilliseconds(60));
57290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->Run();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateAlarm("[\"bb\", {\"delayInMinutes\": 10}]");
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(alarm_manager_->timer_.IsRunning());
5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RemoveAllAlarms();
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(alarm_manager_->timer_.IsRunning());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, MinimumGranularity) {
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_extension(utils::CreateEmptyExtensionWithLocation(
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extensions::Manifest::INTERNAL));
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->SetNow(base::Time::FromJsTime(0));
5843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->Advance(base::TimeDelta::FromSeconds(1));
5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CreateAlarm("[\"b\", {\"periodInMinutes\": 2}]");
5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  test_clock_->Advance(base::TimeDelta::FromMinutes(2));
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  alarm_manager_->last_poll_time_ = base::Time::FromJsTime(2 * 60000);
5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // In released extensions, we set the granularity to at least 1
5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // minute, which makes scheduler set it to 1 minute, rather than
5923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // 1 second later (when b is supposed to go off).
5933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  alarm_manager_->ScheduleNextPoll();
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    base::TimeDelta::FromMinutes(1)).ToJsTime(),
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    alarm_manager_->next_poll_time_.ToJsTime());
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, DifferentMinimumGranularities) {
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_clock_->SetNow(base::Time::FromJsTime(0));
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create an alarm to go off in 12 seconds. This uses the default, unpacked
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // extension - so there is no minimum granularity.
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateAlarm("[\"a\", {\"periodInMinutes\": 0.2}]");  // 12 seconds.
6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a new extension, which is packed, and has a granularity of 1 minute.
6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CreateAlarm() uses extension_, so keep a ref of the old one around, and
6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // repopulate extension_.
6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<Extension> extension2(extension_ref());
6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  set_extension(
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      utils::CreateEmptyExtensionWithLocation(extensions::Manifest::INTERNAL));
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateAlarm("[\"b\", {\"periodInMinutes\": 2}]");
6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->last_poll_time_ = base::Time::FromJsTime(0);
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->ScheduleNextPoll();
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The next poll time should be 12 seconds from now - the time at which the
6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // first alarm should go off.
6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    base::TimeDelta::FromSeconds(12)).ToJsTime(),
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    alarm_manager_->next_poll_time_.ToJsTime());
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that scheduled alarms go off at set intervals, even if their actual
6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// trigger is off.
6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ExtensionAlarmsSchedulingTest, RepeatingAlarmsScheduledPredictably) {
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_clock_->SetNow(base::Time::FromJsTime(0));
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CreateAlarm("[\"a\", {\"periodInMinutes\": 2}]");
6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->last_poll_time_ = base::Time::FromJsTime(0);
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->ScheduleNextPoll();
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We expect the first poll to happen two minutes from the start.
6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       base::TimeDelta::FromSeconds(120)).ToJsTime(),
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   alarm_manager_->next_poll_time_.ToJsTime());
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Poll more than two minutes later.
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_clock_->Advance(base::TimeDelta::FromSeconds(125));
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->PollAlarms();
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The alarm should have triggered once.
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1u, alarm_delegate_->alarms_seen.size());
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The next poll should still be scheduled for four minutes from the start,
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // even though this is less than two minutes since the last alarm.
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Last poll was at 125 seconds; next poll should be at 240 seconds.
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       base::TimeDelta::FromSeconds(115)).ToJsTime(),
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   alarm_manager_->next_poll_time_.ToJsTime());
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Completely miss a scheduled trigger.
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  test_clock_->Advance(base::TimeDelta::FromSeconds(255));  // Total Time: 380s
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  alarm_manager_->PollAlarms();
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The alarm should have triggered again at this last poll.
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(2u, alarm_delegate_->alarms_seen.size());
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The next poll should be the first poll that hasn't happened and is in-line
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // with the original scheduling.
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Last poll was at 380 seconds; next poll should be at 480 seconds.
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ +
6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       base::TimeDelta::FromSeconds(100)).ToJsTime(),
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   alarm_manager_->next_poll_time_.ToJsTime());
6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
668