Home | History | Annotate | Download | only in drive_backend_v1
      1 // Copyright 2013 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 "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h"
      6 
      7 #include <utility>
      8 
      9 #include "base/command_line.h"
     10 #include "base/file_util.h"
     11 #include "base/message_loop/message_loop_proxy.h"
     12 #include "base/run_loop.h"
     13 #include "chrome/browser/drive/drive_uploader.h"
     14 #include "chrome/browser/drive/fake_drive_service.h"
     15 #include "chrome/browser/extensions/test_extension_service.h"
     16 #include "chrome/browser/extensions/test_extension_system.h"
     17 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util.h"
     18 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_util.h"
     19 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
     20 #include "chrome/browser/sync_file_system/drive_backend_v1/fake_drive_service_helper.h"
     21 #include "chrome/browser/sync_file_system/file_status_observer.h"
     22 #include "chrome/browser/sync_file_system/mock_remote_change_processor.h"
     23 #include "chrome/browser/sync_file_system/sync_direction.h"
     24 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
     25 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
     26 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
     27 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
     28 #include "chrome/test/base/testing_profile.h"
     29 #include "content/public/test/test_browser_thread_bundle.h"
     30 #include "extensions/common/extension.h"
     31 #include "extensions/common/extension_builder.h"
     32 #include "extensions/common/id_util.h"
     33 #include "google_apis/drive/drive_api_parser.h"
     34 #include "google_apis/drive/gdata_errorcode.h"
     35 #include "google_apis/drive/gdata_wapi_parser.h"
     36 #include "google_apis/drive/test_util.h"
     37 #include "testing/gmock/include/gmock/gmock.h"
     38 #include "testing/gtest/include/gtest/gtest.h"
     39 #include "webkit/common/fileapi/file_system_util.h"
     40 
     41 #if defined(OS_CHROMEOS)
     42 #include "chrome/browser/chromeos/login/user_manager.h"
     43 #include "chrome/browser/chromeos/settings/cros_settings.h"
     44 #include "chrome/browser/chromeos/settings/device_settings_service.h"
     45 #endif
     46 
     47 #define FPL(x) FILE_PATH_LITERAL(x)
     48 
     49 using ::testing::StrictMock;
     50 using ::testing::_;
     51 
     52 using drive::DriveServiceInterface;
     53 using drive::DriveUploader;
     54 using drive::DriveUploaderInterface;
     55 using drive::FakeDriveService;
     56 
     57 using extensions::Extension;
     58 using extensions::DictionaryBuilder;
     59 using google_apis::GDataErrorCode;
     60 using google_apis::ResourceEntry;
     61 
     62 namespace sync_file_system {
     63 
     64 using drive_backend::APIUtil;
     65 using drive_backend::APIUtilInterface;
     66 using drive_backend::FakeDriveServiceHelper;
     67 
     68 namespace {
     69 
     70 #if !defined(OS_ANDROID)
     71 const char kExtensionName1[] = "example1";
     72 const char kExtensionName2[] = "example2";
     73 #endif
     74 
     75 void DidInitialize(bool* done, SyncStatusCode status, bool created) {
     76   EXPECT_FALSE(*done);
     77   *done = true;
     78   EXPECT_EQ(SYNC_STATUS_OK, status);
     79   EXPECT_TRUE(created);
     80 }
     81 
     82 // Mocks adding an installed extension to ExtensionService.
     83 scoped_refptr<const extensions::Extension> AddTestExtension(
     84     ExtensionService* extension_service,
     85     const base::FilePath::StringType& extension_name) {
     86   std::string id = extensions::id_util::GenerateIdForPath(
     87       base::FilePath(extension_name));
     88 
     89   scoped_refptr<const Extension> extension =
     90       extensions::ExtensionBuilder().SetManifest(
     91           DictionaryBuilder()
     92             .Set("name", extension_name)
     93             .Set("version", "1.0"))
     94           .SetID(id)
     95       .Build();
     96   extension_service->AddExtension(extension.get());
     97   return extension;
     98 }
     99 
    100 // Converts extension_name to extension ID.
    101 std::string ExtensionNameToId(const std::string& extension_name) {
    102   base::FilePath path = base::FilePath::FromUTF8Unsafe(extension_name);
    103   return extensions::id_util::GenerateIdForPath(path);
    104 }
    105 
    106 // Converts extension_name to GURL version.
    107 GURL ExtensionNameToGURL(const std::string& extension_name) {
    108   return extensions::Extension::GetBaseURLFromExtensionId(
    109       ExtensionNameToId(extension_name));
    110 }
    111 
    112 #if !defined(OS_ANDROID)
    113 ACTION(InvokeCompletionCallback) {
    114   base::MessageLoopProxy::current()->PostTask(FROM_HERE, arg2);
    115 }
    116 
    117 ACTION(PrepareForRemoteChange_Busy) {
    118   base::MessageLoopProxy::current()->PostTask(
    119       FROM_HERE,
    120       base::Bind(arg1,
    121                  SYNC_STATUS_FILE_BUSY,
    122                  SyncFileMetadata(),
    123                  FileChangeList()));
    124 }
    125 
    126 ACTION(PrepareForRemoteChange_NotFound) {
    127   base::MessageLoopProxy::current()->PostTask(
    128       FROM_HERE,
    129       base::Bind(arg1,
    130                  SYNC_STATUS_OK,
    131                  SyncFileMetadata(SYNC_FILE_TYPE_UNKNOWN, 0, base::Time()),
    132                  FileChangeList()));
    133 }
    134 
    135 ACTION(PrepareForRemoteChange_NotModified) {
    136   base::MessageLoopProxy::current()->PostTask(
    137       FROM_HERE,
    138       base::Bind(arg1,
    139                  SYNC_STATUS_OK,
    140                  SyncFileMetadata(SYNC_FILE_TYPE_FILE, 0, base::Time()),
    141                  FileChangeList()));
    142 }
    143 
    144 ACTION(InvokeDidApplyRemoteChange) {
    145   base::MessageLoopProxy::current()->PostTask(
    146       FROM_HERE, base::Bind(arg3, SYNC_STATUS_OK));
    147 }
    148 #endif  // !defined(OS_ANDROID)
    149 
    150 }  // namespace
    151 
    152 class MockFileStatusObserver: public FileStatusObserver {
    153  public:
    154   MockFileStatusObserver() {}
    155   virtual ~MockFileStatusObserver() {}
    156 
    157   MOCK_METHOD4(OnFileStatusChanged,
    158                void(const fileapi::FileSystemURL& url,
    159                     SyncFileStatus sync_status,
    160                     SyncAction action_taken,
    161                     SyncDirection direction));
    162 };
    163 
    164 class DriveFileSyncServiceFakeTest : public testing::Test {
    165  public:
    166   DriveFileSyncServiceFakeTest()
    167       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
    168         fake_drive_service_(NULL) {
    169   }
    170 
    171   virtual void SetUp() OVERRIDE {
    172     profile_.reset(new TestingProfile());
    173 
    174     // Add TestExtensionSystem with registered ExtensionIds used in tests.
    175     extensions::TestExtensionSystem* extension_system(
    176         static_cast<extensions::TestExtensionSystem*>(
    177             extensions::ExtensionSystem::Get(profile_.get())));
    178     extension_system->CreateExtensionService(
    179         CommandLine::ForCurrentProcess(), base::FilePath(), false);
    180     extension_service_ = extension_system->Get(
    181         profile_.get())->extension_service();
    182 
    183     AddTestExtension(extension_service_, FPL("example1"));
    184     AddTestExtension(extension_service_, FPL("example2"));
    185 
    186     RegisterSyncableFileSystem();
    187 
    188     fake_drive_service_ = new FakeDriveService;
    189     DriveUploaderInterface* drive_uploader = new DriveUploader(
    190         fake_drive_service_, base::MessageLoopProxy::current().get());
    191 
    192     fake_drive_helper_.reset(new FakeDriveServiceHelper(
    193         fake_drive_service_, drive_uploader));
    194 
    195     api_util_ = APIUtil::CreateForTesting(
    196         fake_drive_helper_->base_dir_path().AppendASCII("tmp"),
    197         scoped_ptr<DriveServiceInterface>(fake_drive_service_),
    198         scoped_ptr<DriveUploaderInterface>(drive_uploader)).Pass();
    199     metadata_store_.reset(new DriveMetadataStore(
    200         fake_drive_helper_->base_dir_path(),
    201         base::MessageLoopProxy::current().get()));
    202 
    203     bool done = false;
    204     metadata_store_->Initialize(base::Bind(&DidInitialize, &done));
    205     base::RunLoop().RunUntilIdle();
    206     EXPECT_TRUE(done);
    207 
    208     fake_drive_service_->LoadResourceListForWapi(
    209         "sync_file_system/initialize.json");
    210     fake_drive_service()->LoadAccountMetadataForWapi(
    211         "sync_file_system/account_metadata.json");
    212 
    213     // Setup the sync root directory.
    214     EXPECT_EQ(google_apis::HTTP_CREATED,
    215               fake_drive_helper_->AddOrphanedFolder(
    216                   APIUtil::GetSyncRootDirectoryName(),
    217                   &sync_root_resource_id_));
    218     metadata_store()->SetSyncRootDirectory(sync_root_resource_id_);
    219   }
    220 
    221   void SetUpDriveSyncService(bool enabled) {
    222     sync_service_ = DriveFileSyncService::CreateForTesting(
    223         profile_.get(),
    224         fake_drive_helper_->base_dir_path(),
    225         api_util_.PassAs<APIUtilInterface>(),
    226         metadata_store_.Pass()).Pass();
    227     sync_service_->AddFileStatusObserver(&mock_file_status_observer_);
    228     sync_service_->SetRemoteChangeProcessor(mock_remote_processor());
    229     sync_service_->SetSyncEnabled(enabled);
    230     base::RunLoop().RunUntilIdle();
    231   }
    232 
    233   virtual void TearDown() OVERRIDE {
    234     if (sync_service_) {
    235       sync_service_.reset();
    236     }
    237 
    238     metadata_store_.reset();
    239     api_util_.reset();
    240     fake_drive_service_ = NULL;
    241 
    242     RevokeSyncableFileSystem();
    243 
    244     extension_service_ = NULL;
    245     profile_.reset();
    246     base::RunLoop().RunUntilIdle();
    247   }
    248 
    249  protected:
    250   void EnableExtension(const std::string& extension_id) {
    251     extension_service_->EnableExtension(extension_id);
    252   }
    253 
    254   void DisableExtension(const std::string& extension_id) {
    255     extension_service_->DisableExtension(
    256         extension_id, extensions::Extension::DISABLE_NONE);
    257   }
    258 
    259   void UninstallExtension(const std::string& extension_id) {
    260     // Call UnloadExtension instead of UninstallExtension since it does
    261     // unnecessary cleanup (e.g. deleting extension data) and emits warnings.
    262     extension_service_->UnloadExtension(
    263         extension_id, extensions::UnloadedExtensionInfo::REASON_UNINSTALL);
    264   }
    265 
    266   void UpdateRegisteredOrigins() {
    267     sync_service_->UpdateRegisteredOrigins();
    268     // Wait for completion of uninstalling origin.
    269     base::RunLoop().RunUntilIdle();
    270   }
    271 
    272   void VerifySizeOfRegisteredOrigins(size_t b_size,
    273                                      size_t i_size,
    274                                      size_t d_size) {
    275     EXPECT_EQ(b_size, pending_batch_sync_origins()->size());
    276     EXPECT_EQ(i_size, metadata_store()->incremental_sync_origins().size());
    277     EXPECT_EQ(d_size, metadata_store()->disabled_origins().size());
    278   }
    279 
    280   DriveMetadataStore* metadata_store() {
    281     if (metadata_store_)
    282       return metadata_store_.get();
    283     return sync_service_->metadata_store_.get();
    284   }
    285 
    286   FakeDriveService* fake_drive_service() {
    287     return fake_drive_service_;
    288   }
    289 
    290   StrictMock<MockFileStatusObserver>* mock_file_status_observer() {
    291     return &mock_file_status_observer_;
    292   }
    293 
    294   StrictMock<MockRemoteChangeProcessor>* mock_remote_processor() {
    295     return &mock_remote_processor_;
    296   }
    297 
    298   DriveFileSyncService* sync_service() { return sync_service_.get(); }
    299   std::map<GURL, std::string>* pending_batch_sync_origins() {
    300     return &(sync_service()->pending_batch_sync_origins_);
    301   }
    302 
    303   const RemoteChangeHandler& remote_change_handler() const {
    304     return sync_service_->remote_change_handler_;
    305   }
    306 
    307   fileapi::FileSystemURL CreateURL(const GURL& origin,
    308                                    const std::string& filename) {
    309     return CreateSyncableFileSystemURL(
    310         origin, base::FilePath::FromUTF8Unsafe(filename));
    311   }
    312 
    313   void ProcessRemoteChange(SyncStatusCode expected_status,
    314                            const fileapi::FileSystemURL& expected_url,
    315                            SyncFileStatus expected_sync_file_status,
    316                            SyncAction expected_sync_action,
    317                            SyncDirection expected_sync_direction) {
    318     SyncStatusCode actual_status = SYNC_STATUS_UNKNOWN;
    319     fileapi::FileSystemURL actual_url;
    320 
    321     if (expected_sync_file_status != SYNC_FILE_STATUS_UNKNOWN) {
    322       EXPECT_CALL(*mock_file_status_observer(),
    323                   OnFileStatusChanged(expected_url,
    324                                       expected_sync_file_status,
    325                                       expected_sync_action,
    326                                       expected_sync_direction))
    327           .Times(1);
    328     }
    329 
    330     sync_service_->ProcessRemoteChange(
    331         CreateResultReceiver(&actual_status, &actual_url));
    332     base::RunLoop().RunUntilIdle();
    333 
    334     EXPECT_EQ(expected_status, actual_status);
    335     EXPECT_EQ(expected_url, actual_url);
    336   }
    337 
    338   bool AppendIncrementalRemoteChangeByResourceId(
    339       const std::string& resource_id,
    340       const GURL& origin) {
    341     scoped_ptr<ResourceEntry> entry;
    342     EXPECT_EQ(google_apis::HTTP_SUCCESS,
    343               fake_drive_helper_->GetResourceEntry(resource_id, &entry));
    344     return sync_service_->AppendRemoteChange(origin, *entry, 12345);
    345   }
    346 
    347   bool AppendIncrementalRemoteChange(
    348       const GURL& origin,
    349       const base::FilePath& path,
    350       bool is_deleted,
    351       const std::string& resource_id,
    352       int64 changestamp,
    353       const std::string& remote_file_md5) {
    354     return sync_service_->AppendRemoteChangeInternal(
    355         origin, path, is_deleted, resource_id,
    356         changestamp, remote_file_md5, base::Time(),
    357         SYNC_FILE_TYPE_FILE);
    358   }
    359 
    360   std::string SetUpOriginRootDirectory(const char* extension_name) {
    361     EXPECT_TRUE(!sync_root_resource_id_.empty());
    362 
    363     std::string origin_root_resource_id;
    364     EXPECT_EQ(google_apis::HTTP_CREATED,
    365               fake_drive_helper_->AddFolder(
    366                   sync_root_resource_id_,
    367                   ExtensionNameToId(extension_name),
    368                   &origin_root_resource_id));
    369 
    370     metadata_store()->AddIncrementalSyncOrigin(
    371         ExtensionNameToGURL(extension_name), origin_root_resource_id);
    372     return origin_root_resource_id;
    373   }
    374 
    375   void AddNewFile(const GURL& origin,
    376                   const std::string& parent_resource_id,
    377                   const std::string& title,
    378                   const std::string& content,
    379                   scoped_ptr<google_apis::ResourceEntry>* entry) {
    380     std::string file_id;
    381     ASSERT_EQ(google_apis::HTTP_SUCCESS,
    382               fake_drive_helper_->AddFile(
    383                   parent_resource_id, title, content, &file_id));
    384     ASSERT_EQ(google_apis::HTTP_SUCCESS,
    385               fake_drive_helper_->GetResourceEntry(
    386                   file_id, entry));
    387 
    388     DriveMetadata metadata;
    389     metadata.set_resource_id(file_id);
    390     metadata.set_md5_checksum((*entry)->file_md5());
    391     metadata.set_conflicted(false);
    392     metadata.set_to_be_fetched(false);
    393     metadata.set_type(DriveMetadata::RESOURCE_TYPE_FILE);
    394 
    395     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    396     metadata_store()->UpdateEntry(
    397         CreateURL(origin, title), metadata,
    398         CreateResultReceiver(&status));
    399     base::RunLoop().RunUntilIdle();
    400     ASSERT_EQ(SYNC_STATUS_OK, status);
    401   }
    402 
    403   void TestRegisterNewOrigin();
    404   void TestRegisterExistingOrigin();
    405   void TestRegisterOriginWithSyncDisabled();
    406   void TestUninstallOrigin();
    407   void TestUpdateRegisteredOrigins();
    408   void TestRemoteChange_NoChange();
    409   void TestRemoteChange_Busy();
    410   void TestRemoteChange_NewFile();
    411   void TestRemoteChange_UpdateFile();
    412   void TestRemoteChange_Override();
    413   void TestRemoteChange_Folder();
    414   void TestGetRemoteVersions();
    415 
    416  private:
    417   content::TestBrowserThreadBundle thread_bundle_;
    418 
    419   scoped_ptr<TestingProfile> profile_;
    420 
    421   std::string sync_root_resource_id_;
    422 
    423 #if defined OS_CHROMEOS
    424   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
    425   chromeos::ScopedTestCrosSettings test_cros_settings_;
    426   chromeos::ScopedTestUserManager test_user_manager_;
    427 #endif
    428 
    429   scoped_ptr<DriveFileSyncService> sync_service_;
    430 
    431   // Not owned.
    432   ExtensionService* extension_service_;
    433 
    434   FakeDriveService* fake_drive_service_;
    435   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
    436 
    437   StrictMock<MockFileStatusObserver> mock_file_status_observer_;
    438   StrictMock<MockRemoteChangeProcessor> mock_remote_processor_;
    439 
    440   scoped_ptr<APIUtil> api_util_;
    441   scoped_ptr<DriveMetadataStore> metadata_store_;
    442 
    443   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceFakeTest);
    444 };
    445 
    446 #if !defined(OS_ANDROID)
    447 
    448 void DriveFileSyncServiceFakeTest::TestRegisterNewOrigin() {
    449   SetUpDriveSyncService(true);
    450   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    451   sync_service()->RegisterOrigin(
    452       ExtensionNameToGURL(kExtensionName1),
    453       CreateResultReceiver(&status));
    454   base::RunLoop().RunUntilIdle();
    455   EXPECT_EQ(SYNC_STATUS_OK, status);
    456 
    457   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
    458   EXPECT_TRUE(!remote_change_handler().HasChanges());
    459 }
    460 
    461 void DriveFileSyncServiceFakeTest::TestRegisterExistingOrigin() {
    462   const std::string origin_resource_id =
    463       SetUpOriginRootDirectory(kExtensionName1);
    464 
    465   std::string file_id;
    466   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    467             fake_drive_helper_->AddFile(
    468                 origin_resource_id, "1.txt", "data1", &file_id));
    469   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    470             fake_drive_helper_->AddFile(
    471                 origin_resource_id, "2.txt", "data2", &file_id));
    472   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    473             fake_drive_helper_->AddFile(
    474                 origin_resource_id, "3.txt", "data3", &file_id));
    475 
    476   SetUpDriveSyncService(true);
    477 
    478   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    479   sync_service()->RegisterOrigin(
    480       ExtensionNameToGURL(kExtensionName1),
    481       CreateResultReceiver(&status));
    482   base::RunLoop().RunUntilIdle();
    483   EXPECT_EQ(SYNC_STATUS_OK, status);
    484 
    485   // The origin should be registered as an incremental sync origin.
    486   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
    487 
    488   // There are 3 items to sync.
    489   EXPECT_EQ(3u, remote_change_handler().ChangesSize());
    490 }
    491 
    492 void DriveFileSyncServiceFakeTest::TestRegisterOriginWithSyncDisabled() {
    493   // Usually the sync service starts here, but since we're setting up a drive
    494   // service with sync disabled sync doesn't start (while register origin should
    495   // still return OK).
    496   SetUpDriveSyncService(false);
    497 
    498   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    499   sync_service()->RegisterOrigin(
    500       ExtensionNameToGURL(kExtensionName1),
    501       CreateResultReceiver(&status));
    502   base::RunLoop().RunUntilIdle();
    503   EXPECT_EQ(SYNC_STATUS_OK, status);
    504 
    505   // We must not have started batch sync for the newly registered origin,
    506   // so it should still be in the batch_sync_origins.
    507   VerifySizeOfRegisteredOrigins(1u, 0u, 0u);
    508   EXPECT_TRUE(!remote_change_handler().HasChanges());
    509 }
    510 
    511 void DriveFileSyncServiceFakeTest::TestUninstallOrigin() {
    512   SetUpOriginRootDirectory(kExtensionName1);
    513   SetUpOriginRootDirectory(kExtensionName2);
    514 
    515   SetUpDriveSyncService(true);
    516 
    517   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
    518   EXPECT_EQ(0u, remote_change_handler().ChangesSize());
    519 
    520   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
    521   sync_service()->UninstallOrigin(
    522       ExtensionNameToGURL(kExtensionName1),
    523       RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
    524       CreateResultReceiver(&status));
    525   base::RunLoop().RunUntilIdle();
    526   EXPECT_EQ(SYNC_STATUS_OK, status);
    527 
    528   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
    529   EXPECT_TRUE(!remote_change_handler().HasChanges());
    530 }
    531 
    532 void DriveFileSyncServiceFakeTest::TestUpdateRegisteredOrigins() {
    533   SetUpOriginRootDirectory(kExtensionName1);
    534   SetUpOriginRootDirectory(kExtensionName2);
    535   SetUpDriveSyncService(true);
    536 
    537   // [1] Both extensions and origins are enabled. Nothing to do.
    538   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
    539   UpdateRegisteredOrigins();
    540   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
    541 
    542   // [2] Extension 1 should move to disabled list.
    543   DisableExtension(ExtensionNameToId(kExtensionName1));
    544   UpdateRegisteredOrigins();
    545   VerifySizeOfRegisteredOrigins(0u, 1u, 1u);
    546 
    547   // [3] Make sure that state remains the same, nothing should change.
    548   UpdateRegisteredOrigins();
    549   VerifySizeOfRegisteredOrigins(0u, 1u, 1u);
    550 
    551   // [4] Uninstall Extension 2.
    552   UninstallExtension(ExtensionNameToId(kExtensionName2));
    553   UpdateRegisteredOrigins();
    554   VerifySizeOfRegisteredOrigins(0u, 0u, 1u);
    555 
    556   // [5] Re-enable Extension 1. It moves back to batch and not to incremental.
    557   EnableExtension(ExtensionNameToId(kExtensionName1));
    558   UpdateRegisteredOrigins();
    559   VerifySizeOfRegisteredOrigins(1u, 0u, 0u);
    560 }
    561 
    562 void DriveFileSyncServiceFakeTest::TestRemoteChange_NoChange() {
    563   SetUpDriveSyncService(true);
    564 
    565   ProcessRemoteChange(SYNC_STATUS_NO_CHANGE_TO_SYNC,
    566                       fileapi::FileSystemURL(),
    567                       SYNC_FILE_STATUS_UNKNOWN,
    568                       SYNC_ACTION_NONE,
    569                       SYNC_DIRECTION_NONE);
    570   VerifySizeOfRegisteredOrigins(0u, 0u, 0u);
    571   EXPECT_TRUE(!remote_change_handler().HasChanges());
    572 }
    573 
    574 void DriveFileSyncServiceFakeTest::TestRemoteChange_Busy() {
    575   const char kFileName[] = "File 1.txt";
    576   const GURL origin = ExtensionNameToGURL(kExtensionName1);
    577 
    578   const std::string origin_resource_id =
    579       SetUpOriginRootDirectory(kExtensionName1);
    580 
    581   EXPECT_CALL(*mock_remote_processor(),
    582               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
    583       .WillOnce(PrepareForRemoteChange_Busy());
    584   EXPECT_CALL(*mock_remote_processor(),
    585               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
    586       .WillOnce(InvokeCompletionCallback());
    587 
    588   SetUpDriveSyncService(true);
    589 
    590   std::string resource_id;
    591   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    592             fake_drive_helper_->AddFile(
    593                 origin_resource_id, kFileName, "test data", &resource_id));
    594   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
    595 
    596   ProcessRemoteChange(SYNC_STATUS_FILE_BUSY,
    597                       CreateURL(origin, kFileName),
    598                       SYNC_FILE_STATUS_UNKNOWN,
    599                       SYNC_ACTION_NONE,
    600                       SYNC_DIRECTION_NONE);
    601 }
    602 
    603 void DriveFileSyncServiceFakeTest::TestRemoteChange_NewFile() {
    604   const char kFileName[] = "File 1.txt";
    605   const GURL origin = ExtensionNameToGURL(kExtensionName1);
    606 
    607   const std::string origin_resource_id =
    608       SetUpOriginRootDirectory(kExtensionName1);
    609 
    610   EXPECT_CALL(*mock_remote_processor(),
    611               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
    612       .WillOnce(PrepareForRemoteChange_NotFound());
    613   EXPECT_CALL(*mock_remote_processor(),
    614               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
    615       .WillOnce(InvokeCompletionCallback());
    616 
    617   EXPECT_CALL(*mock_remote_processor(),
    618               ApplyRemoteChange(_, _, CreateURL(origin, kFileName), _))
    619       .WillOnce(InvokeDidApplyRemoteChange());
    620 
    621   SetUpDriveSyncService(true);
    622 
    623   std::string resource_id;
    624   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    625             fake_drive_helper_->AddFile(
    626                 origin_resource_id, kFileName, "test data", &resource_id));
    627   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
    628 
    629   ProcessRemoteChange(SYNC_STATUS_OK,
    630                       CreateURL(origin, kFileName),
    631                       SYNC_FILE_STATUS_SYNCED,
    632                       SYNC_ACTION_ADDED,
    633                       SYNC_DIRECTION_REMOTE_TO_LOCAL);
    634 }
    635 
    636 void DriveFileSyncServiceFakeTest::TestRemoteChange_UpdateFile() {
    637   const char kFileName[] = "File 1.txt";
    638   const GURL origin = ExtensionNameToGURL(kExtensionName1);
    639 
    640   const std::string origin_resource_id =
    641       SetUpOriginRootDirectory(kExtensionName1);
    642 
    643   EXPECT_CALL(*mock_remote_processor(),
    644               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
    645       .WillOnce(PrepareForRemoteChange_NotModified());
    646   EXPECT_CALL(*mock_remote_processor(),
    647               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
    648       .WillOnce(InvokeCompletionCallback());
    649 
    650   EXPECT_CALL(*mock_remote_processor(),
    651               ApplyRemoteChange(_, _, CreateURL(origin, kFileName), _))
    652       .WillOnce(InvokeDidApplyRemoteChange());
    653 
    654   SetUpDriveSyncService(true);
    655 
    656   std::string resource_id;
    657   EXPECT_EQ(google_apis::HTTP_SUCCESS,
    658             fake_drive_helper_->AddFile(
    659                 origin_resource_id, kFileName, "test data", &resource_id));
    660   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
    661 
    662   ProcessRemoteChange(SYNC_STATUS_OK,
    663                       CreateURL(origin, kFileName),
    664                       SYNC_FILE_STATUS_SYNCED,
    665                       SYNC_ACTION_UPDATED,
    666                       SYNC_DIRECTION_REMOTE_TO_LOCAL);
    667 }
    668 
    669 void DriveFileSyncServiceFakeTest::TestRemoteChange_Override() {
    670   const base::FilePath kFilePath(FPL("File 1.txt"));
    671   const std::string kFileResourceId("file:2_file_resource_id");
    672   const std::string kFileResourceId2("file:2_file_resource_id_2");
    673   const GURL origin = ExtensionNameToGURL(kExtensionName1);
    674 
    675   SetUpOriginRootDirectory(kExtensionName1);
    676   SetUpDriveSyncService(true);
    677 
    678   EXPECT_TRUE(AppendIncrementalRemoteChange(
    679       origin, kFilePath, false /* is_deleted */,
    680       kFileResourceId, 2, "remote_file_md5"));
    681 
    682   // Expect to drop this change since there is another newer change on the
    683   // queue.
    684   EXPECT_FALSE(AppendIncrementalRemoteChange(
    685       origin, kFilePath, false /* is_deleted */,
    686       kFileResourceId, 1, "remote_file_md5_2"));
    687 
    688   // Expect to drop this change since it has the same md5 with the previous one.
    689   EXPECT_FALSE(AppendIncrementalRemoteChange(
    690       origin, kFilePath, false /* is_deleted */,
    691       kFileResourceId, 4, "remote_file_md5"));
    692 
    693   // This should not cause browser crash.
    694   EXPECT_FALSE(AppendIncrementalRemoteChange(
    695       origin, kFilePath, false /* is_deleted */,
    696       kFileResourceId, 4, "remote_file_md5"));
    697 
    698   // Expect to drop these changes since they have different resource IDs with
    699   // the previous ones.
    700   EXPECT_FALSE(AppendIncrementalRemoteChange(
    701       origin, kFilePath, false /* is_deleted */,
    702       kFileResourceId2, 5, "updated_file_md5"));
    703   EXPECT_FALSE(AppendIncrementalRemoteChange(
    704       origin, kFilePath, true /* is_deleted */,
    705       kFileResourceId2, 5, "deleted_file_md5"));
    706 
    707   // Push delete change.
    708   EXPECT_TRUE(AppendIncrementalRemoteChange(
    709       origin, kFilePath, true /* is_deleted */,
    710       kFileResourceId, 6, "deleted_file_md5"));
    711 
    712   // Expect to drop this delete change since it has a different resource ID with
    713   // the previous one.
    714   EXPECT_FALSE(AppendIncrementalRemoteChange(
    715       origin, kFilePath, true /* is_deleted */,
    716       kFileResourceId2, 7, "deleted_file_md5"));
    717 
    718   // Expect not to drop this change even if it has a different resource ID with
    719   // the previous one.
    720   EXPECT_TRUE(AppendIncrementalRemoteChange(
    721       origin, kFilePath, false /* is_deleted */,
    722       kFileResourceId2, 8, "updated_file_md5"));
    723 }
    724 
    725 void DriveFileSyncServiceFakeTest::TestRemoteChange_Folder() {
    726   const std::string origin_resource_id =
    727       SetUpOriginRootDirectory(kExtensionName1);
    728   SetUpDriveSyncService(true);
    729 
    730   std::string resource_id;
    731   EXPECT_EQ(google_apis::HTTP_CREATED,
    732             fake_drive_helper_->AddFolder(
    733                 origin_resource_id, "test_dir", &resource_id));
    734 
    735   // Expect to drop this change for file.
    736   EXPECT_FALSE(AppendIncrementalRemoteChangeByResourceId(
    737       resource_id, ExtensionNameToGURL(kExtensionName1)));
    738 }
    739 
    740 void DriveFileSyncServiceFakeTest::TestGetRemoteVersions() {
    741   SetUpDriveSyncService(true);
    742   const std::string origin_resource_id =
    743       SetUpOriginRootDirectory(kExtensionName1);
    744 
    745   const GURL origin(ExtensionNameToGURL(kExtensionName1));
    746   const std::string title("file");
    747   const std::string content("data1");
    748   const fileapi::FileSystemURL& url(CreateURL(origin, title));
    749 
    750   scoped_ptr<google_apis::ResourceEntry> entry;
    751   AddNewFile(origin, origin_resource_id, title, content, &entry);
    752 
    753   SyncStatusCode status = SYNC_STATUS_FAILED;
    754   std::vector<RemoteFileSyncService::Version> versions;
    755   sync_service_->GetRemoteVersions(
    756       url, CreateResultReceiver(&status, &versions));
    757   base::RunLoop().RunUntilIdle();
    758 
    759   ASSERT_EQ(SYNC_STATUS_OK, status);
    760   ASSERT_FALSE(versions.empty());
    761   EXPECT_EQ(1u, versions.size());
    762   EXPECT_EQ(static_cast<int64>(content.length()), versions[0].metadata.size);
    763   EXPECT_EQ(entry->file_size(), versions[0].metadata.size);
    764   EXPECT_EQ(entry->updated_time(), versions[0].metadata.last_modified);
    765 
    766   status = SYNC_STATUS_FAILED;
    767   webkit_blob::ScopedFile downloaded;
    768   sync_service_->DownloadRemoteVersion(
    769       url, versions[0].id, CreateResultReceiver(&status, &downloaded));
    770   base::RunLoop().RunUntilIdle();
    771 
    772   ASSERT_EQ(SYNC_STATUS_OK, status);
    773 
    774   std::string downloaded_content;
    775   EXPECT_TRUE(base::ReadFileToString(downloaded.path(), &downloaded_content));
    776   EXPECT_EQ(content, downloaded_content);
    777 }
    778 
    779 TEST_F(DriveFileSyncServiceFakeTest, RegisterNewOrigin) {
    780   ASSERT_FALSE(IsDriveAPIDisabled());
    781   TestRegisterNewOrigin();
    782 }
    783 
    784 TEST_F(DriveFileSyncServiceFakeTest, RegisterNewOrigin_WAPI) {
    785   ScopedDisableDriveAPI disable_drive_api;
    786   TestRegisterNewOrigin();
    787 }
    788 
    789 TEST_F(DriveFileSyncServiceFakeTest, RegisterExistingOrigin) {
    790   ASSERT_FALSE(IsDriveAPIDisabled());
    791   TestRegisterExistingOrigin();
    792 }
    793 
    794 TEST_F(DriveFileSyncServiceFakeTest, RegisterExistingOrigin_WAPI) {
    795   ScopedDisableDriveAPI disable_drive_api;
    796   TestRegisterExistingOrigin();
    797 }
    798 
    799 TEST_F(DriveFileSyncServiceFakeTest, RegisterOriginWithSyncDisabled) {
    800   ASSERT_FALSE(IsDriveAPIDisabled());
    801   TestRegisterOriginWithSyncDisabled();
    802 }
    803 
    804 TEST_F(DriveFileSyncServiceFakeTest, RegisterOriginWithSyncDisabled_WAPI) {
    805   ScopedDisableDriveAPI disable_drive_api;
    806   TestRegisterOriginWithSyncDisabled();
    807 }
    808 
    809 TEST_F(DriveFileSyncServiceFakeTest, UninstallOrigin) {
    810   ASSERT_FALSE(IsDriveAPIDisabled());
    811   TestUninstallOrigin();
    812 }
    813 
    814 TEST_F(DriveFileSyncServiceFakeTest, UninstallOrigin_WAPI) {
    815   ScopedDisableDriveAPI disable_drive_api;
    816   TestUninstallOrigin();
    817 }
    818 
    819 TEST_F(DriveFileSyncServiceFakeTest, UpdateRegisteredOrigins) {
    820   ASSERT_FALSE(IsDriveAPIDisabled());
    821   TestUpdateRegisteredOrigins();
    822 }
    823 
    824 TEST_F(DriveFileSyncServiceFakeTest, UpdateRegisteredOrigins_WAPI) {
    825   ScopedDisableDriveAPI disable_drive_api;
    826   TestUpdateRegisteredOrigins();
    827 }
    828 
    829 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NoChange) {
    830   ASSERT_FALSE(IsDriveAPIDisabled());
    831   TestRemoteChange_NoChange();
    832 }
    833 
    834 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NoChange_WAPI) {
    835   ScopedDisableDriveAPI disable_drive_api;
    836   TestRemoteChange_NoChange();
    837 }
    838 
    839 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Busy) {
    840   ASSERT_FALSE(IsDriveAPIDisabled());
    841   TestRemoteChange_Busy();
    842 }
    843 
    844 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Busy_WAPI) {
    845   ScopedDisableDriveAPI disable_drive_api;
    846   TestRemoteChange_Busy();
    847 }
    848 
    849 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NewFile) {
    850   ASSERT_FALSE(IsDriveAPIDisabled());
    851   TestRemoteChange_NewFile();
    852 }
    853 
    854 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NewFile_WAPI) {
    855   ScopedDisableDriveAPI disable_drive_api;
    856   TestRemoteChange_NewFile();
    857 }
    858 
    859 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_UpdateFile) {
    860   ASSERT_FALSE(IsDriveAPIDisabled());
    861   TestRemoteChange_UpdateFile();
    862 }
    863 
    864 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_UpdateFile_WAPI) {
    865   ScopedDisableDriveAPI disable_drive_api;
    866   TestRemoteChange_UpdateFile();
    867 }
    868 
    869 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Override) {
    870   ASSERT_FALSE(IsDriveAPIDisabled());
    871   TestRemoteChange_Override();
    872 }
    873 
    874 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Override_WAPI) {
    875   ScopedDisableDriveAPI disable_drive_api;
    876   TestRemoteChange_Override();
    877 }
    878 
    879 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Folder) {
    880   ASSERT_FALSE(IsDriveAPIDisabled());
    881   TestRemoteChange_Folder();
    882 }
    883 
    884 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Folder_WAPI) {
    885   ScopedDisableDriveAPI disable_drive_api;
    886   TestRemoteChange_Folder();
    887 }
    888 
    889 TEST_F(DriveFileSyncServiceFakeTest, GetRemoteVersions) {
    890   ASSERT_FALSE(IsDriveAPIDisabled());
    891   TestGetRemoteVersions();
    892 }
    893 
    894 TEST_F(DriveFileSyncServiceFakeTest, GetRemoteVersions_WAPI) {
    895   ScopedDisableDriveAPI disable_drive_api;
    896   TestGetRemoteVersions();
    897 }
    898 
    899 #endif  // !defined(OS_ANDROID)
    900 
    901 }  // namespace sync_file_system
    902