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

Unified Diff: google_apis/drive/files_list_request_runner_unittest.cc

Issue 1218773003: Implement a DRIVE_REQUEST_TOO_LARGE backoff. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. Created 5 years, 6 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
Index: google_apis/drive/files_list_request_runner_unittest.cc
diff --git a/google_apis/drive/files_list_request_runner_unittest.cc b/google_apis/drive/files_list_request_runner_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..94d731210aa7d3160fbd32b0acb667277cae7fbf
--- /dev/null
+++ b/google_apis/drive/files_list_request_runner_unittest.cc
@@ -0,0 +1,273 @@
+// Copyright 2015 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 "google_apis/drive/files_list_request_runner.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/sequenced_task_runner.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/thread_task_runner_handle.h"
+#include "google_apis/drive/base_requests.h"
+#include "google_apis/drive/dummy_auth_service.h"
+#include "google_apis/drive/request_sender.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace google_apis {
+namespace {
+
+const int kMaxResults = 4;
+const char kQuery[] = "testing-query";
+const char kFields[] = "testing-fields";
+const char kTestUserAgent[] = "test-user-agent";
+
+const char kSuccessResource[] =
+ "{\n"
+ " \"kind\": \"drive#fileList\",\n"
+ " \"etag\": \"etag\",\n"
+ " \"items\": []\n"
+ "}\n";
+
+const char kResponseTooLargeErrorResource[] =
+ "{\n"
+ " \"error\": {\n"
+ " \"errors\": [\n"
+ " {\n"
+ " \"reason\": \"responseTooLarge\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ "}\n";
+
+const char kQuotaExceededErrorResource[] =
+ "{\n"
+ " \"error\": {\n"
+ " \"errors\": [\n"
+ " {\n"
+ " \"reason\": \"quotaExceeded\"\n"
+ " }\n"
+ " ]\n"
+ " }\n"
+ "}\n";
+
+} // namespace
+
+class FilesListRequestRunnerTest : public testing::Test {
+ public:
+ FilesListRequestRunnerTest() {}
+
+ void SetUp() override {
+ request_context_getter_ =
+ new net::TestURLRequestContextGetter(message_loop_.task_runner());
+
+ request_sender_.reset(
+ new RequestSender(new DummyAuthService, request_context_getter_.get(),
+ message_loop_.task_runner(), kTestUserAgent));
+
+ test_server_.RegisterRequestHandler(
+ base::Bind(&FilesListRequestRunnerTest::OnFilesListRequest,
+ base::Unretained(this), test_server_.base_url()));
+ ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady());
+
+ runner_.reset(new FilesListRequestRunner(
+ request_sender_.get(),
+ google_apis::DriveApiUrlGenerator(test_server_.base_url(),
+ test_server_.GetURL("/download/"))));
+ }
+
+ void TearDown() override {
+ on_completed_callback_ = base::Closure();
+ http_request_.reset();
+ response_error_.reset();
+ response_entry_.reset();
+ }
+
+ // Called when the request is completed and no more backoff retries will
+ // happen.
+ void OnCompleted(DriveApiErrorCode error, scoped_ptr<FileList> entry) {
+ response_error_.reset(new DriveApiErrorCode(error));
+ response_entry_ = entry.Pass();
+ on_completed_callback_.Run();
+ }
+
+ protected:
+ // Sets a fake Drive API server response to be returned for the upcoming HTTP
+ // request.
+ void SetFakeServerResponse(net::HttpStatusCode code,
+ const std::string& content) {
+ fake_server_response_.reset(new net::test_server::BasicHttpResponse);
+ fake_server_response_->set_code(code);
+ fake_server_response_->set_content(content);
+ fake_server_response_->set_content_type("application/json");
+ }
+
+ // Handles a HTTP request to the Drive API server and returns a fake response.
+ scoped_ptr<net::test_server::HttpResponse> OnFilesListRequest(
+ const GURL& base_url,
+ const net::test_server::HttpRequest& request) {
+ http_request_.reset(new net::test_server::HttpRequest(request));
+ return fake_server_response_.Pass();
+ }
+
+ base::MessageLoopForIO message_loop_; // Test server needs IO thread.
+ scoped_ptr<RequestSender> request_sender_;
+ net::test_server::EmbeddedTestServer test_server_;
+ scoped_ptr<FilesListRequestRunner> runner_;
+ scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
+ base::Closure on_completed_callback_;
+
+ // Response set by test cases to be returned from the HTTP server.
+ scoped_ptr<net::test_server::BasicHttpResponse> fake_server_response_;
+
+ // A requests and a response stored for verification in test cases.
+ scoped_ptr<net::test_server::HttpRequest> http_request_;
+ scoped_ptr<DriveApiErrorCode> response_error_;
+ scoped_ptr<FileList> response_entry_;
+};
+
+TEST_F(FilesListRequestRunnerTest, Success_NoBackoff) {
+ SetFakeServerResponse(net::HTTP_OK, kSuccessResource);
+ runner_->CreateAndStartWithSizeBackoff(
+ kMaxResults, kQuery, kFields,
+ base::Bind(&FilesListRequestRunnerTest::OnCompleted,
+ base::Unretained(this)));
+
+ base::RunLoop run_loop;
+ on_completed_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+
+ ASSERT_TRUE(response_error_.get());
+ EXPECT_EQ(HTTP_SUCCESS, *response_error_);
+ EXPECT_TRUE(response_entry_.get());
+}
+
+TEST_F(FilesListRequestRunnerTest, Success_Backoff) {
+ SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ kResponseTooLargeErrorResource);
+ runner_->CreateAndStartWithSizeBackoff(
+ kMaxResults, kQuery, kFields,
+ base::Bind(&FilesListRequestRunnerTest::OnCompleted,
+ base::Unretained(this)));
+ {
+ base::RunLoop run_loop;
+ runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure());
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+ EXPECT_FALSE(response_error_.get());
+ }
+
+ // Backoff will decreasing the number of results by 2, which will succeed.
+ {
+ SetFakeServerResponse(net::HTTP_OK, kSuccessResource);
+
+ base::RunLoop run_loop;
+ on_completed_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+
+ ASSERT_TRUE(response_error_.get());
+ EXPECT_EQ(HTTP_SUCCESS, *response_error_);
+ EXPECT_TRUE(response_entry_.get());
+ }
+}
+
+TEST_F(FilesListRequestRunnerTest, Failure_TooManyBackoffs) {
+ SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ kResponseTooLargeErrorResource);
+ runner_->CreateAndStartWithSizeBackoff(
+ kMaxResults, kQuery, kFields,
+ base::Bind(&FilesListRequestRunnerTest::OnCompleted,
+ base::Unretained(this)));
+ {
+ base::RunLoop run_loop;
+ runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure());
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+ EXPECT_FALSE(response_error_.get());
+ }
+
+ // Backoff will decreasing the number of results by 2, which will still fail
+ // due to too large response.
+ {
+ SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ kResponseTooLargeErrorResource);
+
+ base::RunLoop run_loop;
+ runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure());
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+ EXPECT_FALSE(response_error_.get());
+ }
+
+ // The last backoff, decreasing the number of results to 1.
+ {
+ SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ kResponseTooLargeErrorResource);
+
+ base::RunLoop run_loop;
+ on_completed_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=1&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+
+ ASSERT_TRUE(response_error_.get());
+ EXPECT_EQ(DRIVE_RESPONSE_TOO_LARGE, *response_error_);
+ EXPECT_FALSE(response_entry_.get());
+ }
+}
+
+TEST_F(FilesListRequestRunnerTest, Failure_AnotherError) {
+ SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ kQuotaExceededErrorResource);
+ runner_->CreateAndStartWithSizeBackoff(
+ kMaxResults, kQuery, kFields,
+ base::Bind(&FilesListRequestRunnerTest::OnCompleted,
+ base::Unretained(this)));
+
+ base::RunLoop run_loop;
+ on_completed_callback_ = run_loop.QuitClosure();
+ run_loop.Run();
+
+ ASSERT_TRUE(http_request_.get());
+ EXPECT_EQ(
+ "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
+ http_request_->relative_url);
+
+ // There must be no backoff in case of an error different than
+ // DRIVE_RESPONSE_TOO_LARGE.
+ ASSERT_TRUE(response_error_.get());
+ EXPECT_EQ(DRIVE_NO_SPACE, *response_error_);
+ EXPECT_FALSE(response_entry_.get());
+}
+
+} // namespace google_apis

Powered by Google App Engine
This is Rietveld 408576698