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