
The performance manager now lives on the UI thread, making these functions obsolete. The graph can be directly accessed through the PerformanceManager::GetGraph() function. This CL was uploaded by git cl split. R=joenotcharles@google.com Bug: 40755583 Change-Id: Id00ef39f891380c54eca6227456923956d565a6b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6284745 Reviewed-by: Joe Mason <joenotcharles@google.com> Commit-Queue: Patrick Monette <pmonette@chromium.org> Auto-Submit: Patrick Monette <pmonette@chromium.org> Cr-Commit-Position: refs/heads/main@{#1422663}
217 lines
9.0 KiB
C++
217 lines
9.0 KiB
C++
// Copyright 2021 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include <string>
|
|
|
|
#include "base/functional/bind.h"
|
|
#include "base/memory/weak_ptr.h"
|
|
#include "components/performance_manager/public/graph/frame_node.h"
|
|
#include "components/performance_manager/public/graph/page_node.h"
|
|
#include "components/performance_manager/public/performance_manager.h"
|
|
#include "components/performance_manager/test_support/performance_manager_browsertest_harness.h"
|
|
#include "content/public/browser/back_forward_cache.h"
|
|
#include "content/public/browser/render_frame_host.h"
|
|
#include "content/public/browser/web_contents.h"
|
|
#include "content/public/test/back_forward_cache_util.h"
|
|
#include "content/public/test/browser_test.h"
|
|
#include "content/public/test/browser_test_utils.h"
|
|
#include "content/public/test/prerender_test_util.h"
|
|
#include "content/public/test/test_utils.h"
|
|
#include "content/shell/browser/shell.h"
|
|
#include "net/test/embedded_test_server/embedded_test_server.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "url/gurl.h"
|
|
|
|
namespace performance_manager {
|
|
|
|
class Graph;
|
|
|
|
// Tests that the PerformanceManager node states are updated correctly during
|
|
// prerendering.
|
|
//
|
|
// TODO(crbug.com/40182881): These tests assume prerendering frames are added as
|
|
// extra FrameNodes on the existing PageNode. Update this logic once
|
|
// prerendering frame trees have their own PageNode.
|
|
class PerformanceManagerPrerenderingBrowserTest
|
|
: public PerformanceManagerBrowserTestHarness {
|
|
public:
|
|
using Super = PerformanceManagerBrowserTestHarness;
|
|
|
|
PerformanceManagerPrerenderingBrowserTest()
|
|
: prerender_helper_(base::BindRepeating(
|
|
&PerformanceManagerPrerenderingBrowserTest::web_contents,
|
|
base::Unretained(this))) {
|
|
prerender_helper_.RegisterServerRequestMonitor(&ssl_server_);
|
|
}
|
|
|
|
void SetUpOnMainThread() override {
|
|
Super::SetUpOnMainThread();
|
|
ssl_server_.AddDefaultHandlers(GetTestDataFilePath());
|
|
ssl_server_.SetSSLConfig(
|
|
net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
|
|
ASSERT_TRUE(ssl_server_.Start());
|
|
|
|
// TODO(crbug.com/40172688): PrerenderHost is not deleted when the
|
|
// page enters BackForwardCache, though it should be. While this
|
|
// functionality is not implemented, disable BackForwardCache for testing
|
|
// and wait for the old RenderFrameHost to be deleted after we navigate away
|
|
// from it.
|
|
content::DisableBackForwardCacheForTesting(
|
|
web_contents(), content::BackForwardCache::TEST_REQUIRES_NO_CACHING);
|
|
}
|
|
|
|
void TearDownOnMainThread() override {
|
|
EXPECT_TRUE(ssl_server_.ShutdownAndWaitUntilComplete());
|
|
Super::TearDownOnMainThread();
|
|
}
|
|
|
|
content::WebContents* web_contents() { return shell()->web_contents(); }
|
|
|
|
GURL GetUrl(const std::string& path) {
|
|
return ssl_server_.GetURL("a.test", path);
|
|
}
|
|
|
|
protected:
|
|
net::test_server::EmbeddedTestServer ssl_server_{
|
|
net::test_server::EmbeddedTestServer::TYPE_HTTPS};
|
|
content::test::PrerenderTestHelper prerender_helper_;
|
|
};
|
|
|
|
IN_PROC_BROWSER_TEST_F(PerformanceManagerPrerenderingBrowserTest,
|
|
PrerenderingFinishes) {
|
|
const GURL kInitialUrl = GetUrl("/empty.html");
|
|
const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
|
|
|
|
// Navigate to an initial page. Test that PM has a PageNode for it, and
|
|
// GetMainFrameNode returns its main frame.
|
|
ASSERT_TRUE(content::NavigateToURL(web_contents(), kInitialUrl));
|
|
base::WeakPtr<PageNode> page_node =
|
|
PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents());
|
|
|
|
ASSERT_TRUE(page_node);
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 1U);
|
|
const FrameNode* initial_main_frame_node = page_node->GetMainFrameNode();
|
|
int64_t initial_navigation_id = page_node->GetNavigationID();
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kInitialUrl);
|
|
EXPECT_TRUE(initial_main_frame_node->IsCurrent());
|
|
|
|
// Start prerendering a document. Test that the prerendering frame tree is
|
|
// added as additional frame nodes, but GetMainFrameNode is unchanged.
|
|
prerender_helper_.AddPrerender(kPrerenderingUrl);
|
|
base::WeakPtr<PageNode> page_node2 =
|
|
PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents());
|
|
|
|
ASSERT_TRUE(page_node);
|
|
ASSERT_EQ(page_node.get(), page_node2.get());
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 2U);
|
|
EXPECT_EQ(page_node->GetMainFrameNode(), initial_main_frame_node);
|
|
EXPECT_TRUE(initial_main_frame_node->IsCurrent());
|
|
|
|
// Find the prerendering MainFrameNode.
|
|
const FrameNode* prerender_main_frame_node = nullptr;
|
|
for (const FrameNode* frame_node : page_node->GetMainFrameNodes()) {
|
|
if (frame_node != initial_main_frame_node) {
|
|
prerender_main_frame_node = frame_node;
|
|
break;
|
|
}
|
|
}
|
|
ASSERT_TRUE(prerender_main_frame_node);
|
|
EXPECT_EQ(prerender_main_frame_node->GetURL(), kPrerenderingUrl);
|
|
EXPECT_FALSE(prerender_main_frame_node->IsCurrent());
|
|
|
|
// The prerendering navigation should not be reflected in the PageNode.
|
|
EXPECT_EQ(page_node->GetNavigationID(), initial_navigation_id);
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kInitialUrl);
|
|
|
|
// Activate the prerendered document. Test that GetMainFrameNode now returns
|
|
// its main frame, and the original frame tree is gone.
|
|
content::RenderFrameDeletedObserver deleted_observer(
|
|
web_contents()->GetPrimaryMainFrame());
|
|
content::test::PrerenderHostObserver prerender_observer(*web_contents(),
|
|
kPrerenderingUrl);
|
|
prerender_helper_.NavigatePrimaryPage(kPrerenderingUrl);
|
|
ASSERT_TRUE(prerender_observer.was_activated());
|
|
deleted_observer.WaitUntilDeleted();
|
|
|
|
ASSERT_TRUE(page_node);
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 1U);
|
|
EXPECT_EQ(page_node->GetMainFrameNode(), prerender_main_frame_node);
|
|
EXPECT_TRUE(prerender_main_frame_node->IsCurrent());
|
|
|
|
// Now the PageNode should reflect the prerendering navigation.
|
|
EXPECT_NE(page_node->GetNavigationID(), initial_navigation_id);
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kPrerenderingUrl);
|
|
}
|
|
|
|
IN_PROC_BROWSER_TEST_F(PerformanceManagerPrerenderingBrowserTest,
|
|
PrerenderingCancelled) {
|
|
const GURL kInitialUrl = GetUrl("/empty.html");
|
|
const GURL kPrerenderingUrl = GetUrl("/empty.html?prerender");
|
|
const GURL kFinalUrl = GetUrl("/empty.html?elsewhere");
|
|
|
|
// Navigate to an initial page. Test that PM has a PageNode for it, and
|
|
// GetMainFrameNode returns its main frame.
|
|
ASSERT_TRUE(content::NavigateToURL(web_contents(), kInitialUrl));
|
|
base::WeakPtr<PageNode> page_node =
|
|
PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents());
|
|
|
|
ASSERT_TRUE(page_node);
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 1U);
|
|
const FrameNode* initial_main_frame_node = page_node->GetMainFrameNode();
|
|
int64_t initial_navigation_id = page_node->GetNavigationID();
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kInitialUrl);
|
|
EXPECT_TRUE(initial_main_frame_node->IsCurrent());
|
|
|
|
// Start prerendering a document. Test that the prerendering frame tree is
|
|
// added as additional frame nodes, but GetMainFrameNode is unchanged.
|
|
content::FrameTreeNodeId prerender_host =
|
|
prerender_helper_.AddPrerender(kPrerenderingUrl);
|
|
base::WeakPtr<PageNode> page_node2 =
|
|
PerformanceManager::GetPrimaryPageNodeForWebContents(web_contents());
|
|
|
|
ASSERT_TRUE(page_node);
|
|
ASSERT_EQ(page_node.get(), page_node2.get());
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 2U);
|
|
EXPECT_EQ(page_node->GetMainFrameNode(), initial_main_frame_node);
|
|
EXPECT_TRUE(initial_main_frame_node->IsCurrent());
|
|
|
|
// Find the prerendering MainFrameNode.
|
|
const FrameNode* prerender_main_frame_node = nullptr;
|
|
for (const FrameNode* frame_node : page_node->GetMainFrameNodes()) {
|
|
if (frame_node != initial_main_frame_node) {
|
|
prerender_main_frame_node = frame_node;
|
|
break;
|
|
}
|
|
}
|
|
ASSERT_TRUE(prerender_main_frame_node);
|
|
EXPECT_EQ(prerender_main_frame_node->GetURL(), kPrerenderingUrl);
|
|
EXPECT_FALSE(prerender_main_frame_node->IsCurrent());
|
|
|
|
// The prerendering navigation should not be reflected in the PageNode.
|
|
EXPECT_EQ(page_node->GetNavigationID(), initial_navigation_id);
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kInitialUrl);
|
|
|
|
// Navigate the main frame to another page. Test that the prerendering frame
|
|
// tree is removed from PerformanceManager.
|
|
content::RenderFrameDeletedObserver deleted_observer(
|
|
prerender_helper_.GetPrerenderedMainFrameHost(prerender_host));
|
|
bool rfh_should_change =
|
|
web_contents()
|
|
->GetPrimaryMainFrame()
|
|
->ShouldChangeRenderFrameHostOnSameSiteNavigation();
|
|
ASSERT_TRUE(content::NavigateToURL(web_contents(), kFinalUrl));
|
|
deleted_observer.WaitUntilDeleted();
|
|
|
|
ASSERT_TRUE(page_node);
|
|
EXPECT_EQ(page_node->GetMainFrameNodes().size(), 1U);
|
|
// The RenderFrameHost might change after the navigation if RenderDocument
|
|
// is enabled.
|
|
EXPECT_EQ(rfh_should_change,
|
|
page_node->GetMainFrameNode() != initial_main_frame_node);
|
|
EXPECT_EQ(page_node->GetMainFrameUrl(), kFinalUrl);
|
|
EXPECT_TRUE(page_node->GetMainFrameNode()->IsCurrent());
|
|
}
|
|
|
|
} // namespace performance_manager
|