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