OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/public/test/navigation_simulator.h" |
| 6 |
| 7 #include "base/memory/weak_ptr.h" |
| 8 #include "base/run_loop.h" |
| 9 #include "content/public/browser/navigation_handle.h" |
| 10 #include "content/public/browser/navigation_throttle.h" |
| 11 #include "content/test/test_render_frame_host.h" |
| 12 #include "content/test/test_web_contents.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 |
| 15 namespace content { |
| 16 |
| 17 enum CancelTime { |
| 18 WILL_SEND_REQUEST, |
| 19 WILL_REDIRECT_REQUEST, |
| 20 WILL_PROCESS_RESPONSE, |
| 21 NEVER, |
| 22 }; |
| 23 |
| 24 enum ResultSynchrony { |
| 25 SYNCHRONOUS, |
| 26 ASYNCHRONOUS, |
| 27 }; |
| 28 |
| 29 std::string CancelTimeToString(CancelTime cancel_time) { |
| 30 switch (cancel_time) { |
| 31 case WILL_SEND_REQUEST: |
| 32 return "WILL_SEND_REQUEST"; |
| 33 case WILL_REDIRECT_REQUEST: |
| 34 return "WILL_REDIRECT_REQUEST"; |
| 35 case WILL_PROCESS_RESPONSE: |
| 36 return "WILL_PROCESS_RESPONSE"; |
| 37 case NEVER: |
| 38 return "NEVER"; |
| 39 } |
| 40 NOTREACHED(); |
| 41 return ""; |
| 42 } |
| 43 |
| 44 std::string ResultSynchronyToString(ResultSynchrony sync) { |
| 45 return sync == SYNCHRONOUS ? "SYNCHRONOUS" : "ASYNCHRONOUS"; |
| 46 } |
| 47 |
| 48 class CancellingNavigationThrottle : public NavigationThrottle { |
| 49 public: |
| 50 CancellingNavigationThrottle(NavigationHandle* handle, |
| 51 CancelTime cancel_time, |
| 52 ResultSynchrony sync) |
| 53 : NavigationThrottle(handle), |
| 54 cancel_time_(cancel_time), |
| 55 sync_(sync), |
| 56 weak_ptr_factory_(this) {} |
| 57 |
| 58 ~CancellingNavigationThrottle() override {} |
| 59 |
| 60 NavigationThrottle::ThrottleCheckResult WillStartRequest() override { |
| 61 return ProcessState(cancel_time_ == WILL_SEND_REQUEST); |
| 62 } |
| 63 |
| 64 NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override { |
| 65 return ProcessState(cancel_time_ == WILL_REDIRECT_REQUEST); |
| 66 } |
| 67 |
| 68 NavigationThrottle::ThrottleCheckResult WillProcessResponse() override { |
| 69 return ProcessState(cancel_time_ == WILL_PROCESS_RESPONSE); |
| 70 } |
| 71 |
| 72 NavigationThrottle::ThrottleCheckResult ProcessState(bool should_cancel) { |
| 73 if (sync_ == ASYNCHRONOUS) { |
| 74 BrowserThread::PostTask( |
| 75 BrowserThread::UI, FROM_HERE, |
| 76 base::Bind(&CancellingNavigationThrottle::MaybeCancel, |
| 77 weak_ptr_factory_.GetWeakPtr(), should_cancel)); |
| 78 return NavigationThrottle::DEFER; |
| 79 } |
| 80 return should_cancel ? NavigationThrottle::CANCEL |
| 81 : NavigationThrottle::PROCEED; |
| 82 } |
| 83 |
| 84 void MaybeCancel(bool cancel) { |
| 85 if (cancel) |
| 86 navigation_handle()->CancelDeferredNavigation(NavigationThrottle::CANCEL); |
| 87 else |
| 88 navigation_handle()->Resume(); |
| 89 } |
| 90 |
| 91 const CancelTime cancel_time_; |
| 92 const ResultSynchrony sync_; |
| 93 base::WeakPtrFactory<CancellingNavigationThrottle> weak_ptr_factory_; |
| 94 }; |
| 95 |
| 96 class NavigationSimulatorTest : public RenderViewHostImplTestHarness, |
| 97 public WebContentsObserver, |
| 98 public testing::WithParamInterface< |
| 99 std::tuple<CancelTime, ResultSynchrony>> { |
| 100 public: |
| 101 void SetUp() override { |
| 102 RenderViewHostImplTestHarness::SetUp(); |
| 103 contents()->GetMainFrame()->InitializeRenderFrameIfNeeded(); |
| 104 Observe(RenderViewHostImplTestHarness::web_contents()); |
| 105 std::tie(cancel_time_, sync_) = GetParam(); |
| 106 simulator_ = NavigationSimulator::CreateRendererInitiated( |
| 107 GURL("https://example.test"), main_rfh()); |
| 108 } |
| 109 |
| 110 void DidStartNavigation(content::NavigationHandle* handle) override { |
| 111 handle->RegisterThrottleForTesting( |
| 112 base::MakeUnique<CancellingNavigationThrottle>(handle, cancel_time_, |
| 113 sync_)); |
| 114 } |
| 115 |
| 116 // Returns true if the request has been cancelled. |
| 117 bool ExpectResult(NavigationThrottle::ThrottleCheckResult sync_result, |
| 118 bool should_cancel) { |
| 119 NavigationThrottle::ThrottleCheckResult result = sync_result; |
| 120 if (sync_ == ASYNCHRONOUS) { |
| 121 EXPECT_EQ(NavigationThrottle::DEFER, sync_result); |
| 122 result = simulator_->WaitForThrottleChecksComplete(); |
| 123 } |
| 124 EXPECT_EQ(should_cancel ? NavigationThrottle::CANCEL |
| 125 : NavigationThrottle::PROCEED, |
| 126 result); |
| 127 return should_cancel; |
| 128 } |
| 129 |
| 130 CancelTime cancel_time_; |
| 131 ResultSynchrony sync_; |
| 132 std::unique_ptr<NavigationSimulator> simulator_; |
| 133 }; |
| 134 |
| 135 // Stress test the navigation simulator by having a navigation throttle cancel |
| 136 // the navigation at various points in the flow, both synchronously and |
| 137 // asynchronously. |
| 138 TEST_P(NavigationSimulatorTest, Cancel) { |
| 139 SCOPED_TRACE(::testing::Message() |
| 140 << "CancelTime: " << CancelTimeToString(cancel_time_) |
| 141 << " ResultSynchrony: " << ResultSynchronyToString(sync_)); |
| 142 if (ExpectResult(simulator_->Start(), cancel_time_ == WILL_SEND_REQUEST)) |
| 143 return; |
| 144 if (ExpectResult(simulator_->Redirect(GURL("https://example.test/redirect")), |
| 145 cancel_time_ == WILL_REDIRECT_REQUEST)) |
| 146 return; |
| 147 ExpectResult(simulator_->Commit(), cancel_time_ == WILL_PROCESS_RESPONSE); |
| 148 } |
| 149 |
| 150 INSTANTIATE_TEST_CASE_P( |
| 151 CancelMethod, |
| 152 NavigationSimulatorTest, |
| 153 ::testing::Values(std::make_tuple(WILL_SEND_REQUEST, SYNCHRONOUS), |
| 154 std::make_tuple(WILL_SEND_REQUEST, ASYNCHRONOUS), |
| 155 std::make_tuple(WILL_REDIRECT_REQUEST, SYNCHRONOUS), |
| 156 std::make_tuple(WILL_REDIRECT_REQUEST, ASYNCHRONOUS), |
| 157 std::make_tuple(WILL_PROCESS_RESPONSE, SYNCHRONOUS), |
| 158 std::make_tuple(WILL_PROCESS_RESPONSE, ASYNCHRONOUS), |
| 159 std::make_tuple(NEVER, SYNCHRONOUS), |
| 160 std::make_tuple(NEVER, ASYNCHRONOUS))); |
| 161 |
| 162 } // namespace content |
OLD | NEW |