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