| 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/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 ScopedVector<google_apis::ResourceEntry> | 238 ScopedVector<google_apis::ResourceEntry> |
| 239 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id, | 239 GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id, |
| 240 const std::string& title) { | 240 const std::string& title) { |
| 241 ScopedVector<google_apis::ResourceEntry> entries; | 241 ScopedVector<google_apis::ResourceEntry> entries; |
| 242 EXPECT_EQ(google_apis::HTTP_SUCCESS, | 242 EXPECT_EQ(google_apis::HTTP_SUCCESS, |
| 243 fake_drive_helper_->SearchByTitle( | 243 fake_drive_helper_->SearchByTitle( |
| 244 parent_folder_id, title, &entries)); | 244 parent_folder_id, title, &entries)); |
| 245 return entries.Pass(); | 245 return entries.Pass(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 void VerifyConflictResolution(const std::string& parent_folder_id, | 248 void VerifyConflictResolution( |
| 249 const std::string& title, | 249 const std::string& parent_folder_id, |
| 250 const std::string& primary_file_id, | 250 const std::string& title, |
| 251 google_apis::DriveEntryKind kind) { | 251 const std::string& primary_file_id, |
| 252 google_apis::ResourceEntry::ResourceEntryKind kind) { |
| 252 ScopedVector<google_apis::ResourceEntry> entries; | 253 ScopedVector<google_apis::ResourceEntry> entries; |
| 253 EXPECT_EQ(google_apis::HTTP_SUCCESS, | 254 EXPECT_EQ(google_apis::HTTP_SUCCESS, |
| 254 fake_drive_helper_->SearchByTitle( | 255 fake_drive_helper_->SearchByTitle( |
| 255 parent_folder_id, title, &entries)); | 256 parent_folder_id, title, &entries)); |
| 256 ASSERT_EQ(1u, entries.size()); | 257 ASSERT_EQ(1u, entries.size()); |
| 257 EXPECT_EQ(primary_file_id, entries[0]->resource_id()); | 258 EXPECT_EQ(primary_file_id, entries[0]->resource_id()); |
| 258 EXPECT_EQ(kind, entries[0]->kind()); | 259 EXPECT_EQ(kind, entries[0]->kind()); |
| 259 } | 260 } |
| 260 | 261 |
| 261 void VerifyLocalChangeConsistency( | 262 void VerifyLocalChangeConsistency( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 305 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 305 RunRemoteToLocalSyncerUntilIdle(); | 306 RunRemoteToLocalSyncerUntilIdle(); |
| 306 | 307 |
| 307 ScopedVector<google_apis::ResourceEntry> entries = | 308 ScopedVector<google_apis::ResourceEntry> entries = |
| 308 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 309 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 309 ASSERT_EQ(4u, entries.size()); | 310 ASSERT_EQ(4u, entries.size()); |
| 310 | 311 |
| 311 // Only primary file should survive. | 312 // Only primary file should survive. |
| 312 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 313 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 313 VerifyConflictResolution(app_root, kTitle, primary, | 314 VerifyConflictResolution(app_root, kTitle, primary, |
| 314 google_apis::ENTRY_KIND_FILE); | 315 google_apis::ResourceEntry::ENTRY_KIND_FILE); |
| 315 } | 316 } |
| 316 | 317 |
| 317 TEST_F(ConflictResolverTest, ResolveConflict_Folders) { | 318 TEST_F(ConflictResolverTest, ResolveConflict_Folders) { |
| 318 const GURL kOrigin("chrome-extension://example"); | 319 const GURL kOrigin("chrome-extension://example"); |
| 319 const std::string sync_root = CreateSyncRoot(); | 320 const std::string sync_root = CreateSyncRoot(); |
| 320 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 321 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 321 InitializeMetadataDatabase(); | 322 InitializeMetadataDatabase(); |
| 322 RegisterApp(kOrigin.host(), app_root); | 323 RegisterApp(kOrigin.host(), app_root); |
| 323 RunRemoteToLocalSyncerUntilIdle(); | 324 RunRemoteToLocalSyncerUntilIdle(); |
| 324 | 325 |
| 325 const std::string kTitle = "foo"; | 326 const std::string kTitle = "foo"; |
| 326 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 327 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 327 CreateRemoteFolder(app_root, kTitle); | 328 CreateRemoteFolder(app_root, kTitle); |
| 328 CreateRemoteFolder(app_root, kTitle); | 329 CreateRemoteFolder(app_root, kTitle); |
| 329 CreateRemoteFolder(app_root, kTitle); | 330 CreateRemoteFolder(app_root, kTitle); |
| 330 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 331 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 331 RunRemoteToLocalSyncerUntilIdle(); | 332 RunRemoteToLocalSyncerUntilIdle(); |
| 332 | 333 |
| 333 ScopedVector<google_apis::ResourceEntry> entries = | 334 ScopedVector<google_apis::ResourceEntry> entries = |
| 334 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 335 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 335 ASSERT_EQ(4u, entries.size()); | 336 ASSERT_EQ(4u, entries.size()); |
| 336 | 337 |
| 337 // Only primary file should survive. | 338 // Only primary file should survive. |
| 338 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 339 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 339 VerifyConflictResolution(app_root, kTitle, primary, | 340 VerifyConflictResolution(app_root, kTitle, primary, |
| 340 google_apis::ENTRY_KIND_FOLDER); | 341 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); |
| 341 } | 342 } |
| 342 | 343 |
| 343 TEST_F(ConflictResolverTest, ResolveConflict_FilesAndFolders) { | 344 TEST_F(ConflictResolverTest, ResolveConflict_FilesAndFolders) { |
| 344 const GURL kOrigin("chrome-extension://example"); | 345 const GURL kOrigin("chrome-extension://example"); |
| 345 const std::string sync_root = CreateSyncRoot(); | 346 const std::string sync_root = CreateSyncRoot(); |
| 346 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 347 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 347 InitializeMetadataDatabase(); | 348 InitializeMetadataDatabase(); |
| 348 RegisterApp(kOrigin.host(), app_root); | 349 RegisterApp(kOrigin.host(), app_root); |
| 349 RunRemoteToLocalSyncerUntilIdle(); | 350 RunRemoteToLocalSyncerUntilIdle(); |
| 350 | 351 |
| 351 const std::string kTitle = "foo"; | 352 const std::string kTitle = "foo"; |
| 352 CreateRemoteFile(app_root, kTitle, "data"); | 353 CreateRemoteFile(app_root, kTitle, "data"); |
| 353 const std::string primary = CreateRemoteFolder(app_root, kTitle); | 354 const std::string primary = CreateRemoteFolder(app_root, kTitle); |
| 354 CreateRemoteFile(app_root, kTitle, "data2"); | 355 CreateRemoteFile(app_root, kTitle, "data2"); |
| 355 CreateRemoteFolder(app_root, kTitle); | 356 CreateRemoteFolder(app_root, kTitle); |
| 356 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 357 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 357 RunRemoteToLocalSyncerUntilIdle(); | 358 RunRemoteToLocalSyncerUntilIdle(); |
| 358 | 359 |
| 359 ScopedVector<google_apis::ResourceEntry> entries = | 360 ScopedVector<google_apis::ResourceEntry> entries = |
| 360 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 361 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 361 ASSERT_EQ(4u, entries.size()); | 362 ASSERT_EQ(4u, entries.size()); |
| 362 | 363 |
| 363 // Only primary file should survive. | 364 // Only primary file should survive. |
| 364 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 365 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 365 VerifyConflictResolution(app_root, kTitle, primary, | 366 VerifyConflictResolution(app_root, kTitle, primary, |
| 366 google_apis::ENTRY_KIND_FOLDER); | 367 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); |
| 367 } | 368 } |
| 368 | 369 |
| 369 TEST_F(ConflictResolverTest, ResolveConflict_RemoteFolderOnLocalFile) { | 370 TEST_F(ConflictResolverTest, ResolveConflict_RemoteFolderOnLocalFile) { |
| 370 const GURL kOrigin("chrome-extension://example"); | 371 const GURL kOrigin("chrome-extension://example"); |
| 371 const std::string sync_root = CreateSyncRoot(); | 372 const std::string sync_root = CreateSyncRoot(); |
| 372 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); | 373 const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host()); |
| 373 InitializeMetadataDatabase(); | 374 InitializeMetadataDatabase(); |
| 374 RegisterApp(kOrigin.host(), app_root); | 375 RegisterApp(kOrigin.host(), app_root); |
| 375 RunRemoteToLocalSyncerUntilIdle(); | 376 RunRemoteToLocalSyncerUntilIdle(); |
| 376 | 377 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 388 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 389 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 389 RunRemoteToLocalSyncerUntilIdle(); | 390 RunRemoteToLocalSyncerUntilIdle(); |
| 390 | 391 |
| 391 ScopedVector<google_apis::ResourceEntry> entries = | 392 ScopedVector<google_apis::ResourceEntry> entries = |
| 392 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 393 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 393 ASSERT_EQ(2u, entries.size()); | 394 ASSERT_EQ(2u, entries.size()); |
| 394 | 395 |
| 395 // Run conflict resolver. Only primary file should survive. | 396 // Run conflict resolver. Only primary file should survive. |
| 396 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 397 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 397 VerifyConflictResolution(app_root, kTitle, primary, | 398 VerifyConflictResolution(app_root, kTitle, primary, |
| 398 google_apis::ENTRY_KIND_FOLDER); | 399 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); |
| 399 | 400 |
| 400 // Continue to run remote-to-local sync. | 401 // Continue to run remote-to-local sync. |
| 401 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 402 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 402 RunRemoteToLocalSyncerUntilIdle(); | 403 RunRemoteToLocalSyncerUntilIdle(); |
| 403 | 404 |
| 404 // Verify that the local side has been synced to the same state | 405 // Verify that the local side has been synced to the same state |
| 405 // (i.e. file deletion and folder creation). | 406 // (i.e. file deletion and folder creation). |
| 406 URLToFileChangesMap expected_changes; | 407 URLToFileChangesMap expected_changes; |
| 407 expected_changes[kURL].push_back( | 408 expected_changes[kURL].push_back( |
| 408 FileChange(FileChange::FILE_CHANGE_DELETE, | 409 FileChange(FileChange::FILE_CHANGE_DELETE, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 436 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 437 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 437 RunRemoteToLocalSyncerUntilIdle(); | 438 RunRemoteToLocalSyncerUntilIdle(); |
| 438 | 439 |
| 439 ScopedVector<google_apis::ResourceEntry> entries = | 440 ScopedVector<google_apis::ResourceEntry> entries = |
| 440 GetResourceEntriesForParentAndTitle(app_root, kTitle); | 441 GetResourceEntriesForParentAndTitle(app_root, kTitle); |
| 441 ASSERT_EQ(2u, entries.size()); | 442 ASSERT_EQ(2u, entries.size()); |
| 442 | 443 |
| 443 // Run conflict resolver. Only primary file should survive. | 444 // Run conflict resolver. Only primary file should survive. |
| 444 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 445 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 445 VerifyConflictResolution(app_root, kTitle, primary, | 446 VerifyConflictResolution(app_root, kTitle, primary, |
| 446 google_apis::ENTRY_KIND_FOLDER); | 447 google_apis::ResourceEntry::ENTRY_KIND_FOLDER); |
| 447 | 448 |
| 448 // Continue to run remote-to-local sync. | 449 // Continue to run remote-to-local sync. |
| 449 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); | 450 EXPECT_EQ(SYNC_STATUS_OK, ListChanges()); |
| 450 RunRemoteToLocalSyncerUntilIdle(); | 451 RunRemoteToLocalSyncerUntilIdle(); |
| 451 | 452 |
| 452 // Verify that the local side has been synced to the same state | 453 // Verify that the local side has been synced to the same state |
| 453 // (i.e. file deletion and folders creation). | 454 // (i.e. file deletion and folders creation). |
| 454 URLToFileChangesMap expected_changes; | 455 URLToFileChangesMap expected_changes; |
| 455 expected_changes[kURL].push_back( | 456 expected_changes[kURL].push_back( |
| 456 FileChange(FileChange::FILE_CHANGE_DELETE, | 457 FileChange(FileChange::FILE_CHANGE_DELETE, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 | 514 |
| 514 EXPECT_EQ(4, CountParents(file)); | 515 EXPECT_EQ(4, CountParents(file)); |
| 515 | 516 |
| 516 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); | 517 EXPECT_EQ(SYNC_STATUS_OK, RunConflictResolver()); |
| 517 | 518 |
| 518 EXPECT_EQ(1, CountParents(file)); | 519 EXPECT_EQ(1, CountParents(file)); |
| 519 } | 520 } |
| 520 | 521 |
| 521 } // namespace drive_backend | 522 } // namespace drive_backend |
| 522 } // namespace sync_file_system | 523 } // namespace sync_file_system |
| OLD | NEW |