Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3042)

Unified Diff: content/browser/loader/throttling_resource_handler_unittest.cc

Issue 2563163002: Add some tests for ThrottlingResourceHandler. (Closed)
Patch Set: Add comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/loader/throttling_resource_handler.cc ('k') | content/test/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/loader/throttling_resource_handler_unittest.cc
diff --git a/content/browser/loader/throttling_resource_handler_unittest.cc b/content/browser/loader/throttling_resource_handler_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0b507b072f2371cdce296117d65aeed08ccf2a9d
--- /dev/null
+++ b/content/browser/loader/throttling_resource_handler_unittest.cc
@@ -0,0 +1,899 @@
+// Copyright 2016 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/loader/throttling_resource_handler.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "content/browser/loader/mock_resource_loader.h"
+#include "content/browser/loader/resource_request_info_impl.h"
+#include "content/browser/loader/test_resource_handler.h"
+#include "content/public/browser/resource_throttle.h"
+#include "content/public/common/resource_response.h"
+#include "net/base/request_priority.h"
+#include "net/url_request/redirect_info.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+namespace {
+
+const char kInitialUrl[] = "http://initial/";
+const char kRedirectUrl[] = "http://redirect/";
+
+class TestResourceThrottle : public ResourceThrottle {
+ public:
+ explicit TestResourceThrottle(TestResourceThrottle* previous_throttle) {
+ if (previous_throttle) {
+ DCHECK(!previous_throttle->next_throttle_);
+ previous_throttle_ = previous_throttle;
+ previous_throttle_->next_throttle_ = this;
+ }
+ }
+
+ ~TestResourceThrottle() override {}
+
+ // Sets the throttle after this one, to enable checks that they're called in
+ // the expected order.
+ void SetNextThrottle(TestResourceThrottle* throttle) {
+ DCHECK(!next_throttle_);
+ DCHECK(!throttle->previous_throttle_);
+
+ next_throttle_ = throttle;
+ throttle->previous_throttle_ = this;
+ }
+
+ // ResourceThrottle implemenation:
+
+ void WillStartRequest(bool* defer) override {
+ EXPECT_EQ(0, will_start_request_called_);
+ EXPECT_EQ(0, will_redirect_request_called_);
+ EXPECT_EQ(0, will_process_response_called_);
+
+ if (previous_throttle_) {
+ EXPECT_EQ(1, previous_throttle_->will_start_request_called_);
+ EXPECT_EQ(0, previous_throttle_->will_redirect_request_called_);
+ EXPECT_EQ(0, previous_throttle_->will_process_response_called_);
+ }
+
+ if (next_throttle_) {
+ EXPECT_EQ(0, next_throttle_->will_start_request_called_);
+ EXPECT_EQ(0, next_throttle_->will_redirect_request_called_);
+ EXPECT_EQ(0, next_throttle_->will_process_response_called_);
+ }
+
+ ++will_start_request_called_;
+ *defer = defer_on_will_start_request_;
+ if (cancel_on_will_start_request_)
+ CancelWithError(net::ERR_UNEXPECTED);
+ }
+
+ void WillRedirectRequest(const net::RedirectInfo& redirect_info,
+ bool* defer) override {
+ EXPECT_EQ(GURL(kRedirectUrl), redirect_info.new_url);
+
+ EXPECT_EQ(1, will_start_request_called_);
+ // None of these tests use multiple redirects.
+ EXPECT_EQ(0, will_redirect_request_called_);
+ EXPECT_EQ(0, will_process_response_called_);
+
+ if (previous_throttle_) {
+ EXPECT_EQ(1, previous_throttle_->will_start_request_called_);
+ EXPECT_EQ(1, previous_throttle_->will_redirect_request_called_);
+ EXPECT_EQ(0, previous_throttle_->will_process_response_called_);
+ }
+
+ if (next_throttle_) {
+ EXPECT_EQ(1, next_throttle_->will_start_request_called_);
+ EXPECT_EQ(0, next_throttle_->will_redirect_request_called_);
+ EXPECT_EQ(0, next_throttle_->will_process_response_called_);
+ }
+
+ ++will_redirect_request_called_;
+ *defer = defer_on_will_redirect_request_;
+ if (cancel_on_will_redirect_request_)
+ CancelWithError(net::ERR_UNEXPECTED);
+ }
+
+ void WillProcessResponse(bool* defer) override {
+ EXPECT_EQ(0, will_process_response_called_);
+
+ if (previous_throttle_)
+ EXPECT_EQ(1, previous_throttle_->will_process_response_called_);
+
+ if (next_throttle_)
+ EXPECT_EQ(0, next_throttle_->will_process_response_called_);
+
+ ++will_process_response_called_;
+ *defer = defer_on_will_process_response_;
+ if (cancel_on_will_process_response_)
+ CancelWithError(net::ERR_UNEXPECTED);
+ }
+
+ const char* GetNameForLogging() const override { return "Hank"; }
+
+ int will_start_request_called() const { return will_start_request_called_; }
+ int will_redirect_request_called() const {
+ return will_redirect_request_called_;
+ }
+ int will_process_response_called() const {
+ return will_process_response_called_;
+ }
+
+ void set_defer_on_will_start_request(bool defer_on_will_start_request) {
+ defer_on_will_start_request_ = defer_on_will_start_request;
+ }
+ void set_defer_on_will_redirect_request(bool defer_on_will_redirect_request) {
+ defer_on_will_redirect_request_ = defer_on_will_redirect_request;
+ }
+ void set_defer_on_will_process_response(bool defer_on_will_process_response) {
+ defer_on_will_process_response_ = defer_on_will_process_response;
+ }
+
+ void set_cancel_on_will_start_request(bool cancel_on_will_start_request) {
+ cancel_on_will_start_request_ = cancel_on_will_start_request;
+ }
+ void set_cancel_on_will_redirect_request(
+ bool cancel_on_will_redirect_request) {
+ cancel_on_will_redirect_request_ = cancel_on_will_redirect_request;
+ }
+ void set_cancel_on_will_process_response(
+ bool cancel_on_will_process_response) {
+ cancel_on_will_process_response_ = cancel_on_will_process_response;
+ }
+
+ using ResourceThrottle::Resume;
+ using ResourceThrottle::CancelWithError;
+
+ private:
+ int will_start_request_called_ = 0;
+ int will_redirect_request_called_ = 0;
+ int will_process_response_called_ = 0;
+
+ bool defer_on_will_start_request_ = false;
+ bool defer_on_will_redirect_request_ = false;
+ bool defer_on_will_process_response_ = false;
+
+ bool cancel_on_will_start_request_ = false;
+ bool cancel_on_will_redirect_request_ = false;
+ bool cancel_on_will_process_response_ = false;
+
+ TestResourceThrottle* previous_throttle_ = nullptr;
+ TestResourceThrottle* next_throttle_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(TestResourceThrottle);
+};
+
+class ThrottlingResourceHandlerTest : public testing::Test {
+ public:
+ ThrottlingResourceHandlerTest()
+ : never_started_url_request_(request_context_.CreateRequest(
+ GURL(kInitialUrl),
+ net::DEFAULT_PRIORITY,
+ &never_started_url_request_delegate_)),
+ throttle1_(new TestResourceThrottle(nullptr)),
+ throttle2_(new TestResourceThrottle(throttle1_)),
+ test_handler_(new TestResourceHandler()) {
+ std::vector<std::unique_ptr<ResourceThrottle>> throttles;
+ throttles.push_back(base::WrapUnique(throttle1_));
+ throttles.push_back(base::WrapUnique(throttle2_));
+ throttling_handler_.reset(new ThrottlingResourceHandler(
+ base::WrapUnique(test_handler_), never_started_url_request_.get(),
+ std::move(throttles)));
+ mock_loader_.reset(new MockResourceLoader(throttling_handler_.get()));
+
+ // Basic initial state sanity checks.
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ }
+
+ // Finish the request with a 0-byte read and success. Reads are not passed
+ // to ResourceThrottles, so are uninteresting for the purposes of these tests.
+ void FinishRequestSuccessfully() {
+ EXPECT_EQ(0, test_handler_->on_will_read_called());
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead(1));
+ EXPECT_EQ(1, test_handler_->on_will_read_called());
+ EXPECT_EQ(0, test_handler_->on_read_completed_called());
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnReadCompleted(0));
+ EXPECT_EQ(1, test_handler_->on_read_completed_called());
+ EXPECT_EQ(0, test_handler_->on_response_completed_called());
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::OK)));
+ EXPECT_EQ(net::OK, mock_loader_->error_code());
+ EXPECT_EQ(1, test_handler_->on_read_completed_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+ }
+
+ protected:
+ // Needs to be first, so it's destroyed last.
+ base::MessageLoopForIO message_loop_;
+
+ // Machinery to construct a URLRequest that's just used as an argument to
+ // methods that expect one, and is never actually started.
+ net::TestURLRequestContext request_context_;
+ net::TestDelegate never_started_url_request_delegate_;
+ std::unique_ptr<net::URLRequest> never_started_url_request_;
+
+ // Owned by test_handler_;
+ TestResourceThrottle* throttle1_;
+ TestResourceThrottle* throttle2_;
+
+ // Owned by |throttling_handler_|.
+ TestResourceHandler* test_handler_;
+ std::unique_ptr<ThrottlingResourceHandler> throttling_handler_;
+ std::unique_ptr<MockResourceLoader> mock_loader_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ThrottlingResourceHandlerTest);
+};
+
+TEST_F(ThrottlingResourceHandlerTest, Sync) {
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(1, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(1, test_handler_->on_response_started_called());
+ EXPECT_EQ(0, test_handler_->on_read_completed_called());
+
+ FinishRequestSuccessfully();
+}
+
+TEST_F(ThrottlingResourceHandlerTest, Async) {
+ throttle1_->set_defer_on_will_start_request(true);
+ throttle1_->set_defer_on_will_redirect_request(true);
+ throttle1_->set_defer_on_will_process_response(true);
+
+ throttle2_->set_defer_on_will_start_request(true);
+ throttle2_->set_defer_on_will_redirect_request(true);
+ throttle2_->set_defer_on_will_process_response(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->status());
+
+ throttle2_->Resume();
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
+
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->status());
+
+ throttle2_->Resume();
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
+
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->status());
+
+ throttle2_->Resume();
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(1, test_handler_->on_response_started_called());
+ EXPECT_EQ(0, test_handler_->on_read_completed_called());
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
+
+ FinishRequestSuccessfully();
+}
+
+// For a given method (WillStartRequest, WillRedirectRequest,
+// WillProcessResponse), each of the two throttles can cancel asynchronously or
+// synchronously, and the second throttle can cancel synchronously or
+// asynchronously after the first throttle completes synchronously or
+// asynchronously, for a total of 6 combinations where one of the
+// ResourceThrottle cancels in each phase. However:
+// 1) Whenever the second throttle cancels asynchronously, it doesn't matter if
+// the first one completed synchronously or asynchronously, the state when it
+// cancels is the same.
+// 2) The second cancelling asynchronously is much like the first one
+// cancelling asynchronously, so isn't worth testing individually.
+// 3) Similarly, the second cancelling synchronously after the first one
+// completes synchronously doesn't really add anything to the first cancelling
+// synchronously. The case where the second cancels synchronously after the
+// first completes asynchronously is more interesting - the cancellation happens
+// in a Resume() call rather in the initial WillFoo call.
+// So that leaves 3 interesting test cases for each of the three points
+// throttles can cancel.
+
+TEST_F(ThrottlingResourceHandlerTest, FirstThrottleSyncCancelOnWillStart) {
+ throttle1_->set_cancel_on_will_start_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, FirstThrottleAsyncCancelOnWillStart) {
+ throttle1_->set_defer_on_will_start_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+// The first throttle also defers and then resumes the request, so that this
+// cancel happens with Resume() on the top of the callstack, instead of
+// OnWillStart(), unlike the test where the first throttle synchronously
+// cancels.
+TEST_F(ThrottlingResourceHandlerTest, SecondThrottleSyncCancelOnWillStart) {
+ throttle1_->set_defer_on_will_start_request(true);
+ throttle2_->set_cancel_on_will_start_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest,
+ FirstThrottleSyncCancelOnRequestRedirected) {
+ throttle1_->set_cancel_on_will_redirect_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest,
+ FirstThrottleAsyncCancelOnRequestRedirected) {
+ throttle1_->set_defer_on_will_redirect_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+// The first throttle also defers and then resumes the request, so that this
+// cancel happens with Resume() on the top of the callstack, instead of
+// OnRequestRedirected(), unlike the test where the first throttle synchronously
+// cancels.
+TEST_F(ThrottlingResourceHandlerTest,
+ SecondThrottleSyncCancelOnRequestRedirected) {
+ throttle1_->set_defer_on_will_redirect_request(true);
+ throttle2_->set_cancel_on_will_redirect_request(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest,
+ FirstThrottleSyncCancelOnWillProcessResponse) {
+ throttle1_->set_cancel_on_will_process_response(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest,
+ FirstThrottleAsyncCancelOnWillProcessResponse) {
+ throttle1_->set_defer_on_will_process_response(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+// The first throttle also defers and then resumes the request, so that this
+// cancel happens with Resume() on the top of the callstack, instead of
+// OnWillProcessResponse(), unlike the test where the first throttle
+// synchronously cancels.
+TEST_F(ThrottlingResourceHandlerTest,
+ SecondThrottleSyncCancelOnWillProcessResponse) {
+ throttle1_->set_defer_on_will_process_response(true);
+ throttle2_->set_cancel_on_will_process_response(true);
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+
+ throttle1_->Resume();
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+ EXPECT_EQ(1, throttle2_->will_process_response_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ ASSERT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, OutOfBandCancelBeforeWillStart) {
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(0, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, OutOfBandCancelAfterWillStart) {
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, OutOfBandCancelAfterRequestRedirected) {
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnRequestRedirected(
+ redirect_info, make_scoped_refptr(new ResourceResponse())));
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, OutOfBandCancelAfterResponseStarted) {
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+ net::RedirectInfo redirect_info;
+ redirect_info.status_code = 301;
+ redirect_info.new_url = GURL(kRedirectUrl);
+ EXPECT_EQ(
+ MockResourceLoader::Status::IDLE,
+ mock_loader_->OnRequestRedirected(redirect_info, new ResourceResponse()));
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseStarted(
+ make_scoped_refptr(new ResourceResponse())));
+
+ throttle1_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(1, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(1, throttle2_->will_start_request_called());
+ EXPECT_EQ(1, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(1, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(1, test_handler_->on_will_start_called());
+ EXPECT_EQ(1, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(1, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, OutOfBandCancelAndResumeDuringWillStart) {
+ throttle1_->set_defer_on_will_start_request(1);
+ EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ // |throttle2_| cancels.
+ throttle2_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // |throttle1_|, blissfully unaware of cancellation, resumes the request.
+ throttle1_->Resume();
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+TEST_F(ThrottlingResourceHandlerTest, DoubleCancelDuringWillStart) {
+ throttle1_->set_defer_on_will_start_request(1);
+ EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader_->OnWillStart(GURL(kInitialUrl)));
+
+ // |throttle2_| cancels.
+ throttle2_->CancelWithError(net::ERR_UNEXPECTED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // |throttle1_|, unaware of the cancellation, also cancels.
+ throttle1_->CancelWithError(net::ERR_FAILED);
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
+ EXPECT_EQ(net::ERR_UNEXPECTED, mock_loader_->error_code());
+
+ // The MockResourceLoader now informs the ResourceHandler of cancellation.
+ EXPECT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(
+ net::URLRequestStatus::FromError(net::ERR_UNEXPECTED)));
+
+ EXPECT_EQ(1, throttle1_->will_start_request_called());
+ EXPECT_EQ(0, throttle1_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle1_->will_process_response_called());
+
+ EXPECT_EQ(0, throttle2_->will_start_request_called());
+ EXPECT_EQ(0, throttle2_->will_redirect_request_called());
+ EXPECT_EQ(0, throttle2_->will_process_response_called());
+
+ EXPECT_EQ(0, test_handler_->on_will_start_called());
+ EXPECT_EQ(0, test_handler_->on_request_redirected_called());
+ EXPECT_EQ(0, test_handler_->on_response_started_called());
+ EXPECT_EQ(1, test_handler_->on_response_completed_called());
+}
+
+} // namespace
+} // namespace content
« no previous file with comments | « content/browser/loader/throttling_resource_handler.cc ('k') | content/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698