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.
5 #include "google_apis/drive/files_list_request_runner.h"
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"
22 namespace google_apis
{
25 const int kMaxResults
= 4;
26 const char kQuery
[] = "testing-query";
27 const char kFields
[] = "testing-fields";
28 const char kTestUserAgent
[] = "test-user-agent";
30 const char kSuccessResource
[] =
32 " \"kind\": \"drive#fileList\",\n"
33 " \"etag\": \"etag\",\n"
37 const char kResponseTooLargeErrorResource
[] =
42 " \"reason\": \"responseTooLarge\"\n"
48 const char kQuotaExceededErrorResource
[] =
53 " \"reason\": \"quotaExceeded\"\n"
61 class FilesListRequestRunnerTest
: public testing::Test
{
63 FilesListRequestRunnerTest() {}
65 void SetUp() override
{
66 request_context_getter_
=
67 new net::TestURLRequestContextGetter(message_loop_
.task_runner());
69 request_sender_
.reset(
70 new RequestSender(new DummyAuthService
, request_context_getter_
.get(),
71 message_loop_
.task_runner(), kTestUserAgent
));
73 test_server_
.RegisterRequestHandler(
74 base::Bind(&FilesListRequestRunnerTest::OnFilesListRequest
,
75 base::Unretained(this), test_server_
.base_url()));
76 ASSERT_TRUE(test_server_
.InitializeAndWaitUntilReady());
78 runner_
.reset(new FilesListRequestRunner(
79 request_sender_
.get(),
80 google_apis::DriveApiUrlGenerator(test_server_
.base_url(),
81 test_server_
.GetURL("/download/"))));
84 void TearDown() override
{
85 on_completed_callback_
= base::Closure();
86 http_request_
.reset();
87 response_error_
.reset();
88 response_entry_
.reset();
91 // Called when the request is completed and no more backoff retries will
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();
100 // Sets a fake Drive API server response to be returned for the upcoming HTTP
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");
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();
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_
;
125 // Response set by test cases to be returned from the HTTP server.
126 scoped_ptr
<net::test_server::BasicHttpResponse
> fake_server_response_
;
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_
;
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)));
141 base::RunLoop run_loop
;
142 on_completed_callback_
= run_loop
.QuitClosure();
145 ASSERT_TRUE(http_request_
.get());
147 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
148 http_request_
->relative_url
);
150 ASSERT_TRUE(response_error_
.get());
151 EXPECT_EQ(HTTP_SUCCESS
, *response_error_
);
152 EXPECT_TRUE(response_entry_
.get());
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)));
163 base::RunLoop run_loop
;
164 runner_
->SetRequestCompletedCallbackForTesting(run_loop
.QuitClosure());
167 ASSERT_TRUE(http_request_
.get());
169 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
170 http_request_
->relative_url
);
171 EXPECT_FALSE(response_error_
.get());
174 // Backoff will decreasing the number of results by 2, which will succeed.
176 SetFakeServerResponse(net::HTTP_OK
, kSuccessResource
);
178 base::RunLoop run_loop
;
179 on_completed_callback_
= run_loop
.QuitClosure();
182 ASSERT_TRUE(http_request_
.get());
184 "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields",
185 http_request_
->relative_url
);
187 ASSERT_TRUE(response_error_
.get());
188 EXPECT_EQ(HTTP_SUCCESS
, *response_error_
);
189 EXPECT_TRUE(response_entry_
.get());
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)));
201 base::RunLoop run_loop
;
202 runner_
->SetRequestCompletedCallbackForTesting(run_loop
.QuitClosure());
205 ASSERT_TRUE(http_request_
.get());
207 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
208 http_request_
->relative_url
);
209 EXPECT_FALSE(response_error_
.get());
212 // Backoff will decreasing the number of results by 2, which will still fail
213 // due to too large response.
215 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR
,
216 kResponseTooLargeErrorResource
);
218 base::RunLoop run_loop
;
219 runner_
->SetRequestCompletedCallbackForTesting(run_loop
.QuitClosure());
222 ASSERT_TRUE(http_request_
.get());
224 "/drive/v2/files?maxResults=2&q=testing-query&fields=testing-fields",
225 http_request_
->relative_url
);
226 EXPECT_FALSE(response_error_
.get());
229 // The last backoff, decreasing the number of results to 1.
231 SetFakeServerResponse(net::HTTP_INTERNAL_SERVER_ERROR
,
232 kResponseTooLargeErrorResource
);
234 base::RunLoop run_loop
;
235 on_completed_callback_
= run_loop
.QuitClosure();
238 ASSERT_TRUE(http_request_
.get());
240 "/drive/v2/files?maxResults=1&q=testing-query&fields=testing-fields",
241 http_request_
->relative_url
);
243 ASSERT_TRUE(response_error_
.get());
244 EXPECT_EQ(DRIVE_RESPONSE_TOO_LARGE
, *response_error_
);
245 EXPECT_FALSE(response_entry_
.get());
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)));
257 base::RunLoop run_loop
;
258 on_completed_callback_
= run_loop
.QuitClosure();
261 ASSERT_TRUE(http_request_
.get());
263 "/drive/v2/files?maxResults=4&q=testing-query&fields=testing-fields",
264 http_request_
->relative_url
);
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());
273 } // namespace google_apis