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"
88f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu#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"
118f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu#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"
178f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu#include "testing/gmock/include/gmock/gmock.h"
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
208f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liuusing ::testing::_;
218f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liuusing ::testing::Invoke;
228f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liuusing ::testing::WithArgs;
238f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace syncer {
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace {
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid OnConfigDone(bool success) {
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(success);
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
328f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liuclass SyncBackupManagerTest : public syncer::SyncManager::Observer,
338f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              public testing::Test {
348f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu public:
358f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD1(OnSyncCycleCompleted,
368f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu               void(const sessions::SyncSessionSnapshot&));
378f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD1(OnConnectionStatusChange, void(ConnectionStatus));
388f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD1(OnActionableError, void(const SyncProtocolError&));
398f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD1(OnMigrationRequested, void(ModelTypeSet));;
408f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD1(OnProtocolEvent, void(const ProtocolEvent&));
418f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  MOCK_METHOD4(OnInitializationComplete,
428f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu               void(const WeakHandle<JsBackend>&,
438f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                    const WeakHandle<DataTypeDebugInfoListener>&,
448f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                    bool, ModelTypeSet));
458f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch protected:
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void SetUp() OVERRIDE {
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CHECK(temp_dir_.CreateUniqueTempDir());
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
518f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  void InitManager(SyncManager* manager, StorageOption storage_option) {
528f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    manager_ = manager;
538f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    EXPECT_CALL(*this, OnInitializationComplete(_, _, _, _))
548f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu        .WillOnce(WithArgs<2>(Invoke(this,
558f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                                     &SyncBackupManagerTest::HandleInit)));
568f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    TestInternalComponentsFactory factory(InternalComponentsFactory::Switches(),
588f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                                          storage_option);
598f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    manager->AddObserver(this);
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
618f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    base::RunLoop run_loop;
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    manager->Init(temp_dir_.path(),
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  MakeWeakHandle(base::WeakPtr<JsEventHandler>()),
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  "", 0, true, scoped_ptr<HttpPostProviderFactory>().Pass(),
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  std::vector<scoped_refptr<ModelSafeWorker> >(),
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  NULL, NULL, SyncCredentials(), "", "", "", &factory,
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  NULL, scoped_ptr<UnrecoverableErrorHandler>().Pass(),
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  NULL, NULL);
698f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    loop_.PostTask(FROM_HERE, run_loop.QuitClosure());
708f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    run_loop.Run();
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void CreateEntry(UserShare* user_share, ModelType type,
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   const std::string& client_tag) {
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    WriteTransaction trans(FROM_HERE, user_share);
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadNode type_root(&trans);
7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    EXPECT_EQ(BaseNode::INIT_OK, type_root.InitTypeRoot(type));
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    WriteNode node(&trans);
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(WriteNode::INIT_SUCCESS,
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              node.InitUniqueByCreation(type, type_root, client_tag));
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
848f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu private:
858f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  void ConfigureSyncer() {
868f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    manager_->ConfigureSyncer(CONFIGURE_REASON_NEW_CLIENT,
878f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              ModelTypeSet(SEARCH_ENGINES),
888f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              ModelTypeSet(), ModelTypeSet(), ModelTypeSet(),
898f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              ModelSafeRoutingInfo(),
908f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              base::Bind(&OnConfigDone, true),
918f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                              base::Bind(&OnConfigDone, false));
928f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  }
938f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
948f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  void HandleInit(bool success) {
958f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    if (success) {
968f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu      loop_.PostTask(FROM_HERE,
978f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                     base::Bind(&SyncBackupManagerTest::ConfigureSyncer,
988f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu                                base::Unretained(this)));
998f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    } else {
1008f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu      manager_->ShutdownOnSyncThread();
1018f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu    }
1028f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  }
1038f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::ScopedTempDir temp_dir_;
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::MessageLoop loop_;    // Needed for WeakHandle
1068f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  SyncManager* manager_;
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1090529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_F(SyncBackupManagerTest, NormalizeAndPersist) {
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SyncBackupManager> manager(new SyncBackupManager);
1118f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  InitManager(manager.get(), STORAGE_ON_DISK);
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1138f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  CreateEntry(manager->GetUserShare(), SEARCH_ENGINES, "test");
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  {
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // New entry is local and unsynced at first.
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadTransaction trans(FROM_HERE, manager->GetUserShare());
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadNode pref(&trans);
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(BaseNode::INIT_OK,
1208f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu              pref.InitByClientTagLookup(SEARCH_ENGINES, "test"));
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_FALSE(pref.GetEntry()->GetId().ServerKnows());
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_TRUE(pref.GetEntry()->GetIsUnsynced());
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  manager->SaveChanges();
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  {
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // New entry has server ID and unsynced bit is cleared after saving.
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadTransaction trans(FROM_HERE, manager->GetUserShare());
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadNode pref(&trans);
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(BaseNode::INIT_OK,
1328f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu              pref.InitByClientTagLookup(SEARCH_ENGINES, "test"));
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_TRUE(pref.GetEntry()->GetId().ServerKnows());
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_FALSE(pref.GetEntry()->GetIsUnsynced());
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  manager->ShutdownOnSyncThread();
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Reopen db to verify entry is persisted.
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  manager.reset(new SyncBackupManager);
1408f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  InitManager(manager.get(), STORAGE_ON_DISK);
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  {
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadTransaction trans(FROM_HERE, manager->GetUserShare());
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReadNode pref(&trans);
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_EQ(BaseNode::INIT_OK,
1458f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu              pref.InitByClientTagLookup(SEARCH_ENGINES, "test"));
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_TRUE(pref.GetEntry()->GetId().ServerKnows());
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EXPECT_FALSE(pref.GetEntry()->GetIsUnsynced());
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1518f6e4bda48b1f7e913c8b2f770559183fd98092bBo LiuTEST_F(SyncBackupManagerTest, FailToInitialize) {
1528f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  // Test graceful shutdown on initialization failure.
1538f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  scoped_ptr<SyncBackupManager> manager(new SyncBackupManager);
1548f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu  InitManager(manager.get(), STORAGE_INVALID);
1558f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu}
1568f6e4bda48b1f7e913c8b2f770559183fd98092bBo Liu
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // anonymous namespace
1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace syncer
1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
161