Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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 #include "chrome/browser/apps/app_browsertest_util.h" | 5 #include "chrome/browser/apps/app_browsertest_util.h" |
| 6 #include "chrome/browser/extensions/extension_apitest.h" | 6 #include "chrome/browser/extensions/extension_apitest.h" |
| 7 #include "chrome/browser/extensions/extension_function_test_utils.h" | 7 #include "chrome/browser/extensions/extension_function_test_utils.h" |
| 8 #include "chrome/browser/extensions/test_extension_dir.h" | 8 #include "chrome/browser/extensions/test_extension_dir.h" |
| 9 #include "chrome/test/base/ui_test_utils.h" | 9 #include "chrome/test/base/ui_test_utils.h" |
| 10 #include "content/public/browser/notification_service.h" | 10 #include "content/public/browser/notification_service.h" |
| 11 #include "extensions/browser/api/runtime/runtime_api.h" | 11 #include "extensions/browser/api/runtime/runtime_api.h" |
| 12 #include "extensions/browser/extension_dialog_auto_confirm.h" | 12 #include "extensions/browser/extension_dialog_auto_confirm.h" |
| 13 #include "extensions/browser/extension_registry.h" | 13 #include "extensions/browser/extension_registry.h" |
| 14 #include "extensions/test/extension_test_message_listener.h" | |
| 14 #include "extensions/test/result_catcher.h" | 15 #include "extensions/test/result_catcher.h" |
| 15 #include "net/test/embedded_test_server/embedded_test_server.h" | 16 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 16 | 17 |
| 17 // Tests the privileged components of chrome.runtime. | 18 // Tests the privileged components of chrome.runtime. |
| 18 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimePrivileged) { | 19 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimePrivileged) { |
| 19 ASSERT_TRUE(RunExtensionTest("runtime/privileged")) << message_; | 20 ASSERT_TRUE(RunExtensionTest("runtime/privileged")) << message_; |
| 20 } | 21 } |
| 21 | 22 |
| 22 // Tests the unprivileged components of chrome.runtime. | 23 // Tests the unprivileged components of chrome.runtime. |
| 23 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) { | 24 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ChromeRuntimeUnprivileged) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 break; | 122 break; |
| 122 } else { | 123 } else { |
| 123 load_observer.Wait(); | 124 load_observer.Wait(); |
| 124 WaitForExtensionViewsToLoad(); | 125 WaitForExtensionViewsToLoad(); |
| 125 } | 126 } |
| 126 } | 127 } |
| 127 ASSERT_TRUE( | 128 ASSERT_TRUE( |
| 128 registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED)); | 129 registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED)); |
| 129 } | 130 } |
| 130 | 131 |
| 132 namespace { | |
| 133 | |
| 134 // An intercepter of the real RuntimeAPIDelegate that simulates a successful | |
| 135 // restart request every time. | |
| 136 class RestartOnWatchdogApiDelegate : public RuntimeAPIDelegate { | |
| 137 public: | |
| 138 // Takes ownership of the |real_api_delegate|. | |
| 139 RestartOnWatchdogApiDelegate( | |
| 140 std::unique_ptr<RuntimeAPIDelegate> real_api_delegate) | |
| 141 : real_api_delegate_(std::move(real_api_delegate)) {} | |
| 142 ~RestartOnWatchdogApiDelegate() override {} | |
| 143 | |
| 144 // RuntimeAPIDelegate: | |
| 145 void AddUpdateObserver(UpdateObserver* observer) override { | |
| 146 real_api_delegate_->AddUpdateObserver(observer); | |
| 147 } | |
| 148 | |
| 149 void RemoveUpdateObserver(UpdateObserver* observer) override { | |
| 150 real_api_delegate_->RemoveUpdateObserver(observer); | |
| 151 } | |
| 152 | |
| 153 base::Version GetPreviousExtensionVersion( | |
| 154 const Extension* extension) override { | |
| 155 return real_api_delegate_->GetPreviousExtensionVersion(extension); | |
| 156 } | |
| 157 | |
| 158 void ReloadExtension(const std::string& extension_id) override { | |
| 159 real_api_delegate_->ReloadExtension(extension_id); | |
| 160 } | |
| 161 | |
| 162 bool CheckForUpdates(const std::string& extension_id, | |
| 163 const UpdateCheckCallback& callback) override { | |
| 164 return real_api_delegate_->CheckForUpdates(extension_id, callback); | |
| 165 } | |
| 166 | |
| 167 void OpenURL(const GURL& uninstall_url) override { | |
| 168 real_api_delegate_->OpenURL(uninstall_url); | |
| 169 } | |
| 170 | |
| 171 bool GetPlatformInfo(api::runtime::PlatformInfo* info) override { | |
| 172 return real_api_delegate_->GetPlatformInfo(info); | |
| 173 } | |
| 174 | |
| 175 bool RestartDevice(std::string* error_message) override { | |
| 176 if (!quit_closure_.is_null()) { | |
| 177 quit_closure_.Run(); | |
|
Devlin
2016/05/25 21:53:22
base::ResetAndReturn(&quit_closure_);
afakhry
2016/05/26 00:18:40
Done.
| |
| 178 quit_closure_.Reset(); | |
| 179 } | |
| 180 | |
| 181 *error_message = "Success."; | |
| 182 return true; | |
| 183 } | |
| 184 | |
| 185 base::TimeTicks WaitForSuccessfulRestart() { | |
| 186 base::RunLoop run_loop; | |
| 187 quit_closure_ = run_loop.QuitClosure(); | |
| 188 run_loop.Run(); | |
| 189 return base::TimeTicks::Now(); | |
| 190 } | |
| 191 | |
| 192 private: | |
| 193 std::unique_ptr<RuntimeAPIDelegate> real_api_delegate_; | |
| 194 | |
| 195 base::Closure quit_closure_; | |
| 196 | |
| 197 DISALLOW_COPY_AND_ASSIGN(RestartOnWatchdogApiDelegate); | |
| 198 }; | |
| 199 | |
| 200 } // namespace | |
| 201 | |
| 202 class RestartOnWatchdogApiTest : public ExtensionApiTest { | |
| 203 public: | |
| 204 RestartOnWatchdogApiTest() {} | |
| 205 ~RestartOnWatchdogApiTest() override {} | |
| 206 | |
| 207 void SetUpOnMainThread() override { | |
| 208 RuntimeAPI* runtime_api = RuntimeAPI::GetFactoryInstance()->Get(profile()); | |
| 209 api_delegate_ = | |
| 210 new RestartOnWatchdogApiDelegate(std::move(runtime_api->delegate_)); | |
| 211 runtime_api->delegate_.reset(api_delegate_); | |
| 212 runtime_api->SetMinDurationBetweenRestartsForTesting( | |
| 213 base::TimeDelta::FromSeconds(3)); | |
| 214 runtime_api->AllowNonKiostAppsInRestartOnWatchdogForTesting(); | |
| 215 | |
| 216 ExtensionApiTest::SetUpOnMainThread(); | |
|
Devlin
2016/05/25 21:53:22
nit: call this first
afakhry
2016/05/26 00:18:39
Done.
| |
| 217 } | |
| 218 | |
| 219 base::TimeTicks WaitForSuccessfulRestart() { | |
| 220 return api_delegate_->WaitForSuccessfulRestart(); | |
| 221 } | |
| 222 | |
| 223 bool IsWatchdogTimerRunning() { | |
| 224 return RuntimeAPI::GetFactoryInstance() | |
| 225 ->Get(profile()) | |
| 226 ->watchdog_timer_.IsRunning(); | |
| 227 } | |
| 228 | |
| 229 base::TimeTicks desired_restart_time() { | |
| 230 return RuntimeAPI::GetFactoryInstance() | |
| 231 ->Get(profile()) | |
| 232 ->watchdog_timer_.desired_run_time(); | |
| 233 } | |
| 234 | |
| 235 private: | |
| 236 RestartOnWatchdogApiDelegate* api_delegate_; // Not Owned. | |
| 237 | |
| 238 DISALLOW_COPY_AND_ASSIGN(RestartOnWatchdogApiTest); | |
| 239 }; | |
| 240 | |
| 241 IN_PROC_BROWSER_TEST_F(RestartOnWatchdogApiTest, RestartOnWatchdogTest) { | |
|
Devlin
2016/05/25 21:53:22
Now that you've simplified some of the tests a bit
afakhry
2016/05/26 00:18:40
For this tricky and sensitive API, I think we shou
Devlin
2016/05/27 15:26:36
Browser tests are orders of magnitude slower and f
afakhry
2016/06/01 18:44:18
Done.
| |
| 242 ASSERT_TRUE(StartEmbeddedTestServer()); | |
| 243 ExtensionTestMessageListener ready_listener("ready", true); | |
| 244 ExtensionTestMessageListener failure_listener("fail", false); | |
| 245 | |
| 246 ASSERT_TRUE( | |
| 247 LoadExtension(test_data_dir_.AppendASCII("runtime/restartOnWatchdog"))); | |
| 248 | |
| 249 // Run test1. | |
| 250 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 251 ready_listener.Reply("test1"); | |
| 252 ready_listener.Reset(); | |
| 253 | |
| 254 // Run test2. | |
| 255 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 256 ExtensionTestMessageListener request_1_listener("request1", true); | |
| 257 base::TimeTicks now = base::TimeTicks::Now(); | |
| 258 ready_listener.Reply("test2"); | |
| 259 ready_listener.Reset(); | |
| 260 ASSERT_TRUE(request_1_listener.WaitUntilSatisfied()); | |
| 261 ASSERT_TRUE(IsWatchdogTimerRunning()); | |
| 262 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(2)); | |
| 263 request_1_listener.Reply("proceed"); | |
| 264 | |
| 265 // Run test3 | |
| 266 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 267 ExtensionTestMessageListener request_2_listener("request2", true); | |
| 268 now = base::TimeTicks::Now(); | |
| 269 ready_listener.Reply("test3"); | |
| 270 ready_listener.Reset(); | |
| 271 ASSERT_TRUE(request_2_listener.WaitUntilSatisfied()); | |
| 272 ASSERT_TRUE(IsWatchdogTimerRunning()); | |
| 273 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(2)); | |
| 274 request_2_listener.Reply("proceed"); | |
| 275 | |
| 276 // Run test4. | |
| 277 // Calls the API with seconds = -1. All restart requests will be cancelled. | |
| 278 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 279 ExtensionTestMessageListener request_3_listener("request3", true); | |
| 280 ready_listener.Reply("test4"); | |
| 281 ready_listener.Reset(); | |
| 282 ASSERT_TRUE(request_3_listener.WaitUntilSatisfied()); | |
| 283 ASSERT_FALSE(IsWatchdogTimerRunning()); | |
| 284 request_3_listener.Reply("proceed"); | |
| 285 | |
| 286 // Run test5. | |
| 287 // Wait for a successful restart after 3 seconds. | |
| 288 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 289 ExtensionTestMessageListener request_4_listener("request4", true); | |
| 290 now = base::TimeTicks::Now(); | |
| 291 ready_listener.Reply("test5"); | |
| 292 ready_listener.Reset(); | |
| 293 ASSERT_TRUE(request_4_listener.WaitUntilSatisfied()); | |
| 294 ASSERT_TRUE(IsWatchdogTimerRunning()); | |
| 295 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(3)); | |
| 296 base::TimeTicks last_restart_time = WaitForSuccessfulRestart(); | |
| 297 ASSERT_FALSE(IsWatchdogTimerRunning()); | |
| 298 ASSERT_GE(base::TimeTicks::Now() - now, base::TimeDelta::FromSeconds(3)); | |
| 299 request_4_listener.Reply("proceed"); | |
| 300 | |
| 301 // Run test6. | |
| 302 // This is a restart request that will be throttled, because it happens too | |
| 303 // soon after a successful restart. | |
| 304 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 305 ExtensionTestMessageListener request_5_listener("request5", true); | |
| 306 ready_listener.Reply("test6"); | |
| 307 ready_listener.Reset(); | |
| 308 ASSERT_TRUE(request_5_listener.WaitUntilSatisfied()); | |
| 309 ASSERT_TRUE(IsWatchdogTimerRunning()); | |
| 310 // Restart will happen 3 seconds later, even though the request was just one | |
| 311 // second. | |
| 312 ASSERT_NEAR((desired_restart_time() - last_restart_time).InSecondsF(), | |
| 313 base::TimeDelta::FromSeconds(3).InSecondsF(), 0.01); | |
| 314 base::TimeTicks this_restart_time = WaitForSuccessfulRestart(); | |
| 315 ASSERT_FALSE(IsWatchdogTimerRunning()); | |
| 316 ASSERT_NEAR((this_restart_time - last_restart_time).InSecondsF(), | |
| 317 base::TimeDelta::FromSeconds(3).InSecondsF(), 0.01); | |
| 318 request_5_listener.Reply("proceed"); | |
| 319 | |
| 320 // Succeed. | |
| 321 ASSERT_TRUE(ready_listener.WaitUntilSatisfied()); | |
| 322 ready_listener.Reply("success"); | |
| 323 | |
| 324 ASSERT_FALSE(failure_listener.was_satisfied()); | |
| 325 } | |
| 326 | |
| 131 } // namespace extensions | 327 } // namespace extensions |
| OLD | NEW |