blob: c3e6537f35a10777e3ed8eeffec184cb036278b1 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/browser_sync/browser/abstract_profile_sync_service_test.h"
#include <utility>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "components/browser_sync/browser/test_http_bridge_factory.h"
#include "components/browser_sync/browser/test_profile_sync_service.h"
#include "components/sync_driver/glue/sync_backend_host_core.h"
#include "components/sync_driver/sync_api_component_factory_mock.h"
#include "google_apis/gaia/gaia_constants.h"
#include "sync/internal_api/public/test/sync_manager_factory_for_profile_sync_test.h"
#include "sync/internal_api/public/test/test_internal_components_factory.h"
#include "sync/internal_api/public/test/test_user_share.h"
#include "sync/protocol/sync.pb.h"
using syncer::ModelType;
using testing::_;
using testing::Return;
namespace {
class SyncBackendHostForProfileSyncTest
: public browser_sync::SyncBackendHostImpl {
public:
SyncBackendHostForProfileSyncTest(
const base::FilePath& temp_dir,
sync_driver::SyncClient* sync_client,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
invalidation::InvalidationService* invalidator,
const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
const base::Closure& callback);
~SyncBackendHostForProfileSyncTest() override;
void RequestConfigureSyncer(
syncer::ConfigureReason reason,
syncer::ModelTypeSet to_download,
syncer::ModelTypeSet to_purge,
syncer::ModelTypeSet to_journal,
syncer::ModelTypeSet to_unapply,
syncer::ModelTypeSet to_ignore,
const syncer::ModelSafeRoutingInfo& routing_info,
const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>&
ready_task,
const base::Closure& retry_callback) override;
protected:
void InitCore(scoped_ptr<browser_sync::DoInitializeOptions> options) override;
private:
// Invoked at the start of HandleSyncManagerInitializationOnFrontendLoop.
// Allows extra initialization work to be performed before the backend comes
// up.
base::Closure callback_;
DISALLOW_COPY_AND_ASSIGN(SyncBackendHostForProfileSyncTest);
};
SyncBackendHostForProfileSyncTest::SyncBackendHostForProfileSyncTest(
const base::FilePath& temp_dir,
sync_driver::SyncClient* sync_client,
const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread,
invalidation::InvalidationService* invalidator,
const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs,
const base::Closure& callback)
: browser_sync::SyncBackendHostImpl(
"dummy_debug_name",
sync_client,
ui_thread,
invalidator,
sync_prefs,
temp_dir.Append(base::FilePath(FILE_PATH_LITERAL("test")))),
callback_(callback) {}
SyncBackendHostForProfileSyncTest::~SyncBackendHostForProfileSyncTest() {}
void SyncBackendHostForProfileSyncTest::InitCore(
scoped_ptr<browser_sync::DoInitializeOptions> options) {
options->http_bridge_factory = scoped_ptr<syncer::HttpPostProviderFactory>(
new browser_sync::TestHttpBridgeFactory());
options->sync_manager_factory.reset(
new syncer::SyncManagerFactoryForProfileSyncTest(callback_));
options->credentials.email = "testuser@gmail.com";
options->credentials.sync_token = "token";
options->credentials.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope);
options->restored_key_for_bootstrapping.clear();
// It'd be nice if we avoided creating the InternalComponentsFactory in the
// first place, but SyncBackendHost will have created one by now so we must
// free it. Grab the switches to pass on first.
syncer::InternalComponentsFactory::Switches factory_switches =
options->internal_components_factory->GetSwitches();
options->internal_components_factory.reset(
new syncer::TestInternalComponentsFactory(
factory_switches,
syncer::InternalComponentsFactory::STORAGE_IN_MEMORY, nullptr));
browser_sync::SyncBackendHostImpl::InitCore(std::move(options));
}
void SyncBackendHostForProfileSyncTest::RequestConfigureSyncer(
syncer::ConfigureReason reason,
syncer::ModelTypeSet to_download,
syncer::ModelTypeSet to_purge,
syncer::ModelTypeSet to_journal,
syncer::ModelTypeSet to_unapply,
syncer::ModelTypeSet to_ignore,
const syncer::ModelSafeRoutingInfo& routing_info,
const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>&
ready_task,
const base::Closure& retry_callback) {
syncer::ModelTypeSet failed_configuration_types;
// The first parameter there should be the set of enabled types. That's not
// something we have access to from this strange test harness. We'll just
// send back the list of newly configured types instead and hope it doesn't
// break anything.
// Posted to avoid re-entrancy issues.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&SyncBackendHostForProfileSyncTest::
FinishConfigureDataTypesOnFrontendLoop,
base::Unretained(this),
syncer::Difference(to_download, failed_configuration_types),
syncer::Difference(to_download, failed_configuration_types),
failed_configuration_types, ready_task));
}
// Helper function for return-type-upcasting of the callback.
sync_driver::SyncService* GetSyncService(
base::Callback<TestProfileSyncService*(void)> get_sync_service_callback) {
return get_sync_service_callback.Run();
}
} // namespace
/* static */
syncer::ImmutableChangeRecordList
ProfileSyncServiceTestHelper::MakeSingletonChangeRecordList(
int64_t node_id,
syncer::ChangeRecord::Action action) {
syncer::ChangeRecord record;
record.action = action;
record.id = node_id;
syncer::ChangeRecordList records(1, record);
return syncer::ImmutableChangeRecordList(&records);
}
/* static */
syncer::ImmutableChangeRecordList
ProfileSyncServiceTestHelper::MakeSingletonDeletionChangeRecordList(
int64_t node_id,
const sync_pb::EntitySpecifics& specifics) {
syncer::ChangeRecord record;
record.action = syncer::ChangeRecord::ACTION_DELETE;
record.id = node_id;
record.specifics = specifics;
syncer::ChangeRecordList records(1, record);
return syncer::ImmutableChangeRecordList(&records);
}
AbstractProfileSyncServiceTest::AbstractProfileSyncServiceTest()
: data_type_thread_("Extra thread") {
CHECK(temp_dir_.CreateUniqueTempDir());
}
AbstractProfileSyncServiceTest::~AbstractProfileSyncServiceTest() {
sync_service_->Shutdown();
}
bool AbstractProfileSyncServiceTest::CreateRoot(ModelType model_type) {
return syncer::TestUserShare::CreateRoot(model_type,
sync_service_->GetUserShare());
}
void AbstractProfileSyncServiceTest::CreateSyncService(
scoped_ptr<sync_driver::SyncClient> sync_client,
const base::Closure& initialization_success_callback) {
DCHECK(sync_client);
ProfileSyncService::InitParams init_params =
profile_sync_service_bundle_.CreateBasicInitParams(
ProfileSyncService::AUTO_START, std::move(sync_client));
sync_service_ =
make_scoped_ptr(new TestProfileSyncService(std::move(init_params)));
SyncApiComponentFactoryMock* components =
profile_sync_service_bundle_.component_factory();
EXPECT_CALL(*components, CreateSyncBackendHost(_, _, _, _))
.WillOnce(Return(new SyncBackendHostForProfileSyncTest(
temp_dir_.path(), sync_service_->GetSyncClient(),
base::ThreadTaskRunnerHandle::Get(),
profile_sync_service_bundle_.fake_invalidation_service(),
sync_service_->sync_prefs()->AsWeakPtr(),
initialization_success_callback)));
sync_service_->SetFirstSetupComplete();
}
base::Callback<sync_driver::SyncService*(void)>
AbstractProfileSyncServiceTest::GetSyncServiceCallback() {
return base::Bind(GetSyncService,
base::Bind(&AbstractProfileSyncServiceTest::sync_service,
base::Unretained(this)));
}
CreateRootHelper::CreateRootHelper(AbstractProfileSyncServiceTest* test,
ModelType model_type)
: callback_(base::Bind(&CreateRootHelper::CreateRootCallback,
base::Unretained(this))),
test_(test),
model_type_(model_type),
success_(false) {
}
CreateRootHelper::~CreateRootHelper() {
}
const base::Closure& CreateRootHelper::callback() const {
return callback_;
}
bool CreateRootHelper::success() {
return success_;
}
void CreateRootHelper::CreateRootCallback() {
success_ = test_->CreateRoot(model_type_);
}