12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/run_loop.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/drive/dummy_drive_service.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/test_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::CancelCallback;
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::FileResource;
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDataErrorCode;
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_NO_CONNECTION;
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::GDATA_OTHER_ERROR;
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CONFLICT;
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_CREATED;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_NOT_FOUND;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_PRECONDITION;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_RESUME_INCOMPLETE;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::HTTP_SUCCESS;
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::InitiateUploadCallback;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::ProgressCallback;
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing google_apis::UploadRangeResponse;
3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)using google_apis::drive::UploadRangeCallback;
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace test_util = google_apis::test_util;
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)const char kTestDummyMd5[] = "dummy_md5";
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestDocumentTitle[] = "Hello world";
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestInitiateUploadParentResourceId[] = "parent_resource_id";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestInitiateUploadResourceId[] = "resource_id";
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestMimeType[] = "text/plain";
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kTestUploadNewFileURL[] = "http://test/upload_location/new_file";
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kTestUploadExistingFileURL[] =
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "http://test/upload_location/existing_file";
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kUploadChunkSize = 512 * 1024;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kTestETag[] = "test_etag";
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Mock DriveService that verifies if the uploaded content matches the preset
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// expectation.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDriveServiceWithUploadExpectation : public DummyDriveService {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets up an expected upload content. InitiateUpload and ResumeUpload will
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // verify that the specified data is correctly uploaded.
60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockDriveServiceWithUploadExpectation(
61a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const base::FilePath& expected_upload_file,
62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      int64 expected_content_length)
63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)     : expected_upload_file_(expected_upload_file),
64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)       expected_content_length_(expected_content_length),
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       received_bytes_(0),
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       resume_upload_call_count_(0) {}
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 received_bytes() const { return received_bytes_; }
6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void set_received_bytes(int64 received_bytes) {
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    received_bytes_ = received_bytes;
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 resume_upload_call_count() const { return resume_upload_call_count_; }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // DriveServiceInterface overrides.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles a request for obtaining an upload location URL.
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadNewFile(
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& parent_resource_id,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& title,
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadNewFileOptions& options,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestDocumentTitle, title);
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestMimeType, content_type);
87a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_EQ(expected_content_length_, content_length);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestInitiateUploadParentResourceId, parent_resource_id);
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Calls back the upload URL for subsequent ResumeUpload requests.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // InitiateUpload is an asynchronous function, so don't callback directly.
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, GURL(kTestUploadNewFileURL)));
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadExistingFile(
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& resource_id,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadExistingFileOptions& options,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestMimeType, content_type);
104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_EQ(expected_content_length_, content_length);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestInitiateUploadResourceId, resource_id);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!options.etag.empty() && options.etag != kTestETag) {
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(FROM_HERE,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::Bind(callback, HTTP_PRECONDITION, GURL()));
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return CancelCallback();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    // Calls back the upload URL for subsequent ResumeUpload requests.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // InitiateUpload is an asynchronous function, so don't callback directly.
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, GURL(kTestUploadExistingFileURL)));
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles a request for uploading a chunk of bytes.
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback ResumeUpload(
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      const GURL& upload_location,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 start_position,
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 end_position,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const base::FilePath& local_file_path,
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UploadRangeCallback& callback,
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const ProgressCallback& progress_callback) OVERRIDE {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The upload range should start from the current first unreceived byte.
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(received_bytes_, start_position);
132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_EQ(expected_upload_file_, local_file_path);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The upload data must be split into 512KB chunks.
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const int64 expected_chunk_end =
136a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        std::min(received_bytes_ + kUploadChunkSize, expected_content_length_);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_chunk_end, end_position);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The upload URL returned by InitiateUpload() must be used.
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(GURL(kTestUploadNewFileURL) == upload_location ||
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                GURL(kTestUploadExistingFileURL) == upload_location);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Other parameters should be the exact values passed to DriveUploader.
144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_EQ(expected_content_length_, content_length);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestMimeType, content_type);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Update the internal status of the current upload session.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resume_upload_call_count_++;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    received_bytes_ = end_position;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Callback progress
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!progress_callback.is_null()) {
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // For the testing purpose, it always notifies the progress at the end of
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // each chunk uploading.
155a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      int64 chunk_size = end_position - start_position;
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(FROM_HERE,
157a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          base::Bind(progress_callback, chunk_size, chunk_size));
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SendUploadRangeResponse(upload_location, callback);
1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Handles a request to fetch the current upload status.
1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback GetUploadStatus(
1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const GURL& upload_location,
1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int64 content_length,
1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      const UploadRangeCallback& callback) OVERRIDE {
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_EQ(expected_content_length_, content_length);
17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // The upload URL returned by InitiateUpload() must be used.
17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    EXPECT_TRUE(GURL(kTestUploadNewFileURL) == upload_location ||
17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                GURL(kTestUploadExistingFileURL) == upload_location);
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SendUploadRangeResponse(upload_location, callback);
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Runs |callback| with the current upload status.
17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void SendUploadRangeResponse(const GURL& upload_location,
18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                               const UploadRangeCallback& callback) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Callback with response.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UploadRangeResponse response;
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<FileResource> entry;
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (received_bytes_ == expected_content_length_) {
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GDataErrorCode response_code =
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          upload_location == GURL(kTestUploadNewFileURL) ?
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          HTTP_CREATED : HTTP_SUCCESS;
18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      response = UploadRangeResponse(response_code, -1, -1);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      entry.reset(new FileResource);
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      entry->set_md5_checksum(kTestDummyMd5);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      response = UploadRangeResponse(
19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          HTTP_RESUME_INCOMPLETE, 0, received_bytes_);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ResumeUpload is an asynchronous function, so don't callback directly.
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, response, base::Passed(&entry)));
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const base::FilePath expected_upload_file_;
202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const int64 expected_content_length_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 received_bytes_;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int64 resume_upload_call_count_;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Mock DriveService that returns a failure at InitiateUpload().
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDriveServiceNoConnectionAtInitiate : public DummyDriveService {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns error.
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadNewFile(
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& parent_resource_id,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& title,
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadNewFileOptions& options,
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadExistingFile(
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& resource_id,
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadExistingFileOptions& options,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback, GDATA_NO_CONNECTION, GURL()));
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should not be used.
2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback ResumeUpload(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& upload_url,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 start_position,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 end_position,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
240a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const base::FilePath& local_file_path,
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UploadRangeCallback& callback,
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const ProgressCallback& progress_callback) OVERRIDE {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Mock DriveService that returns a failure at ResumeUpload().
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDriveServiceNoConnectionAtResume : public DummyDriveService {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Succeeds and returns an upload location URL.
2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadNewFile(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& parent_resource_id,
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& title,
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadNewFileOptions& options,
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, GURL(kTestUploadNewFileURL)));
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback InitiateUploadExistingFile(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& resource_id,
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const InitiateUploadExistingFileOptions& options,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const InitiateUploadCallback& callback) OVERRIDE {
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        base::Bind(callback, HTTP_SUCCESS, GURL(kTestUploadExistingFileURL)));
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns error.
2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual CancelCallback ResumeUpload(
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const GURL& upload_url,
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 start_position,
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 end_position,
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int64 content_length,
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& content_type,
281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      const base::FilePath& local_file_path,
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const UploadRangeCallback& callback,
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const ProgressCallback& progress_callback) OVERRIDE {
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(callback,
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   UploadRangeResponse(GDATA_NO_CONNECTION, -1, -1),
28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return CancelCallback();
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Mock DriveService that returns a failure at GetUploadStatus().
2932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochclass MockDriveServiceNoConnectionAtGetUploadStatus : public DummyDriveService {
2942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Returns error.
2952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual CancelCallback GetUploadStatus(
2962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      const GURL& upload_url,
2972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      int64 content_length,
2982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      const UploadRangeCallback& callback) OVERRIDE {
2992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    base::MessageLoop::current()->PostTask(FROM_HERE,
3002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        base::Bind(callback,
3012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                   UploadRangeResponse(GDATA_NO_CONNECTION, -1, -1),
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                   base::Passed(scoped_ptr<FileResource>())));
3032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return CancelCallback();
3042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
3052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch};
3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DriveUploaderTest : public testing::Test {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, UploadExisting0KB) {
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 0, &local_path, &data));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
32846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockDriveServiceWithUploadExpectation mock_service(local_path, data.size());
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<test_util::ProgressInfo> upload_progress_values;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uploader.UploadExistingFile(
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestInitiateUploadResourceId,
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      local_path,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestMimeType,
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DriveUploader::UploadExistingFileOptions(),
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_util::CreateCopyResultCallback(
34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &error, &upload_location, &entry),
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&test_util::AppendProgressCallbackResult,
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 &upload_progress_values));
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, mock_service.resume_upload_call_count());
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, mock_service.received_bytes());
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(HTTP_SUCCESS, error);
34890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(entry);
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(kTestDummyMd5, entry->md5_checksum());
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, upload_progress_values.size());
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(test_util::ProgressInfo(0, 0), upload_progress_values[0]);
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, UploadExisting512KB) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 512 * 1024, &local_path, &data));
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
365a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockDriveServiceWithUploadExpectation mock_service(local_path, data.size());
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<test_util::ProgressInfo> upload_progress_values;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uploader.UploadExistingFile(
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestInitiateUploadResourceId,
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      local_path,
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestMimeType,
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DriveUploader::UploadExistingFileOptions(),
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_util::CreateCopyResultCallback(
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &error, &upload_location, &entry),
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&test_util::AppendProgressCallbackResult,
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 &upload_progress_values));
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 512KB upload should not be split into multiple chunks.
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, mock_service.resume_upload_call_count());
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(512 * 1024, mock_service.received_bytes());
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(HTTP_SUCCESS, error);
38490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(entry);
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(kTestDummyMd5, entry->md5_checksum());
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(1U, upload_progress_values.size());
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(test_util::ProgressInfo(512 * 1024, 512 * 1024),
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            upload_progress_values[0]);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, InitiateUploadFail) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 512 * 1024, &local_path, &data));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = HTTP_SUCCESS;
39990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockDriveServiceNoConnectionAtInitiate mock_service;
403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uploader.UploadExistingFile(kTestInitiateUploadResourceId,
406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_path,
407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              kTestMimeType,
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              DriveUploader::UploadExistingFileOptions(),
409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              test_util::CreateCopyResultCallback(
41046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  &error, &upload_location, &entry),
411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              google_apis::ProgressCallback());
412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(GDATA_NO_CONNECTION, error);
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(entry);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, InitiateUploadNoConflict) {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 512 * 1024, &local_path, &data));
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
42746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
429a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockDriveServiceWithUploadExpectation mock_service(local_path, data.size());
430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DriveUploader::UploadExistingFileOptions options;
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  options.etag = kTestETag;
434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uploader.UploadExistingFile(kTestInitiateUploadResourceId,
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_path,
436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              kTestMimeType,
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              options,
438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              test_util::CreateCopyResultCallback(
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  &error, &upload_location, &entry),
440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              google_apis::ProgressCallback());
441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(HTTP_SUCCESS, error);
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, InitiateUploadConflict) {
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 512 * 1024, &local_path, &data));
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string kDestinationETag("destination_etag");
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
458a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockDriveServiceWithUploadExpectation mock_service(local_path, data.size());
459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DriveUploader::UploadExistingFileOptions options;
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  options.etag = kDestinationETag;
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uploader.UploadExistingFile(kTestInitiateUploadResourceId,
464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_path,
465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              kTestMimeType,
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              options,
467eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              test_util::CreateCopyResultCallback(
46846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  &error, &upload_location, &entry),
469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              google_apis::ProgressCallback());
470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(HTTP_CONFLICT, error);
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, ResumeUploadFail) {
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_path;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      temp_dir_.path(), 512 * 1024, &local_path, &data));
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = HTTP_SUCCESS;
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
48446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockDriveServiceNoConnectionAtResume mock_service;
487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uploader.UploadExistingFile(kTestInitiateUploadResourceId,
490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              local_path,
491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              kTestMimeType,
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              DriveUploader::UploadExistingFileOptions(),
493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              test_util::CreateCopyResultCallback(
49446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                  &error, &upload_location, &entry),
495eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                              google_apis::ProgressCallback());
496eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(GDATA_NO_CONNECTION, error);
49990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(GURL(kTestUploadExistingFileURL), upload_location);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochTEST_F(DriveUploaderTest, GetUploadStatusFail) {
5032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FilePath local_path;
5042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string data;
5052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
5062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      temp_dir_.path(), 512 * 1024, &local_path, &data));
5072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  GDataErrorCode error = HTTP_SUCCESS;
5092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  GURL upload_location;
51046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
5112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  MockDriveServiceNoConnectionAtGetUploadStatus mock_service;
5132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DriveUploader uploader(&mock_service,
5142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                         base::MessageLoopProxy::current().get());
5152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  uploader.ResumeUploadFile(GURL(kTestUploadExistingFileURL),
5162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                            local_path,
5172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                            kTestMimeType,
5182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                            test_util::CreateCopyResultCallback(
51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                &error, &upload_location, &entry),
5202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                            google_apis::ProgressCallback());
5212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::RunLoop().RunUntilIdle();
5222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_EQ(GDATA_NO_CONNECTION, error);
5242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  EXPECT_TRUE(upload_location.is_empty());
5252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
5262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DriveUploaderTest, NonExistingSourceFile) {
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
52990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
53046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(NULL,  // NULL, the service won't be used.
533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uploader.UploadExistingFile(
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestInitiateUploadResourceId,
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      temp_dir_.path().AppendASCII("_this_path_should_not_exist_"),
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kTestMimeType,
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DriveUploader::UploadExistingFileOptions(),
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      test_util::CreateCopyResultCallback(
54046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &error, &upload_location, &entry),
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      google_apis::ProgressCallback());
542eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should return failure without doing any attempt to connect to the server.
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(HTTP_NOT_FOUND, error);
54690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
54790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
54890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
54990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(DriveUploaderTest, ResumeUpload) {
55090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::FilePath local_path;
55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string data;
55290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_TRUE(test_util::CreateFileOfSpecifiedSize(
55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      temp_dir_.path(), 1024 * 1024, &local_path, &data));
55490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
55590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GDataErrorCode error = GDATA_OTHER_ERROR;
55690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  GURL upload_location;
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<FileResource> entry;
55890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
55990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  MockDriveServiceWithUploadExpectation mock_service(local_path, data.size());
560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DriveUploader uploader(&mock_service,
561eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                         base::MessageLoopProxy::current().get());
56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Emulate the situation that the only first part is successfully uploaded,
56390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // but not the latter half.
56490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  mock_service.set_received_bytes(512 * 1024);
56590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<test_util::ProgressInfo> upload_progress_values;
56790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  uploader.ResumeUploadFile(
56890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GURL(kTestUploadExistingFileURL),
56990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      local_path,
57090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      kTestMimeType,
57190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      test_util::CreateCopyResultCallback(
57246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          &error, &upload_location, &entry),
57390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::Bind(&test_util::AppendProgressCallbackResult,
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                 &upload_progress_values));
575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::RunLoop().RunUntilIdle();
57690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
57790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1, mock_service.resume_upload_call_count());
57890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(1024 * 1024, mock_service.received_bytes());
57990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(HTTP_SUCCESS, error);
58090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(upload_location.is_empty());
58146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  ASSERT_TRUE(entry);
58246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(kTestDummyMd5, entry->md5_checksum());
58390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ASSERT_EQ(1U, upload_progress_values.size());
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_EQ(test_util::ProgressInfo(1024 * 1024, 1024 * 1024),
58590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            upload_progress_values[0]);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
588eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace drive
589