Commit 148d95b8 authored by Hiroki Nakagawa's avatar Hiroki Nakagawa Committed by Commit Bot

Prerender: Add unit tests for mojo calls on PrerenderProcessor

Bug: 1149226
Change-Id: I48391f13e88a5cd772cb2bb79db01dcd54ea6285
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2549021Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Commit-Queue: Hiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829210}
parent 3e59a753
// Copyright 2020 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 "content/browser/prerender/prerender_processor.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/test_browser_context.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "mojo/public/cpp/system/functions.h"
#include "third_party/blink/public/common/features.h"
namespace content {
namespace {
// TODO(https://crbug.com/839030): Remove this implementation along with
// deprecating the prefixed prerender events.
class PrerenderProcessorClient final
: public blink::mojom::PrerenderProcessorClient {
public:
// blink::mojom::PrerenderProcessorClient:
void OnPrerenderStart() override {}
void OnPrerenderStopLoading() override {}
void OnPrerenderDomContentLoaded() override {}
void OnPrerenderStop() override {}
mojo::PendingRemote<blink::mojom::PrerenderProcessorClient>
BindNewPipeAndPassRemote() {
return receiver_.BindNewPipeAndPassRemote();
}
private:
mojo::Receiver<blink::mojom::PrerenderProcessorClient> receiver_{this};
};
class PrerenderProcessorTest : public RenderViewHostImplTestHarness {
public:
void SetUp() override {
RenderViewHostImplTestHarness::SetUp();
scoped_feature_list_.InitAndEnableFeature(blink::features::kPrerender2);
browser_context_ = std::make_unique<TestBrowserContext>();
web_contents_ = TestWebContents::Create(
browser_context_.get(),
SiteInstanceImpl::Create(browser_context_.get()));
web_contents_->NavigateAndCommit(GURL("https://example.com"));
}
void TearDown() override {
web_contents_.reset();
browser_context_.reset();
RenderViewHostImplTestHarness::TearDown();
}
void DestroyPrerenderProcessors() {
// Resetting the web contents destroys render frame hosts, which in turn
// destroy `RenderFrameHostImpl::prerender_processor_receivers_`.
web_contents_.reset();
}
RenderFrameHostImpl* GetRenderFrameHost() {
DCHECK(web_contents_);
return web_contents_->GetMainFrame();
}
PrerenderHostRegistry* GetPrerenderHostRegistry() const {
return static_cast<StoragePartitionImpl*>(
BrowserContext::GetDefaultStoragePartition(
browser_context_.get()))
->GetPrerenderHostRegistry();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<TestWebContents> web_contents_;
};
TEST_F(PrerenderProcessorTest, StartCancel) {
RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
mojo::Remote<blink::mojom::PrerenderProcessor> remote;
render_frame_host->BindPrerenderProcessor(
render_frame_host, remote.BindNewPipeAndPassReceiver());
const GURL kPrerenderingUrl("https://example.com/next");
auto attributes = blink::mojom::PrerenderAttributes::New();
attributes->url = kPrerenderingUrl;
attributes->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client;
// Start() call should register a new prerender host.
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
remote->Start(std::move(attributes), client.BindNewPipeAndPassRemote());
remote.FlushForTesting();
EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
// Cancel() call should abandon the prerender host.
remote->Cancel();
remote.FlushForTesting();
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
}
TEST_F(PrerenderProcessorTest, StartDisconnect) {
RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
mojo::Remote<blink::mojom::PrerenderProcessor> remote;
render_frame_host->BindPrerenderProcessor(
render_frame_host, remote.BindNewPipeAndPassReceiver());
const GURL kPrerenderingUrl("https://example.com/next");
auto attributes = blink::mojom::PrerenderAttributes::New();
attributes->url = kPrerenderingUrl;
attributes->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client;
// Start() call should register a new prerender host.
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
remote->Start(std::move(attributes), client.BindNewPipeAndPassRemote());
remote.FlushForTesting();
EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
// Connection lost should abandon the prerender host.
remote.reset();
// FlushForTesting() is no longer available. Instead, use base::RunLoop.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
}
TEST_F(PrerenderProcessorTest, CancelOnDestruction) {
RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
mojo::Remote<blink::mojom::PrerenderProcessor> remote;
render_frame_host->BindPrerenderProcessor(
render_frame_host, remote.BindNewPipeAndPassReceiver());
const GURL kPrerenderingUrl("https://example.com/next");
auto attributes = blink::mojom::PrerenderAttributes::New();
attributes->url = kPrerenderingUrl;
attributes->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client;
// Start() call should register a new prerender host.
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
remote->Start(std::move(attributes), client.BindNewPipeAndPassRemote());
remote.FlushForTesting();
EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
// The destructor of PrerenderProcessor should abandon the prerender host.
DestroyPrerenderProcessors();
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
}
TEST_F(PrerenderProcessorTest, StartTwice) {
RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
PrerenderHostRegistry* registry = GetPrerenderHostRegistry();
mojo::Remote<blink::mojom::PrerenderProcessor> remote;
render_frame_host->BindPrerenderProcessor(
render_frame_host, remote.BindNewPipeAndPassReceiver());
// Set up the error handler for bad mojo messages.
std::string bad_message_error;
mojo::SetDefaultProcessErrorHandler(
base::BindLambdaForTesting([&](const std::string& error) {
EXPECT_TRUE(bad_message_error.empty());
bad_message_error = error;
}));
const GURL kPrerenderingUrl("https://example.com/next");
auto attributes1 = blink::mojom::PrerenderAttributes::New();
attributes1->url = kPrerenderingUrl;
attributes1->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client1;
// Start() call should register a new prerender host.
EXPECT_FALSE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
remote->Start(std::move(attributes1), client1.BindNewPipeAndPassRemote());
remote.FlushForTesting();
EXPECT_TRUE(registry->FindHostByUrlForTesting(kPrerenderingUrl));
auto attributes2 = blink::mojom::PrerenderAttributes::New();
attributes2->url = kPrerenderingUrl;
attributes2->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client2;
// Call Start() again. This should be reported as a bad mojo message.
ASSERT_TRUE(bad_message_error.empty());
remote->Start(std::move(attributes2), client2.BindNewPipeAndPassRemote());
remote.FlushForTesting();
EXPECT_EQ(bad_message_error, "PP_START_TWICE");
}
TEST_F(PrerenderProcessorTest, CancelBeforeStart) {
RenderFrameHostImpl* render_frame_host = GetRenderFrameHost();
mojo::Remote<blink::mojom::PrerenderProcessor> remote;
render_frame_host->BindPrerenderProcessor(
render_frame_host, remote.BindNewPipeAndPassReceiver());
// Set up the error handler for bad mojo messages.
std::string bad_message_error;
mojo::SetDefaultProcessErrorHandler(
base::BindLambdaForTesting([&](const std::string& error) {
EXPECT_TRUE(bad_message_error.empty());
bad_message_error = error;
}));
const GURL kPrerenderingUrl("https://example.com/next");
auto attributes1 = blink::mojom::PrerenderAttributes::New();
attributes1->url = kPrerenderingUrl;
attributes1->referrer = blink::mojom::Referrer::New();
PrerenderProcessorClient client1;
// Call Cancel() before Start(). This should be reported as a bad mojo
// message.
ASSERT_TRUE(bad_message_error.empty());
remote->Cancel();
remote.FlushForTesting();
EXPECT_EQ(bad_message_error, "PP_CANCEL_BEFORE_START");
}
} // namespace
} // namespace content
...@@ -1889,6 +1889,7 @@ test("content_unittests") { ...@@ -1889,6 +1889,7 @@ test("content_unittests") {
"../browser/plugin_list_unittest.cc", "../browser/plugin_list_unittest.cc",
"../browser/prerender/prerender_host_registry_unittest.cc", "../browser/prerender/prerender_host_registry_unittest.cc",
"../browser/prerender/prerender_host_unittest.cc", "../browser/prerender/prerender_host_unittest.cc",
"../browser/prerender/prerender_processor_unittest.cc",
"../browser/presentation/presentation_service_impl_unittest.cc", "../browser/presentation/presentation_service_impl_unittest.cc",
"../browser/quota/quota_change_dispatcher_unittest.cc", "../browser/quota/quota_change_dispatcher_unittest.cc",
"../browser/renderer_host/ancestor_throttle_unittest.cc", "../browser/renderer_host/ancestor_throttle_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment