blob: 43c4fa4d25cbe47ab9868db4231e5b817bd13428 [file] [log] [blame]
// Copyright 2014 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 "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/test/test_simple_task_runner.h"
#include "components/sync_driver/non_blocking_data_type_controller.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/non_blocking_type_processor.h"
#include "sync/internal_api/public/sync_core_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
class MockSyncCoreProxy : public syncer::SyncCoreProxy {
public:
MockSyncCoreProxy() {}
virtual ~MockSyncCoreProxy() {}
virtual void ConnectTypeToCore(
syncer::ModelType type,
base::WeakPtr<syncer::NonBlockingTypeProcessor> type_processor) OVERRIDE {
type_processor->OnConnect(
base::WeakPtr<syncer::NonBlockingTypeProcessorCore>(),
scoped_refptr<base::SequencedTaskRunner>());
}
virtual scoped_ptr<SyncCoreProxy> Clone() const OVERRIDE {
return scoped_ptr<SyncCoreProxy>(new MockSyncCoreProxy());
}
};
class NonBlockingDataTypeControllerTest : public testing::Test {
public:
NonBlockingDataTypeControllerTest()
: processor_(syncer::DICTIONARY),
model_thread_(new base::TestSimpleTaskRunner()),
controller_(syncer::DICTIONARY, true) {}
virtual ~NonBlockingDataTypeControllerTest() {}
// Connects the processor to the NonBlockingDataTypeController.
void InitProcessor() {
controller_.InitializeProcessor(
model_thread_, processor_.AsWeakPtr());
RunQueuedTasks();
}
// Connects the sync backend to the NonBlockingDataTypeController.
void InitSync() {
controller_.InitializeSyncCoreProxy(mock_core_proxy_.Clone());
RunQueuedTasks();
}
// Disconnects the sync backend from the NonBlockingDataTypeController.
void UninitializeSync() {
controller_.ClearSyncCoreProxy();
RunQueuedTasks();
}
// Toggles the user's preference for syncing this type.
void SetIsPreferred(bool preferred) {
controller_.SetIsPreferred(preferred);
RunQueuedTasks();
}
// The processor pretends to run tasks on a different thread.
// This function runs any posted tasks.
void RunQueuedTasks() {
model_thread_->RunUntilIdle();
}
protected:
MockSyncCoreProxy mock_core_proxy_;
syncer::NonBlockingTypeProcessor processor_;
scoped_refptr<base::TestSimpleTaskRunner> model_thread_;
browser_sync::NonBlockingDataTypeController controller_;
};
// Initialization when the user has disabled syncing for this type.
TEST_F(NonBlockingDataTypeControllerTest, UserDisabled) {
SetIsPreferred(false);
InitProcessor();
InitSync();
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
UninitializeSync();
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
}
// Init the sync backend then the type processor.
TEST_F(NonBlockingDataTypeControllerTest, Enabled_SyncFirst) {
SetIsPreferred(true);
InitSync();
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
InitProcessor();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
UninitializeSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
}
// Init the type processor then the sync backend.
TEST_F(NonBlockingDataTypeControllerTest, Enabled_ProcessorFirst) {
SetIsPreferred(true);
InitProcessor();
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
InitSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
UninitializeSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
}
// Initialize sync then disable it with a pref change.
TEST_F(NonBlockingDataTypeControllerTest, PreferThenNot) {
SetIsPreferred(true);
InitProcessor();
InitSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
SetIsPreferred(false);
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
}
// Connect type processor and sync backend, then toggle prefs repeatedly.
TEST_F(NonBlockingDataTypeControllerTest, RepeatedTogglePreference) {
SetIsPreferred(false);
InitProcessor();
InitSync();
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
SetIsPreferred(true);
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
SetIsPreferred(false);
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
SetIsPreferred(true);
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
SetIsPreferred(false);
EXPECT_FALSE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
}
// Test sync backend getting restarted while processor is connected.
TEST_F(NonBlockingDataTypeControllerTest, RestartSyncBackend) {
SetIsPreferred(true);
InitProcessor();
InitSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
// Shutting down sync backend should disconnect but not disable the type.
UninitializeSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_FALSE(processor_.IsConnected());
// Brining the backend back should reconnect the type.
InitSync();
EXPECT_TRUE(processor_.IsPreferred());
EXPECT_TRUE(processor_.IsConnected());
}
// Test sync backend being restarted before processor connects.
TEST_F(NonBlockingDataTypeControllerTest, RestartSyncBackendEarly) {
SetIsPreferred(true);
// Toggle sync off and on before the type processor is available.
InitSync();
EXPECT_FALSE(processor_.IsConnected());
UninitializeSync();
EXPECT_FALSE(processor_.IsConnected());
InitSync();
EXPECT_FALSE(processor_.IsConnected());
// Introduce the processor.
InitProcessor();
EXPECT_TRUE(processor_.IsConnected());
}
// Test pref toggling before the sync backend has connected.
TEST_F(NonBlockingDataTypeControllerTest, TogglePreferenceWithoutBackend) {
SetIsPreferred(true);
InitProcessor();
// This should emit a disable signal.
SetIsPreferred(false);
EXPECT_FALSE(processor_.IsConnected());
EXPECT_FALSE(processor_.IsPreferred());
// This won't enable us, since we don't have a sync backend.
SetIsPreferred(true);
EXPECT_FALSE(processor_.IsConnected());
EXPECT_FALSE(processor_.IsPreferred());
// Only now do we start sending enable signals.
InitSync();
EXPECT_TRUE(processor_.IsConnected());
EXPECT_TRUE(processor_.IsPreferred());
}
} // namespace