Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(557)

Side by Side Diff: chrome/browser/sync/engine/syncer_thread2_unittest.cc

Issue 5939006: sync: beginnings of MessageLoop based SyncerThread (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/waitable_event.h"
6 #include "base/test/test_timeouts.h"
7 #include "chrome/browser/sync/engine/mock_model_safe_workers.h"
8 #include "chrome/browser/sync/engine/syncer.h"
9 #include "chrome/browser/sync/engine/syncer_thread2.h"
10 #include "chrome/browser/sync/sessions/test_util.h"
11 #include "chrome/test/sync/engine/test_directory_setter_upper.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14
15 using base::TimeDelta;
16 using base::TimeTicks;
17 using testing::_;
18 using testing::AtLeast;
19 using testing::DoAll;
20 using testing::Field;
21 using testing::Invoke;
22 using testing::WithArg;
23
24 namespace browser_sync {
25 using sessions::SyncSession;
26 using sessions::SyncSessionContext;
27 using syncable::ModelTypeBitSet;
28 using sync_pb::GetUpdatesCallerInfo;
29
30 class MockSyncer : public Syncer {
31 public:
32 MOCK_METHOD1(SyncShare, void(sessions::SyncSession*));
33 };
34
35 namespace s3 {
36
37 ACTION_P(SignalEvent, event) {
38 event->Signal();
39 }
40
41 // Used when tests want to record syncing activity to examine later.
42 struct SyncShareRecords {
43 std::vector<TimeTicks> times;
44 std::vector<scoped_refptr<SyncSession> > sessions;
45 };
46
47 class SyncerThread2Test : public testing::Test {
48 public:
49 virtual void SetUp() {
50 syncdb_.SetUp();
51 syncer_ = new MockSyncer();
52 registrar_.reset(MockModelSafeWorkerRegistrar::PassiveBookmarks());
53 context_ = new SyncSessionContext(NULL, syncdb_.manager(),
54 registrar_.get(), std::vector<SyncEngineEventListener*>());
55 context_->set_notifications_enabled(true);
56 context_->set_account_name("Test");
57 syncer_thread_ = new SyncerThread(context_, syncer_);
58 // TODO(tim): Once the SCM is hooked up, remove this.
59 syncer_thread_->server_connection_ok_ = true;
60 }
61
62 SyncerThread* syncer_thread() { return syncer_thread_.get(); }
63 MockSyncer* syncer() { return syncer_; }
64 TimeDelta zero() { return TimeDelta::FromSeconds(0); }
65 TimeDelta timeout() {
66 return TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms());
67 }
68
69 virtual void TearDown() {
70 syncer_thread()->Stop();
71 syncdb_.TearDown();
72 }
73
74 private:
75 scoped_refptr<SyncerThread> syncer_thread_;
76 SyncSessionContext* context_;
77 MockSyncer* syncer_;
78 scoped_ptr<MockModelSafeWorkerRegistrar> registrar_;
79 MockDirectorySetterUpper syncdb_;
80 };
81
82 ACTION_P3(RecordSyncShare, record, signal_after, event) {
83 record->times.push_back(TimeTicks::Now());
84 record->sessions.push_back(arg0);
85 if (record->times.size() >= signal_after)
86 event->Signal();
87 }
88
89 // Test nudge scheduling.
90 TEST_F(SyncerThread2Test, Nudge) {
91 syncer_thread()->Start(SyncerThread::NORMAL_MODE);
92 base::WaitableEvent done(false, false);
93 SyncShareRecords records;
94 syncable::ModelTypeBitSet model_types;
95 model_types[syncable::BOOKMARKS] = true;
96
97 EXPECT_CALL(*syncer(), SyncShare(_))
98 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
99 WithArg<0>(RecordSyncShare(&records, 1U, &done))));
100 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, model_types);
101 done.TimedWait(timeout());
102
103 EXPECT_EQ(1, records.sessions.size());
104 EXPECT_EQ(model_types, records.sessions[0]->source().second);
105 EXPECT_EQ(GetUpdatesCallerInfo::LOCAL, records.sessions[0]->source().first);
106 }
107
108 // Test that nudges are coalesced.
109 TEST_F(SyncerThread2Test, NudgeCoalescing) {
110 syncer_thread()->Start(SyncerThread::NORMAL_MODE);
111 base::WaitableEvent done(false, false);
112 SyncShareRecords r;
113 EXPECT_CALL(*syncer(), SyncShare(_))
114 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
115 WithArg<0>(RecordSyncShare(&r, 1U, &done))));
116 syncable::ModelTypeBitSet types1, types2, types3;
117 types1[syncable::BOOKMARKS] = true;
118 types2[syncable::AUTOFILL] = true;
119 types3[syncable::THEMES] = true;
120 TimeDelta delay = TimeDelta::FromMilliseconds(20);
121 TimeTicks optimal_time = TimeTicks::Now() + delay;
122 syncer_thread()->ScheduleNudge(delay, NUDGE_SOURCE_UNKNOWN, types1);
123 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, types2);
124 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_NOTIFICATION, types3);
125 done.TimedWait(timeout());
126
127 EXPECT_EQ(1, r.sessions.size());
128 EXPECT_GE(r.times[0], optimal_time);
129 EXPECT_EQ(types1 | types2 | types3, r.sessions[0]->source().second);
130 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, r.sessions[0]->source().first);
131
132 SyncShareRecords r2;
133 EXPECT_CALL(*syncer(), SyncShare(_))
134 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
135 WithArg<0>(RecordSyncShare(&r2, 1U, &done))));
136 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_NOTIFICATION, types3);
137 done.TimedWait(timeout());
138 EXPECT_EQ(1, r2.sessions.size());
139 EXPECT_EQ(types3, r2.sessions[0]->source().second);
140 EXPECT_EQ(GetUpdatesCallerInfo::NOTIFICATION, r2.sessions[0]->source().first);
141 }
142
143 // Test that polling works as expected.
144 TEST_F(SyncerThread2Test, Polling) {
145 SyncShareRecords records;
146 base::WaitableEvent done(false, false);
147 const size_t min_num_samples = 5;
148 TimeDelta poll_interval(TimeDelta::FromMilliseconds(30));
149 syncer_thread()->OnReceivedLongPollIntervalUpdate(poll_interval);
150 EXPECT_CALL(*syncer(), SyncShare(_)).Times(AtLeast(min_num_samples))
151 .WillRepeatedly(DoAll(Invoke(sessions::test_util::SimulateSuccess),
152 WithArg<0>(RecordSyncShare(&records, min_num_samples, &done))));
153
154 TimeTicks optimal_start = TimeTicks::Now() + poll_interval;
155 syncer_thread()->Start(SyncerThread::NORMAL_MODE);
156 done.TimedWait(timeout());
157 syncer_thread()->Stop();
158
159 // Now analyze the run.
160 const std::vector<TimeTicks>& data(records.times);
161 EXPECT_GE(data.size(), min_num_samples);
162 for (size_t i = 0; i < data.size(); i++) {
163 SCOPED_TRACE(testing::Message() << "SyncShare # (" << i << ")");
164 TimeTicks optimal_next_sync = optimal_start + poll_interval * i;
165 EXPECT_GE(data[i], optimal_next_sync);
166 EXPECT_LT(data[i], optimal_next_sync + poll_interval);
167 EXPECT_EQ(GetUpdatesCallerInfo::PERIODIC,
168 records.sessions[i]->source().first);
169 }
170 }
171
172 // Test that the short poll interval is used.
173 TEST_F(SyncerThread2Test, PollNotificationsDisabled) {
174
175 }
176
177 // Test that polling intervals are updated when needed.
178 TEST_F(SyncerThread2Test, PollIntervalUpdate) {
179
180 }
181
182 // Test that a sync session is run through to completion.
183 TEST_F(SyncerThread2Test, HasMoreToSync) {
184 syncer_thread()->Start(SyncerThread::NORMAL_MODE);
185 base::WaitableEvent done(false, false);
186 EXPECT_CALL(*syncer(), SyncShare(_))
187 .WillOnce(Invoke(sessions::test_util::SimulateHasMoreToSync))
188 .WillOnce(DoAll(Invoke(sessions::test_util::SimulateSuccess),
189 SignalEvent(&done)));
190 syncer_thread()->ScheduleNudge(zero(), NUDGE_SOURCE_LOCAL, ModelTypeBitSet());
191 done.TimedWait(timeout());
192 // If more nudges are scheduled, they'll be waited on by TearDown, and would
193 // cause our expectation to break.
194 }
195
196 // Test nudges / polls don't run in config mode.
197 TEST_F(SyncerThread2Test, ConfigurationMode) {
198 // TODO(tim): To test mode contract, use orthogonal NudgeSources for config
199 // vs nudge, expect config source.
200 }
201
202 // Test that no syncing occurs when throttled.
203 TEST_F(SyncerThread2Test, Throttled) {
204 }
205
206 // Test that exponential backoff is properly triggered.
207 TEST_F(SyncerThread2Test, BackoffTriggered) {
208 }
209
210 // Test that no polls or extraneous nudges occur when in backoff.
211 TEST_F(SyncerThread2Test, BackoffDropsJobs) {
212 }
213
214 // Test that backoff is shaping traffic properly with consecutive errors.
215 TEST_F(SyncerThread2Test, BackoffElevation) {
216 }
217
218 // Test that things go back to normal once a canary task makes forward progress
219 // following a succession of failures.
220 TEST_F(SyncerThread2Test, BackoffRelief) {
221 }
222
223 TEST_F(SyncerThread2Test, StopSyncPermanently) {
224 }
225
226 TEST_F(SyncerThread2Test, GetRecommendedDelay) {
227 }
228
229 // Test config tasks don't run during normal mode.
230 TEST_F(SyncerThread2Test, DISABLED_NoConfigDuringNormal) {
231 }
232
233 // Test that starting the syncer thread without a valid connection doesn't
234 // break things when a connection is detected.
235 TEST_F(SyncerThread2Test, DISABLED_StartWhenNotConnected) {
236
237 }
238
239 } // namespace s3
240 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698