summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorlfg <lfg@chromium.org>2015-03-07 15:03:33 -0800
committerCommit bot <commit-bot@chromium.org>2015-03-07 23:04:11 +0000
commitf52ea14b61ebdf8ad18814da5166a2b30b7a3f66 (patch)
tree10593327b711fe227fbdaf8e72e93316b4c135a2 /content
parent98bc520d5bef9bb2b3699f10e1b9fdc306de9c6a (diff)
downloadchromium_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.cc163
-rw-r--r--content/renderer/render_frame_proxy.cc7
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, &param))
return;