Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1218)

Unified Diff: content/browser/renderer_host/render_process_host_browsertest.cc

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: Change creation of storage partition to not break unittests with subtle threading issues Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/render_process_host_browsertest.cc
diff --git a/content/browser/renderer_host/render_process_host_browsertest.cc b/content/browser/renderer_host/render_process_host_browsertest.cc
index 866e829d1b74c93dad22fc5b77ee71e84cf19598..686c62a684e13c510772edd1c56cd705cea53992 100644
--- a/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -17,6 +17,10 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_service.mojom.h"
#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_browser_context.h"
+#include "content/shell/browser/shell_browser_main_parts.h"
+#include "content/shell/browser/shell_content_browser_client.h"
+#include "content/test/test_content_browser_client.h"
#include "media/base/bind_to_current_loop.h"
#include "media/base/media_switches.h"
#include "media/base/test_data_util.h"
@@ -73,6 +77,36 @@ class RenderProcessHostTest : public ContentBrowserTest,
base::Closure process_exit_callback_;
};
+// A mock ContentBrowserClient that only considers a spare renderer to be a
+// suitable host.
+class SpareRendererContentBrowserClient : public TestContentBrowserClient {
+ public:
+ bool IsSuitableHost(RenderProcessHost* process_host,
+ const GURL& site_url) override {
+ if (RenderProcessHostImpl::GetSpareRenderProcessHostForTesting()) {
+ return process_host ==
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ }
+ return true;
+ }
+};
+
+// A mock ContentBrowserClient that only considers a non-spare renderer to be a
+// suitable host, but otherwise tries to reuse processes.
+class NonSpareRendererContentBrowserClient : public TestContentBrowserClient {
+ public:
+ bool IsSuitableHost(RenderProcessHost* process_host,
+ const GURL& site_url) override {
+ return RenderProcessHostImpl::GetSpareRenderProcessHostForTesting() !=
+ process_host;
+ }
+
+ bool ShouldTryToUseExistingProcessHost(BrowserContext* context,
+ const GURL& url) override {
+ return true;
+ }
+};
+
// Sometimes the renderer process's ShutdownRequest (corresponding to the
// ViewMsg_WasSwappedOut from a previous navigation) doesn't arrive until after
// the browser process decides to re-use the renderer for a new purpose. This
@@ -130,6 +164,144 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
EXPECT_EQ(2, RenderProcessHostCount());
}
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostTaken) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->browser_context());
+ RenderProcessHost* spare_renderer =
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ EXPECT_NE(nullptr, spare_renderer);
+
+ GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
+ Shell* window = CreateBrowser();
+ NavigateToURL(window, test_url);
+
+ EXPECT_EQ(spare_renderer,
+ window->web_contents()->GetMainFrame()->GetProcess());
+
+ // The spare render process host should no longer be available.
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+}
+
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostNotTaken) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->off_the_record_browser_context());
+ RenderProcessHost* spare_renderer =
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
+ Shell* window = CreateBrowser();
+ NavigateToURL(window, test_url);
+
+ // There should have been another process created for the navigation.
+ EXPECT_NE(spare_renderer,
+ window->web_contents()->GetMainFrame()->GetProcess());
+
+ // The spare RenderProcessHost should have been cleaned up. Note this
+ // behavior is identical to what would have happened if the RenderProcessHost
+ // were taken.
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+}
+
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRenderProcessHostKilled) {
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->browser_context());
+
+ RenderProcessHost* spare_renderer =
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ mojom::TestServicePtr service;
+ ASSERT_NE(nullptr, spare_renderer);
+ BindInterface(spare_renderer, &service);
+
+ base::RunLoop run_loop;
+ set_process_exit_callback(run_loop.QuitClosure());
+ spare_renderer->AddObserver(this); // For process_exit_callback.
+
+ // Should reply with a bad message and cause process death.
+ service->DoSomething(base::Bind(&base::DoNothing));
+ run_loop.Run();
+
+ // The spare RenderProcessHost should disappear when its process dies.
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+}
+
+// Test that the spare renderer works correctly when the limit on the maximum
+// number of processes is small.
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
+ SpareRendererSurpressedMaxProcesses) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ SpareRendererContentBrowserClient browser_client;
+ ContentBrowserClient* old_client =
+ SetBrowserClientForTesting(&browser_client);
+
+ RenderProcessHost::SetMaxRendererProcessCount(1);
+
+ // A process is created with shell startup, so with a maximum of one renderer
+ // process the spare RPH should not be created.
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->browser_context());
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+
+ // A spare RPH should be created with a max of 2 renderer processes.
+ RenderProcessHost::SetMaxRendererProcessCount(2);
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->browser_context());
+ RenderProcessHost* spare_renderer =
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ EXPECT_NE(nullptr, spare_renderer);
+
+ // Thanks to the injected SpareRendererContentBrowserClient and the limit on
+ // processes, the spare RPH will always be used via GetExistingProcessHost()
+ // rather than picked up via MaybeTakeSpareRenderProcessHost().
+ GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
+ Shell* new_window = CreateBrowser();
+ NavigateToURL(new_window, test_url);
+ // The spare RPH should have been dropped during CreateBrowser() and given to
+ // the new window.
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+ EXPECT_EQ(spare_renderer,
+ new_window->web_contents()->GetMainFrame()->GetProcess());
+
+ // Revert to the default process limit and original ContentBrowserClient.
+ RenderProcessHost::SetMaxRendererProcessCount(0);
+ SetBrowserClientForTesting(old_client);
+}
+
+// Check that the spare renderer is dropped if an existing process is reused.
+IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, SpareRendererOnProcessReuse) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ NonSpareRendererContentBrowserClient browser_client;
+ ContentBrowserClient* old_client =
+ SetBrowserClientForTesting(&browser_client);
+
+ RenderProcessHost::WarmupSpareRenderProcessHost(
+ ShellContentBrowserClient::Get()->browser_context());
+ RenderProcessHost* spare_renderer =
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting();
+ EXPECT_NE(nullptr, spare_renderer);
+
+ // This should resuse the existing process and cause the spare renderer to be
+ // dropped.
+ Shell* new_browser = CreateBrowser();
+ EXPECT_EQ(shell()->web_contents()->GetMainFrame()->GetProcess(),
+ new_browser->web_contents()->GetMainFrame()->GetProcess());
+ EXPECT_NE(spare_renderer,
+ new_browser->web_contents()->GetMainFrame()->GetProcess());
+ EXPECT_EQ(nullptr,
+ RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
+
+ SetBrowserClientForTesting(old_client);
+}
+
class ShellCloser : public RenderProcessHostObserver {
public:
ShellCloser(Shell* shell, std::string* logging_string)
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.cc ('k') | content/browser/renderer_host/render_process_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698