| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h" | 5 #include "chrome/browser/sync_file_system/drive_backend/conflict_resolver.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 SyncStatusCode status = SYNC_STATUS_UNKNOWN; | 231 SyncStatusCode status = SYNC_STATUS_UNKNOWN; |
| 232 sync_task_manager_->ScheduleSyncTask( | 232 sync_task_manager_->ScheduleSyncTask( |
| 233 FROM_HERE, | 233 FROM_HERE, |
| 234 scoped_ptr<SyncTask>(new ListChangesTask(context_.get())), | 234 scoped_ptr<SyncTask>(new ListChangesTask(context_.get())), |
| 235 SyncTaskManager::PRIORITY_MED, | 235 SyncTaskManager::PRIORITY_MED, |
| 236 CreateResultReceiver(&status)); | 236 CreateResultReceiver(&status)); |
| 237 base::RunLoop().RunUntilIdle(); | 237 base::RunLoop().RunUntilIdle(); |
| 238 return status; | 238 return status; |
| 239 } | 239 } |
| 240 | 240 |
| 241 ScopedVector<google_apis::ResourceEntry> | 241 ScopedVector<google_apis::FileResource> |
| 242 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id, | 242 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id, |
| 243 const std::string& title) { | 243 const std::string& title) { |
| 244 ScopedVector<google_apis::ResourceEntry> entries; | 244 ScopedVector<google_apis::FileResource> entries; |
| 245 EXPECT_EQ(google_apis::HTTP_SUCCESS, | 245 EXPECT_EQ(google_apis::HTTP_SUCCESS, |
| 246 fake_drive_helper_->SearchByTitle( | 246 fake_drive_helper_->SearchByTitle( |
| 247 parent_folder_id, title, &entries)); | 247 parent_folder_id, title, &entries)); |
| 248 return entries.Pass(); | 248 return entries.Pass(); |
| 249 } | 249 } |
| 250 | 250 |
| 251 void VerifyConflictResolution( | 251 void VerifyConflictResolution( |
| 252 const std::string& parent_folder_id, | 252 const std::string& parent_folder_id, |
| 253 const std::string& title, | 253 const std::string& title, |
| 254 const std::string& primary_file_id, | 254 const std::string& primary_file_id, |
| 255 google_apis::ResourceEntry::ResourceEntryKind kind) { | 255 test_util::FileResourceKind kind) { |
| 256 ScopedVector<google_apis::ResourceEntry> entries; | 256 ScopedVector<google_apis::FileResource> entries; |
| 257 EXPECT_EQ(google_apis::HTTP_SUCCESS, | 257 EXPECT_EQ(google_apis::HTTP_SUCCESS, |
| 258 fake_drive_helper_->SearchByTitle( | 258 fake_drive_helper_->SearchByTitle( |
| 259 parent_folder_id, title, &entries)); | 259 parent_folder_id, title, &entries)); |
| 260 ASSERT_EQ(1u, entries.size()); | 260 ASSERT_EQ(1u, entries.size()); |
| 261 EXPECT_EQ(primary_file_id, entries[0]->resource_id()); | 261 EXPECT_EQ(primary_file_id, entries[0]->file_id()); |
| 262 EXPECT_EQ(kind, entries[0]->kind()); | 262 EXPECT_EQ(kind, test_util::GetFileResourceKind(*entries[0])); |
| 263 } | 263 } |
| 264 | 264 |
| 265 void VerifyLocalChangeConsistency( | 265 void VerifyLocalChangeConsistency( |
| 266 const URLToFileChangesMap& expected_changes) { | 266 const URLToFileChangesMap& expected_changes) { |
| 267 remote_change_processor_->VerifyConsistency(expected_changes); | 267 remote_change_processor_->VerifyConsistency(expected_changes); |
| 268 } | 268 } |
| 269 | 269 |
| 270 private: | 270 private: |
| 271 content::TestBrowserThreadBundle thread_bundle_; | 271 content::TestBrowserThreadBundle thread_bundle_; |
| 272 base::ScopedTempDir database_dir_; | 272 base::ScopedTempDir database_dir_; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 301 RunRemoteToLocalSyncerUntilIdle(); | 301 RunRemoteToLocalSyncerUntilIdle(); |
| 302 | 302 |
| 303 const std::string kTitle = "foo"; | 303 const std::string kTitle = "foo"; |
| 304 const std::string primary = CreateRemoteFile(app_root, kTitle, "data1"); | 304 const std::string primary = CreateRemoteFile(app_root, kTitle, "data1"); |
| 305 CreateRemoteFile(app_root, kTitle, "data2"); | 305 CreateRemoteFile(app_root, kTitle, "data2"); |
| 306 CreateRemoteFile(app_root, kTitle, "data3"); | 306 CreateRemoteFile(app_root, kTitle, "data3"); |
| 307 CreateRemoteFile(app_root, kTitle, "data4"); | 307 CreateRemoteFile(app_root, kTitle, "data4"); |
| 308 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 308 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 309 RunRemoteToLocalSyncerUntilIdle(); | 309 RunRemoteToLocalSyncerUntilIdle(); |
| 310 | 310 |
| 311 ScopedVector<google_apis::ResourceEntry> entries = | 311 ScopedVector<google_apis::FileResource> entries = |
| 312 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 312 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 313 ASSERT_EQ(4u, entries.size()); | 313 ASSERT_EQ(4u, entries.size()); |
| 314 | 314 |
| 315 // Only primary file should survive. | 315 // Only primary file should survive. |
| 316 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 316 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 317 VerifyConflictResolution(app_root, kTitle, primary, | 317 VerifyConflictResolution(app_root, kTitle, primary, |
| 318 google_apis::ResourceEntry::ENTRY_KIND_FILE); | 318 test_util::RESOURCE_KIND_FILE); |
| 319 } | 319 } |
| 320 | 320 |
| 321 TEST_F(ConflictResolverTest, ResolveConflict_Folders) { | 321 TEST_F(ConflictResolverTest, ResolveConflict_Folders) { |
| 322 const GURL kOrigin("chrome-extension://example"); | 322 const GURL kOrigin("chrome-extension://example"); |
| 323 const std::string sync_root = CreateSyncRoot(); | 323 const std::string sync_root = CreateSyncRoot(); |
| 324 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 324 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 325 InitializeMetadataDatabase(); | 325 InitializeMetadataDatabase(); |
| 326 RegisterApp(kOrigin.host(), app_root); | 326 RegisterApp(kOrigin.host(), app_root); |
| 327 RunRemoteToLocalSyncerUntilIdle(); | 327 RunRemoteToLocalSyncerUntilIdle(); |
| 328 | 328 |
| 329 const std::string kTitle = "foo"; | 329 const std::string kTitle = "foo"; |
| 330 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 330 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 331 CreateRemoteFolder(app_root, kTitle); | 331 CreateRemoteFolder(app_root, kTitle); |
| 332 CreateRemoteFolder(app_root, kTitle); | 332 CreateRemoteFolder(app_root, kTitle); |
| 333 CreateRemoteFolder(app_root, kTitle); | 333 CreateRemoteFolder(app_root, kTitle); |
| 334 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 334 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 335 RunRemoteToLocalSyncerUntilIdle(); | 335 RunRemoteToLocalSyncerUntilIdle(); |
| 336 | 336 |
| 337 ScopedVector<google_apis::ResourceEntry> entries = | 337 ScopedVector<google_apis::FileResource> entries = |
| 338 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 338 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 339 ASSERT_EQ(4u, entries.size()); | 339 ASSERT_EQ(4u, entries.size()); |
| 340 | 340 |
| 341 // Only primary file should survive. | 341 // Only primary file should survive. |
| 342 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 342 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 343 VerifyConflictResolution(app_root, kTitle, primary, | 343 VerifyConflictResolution(app_root, kTitle, primary, |
| 344 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); | 344 test_util::RESOURCE_KIND_FOLDER); |
| 345 } | 345 } |
| 346 | 346 |
| 347 TEST_F(ConflictResolverTest, ResolveConflict_FilesAndFolders) { | 347 TEST_F(ConflictResolverTest, ResolveConflict_FilesAndFolders) { |
| 348 const GURL kOrigin("chrome-extension://example"); | 348 const GURL kOrigin("chrome-extension://example"); |
| 349 const std::string sync_root = CreateSyncRoot(); | 349 const std::string sync_root = CreateSyncRoot(); |
| 350 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 350 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 351 InitializeMetadataDatabase(); | 351 InitializeMetadataDatabase(); |
| 352 RegisterApp(kOrigin.host(), app_root); | 352 RegisterApp(kOrigin.host(), app_root); |
| 353 RunRemoteToLocalSyncerUntilIdle(); | 353 RunRemoteToLocalSyncerUntilIdle(); |
| 354 | 354 |
| 355 const std::string kTitle = "foo"; | 355 const std::string kTitle = "foo"; |
| 356 CreateRemoteFile(app_root, kTitle, "data"); | 356 CreateRemoteFile(app_root, kTitle, "data"); |
| 357 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 357 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 358 CreateRemoteFile(app_root, kTitle, "data2"); | 358 CreateRemoteFile(app_root, kTitle, "data2"); |
| 359 CreateRemoteFolder(app_root, kTitle); | 359 CreateRemoteFolder(app_root, kTitle); |
| 360 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 360 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 361 RunRemoteToLocalSyncerUntilIdle(); | 361 RunRemoteToLocalSyncerUntilIdle(); |
| 362 | 362 |
| 363 ScopedVector<google_apis::ResourceEntry> entries = | 363 ScopedVector<google_apis::FileResource> entries = |
| 364 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 364 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 365 ASSERT_EQ(4u, entries.size()); | 365 ASSERT_EQ(4u, entries.size()); |
| 366 | 366 |
| 367 // Only primary file should survive. | 367 // Only primary file should survive. |
| 368 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 368 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 369 VerifyConflictResolution(app_root, kTitle, primary, | 369 VerifyConflictResolution(app_root, kTitle, primary, |
| 370 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); | 370 test_util::RESOURCE_KIND_FOLDER); |
| 371 } | 371 } |
| 372 | 372 |
| 373 TEST_F(ConflictResolverTest, ResolveConflict_RemoteFolderOnLocalFile) { | 373 TEST_F(ConflictResolverTest, ResolveConflict_RemoteFolderOnLocalFile) { |
| 374 const GURL kOrigin("chrome-extension://example"); | 374 const GURL kOrigin("chrome-extension://example"); |
| 375 const std::string sync_root = CreateSyncRoot(); | 375 const std::string sync_root = CreateSyncRoot(); |
| 376 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 376 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 377 InitializeMetadataDatabase(); | 377 InitializeMetadataDatabase(); |
| 378 RegisterApp(kOrigin.host(), app_root); | 378 RegisterApp(kOrigin.host(), app_root); |
| 379 RunRemoteToLocalSyncerUntilIdle(); | 379 RunRemoteToLocalSyncerUntilIdle(); |
| 380 | 380 |
| 381 const std::string kTitle = "foo"; | 381 const std::string kTitle = "foo"; |
| 382 storage::FileSystemURL kURL = URL(kOrigin, kTitle); | 382 storage::FileSystemURL kURL = URL(kOrigin, kTitle); |
| 383 | 383 |
| 384 // Create a file on local and sync it. | 384 // Create a file on local and sync it. |
| 385 CreateLocalFile(kURL); | 385 CreateLocalFile(kURL); |
| 386 RunLocalToRemoteSyncer( | 386 RunLocalToRemoteSyncer( |
| 387 kURL, | 387 kURL, |
| 388 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE)); | 388 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE)); |
| 389 | 389 |
| 390 // Create a folder on remote and sync it. | 390 // Create a folder on remote and sync it. |
| 391 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 391 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 392 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 392 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 393 RunRemoteToLocalSyncerUntilIdle(); | 393 RunRemoteToLocalSyncerUntilIdle(); |
| 394 | 394 |
| 395 ScopedVector<google_apis::ResourceEntry> entries = | 395 ScopedVector<google_apis::FileResource> entries = |
| 396 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 396 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 397 ASSERT_EQ(2u, entries.size()); | 397 ASSERT_EQ(2u, entries.size()); |
| 398 | 398 |
| 399 // Run conflict resolver. Only primary file should survive. | 399 // Run conflict resolver. Only primary file should survive. |
| 400 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 400 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 401 VerifyConflictResolution(app_root, kTitle, primary, | 401 VerifyConflictResolution(app_root, kTitle, primary, |
| 402 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); | 402 test_util::RESOURCE_KIND_FOLDER); |
| 403 | 403 |
| 404 // Continue to run remote-to-local sync. | 404 // Continue to run remote-to-local sync. |
| 405 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 405 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 406 RunRemoteToLocalSyncerUntilIdle(); | 406 RunRemoteToLocalSyncerUntilIdle(); |
| 407 | 407 |
| 408 // Verify that the local side has been synced to the same state | 408 // Verify that the local side has been synced to the same state |
| 409 // (i.e. file deletion and folder creation). | 409 // (i.e. file deletion and folder creation). |
| 410 URLToFileChangesMap expected_changes; | 410 URLToFileChangesMap expected_changes; |
| 411 expected_changes[kURL].push_back( | 411 expected_changes[kURL].push_back( |
| 412 FileChange(FileChange::FILE_CHANGE_DELETE, | 412 FileChange(FileChange::FILE_CHANGE_DELETE, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 433 RunLocalToRemoteSyncer( | 433 RunLocalToRemoteSyncer( |
| 434 kURL, | 434 kURL, |
| 435 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE)); | 435 FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE)); |
| 436 | 436 |
| 437 // Create a folder and subfolder in it on remote, and sync it. | 437 // Create a folder and subfolder in it on remote, and sync it. |
| 438 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 438 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 439 CreateRemoteFolder(primary, "nested"); | 439 CreateRemoteFolder(primary, "nested"); |
| 440 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 440 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 441 RunRemoteToLocalSyncerUntilIdle(); | 441 RunRemoteToLocalSyncerUntilIdle(); |
| 442 | 442 |
| 443 ScopedVector<google_apis::ResourceEntry> entries = | 443 ScopedVector<google_apis::FileResource> entries = |
| 444 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 444 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 445 ASSERT_EQ(2u, entries.size()); | 445 ASSERT_EQ(2u, entries.size()); |
| 446 | 446 |
| 447 // Run conflict resolver. Only primary file should survive. | 447 // Run conflict resolver. Only primary file should survive. |
| 448 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 448 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 449 VerifyConflictResolution(app_root, kTitle, primary, | 449 VerifyConflictResolution(app_root, kTitle, primary, |
| 450 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); | 450 test_util::RESOURCE_KIND_FOLDER); |
| 451 | 451 |
| 452 // Continue to run remote-to-local sync. | 452 // Continue to run remote-to-local sync. |
| 453 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 453 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 454 RunRemoteToLocalSyncerUntilIdle(); | 454 RunRemoteToLocalSyncerUntilIdle(); |
| 455 | 455 |
| 456 // Verify that the local side has been synced to the same state | 456 // Verify that the local side has been synced to the same state |
| 457 // (i.e. file deletion and folders creation). | 457 // (i.e. file deletion and folders creation). |
| 458 URLToFileChangesMap expected_changes; | 458 URLToFileChangesMap expected_changes; |
| 459 expected_changes[kURL].push_back( | 459 expected_changes[kURL].push_back( |
| 460 FileChange(FileChange::FILE_CHANGE_DELETE, | 460 FileChange(FileChange::FILE_CHANGE_DELETE, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 | 517 |
| 518 EXPECT_EQ(4, CountParents(file)); | 518 EXPECT_EQ(4, CountParents(file)); |
| 519 | 519 |
| 520 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 520 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 521 | 521 |
| 522 EXPECT_EQ(1, CountParents(file)); | 522 EXPECT_EQ(1, CountParents(file)); |
| 523 } | 523 } |
| 524 | 524 |
| 525 } // namespace drive_backend | 525 } // namespace drive_backend |
| 526 } // namespace sync_file_system | 526 } // namespace sync_file_system |
| OLD | NEW |