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

Side by Side Diff: chrome/browser/sync/glue/new_non_frontend_data_type_controller_unittest.cc

Issue 8065016: [Sync] Refactor non-frontend DTC to handle new API properly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Self review Created 9 years, 2 months 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) 2011 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 "testing/gtest/include/gtest/gtest.h"
akalin 2011/10/13 00:08:16 the new_non_frontend_dtc.h header should go first,
Nicolas Zea 2011/10/13 01:16:14 Done.
6
7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "base/task.h"
11 #include "base/test/test_timeouts.h"
12 #include "base/tracked_objects.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "chrome/browser/sync/api/syncable_service_mock.h"
15 #include "chrome/browser/sync/engine/model_safe_worker.h"
16 #include "chrome/browser/sync/glue/data_type_controller_mock.h"
17 #include "chrome/browser/sync/glue/new_non_frontend_data_type_controller.h"
18 #include "chrome/browser/sync/glue/new_non_frontend_data_type_controller_mock.h"
19 #include "chrome/browser/sync/glue/shared_change_processor_mock.h"
20 #include "chrome/browser/sync/profile_sync_factory_mock.h"
21 #include "chrome/browser/sync/profile_sync_service_mock.h"
22 #include "chrome/test/base/profile_mock.h"
23 #include "content/browser/browser_thread.h"
24
25 using base::WaitableEvent;
26 using browser_sync::GenericChangeProcessor;
27 using browser_sync::SharedChangeProcessorMock;
28 using browser_sync::DataTypeController;
29 using browser_sync::GROUP_DB;
30 using browser_sync::NewNonFrontendDataTypeController;
31 using browser_sync::NewNonFrontendDataTypeControllerMock;
32 using browser_sync::StartCallback;
33 using syncable::AUTOFILL_PROFILE;
34 using testing::_;
35 using testing::DoAll;
36 using testing::InvokeWithoutArgs;
37 using testing::Return;
38 using testing::SetArgumentPointee;
39 using testing::StrictMock;
40
41 ACTION_P(WaitOnEvent, event) {
akalin 2011/10/13 00:08:16 put everything in browser_sync? if possible, put
Nicolas Zea 2011/10/13 01:16:14 Done.
42 event->Wait();
43 }
44
45 ACTION_P(SignalEvent, event) {
46 event->Signal();
47 }
48
49 ACTION_P(SaveChangeProcessor, scoped_change_processor) {
50 scoped_change_processor->reset(arg2);
51 }
52
53 ACTION_P(GetWeakPtrToSyncableService, syncable_service) {
54 // Have to do this within an Action to ensure it's not evaluated on the wrong
55 // thread.
56 return syncable_service->AsWeakPtr();
57 }
58
59 class NewNonFrontendDataTypeControllerFake
60 : public NewNonFrontendDataTypeController {
61 public:
62 NewNonFrontendDataTypeControllerFake(
63 ProfileSyncFactory* profile_sync_factory,
64 Profile* profile,
65 NewNonFrontendDataTypeControllerMock* mock)
66 : NewNonFrontendDataTypeController(profile_sync_factory,
67 profile),
68 mock_(mock) {}
69
70 virtual syncable::ModelType type() const OVERRIDE {
71 return AUTOFILL_PROFILE;
72 }
73 virtual browser_sync::ModelSafeGroup model_safe_group() const OVERRIDE {
74 return GROUP_DB;
75 }
76
77 private:
78 virtual base::WeakPtr<SyncableService>
79 GetWeakPtrToSyncableService() const OVERRIDE {
80 return profile_sync_factory()->GetAutofillProfileSyncableService(NULL);
81 }
82 virtual bool StartAssociationAsync() OVERRIDE {
83 mock_->StartAssociationAsync();
84 return BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
85 base::Bind(
86 &NewNonFrontendDataTypeControllerFake::StartAssociation,
87 this));
88 }
89
90 // We mock the following methods because their default implementations do
91 // nothing, but we still want to make sure they're called appropriately.
92 virtual bool StartModels() OVERRIDE {
93 return mock_->StartModels();
94 }
95 virtual void StopModels() OVERRIDE {
96 mock_->StopModels();
97 }
98 virtual void StopLocalServiceAsync() OVERRIDE {
99 mock_->StopLocalServiceAsync();
100 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
101 base::Bind(
102 &NewNonFrontendDataTypeController::StopLocalService,
103 this));
104 }
105 virtual void RecordUnrecoverableError(
106 const tracked_objects::Location& from_here,
107 const std::string& message) OVERRIDE {
108 mock_->RecordUnrecoverableError(from_here, message);
109 }
110 virtual void RecordAssociationTime(base::TimeDelta time) OVERRIDE {
111 mock_->RecordAssociationTime(time);
112 }
113 virtual void RecordStartFailure(DataTypeController::StartResult result)
114 OVERRIDE {
115 mock_->RecordStartFailure(result);
116 }
117 private:
118 NewNonFrontendDataTypeControllerMock* mock_;
119 };
120
121 class NewNonFrontendDataTypeControllerTest : public testing::Test {
122 public:
123 NewNonFrontendDataTypeControllerTest()
124 : ui_thread_(BrowserThread::UI, &message_loop_),
125 db_thread_(BrowserThread::DB) {}
126
127 virtual void SetUp() OVERRIDE {
128 EXPECT_CALL(profile_, GetProfileSyncService()).WillRepeatedly(
129 Return(&service_));
130 EXPECT_CALL(service_, GetUserShare()).WillRepeatedly(
131 Return((sync_api::UserShare*)NULL));
132 db_thread_.Start();
133 profile_sync_factory_.reset(new ProfileSyncFactoryMock());
134 change_processor_ = new SharedChangeProcessorMock();
135
136 // Both of these are refcounted, so don't need to be released.
137 dtc_mock_ = new StrictMock<NewNonFrontendDataTypeControllerMock>();
138 new_non_frontend_dtc_ =
139 new NewNonFrontendDataTypeControllerFake(profile_sync_factory_.get(),
140 &profile_,
141 dtc_mock_.get());
142 }
143
144 virtual void TearDown() OVERRIDE {
145 db_thread_.Stop();
146 }
147
148 void WaitForDTC() {
149 WaitableEvent done(true, false);
150 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
151 base::Bind(&NewNonFrontendDataTypeControllerTest::SignalDone,
152 &done));
153 done.TimedWait(base::TimeDelta::FromMilliseconds(
akalin 2011/10/13 00:08:16 phajdan may do a drive-by about this (re test fail
Nicolas Zea 2011/10/13 01:16:14 I think as long as we use the right timeout we're
154 TestTimeouts::action_timeout_ms()));
155 if (!done.IsSignaled()) {
156 ADD_FAILURE() << "Timed out waiting for DB thread to finish.";
157 }
158 MessageLoop::current()->RunAllPending();
159 }
160
161 protected:
162 void SetStartExpectations() {
163 EXPECT_CALL(*dtc_mock_, StartModels()).WillOnce(Return(true));
164 EXPECT_CALL(*profile_sync_factory_,
165 GetAutofillProfileSyncableService(_)).
166 WillOnce(GetWeakPtrToSyncableService(&syncable_service_));
167 EXPECT_CALL(*profile_sync_factory_,
168 CreateSharedChangeProcessor()).
169 WillOnce(Return(change_processor_.get()));
170 }
171
172 void SetAssociateExpectations() {
173 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
174 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
175 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
176 WillOnce(Return(true));
177 EXPECT_CALL(*change_processor_, SyncModelHasUserCreatedNodes(_,_)).
178 WillOnce(DoAll(SetArgumentPointee<1>(true), Return(true)));
179 EXPECT_CALL(*change_processor_, GetSyncDataForType(_,_)).
180 WillOnce(Return(SyncError()));
181 EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
182 WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
183 Return(SyncError())));
184 EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
185 }
186
187 void SetActivateExpectations(DataTypeController::StartResult result) {
188 EXPECT_CALL(service_, ActivateDataType(_, _, _));
189 EXPECT_CALL(start_callback_, Run(result,_));
190 }
191
192 void SetStopExpectations() {
193 EXPECT_CALL(*dtc_mock_, StopModels());
194 EXPECT_CALL(*change_processor_, Disconnect()).WillOnce(Return(true));
195 EXPECT_CALL(service_, DeactivateDataType(_));
196 EXPECT_CALL(*dtc_mock_, StopLocalServiceAsync());
197 EXPECT_CALL(syncable_service_, StopSyncing(_));
198 }
199
200 void SetStartFailExpectations(DataTypeController::StartResult result) {
201 EXPECT_CALL(*dtc_mock_, StopModels());
202 EXPECT_CALL(*dtc_mock_, RecordStartFailure(result));
203 EXPECT_CALL(start_callback_, Run(result,_));
204 }
205
206 static void SignalDone(WaitableEvent* done) {
207 done->Signal();
208 }
209
210 MessageLoopForUI message_loop_;
211 BrowserThread ui_thread_;
212 BrowserThread db_thread_;
213 ProfileMock profile_;
214 scoped_ptr<ProfileSyncFactoryMock> profile_sync_factory_;
215 ProfileSyncServiceMock service_;
216 StartCallback start_callback_;
217 // Must be destroyed after new_non_frontend_dtc_.
218 SyncableServiceMock syncable_service_;
219 scoped_refptr<NewNonFrontendDataTypeControllerFake> new_non_frontend_dtc_;
220 scoped_refptr<NewNonFrontendDataTypeControllerMock> dtc_mock_;
221 scoped_refptr<SharedChangeProcessorMock> change_processor_;
222 scoped_ptr<SyncChangeProcessor> saved_change_processor_;
223 };
224
225 TEST_F(NewNonFrontendDataTypeControllerTest, StartOk) {
226 SetStartExpectations();
227 SetAssociateExpectations();
228 SetActivateExpectations(DataTypeController::OK);
229 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
230 new_non_frontend_dtc_->Start(
231 NewCallback(&start_callback_, &StartCallback::Run));
232 WaitForDTC();
233 EXPECT_EQ(DataTypeController::RUNNING, new_non_frontend_dtc_->state());
234 }
235
236 TEST_F(NewNonFrontendDataTypeControllerTest, StartFirstRun) {
237 SetStartExpectations();
238 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
239 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
240 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
241 WillOnce(Return(true));
242 EXPECT_CALL(*change_processor_, SyncModelHasUserCreatedNodes(_,_)).
243 WillOnce(DoAll(SetArgumentPointee<1>(false), Return(true)));
244 EXPECT_CALL(*change_processor_, GetSyncDataForType(_,_)).
245 WillOnce(Return(SyncError()));
246 EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
247 WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
248 Return(SyncError())));
249 EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
250 SetActivateExpectations(DataTypeController::OK_FIRST_RUN);
251 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
252 new_non_frontend_dtc_->Start(
253 NewCallback(&start_callback_, &StartCallback::Run));
254 WaitForDTC();
255 EXPECT_EQ(DataTypeController::RUNNING, new_non_frontend_dtc_->state());
256 }
257
258 TEST_F(NewNonFrontendDataTypeControllerTest, AbortDuringStartModels) {
259 EXPECT_CALL(*dtc_mock_, StartModels()).WillOnce(Return(false));
260 SetStartFailExpectations(DataTypeController::ABORTED);
261 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
262 new_non_frontend_dtc_->Start(
263 NewCallback(&start_callback_, &StartCallback::Run));
264 WaitForDTC();
265 EXPECT_EQ(DataTypeController::MODEL_STARTING, new_non_frontend_dtc_->state());
266 new_non_frontend_dtc_->Stop();
267 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
268 }
269
270 TEST_F(NewNonFrontendDataTypeControllerTest, StartAssociationFailed) {
271 SetStartExpectations();
272 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
273 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
274 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
275 WillOnce(Return(true));
276 EXPECT_CALL(*change_processor_, SyncModelHasUserCreatedNodes(_,_)).
277 WillOnce(DoAll(SetArgumentPointee<1>(true), Return(true)));
278 EXPECT_CALL(*change_processor_, GetSyncDataForType(_,_)).
279 WillOnce(Return(SyncError()));
280 EXPECT_CALL(syncable_service_, MergeDataAndStartSyncing(_,_,_)).
281 WillOnce(DoAll(SaveChangeProcessor(&saved_change_processor_),
282 Return(SyncError(FROM_HERE, "failed", AUTOFILL_PROFILE))));
283 EXPECT_CALL(*dtc_mock_, RecordAssociationTime(_));
284 SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED);
285 EXPECT_CALL(syncable_service_, StopSyncing(_));
286 // Set up association to fail with an association failed error.
287 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
288 new_non_frontend_dtc_->Start(
289 NewCallback(&start_callback_, &StartCallback::Run));
290 WaitForDTC();
291 EXPECT_EQ(DataTypeController::DISABLED, new_non_frontend_dtc_->state());
292 }
293
294 TEST_F(NewNonFrontendDataTypeControllerTest,
295 StartAssociationTriggersUnrecoverableError) {
296 SetStartExpectations();
297 SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR);
298 // Set up association to fail with an unrecoverable error.
299 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
300 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
301 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
302 WillRepeatedly(Return(true));
303 EXPECT_CALL(*change_processor_, SyncModelHasUserCreatedNodes(_,_)).
304 WillRepeatedly(DoAll(SetArgumentPointee<1>(false), Return(false)));
305 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
306 new_non_frontend_dtc_->Start(
307 NewCallback(&start_callback_, &StartCallback::Run));
308 WaitForDTC();
309 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
310 }
311
312 TEST_F(NewNonFrontendDataTypeControllerTest, StartAssociationCryptoNotReady) {
313 SetStartExpectations();
314 SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO);
315 // Set up association to fail with a NEEDS_CRYPTO error.
316 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
317 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
318 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
319 WillRepeatedly(Return(false));
320 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
321 new_non_frontend_dtc_->Start(
322 NewCallback(&start_callback_, &StartCallback::Run));
323 WaitForDTC();
324 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
325 }
326
327 // Trigger a Stop() call when we check if the model associator has user created
328 // nodes.
329 TEST_F(NewNonFrontendDataTypeControllerTest, AbortDuringAssociation) {
330 WaitableEvent wait_for_db_thread_pause(false, false);
331 WaitableEvent pause_db_thread(false, false);
332
333 SetStartExpectations();
334 SetStartFailExpectations(DataTypeController::ABORTED);
335 EXPECT_CALL(*dtc_mock_, StartAssociationAsync());
336 EXPECT_CALL(*change_processor_, Connect(_,_,_,_)).WillOnce(Return(true));
337 EXPECT_CALL(*change_processor_, CryptoReadyIfNecessary(_)).
338 WillOnce(Return(true));
339 EXPECT_CALL(*change_processor_, SyncModelHasUserCreatedNodes(_,_)).
340 WillOnce(DoAll(
341 SignalEvent(&wait_for_db_thread_pause),
342 WaitOnEvent(&pause_db_thread),
343 SetArgumentPointee<1>(true),
344 Return(true)));
345 EXPECT_CALL(*change_processor_, GetSyncDataForType(_,_)).
346 WillOnce(Return(SyncError(FROM_HERE, "Disconnected.", AUTOFILL_PROFILE)));
347 EXPECT_CALL(*change_processor_, Disconnect()).
348 WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true)));
349 EXPECT_CALL(service_, DeactivateDataType(_));
350 EXPECT_CALL(*dtc_mock_, StopLocalServiceAsync());
351 EXPECT_CALL(syncable_service_, StopSyncing(_));
352 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
353 new_non_frontend_dtc_->Start(
354 NewCallback(&start_callback_, &StartCallback::Run));
355 wait_for_db_thread_pause.Wait();
356 new_non_frontend_dtc_->Stop();
357 WaitForDTC();
358 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
359 }
360
361 TEST_F(NewNonFrontendDataTypeControllerTest, Stop) {
362 SetStartExpectations();
363 SetAssociateExpectations();
364 SetActivateExpectations(DataTypeController::OK);
365 SetStopExpectations();
366 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
367 new_non_frontend_dtc_->Start(
368 NewCallback(&start_callback_, &StartCallback::Run));
369 WaitForDTC();
370 EXPECT_EQ(DataTypeController::RUNNING, new_non_frontend_dtc_->state());
371 new_non_frontend_dtc_->Stop();
372 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
373 }
374
375 TEST_F(NewNonFrontendDataTypeControllerTest, OnUnrecoverableError) {
376 SetStartExpectations();
377 SetAssociateExpectations();
378 SetActivateExpectations(DataTypeController::OK);
379 EXPECT_CALL(*dtc_mock_, RecordUnrecoverableError(_, "Test"));
380 EXPECT_CALL(service_, OnUnrecoverableError(_,_)).WillOnce(
381 InvokeWithoutArgs(new_non_frontend_dtc_.get(),
382 &NewNonFrontendDataTypeController::Stop));
383 SetStopExpectations();
384 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
385 new_non_frontend_dtc_->Start(
386 NewCallback(&start_callback_, &StartCallback::Run));
387 WaitForDTC();
388 EXPECT_EQ(DataTypeController::RUNNING, new_non_frontend_dtc_->state());
389 // This should cause new_non_frontend_dtc_->Stop() to be called.
390 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
391 base::Bind(
392 &NewNonFrontendDataTypeControllerFake::OnUnrecoverableError,
393 new_non_frontend_dtc_.get(),
394 FROM_HERE,
395 std::string("Test")));
396 WaitForDTC();
397 EXPECT_EQ(DataTypeController::NOT_RUNNING, new_non_frontend_dtc_->state());
398 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698