Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_crash_recovery_browsertest.cc
blobcccf918c96fba5b53bf199b25ec9e46921dabd3b
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
3 // found in the LICENSE file.
5 #include "chrome/browser/browser_process.h"
6 #include "chrome/browser/extensions/extension_browsertest.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/notifications/notification.h"
9 #include "chrome/browser/notifications/notification_delegate.h"
10 #include "chrome/browser/notifications/notification_ui_manager.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/result_codes.h"
21 #include "extensions/browser/extension_host.h"
22 #include "extensions/browser/extension_registry.h"
23 #include "extensions/browser/extension_system.h"
24 #include "extensions/browser/process_manager.h"
25 #include "extensions/browser/process_map.h"
26 #include "ui/message_center/message_center.h"
27 #include "ui/message_center/notification_list.h"
29 using content::NavigationController;
30 using content::WebContents;
31 using extensions::Extension;
32 using extensions::ExtensionRegistry;
34 // Tests are timing out waiting for extension to crash.
35 // http://crbug.com/174705
36 #if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
37 #define MAYBE_ExtensionCrashRecoveryTest DISABLED_ExtensionCrashRecoveryTest
38 #else
39 #define MAYBE_ExtensionCrashRecoveryTest ExtensionCrashRecoveryTest
40 #endif // defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
42 class ExtensionCrashRecoveryTestBase : public ExtensionBrowserTest {
43 protected:
44 virtual void AcceptNotification(size_t index) = 0;
45 virtual void CancelNotification(size_t index) = 0;
46 virtual size_t CountBalloons() = 0;
48 ExtensionService* GetExtensionService() {
49 return browser()->profile()->GetExtensionService();
52 extensions::ProcessManager* GetProcessManager() {
53 return extensions::ExtensionSystem::Get(browser()->profile())->
54 process_manager();
57 ExtensionRegistry* GetExtensionRegistry() {
58 return ExtensionRegistry::Get(browser()->profile());
61 size_t GetEnabledExtensionCount() {
62 return GetExtensionRegistry()->enabled_extensions().size();
65 size_t GetTerminatedExtensionCount() {
66 return GetExtensionRegistry()->terminated_extensions().size();
69 void CrashExtension(const std::string& extension_id) {
70 const Extension* extension = GetExtensionRegistry()->GetExtensionById(
71 extension_id, ExtensionRegistry::ENABLED);
72 ASSERT_TRUE(extension);
73 extensions::ExtensionHost* extension_host = GetProcessManager()->
74 GetBackgroundHostForExtension(extension_id);
75 ASSERT_TRUE(extension_host);
77 base::KillProcess(extension_host->render_process_host()->GetHandle(),
78 content::RESULT_CODE_KILLED, false);
79 ASSERT_TRUE(WaitForExtensionCrash(extension_id));
80 ASSERT_FALSE(GetProcessManager()->
81 GetBackgroundHostForExtension(extension_id));
83 // Wait for extension crash balloon to appear.
84 base::MessageLoop::current()->RunUntilIdle();
87 void CheckExtensionConsistency(const std::string& extension_id) {
88 const Extension* extension = GetExtensionRegistry()->GetExtensionById(
89 extension_id, ExtensionRegistry::ENABLED);
90 ASSERT_TRUE(extension);
91 extensions::ExtensionHost* extension_host = GetProcessManager()->
92 GetBackgroundHostForExtension(extension_id);
93 ASSERT_TRUE(extension_host);
94 extensions::ProcessManager::ViewSet all_views =
95 GetProcessManager()->GetAllViews();
96 extensions::ProcessManager::ViewSet::const_iterator it =
97 all_views.find(extension_host->host_contents()->GetRenderViewHost());
98 ASSERT_FALSE(it == all_views.end());
99 ASSERT_TRUE(extension_host->IsRenderViewLive());
100 extensions::ProcessMap* process_map =
101 extensions::ProcessMap::Get(browser()->profile());
102 ASSERT_TRUE(process_map->Contains(
103 extension_id,
104 extension_host->render_view_host()->GetProcess()->GetID()));
107 void LoadTestExtension() {
108 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
109 const Extension* extension = LoadExtension(
110 test_data_dir_.AppendASCII("common").AppendASCII("background_page"));
111 ASSERT_TRUE(extension);
112 first_extension_id_ = extension->id();
113 CheckExtensionConsistency(first_extension_id_);
116 void LoadSecondExtension() {
117 const Extension* extension = LoadExtension(
118 test_data_dir_.AppendASCII("install").AppendASCII("install"));
119 ASSERT_TRUE(extension);
120 second_extension_id_ = extension->id();
121 CheckExtensionConsistency(second_extension_id_);
124 std::string first_extension_id_;
125 std::string second_extension_id_;
128 class MAYBE_ExtensionCrashRecoveryTest
129 : public ExtensionCrashRecoveryTestBase {
130 protected:
131 virtual void AcceptNotification(size_t index) OVERRIDE {
132 message_center::MessageCenter* message_center =
133 message_center::MessageCenter::Get();
134 ASSERT_GT(message_center->NotificationCount(), index);
135 message_center::NotificationList::Notifications::reverse_iterator it =
136 message_center->GetVisibleNotifications().rbegin();
137 for (size_t i=0; i < index; ++i)
138 it++;
139 std::string id = (*it)->id();
140 message_center->ClickOnNotification(id);
141 WaitForExtensionLoad();
144 virtual void CancelNotification(size_t index) OVERRIDE {
145 message_center::MessageCenter* message_center =
146 message_center::MessageCenter::Get();
147 ASSERT_GT(message_center->NotificationCount(), index);
148 message_center::NotificationList::Notifications::reverse_iterator it =
149 message_center->GetVisibleNotifications().rbegin();
150 for (size_t i=0; i < index; i++) { it++; }
151 ASSERT_TRUE(g_browser_process->notification_ui_manager()->
152 CancelById((*it)->id()));
155 virtual size_t CountBalloons() OVERRIDE {
156 return message_center::MessageCenter::Get()->NotificationCount();
160 // Flaky: http://crbug.com/242167.
161 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, DISABLED_Basic) {
162 const size_t count_before = GetEnabledExtensionCount();
163 const size_t crash_count_before = GetTerminatedExtensionCount();
164 LoadTestExtension();
165 CrashExtension(first_extension_id_);
166 ASSERT_EQ(count_before, GetEnabledExtensionCount());
167 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
168 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
170 SCOPED_TRACE("after clicking the balloon");
171 CheckExtensionConsistency(first_extension_id_);
172 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
175 // Flaky, http://crbug.com/241191.
176 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
177 DISABLED_CloseAndReload) {
178 const size_t count_before = GetEnabledExtensionCount();
179 const size_t crash_count_before = GetTerminatedExtensionCount();
180 LoadTestExtension();
181 CrashExtension(first_extension_id_);
183 ASSERT_EQ(count_before, GetEnabledExtensionCount());
184 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
186 ASSERT_NO_FATAL_FAILURE(CancelNotification(0));
187 ReloadExtension(first_extension_id_);
189 SCOPED_TRACE("after reloading");
190 CheckExtensionConsistency(first_extension_id_);
191 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
194 // Test is timing out on Windows http://crbug.com/174705.
195 #if defined(OS_WIN)
196 #define MAYBE_ReloadIndependently DISABLED_ReloadIndependently
197 #else
198 #define MAYBE_ReloadIndependently ReloadIndependently
199 #endif // defined(OS_WIN)
200 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
201 MAYBE_ReloadIndependently) {
202 const size_t count_before = GetEnabledExtensionCount();
203 LoadTestExtension();
204 CrashExtension(first_extension_id_);
205 ASSERT_EQ(count_before, GetEnabledExtensionCount());
207 ReloadExtension(first_extension_id_);
209 SCOPED_TRACE("after reloading");
210 CheckExtensionConsistency(first_extension_id_);
212 WebContents* current_tab =
213 browser()->tab_strip_model()->GetActiveWebContents();
214 ASSERT_TRUE(current_tab);
216 // The balloon should automatically hide after the extension is successfully
217 // reloaded.
218 ASSERT_EQ(0U, CountBalloons());
221 // Test is timing out on Windows http://crbug.com/174705.
222 #if defined(OS_WIN)
223 #define MAYBE_ReloadIndependentlyChangeTabs DISABLED_ReloadIndependentlyChangeTabs
224 #else
225 #define MAYBE_ReloadIndependentlyChangeTabs ReloadIndependentlyChangeTabs
226 #endif // defined(OS_WIN)
228 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
229 MAYBE_ReloadIndependentlyChangeTabs) {
230 const size_t count_before = GetEnabledExtensionCount();
231 LoadTestExtension();
232 CrashExtension(first_extension_id_);
233 ASSERT_EQ(count_before, GetEnabledExtensionCount());
235 WebContents* original_tab =
236 browser()->tab_strip_model()->GetActiveWebContents();
237 ASSERT_TRUE(original_tab);
238 ASSERT_EQ(1U, CountBalloons());
240 // Open a new tab, but the balloon will still be there.
241 chrome::NewTab(browser());
242 WebContents* new_current_tab =
243 browser()->tab_strip_model()->GetActiveWebContents();
244 ASSERT_TRUE(new_current_tab);
245 ASSERT_NE(new_current_tab, original_tab);
246 ASSERT_EQ(1U, CountBalloons());
248 ReloadExtension(first_extension_id_);
250 SCOPED_TRACE("after reloading");
251 CheckExtensionConsistency(first_extension_id_);
253 // The balloon should automatically hide after the extension is successfully
254 // reloaded.
255 ASSERT_EQ(0U, CountBalloons());
258 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
259 DISABLED_ReloadIndependentlyNavigatePage) {
260 const size_t count_before = GetEnabledExtensionCount();
261 LoadTestExtension();
262 CrashExtension(first_extension_id_);
263 ASSERT_EQ(count_before, GetEnabledExtensionCount());
265 WebContents* current_tab =
266 browser()->tab_strip_model()->GetActiveWebContents();
267 ASSERT_TRUE(current_tab);
268 ASSERT_EQ(1U, CountBalloons());
270 // Navigate to another page.
271 ui_test_utils::NavigateToURL(
272 browser(), ui_test_utils::GetTestUrl(
273 base::FilePath(base::FilePath::kCurrentDirectory),
274 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
275 ASSERT_EQ(1U, CountBalloons());
277 ReloadExtension(first_extension_id_);
279 SCOPED_TRACE("after reloading");
280 CheckExtensionConsistency(first_extension_id_);
282 // The balloon should automatically hide after the extension is successfully
283 // reloaded.
284 ASSERT_EQ(0U, CountBalloons());
287 // Make sure that when we don't do anything about the crashed extension
288 // and close the browser, it doesn't crash. The browser is closed implicitly
289 // at the end of each browser test.
291 // http://crbug.com/84719
292 #if defined(OS_LINUX)
293 #define MAYBE_ShutdownWhileCrashed DISABLED_ShutdownWhileCrashed
294 #else
295 #define MAYBE_ShutdownWhileCrashed ShutdownWhileCrashed
296 #endif // defined(OS_LINUX)
298 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
299 MAYBE_ShutdownWhileCrashed) {
300 const size_t count_before = GetEnabledExtensionCount();
301 LoadTestExtension();
302 CrashExtension(first_extension_id_);
303 ASSERT_EQ(count_before, GetEnabledExtensionCount());
306 // Flaky, http://crbug.com/241245.
307 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
308 DISABLED_TwoExtensionsCrashFirst) {
309 const size_t count_before = GetEnabledExtensionCount();
310 LoadTestExtension();
311 LoadSecondExtension();
312 CrashExtension(first_extension_id_);
313 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
314 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
316 SCOPED_TRACE("after clicking the balloon");
317 CheckExtensionConsistency(first_extension_id_);
318 CheckExtensionConsistency(second_extension_id_);
321 // Flaky: http://crbug.com/242196
322 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
323 DISABLED_TwoExtensionsCrashSecond) {
324 const size_t count_before = GetEnabledExtensionCount();
325 LoadTestExtension();
326 LoadSecondExtension();
327 CrashExtension(second_extension_id_);
328 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
329 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
331 SCOPED_TRACE("after clicking the balloon");
332 CheckExtensionConsistency(first_extension_id_);
333 CheckExtensionConsistency(second_extension_id_);
336 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
337 TwoExtensionsCrashBothAtOnce) {
338 const size_t count_before = GetEnabledExtensionCount();
339 const size_t crash_count_before = GetTerminatedExtensionCount();
340 LoadTestExtension();
341 LoadSecondExtension();
342 CrashExtension(first_extension_id_);
343 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
344 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
345 CrashExtension(second_extension_id_);
346 ASSERT_EQ(count_before, GetEnabledExtensionCount());
347 ASSERT_EQ(crash_count_before + 2, GetTerminatedExtensionCount());
350 SCOPED_TRACE("first balloon");
351 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
352 CheckExtensionConsistency(first_extension_id_);
356 SCOPED_TRACE("second balloon");
357 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
358 CheckExtensionConsistency(first_extension_id_);
359 CheckExtensionConsistency(second_extension_id_);
363 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
364 TwoExtensionsOneByOne) {
365 const size_t count_before = GetEnabledExtensionCount();
366 LoadTestExtension();
367 CrashExtension(first_extension_id_);
368 ASSERT_EQ(count_before, GetEnabledExtensionCount());
369 LoadSecondExtension();
370 CrashExtension(second_extension_id_);
371 ASSERT_EQ(count_before, GetEnabledExtensionCount());
374 SCOPED_TRACE("first balloon");
375 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
376 CheckExtensionConsistency(first_extension_id_);
380 SCOPED_TRACE("second balloon");
381 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
382 CheckExtensionConsistency(first_extension_id_);
383 CheckExtensionConsistency(second_extension_id_);
387 // http://crbug.com/84719
388 #if defined(OS_LINUX)
389 #define MAYBE_TwoExtensionsShutdownWhileCrashed \
390 DISABLED_TwoExtensionsShutdownWhileCrashed
391 #else
392 #define MAYBE_TwoExtensionsShutdownWhileCrashed \
393 TwoExtensionsShutdownWhileCrashed
394 #endif // defined(OS_LINUX)
396 // Make sure that when we don't do anything about the crashed extensions
397 // and close the browser, it doesn't crash. The browser is closed implicitly
398 // at the end of each browser test.
399 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
400 MAYBE_TwoExtensionsShutdownWhileCrashed) {
401 const size_t count_before = GetEnabledExtensionCount();
402 LoadTestExtension();
403 CrashExtension(first_extension_id_);
404 ASSERT_EQ(count_before, GetEnabledExtensionCount());
405 LoadSecondExtension();
406 CrashExtension(second_extension_id_);
407 ASSERT_EQ(count_before, GetEnabledExtensionCount());
410 // Flaky, http://crbug.com/241573.
411 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
412 DISABLED_TwoExtensionsIgnoreFirst) {
413 const size_t count_before = GetEnabledExtensionCount();
414 LoadTestExtension();
415 LoadSecondExtension();
416 CrashExtension(first_extension_id_);
417 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
418 CrashExtension(second_extension_id_);
419 ASSERT_EQ(count_before, GetEnabledExtensionCount());
421 // Accept notification 1 before canceling notification 0.
422 // Otherwise, on Linux and Windows, there is a race here, in which
423 // canceled notifications do not immediately go away.
424 ASSERT_NO_FATAL_FAILURE(AcceptNotification(1));
425 ASSERT_NO_FATAL_FAILURE(CancelNotification(0));
427 SCOPED_TRACE("balloons done");
428 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
429 CheckExtensionConsistency(second_extension_id_);
432 // Flaky, http://crbug.com/241164.
433 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
434 DISABLED_TwoExtensionsReloadIndependently) {
435 const size_t count_before = GetEnabledExtensionCount();
436 LoadTestExtension();
437 LoadSecondExtension();
438 CrashExtension(first_extension_id_);
439 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
440 CrashExtension(second_extension_id_);
441 ASSERT_EQ(count_before, GetEnabledExtensionCount());
444 SCOPED_TRACE("first: reload");
445 WebContents* current_tab =
446 browser()->tab_strip_model()->GetActiveWebContents();
447 ASSERT_TRUE(current_tab);
448 // At the beginning we should have one balloon displayed for each extension.
449 ASSERT_EQ(2U, CountBalloons());
450 ReloadExtension(first_extension_id_);
451 // One of the balloons should hide after the extension is reloaded.
452 ASSERT_EQ(1U, CountBalloons());
453 CheckExtensionConsistency(first_extension_id_);
457 SCOPED_TRACE("second: balloon");
458 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
459 CheckExtensionConsistency(first_extension_id_);
460 CheckExtensionConsistency(second_extension_id_);
464 // http://crbug.com/243648
465 #if defined(OS_WIN)
466 #define MAYBE_CrashAndUninstall DISABLED_CrashAndUninstall
467 #else
468 #define MAYBE_CrashAndUninstall CrashAndUninstall
469 #endif
470 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
471 MAYBE_CrashAndUninstall) {
472 const size_t count_before = GetEnabledExtensionCount();
473 const size_t crash_count_before = GetTerminatedExtensionCount();
474 LoadTestExtension();
475 LoadSecondExtension();
476 CrashExtension(first_extension_id_);
477 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
478 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
480 ASSERT_EQ(1U, CountBalloons());
481 UninstallExtension(first_extension_id_);
482 base::MessageLoop::current()->RunUntilIdle();
484 SCOPED_TRACE("after uninstalling");
485 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
486 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
487 ASSERT_EQ(0U, CountBalloons());
490 // http://crbug.com/84719
491 #if defined(OS_LINUX)
492 #define MAYBE_CrashAndUnloadAll DISABLED_CrashAndUnloadAll
493 #else
494 #define MAYBE_CrashAndUnloadAll CrashAndUnloadAll
495 #endif // defined(OS_LINUX)
497 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
498 MAYBE_CrashAndUnloadAll) {
499 const size_t count_before = GetEnabledExtensionCount();
500 const size_t crash_count_before = GetTerminatedExtensionCount();
501 LoadTestExtension();
502 LoadSecondExtension();
503 CrashExtension(first_extension_id_);
504 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
505 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
507 GetExtensionService()->UnloadAllExtensionsForTest();
508 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
511 // Fails a DCHECK on Aura and Linux: http://crbug.com/169622
512 // Failing on Windows: http://crbug.com/232340
513 #if defined(USE_AURA)
514 #define MAYBE_ReloadTabsWithBackgroundPage DISABLED_ReloadTabsWithBackgroundPage
515 #else
516 #define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage
517 #endif
519 // Test that when an extension with a background page that has a tab open
520 // crashes, the tab stays open, and reloading it reloads the extension.
521 // Regression test for issue 71629.
522 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
523 MAYBE_ReloadTabsWithBackgroundPage) {
524 TabStripModel* tab_strip = browser()->tab_strip_model();
525 const size_t count_before = GetEnabledExtensionCount();
526 const size_t crash_count_before = GetTerminatedExtensionCount();
527 LoadTestExtension();
529 // Open a tab extension.
530 chrome::NewTab(browser());
531 ui_test_utils::NavigateToURL(
532 browser(),
533 GURL("chrome-extension://" + first_extension_id_ + "/background.html"));
535 const int tabs_before = tab_strip->count();
536 CrashExtension(first_extension_id_);
538 // Tab should still be open, and extension should be crashed.
539 EXPECT_EQ(tabs_before, tab_strip->count());
540 EXPECT_EQ(count_before, GetEnabledExtensionCount());
541 EXPECT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
544 content::WindowedNotificationObserver observer(
545 content::NOTIFICATION_LOAD_STOP,
546 content::Source<NavigationController>(
547 &browser()->tab_strip_model()->GetActiveWebContents()->
548 GetController()));
549 chrome::Reload(browser(), CURRENT_TAB);
550 observer.Wait();
552 // Extension should now be loaded.
553 SCOPED_TRACE("after reloading the tab");
554 CheckExtensionConsistency(first_extension_id_);
555 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
556 ASSERT_EQ(0U, CountBalloons());