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

Side by Side Diff: extensions/browser/api/runtime/restart_after_delay_api_unittest.cc

Issue 2070753003: Revert "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: Created 4 years, 6 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/prefs/browser_prefs.cc ('k') | extensions/browser/api/runtime/runtime_api.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/callback_helpers.h"
6 #include "base/run_loop.h"
7 #include "components/pref_registry/pref_registry_syncable.h"
8 #include "components/pref_registry/testing_pref_service_syncable.h"
9 #include "extensions/browser/api/runtime/runtime_api.h"
10 #include "extensions/browser/api_test_utils.h"
11 #include "extensions/browser/api_unittest.h"
12 #include "extensions/browser/test_extensions_browser_client.h"
13 #include "extensions/browser/test_runtime_api_delegate.h"
14 #include "extensions/common/manifest.h"
15
16 namespace extensions {
17
18 namespace {
19
20 // A RuntimeAPIDelegate that simulates a successful restart request every time.
21 class DelayedRestartTestApiDelegate : public TestRuntimeAPIDelegate {
22 public:
23 DelayedRestartTestApiDelegate() {}
24 ~DelayedRestartTestApiDelegate() override {}
25
26 // TestRuntimeAPIDelegate:
27 bool RestartDevice(std::string* error_message) override {
28 if (!quit_closure_.is_null())
29 base::ResetAndReturn(&quit_closure_).Run();
30
31 *error_message = "Success.";
32 restart_done_ = true;
33
34 return true;
35 }
36
37 base::TimeTicks WaitForSuccessfulRestart() {
38 if (!restart_done_) {
39 base::RunLoop run_loop;
40 quit_closure_ = run_loop.QuitClosure();
41 run_loop.Run();
42 }
43 restart_done_ = false;
44 return base::TimeTicks::Now();
45 }
46
47 private:
48 base::Closure quit_closure_;
49
50 bool restart_done_ = false;
51
52 DISALLOW_COPY_AND_ASSIGN(DelayedRestartTestApiDelegate);
53 };
54
55 class DelayedRestartExtensionsBrowserClient
56 : public TestExtensionsBrowserClient {
57 public:
58 DelayedRestartExtensionsBrowserClient(content::BrowserContext* context)
59 : TestExtensionsBrowserClient(context) {}
60 ~DelayedRestartExtensionsBrowserClient() override {}
61
62 // TestExtensionsBrowserClient:
63 PrefService* GetPrefServiceForContext(
64 content::BrowserContext* context) override {
65 return &testing_pref_service_;
66 }
67
68 std::unique_ptr<RuntimeAPIDelegate> CreateRuntimeAPIDelegate(
69 content::BrowserContext* context) const override {
70 const_cast<DelayedRestartExtensionsBrowserClient*>(this)->api_delegate_ =
71 new DelayedRestartTestApiDelegate();
72 return base::WrapUnique(api_delegate_);
73 }
74
75 user_prefs::TestingPrefServiceSyncable* testing_pref_service() {
76 return &testing_pref_service_;
77 }
78
79 DelayedRestartTestApiDelegate* api_delegate() const {
80 CHECK(api_delegate_);
81 return api_delegate_;
82 }
83
84 private:
85 DelayedRestartTestApiDelegate* api_delegate_ = nullptr; // Not owned.
86
87 user_prefs::TestingPrefServiceSyncable testing_pref_service_;
88
89 DISALLOW_COPY_AND_ASSIGN(DelayedRestartExtensionsBrowserClient);
90 };
91
92 } // namespace
93
94 class RestartAfterDelayApiTest : public ApiUnitTest {
95 public:
96 RestartAfterDelayApiTest() {}
97 ~RestartAfterDelayApiTest() override {}
98
99 void SetUp() override {
100 ApiUnitTest::SetUp();
101
102 // Use our ExtensionsBrowserClient that returns our RuntimeAPIDelegate.
103 test_browser_client_.reset(
104 new DelayedRestartExtensionsBrowserClient(browser_context()));
105 test_browser_client_->set_extension_system_factory(
106 extensions_browser_client()->extension_system_factory());
107 ExtensionsBrowserClient::Set(test_browser_client_.get());
108
109 // The RuntimeAPI should only be accessed (i.e. constructed) after the above
110 // ExtensionsBrowserClient has been setup.
111 RuntimeAPI* runtime_api =
112 RuntimeAPI::GetFactoryInstance()->Get(browser_context());
113 runtime_api->set_min_duration_between_restarts_for_testing(
114 base::TimeDelta::FromSeconds(2));
115 runtime_api->AllowNonKioskAppsInRestartAfterDelayForTesting();
116
117 RuntimeAPI::RegisterPrefs(
118 test_browser_client_->testing_pref_service()->registry());
119 }
120
121 base::TimeTicks WaitForSuccessfulRestart() {
122 return test_browser_client_->api_delegate()->WaitForSuccessfulRestart();
123 }
124
125 bool IsDelayedRestartTimerRunning() {
126 return RuntimeAPI::GetFactoryInstance()
127 ->Get(browser_context())
128 ->restart_after_delay_timer_.IsRunning();
129 }
130
131 base::TimeTicks desired_restart_time() {
132 return RuntimeAPI::GetFactoryInstance()
133 ->Get(browser_context())
134 ->restart_after_delay_timer_.desired_run_time();
135 }
136
137 void RunRestartAfterDelayFunction(const std::string& args,
138 const std::string& expected_error) {
139 RunRestartAfterDelayFunctionForExtention(args, extension(), expected_error);
140 }
141
142 void RunRestartAfterDelayFunctionForExtention(
143 const std::string& args,
144 const Extension* extension,
145 const std::string& expected_error) {
146 std::string error = RunFunctionGetError(
147 new RuntimeRestartAfterDelayFunction(), extension, args);
148 ASSERT_EQ(error, expected_error);
149 }
150
151 void RunRestartFunctionAssertNoError() {
152 std::string error =
153 RunFunctionGetError(new RuntimeRestartFunction(), extension(), "[]");
154 ASSERT_TRUE(error.empty()) << error;
155 }
156
157 private:
158 std::string RunFunctionGetError(UIThreadExtensionFunction* function,
159 const Extension* extension,
160 const std::string& args) {
161 scoped_refptr<ExtensionFunction> function_owner(function);
162 function->set_extension(extension);
163 function->set_has_callback(true);
164 api_test_utils::RunFunction(function, args, browser_context());
165 return function->GetError();
166 }
167
168 std::unique_ptr<DelayedRestartExtensionsBrowserClient> test_browser_client_;
169
170 DISALLOW_COPY_AND_ASSIGN(RestartAfterDelayApiTest);
171 };
172
173 TEST_F(RestartAfterDelayApiTest, RestartAfterDelayTest) {
174 RunRestartAfterDelayFunction("[-1]", "");
175 ASSERT_FALSE(IsDelayedRestartTimerRunning());
176
177 RunRestartAfterDelayFunction("[-2]", "Invalid argument: -2.");
178
179 // Request a restart after 3 seconds.
180 base::TimeTicks now = base::TimeTicks::Now();
181 RunRestartAfterDelayFunction("[3]", "");
182 ASSERT_TRUE(IsDelayedRestartTimerRunning());
183 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(3));
184
185 // Request another restart after 4 seconds. It should reschedule the previous
186 // request.
187 now = base::TimeTicks::Now();
188 RunRestartAfterDelayFunction("[4]", "");
189 ASSERT_TRUE(IsDelayedRestartTimerRunning());
190 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(4));
191
192 // Create another extension and make it attempt to use the api, and expect a
193 // failure.
194 std::unique_ptr<base::DictionaryValue> test_extension_value(
195 api_test_utils::ParseDictionary("{\n"
196 " \"name\": \"Test\",\n"
197 " \"version\": \"2.0\",\n"
198 " \"app\": {\n"
199 " \"background\": {\n"
200 " \"scripts\": [\"background.js\"]\n"
201 " }\n"
202 " }\n"
203 "}"));
204 scoped_refptr<Extension> test_extension(api_test_utils::CreateExtension(
205 Manifest::INTERNAL, test_extension_value.get(), "id2"));
206 RunRestartAfterDelayFunctionForExtention(
207 "[5]", test_extension.get(), "Not the first extension to call this API.");
208
209 // Cancel restart requests.
210 RunRestartAfterDelayFunction("[-1]", "");
211 ASSERT_FALSE(IsDelayedRestartTimerRunning());
212
213 // Schedule a restart and wait for it to happen.
214 now = base::TimeTicks::Now();
215 RunRestartAfterDelayFunction("[1]", "");
216 ASSERT_TRUE(IsDelayedRestartTimerRunning());
217 ASSERT_GE(desired_restart_time() - now, base::TimeDelta::FromSeconds(1));
218 base::TimeTicks last_restart_time = WaitForSuccessfulRestart();
219 ASSERT_FALSE(IsDelayedRestartTimerRunning());
220 ASSERT_GE(base::TimeTicks::Now() - now, base::TimeDelta::FromSeconds(1));
221
222 // This is a restart request that will be throttled, because it happens too
223 // soon after a successful restart.
224 RunRestartAfterDelayFunction(
225 "[1]", "Restart was requested too soon. It was throttled instead.");
226 ASSERT_TRUE(IsDelayedRestartTimerRunning());
227 // Restart will happen 2 seconds later, even though the request was just one
228 // second.
229 ASSERT_NEAR((desired_restart_time() - last_restart_time).InSecondsF(),
230 base::TimeDelta::FromSeconds(2).InSecondsF(), 0.01);
231
232 // Calling chrome.runtime.restart() will not clear the throttle, and any
233 // subsequent calls to chrome.runtime.restartAfterDelay will still be
234 // throttled.
235 WaitForSuccessfulRestart();
236 RunRestartFunctionAssertNoError();
237 last_restart_time = WaitForSuccessfulRestart();
238 RunRestartAfterDelayFunction(
239 "[1]", "Restart was requested too soon. It was throttled instead.");
240 ASSERT_TRUE(IsDelayedRestartTimerRunning());
241 // Restart will happen 2 seconds later, even though the request was just one
242 // second.
243 ASSERT_NEAR((desired_restart_time() - last_restart_time).InSecondsF(),
244 base::TimeDelta::FromSeconds(2).InSecondsF(), 0.01);
245 }
246
247 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/prefs/browser_prefs.cc ('k') | extensions/browser/api/runtime/runtime_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698