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/test/mock_time_provider.h" |
7 #include "base/values.h" | 8 #include "base/values.h" |
8 #include "base/test/mock_time_provider.h" | |
9 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" | 9 #include "chrome/browser/extensions/api/alarms/alarm_manager.h" |
10 #include "chrome/browser/extensions/api/alarms/alarms_api.h" | 10 #include "chrome/browser/extensions/api/alarms/alarms_api.h" |
11 #include "chrome/browser/extensions/extension_function_test_utils.h" | 11 #include "chrome/browser/extensions/extension_function_test_utils.h" |
12 #include "chrome/browser/extensions/test_extension_system.h" | 12 #include "chrome/browser/extensions/test_extension_system.h" |
13 #include "chrome/browser/profiles/profile_manager.h" | 13 #include "chrome/browser/profiles/profile_manager.h" |
| 14 #include "chrome/browser/ui/browser_tabstrip.h" |
| 15 #include "chrome/common/extensions/extension_messages.h" |
14 #include "chrome/test/base/browser_with_test_window_test.h" | 16 #include "chrome/test/base/browser_with_test_window_test.h" |
| 17 #include "content/public/browser/web_contents.h" |
| 18 #include "content/public/test/mock_render_process_host.h" |
| 19 #include "ipc/ipc_test_sink.h" |
15 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
17 | 22 |
18 typedef extensions::api::alarms::Alarm JsAlarm; | 23 typedef extensions::api::alarms::Alarm JsAlarm; |
19 | 24 |
20 namespace utils = extension_function_test_utils; | 25 namespace utils = extension_function_test_utils; |
21 | 26 |
22 namespace extensions { | 27 namespace extensions { |
23 | 28 |
24 namespace { | 29 namespace { |
(...skipping 22 matching lines...) Expand all Loading... |
47 ExtensionSystem::Get(browser()->profile())); | 52 ExtensionSystem::Get(browser()->profile())); |
48 system->CreateAlarmManager(&base::MockTimeProvider::StaticNow); | 53 system->CreateAlarmManager(&base::MockTimeProvider::StaticNow); |
49 alarm_manager_ = system->alarm_manager(); | 54 alarm_manager_ = system->alarm_manager(); |
50 | 55 |
51 alarm_delegate_ = new AlarmDelegate(); | 56 alarm_delegate_ = new AlarmDelegate(); |
52 alarm_manager_->set_delegate(alarm_delegate_); | 57 alarm_manager_->set_delegate(alarm_delegate_); |
53 | 58 |
54 extension_ = utils::CreateEmptyExtensionWithLocation( | 59 extension_ = utils::CreateEmptyExtensionWithLocation( |
55 extensions::Extension::LOAD); | 60 extensions::Extension::LOAD); |
56 | 61 |
| 62 // Make sure there's a RenderViewHost for alarms to warn into. |
| 63 AddTab(browser(), extension_->GetBackgroundURL()); |
| 64 contents_ = chrome::GetActiveWebContents(browser()); |
| 65 |
57 current_time_ = base::Time::FromDoubleT(10); | 66 current_time_ = base::Time::FromDoubleT(10); |
58 ON_CALL(mock_time_, Now()) | 67 ON_CALL(mock_time_, Now()) |
59 .WillByDefault(testing::ReturnPointee(¤t_time_)); | 68 .WillByDefault(testing::ReturnPointee(¤t_time_)); |
60 } | 69 } |
61 | 70 |
62 base::Value* RunFunctionWithExtension( | 71 base::Value* RunFunctionWithExtension( |
63 UIThreadExtensionFunction* function, const std::string& args) { | 72 UIThreadExtensionFunction* function, const std::string& args) { |
64 scoped_refptr<UIThreadExtensionFunction> delete_function(function); | 73 scoped_refptr<UIThreadExtensionFunction> delete_function(function); |
65 function->set_extension(extension_.get()); | 74 function->set_extension(extension_.get()); |
| 75 function->SetRenderViewHost(contents_->GetRenderViewHost()); |
66 return utils::RunFunctionAndReturnSingleResult(function, args, browser()); | 76 return utils::RunFunctionAndReturnSingleResult(function, args, browser()); |
67 } | 77 } |
68 | 78 |
69 base::DictionaryValue* RunFunctionAndReturnDict( | 79 base::DictionaryValue* RunFunctionAndReturnDict( |
70 UIThreadExtensionFunction* function, const std::string& args) { | 80 UIThreadExtensionFunction* function, const std::string& args) { |
71 base::Value* result = RunFunctionWithExtension(function, args); | 81 base::Value* result = RunFunctionWithExtension(function, args); |
72 return result ? utils::ToDictionary(result) : NULL; | 82 return result ? utils::ToDictionary(result) : NULL; |
73 } | 83 } |
74 | 84 |
75 base::ListValue* RunFunctionAndReturnList( | 85 base::ListValue* RunFunctionAndReturnList( |
76 UIThreadExtensionFunction* function, const std::string& args) { | 86 UIThreadExtensionFunction* function, const std::string& args) { |
77 base::Value* result = RunFunctionWithExtension(function, args); | 87 base::Value* result = RunFunctionWithExtension(function, args); |
78 return result ? utils::ToList(result) : NULL; | 88 return result ? utils::ToList(result) : NULL; |
79 } | 89 } |
80 | 90 |
81 void RunFunction(UIThreadExtensionFunction* function, | 91 void RunFunction(UIThreadExtensionFunction* function, |
82 const std::string& args) { | 92 const std::string& args) { |
83 scoped_ptr<base::Value> result(RunFunctionWithExtension(function, args)); | 93 scoped_ptr<base::Value> result(RunFunctionWithExtension(function, args)); |
84 } | 94 } |
85 | 95 |
86 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 96 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, |
87 const std::string& args) { | 97 const std::string& args) { |
88 function->set_extension(extension_.get()); | 98 function->set_extension(extension_.get()); |
| 99 function->SetRenderViewHost(contents_->GetRenderViewHost()); |
89 return utils::RunFunctionAndReturnError(function, args, browser()); | 100 return utils::RunFunctionAndReturnError(function, args, browser()); |
90 } | 101 } |
91 | 102 |
92 void CreateAlarm(const std::string& args) { | 103 void CreateAlarm(const std::string& args) { |
93 RunFunction(new AlarmsCreateFunction(&base::MockTimeProvider::StaticNow), | 104 RunFunction(new AlarmsCreateFunction(&base::MockTimeProvider::StaticNow), |
94 args); | 105 args); |
95 } | 106 } |
96 | 107 |
97 // Takes a JSON result from a function and converts it to a vector of | 108 // Takes a JSON result from a function and converts it to a vector of |
98 // JsAlarms. | 109 // JsAlarms. |
(...skipping 28 matching lines...) Expand all Loading... |
127 EXPECT_FALSE(result.get()); | 138 EXPECT_FALSE(result.get()); |
128 } | 139 } |
129 } | 140 } |
130 | 141 |
131 protected: | 142 protected: |
132 base::Time current_time_; | 143 base::Time current_time_; |
133 testing::NiceMock<base::MockTimeProvider> mock_time_; | 144 testing::NiceMock<base::MockTimeProvider> mock_time_; |
134 AlarmManager* alarm_manager_; | 145 AlarmManager* alarm_manager_; |
135 AlarmDelegate* alarm_delegate_; | 146 AlarmDelegate* alarm_delegate_; |
136 scoped_refptr<extensions::Extension> extension_; | 147 scoped_refptr<extensions::Extension> extension_; |
| 148 content::WebContents* contents_; |
137 }; | 149 }; |
138 | 150 |
139 TEST_F(ExtensionAlarmsTest, Create) { | 151 TEST_F(ExtensionAlarmsTest, Create) { |
140 current_time_ = base::Time::FromDoubleT(10); | 152 current_time_ = base::Time::FromDoubleT(10); |
141 // Create 1 non-repeating alarm. | 153 // Create 1 non-repeating alarm. |
142 CreateAlarm("[null, {\"delayInMinutes\": 0}]"); | 154 CreateAlarm("[null, {\"delayInMinutes\": 0}]"); |
143 | 155 |
144 const Alarm* alarm = | 156 const Alarm* alarm = |
145 alarm_manager_->GetAlarm(extension_->id(), ""); | 157 alarm_manager_->GetAlarm(extension_->id(), ""); |
146 ASSERT_TRUE(alarm); | 158 ASSERT_TRUE(alarm); |
(...skipping 30 matching lines...) Expand all Loading... |
177 EXPECT_THAT(alarm->js_alarm->period_in_minutes, | 189 EXPECT_THAT(alarm->js_alarm->period_in_minutes, |
178 testing::Pointee(testing::DoubleEq(0.001))); | 190 testing::Pointee(testing::DoubleEq(0.001))); |
179 | 191 |
180 current_time_ += base::TimeDelta::FromSeconds(1); | 192 current_time_ += base::TimeDelta::FromSeconds(1); |
181 // Now wait for the alarm to fire. Our test delegate will quit the | 193 // Now wait for the alarm to fire. Our test delegate will quit the |
182 // MessageLoop when that happens. | 194 // MessageLoop when that happens. |
183 MessageLoop::current()->Run(); | 195 MessageLoop::current()->Run(); |
184 | 196 |
185 current_time_ += base::TimeDelta::FromSeconds(1); | 197 current_time_ += base::TimeDelta::FromSeconds(1); |
186 // Wait again, and ensure the alarm fires again. | 198 // Wait again, and ensure the alarm fires again. |
187 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); | 199 alarm_manager_->ScheduleNextPoll(); |
188 MessageLoop::current()->Run(); | 200 MessageLoop::current()->Run(); |
189 | 201 |
190 ASSERT_EQ(2u, alarm_delegate_->alarms_seen.size()); | 202 ASSERT_EQ(2u, alarm_delegate_->alarms_seen.size()); |
191 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); | 203 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
192 } | 204 } |
193 | 205 |
194 TEST_F(ExtensionAlarmsTest, CreateAbsolute) { | 206 TEST_F(ExtensionAlarmsTest, CreateAbsolute) { |
195 current_time_ = base::Time::FromDoubleT(9.99); | 207 current_time_ = base::Time::FromDoubleT(9.99); |
196 CreateAlarm("[null, {\"when\": 10001}]"); | 208 CreateAlarm("[null, {\"when\": 10001}]"); |
197 | 209 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 const AlarmManager::AlarmList* alarms = | 264 const AlarmManager::AlarmList* alarms = |
253 alarm_manager_->GetAllAlarms(extension_->id()); | 265 alarm_manager_->GetAllAlarms(extension_->id()); |
254 ASSERT_TRUE(alarms); | 266 ASSERT_TRUE(alarms); |
255 EXPECT_EQ(1u, alarms->size()); | 267 EXPECT_EQ(1u, alarms->size()); |
256 EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time); | 268 EXPECT_DOUBLE_EQ(430000, (*alarms)[0].js_alarm->scheduled_time); |
257 } | 269 } |
258 } | 270 } |
259 | 271 |
260 TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) { | 272 TEST_F(ExtensionAlarmsTest, CreateDelayBelowMinimum) { |
261 // Create an alarm with delay below the minimum accepted value. | 273 // Create an alarm with delay below the minimum accepted value. |
262 std::string error = RunFunctionAndReturnError( | 274 CreateAlarm("[\"negative\", {\"delayInMinutes\": -0.2}]"); |
263 new AlarmsCreateFunction(&base::MockTimeProvider::StaticNow), | 275 IPC::TestSink& sink = static_cast<content::MockRenderProcessHost*>( |
264 "[\"negative\", {\"delayInMinutes\": -0.2}]"); | 276 contents_->GetRenderViewHost()->GetProcess())->sink(); |
265 EXPECT_FALSE(error.empty()); | 277 const IPC::Message* warning = sink.GetUniqueMessageMatching( |
| 278 ExtensionMsg_AddMessageToConsole::ID); |
| 279 ASSERT_TRUE(warning); |
| 280 content::ConsoleMessageLevel level; |
| 281 std::string message; |
| 282 ExtensionMsg_AddMessageToConsole::Read(warning, &level, &message); |
| 283 EXPECT_EQ(content::CONSOLE_MESSAGE_LEVEL_WARNING, level); |
| 284 EXPECT_THAT(message, testing::HasSubstr("delay is less than minimum of 5")); |
266 } | 285 } |
267 | 286 |
268 TEST_F(ExtensionAlarmsTest, Get) { | 287 TEST_F(ExtensionAlarmsTest, Get) { |
269 current_time_ = base::Time::FromDoubleT(4); | 288 current_time_ = base::Time::FromDoubleT(4); |
270 | 289 |
271 // Create 2 alarms, and make sure we can query them. | 290 // Create 2 alarms, and make sure we can query them. |
272 CreateAlarms(2); | 291 CreateAlarms(2); |
273 | 292 |
274 // Get the default one. | 293 // Get the default one. |
275 { | 294 { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 const AlarmManager::AlarmList* alarms = | 369 const AlarmManager::AlarmList* alarms = |
351 alarm_manager_->GetAllAlarms(extension_->id()); | 370 alarm_manager_->GetAllAlarms(extension_->id()); |
352 ASSERT_TRUE(alarms); | 371 ASSERT_TRUE(alarms); |
353 EXPECT_EQ(1u, alarms->size()); | 372 EXPECT_EQ(1u, alarms->size()); |
354 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes, | 373 EXPECT_THAT((*alarms)[0].js_alarm->period_in_minutes, |
355 testing::Pointee(0.001)); | 374 testing::Pointee(0.001)); |
356 } | 375 } |
357 | 376 |
358 // Now wait for the alarms to fire, and ensure the cancelled alarms don't | 377 // Now wait for the alarms to fire, and ensure the cancelled alarms don't |
359 // fire. | 378 // fire. |
360 alarm_manager_->ScheduleNextPoll(base::TimeDelta::FromSeconds(0)); | 379 alarm_manager_->ScheduleNextPoll(); |
361 MessageLoop::current()->Run(); | 380 MessageLoop::current()->Run(); |
362 | 381 |
363 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); | 382 ASSERT_EQ(1u, alarm_delegate_->alarms_seen.size()); |
364 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); | 383 EXPECT_EQ("", alarm_delegate_->alarms_seen[0]); |
365 | 384 |
366 // Ensure the 0.001-minute alarm is still there, since it's repeating. | 385 // Ensure the 0.001-minute alarm is still there, since it's repeating. |
367 { | 386 { |
368 const AlarmManager::AlarmList* alarms = | 387 const AlarmManager::AlarmList* alarms = |
369 alarm_manager_->GetAllAlarms(extension_->id()); | 388 alarm_manager_->GetAllAlarms(extension_->id()); |
370 ASSERT_TRUE(alarms); | 389 ASSERT_TRUE(alarms); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 } | 488 } |
470 } | 489 } |
471 | 490 |
472 TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) { | 491 TEST_F(ExtensionAlarmsSchedulingTest, ReleasedExtensionPollsInfrequently) { |
473 extension_ = utils::CreateEmptyExtensionWithLocation( | 492 extension_ = utils::CreateEmptyExtensionWithLocation( |
474 extensions::Extension::INTERNAL); | 493 extensions::Extension::INTERNAL); |
475 current_time_ = base::Time::FromJsTime(300000); | 494 current_time_ = base::Time::FromJsTime(300000); |
476 CreateAlarm("[\"a\", {\"when\": 300010}]"); | 495 CreateAlarm("[\"a\", {\"when\": 300010}]"); |
477 CreateAlarm("[\"b\", {\"when\": 340000}]"); | 496 CreateAlarm("[\"b\", {\"when\": 340000}]"); |
478 | 497 |
479 // In released extensions, we set the granularity to at least 1 | 498 // On startup (when there's no "last poll"), we let alarms fire as |
480 // minute, but AddAlarm schedules its next poll precisely. | 499 // soon as they're scheduled. |
481 EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime()); | 500 EXPECT_DOUBLE_EQ(300010, alarm_manager_->next_poll_time_.ToJsTime()); |
482 | 501 |
483 // Run an iteration to see the effect of the granularity. | 502 alarm_manager_->last_poll_time_ = base::Time::FromJsTime(200000); |
484 current_time_ = base::Time::FromJsTime(300020); | 503 // In released extensions, we set the granularity to at least 5 |
485 MessageLoop::current()->Run(); | 504 // minutes, which makes AddAlarm schedule the next poll after the |
486 EXPECT_DOUBLE_EQ(300020, alarm_manager_->last_poll_time_.ToJsTime()); | 505 // extension requested. |
487 EXPECT_DOUBLE_EQ(360020, alarm_manager_->next_poll_time_.ToJsTime()); | 506 alarm_manager_->ScheduleNextPoll(); |
| 507 EXPECT_DOUBLE_EQ((alarm_manager_->last_poll_time_ + |
| 508 base::TimeDelta::FromMinutes(5)).ToJsTime(), |
| 509 alarm_manager_->next_poll_time_.ToJsTime()); |
488 } | 510 } |
489 | 511 |
490 TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) { | 512 TEST_F(ExtensionAlarmsSchedulingTest, TimerRunning) { |
491 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 513 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
492 CreateAlarm("[\"a\", {\"delayInMinutes\": 0.001}]"); | 514 CreateAlarm("[\"a\", {\"delayInMinutes\": 0.001}]"); |
493 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); | 515 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); |
494 MessageLoop::current()->Run(); | 516 MessageLoop::current()->Run(); |
495 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 517 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
496 CreateAlarm("[\"bb\", {\"delayInMinutes\": 10}]"); | 518 CreateAlarm("[\"bb\", {\"delayInMinutes\": 10}]"); |
497 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); | 519 EXPECT_TRUE(alarm_manager_->timer_.IsRunning()); |
498 alarm_manager_->RemoveAllAlarms(extension_->id()); | 520 alarm_manager_->RemoveAllAlarms(extension_->id()); |
499 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); | 521 EXPECT_FALSE(alarm_manager_->timer_.IsRunning()); |
500 } | 522 } |
501 | 523 |
502 } // namespace extensions | 524 } // namespace extensions |
OLD | NEW |