OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <memory> | 8 #include <memory> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 13 #include "content/common/frame_messages.h" |
| 14 #include "content/public/common/browser_side_navigation_policy.h" |
13 #include "content/public/common/content_constants.h" | 15 #include "content/public/common/content_constants.h" |
14 #include "content/public/test/mock_render_process_host.h" | 16 #include "content/public/test/mock_render_process_host.h" |
15 #include "content/public/test/test_utils.h" | 17 #include "content/public/test/test_utils.h" |
| 18 #include "content/test/test_render_frame_host.h" |
16 #include "content/test/test_render_view_host.h" | 19 #include "content/test/test_render_view_host.h" |
| 20 #include "content/test/test_web_contents.h" |
| 21 #include "third_party/WebKit/public/web/WebSandboxFlags.h" |
17 | 22 |
18 namespace content { | 23 namespace content { |
19 | 24 |
20 class RenderProcessHostUnitTest : public RenderViewHostTestHarness {}; | 25 class RenderProcessHostUnitTest : public RenderViewHostImplTestHarness {}; |
21 | 26 |
22 // Tests that guest RenderProcessHosts are not considered suitable hosts when | 27 // Tests that guest RenderProcessHosts are not considered suitable hosts when |
23 // searching for RenderProcessHost. | 28 // searching for RenderProcessHost. |
24 TEST_F(RenderProcessHostUnitTest, GuestsAreNotSuitableHosts) { | 29 TEST_F(RenderProcessHostUnitTest, GuestsAreNotSuitableHosts) { |
25 GURL test_url("http://foo.com"); | 30 GURL test_url("http://foo.com"); |
26 | 31 |
27 MockRenderProcessHost guest_host(browser_context()); | 32 MockRenderProcessHost guest_host(browser_context()); |
28 guest_host.set_is_for_guests_only(true); | 33 guest_host.set_is_for_guests_only(true); |
29 | 34 |
30 EXPECT_FALSE(RenderProcessHostImpl::IsSuitableHost( | 35 EXPECT_FALSE(RenderProcessHostImpl::IsSuitableHost( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 hosts.push_back(base::MakeUnique<MockRenderProcessHost>(browser_context())); | 82 hosts.push_back(base::MakeUnique<MockRenderProcessHost>(browser_context())); |
78 } | 83 } |
79 | 84 |
80 // Verify that the renderer sharing still won't happen. | 85 // Verify that the renderer sharing still won't happen. |
81 GURL test_url("http://foo.com"); | 86 GURL test_url("http://foo.com"); |
82 EXPECT_FALSE(RenderProcessHostImpl::ShouldTryToUseExistingProcessHost( | 87 EXPECT_FALSE(RenderProcessHostImpl::ShouldTryToUseExistingProcessHost( |
83 browser_context(), test_url)); | 88 browser_context(), test_url)); |
84 } | 89 } |
85 #endif | 90 #endif |
86 | 91 |
| 92 // Tests that RenderProcessHost reuse considers committed sites correctly. |
| 93 TEST_F(RenderProcessHostUnitTest, ReuseCommittedSite) { |
| 94 const GURL kUrl1("http://foo.com"); |
| 95 const GURL kUrl2("http://bar.com"); |
| 96 |
| 97 // At first, trying to get a RenderProcessHost with the |
| 98 // REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process. |
| 99 scoped_refptr<SiteInstanceImpl> site_instance = |
| 100 SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 101 site_instance->set_process_reuse_policy( |
| 102 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 103 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 104 |
| 105 // Have the main frame navigate to the first url. Getting a RenderProcessHost |
| 106 // with the REUSE_PENDING_OR_COMMITTED_SITE policy should now return the |
| 107 // process of the main RFH. |
| 108 NavigateAndCommit(kUrl1); |
| 109 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 110 site_instance->set_process_reuse_policy( |
| 111 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 112 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 113 |
| 114 // Navigate away. Getting a RenderProcessHost with the |
| 115 // REUSE_PENDING_OR_COMMITTED_SITE policy should again return a new process. |
| 116 NavigateAndCommit(kUrl2); |
| 117 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 118 site_instance->set_process_reuse_policy( |
| 119 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 120 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 121 |
| 122 // Now add a subframe that navigates to kUrl1. Getting a RenderProcessHost |
| 123 // with the REUSE_PENDING_OR_COMMITTED_SITE policy for kUrl1 should now |
| 124 // return the process of the subframe RFH. |
| 125 std::string unique_name("uniqueName0"); |
| 126 main_test_rfh()->OnCreateChildFrame( |
| 127 process()->GetNextRoutingID(), blink::WebTreeScopeType::kDocument, |
| 128 std::string(), unique_name, blink::WebSandboxFlags::kNone, |
| 129 ParsedFeaturePolicyHeader(), FrameOwnerProperties()); |
| 130 TestRenderFrameHost* subframe = static_cast<TestRenderFrameHost*>( |
| 131 contents()->GetFrameTree()->root()->child_at(0)->current_frame_host()); |
| 132 { |
| 133 FrameHostMsg_DidCommitProvisionalLoad_Params params; |
| 134 params.nav_entry_id = 0; |
| 135 params.frame_unique_name = unique_name; |
| 136 params.did_create_new_entry = false; |
| 137 params.url = kUrl1; |
| 138 params.transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME; |
| 139 params.should_update_history = false; |
| 140 params.gesture = NavigationGestureUser; |
| 141 params.method = "GET"; |
| 142 params.page_state = PageState::CreateFromURL(kUrl1); |
| 143 subframe->SendRendererInitiatedNavigationRequest(kUrl1, false); |
| 144 subframe->PrepareForCommit(); |
| 145 subframe->SendNavigateWithParams(¶ms); |
| 146 } |
| 147 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 148 site_instance->set_process_reuse_policy( |
| 149 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 150 EXPECT_EQ(subframe->GetProcess(), site_instance->GetProcess()); |
| 151 } |
| 152 |
| 153 // Tests that RenderProcessHost will not consider reusing a process that has |
| 154 // committed an error page. |
| 155 TEST_F(RenderProcessHostUnitTest, DoNotReuseError) { |
| 156 const GURL kUrl1("http://foo.com"); |
| 157 const GURL kUrl2("http://bar.com"); |
| 158 |
| 159 // At first, trying to get a RenderProcessHost with the |
| 160 // REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process. |
| 161 scoped_refptr<SiteInstanceImpl> site_instance = |
| 162 SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 163 site_instance->set_process_reuse_policy( |
| 164 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 165 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 166 |
| 167 // Have the main frame navigate to the first url. Getting a RenderProcessHost |
| 168 // with the REUSE_PENDING_OR_COMMITTED_SITE policy should now return the |
| 169 // process of the main RFH. |
| 170 NavigateAndCommit(kUrl1); |
| 171 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 172 site_instance->set_process_reuse_policy( |
| 173 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 174 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 175 |
| 176 // Navigate away. Getting a RenderProcessHost with the |
| 177 // REUSE_PENDING_OR_COMMITTED_SITE policy should again return a new process. |
| 178 NavigateAndCommit(kUrl2); |
| 179 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 180 site_instance->set_process_reuse_policy( |
| 181 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 182 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 183 |
| 184 // Navigate back and simulate an error. Getting a RenderProcessHost with the |
| 185 // REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process. |
| 186 web_contents()->GetController().GoBack(); |
| 187 TestRenderFrameHost* pending_rfh = contents()->GetPendingMainFrame(); |
| 188 if (!IsBrowserSideNavigationEnabled()) |
| 189 pending_rfh->SimulateNavigationStart(kUrl1); |
| 190 pending_rfh->SimulateNavigationError(kUrl1, net::ERR_TIMED_OUT); |
| 191 pending_rfh->SimulateNavigationErrorPageCommit(); |
| 192 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 193 site_instance->set_process_reuse_policy( |
| 194 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 195 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 196 } |
| 197 |
| 198 // Tests that RenderProcessHost reuse considers navigations correctly. |
| 199 TEST_F(RenderProcessHostUnitTest, ReuseNavigationProcess) { |
| 200 // This is only applicable to PlzNavigate. |
| 201 if (!IsBrowserSideNavigationEnabled()) |
| 202 return; |
| 203 |
| 204 const GURL kUrl1("http://foo.com"); |
| 205 const GURL kUrl2("http://bar.com"); |
| 206 |
| 207 // At first, trying to get a RenderProcessHost with the |
| 208 // REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process. |
| 209 scoped_refptr<SiteInstanceImpl> site_instance = |
| 210 SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 211 site_instance->set_process_reuse_policy( |
| 212 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 213 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 214 |
| 215 // Start a navigation. Now Getting RenderProcessHost with the |
| 216 // REUSE_PENDING_OR_COMMITTED_SITE policy should return the current process. |
| 217 main_test_rfh()->SimulateNavigationStart(kUrl1); |
| 218 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl1); |
| 219 site_instance->set_process_reuse_policy( |
| 220 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 221 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 222 |
| 223 // Finish the navigation and start a new cross-site one. Getting |
| 224 // RenderProcessHost with the REUSE_PENDING_OR_COMMITTED_SITE policy should |
| 225 // return the process of the speculative RenderFrameHost. |
| 226 main_test_rfh()->PrepareForCommit(); |
| 227 main_test_rfh()->SendNavigate(0, true, kUrl1); |
| 228 contents()->GetController().LoadURL(kUrl2, Referrer(), |
| 229 ui::PAGE_TRANSITION_TYPED, std::string()); |
| 230 main_test_rfh()->SendBeforeUnloadACK(true); |
| 231 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl2); |
| 232 site_instance->set_process_reuse_policy( |
| 233 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 234 EXPECT_EQ(contents()->GetPendingMainFrame()->GetProcess(), |
| 235 site_instance->GetProcess()); |
| 236 |
| 237 // Remember the process id and cancel the navigation. Getting |
| 238 // RenderProcessHost with the REUSE_PENDING_OR_COMMITTED_SITE policy should |
| 239 // no longer return the process of the speculative RenderFrameHost. |
| 240 int speculative_process_host_id = |
| 241 contents()->GetPendingMainFrame()->GetProcess()->GetID(); |
| 242 contents()->GetPendingMainFrame()->SimulateNavigationError(kUrl2, |
| 243 net::ERR_ABORTED); |
| 244 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl2); |
| 245 site_instance->set_process_reuse_policy( |
| 246 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 247 EXPECT_NE(speculative_process_host_id, site_instance->GetProcess()->GetID()); |
| 248 } |
| 249 |
| 250 // Tests that RenderProcessHost reuse considers navigations correctly during |
| 251 // redirects. |
| 252 TEST_F(RenderProcessHostUnitTest, ReuseNavigationProcessRedirects) { |
| 253 // This is only applicable to PlzNavigate. |
| 254 if (!IsBrowserSideNavigationEnabled()) |
| 255 return; |
| 256 |
| 257 const GURL kUrl("http://foo.com"); |
| 258 const GURL kRedirectUrl1("http://foo.com/redirect"); |
| 259 const GURL kRedirectUrl2("http://bar.com"); |
| 260 |
| 261 // At first, trying to get a RenderProcessHost with the |
| 262 // REUSE_PENDING_OR_COMMITTED_SITE policy should return a new process. |
| 263 scoped_refptr<SiteInstanceImpl> site_instance = |
| 264 SiteInstanceImpl::CreateForURL(browser_context(), kUrl); |
| 265 site_instance->set_process_reuse_policy( |
| 266 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 267 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 268 |
| 269 // Start a navigation. Now getting RenderProcessHost with the |
| 270 // REUSE_PENDING_OR_COMMITTED_SITE policy should return the current process. |
| 271 main_test_rfh()->SimulateNavigationStart(kUrl); |
| 272 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl); |
| 273 site_instance->set_process_reuse_policy( |
| 274 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 275 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 276 |
| 277 // Simulate a same-site redirect. Getting RenderProcessHost with the |
| 278 // REUSE_PENDING_OR_COMMITTED_SITE policy should return the current process. |
| 279 main_test_rfh()->SimulateRedirect(kRedirectUrl1); |
| 280 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl); |
| 281 site_instance->set_process_reuse_policy( |
| 282 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 283 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 284 |
| 285 // Simulate a cross-site redirect. Getting RenderProcessHost with the |
| 286 // REUSE_PENDING_OR_COMMITTED_SITE policy should not return the current |
| 287 // process, whether for the old site or the new site. |
| 288 main_test_rfh()->SimulateRedirect(kRedirectUrl2); |
| 289 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl); |
| 290 site_instance->set_process_reuse_policy( |
| 291 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 292 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 293 site_instance = |
| 294 SiteInstanceImpl::CreateForURL(browser_context(), kRedirectUrl2); |
| 295 site_instance->set_process_reuse_policy( |
| 296 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 297 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 298 |
| 299 // Once the navigation is ready to commit, Getting RenderProcessHost with the |
| 300 // REUSE_PENDING_OR_COMMITTED_SITE policy should not return the current |
| 301 // process for the final site, but not the initial one. |
| 302 main_test_rfh()->PrepareForCommit(); |
| 303 site_instance = SiteInstanceImpl::CreateForURL(browser_context(), kUrl); |
| 304 site_instance->set_process_reuse_policy( |
| 305 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 306 EXPECT_NE(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 307 site_instance = |
| 308 SiteInstanceImpl::CreateForURL(browser_context(), kRedirectUrl2); |
| 309 site_instance->set_process_reuse_policy( |
| 310 SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE); |
| 311 EXPECT_EQ(main_test_rfh()->GetProcess(), site_instance->GetProcess()); |
| 312 } |
| 313 |
87 } // namespace content | 314 } // namespace content |
OLD | NEW |