render_process_host_chrome_browsertest.cc revision f2477e01787aa58f445919b809d89e252beef54f
1551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer// Copyright (c) 2012 The Chromium Authors. All rights reserved. 263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman// Use of this source code is governed by a BSD-style license that can be 36c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// found in the LICENSE file. 46c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner#include "base/command_line.h" 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner#include "chrome/browser/chrome_notification_types.h" 763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman#include "chrome/browser/devtools/devtools_window.h" 86c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "chrome/browser/search/search.h" 96c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "chrome/browser/ui/browser.h" 106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "chrome/browser/ui/browser_commands.h" 116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "chrome/browser/ui/singleton_tabs.h" 1263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman#include "chrome/browser/ui/tabs/tab_strip_model.h" 139a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson#include "chrome/common/chrome_switches.h" 149a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson#include "chrome/common/url_constants.h" 159a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson#include "chrome/test/base/in_process_browser_test.h" 169a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson#include "chrome/test/base/test_switches.h" 176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "chrome/test/base/ui_test_utils.h" 186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "content/public/browser/notification_service.h" 196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#include "content/public/browser/render_process_host.h" 20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "content/public/browser/render_view_host.h" 21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "content/public/browser/render_widget_host_iterator.h" 22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "content/public/browser/web_contents.h" 238b67f774e9c38b7718b2b300b628388f966df4e0Chandler Carruth#include "content/public/browser/web_contents_observer.h" 246c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 256c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekeusing content::RenderViewHost; 266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekeusing content::RenderWidgetHost; 276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekeusing content::WebContents; 286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekenamespace { 306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaekeint RenderProcessHostCount() { 326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::RenderProcessHost::iterator hosts = 336c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::RenderProcessHost::AllHostsIterator(); 346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke int count = 0; 356c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke while (!hosts.IsAtEnd()) { 36620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke if (hosts.GetCurrentValue()->HasConnection()) 37620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke count++; 38620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke hosts.Advance(); 39620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke } 40620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke return count; 41620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke} 42620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke 43620ee02353d8b65959dc01a66b073adfcdef9eacBrian GaekeRenderViewHost* FindFirstDevToolsHost() { 44620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke scoped_ptr<content::RenderWidgetHostIterator> widgets( 45620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke RenderWidgetHost::GetRenderWidgetHosts()); 466c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { 47757c1f9d87b516a1e3bc4cd678245b207ae9c559Brian Gaeke if (!widget->GetProcess()->HasConnection()) 486c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke continue; 499a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson if (!widget->IsRenderView()) 509a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson continue; 519a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson RenderViewHost* host = RenderViewHost::From(widget); 529a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson WebContents* contents = WebContents::FromRenderViewHost(host); 539a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson GURL url = contents->GetURL(); 549a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson if (url.SchemeIs(chrome::kChromeDevToolsScheme)) 559a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson return host; 569a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson } 579a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson return NULL; 589a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson} 599a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 609a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson} // namespace 619a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 629a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilsonclass ChromeRenderProcessHostTest : public InProcessBrowserTest { 639a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson public: 646c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ChromeRenderProcessHostTest() {} 659a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 666c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Show a tab, activating the current one if there is one, and wait for 676c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // the renderer process to be created or foregrounded, returning the process 686c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // handle. 696c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke base::ProcessHandle ShowSingletonTab(const GURL& page) { 706c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ShowSingletonTab(browser(), page); 716c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents(); 726c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke CHECK(wc->GetURL() == page); 736c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 746c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Ensure that the backgrounding / foregrounding gets a chance to run. 756c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::BrowserThread::PostTaskAndReply( 766c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 776c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke base::Bind(&base::DoNothing), base::MessageLoop::QuitClosure()); 786c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke base::MessageLoop::current()->Run(); 79fe4591bfc2b147c10d6a7b1a5af56454fb78daceStephen Wilson 80314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson return wc->GetRenderProcessHost()->GetHandle(); 816c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke } 829a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 839a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // When we hit the max number of renderers, verify that the way we do process 846c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // sharing behaves correctly. In particular, this test is verifying that even 856c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // when we hit the max process limit, that renderers of each type will wind up 86620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // in a process of that type, even if that means creating a new process. 87620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke void TestProcessOverflow() { 88e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke int tab_count = 1; 899a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson int host_count = 1; 90620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke WebContents* tab1 = NULL; 91620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke WebContents* tab2 = NULL; 92620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke content::RenderProcessHost* rph1 = NULL; 93620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke content::RenderProcessHost* rph2 = NULL; 94620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke content::RenderProcessHost* rph3 = NULL; 95620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke 96620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // Change the first tab to be the omnibox page (TYPE_WEBUI). 97620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke GURL omnibox(chrome::kChromeUIOmniboxURL); 98620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke ui_test_utils::NavigateToURL(browser(), omnibox); 99620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 100620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); 101620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke rph1 = tab1->GetRenderProcessHost(); 102620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke EXPECT_EQ(omnibox, tab1->GetURL()); 1039a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson EXPECT_EQ(host_count, RenderProcessHostCount()); 1049a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 1059a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // Create a new TYPE_TABBED tab. It should be in its own process. 1069a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson GURL page1("data:text/html,hello world1"); 1079a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 108e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke ui_test_utils::WindowedTabAddedNotificationObserver observer1( 109620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke content::NotificationService::AllSources()); 1106c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ShowSingletonTab(browser(), page1); 1116c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke observer1.Wait(); 1126c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 1136c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 1146c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke host_count++; 1156c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 1166c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); 1176c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke rph2 = tab1->GetRenderProcessHost(); 1186c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab1->GetURL(), page1); 1196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 1206c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_NE(rph1, rph2); 1215af8f421b6412e52530608097e39d2602195629fDan Gohman 1225af8f421b6412e52530608097e39d2602195629fDan Gohman // Create another TYPE_TABBED tab. It should share the previous process. 1235af8f421b6412e52530608097e39d2602195629fDan Gohman GURL page2("data:text/html,hello world2"); 1245af8f421b6412e52530608097e39d2602195629fDan Gohman ui_test_utils::WindowedTabAddedNotificationObserver observer2( 1255af8f421b6412e52530608097e39d2602195629fDan Gohman content::NotificationService::AllSources()); 1265af8f421b6412e52530608097e39d2602195629fDan Gohman chrome::ShowSingletonTab(browser(), page2); 1276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke observer2.Wait(); 1286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 1296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 1306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab2 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); 1316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab2->GetURL(), page2); 1326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 1336c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab2->GetRenderProcessHost(), rph2); 1346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 135620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // Create another TYPE_WEBUI tab. It should share the process with omnibox. 1366c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Note: intentionally create this tab after the TYPE_TABBED tabs to 137620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // exercise bug 43448 where extension and WebUI tabs could get combined into 138620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // normal renderers. 1399a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson GURL history(chrome::kChromeUIHistoryURL); 140620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke ui_test_utils::WindowedTabAddedNotificationObserver observer3( 141620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke content::NotificationService::AllSources()); 142cc5fc60468a1915049ef19a549fe4a6ae8708a00Bruno Cardoso Lopes chrome::ShowSingletonTab(browser(), history); 143cc5fc60468a1915049ef19a549fe4a6ae8708a00Bruno Cardoso Lopes observer3.Wait(); 1446c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 1456c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 1466c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab2 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); 1476c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab2->GetURL(), GURL(history)); 1486c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 1496c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab2->GetRenderProcessHost(), rph1); 1506c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 1516c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Create a TYPE_EXTENSION tab. It should be in its own process. 1526c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // (the bookmark manager is implemented as an extension) 1536c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke GURL bookmarks(chrome::kChromeUIBookmarksURL); 1549a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson ui_test_utils::WindowedTabAddedNotificationObserver observer4( 1556c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::NotificationService::AllSources()); 1566c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ShowSingletonTab(browser(), bookmarks); 1576c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke observer4.Wait(); 1586c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 159e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming host_count++; 1605af8f421b6412e52530608097e39d2602195629fDan Gohman EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 161e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming tab1 = browser()->tab_strip_model()->GetWebContentsAt(tab_count - 1); 162e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming rph3 = tab1->GetRenderProcessHost(); 163e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming EXPECT_EQ(tab1->GetURL(), bookmarks); 164e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming EXPECT_EQ(host_count, RenderProcessHostCount()); 165e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming EXPECT_NE(rph1, rph3); 166e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming EXPECT_NE(rph2, rph3); 167e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming } 168e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming}; 169e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming 170e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming 171e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Flemingclass ChromeRenderProcessHostTestWithCommandLine 172e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming : public ChromeRenderProcessHostTest { 173e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming protected: 174e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 175e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); 176e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming } 177e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming}; 178e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming 179e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt FlemingIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, ProcessPerTab) { 180e07cc5dab102c0f8c3f66c2703c95e547d6bf1c6Matt Fleming // Set max renderers to 1 to force running out of processes. 1815af8f421b6412e52530608097e39d2602195629fDan Gohman content::RenderProcessHost::SetMaxRendererProcessCount(1); 1825af8f421b6412e52530608097e39d2602195629fDan Gohman 183004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 184004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming parsed_command_line.AppendSwitch(switches::kProcessPerTab); 185004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 186004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming int tab_count = 1; 187004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming int host_count = 1; 188004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 189004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // Change the first tab to be the new tab page (TYPE_WEBUI). 190004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming GURL omnibox(chrome::kChromeUIOmniboxURL); 191004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming ui_test_utils::NavigateToURL(browser(), omnibox); 192004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 193004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(host_count, RenderProcessHostCount()); 194004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 195004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // Create a new TYPE_TABBED tab. It should be in its own process. 196004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming GURL page1("data:text/html,hello world1"); 197004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming ui_test_utils::WindowedTabAddedNotificationObserver observer1( 198004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming content::NotificationService::AllSources()); 199004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming chrome::ShowSingletonTab(browser(), page1); 200004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming observer1.Wait(); 201004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming tab_count++; 202004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming host_count++; 203004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 204004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(host_count, RenderProcessHostCount()); 205004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 206004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // Create another TYPE_TABBED tab. It should share the previous process. 207004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming GURL page2("data:text/html,hello world2"); 208004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming ui_test_utils::WindowedTabAddedNotificationObserver observer2( 209004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming content::NotificationService::AllSources()); 210004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming chrome::ShowSingletonTab(browser(), page2); 211004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming observer2.Wait(); 212004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming tab_count++; 213004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 214004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming EXPECT_EQ(host_count, RenderProcessHostCount()); 215004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 216004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // Create another omnibox tab. It should share the process with the other 217004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // WebUI. 218004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming ui_test_utils::NavigateToURLWithDisposition( 2196c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke browser(), omnibox, NEW_FOREGROUND_TAB, 2206c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 2216c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 2226c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 2236c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 2246c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2256c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Create another omnibox tab. It should share the process with the other 2266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // WebUI. 22763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman ui_test_utils::NavigateToURLWithDisposition( 2286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke browser(), omnibox, NEW_FOREGROUND_TAB, 2296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 2306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 2316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 2326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 233620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke} 234e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke 235620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke// We don't change process priorities on Mac or Posix because the user lacks the 236620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke// permission to raise a process' priority even after lowering it. 237620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke#if defined(OS_WIN) || defined(OS_LINUX) 238620ee02353d8b65959dc01a66b073adfcdef9eacBrian GaekeIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, Backgrounding) { 239620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke if (!base::Process::CanBackgroundProcesses()) { 240620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke LOG(ERROR) << "Can't background processes"; 241620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke return; 242620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke } 243620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 244620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke parsed_command_line.AppendSwitch(switches::kProcessPerTab); 245e9f6f2c0492af8097166f1b7d62f131f20ca5714Brian Gaeke 246620ee02353d8b65959dc01a66b073adfcdef9eacBrian Gaeke // Change the first tab to be the omnibox page (TYPE_WEBUI). 2476c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke GURL omnibox(chrome::kChromeUIOmniboxURL); 2486c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ui_test_utils::NavigateToURL(browser(), omnibox); 2496c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2506c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Create a new tab. It should be foreground. 2516c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke GURL page1("data:text/html,hello world1"); 2526c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke base::ProcessHandle pid1 = ShowSingletonTab(page1); 2536c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded()); 2546c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2556c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Create another tab. It should be foreground, and the first tab should 2566c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // now be background. 2576c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke GURL page2("data:text/html,hello world2"); 2586c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke base::ProcessHandle pid2 = ShowSingletonTab(page2); 2596c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_NE(pid1, pid2); 2606c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded()); 2616c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded()); 2626c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2636c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Navigate back to first page. It should be foreground again, and the second 2646c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // tab should be background. 2656c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(pid1, ShowSingletonTab(page1)); 2666c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded()); 2676c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_TRUE(base::Process(pid2).IsProcessBackgrounded()); 2686c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 2696c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#endif 2706c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2716c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// TODO(nasko): crbug.com/173137 2726c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#if defined(OS_WIN) 2736c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#define MAYBE_ProcessOverflow DISABLED_ProcessOverflow 2746c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#else 2756c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#define MAYBE_ProcessOverflow ProcessOverflow 2766c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#endif 2776c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2786c39a42b5c93b6d0af008dbafed6134d1deaa848Brian GaekeIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessOverflow) { 2796c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Set max renderers to 1 to force running out of processes. 2806c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::RenderProcessHost::SetMaxRendererProcessCount(1); 2816c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke TestProcessOverflow(); 2826c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 2836c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2846c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// Variation of the ProcessOverflow test, which is driven through command line 2856c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// parameter instead of direct function call into the class. 2869a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen WilsonIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTestWithCommandLine, 2876c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ProcessOverflow) { 2886c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke TestProcessOverflow(); 2896c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 2906c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 2916c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// Ensure that DevTools opened to debug DevTools is launched in a separate 2926c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke// process when --process-per-tab is set. See crbug.com/69873. 2936c39a42b5c93b6d0af008dbafed6134d1deaa848Brian GaekeIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, 29463b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman DevToolsOnSelfInOwnProcessPPT) { 2956c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#if defined(OS_WIN) && defined(USE_ASH) 2966c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Disable this test in Metro+Ash for now (http://crbug.com/262796). 297314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 298314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson return; 299314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson#endif 300314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson 301314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 3026c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke parsed_command_line.AppendSwitch(switches::kProcessPerTab); 3036c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 3046c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke int tab_count = 1; 3056c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke int host_count = 1; 3069a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 3079a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson GURL page1("data:text/html,hello world1"); 3089a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson ui_test_utils::WindowedTabAddedNotificationObserver observer1( 3099a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson content::NotificationService::AllSources()); 3109a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson chrome::ShowSingletonTab(browser(), page1); 3119a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson observer1.Wait(); 3129a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson tab_count++; 3139a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson host_count++; 3149a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 3159a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson EXPECT_EQ(host_count, RenderProcessHostCount()); 3169a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 3179a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // DevTools start in docked mode (no new tab), in a separate process. 3189a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson chrome::ToggleDevToolsWindow(browser(), DevToolsToggleAction::Inspect()); 3199a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson host_count++; 3209a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 3219a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson EXPECT_EQ(host_count, RenderProcessHostCount()); 3229a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 3239a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson RenderViewHost* devtools = FindFirstDevToolsHost(); 3249a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson DCHECK(devtools); 3259a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 3266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // DevTools start in a separate process. 3276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke DevToolsWindow::ToggleDevToolsWindow( 3286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke devtools, true, DevToolsToggleAction::Inspect()); 3296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke host_count++; 3306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 3316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 3326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 3336c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // close docked devtools 3346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::WindowedNotificationObserver close_observer( 3356c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 3366c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::Source<WebContents>(WebContents::FromRenderViewHost(devtools))); 3376c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 3386c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ToggleDevToolsWindow(browser(), DevToolsToggleAction::Toggle()); 3396c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke close_observer.Wait(); 3406c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 3416c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 34253621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman// Ensure that DevTools opened to debug DevTools is launched in a separate 34353621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman// process. See crbug.com/69873. 3446c39a42b5c93b6d0af008dbafed6134d1deaa848Brian GaekeIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, 3456c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke DevToolsOnSelfInOwnProcess) { 3466c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke#if defined(OS_WIN) && defined(USE_ASH) 3476c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Disable this test in Metro+Ash for now (http://crbug.com/262796). 34853621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 34953621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman return; 35053621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman#endif 35153621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman 35253621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman int tab_count = 1; 35353621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman int host_count = 1; 35453621a1a7376cba5d0a22c12a171933eb8c6d3f6Eli Friedman 3556c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke GURL page1("data:text/html,hello world1"); 3566c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ui_test_utils::WindowedTabAddedNotificationObserver observer1( 35763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman content::NotificationService::AllSources()); 3586c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ShowSingletonTab(browser(), page1); 35963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman observer1.Wait(); 3606c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke tab_count++; 3616c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke host_count++; 362314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 363314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson EXPECT_EQ(host_count, RenderProcessHostCount()); 364314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson 365314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson // DevTools start in docked mode (no new tab), in a separate process. 366314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson chrome::ToggleDevToolsWindow(browser(), DevToolsToggleAction::Inspect()); 3676c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke host_count++; 3686c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 3696c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(host_count, RenderProcessHostCount()); 3706c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 3716c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke RenderViewHost* devtools = FindFirstDevToolsHost(); 3726c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke DCHECK(devtools); 37363b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman 3746c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // DevTools start in a separate process. 3756c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke DevToolsWindow::ToggleDevToolsWindow( 37663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman devtools, true, DevToolsToggleAction::Inspect()); 3776c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke host_count++; 3786c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(tab_count, browser()->tab_strip_model()->count()); 379314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson EXPECT_EQ(host_count, RenderProcessHostCount()); 380314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson 381314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson // close docked devtools 382314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson content::WindowedNotificationObserver close_observer( 383314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 3846c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke content::Source<content::WebContents>( 3856c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebContents::FromRenderViewHost(devtools))); 3866c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke chrome::ToggleDevToolsWindow(browser(), DevToolsToggleAction::Toggle()); 3876c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke close_observer.Wait(); 388004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming} 389004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 390004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming// This class's goal is to close the browser window when a renderer process has 391004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming// crashed. It does so by monitoring WebContents for RenderProcessGone event and 392004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming// closing the passed in TabStripModel. This is used in the following test case. 393004c82ad7c0d2da761726f063373c28ffd18e66dMatt Flemingclass WindowDestroyer : public content::WebContentsObserver { 394004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming public: 395314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson WindowDestroyer(content::WebContents* web_contents, TabStripModel* model) 396314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson : content::WebContentsObserver(web_contents), 397004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming tab_strip_model_(model) { 398004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming } 399314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson 400314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE { 401314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson // Wait for the window to be destroyed, which will ensure all other 402004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // RenderViewHost objects are deleted before we return and proceed with 403004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming // the next iteration of notifications. 404004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming content::WindowedNotificationObserver observer( 405004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming chrome::NOTIFICATION_BROWSER_CLOSED, 406004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming content::NotificationService::AllSources()); 407004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming tab_strip_model_->CloseAllTabs(); 408004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming observer.Wait(); 409004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming } 410004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 411004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming private: 412004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming TabStripModel* tab_strip_model_; 413004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 414314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson DISALLOW_COPY_AND_ASSIGN(WindowDestroyer); 415314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson}; 416004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 417004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming// Test to ensure that while iterating through all listeners in 418314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson// RenderProcessHost and invalidating them, we remove them properly and don't 419314451326ad1ef89241b240a704e104897e4ee81Stephen Wilson// access already freed objects. See http://crbug.com/255524. 420314451326ad1ef89241b240a704e104897e4ee81Stephen WilsonIN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, 421004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming CloseAllTabsDuringProcessDied) { 422004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming GURL url(chrome::kChromeUIOmniboxURL); 423004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming 424004c82ad7c0d2da761726f063373c28ffd18e66dMatt Fleming ui_test_utils::NavigateToURL(browser(), url); 4259a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson ui_test_utils::NavigateToURLWithDisposition( 4266c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke browser(), url, NEW_BACKGROUND_TAB, 4276c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 4286c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 4296c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(2, browser()->tab_strip_model()->count()); 4306c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 4316c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebContents* wc1 = browser()->tab_strip_model()->GetWebContentsAt(0); 4326c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WebContents* wc2 = browser()->tab_strip_model()->GetWebContentsAt(1); 4336c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke EXPECT_EQ(wc1->GetRenderProcessHost(), wc2->GetRenderProcessHost()); 4346c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke 4356c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke // Create an object that will close the window on a process crash. 4366c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke WindowDestroyer destroyer(wc1, browser()->tab_strip_model()); 4379a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 4389a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // Use NOTIFICATION_BROWSER_CLOSED instead of NOTIFICATION_WINDOW_CLOSED, 4399a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // since the latter is not implemented on OSX and the test will timeout, 4409a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // causing it to fail. 4419a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson content::WindowedNotificationObserver observer( 4429a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson chrome::NOTIFICATION_BROWSER_CLOSED, 4439a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson content::NotificationService::AllSources()); 4449a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson 4459a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // Kill the renderer process, simulating a crash. This should the ProcessDied 4469a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // method to be called. Alternatively, RenderProcessHost::OnChannelError can 4479a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson // be called to directly force a call to ProcessDied. 4489a9ad77847c1be4ffc5ba6304e33ccecbf72e43fStephen Wilson base::KillProcess(wc1->GetRenderProcessHost()->GetHandle(), -1, true); 4494e9ca339b56f082c6b2d7dd7d91f704801c0d4fdMikhail Glushenkov 4506c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke observer.Wait(); 4516c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke} 4526c39a42b5c93b6d0af008dbafed6134d1deaa848Brian Gaeke