Chromium Code Reviews| Index: content/browser/site_per_process_browsertest.cc |
| diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
| index 88d04041b14e6a1ac1ddf90dd68425ee1a36e410..3a5ba7b511a92826ef73fbe90ff4b0f38518b0a0 100644 |
| --- a/content/browser/site_per_process_browsertest.cc |
| +++ b/content/browser/site_per_process_browsertest.cc |
| @@ -6,6 +6,7 @@ |
| #include "base/strings/stringprintf.h" |
| #include "content/browser/frame_host/cross_process_frame_connector.h" |
| #include "content/browser/frame_host/frame_tree.h" |
| +#include "content/browser/frame_host/navigator.h" |
| #include "content/browser/frame_host/render_frame_proxy_host.h" |
| #include "content/browser/frame_host/render_widget_host_view_child_frame.h" |
| #include "content/browser/renderer_host/render_view_host_impl.h" |
| @@ -21,6 +22,7 @@ |
| #include "content/public/test/test_utils.h" |
| #include "content/shell/browser/shell.h" |
| #include "content/test/content_browser_test_utils_internal.h" |
| +#include "content/test/test_frame_navigation_observer.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "url/gurl.h" |
| @@ -566,4 +568,116 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| } |
| } |
| +// Ensure that when navigating a frame cross-process RenderFrameProxyHosts are |
| +// created in the FrameTree skipping the subtree of the navigating frame. |
| +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ProxiesCreationSkipsSubtree) { |
|
Charlie Reis
2014/09/10 07:39:10
nit: ProxyCreationSkipsSubtree
nasko
2014/09/10 19:36:34
Done.
|
| + host_resolver()->AddRule("*", "127.0.0.1"); |
| + ASSERT_TRUE(test_server()->Start()); |
| + GURL main_url(test_server()->GetURL("files/site_per_process_main.html")); |
| + NavigateToURL(shell(), main_url); |
| + |
| + // It is safe to obtain the root frame tree node here, as it doesn't change. |
| + FrameTreeNode* root = |
| + static_cast<WebContentsImpl*>(shell()->web_contents())-> |
| + GetFrameTree()->root(); |
| + |
| + EXPECT_TRUE(root->child_at(1) != NULL); |
| + EXPECT_EQ(2U, root->child_at(1)->child_count()); |
| + |
| + { |
| + // Load same-site page into iframe. |
| + SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| + GURL http_url(test_server()->GetURL("files/title1.html")); |
| + NavigateFrameToURL(root->child_at(0), http_url); |
| + EXPECT_EQ(http_url, observer.navigation_url()); |
| + EXPECT_TRUE(observer.navigation_succeeded()); |
| + RenderFrameProxyHost* proxy_to_parent = |
| + root->child_at(0)->render_manager()->GetRenderFrameProxyHost( |
| + shell()->web_contents()->GetSiteInstance()); |
| + EXPECT_FALSE(proxy_to_parent); |
| + } |
| + |
| + // Create the cross-site URL to navigate to. |
| + GURL::Replacements replace_host; |
| + std::string foo_com("foo.com"); |
| + GURL cross_site_url(test_server()->GetURL("files/frame_tree/1-1.html")); |
| + replace_host.SetHostStr(foo_com); |
| + cross_site_url = cross_site_url.ReplaceComponents(replace_host); |
| + |
| + // Load cross-site page into the second iframe without waiting for the |
| + // navigation to complete. Once LoadURLWithParams returns, we would expect |
| + // proxies to have been created in the frame tree, but children of the |
| + // navigating frame to still be present. The reason is that we don't run the |
| + // message loop, so no IPCs that alter the frame tree can be processed. |
| + FrameTreeNode* child = root->child_at(1); |
| + SiteInstance* site; |
| + { |
| + SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| + TestFrameNavigationObserver navigation_observer(child); |
| + NavigationController::LoadURLParams params(cross_site_url); |
| + params.transition_type = PageTransitionFromInt(PAGE_TRANSITION_LINK); |
| + params.frame_tree_node_id = child->frame_tree_node_id(); |
| + child->navigator()->GetController()->LoadURLWithParams(params); |
| + EXPECT_TRUE(child->render_manager()->pending_frame_host()); |
| + |
| + site = child->render_manager()->pending_frame_host()->GetSiteInstance(); |
| + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site); |
| + |
| + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(site)); |
| + EXPECT_TRUE( |
| + root->child_at(0)->render_manager()->GetRenderFrameProxyHost(site)); |
| + EXPECT_FALSE(child->render_manager()->GetRenderFrameProxyHost(site)); |
| + for (size_t i = 0; i < child->child_count(); ++i){ |
|
Charlie Reis
2014/09/10 07:39:10
nit: Space after )
nasko
2014/09/10 19:36:34
Done.
|
| + EXPECT_FALSE( |
| + child->child_at(i)->render_manager()->GetRenderFrameProxyHost(site)); |
| + } |
| + // Now that the verification is done, run the message loop and wait for the |
| + // navigation to complete. |
| + navigation_observer.Wait(); |
| + EXPECT_FALSE(child->render_manager()->pending_frame_host()); |
| + EXPECT_EQ(cross_site_url, observer.navigation_url()); |
| + EXPECT_TRUE(observer.navigation_succeeded()); |
|
Charlie Reis
2014/09/10 07:39:10
Are the children FTNs now deleted? Can we verify
nasko
2014/09/10 19:36:34
Not here, since I load a page that has subframes.
|
| + } |
| + |
| + // Load another cross-site page into the same iframe. |
| + cross_site_url = test_server()->GetURL("files/title2.html"); |
| + std::string bar_com("bar.com"); |
| + replace_host.SetHostStr(bar_com); |
| + cross_site_url = cross_site_url.ReplaceComponents(replace_host); |
| + |
| + { |
| + // Perform the same checks as the first cross-site navigation, since |
| + // there have been issues in subsequent cross-site navigations. Also ensure |
| + // that the SiteInstance has properly changed. |
| + // TODO(nasko): Once we have proper cleanup of resources, add code to |
| + // verify that the intermediate SiteInstance/RenderFrameHost have been |
| + // properly cleaned up. |
| + SitePerProcessWebContentsObserver observer(shell()->web_contents()); |
| + TestFrameNavigationObserver navigation_observer(child); |
| + NavigationController::LoadURLParams params(cross_site_url); |
| + params.transition_type = PageTransitionFromInt(PAGE_TRANSITION_LINK); |
| + params.frame_tree_node_id = child->frame_tree_node_id(); |
| + child->navigator()->GetController()->LoadURLWithParams(params); |
| + EXPECT_TRUE(child->render_manager()->pending_frame_host() != NULL); |
| + |
| + SiteInstance* site2 = |
| + child->render_manager()->pending_frame_host()->GetSiteInstance(); |
| + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), site2); |
| + EXPECT_NE(site, site2); |
| + |
| + EXPECT_TRUE(root->render_manager()->GetRenderFrameProxyHost(site2)); |
| + EXPECT_TRUE( |
| + root->child_at(0)->render_manager()->GetRenderFrameProxyHost(site2)); |
| + EXPECT_FALSE(child->render_manager()->GetRenderFrameProxyHost(site2)); |
| + for (size_t i = 0; i < child->child_count(); ++i) { |
| + EXPECT_FALSE( |
| + child->child_at(i)->render_manager()->GetRenderFrameProxyHost(site2)); |
| + } |
| + |
| + navigation_observer.Wait(); |
| + EXPECT_EQ(cross_site_url, observer.navigation_url()); |
| + EXPECT_TRUE(observer.navigation_succeeded()); |
| + } |
| +} |
| + |
| } // namespace content |