Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(821)

Unified Diff: content/browser/isolate_top_document_browsertest.cc

Issue 1797363002: "Top Document Isolation" mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Two new browsertests. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/isolate_top_document_browsertest.cc
diff --git a/content/browser/isolate_top_document_browsertest.cc b/content/browser/isolate_top_document_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..07992aab35ae027e9b654baa8539cc7c462df284
--- /dev/null
+++ b/content/browser/isolate_top_document_browsertest.cc
@@ -0,0 +1,409 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "base/command_line.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class IsolateTopDocumentBrowserTest : public ContentBrowserTest {
+ public:
+ IsolateTopDocumentBrowserTest() {}
+
+ protected:
+ std::string DepictFrameTree(FrameTreeNode* node) {
+ return visualizer_.DepictFrameTree(node);
+ }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(switches::kIsolateTopDocument);
+ }
+
+ void SetUpOnMainThread() {
Xiaocheng 2016/03/22 04:35:04 Please add |override|.
+ host_resolver()->AddRule("*", "127.0.0.1");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ SetupCrossSiteRedirector(embedded_test_server());
+ }
+
+ FrameTreeNode* root() {
+ return static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ }
+
+ void GoBack() {
+ TestNavigationObserver back_load_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_load_observer.Wait();
+ }
+
+ private:
+ FrameTreeVisualizer visualizer_;
+};
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, SameSiteDeeplyNested) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a,a(a,a(a)))"));
+
+ NavigateToURL(shell(), main_url);
+
+ EXPECT_EQ(
+ " Site A\n"
+ " |--Site A\n"
+ " +--Site A\n"
+ " |--Site A\n"
+ " +--Site A\n"
+ " +--Site A\n"
+ "Where A = http://a.com/",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteDeeplyNested) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(c(d(b))))"));
+
+ NavigateToURL(shell(), main_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ " +--Site B -- proxies for A\n"
+ " +--Site B -- proxies for A\n"
+ " +--Site B -- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, ReturnToTopSite) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b(a(c)))"));
+
+ NavigateToURL(shell(), main_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ " +--Site A -- proxies for B\n"
+ " +--Site B -- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, NavigateToSubframeSite) {
+ GURL ab_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ GURL ba_url(embedded_test_server()->GetURL(
+ "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
+
+ NavigateToURL(shell(), ab_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ NavigateToURL(shell(), ba_url);
+
+ // TODO(nick): The following result is wrong; after navigation, b.com should
+ // be in a dedicated process; a.com and b.com should share a 3rd party
+ // subframe process.
+ EXPECT_EQ(
+ " Site B ------------ proxies for A\n"
+ " |--Site A ------- proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest,
+ NavigateToSubframeSiteWithPopup) {
+ // A(B) -> B(A), but while a separate B(A) popup exists.
+ GURL ab_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+
+ NavigateToURL(shell(), ab_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ ShellAddedObserver new_shell_observer;
+ EXPECT_TRUE(ExecuteScript(
+ root()->child_at(0)->current_frame_host(),
+ "popup = window.open('/cross_site_iframe_factory.html?b(a)');"));
+ Shell* popup = new_shell_observer.GetShell();
+
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(popup->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // TODO(nick): This popup is an example of a main frame that ends up in the
+ // 3rd party process. This is unavoidable in this case, however.
+ EXPECT_EQ(
+ " Site B\n"
+ "Where B = http://b.com/ (3rd party)",
+ DepictFrameTree(popup_root));
+
+ // Because of the existing popup, this navigation needs to stay in the 3rd
+ // party process as well.
+ GURL ba_url(embedded_test_server()->GetURL(
+ "b.com", "/cross_site_iframe_factory.html?b(a, c)"));
+ NavigateToURL(shell(), ba_url);
+
+ EXPECT_EQ(
+ " Site B ------------ proxies for A\n"
+ " +--Site A ------- proxies for B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(popup_root));
+ EXPECT_EQ(
+ " Site B ------------ proxies for A\n"
+ " |--Site A ------- proxies for B\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ // If we navigate the popup to a new site, it ought to leave the 3rd party
+ // process.
+ GURL c_url(embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html?c(c, c, c, c)"));
+ NavigateToURL(popup, c_url);
+ EXPECT_EQ(
+ " Site C ------------ proxies for A B\n"
+ " |--Site C ------- proxies for A B\n"
+ " |--Site C ------- proxies for A B\n"
+ " |--Site C ------- proxies for A B\n"
+ " +--Site C ------- proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)\n"
+ " C = http://c.com/",
+ DepictFrameTree(popup_root));
+ NavigateToURL(shell(), c_url);
+ EXPECT_EQ(
+ " Site C\n"
+ " |--Site C\n"
+ " |--Site C\n"
+ " |--Site C\n"
+ " +--Site C\n"
+ "Where C = http://c.com/",
+ DepictFrameTree(popup_root));
+ EXPECT_EQ(
+ " Site C\n"
+ " |--Site C\n"
+ " |--Site C\n"
+ " |--Site C\n"
+ " +--Site C\n"
+ "Where C = http://c.com/",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest,
+ NavigateToSubframeSiteWithPopup2) {
+ // A(B, C) -> C(A, B), but while a separate C(A) popup exists.
+ GURL abb_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b, b)"));
+
+ NavigateToURL(shell(), abb_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " |--Site B ------- proxies for A\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ // A(B, B) -> A(B, C)
+ GURL c_url(embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html?c"));
+ NavigateFrameToURL(root()->child_at(1), c_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " |--Site B ------- proxies for A\n"
+ " +--Site B ------- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ // Subframe C creates C(A) popup.
+ ShellAddedObserver new_shell_observer;
+ EXPECT_TRUE(ExecuteScript(
+ root()->child_at(0)->current_frame_host(),
+ "popup = window.open('/cross_site_iframe_factory.html?c(a)');"));
+ Shell* popup = new_shell_observer.GetShell();
+
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(popup->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // TODO(nick): This popup is an example of a main frame that ends up in the
+ // 3rd party process. This is unavoidable in this case, however.
+ EXPECT_EQ(
+ " Site B\n"
+ "Where B = http://b.com/ (3rd party)",
+ DepictFrameTree(popup_root));
+
+ // Because of the existing popup, this navigation needs to stay in the 3rd
+ // party process as well.
+ GURL ba_url(embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html?c(a, b)"));
+ NavigateToURL(shell(), ba_url);
+
+ EXPECT_EQ(
+ " Site B ------------ proxies for A\n"
+ " +--Site A ------- proxies for B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(popup_root));
+
+ // TODO(nick): This is a bug, caused by the fact that the BrowsingInstance
+ // didn't record that SiteInstance B is also in use by c.com.
+ EXPECT_EQ(
+ " Site C ------------ proxies for A B\n"
+ " |--Site A ------- proxies for B C\n"
+ " +--Site B ------- proxies for A C\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)\n"
+ " C = http://c.com/",
+ DepictFrameTree(root()));
+
+ // If we navigate the popup to a new site, it ought to transfer processes.
+ GURL d_url(embedded_test_server()->GetURL(
+ "d.com", "/cross_site_iframe_factory.html?d"));
+ NavigateToURL(popup, d_url);
+ EXPECT_EQ(
+ " Site D ------------ proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)\n"
+ " D = http://d.com/",
+ DepictFrameTree(popup_root));
+ NavigateToURL(shell(), d_url);
+ EXPECT_EQ(
+ " Site D\n"
+ "Where D = http://d.com/",
+ DepictFrameTree(popup_root));
+ EXPECT_EQ(
+ " Site D\n"
+ "Where D = http://d.com/",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, FramesForSitesInHistory) {
+ // First, do a series of navigations.
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a"));
+ EXPECT_EQ(
+ " Site A\n"
+ "Where A = http://a.com/",
+ DepictFrameTree(root()));
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "b.com", "/cross_site_iframe_factory.html?b"));
+
+ // TODO(nick): Without --isolate-top-document, we would not swap processes
+ // for these cross-site navigations. What should the behavior be here, for
+ // --isolate-top-document?
+ EXPECT_EQ(
+ " Site B\n"
+ "Where B = http://b.com/",
+ DepictFrameTree(root()));
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html?c"));
+ EXPECT_EQ(
+ " Site C\n"
+ "Where C = http://c.com/",
+ DepictFrameTree(root()));
+
+ // Now, navigate to a fourth site with iframes to the sites in the history.
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "d.com", "/cross_site_iframe_factory.html?d(a,b,c)"));
+
+ // TODO(nick): These subframes ought to end up in the third-party process,
+ // but because we cache the SiteInstances in the navigation entries, we
+ // can't place these subframes into the siteinstance for 3rd party frames.
+ EXPECT_EQ(
+ " Site D ------------ proxies for A B C\n"
+ " |--Site A ------- proxies for B C D\n"
+ " |--Site B ------- proxies for A C D\n"
+ " +--Site C ------- proxies for A B D\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/\n"
+ " C = http://c.com/\n"
+ " D = http://d.com/",
+ DepictFrameTree(root()));
+
+ // Now try going back.
+ GoBack();
+ EXPECT_EQ(
+ " Site C\n"
+ "Where C = http://c.com/",
+ DepictFrameTree(root()));
+ GoBack();
+ EXPECT_EQ(
+ " Site B\n"
+ "Where B = http://b.com/",
+ DepictFrameTree(root()));
+ GoBack();
+ EXPECT_EQ(
+ " Site A\n"
+ "Where A = http://a.com/",
+ DepictFrameTree(root()));
+}
+
+IN_PROC_BROWSER_TEST_F(IsolateTopDocumentBrowserTest, CrossSiteAtLevelTwo) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a(b, a))"));
+
+ NavigateToURL(shell(), main_url);
+
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site A ------- proxies for B\n"
+ " |--Site B -- proxies for A\n"
+ " +--Site A -- proxies for B\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+
+ GURL c_url(embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html?c"));
+ NavigateFrameToURL(root()->child_at(0)->child_at(1), c_url);
+
+ // This navigation should complete using the existing 3rd party SiteInstance.
+ EXPECT_EQ(
+ " Site A ------------ proxies for B\n"
+ " +--Site A ------- proxies for B\n"
+ " |--Site B -- proxies for A\n"
+ " +--Site B -- proxies for A\n"
+ "Where A = http://a.com/\n"
+ " B = http://b.com/ (3rd party)",
+ DepictFrameTree(root()));
+}
+
Xiaocheng 2016/03/22 04:35:04 Can we add the following test case? It doesn't con
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698