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 |