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. 4 5#include "chrome/browser/browser_process.h" 6#include "chrome/browser/extensions/extension_browsertest.h" 7#include "chrome/browser/extensions/extension_host.h" 8#include "chrome/browser/extensions/extension_process_manager.h" 9#include "chrome/browser/extensions/extension_service.h" 10#include "chrome/browser/extensions/extension_system.h" 11#include "chrome/browser/notifications/balloon.h" 12#include "chrome/browser/notifications/balloon_collection.h" 13#include "chrome/browser/notifications/balloon_host.h" 14#include "chrome/browser/notifications/balloon_notification_ui_manager.h" 15#include "chrome/browser/notifications/notification.h" 16#include "chrome/browser/notifications/notification_delegate.h" 17#include "chrome/browser/profiles/profile.h" 18#include "chrome/browser/ui/browser.h" 19#include "chrome/browser/ui/browser_commands.h" 20#include "chrome/browser/ui/tabs/tab_strip_model.h" 21#include "chrome/test/base/ui_test_utils.h" 22#include "content/public/browser/navigation_controller.h" 23#include "content/public/browser/render_process_host.h" 24#include "content/public/browser/render_view_host.h" 25#include "content/public/browser/web_contents.h" 26#include "content/public/common/result_codes.h" 27#include "ui/message_center/message_center.h" 28#include "ui/message_center/message_center_switches.h" 29#include "ui/message_center/message_center_util.h" 30#include "ui/message_center/notification_list.h" 31 32using content::NavigationController; 33using content::WebContents; 34using extensions::Extension; 35 36// Tests are timing out waiting for extension to crash. 37// http://crbug.com/174705 38#if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX) 39#define MAYBE_ExtensionCrashRecoveryTest DISABLED_ExtensionCrashRecoveryTest 40#else 41#define MAYBE_ExtensionCrashRecoveryTest ExtensionCrashRecoveryTest 42#endif // defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX) 43 44class ExtensionCrashRecoveryTestBase : public ExtensionBrowserTest { 45 protected: 46 virtual void AcceptNotification(size_t index) = 0; 47 virtual void CancelNotification(size_t index) = 0; 48 virtual size_t CountBalloons() = 0; 49 50 ExtensionService* GetExtensionService() { 51 return browser()->profile()->GetExtensionService(); 52 } 53 54 ExtensionProcessManager* GetExtensionProcessManager() { 55 return extensions::ExtensionSystem::Get(browser()->profile())-> 56 process_manager(); 57 } 58 59 void CrashExtension(std::string extension_id) { 60 const Extension* extension = 61 GetExtensionService()->GetExtensionById(extension_id, false); 62 ASSERT_TRUE(extension); 63 extensions::ExtensionHost* extension_host = GetExtensionProcessManager()-> 64 GetBackgroundHostForExtension(extension_id); 65 ASSERT_TRUE(extension_host); 66 67 base::KillProcess(extension_host->render_process_host()->GetHandle(), 68 content::RESULT_CODE_KILLED, false); 69 ASSERT_TRUE(WaitForExtensionCrash(extension_id)); 70 ASSERT_FALSE(GetExtensionProcessManager()-> 71 GetBackgroundHostForExtension(extension_id)); 72 73 // Wait for extension crash balloon to appear. 74 base::MessageLoop::current()->RunUntilIdle(); 75 } 76 77 void CheckExtensionConsistency(std::string extension_id) { 78 const Extension* extension = 79 GetExtensionService()->extensions()->GetByID(extension_id); 80 ASSERT_TRUE(extension); 81 extensions::ExtensionHost* extension_host = GetExtensionProcessManager()-> 82 GetBackgroundHostForExtension(extension_id); 83 ASSERT_TRUE(extension_host); 84 ExtensionProcessManager::ViewSet all_views = 85 GetExtensionProcessManager()->GetAllViews(); 86 ExtensionProcessManager::ViewSet::const_iterator it = 87 all_views.find(extension_host->host_contents()->GetRenderViewHost()); 88 ASSERT_FALSE(it == all_views.end()); 89 ASSERT_TRUE(extension_host->IsRenderViewLive()); 90 extensions::ProcessMap* process_map = 91 browser()->profile()->GetExtensionService()->process_map(); 92 ASSERT_TRUE(process_map->Contains( 93 extension_id, 94 extension_host->render_view_host()->GetProcess()->GetID())); 95 } 96 97 void LoadTestExtension() { 98 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture(); 99 const Extension* extension = LoadExtension( 100 test_data_dir_.AppendASCII("common").AppendASCII("background_page")); 101 ASSERT_TRUE(extension); 102 first_extension_id_ = extension->id(); 103 CheckExtensionConsistency(first_extension_id_); 104 } 105 106 void LoadSecondExtension() { 107 const Extension* extension = LoadExtension( 108 test_data_dir_.AppendASCII("install").AppendASCII("install")); 109 ASSERT_TRUE(extension); 110 second_extension_id_ = extension->id(); 111 CheckExtensionConsistency(second_extension_id_); 112 } 113 114 std::string first_extension_id_; 115 std::string second_extension_id_; 116}; 117 118class MAYBE_ExtensionCrashRecoveryTest 119 : public ExtensionCrashRecoveryTestBase { 120 protected: 121 virtual void AcceptNotification(size_t index) OVERRIDE { 122 if (message_center::IsRichNotificationEnabled()) { 123 message_center::MessageCenter* message_center = 124 message_center::MessageCenter::Get(); 125 ASSERT_GT(message_center->NotificationCount(), index); 126 message_center::NotificationList::Notifications::reverse_iterator it = 127 message_center->GetNotifications().rbegin(); 128 for (size_t i=0; i < index; ++i) 129 it++; 130 std::string id = (*it)->id(); 131 message_center->ClickOnNotification(id); 132 } else { 133 Balloon* balloon = GetNotificationDelegate(index); 134 ASSERT_TRUE(balloon); 135 balloon->OnClick(); 136 } 137 WaitForExtensionLoad(); 138 } 139 140 virtual void CancelNotification(size_t index) OVERRIDE { 141 if (message_center::IsRichNotificationEnabled()) { 142 message_center::MessageCenter* message_center = 143 message_center::MessageCenter::Get(); 144 ASSERT_GT(message_center->NotificationCount(), index); 145 message_center::NotificationList::Notifications::reverse_iterator it = 146 message_center->GetNotifications().rbegin(); 147 for (size_t i=0; i < index; i++) { it++; } 148 ASSERT_TRUE(g_browser_process->notification_ui_manager()-> 149 CancelById((*it)->id())); 150 } else { 151 Balloon* balloon = GetNotificationDelegate(index); 152 ASSERT_TRUE(balloon); 153 std::string id = balloon->notification().notification_id(); 154 ASSERT_TRUE(g_browser_process->notification_ui_manager()->CancelById(id)); 155 } 156 } 157 158 virtual size_t CountBalloons() OVERRIDE { 159 if (message_center::IsRichNotificationEnabled()) 160 return message_center::MessageCenter::Get()->NotificationCount(); 161 162 return BalloonNotificationUIManager::GetInstanceForTesting()-> 163 balloon_collection()->GetActiveBalloons().size(); 164 } 165 166private: 167 Balloon* GetNotificationDelegate(size_t index) { 168 BalloonNotificationUIManager* manager = 169 BalloonNotificationUIManager::GetInstanceForTesting(); 170 BalloonCollection::Balloons balloons = 171 manager->balloon_collection()->GetActiveBalloons(); 172 return index < balloons.size() ? balloons.at(index) : NULL; 173 } 174}; 175 176// Flaky: http://crbug.com/242167. 177IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, DISABLED_Basic) { 178 const size_t size_before = GetExtensionService()->extensions()->size(); 179 const size_t crash_size_before = 180 GetExtensionService()->terminated_extensions()->size(); 181 LoadTestExtension(); 182 CrashExtension(first_extension_id_); 183 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 184 ASSERT_EQ(crash_size_before + 1, 185 GetExtensionService()->terminated_extensions()->size()); 186 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 187 188 SCOPED_TRACE("after clicking the balloon"); 189 CheckExtensionConsistency(first_extension_id_); 190 ASSERT_EQ(crash_size_before, 191 GetExtensionService()->terminated_extensions()->size()); 192} 193 194// Flaky, http://crbug.com/241191. 195IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 196 DISABLED_CloseAndReload) { 197 const size_t size_before = GetExtensionService()->extensions()->size(); 198 const size_t crash_size_before = 199 GetExtensionService()->terminated_extensions()->size(); 200 LoadTestExtension(); 201 CrashExtension(first_extension_id_); 202 203 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 204 ASSERT_EQ(crash_size_before + 1, 205 GetExtensionService()->terminated_extensions()->size()); 206 207 ASSERT_NO_FATAL_FAILURE(CancelNotification(0)); 208 ReloadExtension(first_extension_id_); 209 210 SCOPED_TRACE("after reloading"); 211 CheckExtensionConsistency(first_extension_id_); 212 ASSERT_EQ(crash_size_before, 213 GetExtensionService()->terminated_extensions()->size()); 214} 215 216// Test is timing out on Windows http://crbug.com/174705. 217#if defined(OS_WIN) 218#define MAYBE_ReloadIndependently DISABLED_ReloadIndependently 219#else 220#define MAYBE_ReloadIndependently ReloadIndependently 221#endif // defined(OS_WIN) 222IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 223 MAYBE_ReloadIndependently) { 224 const size_t size_before = GetExtensionService()->extensions()->size(); 225 LoadTestExtension(); 226 CrashExtension(first_extension_id_); 227 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 228 229 ReloadExtension(first_extension_id_); 230 231 SCOPED_TRACE("after reloading"); 232 CheckExtensionConsistency(first_extension_id_); 233 234 WebContents* current_tab = 235 browser()->tab_strip_model()->GetActiveWebContents(); 236 ASSERT_TRUE(current_tab); 237 238 // The balloon should automatically hide after the extension is successfully 239 // reloaded. 240 ASSERT_EQ(0U, CountBalloons()); 241} 242 243// Test is timing out on Windows http://crbug.com/174705. 244#if defined(OS_WIN) 245#define MAYBE_ReloadIndependentlyChangeTabs DISABLED_ReloadIndependentlyChangeTabs 246#else 247#define MAYBE_ReloadIndependentlyChangeTabs ReloadIndependentlyChangeTabs 248#endif // defined(OS_WIN) 249 250IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 251 MAYBE_ReloadIndependentlyChangeTabs) { 252 const size_t size_before = GetExtensionService()->extensions()->size(); 253 LoadTestExtension(); 254 CrashExtension(first_extension_id_); 255 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 256 257 WebContents* original_tab = 258 browser()->tab_strip_model()->GetActiveWebContents(); 259 ASSERT_TRUE(original_tab); 260 ASSERT_EQ(1U, CountBalloons()); 261 262 // Open a new tab, but the balloon will still be there. 263 chrome::NewTab(browser()); 264 WebContents* new_current_tab = 265 browser()->tab_strip_model()->GetActiveWebContents(); 266 ASSERT_TRUE(new_current_tab); 267 ASSERT_NE(new_current_tab, original_tab); 268 ASSERT_EQ(1U, CountBalloons()); 269 270 ReloadExtension(first_extension_id_); 271 272 SCOPED_TRACE("after reloading"); 273 CheckExtensionConsistency(first_extension_id_); 274 275 // The balloon should automatically hide after the extension is successfully 276 // reloaded. 277 ASSERT_EQ(0U, CountBalloons()); 278} 279 280IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 281 DISABLED_ReloadIndependentlyNavigatePage) { 282 const size_t size_before = GetExtensionService()->extensions()->size(); 283 LoadTestExtension(); 284 CrashExtension(first_extension_id_); 285 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 286 287 WebContents* current_tab = 288 browser()->tab_strip_model()->GetActiveWebContents(); 289 ASSERT_TRUE(current_tab); 290 ASSERT_EQ(1U, CountBalloons()); 291 292 // Navigate to another page. 293 ui_test_utils::NavigateToURL( 294 browser(), ui_test_utils::GetTestUrl( 295 base::FilePath(base::FilePath::kCurrentDirectory), 296 base::FilePath(FILE_PATH_LITERAL("title1.html")))); 297 ASSERT_EQ(1U, CountBalloons()); 298 299 ReloadExtension(first_extension_id_); 300 301 SCOPED_TRACE("after reloading"); 302 CheckExtensionConsistency(first_extension_id_); 303 304 // The balloon should automatically hide after the extension is successfully 305 // reloaded. 306 ASSERT_EQ(0U, CountBalloons()); 307} 308 309// Make sure that when we don't do anything about the crashed extension 310// and close the browser, it doesn't crash. The browser is closed implicitly 311// at the end of each browser test. 312// 313// http://crbug.com/84719 314#if defined(OS_LINUX) 315#define MAYBE_ShutdownWhileCrashed DISABLED_ShutdownWhileCrashed 316#else 317#define MAYBE_ShutdownWhileCrashed ShutdownWhileCrashed 318#endif // defined(OS_LINUX) 319 320IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 321 MAYBE_ShutdownWhileCrashed) { 322 const size_t size_before = GetExtensionService()->extensions()->size(); 323 LoadTestExtension(); 324 CrashExtension(first_extension_id_); 325 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 326} 327 328// Flaky, http://crbug.com/241245. 329IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 330 DISABLED_TwoExtensionsCrashFirst) { 331 const size_t size_before = GetExtensionService()->extensions()->size(); 332 LoadTestExtension(); 333 LoadSecondExtension(); 334 CrashExtension(first_extension_id_); 335 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 336 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 337 338 SCOPED_TRACE("after clicking the balloon"); 339 CheckExtensionConsistency(first_extension_id_); 340 CheckExtensionConsistency(second_extension_id_); 341} 342 343// Flaky: http://crbug.com/242196 344IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 345 DISABLED_TwoExtensionsCrashSecond) { 346 const size_t size_before = GetExtensionService()->extensions()->size(); 347 LoadTestExtension(); 348 LoadSecondExtension(); 349 CrashExtension(second_extension_id_); 350 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 351 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 352 353 SCOPED_TRACE("after clicking the balloon"); 354 CheckExtensionConsistency(first_extension_id_); 355 CheckExtensionConsistency(second_extension_id_); 356} 357 358IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 359 TwoExtensionsCrashBothAtOnce) { 360 const size_t size_before = GetExtensionService()->extensions()->size(); 361 const size_t crash_size_before = 362 GetExtensionService()->terminated_extensions()->size(); 363 LoadTestExtension(); 364 LoadSecondExtension(); 365 CrashExtension(first_extension_id_); 366 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 367 ASSERT_EQ(crash_size_before + 1, 368 GetExtensionService()->terminated_extensions()->size()); 369 CrashExtension(second_extension_id_); 370 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 371 ASSERT_EQ(crash_size_before + 2, 372 GetExtensionService()->terminated_extensions()->size()); 373 374 { 375 SCOPED_TRACE("first balloon"); 376 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 377 CheckExtensionConsistency(first_extension_id_); 378 } 379 380 { 381 SCOPED_TRACE("second balloon"); 382 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 383 CheckExtensionConsistency(first_extension_id_); 384 CheckExtensionConsistency(second_extension_id_); 385 } 386} 387 388IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 389 TwoExtensionsOneByOne) { 390 const size_t size_before = GetExtensionService()->extensions()->size(); 391 LoadTestExtension(); 392 CrashExtension(first_extension_id_); 393 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 394 LoadSecondExtension(); 395 CrashExtension(second_extension_id_); 396 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 397 398 { 399 SCOPED_TRACE("first balloon"); 400 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 401 CheckExtensionConsistency(first_extension_id_); 402 } 403 404 { 405 SCOPED_TRACE("second balloon"); 406 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 407 CheckExtensionConsistency(first_extension_id_); 408 CheckExtensionConsistency(second_extension_id_); 409 } 410} 411 412// http://crbug.com/84719 413#if defined(OS_LINUX) 414#define MAYBE_TwoExtensionsShutdownWhileCrashed \ 415 DISABLED_TwoExtensionsShutdownWhileCrashed 416#else 417#define MAYBE_TwoExtensionsShutdownWhileCrashed \ 418 TwoExtensionsShutdownWhileCrashed 419#endif // defined(OS_LINUX) 420 421// Make sure that when we don't do anything about the crashed extensions 422// and close the browser, it doesn't crash. The browser is closed implicitly 423// at the end of each browser test. 424IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 425 MAYBE_TwoExtensionsShutdownWhileCrashed) { 426 const size_t size_before = GetExtensionService()->extensions()->size(); 427 LoadTestExtension(); 428 CrashExtension(first_extension_id_); 429 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 430 LoadSecondExtension(); 431 CrashExtension(second_extension_id_); 432 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 433} 434 435// Flaky, http://crbug.com/241573. 436IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 437 DISABLED_TwoExtensionsIgnoreFirst) { 438 const size_t size_before = GetExtensionService()->extensions()->size(); 439 LoadTestExtension(); 440 LoadSecondExtension(); 441 CrashExtension(first_extension_id_); 442 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 443 CrashExtension(second_extension_id_); 444 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 445 446 // Accept notification 1 before canceling notification 0. 447 // Otherwise, on Linux and Windows, there is a race here, in which 448 // canceled notifications do not immediately go away. 449 ASSERT_NO_FATAL_FAILURE(AcceptNotification(1)); 450 ASSERT_NO_FATAL_FAILURE(CancelNotification(0)); 451 452 SCOPED_TRACE("balloons done"); 453 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 454 CheckExtensionConsistency(second_extension_id_); 455} 456 457// Flaky, http://crbug.com/241164. 458IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 459 DISABLED_TwoExtensionsReloadIndependently) { 460 const size_t size_before = GetExtensionService()->extensions()->size(); 461 LoadTestExtension(); 462 LoadSecondExtension(); 463 CrashExtension(first_extension_id_); 464 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 465 CrashExtension(second_extension_id_); 466 ASSERT_EQ(size_before, GetExtensionService()->extensions()->size()); 467 468 { 469 SCOPED_TRACE("first: reload"); 470 WebContents* current_tab = 471 browser()->tab_strip_model()->GetActiveWebContents(); 472 ASSERT_TRUE(current_tab); 473 // At the beginning we should have one balloon displayed for each extension. 474 ASSERT_EQ(2U, CountBalloons()); 475 ReloadExtension(first_extension_id_); 476 // One of the balloons should hide after the extension is reloaded. 477 ASSERT_EQ(1U, CountBalloons()); 478 CheckExtensionConsistency(first_extension_id_); 479 } 480 481 { 482 SCOPED_TRACE("second: balloon"); 483 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0)); 484 CheckExtensionConsistency(first_extension_id_); 485 CheckExtensionConsistency(second_extension_id_); 486 } 487} 488 489// http://crbug.com/243648 490#if defined(OS_WIN) 491#define MAYBE_CrashAndUninstall DISABLED_CrashAndUninstall 492#else 493#define MAYBE_CrashAndUninstall CrashAndUninstall 494#endif 495IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 496 MAYBE_CrashAndUninstall) { 497 const size_t size_before = GetExtensionService()->extensions()->size(); 498 const size_t crash_size_before = 499 GetExtensionService()->terminated_extensions()->size(); 500 LoadTestExtension(); 501 LoadSecondExtension(); 502 CrashExtension(first_extension_id_); 503 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 504 ASSERT_EQ(crash_size_before + 1, 505 GetExtensionService()->terminated_extensions()->size()); 506 507 ASSERT_EQ(1U, CountBalloons()); 508 UninstallExtension(first_extension_id_); 509 base::MessageLoop::current()->RunUntilIdle(); 510 511 SCOPED_TRACE("after uninstalling"); 512 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 513 ASSERT_EQ(crash_size_before, 514 GetExtensionService()->terminated_extensions()->size()); 515 ASSERT_EQ(0U, CountBalloons()); 516} 517 518// http://crbug.com/84719 519#if defined(OS_LINUX) 520#define MAYBE_CrashAndUnloadAll DISABLED_CrashAndUnloadAll 521#else 522#define MAYBE_CrashAndUnloadAll CrashAndUnloadAll 523#endif // defined(OS_LINUX) 524 525IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 526 MAYBE_CrashAndUnloadAll) { 527 const size_t size_before = GetExtensionService()->extensions()->size(); 528 const size_t crash_size_before = 529 GetExtensionService()->terminated_extensions()->size(); 530 LoadTestExtension(); 531 LoadSecondExtension(); 532 CrashExtension(first_extension_id_); 533 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 534 ASSERT_EQ(crash_size_before + 1, 535 GetExtensionService()->terminated_extensions()->size()); 536 537 GetExtensionService()->UnloadAllExtensions(); 538 ASSERT_EQ(crash_size_before, 539 GetExtensionService()->terminated_extensions()->size()); 540} 541 542// Fails a DCHECK on Aura and Linux: http://crbug.com/169622 543// Failing on Windows: http://crbug.com/232340 544#if defined(USE_AURA) || defined(OS_WIN) || defined(OS_LINUX) 545#define MAYBE_ReloadTabsWithBackgroundPage DISABLED_ReloadTabsWithBackgroundPage 546#else 547#define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage 548#endif 549 550// Test that when an extension with a background page that has a tab open 551// crashes, the tab stays open, and reloading it reloads the extension. 552// Regression test for issue 71629. 553IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, 554 MAYBE_ReloadTabsWithBackgroundPage) { 555 TabStripModel* tab_strip = browser()->tab_strip_model(); 556 const size_t size_before = GetExtensionService()->extensions()->size(); 557 const size_t crash_size_before = 558 GetExtensionService()->terminated_extensions()->size(); 559 LoadTestExtension(); 560 561 // Open a tab extension. 562 chrome::NewTab(browser()); 563 ui_test_utils::NavigateToURL( 564 browser(), 565 GURL("chrome-extension://" + first_extension_id_ + "/background.html")); 566 567 const int tabs_before = tab_strip->count(); 568 CrashExtension(first_extension_id_); 569 570 // Tab should still be open, and extension should be crashed. 571 EXPECT_EQ(tabs_before, tab_strip->count()); 572 EXPECT_EQ(size_before, GetExtensionService()->extensions()->size()); 573 EXPECT_EQ(crash_size_before + 1, 574 GetExtensionService()->terminated_extensions()->size()); 575 576 { 577 content::WindowedNotificationObserver observer( 578 content::NOTIFICATION_LOAD_STOP, 579 content::Source<NavigationController>( 580 &browser()->tab_strip_model()->GetActiveWebContents()-> 581 GetController())); 582 chrome::Reload(browser(), CURRENT_TAB); 583 observer.Wait(); 584 } 585 // Extension should now be loaded. 586 SCOPED_TRACE("after reloading the tab"); 587 CheckExtensionConsistency(first_extension_id_); 588 ASSERT_EQ(size_before + 1, GetExtensionService()->extensions()->size()); 589 ASSERT_EQ(0U, CountBalloons()); 590} 591