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

Side by Side Diff: chrome/browser/google_apis/drive_uploader_unittest.cc

Issue 12209035: Implement retry flow on DriveUploader. (Closed) Base URL: http://git.chromium.org/chromium/src.git@b148632_wapi_get_upload_status_operation_impl
Patch Set: Created 7 years, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/google_apis/drive_uploader.h" 5 #include "chrome/browser/google_apis/drive_uploader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstdlib> 8 #include <cstdlib>
9 #include <string> 9 #include <string>
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // Mock DriveService that verifies if the uploaded content matches the preset 51 // Mock DriveService that verifies if the uploaded content matches the preset
52 // expectation. 52 // expectation.
53 class MockDriveServiceWithUploadExpectation : public DummyDriveService { 53 class MockDriveServiceWithUploadExpectation : public DummyDriveService {
54 public: 54 public:
55 // Sets up an expected upload content. InitiateUpload and ResumeUpload will 55 // Sets up an expected upload content. InitiateUpload and ResumeUpload will
56 // verify that the specified data is correctly uploaded. 56 // verify that the specified data is correctly uploaded.
57 explicit MockDriveServiceWithUploadExpectation( 57 explicit MockDriveServiceWithUploadExpectation(
58 const std::string& expected_upload_content) 58 const std::string& expected_upload_content)
59 : expected_upload_content_(expected_upload_content), 59 : expected_upload_content_(expected_upload_content),
60 received_bytes_(0), 60 received_bytes_(0),
61 resume_upload_call_count_(0) {} 61 resume_upload_call_count_(0),
62 get_upload_status_call_count_(0),
63 resume_upload_failure_point_(-1) {}
62 64
63 int64 received_bytes() const { return received_bytes_; } 65 int64 received_bytes() const { return received_bytes_; }
64 66
65 int64 resume_upload_call_count() const { return resume_upload_call_count_; } 67 int64 resume_upload_call_count() const { return resume_upload_call_count_; }
66 68
69 int64 get_upload_status_call_count() const {
70 return get_upload_status_call_count_;
71 }
72
73 void set_resume_upload_failure_point(int64 resume_upload_failure_point) {
74 resume_upload_failure_point_ = resume_upload_failure_point;
75 }
76
67 private: 77 private:
68 // DriveServiceInterface overrides. 78 // DriveServiceInterface overrides.
69 // Handles a request for obtaining an upload location URL. 79 // Handles a request for obtaining an upload location URL.
70 virtual void InitiateUpload(const InitiateUploadParams& params, 80 virtual void InitiateUpload(const InitiateUploadParams& params,
71 const InitiateUploadCallback& callback) OVERRIDE { 81 const InitiateUploadCallback& callback) OVERRIDE {
72 const int64 expected_size = expected_upload_content_.size(); 82 const int64 expected_size = expected_upload_content_.size();
73 83
74 // Verify that the expected parameters are passed. 84 // Verify that the expected parameters are passed.
75 if (params.upload_mode == UPLOAD_NEW_FILE) 85 if (params.upload_mode == UPLOAD_NEW_FILE)
76 EXPECT_EQ(kTestDocumentTitle, params.title); 86 EXPECT_EQ(kTestDocumentTitle, params.title);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 125
116 // The upload URL returned by InitiateUpload() must be used. 126 // The upload URL returned by InitiateUpload() must be used.
117 EXPECT_EQ(GURL(kTestUploadURL), params.upload_location); 127 EXPECT_EQ(GURL(kTestUploadURL), params.upload_location);
118 128
119 // Other parameters should be the exact values passed to DriveUploader. 129 // Other parameters should be the exact values passed to DriveUploader.
120 EXPECT_EQ(expected_size, params.content_length); 130 EXPECT_EQ(expected_size, params.content_length);
121 EXPECT_EQ(kTestMimeType, params.content_type); 131 EXPECT_EQ(kTestMimeType, params.content_type);
122 132
123 // Update the internal status of the current upload session. 133 // Update the internal status of the current upload session.
124 resume_upload_call_count_++; 134 resume_upload_call_count_++;
135 if (resume_upload_call_count_ == resume_upload_failure_point_) {
136 // Emulate the server error.
137 // ResumeUpload is an asynchronous function, so don't callback directly.
138 scoped_ptr<ResourceEntry> entry;
139 MessageLoop::current()->PostTask(
140 FROM_HERE,
141 base::Bind(callback,
142 UploadRangeResponse(HTTP_SERVICE_UNAVAILABLE, 0, 0),
143 base::Passed(&entry)));
144 return;
145 }
125 received_bytes_ = params.end_position; 146 received_bytes_ = params.end_position;
126 147
127 // Callback with response. 148 // Callback with response.
128 UploadRangeResponse response; 149 UploadRangeResponse response;
129 scoped_ptr<ResourceEntry> entry; 150 scoped_ptr<ResourceEntry> entry;
130 if (received_bytes_ == params.content_length) { 151 if (received_bytes_ == params.content_length) {
131 response = UploadRangeResponse( 152 response = UploadRangeResponse(
132 params.upload_mode == UPLOAD_NEW_FILE ? HTTP_CREATED : HTTP_SUCCESS, 153 params.upload_mode == UPLOAD_NEW_FILE ? HTTP_CREATED : HTTP_SUCCESS,
133 -1, -1); 154 -1, -1);
134 155
135 base::DictionaryValue dict; 156 base::DictionaryValue dict;
136 dict.Set("id.$t", new base::StringValue(kTestDummyId)); 157 dict.Set("id.$t", new base::StringValue(kTestDummyId));
137 entry = ResourceEntry::CreateFrom(dict); 158 entry = ResourceEntry::CreateFrom(dict);
138 } else { 159 } else {
139 response = UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 0, 160 response = UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 0,
140 params.end_position); 161 params.end_position);
141 } 162 }
142 // ResumeUpload is an asynchronous function, so don't callback directly. 163 // ResumeUpload is an asynchronous function, so don't callback directly.
143 MessageLoop::current()->PostTask(FROM_HERE, 164 MessageLoop::current()->PostTask(FROM_HERE,
144 base::Bind(callback, response, base::Passed(&entry))); 165 base::Bind(callback, response, base::Passed(&entry)));
145 } 166 }
146 167
168 // Handles a request for uploading a chunk of bytes.
169 virtual void GetUploadStatus(
170 UploadMode upload_mode,
171 const FilePath& drive_file_path,
172 const GURL& upload_url,
173 int64 content_length,
174 const UploadRangeCallback& callback) OVERRIDE {
175 EXPECT_EQ(GURL(kTestUploadURL), upload_url);
176 const int64 expected_upload_content_size = expected_upload_content_.size();
177 EXPECT_EQ(expected_upload_content_size, content_length);
178
179 // Update the internal status of the current upload session.
180 get_upload_status_call_count_++;
181
182 // Callback with response.
183 UploadRangeResponse response;
184 scoped_ptr<ResourceEntry> entry;
185 if (received_bytes_ == content_length) {
186 response = UploadRangeResponse(
187 upload_mode == UPLOAD_NEW_FILE ? HTTP_CREATED : HTTP_SUCCESS,
188 -1, -1);
189
190 base::DictionaryValue dict;
191 dict.Set("id.$t", new base::StringValue(kTestDummyId));
192 entry = ResourceEntry::CreateFrom(dict);
193 } else {
194 response =
195 UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 0, received_bytes_);
196 }
197 // GetUploadStatus is an asynchronous function, so don't callback directly.
198 MessageLoop::current()->PostTask(FROM_HERE,
199 base::Bind(callback, response, base::Passed(&entry)));
200 }
201
147 std::string expected_upload_content_; 202 std::string expected_upload_content_;
148 int64 received_bytes_; 203 int64 received_bytes_;
149 int64 resume_upload_call_count_; 204 int64 resume_upload_call_count_;
205 int64 get_upload_status_call_count_;
206
207 // When the resume_upload_call_count is equal to this value,
208 // this mock server will return 503 SERVICE_UNAVAILABLE to test the
209 // failure case. To disable this function, set the value to -1 so that
210 // the resume_upload_call_count_ won't be equal to this in real use cases.
211 int64 resume_upload_failure_point_;
150 }; 212 };
151 213
152 // Mock DriveService that returns a failure at InitiateUpload(). 214 // Mock DriveService that returns a failure at InitiateUpload().
153 class MockDriveServiceNoConnectionAtInitiate : public DummyDriveService { 215 class MockDriveServiceNoConnectionAtInitiate : public DummyDriveService {
154 // Returns error. 216 // Returns error.
155 virtual void InitiateUpload(const InitiateUploadParams& params, 217 virtual void InitiateUpload(const InitiateUploadParams& params,
156 const InitiateUploadCallback& callback) OVERRIDE { 218 const InitiateUploadCallback& callback) OVERRIDE {
157 MessageLoop::current()->PostTask(FROM_HERE, 219 MessageLoop::current()->PostTask(FROM_HERE,
158 base::Bind(callback, GDATA_NO_CONNECTION, GURL())); 220 base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
159 } 221 }
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 // The file should be split into 3 chunks (1234 = 512 + 512 + 210). 399 // The file should be split into 3 chunks (1234 = 512 + 512 + 210).
338 EXPECT_EQ(3, mock_service.resume_upload_call_count()); 400 EXPECT_EQ(3, mock_service.resume_upload_call_count());
339 EXPECT_EQ(1234 * 1024, mock_service.received_bytes()); 401 EXPECT_EQ(1234 * 1024, mock_service.received_bytes());
340 EXPECT_EQ(DRIVE_UPLOAD_OK, out.error); 402 EXPECT_EQ(DRIVE_UPLOAD_OK, out.error);
341 EXPECT_EQ(FilePath::FromUTF8Unsafe(kTestDrivePath), out.drive_path); 403 EXPECT_EQ(FilePath::FromUTF8Unsafe(kTestDrivePath), out.drive_path);
342 EXPECT_EQ(local_path, out.file_path); 404 EXPECT_EQ(local_path, out.file_path);
343 ASSERT_TRUE(out.resource_entry); 405 ASSERT_TRUE(out.resource_entry);
344 EXPECT_EQ(kTestDummyId, out.resource_entry->id()); 406 EXPECT_EQ(kTestDummyId, out.resource_entry->id());
345 } 407 }
346 408
409 TEST_F(DriveUploaderTest, UploadNew1234KBWithRetry) {
410 FilePath local_path;
411 std::string data;
412 ASSERT_TRUE(CreateFileOfSpecifiedSize(temp_dir_.path(), 1234 * 1024,
413 &local_path, &data));
414 UploadCompletionCallbackResult out;
415
416 MockDriveServiceWithUploadExpectation mock_service(data);
417 // Emulate the server failure when ResumeUpload is invoked twice.
418 mock_service.set_resume_upload_failure_point(2);
419 DriveUploader uploader(&mock_service);
420 uploader.UploadNewFile(
421 GURL(kTestInitialUploadURL),
422 FilePath::FromUTF8Unsafe(kTestDrivePath),
423 local_path,
424 kTestDocumentTitle,
425 kTestMimeType,
426 base::Bind(&CopyResultsFromUploadCompletionCallbackAndQuit, &out));
427 message_loop_.Run();
428
429 // The file should be split into 3 chunks (1234 = 512 + 512 + 210) + 1 retry.
430 EXPECT_EQ(4, mock_service.resume_upload_call_count());
431 EXPECT_EQ(1, mock_service.get_upload_status_call_count());
432 EXPECT_EQ(1234 * 1024, mock_service.received_bytes());
433 EXPECT_EQ(DRIVE_UPLOAD_OK, out.error);
434 EXPECT_EQ(FilePath::FromUTF8Unsafe(kTestDrivePath), out.drive_path);
435 EXPECT_EQ(local_path, out.file_path);
436 ASSERT_TRUE(out.resource_entry);
437 EXPECT_EQ(kTestDummyId, out.resource_entry->id());
438 }
439
347 TEST_F(DriveUploaderTest, InitiateUploadFail) { 440 TEST_F(DriveUploaderTest, InitiateUploadFail) {
348 FilePath local_path; 441 FilePath local_path;
349 std::string data; 442 std::string data;
350 ASSERT_TRUE(CreateFileOfSpecifiedSize(temp_dir_.path(), 512 * 1024, 443 ASSERT_TRUE(CreateFileOfSpecifiedSize(temp_dir_.path(), 512 * 1024,
351 &local_path, &data)); 444 &local_path, &data));
352 445
353 UploadCompletionCallbackResult out; 446 UploadCompletionCallbackResult out;
354 447
355 MockDriveServiceNoConnectionAtInitiate mock_service; 448 MockDriveServiceNoConnectionAtInitiate mock_service;
356 DriveUploader uploader(&mock_service); 449 DriveUploader uploader(&mock_service);
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 kTestMimeType, 534 kTestMimeType,
442 "", // etag 535 "", // etag
443 base::Bind(&CopyResultsFromUploadCompletionCallbackAndQuit, &out)); 536 base::Bind(&CopyResultsFromUploadCompletionCallbackAndQuit, &out));
444 message_loop_.Run(); 537 message_loop_.Run();
445 538
446 // Should return failure without doing any attempt to connect to the server. 539 // Should return failure without doing any attempt to connect to the server.
447 EXPECT_EQ(DRIVE_UPLOAD_ERROR_NOT_FOUND, out.error); 540 EXPECT_EQ(DRIVE_UPLOAD_ERROR_NOT_FOUND, out.error);
448 } 541 }
449 542
450 } // namespace google_apis 543 } // namespace google_apis
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698