Commit bbc55f66 authored by Lukasz Anforowicz's avatar Lukasz Anforowicz Committed by Commit Bot

Enable ChromeRenderProcessHostBackgroundingTest.MultipleTabs on Linux.

While |base::Process::CanBackgroundProcesses()| returns false on Linux,
we are still able to verify whether processes are backgrounded by
looking at RenderProcessHost::IsProcessBackgrounded().  This
verification is not as thorough/end-to-end as what we can do on other
platforms, but it is sufficient to enable
ChromeRenderProcessHostBackgroundingTest.MultipleTabs test on Linux.

Bug: 881812, 883468
Change-Id: I536ea10a279d7138d632b8846dc2a0d8e507c001
Reviewed-on: https://chromium-review.googlesource.com/1222249
Commit-Queue: Łukasz Anforowicz <lukasza@chromium.org>
Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#591363}
parent 20ae78ee
...@@ -92,22 +92,21 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest { ...@@ -92,22 +92,21 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest {
ChromeRenderProcessHostTest() {} ChromeRenderProcessHostTest() {}
// Show a tab, activating the current one if there is one, and wait for // 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 // the renderer process to be created or foregrounded, returning the
// handle. // WebContents associated with the tab.
base::Process ShowSingletonTab(const GURL& page) { WebContents* ShowSingletonTab(const GURL& page) {
::ShowSingletonTab(browser(), page); ::ShowSingletonTab(browser(), page);
WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents(); WebContents* wc = browser()->tab_strip_model()->GetActiveWebContents();
CHECK(wc->GetURL() == page); CHECK(wc->GetURL() == page);
WaitForLauncherThread(); WaitForLauncherThread();
WaitForMessageProcessing(wc); WaitForMessageProcessing(wc);
return ProcessFromHandle( return wc;
wc->GetMainFrame()->GetProcess()->GetProcess().Handle());
} }
// Loads the given url in a new background tab and returns the handle of its // Loads the given url in a new background tab and returns the WebContents
// renderer. // associated with the tab.
base::Process OpenBackgroundTab(const GURL& page) { WebContents* OpenBackgroundTab(const GURL& page) {
ui_test_utils::NavigateToURLWithDisposition( ui_test_utils::NavigateToURLWithDisposition(
browser(), page, WindowOpenDisposition::NEW_BACKGROUND_TAB, browser(), page, WindowOpenDisposition::NEW_BACKGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
...@@ -119,8 +118,7 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest { ...@@ -119,8 +118,7 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest {
WaitForLauncherThread(); WaitForLauncherThread();
WaitForMessageProcessing(wc); WaitForMessageProcessing(wc);
return ProcessFromHandle( return wc;
wc->GetMainFrame()->GetProcess()->GetProcess().Handle());
} }
// Ensures that the backgrounding / foregrounding gets a chance to run. // Ensures that the backgrounding / foregrounding gets a chance to run.
...@@ -236,15 +234,25 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest { ...@@ -236,15 +234,25 @@ class ChromeRenderProcessHostTest : public extensions::ExtensionBrowserTest {
EXPECT_NE(rph1, rph3); EXPECT_NE(rph1, rph3);
EXPECT_NE(rph2, rph3); EXPECT_NE(rph2, rph3);
} }
private:
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostTest);
}; };
class ChromeRenderProcessHostTestWithCommandLine class ChromeRenderProcessHostTestWithCommandLine
: public ChromeRenderProcessHostTest { : public ChromeRenderProcessHostTest {
public:
ChromeRenderProcessHostTestWithCommandLine() = default;
~ChromeRenderProcessHostTestWithCommandLine() override = default;
protected: protected:
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
ChromeRenderProcessHostTest::SetUpCommandLine(command_line); ChromeRenderProcessHostTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); command_line->AppendSwitchASCII(switches::kRendererProcessLimit, "1");
} }
private:
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostTestWithCommandLine);
}; };
// Disable on Windows and Mac due to ongoing flakiness. (crbug.com/442785) // Disable on Windows and Mac due to ongoing flakiness. (crbug.com/442785)
...@@ -317,99 +325,125 @@ IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessPerTab) { ...@@ -317,99 +325,125 @@ IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostTest, MAYBE_ProcessPerTab) {
class ChromeRenderProcessHostBackgroundingTest class ChromeRenderProcessHostBackgroundingTest
: public ChromeRenderProcessHostTest { : public ChromeRenderProcessHostTest {
public: public:
ChromeRenderProcessHostBackgroundingTest() = default;
~ChromeRenderProcessHostBackgroundingTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override { void SetUpCommandLine(base::CommandLine* command_line) override {
ChromeRenderProcessHostTest::SetUpCommandLine(command_line); ChromeRenderProcessHostTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kProcessPerTab); command_line->AppendSwitch(switches::kProcessPerTab);
} }
void VerifyProcessIsBackgrounded(WebContents* web_contents) {
constexpr bool kExpectedIsBackground = true;
VerifyProcessPriority(web_contents->GetMainFrame()->GetProcess(),
kExpectedIsBackground);
}
void VerifyProcessIsForegrounded(WebContents* web_contents) {
constexpr bool kExpectedIsBackground = false;
VerifyProcessPriority(web_contents->GetMainFrame()->GetProcess(),
kExpectedIsBackground);
}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(embedded_test_server()->Start());
} }
private:
void VerifyProcessPriority(content::RenderProcessHost* process,
bool expected_is_backgrounded) {
EXPECT_TRUE(process->IsInitializedAndNotDead());
EXPECT_EQ(expected_is_backgrounded, process->IsProcessBackgrounded());
if (base::Process::CanBackgroundProcesses()) {
base::Process p = ProcessFromHandle(process->GetProcess().Handle());
ASSERT_TRUE(p.IsValid());
#if defined(OS_MACOSX)
base::PortProvider* port_provider =
content::BrowserChildProcessHost::GetPortProvider();
EXPECT_EQ(expected_is_backgrounded,
p.IsProcessBackgrounded(port_provider));
#else
EXPECT_EQ(expected_is_backgrounded, p.IsProcessBackgrounded());
#endif
}
}
DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessHostBackgroundingTest);
}; };
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, MultipleTabs) { #define EXPECT_PROCESS_IS_BACKGROUNDED(process_or_tab) \
// This test is invalid on platforms that can't background. do { \
if (!base::Process::CanBackgroundProcesses()) SCOPED_TRACE("Verifying that |" #process_or_tab "| is backgrounded..."); \
return; VerifyProcessIsBackgrounded(process_or_tab); \
} while (0);
#if defined(OS_MACOSX) #define EXPECT_PROCESS_IS_FOREGROUNDED(process_or_tab) \
base::PortProvider* port_provider = do { \
content::BrowserChildProcessHost::GetPortProvider(); SCOPED_TRACE("Verifying that |" #process_or_tab "| is foregrounded..."); \
#endif // defined(OS_MACOSX) VerifyProcessIsForegrounded(process_or_tab); \
} while (0);
IN_PROC_BROWSER_TEST_F(ChromeRenderProcessHostBackgroundingTest, MultipleTabs) {
// Change the first tab to be the omnibox page (TYPE_WEBUI). // Change the first tab to be the omnibox page (TYPE_WEBUI).
GURL omnibox(chrome::kChromeUIOmniboxURL); GURL omnibox(chrome::kChromeUIOmniboxURL);
ui_test_utils::NavigateToURL(browser(), omnibox); ui_test_utils::NavigateToURL(browser(), omnibox);
// Create a new tab. It should be foreground. // Create a new tab. It should be foreground.
GURL page1("data:text/html,hello world1"); GURL page1("data:text/html,hello world1");
base::Process process1 = ShowSingletonTab(page1); WebContents* tab1 = ShowSingletonTab(page1);
ASSERT_TRUE(process1.IsValid()); {
#if defined(OS_MACOSX) SCOPED_TRACE("TEST STEP: Single tab");
EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider)); EXPECT_PROCESS_IS_FOREGROUNDED(tab1);
#else }
EXPECT_FALSE(process1.IsProcessBackgrounded());
#endif
// Create another tab. It should be foreground, and the first tab should // Create another tab. It should be foreground, and the first tab should
// now be background. // now be background.
GURL page2("data:text/html,hello world2"); GURL page2("data:text/html,hello world2");
base::Process process2 = ShowSingletonTab(page2); WebContents* tab2 = ShowSingletonTab(page2);
ASSERT_TRUE(process2.IsValid()); {
EXPECT_NE(process1.Pid(), process2.Pid()); SCOPED_TRACE("TEST STEP: 2nd tab opened in foreground");
#if defined(OS_MACOSX) EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
EXPECT_TRUE(process1.IsProcessBackgrounded(port_provider)); tab2->GetMainFrame()->GetProcess());
EXPECT_FALSE(process2.IsProcessBackgrounded(port_provider)); EXPECT_PROCESS_IS_BACKGROUNDED(tab1);
#else EXPECT_PROCESS_IS_FOREGROUNDED(tab2);
EXPECT_TRUE(process1.IsProcessBackgrounded()); }
EXPECT_FALSE(process2.IsProcessBackgrounded());
#endif // defined(OS_MACOSX)
// Load another tab in background. The renderer of the new tab should be // Load another tab in background. The renderer of the new tab should be
// backgrounded, while visibility of the other renderers should not change. // backgrounded, while visibility of the other renderers should not change.
GURL page3("data:text/html,hello world3"); GURL page3("data:text/html,hello world3");
base::Process process3 = OpenBackgroundTab(page3); WebContents* tab3 = OpenBackgroundTab(page3);
ASSERT_TRUE(process3.IsValid()); {
EXPECT_NE(process3.Pid(), process1.Pid()); SCOPED_TRACE("TEST STEP: 3rd tab opened in background");
EXPECT_NE(process3.Pid(), process2.Pid()); EXPECT_NE(tab1->GetMainFrame()->GetProcess(),
#if defined(OS_MACOSX) tab3->GetMainFrame()->GetProcess());
EXPECT_TRUE(process1.IsProcessBackgrounded(port_provider)); EXPECT_NE(tab2->GetMainFrame()->GetProcess(),
EXPECT_FALSE(process2.IsProcessBackgrounded(port_provider)); tab3->GetMainFrame()->GetProcess());
EXPECT_TRUE(process3.IsProcessBackgrounded(port_provider)); EXPECT_PROCESS_IS_BACKGROUNDED(tab1);
EXPECT_PROCESS_IS_FOREGROUNDED(tab2);
EXPECT_PROCESS_IS_BACKGROUNDED(tab3);
}
// Navigate back to the first page. Its renderer should be in foreground // Navigate back to the first page. Its renderer should be in foreground
// again while the other renderers should be backgrounded. // again while the other renderers should be backgrounded.
EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid()); ShowSingletonTab(page1);
EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider)); {
EXPECT_TRUE(process2.IsProcessBackgrounded(port_provider)); SCOPED_TRACE("TEST STEP: First tab activated again");
EXPECT_TRUE(process3.IsProcessBackgrounded(port_provider)); EXPECT_PROCESS_IS_FOREGROUNDED(tab1);
EXPECT_PROCESS_IS_BACKGROUNDED(tab2);
// Confirm that |process3| remains backgrounded after being shown/hidden. EXPECT_PROCESS_IS_BACKGROUNDED(tab3);
EXPECT_EQ(process3.Pid(), ShowSingletonTab(page3).Pid()); }
EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
EXPECT_FALSE(process1.IsProcessBackgrounded(port_provider));
EXPECT_TRUE(process2.IsProcessBackgrounded(port_provider));
EXPECT_TRUE(process3.IsProcessBackgrounded(port_provider));
#else
EXPECT_TRUE(process1.IsProcessBackgrounded());
EXPECT_FALSE(process2.IsProcessBackgrounded());
EXPECT_TRUE(process3.IsProcessBackgrounded());
// Navigate back to the first page. Its renderer should be in foreground // Confirm that |tab3| remains backgrounded after being shown/hidden.
// again while the other renderers should be backgrounded. ShowSingletonTab(page3);
EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid()); ShowSingletonTab(page1);
EXPECT_FALSE(process1.IsProcessBackgrounded()); {
EXPECT_TRUE(process2.IsProcessBackgrounded()); SCOPED_TRACE("TEST STEP: Third tab activated and deactivated");
EXPECT_TRUE(process3.IsProcessBackgrounded()); EXPECT_PROCESS_IS_FOREGROUNDED(tab1);
EXPECT_PROCESS_IS_BACKGROUNDED(tab2);
// Confirm that |process3| remains backgrounded after being shown/hidden. EXPECT_PROCESS_IS_BACKGROUNDED(tab3);
EXPECT_EQ(process3.Pid(), ShowSingletonTab(page3).Pid()); }
EXPECT_EQ(process1.Pid(), ShowSingletonTab(page1).Pid());
EXPECT_FALSE(process1.IsProcessBackgrounded());
EXPECT_TRUE(process2.IsProcessBackgrounded());
EXPECT_TRUE(process3.IsProcessBackgrounded());
#endif
} }
// TODO(nasko): crbug.com/173137 // TODO(nasko): crbug.com/173137
...@@ -631,7 +665,9 @@ class ChromeRenderProcessHostBackgroundingTestWithAudio ...@@ -631,7 +665,9 @@ class ChromeRenderProcessHostBackgroundingTestWithAudio
->GetProcess() ->GetProcess()
->GetProcess() ->GetProcess()
.Handle()); .Handle());
no_audio_process_ = ShowSingletonTab(no_audio_url_); WebContents* wc = ShowSingletonTab(no_audio_url_);
no_audio_process_ = ProcessFromHandle(
wc->GetMainFrame()->GetProcess()->GetProcess().Handle());
ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid()); ASSERT_NE(audio_process_.Pid(), no_audio_process_.Pid());
ASSERT_TRUE(no_audio_process_.IsValid()); ASSERT_TRUE(no_audio_process_.IsValid());
ASSERT_TRUE(audio_process_.IsValid()); ASSERT_TRUE(audio_process_.IsValid());
......
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