10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/sync_backup_manager.h" 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/files/scoped_temp_dir.h" 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/run_loop.h" 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/read_node.h" 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/read_transaction.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "sync/internal_api/public/sessions/sync_session_snapshot.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/test/test_internal_components_factory.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/write_node.h" 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/internal_api/public/write_transaction.h" 150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/syncable/entry.h" 160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "sync/test/test_directory_backing_store.h" 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gmock/include/gmock/gmock.h" 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "url/gurl.h" 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ::testing::_; 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ::testing::Invoke; 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochusing ::testing::WithArgs; 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace syncer { 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace { 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid OnConfigDone(bool success) { 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_TRUE(success); 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass SyncBackupManagerTest : public syncer::SyncManager::Observer, 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public testing::Test { 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public: 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD1(OnSyncCycleCompleted, 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void(const sessions::SyncSessionSnapshot&)); 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus)); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&)); 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));; 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&)); 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MOCK_METHOD4(OnInitializationComplete, 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void(const WeakHandle<JsBackend>&, 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const WeakHandle<DataTypeDebugInfoListener>&, 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool, ModelTypeSet)); 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch protected: 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual void SetUp() OVERRIDE { 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch CHECK(temp_dir_.CreateUniqueTempDir()); 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void InitManager(SyncManager* manager, 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InternalComponentsFactory::StorageOption storage_option) { 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch manager_ = manager; 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _)) 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .WillOnce(WithArgs<2>(Invoke(this, 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &SyncBackupManagerTest::HandleInit))); 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch manager->AddObserver(this); 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::RunLoop run_loop; 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SyncManager::InitArgs args; 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) args.database_location = temp_dir_.path(); 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) args.event_handler = MakeWeakHandle(base::WeakPtr<JsEventHandler>()); 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) args.service_url = GURL("https://example.com/"); 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) args.post_factory = scoped_ptr<HttpPostProviderFactory>().Pass(); 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) args.internal_components_factory.reset(new TestInternalComponentsFactory( 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InternalComponentsFactory::Switches(), storage_option, 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &storage_used_)); 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) manager->Init(&args); 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED, 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) storage_used_); 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch loop_.PostTask(FROM_HERE, run_loop.QuitClosure()); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch run_loop.Run(); 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void CreateEntry(UserShare* user_share, ModelType type, 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const std::string& client_tag) { 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WriteTransaction trans(FROM_HERE, user_share); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadNode type_root(&trans); 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type)); 830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch WriteNode node(&trans); 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(WriteNode::INIT_SUCCESS, 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch node.InitUniqueByCreation(type, type_root, client_tag)); 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void ConfigureSyncer() { 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch manager_->ConfigureSyncer(CONFIGURE_REASON_NEW_CLIENT, 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModelTypeSet(SEARCH_ENGINES), 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModelTypeSet(), ModelTypeSet(), ModelTypeSet(), 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ModelSafeRoutingInfo(), 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&OnConfigDone, true), 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&OnConfigDone, false)); 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void HandleInit(bool success) { 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (success) { 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch loop_.PostTask(FROM_HERE, 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&SyncBackupManagerTest::ConfigureSyncer, 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manager_->ShutdownOnSyncThread(STOP_SYNC); 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::ScopedTempDir temp_dir_; 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::MessageLoop loop_; // Needed for WeakHandle 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SyncManager* manager_; 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InternalComponentsFactory::StorageOption storage_used_; 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SyncBackupManagerTest, NormalizeEntry) { 1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<SyncBackupManager> manager(new SyncBackupManager); 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InitManager(manager.get(), InternalComponentsFactory::STORAGE_IN_MEMORY); 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateEntry(manager->GetUserShare(), SEARCH_ENGINES, "test"); 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // New entry is local and unsynced at first. 1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadTransaction trans(FROM_HERE, manager->GetUserShare()); 1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadNode pref(&trans); 1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(BaseNode::INIT_OK, 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pref.InitByClientTagLookup(SEARCH_ENGINES, "test")); 1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_FALSE(pref.GetEntry()->GetId().ServerKnows()); 1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_TRUE(pref.GetEntry()->GetIsUnsynced()); 1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch manager->SaveChanges(); 1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // New entry has server ID and unsynced bit is cleared after saving. 1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadTransaction trans(FROM_HERE, manager->GetUserShare()); 1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadNode pref(&trans); 1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(BaseNode::INIT_OK, 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pref.InitByClientTagLookup(SEARCH_ENGINES, "test")); 1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_TRUE(pref.GetEntry()->GetId().ServerKnows()); 1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_FALSE(pref.GetEntry()->GetIsUnsynced()); 1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SyncBackupManagerTest, PersistWithSwitchToSyncShutdown) { 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<SyncBackupManager> manager(new SyncBackupManager); 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InitManager(manager.get(), 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED); 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CreateEntry(manager->GetUserShare(), SEARCH_ENGINES, "test"); 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) manager->SaveChanges(); 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) manager->ShutdownOnSyncThread(SWITCH_MODE_SYNC); 1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Reopen db to verify entry is persisted. 1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch manager.reset(new SyncBackupManager); 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InitManager(manager.get(), InternalComponentsFactory::STORAGE_ON_DISK); 1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadTransaction trans(FROM_HERE, manager->GetUserShare()); 1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ReadNode pref(&trans); 1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_EQ(BaseNode::INIT_OK, 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pref.InitByClientTagLookup(SEARCH_ENGINES, "test")); 1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_TRUE(pref.GetEntry()->GetId().ServerKnows()); 1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_FALSE(pref.GetEntry()->GetIsUnsynced()); 1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(SyncBackupManagerTest, DontPersistWithOtherShutdown) { 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_ptr<SyncBackupManager> manager(new SyncBackupManager); 1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InitManager(manager.get(), 1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED); 1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CreateEntry(manager->GetUserShare(), SEARCH_ENGINES, "test"); 1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) manager->SaveChanges(); 1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) manager->ShutdownOnSyncThread(STOP_SYNC); 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_FALSE(base::PathExists( 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) temp_dir_.path().Append(syncable::Directory::kSyncDatabaseFilename))); 1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 177116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(SyncBackupManagerTest, FailToInitialize) { 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Test graceful shutdown on initialization failure. 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<SyncBackupManager> manager(new SyncBackupManager); 1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) InitManager(manager.get(), InternalComponentsFactory::STORAGE_INVALID); 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // anonymous namespace 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} // namespace syncer 186