Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <list> | 5 #include <list> |
| 6 #include <map> | 6 #include <map> |
| 7 | 7 |
| 8 #include "base/lock.h" | 8 #include "base/lock.h" |
| 9 #include "base/scoped_ptr.h" | 9 #include "base/scoped_ptr.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 using testing::_; | 26 using testing::_; |
| 27 using testing::AnyNumber; | 27 using testing::AnyNumber; |
| 28 using testing::Field; | 28 using testing::Field; |
| 29 | 29 |
| 30 namespace browser_sync { | 30 namespace browser_sync { |
| 31 using sessions::ErrorCounters; | 31 using sessions::ErrorCounters; |
| 32 using sessions::TestScopedSessionEventListener; | 32 using sessions::TestScopedSessionEventListener; |
| 33 using sessions::SyncSessionContext; | 33 using sessions::SyncSessionContext; |
| 34 using sessions::SyncSessionSnapshot; | 34 using sessions::SyncSessionSnapshot; |
| 35 using sessions::SyncerStatus; | 35 using sessions::SyncerStatus; |
| 36 using sessions::SyncSourceInfo; | |
| 36 | 37 |
| 37 typedef testing::Test SyncerThreadTest; | 38 typedef testing::Test SyncerThreadTest; |
| 38 typedef SyncerThread::WaitInterval WaitInterval; | 39 typedef SyncerThread::WaitInterval WaitInterval; |
| 39 | 40 |
| 40 ACTION_P(SignalEvent, event) { | 41 ACTION_P(SignalEvent, event) { |
| 41 event->Signal(); | 42 event->Signal(); |
| 42 } | 43 } |
| 43 | 44 |
| 44 SyncSessionSnapshot SessionSnapshotForTest( | 45 SyncSessionSnapshot SessionSnapshotForTest( |
| 45 int64 num_server_changes_remaining, | 46 int64 num_server_changes_remaining, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 if (!syncer_thread()->RequestResume()) | 163 if (!syncer_thread()->RequestResume()) |
| 163 return false; | 164 return false; |
| 164 return event.TimedWait(max_wait_time_); | 165 return event.TimedWait(max_wait_time_); |
| 165 } | 166 } |
| 166 | 167 |
| 167 void PreventThreadFromPolling() { | 168 void PreventThreadFromPolling() { |
| 168 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); | 169 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
| 169 syncer_thread()->SetSyncerShortPollInterval(poll_interval); | 170 syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
| 170 } | 171 } |
| 171 | 172 |
| 173 // Compare a provided SyncSouceInfo::ModelTypeMap to the pending nudge info | |
| 174 // stored in the SyncerThread vault. | |
| 175 bool CompareNudgeTypesToVault(const SyncSourceInfo::ModelTypeMap& lhs) { | |
| 176 const SyncSourceInfo::ModelTypeMap& vault_nudge_types = | |
| 177 syncer_thread()->vault_.pending_nudge_types_; | |
| 178 for (size_t i = syncable::FIRST_REAL_MODEL_TYPE; | |
|
akalin
2011/01/21 19:50:09
I'm pretty sure a std::map already has operator==
Nicolas Zea
2011/01/21 21:57:44
Done.
| |
| 179 i < syncable::MODEL_TYPE_COUNT; | |
| 180 ++i) { | |
| 181 syncable::ModelType type = syncable::ModelTypeFromInt(i); | |
| 182 SyncSourceInfo::ModelTypeMap::const_iterator payload = lhs.find(type); | |
| 183 if (payload != lhs.end()) { | |
| 184 if (vault_nudge_types.count(type) == 0 || | |
| 185 payload->second != vault_nudge_types.find(type)->second) { | |
| 186 return false; | |
| 187 } | |
| 188 } else if (vault_nudge_types.count(type) > 0) { | |
| 189 return false; | |
| 190 } | |
| 191 } | |
| 192 return true; | |
| 193 } | |
| 194 | |
| 195 // Compare a provided ModelTypeBitset to the pending nudge info stored in the | |
| 196 // SyncerThread vault. | |
| 197 bool CompareNudgeTypesBitSetToVault(const syncable::ModelTypeBitSet& lhs) { | |
|
akalin
2011/01/21 19:50:09
If you write the utility f'n to compare ModelTypeB
Nicolas Zea
2011/01/21 21:57:44
Done.
| |
| 198 const SyncSourceInfo::ModelTypeMap& vault_nudge_types = | |
| 199 syncer_thread()->vault_.pending_nudge_types_; | |
| 200 for (size_t i = syncable::FIRST_REAL_MODEL_TYPE; | |
| 201 i < syncable::MODEL_TYPE_COUNT; | |
| 202 ++i) { | |
| 203 syncable::ModelType type = syncable::ModelTypeFromInt(i); | |
| 204 if (lhs[i] && vault_nudge_types.count(type) == 0) { | |
| 205 return false; | |
| 206 } else if (!lhs[i] && vault_nudge_types.count(type) > 0) { | |
| 207 return false; | |
| 208 } | |
| 209 } | |
| 210 return true; | |
| 211 } | |
| 212 | |
| 213 | |
| 172 private: | 214 private: |
| 173 | 215 |
| 174 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) { | 216 virtual void OnSyncEngineEvent(const SyncEngineEvent& event) { |
| 175 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) | 217 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) |
| 176 sync_cycle_ended_event_.Signal(); | 218 sync_cycle_ended_event_.Signal(); |
| 177 } | 219 } |
| 178 | 220 |
| 179 protected: | 221 protected: |
| 180 TimeDelta max_wait_time_; | 222 TimeDelta max_wait_time_; |
| 181 SyncSessionContext* context_; | 223 SyncSessionContext* context_; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 false); | 503 false); |
| 462 | 504 |
| 463 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, | 505 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
| 464 interval.poll_delta.InSeconds()); | 506 interval.poll_delta.InSeconds()); |
| 465 ASSERT_EQ(WaitInterval::NORMAL, interval.mode); | 507 ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
| 466 ASSERT_FALSE(interval.had_nudge_during_backoff); | 508 ASSERT_FALSE(interval.had_nudge_during_backoff); |
| 467 ASSERT_FALSE(continue_sync_cycle_param); | 509 ASSERT_FALSE(continue_sync_cycle_param); |
| 468 } | 510 } |
| 469 | 511 |
| 470 { | 512 { |
| 471 | |
| 472 // Now try with unsynced local items. | 513 // Now try with unsynced local items. |
| 473 context->set_last_snapshot(SessionSnapshotForTest(0, 1)); | 514 context->set_last_snapshot(SessionSnapshotForTest(0, 1)); |
| 474 bool continue_sync_cycle_param = false; | 515 bool continue_sync_cycle_param = false; |
| 475 | 516 |
| 476 WaitInterval interval = syncer_thread->CalculatePollingWaitTime( | 517 WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
| 477 0, | 518 0, |
| 478 &user_idle_milliseconds_param, | 519 &user_idle_milliseconds_param, |
| 479 &continue_sync_cycle_param, | 520 &continue_sync_cycle_param, |
| 480 false); | 521 false); |
| 481 | 522 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 505 | 546 |
| 506 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, | 547 ASSERT_EQ(SyncerThread::kDefaultLongPollIntervalSeconds, |
| 507 interval.poll_delta.InSeconds()); | 548 interval.poll_delta.InSeconds()); |
| 508 ASSERT_EQ(WaitInterval::NORMAL, interval.mode); | 549 ASSERT_EQ(WaitInterval::NORMAL, interval.mode); |
| 509 ASSERT_FALSE(interval.had_nudge_during_backoff); | 550 ASSERT_FALSE(interval.had_nudge_during_backoff); |
| 510 ASSERT_FALSE(continue_sync_cycle_param); | 551 ASSERT_FALSE(continue_sync_cycle_param); |
| 511 } | 552 } |
| 512 | 553 |
| 513 // Regression for exponential backoff reset when the syncer is nudged. | 554 // Regression for exponential backoff reset when the syncer is nudged. |
| 514 { | 555 { |
| 515 | |
| 516 context->set_last_snapshot(SessionSnapshotForTest(0, 1)); | 556 context->set_last_snapshot(SessionSnapshotForTest(0, 1)); |
| 517 bool continue_sync_cycle_param = false; | 557 bool continue_sync_cycle_param = false; |
| 518 | 558 |
| 519 // Expect move from default polling interval to exponential backoff due to | 559 // Expect move from default polling interval to exponential backoff due to |
| 520 // unsynced_count != 0. | 560 // unsynced_count != 0. |
| 521 WaitInterval interval = syncer_thread->CalculatePollingWaitTime( | 561 WaitInterval interval = syncer_thread->CalculatePollingWaitTime( |
| 522 3600, | 562 3600, |
| 523 &user_idle_milliseconds_param, | 563 &user_idle_milliseconds_param, |
| 524 &continue_sync_cycle_param, | 564 &continue_sync_cycle_param, |
| 525 false); | 565 false); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 725 // The SyncerThread should be waiting for the poll now. Nudge it to sync | 765 // The SyncerThread should be waiting for the poll now. Nudge it to sync |
| 726 // immediately (5ms). | 766 // immediately (5ms). |
| 727 syncable::ModelTypeBitSet model_types; | 767 syncable::ModelTypeBitSet model_types; |
| 728 model_types[syncable::BOOKMARKS] = true; | 768 model_types[syncable::BOOKMARKS] = true; |
| 729 | 769 |
| 730 // Paused so we can verify the nudge types safely. | 770 // Paused so we can verify the nudge types safely. |
| 731 syncer_thread()->RequestPause(); | 771 syncer_thread()->RequestPause(); |
| 732 syncer_thread()->NudgeSyncerWithDataTypes(5, | 772 syncer_thread()->NudgeSyncerWithDataTypes(5, |
| 733 SyncerThread::kUnknown, | 773 SyncerThread::kUnknown, |
| 734 model_types); | 774 model_types); |
| 735 EXPECT_EQ(model_types, syncer_thread()->vault_.pending_nudge_types_); | 775 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
| 736 syncer_thread()->RequestResume(); | 776 syncer_thread()->RequestResume(); |
| 737 | 777 |
| 738 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); | 778 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
| 739 EXPECT_EQ(static_cast<unsigned int>(2), | 779 EXPECT_EQ(static_cast<unsigned int>(2), |
| 740 interceptor.times_sync_occured().size()); | 780 interceptor.times_sync_occured().size()); |
| 741 | 781 |
| 742 // SyncerThread should be waiting again. Signal it to stop. | 782 // SyncerThread should be waiting again. Signal it to stop. |
| 743 EXPECT_TRUE(syncer_thread()->Stop(2000)); | 783 EXPECT_TRUE(syncer_thread()->Stop(2000)); |
| 744 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.none()); | 784 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
| 745 } | 785 } |
| 746 | 786 |
| 747 TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypesCoalesced) { | 787 TEST_F(SyncerThreadWithSyncerTest, NudgeWithDataTypesCoalesced) { |
| 748 SyncShareIntercept interceptor; | 788 SyncShareIntercept interceptor; |
| 749 connection()->SetMidCommitObserver(&interceptor); | 789 connection()->SetMidCommitObserver(&interceptor); |
| 750 // We don't want a poll to happen during this test (except the first one). | 790 // We don't want a poll to happen during this test (except the first one). |
| 751 PreventThreadFromPolling(); | 791 PreventThreadFromPolling(); |
| 752 EXPECT_TRUE(syncer_thread()->Start()); | 792 EXPECT_TRUE(syncer_thread()->Start()); |
| 753 metadb()->Open(); | 793 metadb()->Open(); |
| 754 syncer_thread()->CreateSyncer(metadb()->name()); | 794 syncer_thread()->CreateSyncer(metadb()->name()); |
| 755 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); | 795 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); |
| 756 interceptor.WaitForSyncShare(1, poll_interval + poll_interval); | 796 interceptor.WaitForSyncShare(1, poll_interval + poll_interval); |
| 757 EXPECT_EQ(static_cast<unsigned int>(1), | 797 EXPECT_EQ(static_cast<unsigned int>(1), |
| 758 interceptor.times_sync_occured().size()); | 798 interceptor.times_sync_occured().size()); |
| 759 | 799 |
| 760 // The SyncerThread should be waiting for the poll now. Nudge it to sync | 800 // The SyncerThread should be waiting for the poll now. Nudge it to sync |
| 761 // immediately (5ms). | 801 // immediately (5ms). |
| 762 syncable::ModelTypeBitSet model_types; | 802 syncable::ModelTypeBitSet model_types; |
| 763 model_types[syncable::BOOKMARKS] = true; | 803 model_types[syncable::BOOKMARKS] = true; |
| 764 | 804 |
| 765 // Paused so we can verify the nudge types safely. | 805 // Paused so we can verify the nudge types safely. |
| 766 syncer_thread()->RequestPause(); | 806 syncer_thread()->RequestPause(); |
| 767 syncer_thread()->NudgeSyncerWithDataTypes(100, | 807 syncer_thread()->NudgeSyncerWithDataTypes(100, |
| 768 SyncerThread::kUnknown, | 808 SyncerThread::kUnknown, |
| 769 model_types); | 809 model_types); |
| 770 EXPECT_EQ(model_types, syncer_thread()->vault_.pending_nudge_types_); | 810 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
| 771 | 811 |
| 772 model_types[syncable::BOOKMARKS] = false; | 812 model_types[syncable::BOOKMARKS] = false; |
| 773 model_types[syncable::AUTOFILL] = true; | 813 model_types[syncable::AUTOFILL] = true; |
| 774 syncer_thread()->NudgeSyncerWithDataTypes(0, | 814 syncer_thread()->NudgeSyncerWithDataTypes(0, |
| 775 SyncerThread::kUnknown, | 815 SyncerThread::kUnknown, |
| 776 model_types); | 816 model_types); |
| 777 | 817 |
| 778 // Reset BOOKMARKS for expectations. | 818 // Reset BOOKMARKS for expectations. |
| 779 model_types[syncable::BOOKMARKS] = true; | 819 model_types[syncable::BOOKMARKS] = true; |
| 780 EXPECT_EQ(model_types, syncer_thread()->vault_.pending_nudge_types_); | 820 EXPECT_TRUE(CompareNudgeTypesBitSetToVault(model_types)); |
| 781 | 821 |
| 782 syncer_thread()->RequestResume(); | 822 syncer_thread()->RequestResume(); |
| 783 | 823 |
| 784 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); | 824 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); |
| 785 EXPECT_EQ(static_cast<unsigned int>(2), | 825 EXPECT_EQ(static_cast<unsigned int>(2), |
| 786 interceptor.times_sync_occured().size()); | 826 interceptor.times_sync_occured().size()); |
| 787 | 827 |
| 788 // SyncerThread should be waiting again. Signal it to stop. | 828 // SyncerThread should be waiting again. Signal it to stop. |
| 789 EXPECT_TRUE(syncer_thread()->Stop(2000)); | 829 EXPECT_TRUE(syncer_thread()->Stop(2000)); |
| 790 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.none()); | 830 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); |
| 831 } | |
| 832 | |
| 833 TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloads) { | |
| 834 SyncShareIntercept interceptor; | |
| 835 connection()->SetMidCommitObserver(&interceptor); | |
| 836 // We don't want a poll to happen during this test (except the first one). | |
| 837 PreventThreadFromPolling(); | |
| 838 EXPECT_TRUE(syncer_thread()->Start()); | |
| 839 metadb()->Open(); | |
| 840 syncer_thread()->CreateSyncer(metadb()->name()); | |
| 841 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); | |
| 842 interceptor.WaitForSyncShare(1, poll_interval + poll_interval); | |
| 843 EXPECT_EQ(static_cast<unsigned int>(1), | |
| 844 interceptor.times_sync_occured().size()); | |
| 845 | |
| 846 // The SyncerThread should be waiting for the poll now. Nudge it to sync | |
| 847 // immediately (5ms). | |
| 848 SyncSourceInfo::ModelTypeMap nudge_types; | |
| 849 nudge_types[syncable::BOOKMARKS] = "test"; | |
| 850 | |
| 851 // Paused so we can verify the nudge types safely. | |
| 852 syncer_thread()->RequestPause(); | |
| 853 syncer_thread()->NudgeSyncerWithPayloads(5, | |
| 854 SyncerThread::kUnknown, | |
| 855 nudge_types); | |
| 856 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); | |
| 857 syncer_thread()->RequestResume(); | |
| 858 | |
| 859 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); | |
| 860 EXPECT_EQ(static_cast<unsigned int>(2), | |
| 861 interceptor.times_sync_occured().size()); | |
| 862 | |
| 863 // SyncerThread should be waiting again. Signal it to stop. | |
| 864 EXPECT_TRUE(syncer_thread()->Stop(2000)); | |
| 865 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); | |
| 866 } | |
| 867 | |
| 868 TEST_F(SyncerThreadWithSyncerTest, NudgeWithPayloadsCoalesced) { | |
| 869 SyncShareIntercept interceptor; | |
| 870 connection()->SetMidCommitObserver(&interceptor); | |
| 871 // We don't want a poll to happen during this test (except the first one). | |
| 872 PreventThreadFromPolling(); | |
| 873 EXPECT_TRUE(syncer_thread()->Start()); | |
| 874 metadb()->Open(); | |
| 875 syncer_thread()->CreateSyncer(metadb()->name()); | |
| 876 const TimeDelta poll_interval = TimeDelta::FromMinutes(5); | |
| 877 interceptor.WaitForSyncShare(1, poll_interval + poll_interval); | |
| 878 EXPECT_EQ(static_cast<unsigned int>(1), | |
| 879 interceptor.times_sync_occured().size()); | |
| 880 | |
| 881 // The SyncerThread should be waiting for the poll now. Nudge it to sync | |
| 882 // immediately (5ms). | |
| 883 SyncSourceInfo::ModelTypeMap nudge_types; | |
| 884 nudge_types[syncable::BOOKMARKS] = "books"; | |
| 885 | |
| 886 // Paused so we can verify the nudge types safely. | |
| 887 syncer_thread()->RequestPause(); | |
| 888 syncer_thread()->NudgeSyncerWithPayloads(100, | |
| 889 SyncerThread::kUnknown, | |
| 890 nudge_types); | |
| 891 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); | |
| 892 | |
| 893 nudge_types.erase(syncable::BOOKMARKS); | |
| 894 nudge_types[syncable::AUTOFILL] = "auto"; | |
| 895 syncer_thread()->NudgeSyncerWithPayloads(0, | |
| 896 SyncerThread::kUnknown, | |
| 897 nudge_types); | |
| 898 | |
| 899 // Reset BOOKMARKS for expectations. | |
| 900 nudge_types[syncable::BOOKMARKS] = "books"; | |
| 901 EXPECT_TRUE(CompareNudgeTypesToVault(nudge_types)); | |
| 902 | |
| 903 syncer_thread()->RequestResume(); | |
| 904 | |
| 905 interceptor.WaitForSyncShare(1, TimeDelta::FromSeconds(1)); | |
| 906 EXPECT_EQ(static_cast<unsigned int>(2), | |
| 907 interceptor.times_sync_occured().size()); | |
| 908 | |
| 909 // SyncerThread should be waiting again. Signal it to stop. | |
| 910 EXPECT_TRUE(syncer_thread()->Stop(2000)); | |
| 911 EXPECT_TRUE(syncer_thread()->vault_.pending_nudge_types_.empty()); | |
| 791 } | 912 } |
| 792 | 913 |
| 793 TEST_F(SyncerThreadWithSyncerTest, Throttling) { | 914 TEST_F(SyncerThreadWithSyncerTest, Throttling) { |
| 794 SyncShareIntercept interceptor; | 915 SyncShareIntercept interceptor; |
| 795 connection()->SetMidCommitObserver(&interceptor); | 916 connection()->SetMidCommitObserver(&interceptor); |
| 796 const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10); | 917 const TimeDelta poll_interval = TimeDelta::FromMilliseconds(10); |
| 797 syncer_thread()->SetSyncerShortPollInterval(poll_interval); | 918 syncer_thread()->SetSyncerShortPollInterval(poll_interval); |
| 798 | 919 |
| 799 EXPECT_TRUE(syncer_thread()->Start()); | 920 EXPECT_TRUE(syncer_thread()->Start()); |
| 800 metadb()->Open(); | 921 metadb()->Open(); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1126 EXPECT_CALL(listener, OnSyncEngineEvent( | 1247 EXPECT_CALL(listener, OnSyncEngineEvent( |
| 1127 Field(&SyncEngineEvent::what_happened, | 1248 Field(&SyncEngineEvent::what_happened, |
| 1128 SyncEngineEvent::SYNCER_THREAD_EXITING))); | 1249 SyncEngineEvent::SYNCER_THREAD_EXITING))); |
| 1129 | 1250 |
| 1130 ASSERT_TRUE(Resume(&listener)); | 1251 ASSERT_TRUE(Resume(&listener)); |
| 1131 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); | 1252 ASSERT_TRUE(sync_cycle_ended_event.TimedWait(max_wait_time_)); |
| 1132 EXPECT_TRUE(syncer_thread()->Stop(2000)); | 1253 EXPECT_TRUE(syncer_thread()->Stop(2000)); |
| 1133 } | 1254 } |
| 1134 | 1255 |
| 1135 } // namespace browser_sync | 1256 } // namespace browser_sync |
| OLD | NEW |