Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Unified Diff: extensions/browser/api/runtime/runtime_apitest.cc

Issue 1970613003: Add a new app API to enable watchdog behavior restarts in kiosk apps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + Devlin's comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/browser/api/runtime/runtime_apitest.cc
diff --git a/extensions/browser/api/runtime/runtime_apitest.cc b/extensions/browser/api/runtime/runtime_apitest.cc
index 78f5998cffdfeb6d73146667599f22e28ffcdfc1..4585d6368cf054c9522d52ff7623a0df3cca00b3 100644
--- a/extensions/browser/api/runtime/runtime_apitest.cc
+++ b/extensions/browser/api/runtime/runtime_apitest.cc
@@ -11,6 +11,7 @@
#include "extensions/browser/api/runtime/runtime_api.h"
#include "extensions/browser/extension_dialog_auto_confirm.h"
#include "extensions/browser/extension_registry.h"
+#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -128,4 +129,199 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_ChromeRuntimeReload) {
registry->GetExtensionById(extension_id, ExtensionRegistry::TERMINATED));
}
+namespace {
+
+// An intercepter of the real RuntimeAPIDelegate that simulates a successful
+// restart request every time.
+class RestartOnWatchdogApiDelegate : public RuntimeAPIDelegate {
+ public:
+ // Takes ownership of the |real_api_delegate|.
+ RestartOnWatchdogApiDelegate(
+ std::unique_ptr<RuntimeAPIDelegate> real_api_delegate)
+ : real_api_delegate_(std::move(real_api_delegate)) {}
+ ~RestartOnWatchdogApiDelegate() override {}
+
+ // RuntimeAPIDelegate:
+ void AddUpdateObserver(UpdateObserver* observer) override {
+ real_api_delegate_->AddUpdateObserver(observer);
+ }
+
+ void RemoveUpdateObserver(UpdateObserver* observer) override {
+ real_api_delegate_->RemoveUpdateObserver(observer);
+ }
+
+ base::Version GetPreviousExtensionVersion(
+ const Extension* extension) override {
+ return real_api_delegate_->GetPreviousExtensionVersion(extension);
+ }
+
+ void ReloadExtension(const std::string& extension_id) override {
+ real_api_delegate_->ReloadExtension(extension_id);
+ }
+
+ bool CheckForUpdates(const std::string& extension_id,
+ const UpdateCheckCallback& callback) override {
+ return real_api_delegate_->CheckForUpdates(extension_id, callback);
+ }
+
+ void OpenURL(const GURL& uninstall_url) override {
+ real_api_delegate_->OpenURL(uninstall_url);
+ }
+
+ bool GetPlatformInfo(api::runtime::PlatformInfo* info) override {
+ return real_api_delegate_->GetPlatformInfo(info);
+ }
+
+ bool RestartDevice(std::string* error_message) override {
+ if (!quit_closure_.is_null()) {
+ quit_closure_.Run();
Devlin 2016/05/25 21:53:22 base::ResetAndReturn(&quit_closure_);
afakhry 2016/05/26 00:18:40 Done.
+ quit_closure_.Reset();
+ }
+
+ *error_message = "Success.";
+ return true;
+ }
+
+ base::TimeTicks WaitForSuccessfulRestart() {
+ base::RunLoop run_loop;
+ quit_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+ return base::TimeTicks::Now();
+ }
+
+ private:
+ std::unique_ptr<RuntimeAPIDelegate> real_api_delegate_;
+
+ base::Closure quit_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(RestartOnWatchdogApiDelegate);
+};
+
+} // namespace
+
+class RestartOnWatchdogApiTest : public ExtensionApiTest {
+ public:
+ RestartOnWatchdogApiTest() {}
+ ~RestartOnWatchdogApiTest() override {}
+
+ void SetUpOnMainThread() override {
+ RuntimeAPI* runtime_api = RuntimeAPI::GetFactoryInstance()->Get(profile());
+ api_delegate_ =
+ new RestartOnWatchdogApiDelegate(std::move(runtime_api->delegate_));
+ runtime_api->delegate_.reset(api_delegate_);
+ runtime_api->SetMinDurationBetweenRestartsForTesting(
+ base::TimeDelta::FromSeconds(3));
+ runtime_api->AllowNonKiostAppsInRestartOnWatchdogForTesting();
+
+ ExtensionApiTest::SetUpOnMainThread();
Devlin 2016/05/25 21:53:22 nit: call this first
afakhry 2016/05/26 00:18:39 Done.
+ }
+
+ base::TimeTicks WaitForSuccessfulRestart() {
+ return api_delegate_->WaitForSuccessfulRestart();
+ }
+
+ bool IsWatchdogTimerRunning() {
+ return RuntimeAPI::GetFactoryInstance()
+ ->Get(profile())
+ ->watchdog_timer_.IsRunning();
+ }
+
+ base::TimeTicks desired_restart_time() {
+ return RuntimeAPI::GetFactoryInstance()
+ ->Get(profile())
+ ->watchdog_timer_.desired_run_time();
+ }
+
+ private:
+ RestartOnWatchdogApiDelegate* api_delegate_; // Not Owned.
+
+ DISALLOW_COPY_AND_ASSIGN(RestartOnWatchdogApiTest);
+};
+
+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.
+ ASSERT_TRUE(StartEmbeddedTestServer());
+ ExtensionTestMessageListener ready_listener("ready", true);
+ ExtensionTestMessageListener failure_listener("fail", false);
+
+ ASSERT_TRUE(
+ LoadExtension(test_data_dir_.AppendASCII("runtime/restartOnWatchdog")));
+
+ // Run test1.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ready_listener.Reply("test1");
+ ready_listener.Reset();
+
+ // Run test2.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener request_1_listener("request1", true);
+ base::TimeTicks now = base::TimeTicks::Now();
+ ready_listener.Reply("test2");
+ ready_listener.Reset();
+ ASSERT_TRUE(request_1_listener.WaitUntilSatisfied());
+ ASSERT_TRUE(IsWatchdogTimerRunning());
+ ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(2));
+ request_1_listener.Reply("proceed");
+
+ // Run test3
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener request_2_listener("request2", true);
+ now = base::TimeTicks::Now();
+ ready_listener.Reply("test3");
+ ready_listener.Reset();
+ ASSERT_TRUE(request_2_listener.WaitUntilSatisfied());
+ ASSERT_TRUE(IsWatchdogTimerRunning());
+ ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(2));
+ request_2_listener.Reply("proceed");
+
+ // Run test4.
+ // Calls the API with seconds = -1. All restart requests will be cancelled.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener request_3_listener("request3", true);
+ ready_listener.Reply("test4");
+ ready_listener.Reset();
+ ASSERT_TRUE(request_3_listener.WaitUntilSatisfied());
+ ASSERT_FALSE(IsWatchdogTimerRunning());
+ request_3_listener.Reply("proceed");
+
+ // Run test5.
+ // Wait for a successful restart after 3 seconds.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener request_4_listener("request4", true);
+ now = base::TimeTicks::Now();
+ ready_listener.Reply("test5");
+ ready_listener.Reset();
+ ASSERT_TRUE(request_4_listener.WaitUntilSatisfied());
+ ASSERT_TRUE(IsWatchdogTimerRunning());
+ ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(3));
+ base::TimeTicks last_restart_time = WaitForSuccessfulRestart();
+ ASSERT_FALSE(IsWatchdogTimerRunning());
+ ASSERT_GE(base::TimeTicks::Now() - now, base::TimeDelta::FromSeconds(3));
+ request_4_listener.Reply("proceed");
+
+ // Run test6.
+ // This is a restart request that will be throttled, because it happens too
+ // soon after a successful restart.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener request_5_listener("request5", true);
+ ready_listener.Reply("test6");
+ ready_listener.Reset();
+ ASSERT_TRUE(request_5_listener.WaitUntilSatisfied());
+ ASSERT_TRUE(IsWatchdogTimerRunning());
+ // Restart will happen 3 seconds later, even though the request was just one
+ // second.
+ ASSERT_NEAR((desired_restart_time() - last_restart_time).InSecondsF(),
+ base::TimeDelta::FromSeconds(3).InSecondsF(), 0.01);
+ base::TimeTicks this_restart_time = WaitForSuccessfulRestart();
+ ASSERT_FALSE(IsWatchdogTimerRunning());
+ ASSERT_NEAR((this_restart_time - last_restart_time).InSecondsF(),
+ base::TimeDelta::FromSeconds(3).InSecondsF(), 0.01);
+ request_5_listener.Reply("proceed");
+
+ // Succeed.
+ ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
+ ready_listener.Reply("success");
+
+ ASSERT_FALSE(failure_listener.was_satisfied());
+}
+
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698