| 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 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
| 11 #include "base/time.h" | 11 #include "base/time.h" |
| 12 #include "base/waitable_event.h" |
| 12 #include "chrome/browser/sync/engine/model_safe_worker.h" | 13 #include "chrome/browser/sync/engine/model_safe_worker.h" |
| 13 #include "chrome/browser/sync/engine/syncer_thread.h" | 14 #include "chrome/browser/sync/engine/syncer_thread.h" |
| 14 #include "chrome/browser/sync/engine/syncer_thread_timed_stop.h" | 15 #include "chrome/browser/sync/sessions/sync_session_context.h" |
| 15 #include "chrome/test/sync/engine/mock_server_connection.h" | 16 #include "chrome/test/sync/engine/mock_server_connection.h" |
| 16 #include "chrome/test/sync/engine/test_directory_setter_upper.h" | 17 #include "chrome/test/sync/engine/test_directory_setter_upper.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 19 |
| 19 using base::TimeTicks; | 20 using base::TimeTicks; |
| 20 using base::TimeDelta; | 21 using base::TimeDelta; |
| 21 | 22 |
| 22 namespace browser_sync { | 23 namespace browser_sync { |
| 24 using sessions::SyncSessionContext; |
| 23 | 25 |
| 24 typedef testing::Test SyncerThreadTest; | 26 typedef testing::Test SyncerThreadTest; |
| 25 typedef SyncerThread::WaitInterval WaitInterval; | 27 typedef SyncerThread::WaitInterval WaitInterval; |
| 26 | 28 |
| 27 class SyncerThreadWithSyncerTest : public testing::Test { | 29 class SyncerThreadWithSyncerTest : public testing::Test { |
| 28 public: | 30 public: |
| 29 SyncerThreadWithSyncerTest() {} | 31 SyncerThreadWithSyncerTest() : sync_cycle_ended_event_(false, false) {} |
| 30 virtual void SetUp() { | 32 virtual void SetUp() { |
| 31 metadb_.SetUp(); | 33 metadb_.SetUp(); |
| 32 connection_.reset(new MockConnectionManager(metadb_.manager(), | 34 connection_.reset(new MockConnectionManager(metadb_.manager(), |
| 33 metadb_.name())); | 35 metadb_.name())); |
| 34 allstatus_.reset(new AllStatus()); | 36 allstatus_.reset(new AllStatus()); |
| 35 | 37 SyncSessionContext* context = new SyncSessionContext(connection_.get(), |
| 36 syncer_thread_ = SyncerThreadFactory::Create(NULL, metadb_.manager(), | 38 metadb_.manager(), new ModelSafeWorker()); |
| 37 connection_.get(), allstatus_.get(), new ModelSafeWorker()); | 39 syncer_thread_ = new SyncerThread(context, allstatus_.get()); |
| 38 | 40 syncer_event_hookup_.reset( |
| 41 NewEventListenerHookup(syncer_thread_->relay_channel(), this, |
| 42 &SyncerThreadWithSyncerTest::HandleSyncerEvent)); |
| 39 allstatus_->WatchSyncerThread(syncer_thread_); | 43 allstatus_->WatchSyncerThread(syncer_thread_); |
| 40 syncer_thread_->SetConnected(true); | 44 syncer_thread_->SetConnected(true); |
| 41 } | 45 } |
| 42 virtual void TearDown() { | 46 virtual void TearDown() { |
| 43 syncer_thread_ = NULL; | 47 syncer_thread_ = NULL; |
| 44 allstatus_.reset(); | 48 allstatus_.reset(); |
| 45 connection_.reset(); | 49 connection_.reset(); |
| 46 metadb_.TearDown(); | 50 metadb_.TearDown(); |
| 47 } | 51 } |
| 48 | 52 |
| 49 ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; } | 53 ManuallyOpenedTestDirectorySetterUpper* metadb() { return &metadb_; } |
| 50 MockConnectionManager* connection() { return connection_.get(); } | 54 MockConnectionManager* connection() { return connection_.get(); } |
| 51 SyncerThread* syncer_thread() { return syncer_thread_; } | 55 SyncerThread* syncer_thread() { return syncer_thread_; } |
| 56 |
| 57 // Waits an indefinite amount of sync cycles for the syncer thread to become |
| 58 // throttled. Only call this if a throttle is supposed to occur! |
| 59 void WaitForThrottle() { |
| 60 while (!syncer_thread()->IsSyncingCurrentlySilenced()) |
| 61 sync_cycle_ended_event_.Wait(); |
| 62 } |
| 63 |
| 52 private: | 64 private: |
| 65 |
| 66 void HandleSyncerEvent(const SyncerEvent& event) { |
| 67 if (event.what_happened == SyncerEvent::SYNC_CYCLE_ENDED) |
| 68 sync_cycle_ended_event_.Signal(); |
| 69 } |
| 70 |
| 53 ManuallyOpenedTestDirectorySetterUpper metadb_; | 71 ManuallyOpenedTestDirectorySetterUpper metadb_; |
| 54 scoped_ptr<MockConnectionManager> connection_; | 72 scoped_ptr<MockConnectionManager> connection_; |
| 55 scoped_ptr<AllStatus> allstatus_; | 73 scoped_ptr<AllStatus> allstatus_; |
| 56 scoped_refptr<SyncerThread> syncer_thread_; | 74 scoped_refptr<SyncerThread> syncer_thread_; |
| 75 scoped_ptr<EventListenerHookup> syncer_event_hookup_; |
| 76 base::WaitableEvent sync_cycle_ended_event_; |
| 57 DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest); | 77 DISALLOW_COPY_AND_ASSIGN(SyncerThreadWithSyncerTest); |
| 58 }; | 78 }; |
| 59 | 79 |
| 60 class SyncShareIntercept : public MockConnectionManager::ThrottleRequestVisitor, | 80 class SyncShareIntercept : public MockConnectionManager::ThrottleRequestVisitor, |
| 61 public MockConnectionManager::MidCommitObserver { | 81 public MockConnectionManager::MidCommitObserver { |
| 62 public: | 82 public: |
| 63 SyncShareIntercept() : sync_occured_(false, false), | 83 SyncShareIntercept() : sync_occured_(false, false), |
| 64 allow_multiple_interceptions_(true) {} | 84 allow_multiple_interceptions_(true) {} |
| 65 virtual ~SyncShareIntercept() {} | 85 virtual ~SyncShareIntercept() {} |
| 66 virtual void Observe() { | 86 virtual void Observe() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 85 return times_sync_occured_; | 105 return times_sync_occured_; |
| 86 } | 106 } |
| 87 private: | 107 private: |
| 88 std::vector<TimeTicks> times_sync_occured_; | 108 std::vector<TimeTicks> times_sync_occured_; |
| 89 base::WaitableEvent sync_occured_; | 109 base::WaitableEvent sync_occured_; |
| 90 bool allow_multiple_interceptions_; | 110 bool allow_multiple_interceptions_; |
| 91 DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept); | 111 DISALLOW_COPY_AND_ASSIGN(SyncShareIntercept); |
| 92 }; | 112 }; |
| 93 | 113 |
| 94 TEST_F(SyncerThreadTest, Construction) { | 114 TEST_F(SyncerThreadTest, Construction) { |
| 95 scoped_refptr<SyncerThread> syncer_thread( | 115 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL); |
| 96 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 116 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context, NULL)); |
| 97 } | 117 } |
| 98 | 118 |
| 99 TEST_F(SyncerThreadTest, StartStop) { | 119 TEST_F(SyncerThreadTest, StartStop) { |
| 100 scoped_refptr<SyncerThread> syncer_thread( | 120 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL); |
| 101 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 121 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context, NULL)); |
| 102 EXPECT_TRUE(syncer_thread->Start()); | 122 EXPECT_TRUE(syncer_thread->Start()); |
| 103 EXPECT_TRUE(syncer_thread->Stop(2000)); | 123 EXPECT_TRUE(syncer_thread->Stop(2000)); |
| 104 | 124 |
| 105 // Do it again for good measure. I caught some bugs by adding this so | 125 // Do it again for good measure. I caught some bugs by adding this so |
| 106 // I would recommend keeping it. | 126 // I would recommend keeping it. |
| 107 EXPECT_TRUE(syncer_thread->Start()); | 127 EXPECT_TRUE(syncer_thread->Start()); |
| 108 EXPECT_TRUE(syncer_thread->Stop(2000)); | 128 EXPECT_TRUE(syncer_thread->Stop(2000)); |
| 109 } | 129 } |
| 110 | 130 |
| 111 TEST_F(SyncerThreadTest, CalculateSyncWaitTime) { | 131 TEST_F(SyncerThreadTest, CalculateSyncWaitTime) { |
| 112 scoped_refptr<SyncerThread> syncer_thread( | 132 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL); |
| 113 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 133 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context, NULL)); |
| 114 syncer_thread->DisableIdleDetection(); | 134 syncer_thread->DisableIdleDetection(); |
| 115 | 135 |
| 116 // Syncer_polling_interval_ is less than max poll interval. | 136 // Syncer_polling_interval_ is less than max poll interval. |
| 117 TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1); | 137 TimeDelta syncer_polling_interval = TimeDelta::FromSeconds(1); |
| 118 | 138 |
| 119 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); | 139 syncer_thread->SetSyncerPollingInterval(syncer_polling_interval); |
| 120 | 140 |
| 121 // user_idle_ms is less than 10 * (syncer_polling_interval*1000). | 141 // user_idle_ms is less than 10 * (syncer_polling_interval*1000). |
| 122 ASSERT_EQ(syncer_polling_interval.InMilliseconds(), | 142 ASSERT_EQ(syncer_polling_interval.InMilliseconds(), |
| 123 syncer_thread->CalculateSyncWaitTime(1000, 0)); | 143 syncer_thread->CalculateSyncWaitTime(1000, 0)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 syncer_thread->CalculateSyncWaitTime(last_poll_time, | 182 syncer_thread->CalculateSyncWaitTime(last_poll_time, |
| 163 over_sync_max_interval)); | 183 over_sync_max_interval)); |
| 164 ASSERT_TRUE(last_poll_time * 3 >= | 184 ASSERT_TRUE(last_poll_time * 3 >= |
| 165 syncer_thread->CalculateSyncWaitTime(last_poll_time, | 185 syncer_thread->CalculateSyncWaitTime(last_poll_time, |
| 166 over_sync_max_interval)); | 186 over_sync_max_interval)); |
| 167 } | 187 } |
| 168 | 188 |
| 169 TEST_F(SyncerThreadTest, CalculatePollingWaitTime) { | 189 TEST_F(SyncerThreadTest, CalculatePollingWaitTime) { |
| 170 // Set up the environment. | 190 // Set up the environment. |
| 171 int user_idle_milliseconds_param = 0; | 191 int user_idle_milliseconds_param = 0; |
| 172 scoped_refptr<SyncerThread> syncer_thread( | 192 SyncSessionContext* context = new SyncSessionContext(NULL, NULL, NULL); |
| 173 SyncerThreadFactory::Create(NULL, NULL, NULL, NULL, NULL)); | 193 scoped_refptr<SyncerThread> syncer_thread(new SyncerThread(context, NULL)); |
| 174 syncer_thread->DisableIdleDetection(); | 194 syncer_thread->DisableIdleDetection(); |
| 175 // Hold the lock to appease asserts in code. | 195 // Hold the lock to appease asserts in code. |
| 176 AutoLock lock(syncer_thread->lock_); | 196 AutoLock lock(syncer_thread->lock_); |
| 177 | 197 |
| 178 // Notifications disabled should result in a polling interval of | 198 // Notifications disabled should result in a polling interval of |
| 179 // kDefaultShortPollInterval. | 199 // kDefaultShortPollInterval. |
| 180 { | 200 { |
| 181 AllStatus::Status status = {}; | 201 AllStatus::Status status = {}; |
| 182 status.notifications_enabled = 0; | 202 status.notifications_enabled = 0; |
| 183 bool continue_sync_cycle_param = false; | 203 bool continue_sync_cycle_param = false; |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 // Tell the server to throttle a single request, which should be all it takes | 609 // Tell the server to throttle a single request, which should be all it takes |
| 590 // to silence our syncer (for 2 hours, so we shouldn't hit that in this test). | 610 // to silence our syncer (for 2 hours, so we shouldn't hit that in this test). |
| 591 // This will atomically visit the interceptor so it can switch to throttled | 611 // This will atomically visit the interceptor so it can switch to throttled |
| 592 // mode and fail on multiple requests. | 612 // mode and fail on multiple requests. |
| 593 connection()->ThrottleNextRequest(&interceptor); | 613 connection()->ThrottleNextRequest(&interceptor); |
| 594 | 614 |
| 595 // Try to trigger a sync (we have a really short poll interval already). | 615 // Try to trigger a sync (we have a really short poll interval already). |
| 596 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); | 616 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
| 597 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); | 617 syncer_thread()->NudgeSyncer(0, SyncerThread::kUnknown); |
| 598 | 618 |
| 599 // Stick around for several poll intervals for good measure. Any sync is | 619 // Wait until the syncer thread reports that it is throttled. Any further |
| 600 // a failure. | 620 // sync share interceptions will result in failure. If things are broken, |
| 601 interceptor.WaitForSyncShare(1, poll_interval * 10); | 621 // we may never halt. |
| 622 WaitForThrottle(); |
| 623 EXPECT_TRUE(syncer_thread()->IsSyncingCurrentlySilenced()); |
| 602 | 624 |
| 603 EXPECT_TRUE(syncer_thread()->Stop(2000)); | 625 EXPECT_TRUE(syncer_thread()->Stop(2000)); |
| 604 } | 626 } |
| 605 | 627 |
| 606 } // namespace browser_sync | 628 } // namespace browser_sync |
| OLD | NEW |