| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Unit tests for the SyncApi. Note that a lot of the underlying | 5 // Unit tests for the SyncApi. Note that a lot of the underlying |
| 6 // functionality is provided by the Syncable layer, which has its own | 6 // functionality is provided by the Syncable layer, which has its own |
| 7 // unit tests. We'll test SyncApi specific things in this harness. | 7 // unit tests. We'll test SyncApi specific things in this harness. |
| 8 | 8 |
| 9 #include <cstddef> | 9 #include <cstddef> |
| 10 #include <map> | 10 #include <map> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 15 #include "base/format_macros.h" | 15 #include "base/format_macros.h" |
| 16 #include "base/location.h" | 16 #include "base/location.h" |
| 17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/message_loop.h" | 18 #include "base/message_loop.h" |
| 19 #include "base/message_loop_proxy.h" | 19 #include "base/message_loop_proxy.h" |
| 20 #include "base/scoped_temp_dir.h" | 20 #include "base/scoped_temp_dir.h" |
| 21 #include "base/string_number_conversions.h" | 21 #include "base/string_number_conversions.h" |
| 22 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
| 23 #include "base/test/values_test_util.h" | 23 #include "base/test/values_test_util.h" |
| 24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
| 25 #include "base/values.h" | 25 #include "base/values.h" |
| 26 #include "sync/internal_api/public/base/model_type_test_util.h" | 26 #include "sync/internal_api/public/base/model_type_test_util.h" |
| 27 #include "sync/engine/sync_scheduler.h" | |
| 28 #include "sync/internal_api/public/change_record.h" | 27 #include "sync/internal_api/public/change_record.h" |
| 29 #include "sync/internal_api/public/engine/model_safe_worker.h" | 28 #include "sync/internal_api/public/engine/model_safe_worker.h" |
| 30 #include "sync/internal_api/public/engine/polling_constants.h" | 29 #include "sync/internal_api/public/engine/polling_constants.h" |
| 31 #include "sync/internal_api/public/http_post_provider_factory.h" | 30 #include "sync/internal_api/public/http_post_provider_factory.h" |
| 32 #include "sync/internal_api/public/http_post_provider_interface.h" | 31 #include "sync/internal_api/public/http_post_provider_interface.h" |
| 33 #include "sync/internal_api/public/read_node.h" | 32 #include "sync/internal_api/public/read_node.h" |
| 34 #include "sync/internal_api/public/read_transaction.h" | 33 #include "sync/internal_api/public/read_transaction.h" |
| 35 #include "sync/internal_api/public/sync_manager.h" | 34 #include "sync/internal_api/public/sync_manager.h" |
| 36 #include "sync/internal_api/public/test/test_user_share.h" | 35 #include "sync/internal_api/public/test/test_user_share.h" |
| 37 #include "sync/internal_api/public/write_node.h" | 36 #include "sync/internal_api/public/write_node.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 51 #include "sync/protocol/preference_specifics.pb.h" | 50 #include "sync/protocol/preference_specifics.pb.h" |
| 52 #include "sync/protocol/proto_value_conversions.h" | 51 #include "sync/protocol/proto_value_conversions.h" |
| 53 #include "sync/protocol/sync.pb.h" | 52 #include "sync/protocol/sync.pb.h" |
| 54 #include "sync/sessions/sync_session.h" | 53 #include "sync/sessions/sync_session.h" |
| 55 #include "sync/syncable/directory.h" | 54 #include "sync/syncable/directory.h" |
| 56 #include "sync/syncable/entry.h" | 55 #include "sync/syncable/entry.h" |
| 57 #include "sync/syncable/mutable_entry.h" | 56 #include "sync/syncable/mutable_entry.h" |
| 58 #include "sync/syncable/nigori_util.h" | 57 #include "sync/syncable/nigori_util.h" |
| 59 #include "sync/syncable/syncable_id.h" | 58 #include "sync/syncable/syncable_id.h" |
| 60 #include "sync/syncable/write_transaction.h" | 59 #include "sync/syncable/write_transaction.h" |
| 61 #include "sync/test/callback_counter.h" | |
| 62 #include "sync/test/fake_encryptor.h" | 60 #include "sync/test/fake_encryptor.h" |
| 63 #include "sync/test/fake_extensions_activity_monitor.h" | 61 #include "sync/test/fake_extensions_activity_monitor.h" |
| 64 #include "sync/util/cryptographer.h" | 62 #include "sync/util/cryptographer.h" |
| 65 #include "sync/util/extensions_activity_monitor.h" | 63 #include "sync/util/extensions_activity_monitor.h" |
| 66 #include "sync/util/test_unrecoverable_error_handler.h" | 64 #include "sync/util/test_unrecoverable_error_handler.h" |
| 67 #include "sync/util/time.h" | 65 #include "sync/util/time.h" |
| 68 #include "testing/gmock/include/gmock/gmock.h" | 66 #include "testing/gmock/include/gmock/gmock.h" |
| 69 #include "testing/gtest/include/gtest/gtest.h" | 67 #include "testing/gtest/include/gtest/gtest.h" |
| 70 | 68 |
| 71 using base::ExpectDictStringValue; | 69 using base::ExpectDictStringValue; |
| 72 using testing::_; | 70 using testing::_; |
| 73 using testing::AnyNumber; | 71 using testing::AnyNumber; |
| 74 using testing::AtLeast; | 72 using testing::AtLeast; |
| 75 using testing::DoAll; | |
| 76 using testing::InSequence; | 73 using testing::InSequence; |
| 77 using testing::Invoke; | 74 using testing::Invoke; |
| 78 using testing::Return; | |
| 79 using testing::SaveArg; | 75 using testing::SaveArg; |
| 80 using testing::StrictMock; | 76 using testing::StrictMock; |
| 81 | 77 |
| 82 namespace syncer { | 78 namespace syncer { |
| 83 | 79 |
| 84 using sessions::SyncSessionSnapshot; | 80 using sessions::SyncSessionSnapshot; |
| 85 using syncable::IS_DEL; | 81 using syncable::IS_DEL; |
| 86 using syncable::IS_UNSYNCED; | 82 using syncable::IS_UNSYNCED; |
| 87 using syncable::kEncryptedString; | 83 using syncable::kEncryptedString; |
| 88 using syncable::NON_UNIQUE_NAME; | 84 using syncable::NON_UNIQUE_NAME; |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 const std::string hash = BaseNode::GenerateSyncableHash(type, client_tag); | 899 const std::string hash = BaseNode::GenerateSyncableHash(type, client_tag); |
| 904 syncable::MutableEntry entry(&trans, syncable::GET_BY_CLIENT_TAG, | 900 syncable::MutableEntry entry(&trans, syncable::GET_BY_CLIENT_TAG, |
| 905 hash); | 901 hash); |
| 906 EXPECT_TRUE(entry.good()); | 902 EXPECT_TRUE(entry.good()); |
| 907 if (!entry.Get(IS_UNSYNCED)) | 903 if (!entry.Get(IS_UNSYNCED)) |
| 908 return false; | 904 return false; |
| 909 entry.Put(IS_UNSYNCED, false); | 905 entry.Put(IS_UNSYNCED, false); |
| 910 return true; | 906 return true; |
| 911 } | 907 } |
| 912 | 908 |
| 913 void SetScheduler(scoped_ptr<SyncScheduler> scheduler) { | |
| 914 sync_manager_.SetSyncSchedulerForTest(scheduler.Pass()); | |
| 915 } | |
| 916 | |
| 917 private: | 909 private: |
| 918 // Needed by |sync_manager_|. | 910 // Needed by |sync_manager_|. |
| 919 MessageLoop message_loop_; | 911 MessageLoop message_loop_; |
| 920 // Needed by |sync_manager_|. | 912 // Needed by |sync_manager_|. |
| 921 ScopedTempDir temp_dir_; | 913 ScopedTempDir temp_dir_; |
| 922 // Sync Id's for the roots of the enabled datatypes. | 914 // Sync Id's for the roots of the enabled datatypes. |
| 923 std::map<ModelType, int64> type_roots_; | 915 std::map<ModelType, int64> type_roots_; |
| 924 FakeExtensionsActivityMonitor extensions_activity_monitor_; | 916 FakeExtensionsActivityMonitor extensions_activity_monitor_; |
| 925 StrictMock<SyncNotifierMock>* sync_notifier_mock_; | 917 StrictMock<SyncNotifierMock>* sync_notifier_mock_; |
| 926 | 918 |
| (...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2486 node.InitByClientTagLookup(syncer::BOOKMARKS, client_tag)); | 2478 node.InitByClientTagLookup(syncer::BOOKMARKS, client_tag)); |
| 2487 EXPECT_EQ(title, node.GetTitle()); | 2479 EXPECT_EQ(title, node.GetTitle()); |
| 2488 EXPECT_EQ(GURL(url2), node.GetURL()); | 2480 EXPECT_EQ(GURL(url2), node.GetURL()); |
| 2489 const syncable::Entry* node_entry = node.GetEntry(); | 2481 const syncable::Entry* node_entry = node.GetEntry(); |
| 2490 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); | 2482 EXPECT_EQ(kEncryptedString, node_entry->Get(NON_UNIQUE_NAME)); |
| 2491 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); | 2483 const sync_pb::EntitySpecifics& specifics = node_entry->Get(SPECIFICS); |
| 2492 EXPECT_TRUE(specifics.has_encrypted()); | 2484 EXPECT_TRUE(specifics.has_encrypted()); |
| 2493 } | 2485 } |
| 2494 } | 2486 } |
| 2495 | 2487 |
| 2496 class MockSyncScheduler : public SyncScheduler { | 2488 } // namespace syncer |
| 2497 public: | |
| 2498 MockSyncScheduler() : SyncScheduler("name", NULL, NULL) {} | |
| 2499 virtual ~MockSyncScheduler() {} | |
| 2500 | |
| 2501 MOCK_METHOD1(Start, void(SyncScheduler::Mode)); | |
| 2502 MOCK_METHOD1(ScheduleConfiguration, bool(const ConfigurationParams&)); | |
| 2503 }; | |
| 2504 | |
| 2505 // Test that the configuration params are properly created and sent to | |
| 2506 // ScheduleConfigure. No callback should be invoked. | |
| 2507 TEST_F(SyncManagerTest, BasicConfiguration) { | |
| 2508 ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; | |
| 2509 syncer::ModelTypeSet types_to_download(syncer::BOOKMARKS, | |
| 2510 syncer::PREFERENCES); | |
| 2511 syncer::ModelSafeRoutingInfo new_routing_info; | |
| 2512 GetModelSafeRoutingInfo(&new_routing_info); | |
| 2513 | |
| 2514 scoped_ptr<MockSyncScheduler> scheduler(new MockSyncScheduler()); | |
| 2515 ConfigurationParams params; | |
| 2516 EXPECT_CALL(*scheduler, Start(SyncScheduler::CONFIGURATION_MODE)); | |
| 2517 EXPECT_CALL(*scheduler, ScheduleConfiguration(_)). | |
| 2518 WillOnce(DoAll(SaveArg<0>(¶ms), Return(true))); | |
| 2519 SetScheduler(scheduler.PassAs<SyncScheduler>()); | |
| 2520 | |
| 2521 CallbackCounter ready_task_counter, retry_task_counter; | |
| 2522 sync_manager_.ConfigureSyncer( | |
| 2523 reason, | |
| 2524 types_to_download, | |
| 2525 new_routing_info, | |
| 2526 base::Bind(&CallbackCounter::Callback, | |
| 2527 base::Unretained(&ready_task_counter)), | |
| 2528 base::Bind(&CallbackCounter::Callback, | |
| 2529 base::Unretained(&retry_task_counter))); | |
| 2530 EXPECT_EQ(0, ready_task_counter.times_called()); | |
| 2531 EXPECT_EQ(0, retry_task_counter.times_called()); | |
| 2532 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, | |
| 2533 params.source); | |
| 2534 EXPECT_TRUE(types_to_download.Equals(params.types_to_download)); | |
| 2535 EXPECT_EQ(new_routing_info, params.routing_info); | |
| 2536 } | |
| 2537 | |
| 2538 // Test that the retry callback is invoked on configuration failure. | |
| 2539 TEST_F(SyncManagerTest, ConfigurationRetry) { | |
| 2540 ConfigureReason reason = CONFIGURE_REASON_RECONFIGURATION; | |
| 2541 syncer::ModelTypeSet types_to_download(syncer::BOOKMARKS, | |
| 2542 syncer::PREFERENCES); | |
| 2543 syncer::ModelSafeRoutingInfo new_routing_info; | |
| 2544 GetModelSafeRoutingInfo(&new_routing_info); | |
| 2545 | |
| 2546 scoped_ptr<MockSyncScheduler> scheduler(new MockSyncScheduler()); | |
| 2547 ConfigurationParams params; | |
| 2548 EXPECT_CALL(*scheduler, Start(SyncScheduler::CONFIGURATION_MODE)); | |
| 2549 EXPECT_CALL(*scheduler, ScheduleConfiguration(_)). | |
| 2550 WillOnce(DoAll(SaveArg<0>(¶ms), Return(false))); | |
| 2551 SetScheduler(scheduler.PassAs<SyncScheduler>()); | |
| 2552 | |
| 2553 CallbackCounter ready_task_counter, retry_task_counter; | |
| 2554 sync_manager_.ConfigureSyncer( | |
| 2555 reason, | |
| 2556 types_to_download, | |
| 2557 new_routing_info, | |
| 2558 base::Bind(&CallbackCounter::Callback, | |
| 2559 base::Unretained(&ready_task_counter)), | |
| 2560 base::Bind(&CallbackCounter::Callback, | |
| 2561 base::Unretained(&retry_task_counter))); | |
| 2562 EXPECT_EQ(0, ready_task_counter.times_called()); | |
| 2563 EXPECT_EQ(1, retry_task_counter.times_called()); | |
| 2564 EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, | |
| 2565 params.source); | |
| 2566 EXPECT_TRUE(types_to_download.Equals(params.types_to_download)); | |
| 2567 EXPECT_EQ(new_routing_info, params.routing_info); | |
| 2568 } | |
| 2569 | |
| 2570 // Test that PurgePartiallySyncedTypes purges only those types that don't | |
| 2571 // have empty progress marker and don't have initial sync ended set. | |
| 2572 TEST_F(SyncManagerTest, PurgePartiallySyncedTypes) { | |
| 2573 UserShare* share = sync_manager_.GetUserShare(); | |
| 2574 | |
| 2575 // Set Nigori and Bookmarks to be partial types. | |
| 2576 sync_pb::DataTypeProgressMarker nigori_marker; | |
| 2577 nigori_marker.set_data_type_id( | |
| 2578 GetSpecificsFieldNumberFromModelType(NIGORI)); | |
| 2579 nigori_marker.set_token("token"); | |
| 2580 sync_pb::DataTypeProgressMarker bookmark_marker; | |
| 2581 bookmark_marker.set_data_type_id( | |
| 2582 GetSpecificsFieldNumberFromModelType(BOOKMARKS)); | |
| 2583 bookmark_marker.set_token("token"); | |
| 2584 share->directory->SetDownloadProgress(NIGORI, nigori_marker); | |
| 2585 share->directory->SetDownloadProgress(BOOKMARKS, bookmark_marker); | |
| 2586 | |
| 2587 // Set Preferences to be a full type. | |
| 2588 sync_pb::DataTypeProgressMarker pref_marker; | |
| 2589 pref_marker.set_data_type_id( | |
| 2590 GetSpecificsFieldNumberFromModelType(PREFERENCES)); | |
| 2591 pref_marker.set_token("token"); | |
| 2592 share->directory->SetDownloadProgress(PREFERENCES, pref_marker); | |
| 2593 share->directory->set_initial_sync_ended_for_type(PREFERENCES, true); | |
| 2594 | |
| 2595 ModelTypeSet partial_types = | |
| 2596 sync_manager_.GetTypesWithEmptyProgressMarkerToken(ModelTypeSet::All()); | |
| 2597 EXPECT_FALSE(partial_types.Has(NIGORI)); | |
| 2598 EXPECT_FALSE(partial_types.Has(BOOKMARKS)); | |
| 2599 EXPECT_FALSE(partial_types.Has(PREFERENCES)); | |
| 2600 | |
| 2601 EXPECT_TRUE(sync_manager_.PurgePartiallySyncedTypes()); | |
| 2602 | |
| 2603 // Ensure only bookmarks and nigori lost their progress marker. Preferences | |
| 2604 // should still have it. | |
| 2605 partial_types = | |
| 2606 sync_manager_.GetTypesWithEmptyProgressMarkerToken(ModelTypeSet::All()); | |
| 2607 EXPECT_TRUE(partial_types.Has(NIGORI)); | |
| 2608 EXPECT_TRUE(partial_types.Has(BOOKMARKS)); | |
| 2609 EXPECT_FALSE(partial_types.Has(PREFERENCES)); | |
| 2610 } | |
| 2611 | |
| 2612 } // namespace | |
| OLD | NEW |