| Index: content/test/navigation_simulator_unittest.cc
|
| diff --git a/content/test/navigation_simulator_unittest.cc b/content/test/navigation_simulator_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..27638b794c5a5683db734ce346250f062ee1ded0
|
| --- /dev/null
|
| +++ b/content/test/navigation_simulator_unittest.cc
|
| @@ -0,0 +1,166 @@
|
| +// Copyright 2017 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/public/test/navigation_simulator.h"
|
| +
|
| +#include "base/memory/weak_ptr.h"
|
| +#include "base/run_loop.h"
|
| +#include "content/public/browser/navigation_handle.h"
|
| +#include "content/public/browser/navigation_throttle.h"
|
| +#include "content/test/test_render_frame_host.h"
|
| +#include "content/test/test_web_contents.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +enum CancelTime {
|
| + WILL_SEND_REQUEST,
|
| + WILL_REDIRECT_REQUEST,
|
| + WILL_PROCESS_RESPONSE,
|
| + NEVER,
|
| +};
|
| +
|
| +enum ResultSynchrony {
|
| + SYNCHRONOUS,
|
| + ASYNCHRONOUS,
|
| +};
|
| +
|
| +std::string CancelTimeToString(CancelTime cancel_time) {
|
| + switch (cancel_time) {
|
| + case WILL_SEND_REQUEST:
|
| + return "WILL_SEND_REQUEST";
|
| + case WILL_REDIRECT_REQUEST:
|
| + return "WILL_REDIRECT_REQUEST";
|
| + case WILL_PROCESS_RESPONSE:
|
| + return "WILL_PROCESS_RESPONSE";
|
| + case NEVER:
|
| + return "NEVER";
|
| + }
|
| + NOTREACHED();
|
| + return "";
|
| +}
|
| +
|
| +std::string ResultSynchronyToString(ResultSynchrony sync) {
|
| + return sync == SYNCHRONOUS ? "SYNCHRONOUS" : "ASYNCHRONOUS";
|
| +}
|
| +
|
| +class CancellingNavigationThrottle : public NavigationThrottle {
|
| + public:
|
| + CancellingNavigationThrottle(NavigationHandle* handle,
|
| + CancelTime cancel_time,
|
| + ResultSynchrony sync)
|
| + : NavigationThrottle(handle),
|
| + cancel_time_(cancel_time),
|
| + sync_(sync),
|
| + weak_ptr_factory_(this) {}
|
| +
|
| + ~CancellingNavigationThrottle() override {}
|
| +
|
| + NavigationThrottle::ThrottleCheckResult WillStartRequest() override {
|
| + return ProcessState(cancel_time_ == WILL_SEND_REQUEST);
|
| + }
|
| +
|
| + NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override {
|
| + return ProcessState(cancel_time_ == WILL_REDIRECT_REQUEST);
|
| + }
|
| +
|
| + NavigationThrottle::ThrottleCheckResult WillProcessResponse() override {
|
| + return ProcessState(cancel_time_ == WILL_PROCESS_RESPONSE);
|
| + }
|
| +
|
| + NavigationThrottle::ThrottleCheckResult ProcessState(bool should_cancel) {
|
| + if (sync_ == ASYNCHRONOUS) {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&CancellingNavigationThrottle::MaybeCancel,
|
| + weak_ptr_factory_.GetWeakPtr(), should_cancel));
|
| + return NavigationThrottle::DEFER;
|
| + }
|
| + return should_cancel ? NavigationThrottle::CANCEL
|
| + : NavigationThrottle::PROCEED;
|
| + }
|
| +
|
| + void MaybeCancel(bool cancel) {
|
| + if (cancel)
|
| + navigation_handle()->CancelDeferredNavigation(NavigationThrottle::CANCEL);
|
| + else
|
| + navigation_handle()->Resume();
|
| + }
|
| +
|
| + const CancelTime cancel_time_;
|
| + const ResultSynchrony sync_;
|
| + base::WeakPtrFactory<CancellingNavigationThrottle> weak_ptr_factory_;
|
| +};
|
| +
|
| +class NavigationSimulatorTest : public RenderViewHostImplTestHarness,
|
| + public WebContentsObserver,
|
| + public testing::WithParamInterface<
|
| + std::tuple<CancelTime, ResultSynchrony>> {
|
| + public:
|
| + void SetUp() override {
|
| + RenderViewHostImplTestHarness::SetUp();
|
| + contents()->GetMainFrame()->InitializeRenderFrameIfNeeded();
|
| + Observe(RenderViewHostImplTestHarness::web_contents());
|
| + std::tie(cancel_time_, sync_) = GetParam();
|
| + simulator_ = NavigationSimulator::CreateRendererInitiated(
|
| + GURL("https://example.test"), main_rfh());
|
| + }
|
| +
|
| + void DidStartNavigation(content::NavigationHandle* handle) override {
|
| + handle->RegisterThrottleForTesting(
|
| + base::MakeUnique<CancellingNavigationThrottle>(handle, cancel_time_,
|
| + sync_));
|
| + }
|
| +
|
| + CancelTime cancel_time_;
|
| + ResultSynchrony sync_;
|
| + std::unique_ptr<NavigationSimulator> simulator_;
|
| +};
|
| +
|
| +// Stress test the navigation simulator by having a navigation throttle cancel
|
| +// the navigation at various points in the flow, both synchronously and
|
| +// asynchronously.
|
| +TEST_P(NavigationSimulatorTest, Cancel) {
|
| + SCOPED_TRACE(::testing::Message()
|
| + << "CancelTime: " << CancelTimeToString(cancel_time_)
|
| + << " ResultSynchrony: " << ResultSynchronyToString(sync_));
|
| + simulator_->Start();
|
| + if (cancel_time_ == WILL_SEND_REQUEST) {
|
| + EXPECT_EQ(NavigationThrottle::CANCEL,
|
| + simulator_->GetLastThrottleCheckResult());
|
| + return;
|
| + }
|
| + EXPECT_EQ(NavigationThrottle::PROCEED,
|
| + simulator_->GetLastThrottleCheckResult());
|
| + simulator_->Redirect(GURL("https://example.redirect"));
|
| + if (cancel_time_ == WILL_REDIRECT_REQUEST) {
|
| + EXPECT_EQ(NavigationThrottle::CANCEL,
|
| + simulator_->GetLastThrottleCheckResult());
|
| + return;
|
| + }
|
| + EXPECT_EQ(NavigationThrottle::PROCEED,
|
| + simulator_->GetLastThrottleCheckResult());
|
| + simulator_->Commit();
|
| + if (cancel_time_ == WILL_PROCESS_RESPONSE) {
|
| + EXPECT_EQ(NavigationThrottle::CANCEL,
|
| + simulator_->GetLastThrottleCheckResult());
|
| + return;
|
| + }
|
| + EXPECT_EQ(NavigationThrottle::PROCEED,
|
| + simulator_->GetLastThrottleCheckResult());
|
| +}
|
| +
|
| +INSTANTIATE_TEST_CASE_P(
|
| + CancelMethod,
|
| + NavigationSimulatorTest,
|
| + ::testing::Values(std::make_tuple(WILL_SEND_REQUEST, SYNCHRONOUS),
|
| + std::make_tuple(WILL_SEND_REQUEST, ASYNCHRONOUS),
|
| + std::make_tuple(WILL_REDIRECT_REQUEST, SYNCHRONOUS),
|
| + std::make_tuple(WILL_REDIRECT_REQUEST, ASYNCHRONOUS),
|
| + std::make_tuple(WILL_PROCESS_RESPONSE, SYNCHRONOUS),
|
| + std::make_tuple(WILL_PROCESS_RESPONSE, ASYNCHRONOUS),
|
| + std::make_tuple(NEVER, SYNCHRONOUS),
|
| + std::make_tuple(NEVER, ASYNCHRONOUS)));
|
| +
|
| +} // namespace content
|
|
|