Commit 0c13fe0c authored by jam@chromium.org's avatar jam@chromium.org

Move the render process host tests in content to chrome. These test chrome...

Move the render process host tests in content to chrome. These test chrome specific behavior with things like extensions/webui/singleton tabs.

BUG=90448
Review URL: https://chromiumcodereview.appspot.com/10820056

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148852 0039d316-1c4b-4281-b951-d872f2087c98
parent f9d1f33d
......@@ -6,6 +6,7 @@
#include "chrome/browser/debugger/devtools_window.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
......@@ -61,7 +62,218 @@ RenderViewHost* FindFirstDevToolsHost() {
} // namespace
typedef InProcessBrowserTest ChromeRenderProcessHostTest;
class ChromeRenderProcessHostTest : public InProcessBrowserTest {
public:
ChromeRenderProcessHostTest() {}
// Show a tab, activating the current one if there is one, and wait for
// the renderer process to be created or foregrounded, returning the process
// handle.
base::ProcessHandle ShowSingletonTab(const GURL& page) {
chrome::ShowSingletonTab(browser(), page);
WebContents* wc = chrome::GetActiveWebContents(browser());
CHECK(wc->GetURL() == page);
// Ensure that the backgrounding / foregrounding gets a chance to run.
content::BrowserThread::PostTaskAndReply(
content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
base::Bind(&base::DoNothing), MessageLoop::QuitClosure());
MessageLoop::current()->Run();
return wc->GetRenderProcessHost()->GetHandle();
}
// When we hit the max number of renderers, verify that the way we do process
// sharing behaves correctly. In particular, this test is verifying that even
// when we hit the max process limit, that renderers of each type will wind up
// in a process of that type, even if that means creating a new process.
void TestProcessOverflow() {
int tab_count = 1;
int host_count = 1;
WebContents* tab1 = NULL;
WebContents* tab2 = NULL;
content::RenderProcessHost* rph1 = NULL;
content::RenderProcessHost* rph2 = NULL;
content::RenderProcessHost* rph3 = NULL;
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(chrome::kChromeUINewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph1 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), newtab);
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create a new TYPE_TABBED tab. It should be in its own process.
GURL page1("data:text/html,hello world1");
chrome::ShowSingletonTab(browser(), page1);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph2 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), page1);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_NE(rph1, rph2);
// Create another TYPE_TABBED tab. It should share the previous process.
GURL page2("data:text/html,hello world2");
chrome::ShowSingletonTab(browser(), page2);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab2 = chrome::GetWebContentsAt(browser(), tab_count - 1);
EXPECT_EQ(tab2->GetURL(), page2);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_EQ(tab2->GetRenderProcessHost(), rph2);
// Create another TYPE_WEBUI tab. It should share the process with newtab.
// Note: intentionally create this tab after the TYPE_TABBED tabs to
// exercise bug 43448 where extension and WebUI tabs could get combined into
// normal renderers.
GURL history(chrome::kChromeUIHistoryURL);
chrome::ShowSingletonTab(browser(), history);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab2 = chrome::GetWebContentsAt(browser(), tab_count - 1);
// Use chrome://chrome/history/ since the URL gets rewritten.
EXPECT_EQ(tab2->GetURL(), GURL("chrome://chrome/history/"));
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_EQ(tab2->GetRenderProcessHost(), rph1);
// Create a TYPE_EXTENSION tab. It should be in its own process.
// (the bookmark manager is implemented as an extension)
GURL bookmarks(chrome::kChromeUIBookmarksURL);
chrome::ShowSingletonTab(browser(), bookmarks);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph3 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), bookmarks);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_NE(rph1, rph3);
EXPECT_NE(rph2, rph3);
}
};
class ChromeRenderProcessHostTestWithCommandLine
: public ChromeRenderProcessHostTest {
protected:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1");
}
};
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, ProcessPerTab) {
// Set max renderers to 1 to force running out of processes.
content::RenderProcessHost::SetMaxRendererProcessCount(1);
CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
parsed_command_line.AppendSwitch(switches::kProcessPerTab);
int tab_count = 1;
int host_count = 1;
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(chrome::kChromeUINewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create a new TYPE_TABBED tab. It should be in its own process.
GURL page1("data:text/html,hello world1");
chrome::ShowSingletonTab(browser(), page1);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another TYPE_TABBED tab. It should share the previous process.
GURL page2("data:text/html,hello world2");
chrome::ShowSingletonTab(browser(), page2);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another new tab. It should share the process with the other WebUI.
chrome::NewTab(browser());
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another new tab. It should share the process with the other WebUI.
chrome::NewTab(browser());
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
}
// We don't change process priorities on Mac or Posix because the user lacks the
// permission to raise a process' priority even after lowering it.
#if defined(OS_WIN) || defined(OS_LINUX)
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, Backgrounding) {
if (!base::Process::CanBackgroundProcesses()) {
LOG(ERROR) << "Can't background processes";
return;
}
CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
parsed_command_line.AppendSwitch(switches::kProcessPerTab);
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(chrome::kChromeUINewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
// Create a new tab. It should be foreground.
GURL page1("data:text/html,hello world1");
base::ProcessHandle pid1 = ShowSingletonTab(page1);
EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
// Create another tab. It should be foreground, and the first tab should
// now be background.
GURL page2("data:text/html,hello world2");
base::ProcessHandle pid2 = ShowSingletonTab(page2);
EXPECT_NE(pid1, pid2);
EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded());
EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded());
// Navigate back to first page. It should be foreground again, and the second
// tab should be background.
EXPECT_EQ(pid1, ShowSingletonTab(page1));
EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
EXPECT_TRUE(base::Process(pid2).IsProcessBackgrounded());
}
#endif
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, ProcessOverflow) {
// Set max renderers to 1 to force running out of processes.
content::RenderProcessHost::SetMaxRendererProcessCount(1);
TestProcessOverflow();
}
// Variation of the ProcessOverflow test, which is driven through command line
// parameter instead of direct function call into the class.
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTestWithCommandLine,
ProcessOverflow) {
TestProcessOverflow();
}
// Ensure that DevTools opened to debug DevTools is launched in a separate
// process when --process-per-tab is set. See crbug.com/69873.
......
......@@ -2602,7 +2602,6 @@
'msvs_cygwin_dirs': ['<(DEPTH)/third_party/cygwin'],
'dependencies': [
'browser',
'../sync/protocol/sync_proto.gyp:sync_proto',
'chrome_resources.gyp:chrome_resources',
'chrome_resources.gyp:chrome_strings',
'chrome_resources.gyp:packed_extra_resources',
......@@ -2616,6 +2615,7 @@
'../net/net.gyp:net',
'../net/net.gyp:net_test_support',
'../skia/skia.gyp:skia',
'../sync/protocol/sync_proto.gyp:sync_proto',
'../sync/sync.gyp:test_support_syncapi_service',
'../testing/gmock.gyp:gmock',
'../testing/gtest.gyp:gtest',
......@@ -3036,7 +3036,6 @@
# TODO(craig): Rename this and run from base_unittests when the test
# is safe to run there. See http://crbug.com/78722 for details.
'../base/files/file_path_watcher_browsertest.cc',
'../content/browser/renderer_host/render_process_host_browsertest.cc',
'../content/browser/renderer_host/render_view_host_manager_browsertest.cc',
'../content/browser/renderer_host/resource_dispatcher_host_browsertest.cc',
],
......
......@@ -176,12 +176,6 @@ TEST_F(ChildProcessSecurityPolicyTest, AboutTest) {
p->GrantRequestURL(kRendererID, GURL(content::kTestNewTabURL));
EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL(content::kTestNewTabURL)));
p->GrantRequestURL(kRendererID, GURL(content::kTestHistoryURL));
EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL(content::kTestHistoryURL)));
p->GrantRequestURL(kRendererID, GURL(content::kTestBookmarksURL));
EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL(content::kTestBookmarksURL)));
p->Remove(kRendererID);
}
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/test_url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_switches.h"
using content::WebContents;
void PostQuit(MessageLoop* loop) {
loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
}
class RenderProcessHostTest : public InProcessBrowserTest {
public:
RenderProcessHostTest() {}
int RenderProcessHostCount() {
content::RenderProcessHost::iterator hosts =
content::RenderProcessHost::AllHostsIterator();
int count = 0;
while (!hosts.IsAtEnd()) {
if (hosts.GetCurrentValue()->HasConnection())
count++;
hosts.Advance();
}
return count;
}
// Show a tab, activating the current one if there is one, and wait for
// the renderer process to be created or foregrounded, returning the process
// handle.
base::ProcessHandle ShowSingletonTab(const GURL& page) {
chrome::ShowSingletonTab(browser(), page);
WebContents* wc = chrome::GetActiveWebContents(browser());
CHECK(wc->GetURL() == page);
// Ensure that the backgrounding / foregrounding gets a chance to run.
content::BrowserThread::PostTaskAndReply(
content::BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
base::Bind(&base::DoNothing), MessageLoop::QuitClosure());
MessageLoop::current()->Run();
return wc->GetRenderProcessHost()->GetHandle();
}
// When we hit the max number of renderers, verify that the way we do process
// sharing behaves correctly. In particular, this test is verifying that even
// when we hit the max process limit, that renderers of each type will wind up
// in a process of that type, even if that means creating a new process.
void TestProcessOverflow() {
int tab_count = 1;
int host_count = 1;
WebContents* tab1 = NULL;
WebContents* tab2 = NULL;
content::RenderProcessHost* rph1 = NULL;
content::RenderProcessHost* rph2 = NULL;
content::RenderProcessHost* rph3 = NULL;
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(content::kTestNewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph1 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), newtab);
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create a new TYPE_TABBED tab. It should be in its own process.
GURL page1("data:text/html,hello world1");
chrome::ShowSingletonTab(browser(), page1);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph2 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), page1);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_NE(rph1, rph2);
// Create another TYPE_TABBED tab. It should share the previous process.
GURL page2("data:text/html,hello world2");
chrome::ShowSingletonTab(browser(), page2);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab2 = chrome::GetWebContentsAt(browser(), tab_count - 1);
EXPECT_EQ(tab2->GetURL(), page2);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_EQ(tab2->GetRenderProcessHost(), rph2);
// Create another TYPE_WEBUI tab. It should share the process with newtab.
// Note: intentionally create this tab after the TYPE_TABBED tabs to
// exercise bug 43448 where extension and WebUI tabs could get combined into
// normal renderers.
GURL history(content::kTestHistoryURL);
chrome::ShowSingletonTab(browser(), history);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab2 = chrome::GetWebContentsAt(browser(), tab_count - 1);
EXPECT_EQ(tab2->GetURL(), history);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_EQ(tab2->GetRenderProcessHost(), rph1);
// Create a TYPE_EXTENSION tab. It should be in its own process.
// (the bookmark manager is implemented as an extension)
GURL bookmarks(content::kTestBookmarksURL);
chrome::ShowSingletonTab(browser(), bookmarks);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
tab1 = chrome::GetWebContentsAt(browser(), tab_count - 1);
rph3 = tab1->GetRenderProcessHost();
EXPECT_EQ(tab1->GetURL(), bookmarks);
EXPECT_EQ(host_count, RenderProcessHostCount());
EXPECT_NE(rph1, rph3);
EXPECT_NE(rph2, rph3);
}
};
class RenderProcessHostTestWithCommandLine : public RenderProcessHostTest {
protected:
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1");
}
};
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessPerTab) {
// Set max renderers to 1 to force running out of processes.
content::RenderProcessHost::SetMaxRendererProcessCount(1);
CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
parsed_command_line.AppendSwitch(switches::kProcessPerTab);
int tab_count = 1;
int host_count = 1;
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(content::kTestNewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create a new TYPE_TABBED tab. It should be in its own process.
GURL page1("data:text/html,hello world1");
chrome::ShowSingletonTab(browser(), page1);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
host_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another TYPE_TABBED tab. It should share the previous process.
GURL page2("data:text/html,hello world2");
chrome::ShowSingletonTab(browser(), page2);
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another new tab. It should share the process with the other WebUI.
chrome::NewTab(browser());
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
// Create another new tab. It should share the process with the other WebUI.
chrome::NewTab(browser());
if (browser()->tab_count() == tab_count)
ui_test_utils::WaitForNewTab(browser());
tab_count++;
EXPECT_EQ(tab_count, browser()->tab_count());
EXPECT_EQ(host_count, RenderProcessHostCount());
}
// We don't change process priorities on Mac or Posix because the user lacks the
// permission to raise a process' priority even after lowering it.
#if defined(OS_WIN) || defined(OS_LINUX)
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, Backgrounding) {
if (!base::Process::CanBackgroundProcesses()) {
LOG(ERROR) << "Can't background processes";
return;
}
CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
parsed_command_line.AppendSwitch(switches::kProcessPerTab);
// Change the first tab to be the new tab page (TYPE_WEBUI).
GURL newtab(content::kTestNewTabURL);
ui_test_utils::NavigateToURL(browser(), newtab);
// Create a new tab. It should be foreground.
GURL page1("data:text/html,hello world1");
base::ProcessHandle pid1 = ShowSingletonTab(page1);
EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
// Create another tab. It should be foreground, and the first tab should
// now be background.
GURL page2("data:text/html,hello world2");
base::ProcessHandle pid2 = ShowSingletonTab(page2);
EXPECT_NE(pid1, pid2);
EXPECT_TRUE(base::Process(pid1).IsProcessBackgrounded());
EXPECT_FALSE(base::Process(pid2).IsProcessBackgrounded());
// Navigate back to first page. It should be foreground again, and the second
// tab should be background.
EXPECT_EQ(pid1, ShowSingletonTab(page1));
EXPECT_FALSE(base::Process(pid1).IsProcessBackgrounded());
EXPECT_TRUE(base::Process(pid2).IsProcessBackgrounded());
}
#endif
IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ProcessOverflow) {
// Set max renderers to 1 to force running out of processes.
content::RenderProcessHost::SetMaxRendererProcessCount(1);
TestProcessOverflow();
}
// Variation of the ProcessOverflow test, which is driven through command line
// parameter instead of direct function call into the class.
IN_PROC_BROWSER_TEST_F(RenderProcessHostTestWithCommandLine, ProcessOverflow) {
TestProcessOverflow();
}
......@@ -6,9 +6,6 @@
namespace content {
const char kTestCacheURL[] = "about:cache";
const char kTestNewTabURL[] = "chrome://newtab";
const char kTestHistoryURL[] = "chrome://chrome/history/";
const char kTestBookmarksURL[] = "chrome://bookmarks/";
} // namespace content
......@@ -8,28 +8,9 @@
// Contains constants for known URLs and portions thereof.
namespace content {
// Various special URLs used for testing. They have the same values as the URLs
// in chrome/common/url_constants.h, but are duplicated here so that the reverse
// dependency can be broken.
// Various URLs used in security policy testing.
extern const char kTestCacheURL[];
// The NTP is assumed in several tests to have the property that it is WebUI.
extern const char kTestNewTabURL[];
// The History page is assumed in several tests to have the property that it is
// WebUI. That's the case only with the ChromeBrowserContentClient
// implementation of WebUIFactory. With a different implementation that might
// not be the case.
extern const char kTestHistoryURL[];
// The Bookmarks page is assumed in several tests to have the property that it
// is an extension. That's the case only with the ChromeBrowserContentClient
// implementation of WebUIFactory. With a different implementation that might
// not be the case.
extern const char kTestBookmarksURL[];
} // namespace content
#endif // CONTENT_COMMON_TEST_URL_CONSTANTS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment