Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / render_process_host_browsertest.cc
blobb1c89a577bb1b1765e9ec8bb464a98f317db9188
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/render_process_host_impl.h"
6 #include "content/common/child_process_messages.h"
7 #include "content/public/browser/render_process_host.h"
8 #include "content/public/browser/render_process_host_observer.h"
9 #include "content/public/browser/render_view_host.h"
10 #include "content/public/browser/web_contents.h"
11 #include "content/public/common/url_constants.h"
12 #include "content/public/test/content_browser_test.h"
13 #include "content/public/test/content_browser_test_utils.h"
14 #include "content/shell/browser/shell.h"
15 #include "net/test/embedded_test_server/embedded_test_server.h"
17 namespace content {
18 namespace {
20 int RenderProcessHostCount() {
21 content::RenderProcessHost::iterator hosts =
22 content::RenderProcessHost::AllHostsIterator();
23 int count = 0;
24 while (!hosts.IsAtEnd()) {
25 if (hosts.GetCurrentValue()->HasConnection())
26 count++;
27 hosts.Advance();
29 return count;
32 class RenderProcessHostTest : public ContentBrowserTest,
33 public RenderProcessHostObserver {
34 public:
35 RenderProcessHostTest() : process_exits_(0), host_destructions_(0) {}
37 protected:
38 // RenderProcessHostObserver:
39 virtual void RenderProcessExited(RenderProcessHost* host,
40 base::ProcessHandle handle,
41 base::TerminationStatus status,
42 int exit_code) OVERRIDE {
43 ++process_exits_;
45 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE {
46 ++host_destructions_;
49 int process_exits_;
50 int host_destructions_;
53 // Sometimes the renderer process's ShutdownRequest (corresponding to the
54 // ViewMsg_WasSwappedOut from a previous navigation) doesn't arrive until after
55 // the browser process decides to re-use the renderer for a new purpose. This
56 // test makes sure the browser doesn't let the renderer die in that case. See
57 // http://crbug.com/87176.
58 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
59 ShutdownRequestFromActiveTabIgnored) {
60 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
62 GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
63 NavigateToURL(shell(), test_url);
64 RenderProcessHost* rph =
65 shell()->web_contents()->GetRenderViewHost()->GetProcess();
67 host_destructions_ = 0;
68 process_exits_ = 0;
69 rph->AddObserver(this);
70 ChildProcessHostMsg_ShutdownRequest msg;
71 rph->OnMessageReceived(msg);
73 // If the RPH sends a mistaken ChildProcessMsg_Shutdown, the renderer process
74 // will take some time to die. Wait for a second tab to load in order to give
75 // that time to happen.
76 NavigateToURL(CreateBrowser(), test_url);
78 EXPECT_EQ(0, process_exits_);
79 if (!host_destructions_)
80 rph->RemoveObserver(this);
83 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
84 GuestsAreNotSuitableHosts) {
85 // Set max renderers to 1 to force running out of processes.
86 content::RenderProcessHost::SetMaxRendererProcessCount(1);
88 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
90 GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
91 NavigateToURL(shell(), test_url);
92 RenderProcessHost* rph =
93 shell()->web_contents()->GetRenderViewHost()->GetProcess();
94 // Make it believe it's a guest.
95 reinterpret_cast<RenderProcessHostImpl*>(rph)->SetIsGuestForTesting(true);
96 EXPECT_EQ(1, RenderProcessHostCount());
98 // Navigate to a different page.
99 GURL::Replacements replace_host;
100 std::string host_str("localhost"); // Must stay in scope with replace_host.
101 replace_host.SetHostStr(host_str);
102 GURL another_url = embedded_test_server()->GetURL("/simple_page.html");
103 another_url = another_url.ReplaceComponents(replace_host);
104 NavigateToURL(CreateBrowser(), another_url);
106 // Expect that we got another process (the guest renderer was not reused).
107 EXPECT_EQ(2, RenderProcessHostCount());
110 class ShellCloser : public RenderProcessHostObserver {
111 public:
112 ShellCloser(Shell* shell, std::string* logging_string)
113 : shell_(shell), logging_string_(logging_string) {}
115 protected:
116 // RenderProcessHostObserver:
117 virtual void RenderProcessExited(RenderProcessHost* host,
118 base::ProcessHandle handle,
119 base::TerminationStatus status,
120 int exit_code) OVERRIDE {
121 logging_string_->append("ShellCloser::RenderProcessExited ");
122 shell_->Close();
125 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE {
126 logging_string_->append("ShellCloser::RenderProcessHostDestroyed ");
129 Shell* shell_;
130 std::string* logging_string_;
133 class ObserverLogger : public RenderProcessHostObserver {
134 public:
135 explicit ObserverLogger(std::string* logging_string)
136 : logging_string_(logging_string), host_destroyed_(false) {}
138 bool host_destroyed() { return host_destroyed_; }
140 protected:
141 // RenderProcessHostObserver:
142 virtual void RenderProcessExited(RenderProcessHost* host,
143 base::ProcessHandle handle,
144 base::TerminationStatus status,
145 int exit_code) OVERRIDE {
146 logging_string_->append("ObserverLogger::RenderProcessExited ");
149 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE {
150 logging_string_->append("ObserverLogger::RenderProcessHostDestroyed ");
151 host_destroyed_ = true;
154 std::string* logging_string_;
155 bool host_destroyed_;
158 IN_PROC_BROWSER_TEST_F(RenderProcessHostTest,
159 AllProcessExitedCallsBeforeAnyHostDestroyedCalls) {
160 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
162 GURL test_url = embedded_test_server()->GetURL("/simple_page.html");
163 NavigateToURL(shell(), test_url);
165 std::string logging_string;
166 ShellCloser shell_closer(shell(), &logging_string);
167 ObserverLogger observer_logger(&logging_string);
168 RenderProcessHost* rph =
169 shell()->web_contents()->GetRenderViewHost()->GetProcess();
171 // Ensure that the ShellCloser observer is first, so that it will have first
172 // dibs on the ProcessExited callback.
173 rph->AddObserver(&shell_closer);
174 rph->AddObserver(&observer_logger);
176 // This will crash the render process, and start all the callbacks.
177 NavigateToURL(shell(), GURL(kChromeUICrashURL));
179 // The key here is that all the RenderProcessExited callbacks precede all the
180 // RenderProcessHostDestroyed callbacks.
181 EXPECT_EQ("ShellCloser::RenderProcessExited "
182 "ObserverLogger::RenderProcessExited "
183 "ShellCloser::RenderProcessHostDestroyed "
184 "ObserverLogger::RenderProcessHostDestroyed ", logging_string);
186 // If the test fails, and somehow the RPH is still alive somehow, at least
187 // deregister the observers so that the test fails and doesn't also crash.
188 if (!observer_logger.host_destroyed()) {
189 rph->RemoveObserver(&shell_closer);
190 rph->RemoveObserver(&observer_logger);
194 } // namespace
195 } // namespace content