diff options
author | lfg <lfg@chromium.org> | 2015-03-07 15:03:33 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-07 23:04:11 +0000 |
commit | f52ea14b61ebdf8ad18814da5166a2b30b7a3f66 (patch) | |
tree | 10593327b711fe227fbdaf8e72e93316b4c135a2 /content | |
parent | 98bc520d5bef9bb2b3699f10e1b9fdc306de9c6a (diff) | |
download | chromium_src-f52ea14b61ebdf8ad18814da5166a2b30b7a3f66.zip chromium_src-f52ea14b61ebdf8ad18814da5166a2b30b7a3f66.tar.gz chromium_src-f52ea14b61ebdf8ad18814da5166a2b30b7a3f66.tar.bz2 |
Fix flakyness in NavigateRemoteFrame browsertest.
Fix a race where RenderFrameProxy::OnCompositorFrameSwapped message can arrive after the RemoteFrame was swapped with a LocalFrame.
Enabled NavigateRemoteFrame tests, merged NavigateRemoteToDataURL and NavigateRemoteToBlankURL into NavigateRemoteFrameToBlankAndDataURLs.
BUG=446575
Review URL: https://codereview.chromium.org/881413005
Cr-Commit-Position: refs/heads/master@{#319567}
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/site_per_process_browsertest.cc | 163 | ||||
-rw-r--r-- | content/renderer/render_frame_proxy.cc | 7 |
2 files changed, 70 insertions, 100 deletions
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 8b0a609..c0357ca 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc @@ -283,7 +283,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteIframe) { // Disabled for flaky crashing: crbug.com/446575 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DISABLED_NavigateRemoteFrame) { + NavigateRemoteFrame) { GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html")); NavigateToURL(shell(), main_url); @@ -337,6 +337,68 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, child->current_frame_host()->GetSiteInstance()); } +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + NavigateRemoteFrameToBlankAndDataURLs) { + GURL main_url(embedded_test_server()->GetURL("/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(); + + TestNavigationObserver observer(shell()->web_contents()); + + // Load same-site page into iframe. + FrameTreeNode* child = root->child_at(0); + GURL http_url(embedded_test_server()->GetURL("/title1.html")); + NavigateFrameToURL(child, http_url); + EXPECT_EQ(http_url, observer.last_navigation_url()); + EXPECT_TRUE(observer.last_navigation_succeeded()); + + // Load cross-site page into iframe. + GURL url = embedded_test_server()->GetURL("foo.com", "/title2.html"); + NavigateFrameToURL(root->child_at(0), url); + EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_EQ(url, observer.last_navigation_url()); + ASSERT_EQ(2U, root->child_count()); + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), + root->child_at(0)->current_frame_host()->GetSiteInstance()); + + // Navigate iframe to a data URL. The navigation happens from a script in the + // parent frame, so the data URL should be committed in the same SiteInstance + // as the parent frame. + GURL data_url("data:text/html,dataurl"); + NavigateIframeToURL(shell()->web_contents(), "test", data_url); + EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_EQ(data_url, observer.last_navigation_url()); + + // Ensure that we have navigated using the top level process. + EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), + root->child_at(0)->current_frame_host()->GetSiteInstance()); + + // Load cross-site page into iframe. + url = embedded_test_server()->GetURL("bar.com", "/title2.html"); + NavigateFrameToURL(root->child_at(0), url); + EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_EQ(url, observer.last_navigation_url()); + ASSERT_EQ(2U, root->child_count()); + EXPECT_NE(shell()->web_contents()->GetSiteInstance(), + root->child_at(0)->current_frame_host()->GetSiteInstance()); + + // Navigate iframe to about:blank. The navigation happens from a script in the + // parent frame, so it should be committed in the same SiteInstance as the + // parent frame. + GURL about_blank_url("about:blank"); + NavigateIframeToURL(shell()->web_contents(), "test", about_blank_url); + EXPECT_TRUE(observer.last_navigation_succeeded()); + EXPECT_EQ(about_blank_url, observer.last_navigation_url()); + + // Ensure that we have navigated using the top level process. + EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), + root->child_at(0)->current_frame_host()->GetSiteInstance()); +} + // This test checks that killing a renderer process of a remote frame // and then navigating some other frame to the same SiteInstance of the killed // process works properly. @@ -1425,105 +1487,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, WindowNameReplication) { EXPECT_EQ("3-1-name", result); } -// TODO(lfg): Merge the test below with NavigateRemoteFrame test. -// TODO(lfg): Disabled because this triggers http://crbug.com/433012, and since -// the renderer process crashes, it causes the title watcher to never return. -// Alternatively, this could also be fixed if we could use NavigateIframeToURL -// and classified the navigation as MANUAL_SUBFRAME (http://crbug.com/441863) or -// if we waited for DidStopLoading (currently broken -- see comment in -// NavigateIframeToURL). -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DISABLED_NavigateRemoteToDataURL) { - GURL main_url(embedded_test_server()->GetURL("/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(); - - TestNavigationObserver observer(shell()->web_contents()); - - // Load cross-site page into iframe. - GURL url = embedded_test_server()->GetURL("foo.com", "/title1.html"); - NavigateFrameToURL(root->child_at(0), url); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(url, observer.last_navigation_url()); - - // Ensure that we have created a new process for the subframe. - EXPECT_NE(shell()->web_contents()->GetSiteInstance(), - root->child_at(0)->current_frame_host()->GetSiteInstance()); - - // Navigate iframe to a data URL. The navigation happens from a script in the - // parent frame, so the data URL should be committed in the same SiteInstance - // as the parent frame. - GURL data_url("data:text/html,dataurl"); - std::string script = base::StringPrintf( - "setTimeout(function() {" - "var iframe = document.getElementById('test');" - "iframe.onload = function() { document.title = 'LOADED'; };" - "iframe.src=\"%s\";" - "},0);", - data_url.spec().c_str()); - base::string16 passed_string(base::UTF8ToUTF16("LOADED")); - TitleWatcher title_watcher(shell()->web_contents(), passed_string); - EXPECT_TRUE(ExecuteScript(shell()->web_contents(), script)); - EXPECT_EQ(title_watcher.WaitAndGetTitle(), passed_string); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(data_url, observer.last_navigation_url()); - - // Ensure that we have navigated using the top level process. - EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), - root->child_at(0)->current_frame_host()->GetSiteInstance()); -} - -// TODO(lfg): Merge the test below with NavigateRemoteFrame test. -// Disabled due to the same reason as NavigateRemoteToDataURL. -IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, - DISABLED_NavigateRemoteToBlankURL) { - GURL main_url(embedded_test_server()->GetURL("/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(); - - TestNavigationObserver observer(shell()->web_contents()); - - // Load cross-site page into iframe. - GURL url = embedded_test_server()->GetURL("foo.com", "/title1.html"); - NavigateFrameToURL(root->child_at(0), url); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(url, observer.last_navigation_url()); - - // Ensure that we have created a new process for the subframe. - EXPECT_NE(shell()->web_contents()->GetSiteInstance(), - root->child_at(0)->current_frame_host()->GetSiteInstance()); - - // Navigate iframe to about:blank. The navigation happens from a script in the - // parent frame, so it should be committed in the same SiteInstance as the - // parent frame. - GURL about_blank_url("about:blank"); - std::string script = base::StringPrintf( - "setTimeout(function() {" - "var iframe = document.getElementById('test');" - "iframe.onload = function() { document.title = 'LOADED'; };" - "iframe.src=\"%s\";" - "},0);", - about_blank_url.spec().c_str()); - base::string16 passed_string(base::UTF8ToUTF16("LOADED")); - TitleWatcher title_watcher(shell()->web_contents(), passed_string); - EXPECT_TRUE(ExecuteScript(shell()->web_contents(), script)); - EXPECT_EQ(title_watcher.WaitAndGetTitle(), passed_string); - EXPECT_TRUE(observer.last_navigation_succeeded()); - EXPECT_EQ(about_blank_url, observer.last_navigation_url()); - - // Ensure that we have navigated using the top level process. - EXPECT_EQ(shell()->web_contents()->GetSiteInstance(), - root->child_at(0)->current_frame_host()->GetSiteInstance()); -} - // Ensure that navigating subframes in --site-per-process mode properly fires // the DidStopLoading event on WebContentsObserver. IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CrossSiteDidStopLoading) { diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 514e420..1fc7375 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc @@ -232,6 +232,13 @@ void RenderFrameProxy::OnChildFrameProcessGone() { } void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) { + // If this WebFrame has already been detached, its parent will be null. This + // can happen when swapping a WebRemoteFrame with a WebLocalFrame, where this + // message may arrive after the frame was removed from the frame tree, but + // before the frame has been destroyed. http://crbug.com/446575. + if (!web_frame()->parent()) + return; + FrameMsg_CompositorFrameSwapped::Param param; if (!FrameMsg_CompositorFrameSwapped::Read(&message, ¶m)) return; |