1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/sync_driver/non_ui_data_type_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h" 15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/threading/thread.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/sync_driver/data_type_controller_mock.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "components/sync_driver/generic_change_processor_factory.h" 19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/sync_driver/non_ui_data_type_controller_mock.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/fake_syncable_service.h" 21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "sync/api/sync_change.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/model_safe_worker.h" 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace sync_driver { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::WaitableEvent; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::AUTOFILL_PROFILE; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AtLeast; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InvokeWithoutArgs; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::SetArgumentPointee; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrictMock; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(WaitOnEvent, event) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Wait(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(SignalEvent, event) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Signal(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(SaveChangeProcessor, scoped_change_processor) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_change_processor->reset(arg2); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(GetWeakPtrToSyncableService, syncable_service) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have to do this within an Action to ensure it's not evaluated on the wrong 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncable_service->AsWeakPtr(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass SharedChangeProcessorMock : public SharedChangeProcessor { 605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SharedChangeProcessorMock() {} 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MOCK_METHOD6(Connect, base::WeakPtr<syncer::SyncableService>( 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SyncApiComponentFactory*, 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GenericChangeProcessorFactory*, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) syncer::UserShare*, 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DataTypeErrorHandler*, 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu syncer::ModelType, 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const base::WeakPtr<syncer::SyncMergeResult>&)); 705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD0(Disconnect, bool()); 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD2(ProcessSyncChanges, 725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu syncer::SyncError(const tracked_objects::Location&, 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const syncer::SyncChangeList&)); 745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_CONST_METHOD2(GetAllSyncDataReturnError, 755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu syncer::SyncError(syncer::ModelType, 765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu syncer::SyncDataList*)); 775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD0(GetSyncCount, int()); 785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD1(SyncModelHasUserCreatedNodes, 795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu bool(bool*)); 805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD0(CryptoReadyIfNecessary, bool()); 815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_CONST_METHOD1(GetDataTypeContext, bool(std::string*)); 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu protected: 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual ~SharedChangeProcessorMock() {} 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string&)); 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessorMock); 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NonUIDataTypeControllerFake 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public NonUIDataTypeController { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NonUIDataTypeControllerFake( 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SyncApiComponentFactory* sync_factory, 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NonUIDataTypeControllerMock* mock, 98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) SharedChangeProcessor* change_processor, 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> backend_loop) 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : NonUIDataTypeController( 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::MessageLoopProxy::current(), 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Closure(), 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sync_factory), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_(false), 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mock_(mock), 106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) change_processor_(change_processor), 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_loop_(backend_loop) {} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelType type() const OVERRIDE { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AUTOFILL_PROFILE; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::GROUP_DB; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent tasks from being posted on the backend thread until 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnblockBackendTasks() is called. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BlockBackendTasks() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_ = true; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post pending tasks on the backend thread and start allowing tasks 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be posted on the backend thread again. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnblockBackendTasks() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_ = false; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PendingTask>::const_iterator it = pending_tasks_.begin(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_tasks_.end(); ++it) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskOnBackendThread(it->from_here, it->task); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.clear(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual SharedChangeProcessor* CreateSharedChangeProcessor() OVERRIDE { 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return change_processor_.get(); 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool PostTaskOnBackendThread( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) OVERRIDE { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.push_back(PendingTask(from_here, task)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return backend_loop_->PostTask(from_here, task); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We mock the following methods because their default implementations do 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nothing, but we still want to make sure they're called appropriately. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool StartModels() OVERRIDE { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mock_->StartModels(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StopModels() OVERRIDE { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->StopModels(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAssociationTime(base::TimeDelta time) OVERRIDE { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->RecordAssociationTime(time); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void RecordStartFailure(DataTypeController::ConfigureResult result) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OVERRIDE { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->RecordStartFailure(result); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~NonUIDataTypeControllerFake() {} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NonUIDataTypeControllerFake); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PendingTask { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask(const tracked_objects::Location& from_here, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : from_here(from_here), task(task) {} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::Location from_here; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool blocked_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PendingTask> pending_tasks_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NonUIDataTypeControllerMock* mock_; 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_refptr<SharedChangeProcessor> change_processor_; 183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> backend_loop_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncNonUIDataTypeControllerTest : public testing::Test { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncNonUIDataTypeControllerTest() 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : backend_thread_("dbthread") {} 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_thread_.Start(); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_processor_ = new SharedChangeProcessorMock(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All of these are refcounted, so don't need to be released. 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>(); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_ = 197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) new NonUIDataTypeControllerFake(NULL, 1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu dtc_mock_.get(), 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci change_processor_.get(), 200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_thread_.message_loop_proxy()); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_thread_.Stop(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForDTC() { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent done(true, false); 209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_thread_.message_loop_proxy()->PostTask( 210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FROM_HERE, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncNonUIDataTypeControllerTest::SignalDone, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &done)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.TimedWait(TestTimeouts::action_timeout()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!done.IsSignaled()) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE() << "Timed out waiting for DB thread to finish."; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStartExpectations() { 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(model_load_callback_, Run(_, _)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetAssociateExpectations() { 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetSyncCount()).WillOnce(Return(0)); 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetActivateExpectations(DataTypeController::ConfigureResult result) { 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(start_callback_, Run(result,_,_)); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStopExpectations() { 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()); 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetStartFailExpectations(DataTypeController::ConfigureResult result) { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()).Times(AtLeast(1)); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(start_callback_, Run(result, _, _)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start() { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->LoadModels( 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ModelLoadCallbackMock::Run, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&model_load_callback_))); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->StartAssociating( 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&StartCallbackMock::Run, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&start_callback_))); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SignalDone(WaitableEvent* done) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done->Signal(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForUI message_loop_; 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Thread backend_thread_; 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartCallbackMock start_callback_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelLoadCallbackMock model_load_callback_; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Must be destroyed after non_ui_dtc_. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::FakeSyncableService syncable_service_; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<NonUIDataTypeControllerFake> non_ui_dtc_; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedChangeProcessorMock> change_processor_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> saved_change_processor_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartOk) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); 29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK_FIRST_RUN); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC and have StartModels() return false. Then, stop the 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DTC without finishing model startup. It should stop cleanly. 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringStartModels) { 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->LoadModels( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ModelLoadCallbackMock::Run, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&model_load_callback_))); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::MODEL_STARTING, non_ui_dtc_->state()); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC and have MergeDataAndStartSyncing() return an error. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DTC should become disabled, and the DTC should still stop 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cleanly. 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); 33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with an association failed error. 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable_service_.set_merge_data_and_start_syncing_error( 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError(FROM_HERE, 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Sync Error", 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch non_ui_dtc_->type())); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state()); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartAssociationTriggersUnrecoverableError) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with an unrecoverable error. 357010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(Return(true)); 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartAssociationCryptoNotReady) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with a NEEDS_CRYPTO error. 374010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(Return(false)); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Trigger a Stop() call when we check if the model associator has user created 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nodes. 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent wait_for_db_thread_pause(false, false); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent pause_db_thread(false, false); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SignalEvent(&wait_for_db_thread_pause), 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WaitOnEvent(&pause_db_thread), 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetArgumentPointee<0>(true), 399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Return(true))); 40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) .WillOnce( 40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Return(syncer::SyncError(FROM_HERE, 40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) syncer::SyncError::DATATYPE_ERROR, 40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "Disconnected.", 40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AUTOFILL_PROFILE))); 406868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()) 407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true))); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_db_thread_pause.Wait(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC while the backend tasks are blocked. Then stop the DTC before 417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the backend tasks get a chance to run. 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartAfterSyncShutdown) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->BlockBackendTasks(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't expect StopSyncing to be called because local_service_ will never 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have been set. 424868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Mock::VerifyAndClearExpectations(change_processor_.get()); 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Mock::VerifyAndClearExpectations(dtc_mock_.get()); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) 433868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(base::WeakPtr<syncer::SyncableService>())); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->UnblockBackendTasks(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, Stop) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStopExpectations(); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC then block its backend tasks. While its backend 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tasks are blocked, stop and start it again, then unblock its 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backend tasks. The (delayed) running of the backend tasks from the 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stop after the restart shouldn't cause any problems. 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StopStart) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStopExpectations(); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->BlockBackendTasks(); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->UnblockBackendTasks(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) testing::Mock::VerifyAndClearExpectations(&start_callback_); 4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_CALL(model_load_callback_, Run(_, _)); 4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncError error(FROM_HERE, 4906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncer::SyncError::DATATYPE_ERROR, 4916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "error", 4926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) non_ui_dtc_->type()); 493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) backend_thread_.message_loop_proxy()->PostTask(FROM_HERE, base::Bind( 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &NonUIDataTypeControllerFake:: 4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OnSingleDataTypeUnrecoverableError, 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_.get(), 4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) error)); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace sync_driver 504