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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/google_apis/drive_uploader_unittest.cc
diff --git a/chrome/browser/google_apis/drive_uploader_unittest.cc b/chrome/browser/google_apis/drive_uploader_unittest.cc
index 38aafedabe94ade969d7f689a553580cbac89fcc..2209a7dc03a18cfb16a46b0f8b03737cbf9ffc46 100644
--- a/chrome/browser/google_apis/drive_uploader_unittest.cc
+++ b/chrome/browser/google_apis/drive_uploader_unittest.cc
@@ -58,12 +58,22 @@ class MockDriveServiceWithUploadExpectation : public DummyDriveService {
const std::string& expected_upload_content)
: expected_upload_content_(expected_upload_content),
received_bytes_(0),
- resume_upload_call_count_(0) {}
+ resume_upload_call_count_(0),
+ get_upload_status_call_count_(0),
+ resume_upload_failure_point_(-1) {}
int64 received_bytes() const { return received_bytes_; }
int64 resume_upload_call_count() const { return resume_upload_call_count_; }
+ int64 get_upload_status_call_count() const {
+ return get_upload_status_call_count_;
+ }
+
+ void set_resume_upload_failure_point(int64 resume_upload_failure_point) {
+ resume_upload_failure_point_ = resume_upload_failure_point;
+ }
+
private:
// DriveServiceInterface overrides.
// Handles a request for obtaining an upload location URL.
@@ -122,6 +132,17 @@ class MockDriveServiceWithUploadExpectation : public DummyDriveService {
// Update the internal status of the current upload session.
resume_upload_call_count_++;
+ if (resume_upload_call_count_ == resume_upload_failure_point_) {
+ // Emulate the server error.
+ // ResumeUpload is an asynchronous function, so don't callback directly.
+ scoped_ptr<ResourceEntry> entry;
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(callback,
+ UploadRangeResponse(HTTP_SERVICE_UNAVAILABLE, 0, 0),
+ base::Passed(&entry)));
+ return;
+ }
received_bytes_ = params.end_position;
// Callback with response.
@@ -144,9 +165,50 @@ class MockDriveServiceWithUploadExpectation : public DummyDriveService {
base::Bind(callback, response, base::Passed(&entry)));
}
+ // Handles a request for uploading a chunk of bytes.
+ virtual void GetUploadStatus(
+ UploadMode upload_mode,
+ const FilePath& drive_file_path,
+ const GURL& upload_url,
+ int64 content_length,
+ const UploadRangeCallback& callback) OVERRIDE {
+ EXPECT_EQ(GURL(kTestUploadURL), upload_url);
+ const int64 expected_upload_content_size = expected_upload_content_.size();
+ EXPECT_EQ(expected_upload_content_size, content_length);
+
+ // Update the internal status of the current upload session.
+ get_upload_status_call_count_++;
+
+ // Callback with response.
+ UploadRangeResponse response;
+ scoped_ptr<ResourceEntry> entry;
+ if (received_bytes_ == content_length) {
+ response = UploadRangeResponse(
+ upload_mode == UPLOAD_NEW_FILE ? HTTP_CREATED : HTTP_SUCCESS,
+ -1, -1);
+
+ base::DictionaryValue dict;
+ dict.Set("id.$t", new base::StringValue(kTestDummyId));
+ entry = ResourceEntry::CreateFrom(dict);
+ } else {
+ response =
+ UploadRangeResponse(HTTP_RESUME_INCOMPLETE, 0, received_bytes_);
+ }
+ // GetUploadStatus is an asynchronous function, so don't callback directly.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ base::Bind(callback, response, base::Passed(&entry)));
+ }
+
std::string expected_upload_content_;
int64 received_bytes_;
int64 resume_upload_call_count_;
+ int64 get_upload_status_call_count_;
+
+ // When the resume_upload_call_count is equal to this value,
+ // this mock server will return 503 SERVICE_UNAVAILABLE to test the
+ // failure case. To disable this function, set the value to -1 so that
+ // the resume_upload_call_count_ won't be equal to this in real use cases.
+ int64 resume_upload_failure_point_;
};
// Mock DriveService that returns a failure at InitiateUpload().
@@ -344,6 +406,37 @@ TEST_F(DriveUploaderTest, UploadNew1234KB) {
EXPECT_EQ(kTestDummyId, out.resource_entry->id());
}
+TEST_F(DriveUploaderTest, UploadNew1234KBWithRetry) {
+ FilePath local_path;
+ std::string data;
+ ASSERT_TRUE(CreateFileOfSpecifiedSize(temp_dir_.path(), 1234 * 1024,
+ &local_path, &data));
+ UploadCompletionCallbackResult out;
+
+ MockDriveServiceWithUploadExpectation mock_service(data);
+ // Emulate the server failure when ResumeUpload is invoked twice.
+ mock_service.set_resume_upload_failure_point(2);
+ DriveUploader uploader(&mock_service);
+ uploader.UploadNewFile(
+ GURL(kTestInitialUploadURL),
+ FilePath::FromUTF8Unsafe(kTestDrivePath),
+ local_path,
+ kTestDocumentTitle,
+ kTestMimeType,
+ base::Bind(&CopyResultsFromUploadCompletionCallbackAndQuit, &out));
+ message_loop_.Run();
+
+ // The file should be split into 3 chunks (1234 = 512 + 512 + 210) + 1 retry.
+ EXPECT_EQ(4, mock_service.resume_upload_call_count());
+ EXPECT_EQ(1, mock_service.get_upload_status_call_count());
+ EXPECT_EQ(1234 * 1024, mock_service.received_bytes());
+ EXPECT_EQ(DRIVE_UPLOAD_OK, out.error);
+ EXPECT_EQ(FilePath::FromUTF8Unsafe(kTestDrivePath), out.drive_path);
+ EXPECT_EQ(local_path, out.file_path);
+ ASSERT_TRUE(out.resource_entry);
+ EXPECT_EQ(kTestDummyId, out.resource_entry->id());
+}
+
TEST_F(DriveUploaderTest, InitiateUploadFail) {
FilePath local_path;
std::string data;

Powered by Google App Engine
This is Rietveld 408576698