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 |