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