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

Side by Side Diff: chrome/browser/chromeos/power/renderer_freezer_unittest.cc

Issue 738993002: Re-land chromeos: Add non-extension renderers to the freezer cgroup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 6 years, 1 month 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
OLDNEW
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/chromeos/power/renderer_freezer.h" 5 #include "chrome/browser/chromeos/power/renderer_freezer.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
16 #include "chrome/browser/chromeos/settings/device_settings_service.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/extensions/test_extension_system.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
11 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
12 #include "chromeos/dbus/fake_power_manager_client.h" 23 #include "chromeos/dbus/fake_power_manager_client.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/site_instance.h"
28 #include "content/public/test/mock_render_process_host.h"
29 #include "content/public/test/test_browser_thread_bundle.h"
30 #include "extensions/browser/notification_types.h"
31 #include "extensions/browser/process_manager.h"
32 #include "extensions/browser/process_map.h"
33 #include "extensions/common/extension_builder.h"
34 #include "extensions/common/manifest_handlers/background_info.h"
35 #include "extensions/common/value_builder.h"
13 #include "testing/gtest/include/gtest/gtest-death-test.h" 36 #include "testing/gtest/include/gtest/gtest-death-test.h"
14 #include "testing/gtest/include/gtest/gtest.h" 37 #include "testing/gtest/include/gtest/gtest.h"
15 38
16 namespace chromeos { 39 namespace chromeos {
17 40
18 namespace { 41 namespace {
19 // Class that delegates used in testing can inherit from to record calls that 42 // Class that delegates used in testing can inherit from to record calls that
20 // are made by the code being tested. 43 // are made by the code being tested.
21 class ActionRecorder { 44 class ActionRecorder {
22 public: 45 public:
(...skipping 19 matching lines...) Expand all
42 } 65 }
43 66
44 private: 67 private:
45 // Comma-separated list of actions that have been performed. 68 // Comma-separated list of actions that have been performed.
46 std::string actions_; 69 std::string actions_;
47 70
48 DISALLOW_COPY_AND_ASSIGN(ActionRecorder); 71 DISALLOW_COPY_AND_ASSIGN(ActionRecorder);
49 }; 72 };
50 73
51 // Actions that can be returned by TestDelegate::GetActions(). 74 // Actions that can be returned by TestDelegate::GetActions().
75 const char kSetShouldFreezeRenderer[] = "set_should_freeze_renderer";
76 const char kSetShouldNotFreezeRenderer[] = "set_should_not_freeze_renderer";
52 const char kFreezeRenderers[] = "freeze_renderers"; 77 const char kFreezeRenderers[] = "freeze_renderers";
53 const char kThawRenderers[] = "thaw_renderers"; 78 const char kThawRenderers[] = "thaw_renderers";
54 const char kNoActions[] = ""; 79 const char kNoActions[] = "";
55 80
56 // Test implementation of RendererFreezer::Delegate that records the actions it 81 // Test implementation of RendererFreezer::Delegate that records the actions it
57 // was asked to perform. 82 // was asked to perform.
58 class TestDelegate : public RendererFreezer::Delegate, public ActionRecorder { 83 class TestDelegate : public RendererFreezer::Delegate, public ActionRecorder {
59 public: 84 public:
60 TestDelegate() 85 TestDelegate()
61 : can_freeze_renderers_(true), 86 : can_freeze_renderers_(true),
62 freeze_renderers_result_(true), 87 freeze_renderers_result_(true),
63 thaw_renderers_result_(true) {} 88 thaw_renderers_result_(true) {}
64 89
65 virtual ~TestDelegate() {} 90 ~TestDelegate() override {}
66 91
67 // RendererFreezer::Delegate overrides. 92 // RendererFreezer::Delegate overrides.
68 virtual bool FreezeRenderers() override { 93 void SetShouldFreezeRenderer(base::ProcessHandle handle,
94 bool frozen) override {
95 AppendAction(frozen ? kSetShouldFreezeRenderer
96 : kSetShouldNotFreezeRenderer);
97 }
98 bool FreezeRenderers() override {
69 AppendAction(kFreezeRenderers); 99 AppendAction(kFreezeRenderers);
70 100
71 return freeze_renderers_result_; 101 return freeze_renderers_result_;
72 } 102 }
73 virtual bool ThawRenderers() override { 103 bool ThawRenderers() override {
74 AppendAction(kThawRenderers); 104 AppendAction(kThawRenderers);
75 105
76 return thaw_renderers_result_; 106 return thaw_renderers_result_;
77 } 107 }
78 virtual bool CanFreezeRenderers() override { return can_freeze_renderers_; } 108 bool CanFreezeRenderers() override { return can_freeze_renderers_; }
79 109
80 void set_freeze_renderers_result(bool result) { 110 void set_freeze_renderers_result(bool result) {
81 freeze_renderers_result_ = result; 111 freeze_renderers_result_ = result;
82 } 112 }
83 113
84 void set_thaw_renderers_result(bool result) { 114 void set_thaw_renderers_result(bool result) {
85 thaw_renderers_result_ = result; 115 thaw_renderers_result_ = result;
86 } 116 }
87 117
88 // Sets whether the delegate is capable of freezing renderers. This also 118 // Sets whether the delegate is capable of freezing renderers. This also
(...skipping 19 matching lines...) Expand all
108 138
109 class RendererFreezerTest : public testing::Test { 139 class RendererFreezerTest : public testing::Test {
110 public: 140 public:
111 RendererFreezerTest() 141 RendererFreezerTest()
112 : power_manager_client_(new FakePowerManagerClient()), 142 : power_manager_client_(new FakePowerManagerClient()),
113 test_delegate_(new TestDelegate()) { 143 test_delegate_(new TestDelegate()) {
114 DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient( 144 DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
115 scoped_ptr<PowerManagerClient>(power_manager_client_)); 145 scoped_ptr<PowerManagerClient>(power_manager_client_));
116 } 146 }
117 147
118 virtual ~RendererFreezerTest() { 148 ~RendererFreezerTest() override {
119 renderer_freezer_.reset(); 149 renderer_freezer_.reset();
120 150
121 DBusThreadManager::Shutdown(); 151 DBusThreadManager::Shutdown();
122 } 152 }
123 153
154 protected:
124 void Init() { 155 void Init() {
125 renderer_freezer_.reset(new RendererFreezer( 156 renderer_freezer_.reset(new RendererFreezer(
126 scoped_ptr<RendererFreezer::Delegate>(test_delegate_))); 157 scoped_ptr<RendererFreezer::Delegate>(test_delegate_)));
127 } 158 }
128 159
129 protected: 160 // Owned by DBusThreadManager.
130 FakePowerManagerClient* power_manager_client_; 161 FakePowerManagerClient* power_manager_client_;
162
163 // Owned by |renderer_freezer_|.
131 TestDelegate* test_delegate_; 164 TestDelegate* test_delegate_;
132
133 scoped_ptr<RendererFreezer> renderer_freezer_; 165 scoped_ptr<RendererFreezer> renderer_freezer_;
134 166
135 private: 167 private:
136 base::MessageLoop message_loop_; 168 content::TestBrowserThreadBundle browser_thread_bundle_;
169
137 DISALLOW_COPY_AND_ASSIGN(RendererFreezerTest); 170 DISALLOW_COPY_AND_ASSIGN(RendererFreezerTest);
138 }; 171 };
139 172
140 // Tests that the RendererFreezer freezes renderers on suspend and thaws them on 173 // Tests that the RendererFreezer freezes renderers on suspend and thaws them on
141 // resume. 174 // resume.
142 TEST_F(RendererFreezerTest, SuspendResume) { 175 TEST_F(RendererFreezerTest, SuspendResume) {
143 Init(); 176 Init();
144 177
145 power_manager_client_->SendSuspendImminent(); 178 power_manager_client_->SendSuspendImminent();
146
147 // The RendererFreezer should have grabbed an asynchronous callback and done
148 // nothing else.
149 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
150 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
151
152 // The RendererFreezer should eventually freeze the renderers and run the
153 // callback.
154 base::RunLoop().RunUntilIdle();
155 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
156 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); 179 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions());
157 180
158 // The renderers should be thawed when we resume. 181 // The renderers should be thawed when we resume.
159 power_manager_client_->SendSuspendDone(); 182 power_manager_client_->SendSuspendDone();
160 EXPECT_EQ(kThawRenderers, test_delegate_->GetActions()); 183 EXPECT_EQ(kThawRenderers, test_delegate_->GetActions());
161 } 184 }
162 185
163 // Tests that the RendereFreezer doesn't freeze renderers if the suspend attempt
164 // was canceled before it had a chance to complete.
165 TEST_F(RendererFreezerTest, SuspendCanceled) {
166 Init();
167
168 // We shouldn't do anything yet.
169 power_manager_client_->SendSuspendImminent();
170 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
171
172 // If a suspend gets canceled for any reason, we should see a SuspendDone().
173 power_manager_client_->SendSuspendDone();
174
175 // We shouldn't try to freeze the renderers now.
176 base::RunLoop().RunUntilIdle();
177 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
178 }
179
180 // Tests that the renderer freezer does nothing if the delegate cannot freeze 186 // Tests that the renderer freezer does nothing if the delegate cannot freeze
181 // renderers. 187 // renderers.
182 TEST_F(RendererFreezerTest, DelegateCannotFreezeRenderers) { 188 TEST_F(RendererFreezerTest, DelegateCannotFreezeRenderers) {
183 test_delegate_->set_can_freeze_renderers(false); 189 test_delegate_->set_can_freeze_renderers(false);
184 Init(); 190 Init();
185 191
192 // Nothing happens on suspend.
186 power_manager_client_->SendSuspendImminent(); 193 power_manager_client_->SendSuspendImminent();
187
188 // The RendererFreezer should not have grabbed a callback or done anything
189 // else.
190 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
191 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
192
193 // There should be nothing in the message loop.
194 base::RunLoop().RunUntilIdle();
195 EXPECT_EQ(kNoActions, test_delegate_->GetActions()); 194 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
196 195
197 // Nothing happens on resume. 196 // Nothing happens on resume.
198 power_manager_client_->SendSuspendDone(); 197 power_manager_client_->SendSuspendDone();
199 EXPECT_EQ(kNoActions, test_delegate_->GetActions()); 198 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
200 } 199 }
201 200
202 // Tests that the RendererFreezer does nothing on resume if the freezing 201 // Tests that the RendererFreezer does nothing on resume if the freezing
203 // operation was unsuccessful. 202 // operation was unsuccessful.
204 TEST_F(RendererFreezerTest, ErrorFreezingRenderers) { 203 TEST_F(RendererFreezerTest, ErrorFreezingRenderers) {
205 Init(); 204 Init();
206 test_delegate_->set_freeze_renderers_result(false); 205 test_delegate_->set_freeze_renderers_result(false);
207 206
207 // The freezing operation will fail.
208 power_manager_client_->SendSuspendImminent(); 208 power_manager_client_->SendSuspendImminent();
209 EXPECT_EQ(1, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
210
211 // The freezing operation should fail, but we should still report readiness.
212 base::RunLoop().RunUntilIdle();
213 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); 209 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions());
214 EXPECT_EQ(0, power_manager_client_->GetNumPendingSuspendReadinessCallbacks());
215 210
216 // Since the delegate reported that the freezing was unsuccessful, don't do 211 // Since the delegate reported that the freezing was unsuccessful, don't do
217 // anything on resume. 212 // anything on resume.
218 power_manager_client_->SendSuspendDone(); 213 power_manager_client_->SendSuspendDone();
219 EXPECT_EQ(kNoActions, test_delegate_->GetActions()); 214 EXPECT_EQ(kNoActions, test_delegate_->GetActions());
220 } 215 }
221 216
222 #if defined(GTEST_HAS_DEATH_TEST) 217 #if defined(GTEST_HAS_DEATH_TEST)
223 // Tests that the RendererFreezer crashes the browser if the freezing operation 218 // Tests that the RendererFreezer crashes the browser if the freezing operation
224 // was successful but the thawing operation failed. 219 // was successful but the thawing operation failed.
225 TEST_F(RendererFreezerTest, ErrorThawingRenderers) { 220 TEST_F(RendererFreezerTest, ErrorThawingRenderers) {
221 // The "threadsafe" style of death test re-executes the unit test binary,
222 // which in turn re-initializes some global state leading to failed CHECKs.
223 // Instead, we use the "fast" style here to prevent re-initialization.
224 ::testing::FLAGS_gtest_death_test_style = "fast";
226 Init(); 225 Init();
227 test_delegate_->set_thaw_renderers_result(false); 226 test_delegate_->set_thaw_renderers_result(false);
228 227
229 power_manager_client_->SendSuspendImminent(); 228 power_manager_client_->SendSuspendImminent();
230 base::RunLoop().RunUntilIdle();
231 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions()); 229 EXPECT_EQ(kFreezeRenderers, test_delegate_->GetActions());
232 230
233 EXPECT_DEATH(power_manager_client_->SendSuspendDone(), "Unable to thaw"); 231 EXPECT_DEATH(power_manager_client_->SendSuspendDone(), "Unable to thaw");
234 } 232 }
235 #endif // GTEST_HAS_DEATH_TEST 233 #endif // GTEST_HAS_DEATH_TEST
236 234
235 class RendererFreezerTestWithExtensions : public RendererFreezerTest {
236 public:
237 RendererFreezerTestWithExtensions() {}
238 ~RendererFreezerTestWithExtensions() override {}
239
240 // testing::Test overrides.
241 void SetUp() override {
242 RendererFreezerTest::SetUp();
243
244 profile_manager_.reset(
245 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
246
247 // Must be called from testing::Test::SetUp.
248 EXPECT_TRUE(profile_manager_->SetUp());
249
250 profile_ = profile_manager_->CreateTestingProfile("RendererFreezerTest");
251
252 extensions::TestExtensionSystem* extension_system =
253 static_cast<extensions::TestExtensionSystem*>(
254 extensions::ExtensionSystem::Get(profile_));
255 extension_system->CreateExtensionService(
256 base::CommandLine::ForCurrentProcess(),
257 base::FilePath() /* install_directory */,
258 false /* autoupdate_enabled*/);
259 }
260 void TearDown() override {
261 extensions::ExtensionSystem::Get(profile_)->Shutdown();
262
263 profile_ = NULL;
264
265 profile_manager_->DeleteAllTestingProfiles();
266
267 base::RunLoop().RunUntilIdle();
268
269 profile_manager_.reset();
270
271 RendererFreezerTest::TearDown();
272 }
273
274 protected:
275 void CreateRenderProcessForExtension(extensions::Extension* extension) {
276 scoped_ptr<content::MockRenderProcessHostFactory> rph_factory(
277 new content::MockRenderProcessHostFactory());
278 scoped_refptr<content::SiteInstance> site_instance(
279 extensions::ProcessManager::Get(profile_)->GetSiteInstanceForURL(
280 extensions::BackgroundInfo::GetBackgroundURL(extension)));
281 scoped_ptr<content::RenderProcessHost> rph(
282 rph_factory->CreateRenderProcessHost(profile_, site_instance.get()));
283
284 // Fake that the RenderProcessHost is hosting the gcm app.
285 extensions::ProcessMap::Get(profile_)
286 ->Insert(extension->id(), rph->GetID(), site_instance->GetId());
287
288 // Send the notification that the RenderProcessHost has been created.
289 content::NotificationService::current()->Notify(
290 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
291 content::Source<content::RenderProcessHost>(rph.get()),
292 content::NotificationService::NoDetails());
293 }
294
295 // Owned by |profile_manager_|.
296 TestingProfile* profile_;
297 scoped_ptr<TestingProfileManager> profile_manager_;
298
299 private:
300 // Chrome OS needs extra services to run in the following order.
301 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
302 chromeos::ScopedTestCrosSettings test_cros_settings_;
303 chromeos::ScopedTestUserManager test_user_manager_;
304
305 DISALLOW_COPY_AND_ASSIGN(RendererFreezerTestWithExtensions);
306 };
307
308 // Tests that the RendererFreezer freezes renderers that are not hosting
309 // GCM extensions.
310 TEST_F(RendererFreezerTestWithExtensions, FreezesNonExtensionRenderers) {
311 Init();
312
313 // Create the mock RenderProcessHost.
314 scoped_ptr<content::MockRenderProcessHostFactory> rph_factory(
315 new content::MockRenderProcessHostFactory());
316 scoped_refptr<content::SiteInstance> site_instance(
317 content::SiteInstance::Create(profile_));
318 scoped_ptr<content::RenderProcessHost> rph(
319 rph_factory->CreateRenderProcessHost(profile_, site_instance.get()));
320
321 // Send the notification that the RenderProcessHost has been created.
322 content::NotificationService::current()->Notify(
323 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
324 content::Source<content::RenderProcessHost>(rph.get()),
325 content::NotificationService::NoDetails());
326
327 EXPECT_EQ(kSetShouldFreezeRenderer, test_delegate_->GetActions());
328 }
329
330 // Tests that the RendererFreezer does not freeze renderers that are hosting
331 // extensions that use GCM.
332 TEST_F(RendererFreezerTestWithExtensions, DoesNotFreezeGcmExtensionRenderers) {
333 Init();
334
335 // First build the GCM extension.
336 scoped_refptr<extensions::Extension> gcm_app =
337 extensions::ExtensionBuilder()
338 .SetManifest(extensions::DictionaryBuilder()
339 .Set("name", "GCM App")
340 .Set("version", "1.0.0")
341 .Set("manifest_version", 2)
342 .Set("app",
343 extensions::DictionaryBuilder()
344 .Set("background",
345 extensions::DictionaryBuilder()
346 .Set("scripts",
347 extensions::ListBuilder()
348 .Append("background.js"))))
349 .Set("permissions",
350 extensions::ListBuilder()
351 .Append("gcm")))
352 .Build();
353
354 // Now install it and give it a renderer.
355 extensions::ExtensionSystem::Get(profile_)
356 ->extension_service()
357 ->AddExtension(gcm_app.get());
358 CreateRenderProcessForExtension(gcm_app.get());
359
360 EXPECT_EQ(kSetShouldNotFreezeRenderer, test_delegate_->GetActions());
361 }
362
363 // Tests that the RendererFreezer freezes renderers that are hosting extensions
364 // that do not use GCM.
365 TEST_F(RendererFreezerTestWithExtensions, FreezesNonGcmExtensionRenderers) {
366 Init();
367
368 // First build the extension.
369 scoped_refptr<extensions::Extension> background_app =
370 extensions::ExtensionBuilder()
371 .SetManifest(extensions::DictionaryBuilder()
372 .Set("name", "Background App")
373 .Set("version", "1.0.0")
374 .Set("manifest_version", 2)
375 .Set("app",
376 extensions::DictionaryBuilder()
377 .Set("background",
378 extensions::DictionaryBuilder()
379 .Set("scripts",
380 extensions::ListBuilder()
381 .Append("background.js")))))
382 .Build();
383
384 // Now install it and give it a renderer.
385 extensions::ExtensionSystem::Get(profile_)
386 ->extension_service()
387 ->AddExtension(background_app.get());
388 CreateRenderProcessForExtension(background_app.get());
389
390 EXPECT_EQ(kSetShouldFreezeRenderer, test_delegate_->GetActions());
391 }
392
237 } // namespace chromeos 393 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/power/renderer_freezer.cc ('k') | chromeos/dbus/fake_power_manager_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698