render_process_host_chrome_browsertest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Use of this source code is governed by a BSD-style license that can be
354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// found in the LICENSE file.
4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "base/command_line.h"
6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "base/process_util.h"
7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/chrome_notification_types.h"
8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/devtools/devtools_window.h"
9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/ui/browser.h"
10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/ui/browser_commands.h"
11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/ui/singleton_tabs.h"
12b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/browser/ui/tabs/tab_strip_model.h"
13b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/common/chrome_switches.h"
14b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/common/url_constants.h"
15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/test/base/in_process_browser_test.h"
16b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "chrome/test/base/ui_test_utils.h"
17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "content/public/browser/notification_service.h"
18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "content/public/browser/render_process_host.h"
19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "content/public/browser/render_view_host.h"
20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "content/public/browser/web_contents.h"
21103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "content/public/browser/web_contents_observer.h"
22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehousing content::RenderViewHost;
24b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehousing content::RenderWidgetHost;
25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehousing content::WebContents;
26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehonamespace {
28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint RenderProcessHostCount() {
30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  content::RenderProcessHost::iterator hosts =
31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::RenderProcessHost::AllHostsIterator();
32b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int count = 0;
33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  while (!hosts.IsAtEnd()) {
34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (hosts.GetCurrentValue()->HasConnection())
35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      count++;
36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    hosts.Advance();
37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  return count;
39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
41b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoRenderViewHost* FindFirstDevToolsHost() {
42b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts();
43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  for (size_t i = 0; i < widgets.size(); ++i) {
4454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    if (!widgets[i]->GetProcess()->HasConnection())
45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      continue;
46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (!widgets[i]->IsRenderView())
47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      continue;
48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    RenderViewHost* host = RenderViewHost::From(widgets[i]);
4954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    WebContents* contents = WebContents::FromRenderViewHost(host);
50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL url = contents->GetURL();
51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (url.SchemeIs(chrome::kChromeDevToolsScheme))
52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      return host;
53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  return NULL;
55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
57b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}  // namespace
58b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
5954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusclass ChromeRenderProcessHostTest : public InProcessBrowserTest {
60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho public:
61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ChromeRenderProcessHostTest() {}
62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Show a tab, activating the current one if there is one, and wait for
64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // the renderer process to be created or foregrounded, returning the process
6554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  // handle.
66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  base::ProcessHandle ShowSingletonTab(const GURL& page) {
67b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    chrome::ShowSingletonTab(browser(), page);
68b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents();
69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    CHECK(wc->GetURL() == page);
70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Ensure that the backgrounding / foregrounding gets a chance to run.
72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    content::BrowserThread::PostTaskAndReply(
73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        base::Bind(&base::DoNothing), base::MessageLoop::QuitClosure());
75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    base::MessageLoop::current()->Run();
76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return wc->GetRenderProcessHost()->GetHandle();
78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // When we hit the max number of renderers, verify that the way we do process
81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // sharing behaves correctly.  In particular, this test is verifying that even
82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // when we hit the max process limit, that renderers of each type will wind up
83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // in a process of that type, even if that means creating a new process.
84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  void TestProcessOverflow() {
85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int tab_count = 1;
86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int host_count = 1;
87b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    WebContents* tab1 = NULL;
88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    WebContents* tab2 = NULL;
89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    content::RenderProcessHost* rph1 = NULL;
90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    content::RenderProcessHost* rph2 = NULL;
91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    content::RenderProcessHost* rph3 = NULL;
92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Change the first tab to be the new tab page (TYPE_WEBUI).
94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL newtab(chrome::kChromeUINewTabURL);
95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    ui_test_utils::NavigateToURL(browser(), newtab);
9654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
9754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
9854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    rph1 = tab1->GetRenderProcessHost();
9954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    EXPECT_EQ(tab1->GetURL(), newtab);
10054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius    EXPECT_EQ(host_count, RenderProcessHostCount());
101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Create a new TYPE_TABBED tab.  It should be in its own process.
103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL page1("data:text/html,hello world1");
104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    ui_test_utils::WindowedTabAddedNotificationObserver observer1(
106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::NotificationService::AllSources());
107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    chrome::ShowSingletonTab(browser(), page1);
108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    observer1.Wait();
109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab_count++;
111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    host_count++;
112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    rph2 = tab1->GetRenderProcessHost();
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab1->GetURL(), page1);
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(host_count, RenderProcessHostCount());
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_NE(rph1, rph2);
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Create another TYPE_TABBED tab.  It should share the previous process.
120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL page2("data:text/html,hello world2");
121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    ui_test_utils::WindowedTabAddedNotificationObserver observer2(
122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::NotificationService::AllSources());
123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    chrome::ShowSingletonTab(browser(), page2);
124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    observer2.Wait();
125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab_count++;
126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab2 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab2->GetURL(), page2);
129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(host_count, RenderProcessHostCount());
130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab2->GetRenderProcessHost(), rph2);
131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Create another TYPE_WEBUI tab.  It should share the process with newtab.
133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Note: intentionally create this tab after the TYPE_TABBED tabs to
134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // exercise bug 43448 where extension and WebUI tabs could get combined into
135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // normal renderers.
136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL history(chrome::kChromeUIHistoryURL);
137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    ui_test_utils::WindowedTabAddedNotificationObserver observer3(
138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::NotificationService::AllSources());
139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    chrome::ShowSingletonTab(browser(), history);
140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    observer3.Wait();
141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab_count++;
142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab2 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab2->GetURL(), GURL(history));
145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(host_count, RenderProcessHostCount());
146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab2->GetRenderProcessHost(), rph1);
147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Create a TYPE_EXTENSION tab.  It should be in its own process.
149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // (the bookmark manager is implemented as an extension)
150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    GURL bookmarks(chrome::kChromeUIBookmarksURL);
151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    ui_test_utils::WindowedTabAddedNotificationObserver observer4(
152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::NotificationService::AllSources());
153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    chrome::ShowSingletonTab(browser(), bookmarks);
154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    observer4.Wait();
155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab_count++;
156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    host_count++;
157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1);
159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    rph3 = tab1->GetRenderProcessHost();
160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(tab1->GetURL(), bookmarks);
161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_EQ(host_count, RenderProcessHostCount());
162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_NE(rph1, rph3);
163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    EXPECT_NE(rph2, rph3);
164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass ChromeRenderProcessHostTestWithCommandLine
169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    : public ChromeRenderProcessHostTest {
170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho protected:
171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1");
173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, ProcessPerTab) {
177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Set max renderers to 1 to force running out of processes.
178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  content::RenderProcessHost::SetMaxRendererProcessCount(1);
179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  parsed_command_line.AppendSwitch(switches::kProcessPerTab);
182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int tab_count = 1;
184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int host_count = 1;
18554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Change the first tab to be the new tab page (TYPE_WEBUI).
187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL newtab(chrome::kChromeUINewTabURL);
188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::NavigateToURL(browser(), newtab);
189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create a new TYPE_TABBED tab.  It should be in its own process.
193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page1("data:text/html,hello world1");
194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer1(
195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ShowSingletonTab(browser(), page1);
197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer1.Wait();
198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create another TYPE_TABBED tab.  It should share the previous process.
204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page2("data:text/html,hello world2");
205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer2(
206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ShowSingletonTab(browser(), page2);
208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer2.Wait();
209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create another new tab.  It should share the process with the other WebUI.
214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer3(
215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::NewTab(browser());
217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer3.Wait();
218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create another new tab.  It should share the process with the other WebUI.
223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer4(
224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::NewTab(browser());
226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer4.Wait();
227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// We don't change process priorities on Mac or Posix because the user lacks the
233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// permission to raise a process' priority even after lowering it.
234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if defined(OS_WIN) || defined(OS_LINUX)
235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, Backgrounding) {
236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  if (!base::Process::CanBackgroundProcesses()) {
237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    LOG(ERROR) << "Can't background processes";
238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return;
239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  parsed_command_line.AppendSwitch(switches::kProcessPerTab);
242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Change the first tab to be the new tab page (TYPE_WEBUI).
244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL newtab(chrome::kChromeUINewTabURL);
245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::NavigateToURL(browser(), newtab);
246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create a new tab. It should be foreground.
248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page1("data:text/html,hello world1");
249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  base::ProcessHandle pid1 = ShowSingletonTab(page1);
250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create another tab. It should be foreground, and the first tab should
253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // now be background.
254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page2("data:text/html,hello world2");
255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  base::ProcessHandle pid2 = ShowSingletonTab(page2);
256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_NE(pid1, pid2);
257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded());
258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded());
259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Navigate back to first page. It should be foreground again, and the second
261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // tab should be background.
262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(pid1, ShowSingletonTab(page1));
263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_TRUE(base::Process(pid2).IsProcessBackgrounded());
265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif
267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// TODO(nasko): crbug.com/173137
269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if defined(OS_WIN)
270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define MAYBE_ProcessOverflow DISABLED_ProcessOverflow
271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#else
272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define MAYBE_ProcessOverflow ProcessOverflow
273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif
274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessOverflow) {
276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Set max renderers to 1 to force running out of processes.
277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  content::RenderProcessHost::SetMaxRendererProcessCount(1);
278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  TestProcessOverflow();
279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Variation of the ProcessOverflow test, which is driven through command line
282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// parameter instead of direct function call into the class.
283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTestWithCommandLine,
284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       ProcessOverflow) {
285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  TestProcessOverflow();
286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Ensure that DevTools opened to debug DevTools is launched in a separate
289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// process when --process-per-tab is set. See crbug.com/69873.
290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest,
291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       DevToolsOnSelfInOwnProcessPPT) {
292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  parsed_command_line.AppendSwitch(switches::kProcessPerTab);
294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int tab_count = 1;
296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int host_count = 1;
297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page1("data:text/html,hello world1");
299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer1(
300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ShowSingletonTab(browser(), page1);
302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer1.Wait();
303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // DevTools start in docked mode (no new tab), in a separate process.
309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ToggleDevToolsWindow(browser(), DEVTOOLS_TOGGLE_ACTION_INSPECT);
310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  RenderViewHost* devtools = FindFirstDevToolsHost();
315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  DCHECK(devtools);
316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // DevTools start in a separate process.
318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  DevToolsWindow::ToggleDevToolsWindow(
319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      devtools, true, DEVTOOLS_TOGGLE_ACTION_INSPECT);
32054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius  host_count++;
321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Ensure that DevTools opened to debug DevTools is launched in a separate
326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// process. See crbug.com/69873.
327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest,
328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       DevToolsOnSelfInOwnProcess) {
329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int tab_count = 1;
330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  int host_count = 1;
331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL page1("data:text/html,hello world1");
333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::WindowedTabAddedNotificationObserver observer1(
334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ShowSingletonTab(browser(), page1);
336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer1.Wait();
337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  tab_count++;
338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // DevTools start in docked mode (no new tab), in a separate process.
343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  chrome::ToggleDevToolsWindow(browser(), DEVTOOLS_TOGGLE_ACTION_INSPECT);
344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  RenderViewHost* devtools = FindFirstDevToolsHost();
349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  DCHECK(devtools);
350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // DevTools start in a separate process.
352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  DevToolsWindow::ToggleDevToolsWindow(
353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      devtools, true, DEVTOOLS_TOGGLE_ACTION_INSPECT);
354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  host_count++;
355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(tab_count, browser()->tab_strip_model()->count());
356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(host_count, RenderProcessHostCount());
357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// This class's goal is to close the browser window when a renderer process has
360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// crashed. It does so by monitoring WebContents for RenderProcessGone event and
361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// closing the passed in TabStripModel. This is used in the following test case.
362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass WindowDestroyer : public content::WebContentsObserver {
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho public:
364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  WindowDestroyer(content::WebContents* web_contents, TabStripModel* model)
365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      : content::WebContentsObserver(web_contents),
366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        tab_strip_model_(model) {
367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE {
370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Wait for the window to be destroyed, which will ensure all other
371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // RenderViewHost objects are deleted before we return and proceed with
372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // the next iteration of notifications.
373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    content::WindowedNotificationObserver observer(
374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        chrome::NOTIFICATION_BROWSER_CLOSED,
375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        content::NotificationService::AllSources());
376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    tab_strip_model_->CloseAllTabs();
377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    observer.Wait();
378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  }
379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho private:
381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  TabStripModel* tab_strip_model_;
382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  DISALLOW_COPY_AND_ASSIGN(WindowDestroyer);
384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Test to ensure that while iterating through all listeners in
387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// RenderProcessHost and invalidating them, we remove them properly and don't
388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// access already freed objects. See http://crbug.com/255524.
389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest,
390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                       CloseAllTabsDuringProcessDied) {
391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  GURL url(chrome::kChromeUINewTabURL);
392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::NavigateToURL(browser(), url);
394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  ui_test_utils::NavigateToURLWithDisposition(
395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      browser(), url, NEW_BACKGROUND_TAB,
396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(2, browser()->tab_strip_model()->count());
399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  WebContents* wc1 = browser()->tab_strip_model()->GetWebContentsAt(0);
401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  WebContents* wc2 = browser()->tab_strip_model()->GetWebContentsAt(1);
402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  EXPECT_EQ(wc1->GetRenderProcessHost(), wc2->GetRenderProcessHost());
403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Create an object that will close the window on a process crash.
405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  WindowDestroyer destroyer(wc1, browser()->tab_strip_model());
406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Use NOTIFICATION_BROWSER_CLOSED instead of NOTIFICATION_WINDOW_CLOSED,
408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // since the latter is not implemented on OSX and the test will timeout,
409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // causing it to fail.
410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  content::WindowedNotificationObserver observer(
411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      chrome::NOTIFICATION_BROWSER_CLOSED,
412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho      content::NotificationService::AllSources());
413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // Kill the renderer process, simulating a crash. This should the ProcessDied
415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // method to be called. Alternatively, RenderProcessHost::OnChannelError can
416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  // be called to directly force a call to ProcessDied.
417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  base::KillProcess(wc1->GetRenderProcessHost()->GetHandle(), -1, true);
418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho  observer.Wait();
420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho