15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/glue/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" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/data_type_controller_mock.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sync/glue/non_ui_data_type_controller_mock.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/glue/shared_change_processor_mock.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_components_factory_mock.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_mock.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/fake_syncable_service.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/engine/model_safe_worker.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace browser_sync { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::WaitableEvent; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using syncer::AUTOFILL_PROFILE; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AtLeast; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InvokeWithoutArgs; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::SetArgumentPointee; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrictMock; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(WaitOnEvent, event) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Wait(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(SignalEvent, event) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Signal(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(SaveChangeProcessor, scoped_change_processor) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_change_processor->reset(arg2); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(GetWeakPtrToSyncableService, syncable_service) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Have to do this within an Action to ensure it's not evaluated on the wrong 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncable_service->AsWeakPtr(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NonUIDataTypeControllerFake 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public NonUIDataTypeController { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NonUIDataTypeControllerFake( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncComponentsFactory* profile_sync_factory, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileSyncService* sync_service, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NonUIDataTypeControllerMock* mock) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : NonUIDataTypeController(profile_sync_factory, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_service), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_(false), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_(mock) {} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelType type() const OVERRIDE { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AUTOFILL_PROFILE; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual syncer::ModelSafeGroup model_safe_group() const OVERRIDE { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::GROUP_DB; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prevent tasks from being posted on the backend thread until 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnblockBackendTasks() is called. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BlockBackendTasks() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_ = true; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post pending tasks on the backend thread and start allowing tasks 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be posted on the backend thread again. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UnblockBackendTasks() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) blocked_ = false; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<PendingTask>::const_iterator it = pending_tasks_.begin(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_tasks_.end(); ++it) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskOnBackendThread(it->from_here, it->task); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.clear(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool PostTaskOnBackendThread( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) OVERRIDE { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (blocked_) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_tasks_.push_back(PendingTask(from_here, task)); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BrowserThread::PostTask(BrowserThread::DB, from_here, task); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We mock the following methods because their default implementations do 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nothing, but we still want to make sure they're called appropriately. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool StartModels() OVERRIDE { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mock_->StartModels(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StopModels() OVERRIDE { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->StopModels(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordUnrecoverableError( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message) OVERRIDE { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->RecordUnrecoverableError(from_here, message); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordAssociationTime(base::TimeDelta time) OVERRIDE { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->RecordAssociationTime(time); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void RecordStartFailure(DataTypeController::StartResult result) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OVERRIDE { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_->RecordStartFailure(result); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~NonUIDataTypeControllerFake() {} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NonUIDataTypeControllerFake); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PendingTask { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTask(const tracked_objects::Location& from_here, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : from_here(from_here), task(task) {} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::Location from_here; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure task; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool blocked_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PendingTask> pending_tasks_; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NonUIDataTypeControllerMock* mock_; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SyncNonUIDataTypeControllerTest : public testing::Test { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SyncNonUIDataTypeControllerTest() 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ui_thread_(BrowserThread::UI, &message_loop_), 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) db_thread_(BrowserThread::DB), service_(&profile_) {} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(service_, GetUserShare()).WillRepeatedly( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Return((syncer::UserShare*)NULL)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_thread_.Start(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_sync_factory_.reset( 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new StrictMock<ProfileSyncComponentsFactoryMock>()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_processor_ = new SharedChangeProcessorMock(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All of these are refcounted, so don't need to be released. 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>(); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_ = 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new NonUIDataTypeControllerFake(profile_sync_factory_.get(), 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &profile_, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &service_, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dtc_mock_.get()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_thread_.Stop(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForDTC() { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent done(true, false); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&SyncNonUIDataTypeControllerTest::SignalDone, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &done)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.TimedWait(TestTimeouts::action_timeout()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!done.IsSignaled()) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE() << "Timed out waiting for DB thread to finish."; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStartExpectations() { 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(model_load_callback_, Run(_, _)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*profile_sync_factory_, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSharedChangeProcessor()). 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WillOnce(Return(change_processor_.get())); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetAssociateExpectations() { 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), ActivateDataType(_)); 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetSyncCount()).WillOnce(Return(0)); 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetActivateExpectations(DataTypeController::StartResult result) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(start_callback_, Run(result,_,_)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStopExpectations() { 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()); 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(service_, DeactivateDataType(_)); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetStartFailExpectations(DataTypeController::StartResult result) { 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()).Times(AtLeast(1)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DataTypeController::IsUnrecoverableResult(result)) 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, _)); 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(start_callback_, Run(result, _, _)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start() { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->LoadModels( 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ModelLoadCallbackMock::Run, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&model_load_callback_))); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->StartAssociating( 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&StartCallbackMock::Run, 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&start_callback_))); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SignalDone(WaitableEvent* done) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done->Signal(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoopForUI message_loop_; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread db_thread_; 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TestingProfile profile_; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ProfileSyncComponentsFactoryMock> profile_sync_factory_; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StrictMock<ProfileSyncServiceMock> service_; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartCallbackMock start_callback_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModelLoadCallbackMock model_load_callback_; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Must be destroyed after non_ui_dtc_. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::FakeSyncableService syncable_service_; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<NonUIDataTypeControllerFake> non_ui_dtc_; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SharedChangeProcessorMock> change_processor_; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> saved_change_processor_; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartOk) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); 27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK_FIRST_RUN); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC and have StartModels() return false. Then, stop the 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DTC without finishing model startup. It should stop cleanly. 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringStartModels) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*profile_sync_factory_, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSharedChangeProcessor()). 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WillOnce(Return(change_processor_.get())); 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(model_load_callback_, Run(_, _)); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->LoadModels( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ModelLoadCallbackMock::Run, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&model_load_callback_))); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::MODEL_STARTING, non_ui_dtc_->state()); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC and have MergeDataAndStartSyncing() return an error. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The DTC should become disabled, and the DTC should still stop 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cleanly. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); 31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(syncer::SyncError())); 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with an association failed error. 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncable_service_.set_merge_data_and_start_syncing_error( 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError(FROM_HERE, 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Sync Error", 327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch non_ui_dtc_->type())); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state()); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartAssociationTriggersUnrecoverableError) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with an unrecoverable error. 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(Return(true)); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 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) StartAssociationCryptoNotReady) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up association to fail with a NEEDS_CRYPTO error. 357868fa2fe829687343ffae624259930155e16dbd8Torne (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(false)); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Trigger a Stop() call when we check if the model associator has user created 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nodes. 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent wait_for_db_thread_pause(false, false); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent pause_db_thread(false, false); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartFailExpectations(DataTypeController::ABORTED); 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(true)); 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SignalEvent(&wait_for_db_thread_pause), 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WaitOnEvent(&pause_db_thread), 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SetArgumentPointee<0>(true), 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Return(true))); 38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_,_)) 38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) .WillOnce( 38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Return(syncer::SyncError(FROM_HERE, 38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) syncer::SyncError::DATATYPE_ERROR, 38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "Disconnected.", 38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AUTOFILL_PROFILE))); 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()) 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true))); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(service_, DeactivateDataType(_)); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_for_db_thread_pause.Wait(); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC while the backend tasks are blocked. Then stop the DTC before 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the backend tasks get a chance to run. The DTC should have no interaction 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the profile sync factory or profile sync service once stopped. 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StartAfterSyncShutdown) { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->BlockBackendTasks(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't expect StopSyncing to be called because local_service_ will never 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have been set. 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), StopModels()); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(service_, DeactivateDataType(_)); 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordStartFailure(DataTypeController::ABORTED)); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(start_callback_, Run(DataTypeController::ABORTED, _, _)); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&profile_sync_factory_); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&service_); 422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Mock::VerifyAndClearExpectations(change_processor_.get()); 423868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Mock::VerifyAndClearExpectations(dtc_mock_.get()); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _)) 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillOnce(Return(base::WeakPtr<syncer::SyncableService>())); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->UnblockBackendTasks(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, Stop) { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStopExpectations(); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Start the DTC then block its backend tasks. While its backend 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tasks are blocked, stop and start it again, then unblock its 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// backend tasks. The (delayed) running of the backend tasks from the 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stop after the restart shouldn't cause any problems. 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, StopStart) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStopExpectations(); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->BlockBackendTasks(); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->Stop(); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mock::VerifyAndClearExpectations(&profile_sync_factory_); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_->UnblockBackendTasks(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(SyncNonUIDataTypeControllerTest, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSingleDatatypeUnrecoverableError) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStartExpectations(); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetAssociateExpectations(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetActivateExpectations(DataTypeController::OK); 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, "Test")); 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(service_, DisableBrokenDatatype(_, _, _)).WillOnce( 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) InvokeWithoutArgs(non_ui_dtc_.get(), &NonUIDataTypeController::Stop)); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStopExpectations(); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Start(); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should cause non_ui_dtc_->Stop() to be called. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind( 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &NonUIDataTypeControllerFake:: 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSingleDatatypeUnrecoverableError, 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) non_ui_dtc_.get(), 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string("Test"))); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForDTC(); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace browser_sync 499