Chromium Code Reviews| Index: content/browser/frame_host/navigation_controller_impl_browsertest.cc | 
| diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc | 
| index 38642fc746f336a60ac113d2d6c35fecc4cb9394..e37f6d76444d3d93663a955821d1e38e6501c21c 100644 | 
| --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc | 
| +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc | 
| @@ -2680,6 +2680,111 @@ IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, | 
| EXPECT_EQ(dsn_3, dsn_4); | 
| } | 
| +// Support a set of tests that isolate only a subset of sites with | 
| +// out-of-process iframes (OOPIFs). | 
| +class NavigationControllerOOPIFBrowserTest | 
| 
 
nasko
2015/12/08 18:23:35
nit: Per the newest discussions on chromium-dev, a
 
Charlie Reis
2015/12/08 19:04:57
Done.
 
 | 
| + : public NavigationControllerBrowserTest { | 
| + public: | 
| + NavigationControllerOOPIFBrowserTest() {} | 
| + | 
| + void SetUpCommandLine(base::CommandLine* command_line) override { | 
| + // TODO(creis): Turn on OOPIF framework without isolating all sites. | 
| 
 
Charlie Reis
2015/12/08 18:01:10
Nick is adding a command line flag to content to m
 
 | 
| + } | 
| + | 
| + private: | 
| + DISALLOW_COPY_AND_ASSIGN(NavigationControllerOOPIFBrowserTest); | 
| +}; | 
| + | 
| +// Verify that restoring a NavigationEntry with cross-site subframes does not | 
| +// create out-of-process iframes unless the current SiteIsolationPolicy says to. | 
| +IN_PROC_BROWSER_TEST_F(NavigationControllerOOPIFBrowserTest, | 
| + RestoreWithoutExtraOOPIFs) { | 
| + // 1. Start on a page with a data URL iframe. | 
| + GURL main_url_a(embedded_test_server()->GetURL( | 
| + "a.com", "/navigation_controller/page_with_data_iframe.html")); | 
| + GURL data_url("data:text/html,Subframe"); | 
| + NavigateToURL(shell(), main_url_a); | 
| 
 
nasko
2015/12/08 18:23:34
nit: EXPECT_TRUE
 
Charlie Reis
2015/12/08 19:04:57
Done.
 
 | 
| + const NavigationControllerImpl& controller = | 
| + static_cast<const NavigationControllerImpl&>( | 
| + shell()->web_contents()->GetController()); | 
| + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) | 
| + ->GetFrameTree() | 
| + ->root(); | 
| + EXPECT_EQ(main_url_a, root->current_url()); | 
| + EXPECT_EQ(data_url, root->child_at(0)->current_url()); | 
| + | 
| + // 2. Navigate the iframe cross-site. | 
| + GURL frame_url_b(embedded_test_server()->GetURL( | 
| + "b.com", "/navigation_controller/simple_page_1.html")); | 
| + { | 
| + FrameNavigateParamsCapturer capturer(root->child_at(0)); | 
| 
 
nasko
2015/12/08 18:23:35
Why not use the usual loading stopped event? Or Te
 
Charlie Reis
2015/12/08 19:04:57
Done.
 
 | 
| + NavigateFrameToURL(root->child_at(0), frame_url_b); | 
| + capturer.Wait(); | 
| + } | 
| + EXPECT_EQ(main_url_a, root->current_url()); | 
| + EXPECT_EQ(frame_url_b, root->child_at(0)->current_url()); | 
| + | 
| + EXPECT_EQ(2, controller.GetEntryCount()); | 
| + EXPECT_EQ(1, controller.GetLastCommittedEntryIndex()); | 
| + NavigationEntryImpl* entry2 = controller.GetLastCommittedEntry(); | 
| + | 
| + // 3. Create a NavigationEntry with the same PageState as |entry2|. | 
| + scoped_ptr<NavigationEntryImpl> restored_entry = | 
| + NavigationEntryImpl::FromNavigationEntry( | 
| + NavigationControllerImpl::CreateNavigationEntry( | 
| + main_url_a, Referrer(), ui::PAGE_TRANSITION_RELOAD, false, | 
| + std::string(), controller.GetBrowserContext())); | 
| + restored_entry->SetPageID(0); | 
| + EXPECT_EQ(0U, restored_entry->root_node()->children.size()); | 
| + restored_entry->SetPageState(entry2->GetPageState()); | 
| + | 
| + // Verify subframe entries if they're enabled (e.g. in --site-per-process). | 
| + if (SiteIsolationPolicy::UseSubframeNavigationEntries()) { | 
| + // The entry should have no SiteInstance in the FrameNavigationEntry for the | 
| + // b.com subframe. | 
| + EXPECT_FALSE( | 
| + restored_entry->root_node()->children[0]->frame_entry->site_instance()); | 
| + } else { | 
| + // There are no subframe FrameNavigationEntries by default. | 
| + EXPECT_EQ(0U, restored_entry->root_node()->children.size()); | 
| + } | 
| + | 
| + // 4. Restore the new entry in a new tab and verify the correct URLs load. | 
| + std::vector<scoped_ptr<NavigationEntry>> entries; | 
| + entries.push_back(restored_entry.Pass()); | 
| + Shell* new_shell = Shell::CreateNewWindow( | 
| + controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size()); | 
| + FrameTreeNode* new_root = | 
| + static_cast<WebContentsImpl*>(new_shell->web_contents()) | 
| + ->GetFrameTree() | 
| + ->root(); | 
| + NavigationControllerImpl& new_controller = | 
| + static_cast<NavigationControllerImpl&>( | 
| + new_shell->web_contents()->GetController()); | 
| + new_controller.Restore( | 
| + entries.size() - 1, | 
| + NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries); | 
| + ASSERT_EQ(0u, entries.size()); | 
| + { | 
| + TestNavigationObserver restore_observer(new_shell->web_contents()); | 
| + new_controller.LoadIfNecessary(); | 
| + restore_observer.Wait(); | 
| + } | 
| + ASSERT_EQ(1U, new_root->child_count()); | 
| + EXPECT_EQ(main_url_a, new_root->current_url()); | 
| + EXPECT_EQ(frame_url_b, new_root->child_at(0)->current_url()); | 
| + | 
| + // The subframe should only be in a different process if OOPIFs are required | 
| 
 
nasko
2015/12/08 18:23:35
nit: "different SiteInstance" as process allocatio
 
Charlie Reis
2015/12/08 19:04:57
Done.
 
 | 
| + // for all sites. | 
| + if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) { | 
| + EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(), | 
| + new_root->child_at(0)->current_frame_host()->GetSiteInstance()); | 
| + } else { | 
| + EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(), | 
| + new_root->child_at(0)->current_frame_host()->GetSiteInstance()); | 
| + } | 
| +} | 
| + | 
| namespace { | 
| // Loads |start_url|, then loads |stalled_url| which stalls. While the page is |