OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 "google_apis/drive/files_list_request_runner.h" |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/run_loop.h" |
| 10 #include "base/sequenced_task_runner.h" |
| 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "google_apis/drive/base_requests.h" |
| 14 #include "google_apis/drive/dummy_auth_service.h" |
| 15 #include "google_apis/drive/request_sender.h" |
| 16 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 17 #include "net/test/embedded_test_server/http_request.h" |
| 18 #include "net/test/embedded_test_server/http_response.h" |
| 19 #include "net/url_request/url_request_test_util.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 |
| 22 namespace google_apis { |
| 23 namespace { |
| 24 |
| 25 const int kMaxResults = 4; |
| 26 const char kQuery[] = "testing-query"; |
| 27 const char kFields[] = "testing-fields"; |
| 28 const char kTestUserAgent[] = "test-user-agent"; |
| 29 |
| 30 const char kSuccessResource[] = |
| 31 "{\n" |
| 32 " \"kind\": \"drive#fileList\",\n" |
| 33 " \"etag\": \"etag\",\n" |
| 34 " \"items\": []\n" |
| 35 "}\n"; |
| 36 |
| 37 const char kResponseTooLargeErrorResource[] = |
| 38 "{\n" |
| 39 " \"error\": {\n" |
| 40 " \"errors\": [\n" |
| 41 " {\n" |
| 42 " \"reason\": \"responseTooLarge\"\n" |
| 43 " }\n" |
| 44 " ]\n" |
| 45 " }\n" |
| 46 "}\n"; |
| 47 |
| 48 const char kQuotaExceededErrorResource[] = |
| 49 "{\n" |
| 50 " \"error\": {\n" |
| 51 " \"errors\": [\n" |
| 52 " {\n" |
| 53 " \"reason\": \"quotaExceeded\"\n" |
| 54 " }\n" |
| 55 " ]\n" |
| 56 " }\n" |
| 57 "}\n"; |
| 58 |
| 59 } // namespace |
| 60 |
| 61 class FilesListRequestRunnerTest : public testing::Test { |
| 62 public: |
| 63 FilesListRequestRunnerTest() {} |
| 64 |
| 65 void SetUp() override { |
| 66 request_context_getter_ = |
| 67 new net::TestURLRequestContextGetter(message_loop_.task_runner()); |
| 68 |
| 69 request_sender_.reset( |
| 70 new RequestSender(new DummyAuthService, request_context_getter_.get(), |
| 71 message_loop_.task_runner(), kTestUserAgent)); |
| 72 |
| 73 test_server_.RegisterRequestHandler( |
| 74 base::Bind(&FilesListRequestRunnerTest::OnFilesListRequest, |
| 75 base::Unretained(this), test_server_.base_url())); |
| 76 ASSERT_TRUE(test_server_.InitializeAndWaitUntilReady()); |
| 77 |
| 78 runner_.reset(new FilesListRequestRunner( |
| 79 request_sender_.get(), |
| 80 google_apis::DriveApiUrlGenerator(test_server_.base_url(), |
| 81 test_server_.GetURL("/download/")))); |
| 82 } |
| 83 |
| 84 void TearDown() override { |
| 85 on_completed_callback_ = base::Closure(); |
| 86 http_request_.reset(); |
| 87 response_error_.reset(); |
| 88 response_entry_.reset(); |
| 89 } |
| 90 |
| 91 // Called when the request is completed and no more backoff retries will |
| 92 // happen. |
| 93 void OnCompleted(DriveApiErrorCode error, scoped_ptr<FileList> entry) { |
| 94 response_error_.reset(new DriveApiErrorCode(error)); |
| 95 response_entry_ = entry.Pass(); |
| 96 on_completed_callback_.Run(); |
| 97 } |
| 98 |
| 99 protected: |
| 100 // Sets a fake Drive API server response to be returned for the upcoming HTTP |
| 101 // request. |
| 102 void SetFakeServerResponse(net::HttpStatusCode code, |
| 103 const std::string& content) { |
| 104 fake_server_response_.reset(new net::test_server::BasicHttpResponse); |
| 105 fake_server_response_->set_code(code); |
| 106 fake_server_response_->set_content(content); |
| 107 fake_server_response_->set_content_type("application/json"); |
| 108 } |
| 109 |
| 110 // Handles a HTTP request to the Drive API server and returns a fake response. |
| 111 scoped_ptr<net::test_server::HttpResponse> OnFilesListRequest( |
| 112 const GURL& base_url, |
| 113 const net::test_server::HttpRequest& request) { |
| 114 http_request_.reset(new net::test_server::HttpRequest(request)); |
| 115 return fake_server_response_.Pass(); |
| 116 } |
| 117 |
| 118 base::MessageLoopForIO message_loop_; // Test server needs IO thread. |
| 119 scoped_ptr<RequestSender> request_sender_; |
| 120 net::test_server::EmbeddedTestServer test_server_; |
| 121 scoped_ptr<FilesListRequestRunner> runner_; |
| 122 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; |
| 123 base::Closure on_completed_callback_; |
| 124 |
| 125 // Response set by test cases to be returned from the HTTP server. |
| 126 scoped_ptr<net::test_server::BasicHttpResponse> fake_server_response_; |
| 127 |
| 128 // A requests and a response stored for verification in test cases. |
| 129 scoped_ptr<net::test_server::HttpRequest> http_request_; |
| 130 scoped_ptr<DriveApiErrorCode> response_error_; |
| 131 scoped_ptr<FileList> response_entry_; |
| 132 }; |
| 133 |
| 134 TEST_F(FilesListRequestRunnerTest, Success_NoBackoff) { |
| 135 SetFakeServerResponse(net::HTTP_OK, kSuccessResource); |
| 136 runner_->CreateAndStartWithSizeBackoff( |
| 137 kMaxResults, kQuery, kFields, |
| 138 base::Bind(&FilesListRequestRunnerTest::OnCompleted, |
| 139 base::Unretained(this))); |
| 140 |
| 141 base::RunLoop run_loop; |
| 142 on_completed_callback_ = run_loop.QuitClosure(); |
| 143 run_loop.Run(); |
| 144 |
| 145 ASSERT_TRUE(http_request_.get()); |
| 146 EXPECT_EQ( |
| 147 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields", |
| 148 http_request_->relative_url); |
| 149 |
| 150 ASSERT_TRUE(response_error_.get()); |
| 151 EXPECT_EQ(HTTP_SUCCESS, *response_error_); |
| 152 EXPECT_TRUE(response_entry_.get()); |
| 153 } |
| 154 |
| 155 TEST_F(FilesListRequestRunnerTest, Success_Backoff) { |
| 156 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR, |
| 157 kResponseTooLargeErrorResource); |
| 158 runner_->CreateAndStartWithSizeBackoff( |
| 159 kMaxResults, kQuery, kFields, |
| 160 base::Bind(&FilesListRequestRunnerTest::OnCompleted, |
| 161 base::Unretained(this))); |
| 162 { |
| 163 base::RunLoop run_loop; |
| 164 runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure()); |
| 165 run_loop.Run(); |
| 166 |
| 167 ASSERT_TRUE(http_request_.get()); |
| 168 EXPECT_EQ( |
| 169 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields", |
| 170 http_request_->relative_url); |
| 171 EXPECT_FALSE(response_error_.get()); |
| 172 } |
| 173 |
| 174 // Backoff will decreasing the number of results by 2, which will succeed. |
| 175 { |
| 176 SetFakeServerResponse(net::HTTP_OK, kSuccessResource); |
| 177 |
| 178 base::RunLoop run_loop; |
| 179 on_completed_callback_ = run_loop.QuitClosure(); |
| 180 run_loop.Run(); |
| 181 |
| 182 ASSERT_TRUE(http_request_.get()); |
| 183 EXPECT_EQ( |
| 184 "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields", |
| 185 http_request_->relative_url); |
| 186 |
| 187 ASSERT_TRUE(response_error_.get()); |
| 188 EXPECT_EQ(HTTP_SUCCESS, *response_error_); |
| 189 EXPECT_TRUE(response_entry_.get()); |
| 190 } |
| 191 } |
| 192 |
| 193 TEST_F(FilesListRequestRunnerTest, Failure_TooManyBackoffs) { |
| 194 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR, |
| 195 kResponseTooLargeErrorResource); |
| 196 runner_->CreateAndStartWithSizeBackoff( |
| 197 kMaxResults, kQuery, kFields, |
| 198 base::Bind(&FilesListRequestRunnerTest::OnCompleted, |
| 199 base::Unretained(this))); |
| 200 { |
| 201 base::RunLoop run_loop; |
| 202 runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure()); |
| 203 run_loop.Run(); |
| 204 |
| 205 ASSERT_TRUE(http_request_.get()); |
| 206 EXPECT_EQ( |
| 207 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields", |
| 208 http_request_->relative_url); |
| 209 EXPECT_FALSE(response_error_.get()); |
| 210 } |
| 211 |
| 212 // Backoff will decreasing the number of results by 2, which will still fail |
| 213 // due to too large response. |
| 214 { |
| 215 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR, |
| 216 kResponseTooLargeErrorResource); |
| 217 |
| 218 base::RunLoop run_loop; |
| 219 runner_->SetRequestCompletedCallbackForTesting(run_loop.QuitClosure()); |
| 220 run_loop.Run(); |
| 221 |
| 222 ASSERT_TRUE(http_request_.get()); |
| 223 EXPECT_EQ( |
| 224 "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields", |
| 225 http_request_->relative_url); |
| 226 EXPECT_FALSE(response_error_.get()); |
| 227 } |
| 228 |
| 229 // The last backoff, decreasing the number of results to 1. |
| 230 { |
| 231 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR, |
| 232 kResponseTooLargeErrorResource); |
| 233 |
| 234 base::RunLoop run_loop; |
| 235 on_completed_callback_ = run_loop.QuitClosure(); |
| 236 run_loop.Run(); |
| 237 |
| 238 ASSERT_TRUE(http_request_.get()); |
| 239 EXPECT_EQ( |
| 240 "/drive/v2/files?maxResults=1&q=testing-query&fields=testing-fields", |
| 241 http_request_->relative_url); |
| 242 |
| 243 ASSERT_TRUE(response_error_.get()); |
| 244 EXPECT_EQ(DRIVE_RESPONSE_TOO_LARGE, *response_error_); |
| 245 EXPECT_FALSE(response_entry_.get()); |
| 246 } |
| 247 } |
| 248 |
| 249 TEST_F(FilesListRequestRunnerTest, Failure_AnotherError) { |
| 250 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR, |
| 251 kQuotaExceededErrorResource); |
| 252 runner_->CreateAndStartWithSizeBackoff( |
| 253 kMaxResults, kQuery, kFields, |
| 254 base::Bind(&FilesListRequestRunnerTest::OnCompleted, |
| 255 base::Unretained(this))); |
| 256 |
| 257 base::RunLoop run_loop; |
| 258 on_completed_callback_ = run_loop.QuitClosure(); |
| 259 run_loop.Run(); |
| 260 |
| 261 ASSERT_TRUE(http_request_.get()); |
| 262 EXPECT_EQ( |
| 263 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields", |
| 264 http_request_->relative_url); |
| 265 |
| 266 // There must be no backoff in case of an error different than |
| 267 // DRIVE_RESPONSE_TOO_LARGE. |
| 268 ASSERT_TRUE(response_error_.get()); |
| 269 EXPECT_EQ(DRIVE_NO_SPACE, *response_error_); |
| 270 EXPECT_FALSE(response_entry_.get()); |
| 271 } |
| 272 |
| 273 } // namespace google_apis |
OLD | NEW |