1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/deferred_sequenced_task_runner.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "sync/engine/model_type_sync_proxy_impl.h"
11 #include "sync/internal_api/public/base/model_type.h"
12 #include "sync/sessions/model_type_registry.h"
13 #include "sync/test/engine/fake_model_worker.h"
14 #include "sync/test/engine/mock_nudge_handler.h"
15 #include "sync/test/engine/test_directory_setter_upper.h"
16 #include "testing/gtest/include/gtest/gtest.h"
20 class ModelTypeRegistryTest : public ::testing::Test {
22 ModelTypeRegistryTest();
23 virtual void SetUp() override;
24 virtual void TearDown() override;
26 ModelTypeRegistry* registry();
28 static DataTypeState MakeInitialDataTypeState(ModelType type) {
30 state.progress_marker.set_data_type_id(
31 GetSpecificsFieldNumberFromModelType(type));
32 state.next_client_id = 0;
37 syncable::Directory* directory();
39 base::MessageLoop message_loop_;
41 TestDirectorySetterUpper dir_maker_;
42 std::vector<scoped_refptr<ModelSafeWorker> > workers_;
43 scoped_ptr<ModelTypeRegistry> registry_;
44 MockNudgeHandler mock_nudge_handler_;
47 ModelTypeRegistryTest::ModelTypeRegistryTest() {}
49 void ModelTypeRegistryTest::SetUp() {
51 scoped_refptr<ModelSafeWorker> passive_worker(
52 new FakeModelWorker(GROUP_PASSIVE));
53 scoped_refptr<ModelSafeWorker> ui_worker(
54 new FakeModelWorker(GROUP_UI));
55 scoped_refptr<ModelSafeWorker> db_worker(
56 new FakeModelWorker(GROUP_DB));
57 workers_.push_back(passive_worker);
58 workers_.push_back(ui_worker);
59 workers_.push_back(db_worker);
62 new ModelTypeRegistry(workers_, directory(), &mock_nudge_handler_));
65 void ModelTypeRegistryTest::TearDown() {
68 dir_maker_.TearDown();
71 ModelTypeRegistry* ModelTypeRegistryTest::registry() {
72 return registry_.get();
75 syncable::Directory* ModelTypeRegistryTest::directory() {
76 return dir_maker_.directory();
79 // Create some directory update handlers and commit contributors.
81 // We don't get to inspect any of the state we're modifying. This test is
82 // useful only for detecting crashes or memory leaks.
83 TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Once) {
84 ModelSafeRoutingInfo routing_info;
85 routing_info.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
86 routing_info.insert(std::make_pair(BOOKMARKS, GROUP_UI));
87 routing_info.insert(std::make_pair(AUTOFILL, GROUP_DB));
89 registry()->SetEnabledDirectoryTypes(routing_info);
92 // Try two different routing info settings.
94 // We don't get to inspect any of the state we're modifying. This test is
95 // useful only for detecting crashes or memory leaks.
96 TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Repeatedly) {
97 ModelSafeRoutingInfo routing_info1;
98 routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
99 routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_PASSIVE));
100 routing_info1.insert(std::make_pair(AUTOFILL, GROUP_PASSIVE));
102 registry()->SetEnabledDirectoryTypes(routing_info1);
104 ModelSafeRoutingInfo routing_info2;
105 routing_info2.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
106 routing_info2.insert(std::make_pair(BOOKMARKS, GROUP_UI));
107 routing_info2.insert(std::make_pair(AUTOFILL, GROUP_DB));
109 registry()->SetEnabledDirectoryTypes(routing_info2);
112 // Test removing all types from the list.
114 // We don't get to inspect any of the state we're modifying. This test is
115 // useful only for detecting crashes or memory leaks.
116 TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_Clear) {
117 ModelSafeRoutingInfo routing_info1;
118 routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
119 routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
120 routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));
122 registry()->SetEnabledDirectoryTypes(routing_info1);
124 ModelSafeRoutingInfo routing_info2;
125 registry()->SetEnabledDirectoryTypes(routing_info2);
128 // Test disabling then re-enabling some directory types.
130 // We don't get to inspect any of the state we're modifying. This test is
131 // useful only for detecting crashes or memory leaks.
132 TEST_F(ModelTypeRegistryTest, SetEnabledDirectoryTypes_OffAndOn) {
133 ModelSafeRoutingInfo routing_info1;
134 routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
135 routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
136 routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));
138 registry()->SetEnabledDirectoryTypes(routing_info1);
140 ModelSafeRoutingInfo routing_info2;
141 registry()->SetEnabledDirectoryTypes(routing_info2);
143 registry()->SetEnabledDirectoryTypes(routing_info1);
146 TEST_F(ModelTypeRegistryTest, NonBlockingTypes) {
147 ModelTypeSyncProxyImpl themes_sync_proxy(syncer::THEMES);
148 ModelTypeSyncProxyImpl sessions_sync_proxy(syncer::SESSIONS);
149 scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
150 new base::DeferredSequencedTaskRunner(
151 base::ThreadTaskRunnerHandle::Get());
153 EXPECT_TRUE(registry()->GetEnabledTypes().Empty());
155 registry()->ConnectSyncTypeToWorker(syncer::THEMES,
156 MakeInitialDataTypeState(THEMES),
157 UpdateResponseDataList(),
159 themes_sync_proxy.AsWeakPtrForUI());
160 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
161 ModelTypeSet(syncer::THEMES)));
163 registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
164 MakeInitialDataTypeState(SESSIONS),
165 UpdateResponseDataList(),
167 sessions_sync_proxy.AsWeakPtrForUI());
168 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
169 ModelTypeSet(syncer::THEMES, syncer::SESSIONS)));
171 registry()->DisconnectSyncWorker(syncer::THEMES);
172 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
173 ModelTypeSet(syncer::SESSIONS)));
175 // Allow ModelTypeRegistry destruction to delete the
176 // Sessions' ModelTypeSyncWorker.
179 TEST_F(ModelTypeRegistryTest, NonBlockingTypesWithDirectoryTypes) {
180 ModelTypeSyncProxyImpl themes_sync_proxy(syncer::THEMES);
181 ModelTypeSyncProxyImpl sessions_sync_proxy(syncer::SESSIONS);
182 scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
183 new base::DeferredSequencedTaskRunner(
184 base::ThreadTaskRunnerHandle::Get());
186 ModelSafeRoutingInfo routing_info1;
187 routing_info1.insert(std::make_pair(NIGORI, GROUP_PASSIVE));
188 routing_info1.insert(std::make_pair(BOOKMARKS, GROUP_UI));
189 routing_info1.insert(std::make_pair(AUTOFILL, GROUP_DB));
191 ModelTypeSet current_types;
192 EXPECT_TRUE(registry()->GetEnabledTypes().Empty());
194 // Add the themes non-blocking type.
195 registry()->ConnectSyncTypeToWorker(syncer::THEMES,
196 MakeInitialDataTypeState(THEMES),
197 UpdateResponseDataList(),
199 themes_sync_proxy.AsWeakPtrForUI());
200 current_types.Put(syncer::THEMES);
201 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
203 // Add some directory types.
204 registry()->SetEnabledDirectoryTypes(routing_info1);
205 current_types.PutAll(GetRoutingInfoTypes(routing_info1));
206 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
208 // Add sessions non-blocking type.
209 registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
210 MakeInitialDataTypeState(SESSIONS),
211 UpdateResponseDataList(),
213 sessions_sync_proxy.AsWeakPtrForUI());
214 current_types.Put(syncer::SESSIONS);
215 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
217 // Remove themes non-blocking type.
218 registry()->DisconnectSyncWorker(syncer::THEMES);
219 current_types.Remove(syncer::THEMES);
220 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
222 // Clear all directory types.
223 ModelSafeRoutingInfo routing_info2;
224 registry()->SetEnabledDirectoryTypes(routing_info2);
225 current_types.RemoveAll(GetRoutingInfoTypes(routing_info1));
226 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(current_types));
229 TEST_F(ModelTypeRegistryTest, DeletionOrdering) {
230 scoped_ptr<ModelTypeSyncProxyImpl> themes_sync_proxy(
231 new ModelTypeSyncProxyImpl(syncer::THEMES));
232 scoped_ptr<ModelTypeSyncProxyImpl> sessions_sync_proxy(
233 new ModelTypeSyncProxyImpl(syncer::SESSIONS));
234 scoped_refptr<base::DeferredSequencedTaskRunner> task_runner =
235 new base::DeferredSequencedTaskRunner(
236 base::ThreadTaskRunnerHandle::Get());
238 EXPECT_TRUE(registry()->GetEnabledTypes().Empty());
240 registry()->ConnectSyncTypeToWorker(syncer::THEMES,
241 MakeInitialDataTypeState(THEMES),
242 UpdateResponseDataList(),
244 themes_sync_proxy->AsWeakPtrForUI());
245 registry()->ConnectSyncTypeToWorker(syncer::SESSIONS,
246 MakeInitialDataTypeState(SESSIONS),
247 UpdateResponseDataList(),
249 sessions_sync_proxy->AsWeakPtrForUI());
250 EXPECT_TRUE(registry()->GetEnabledTypes().Equals(
251 ModelTypeSet(syncer::THEMES, syncer::SESSIONS)));
253 // Tear down themes processing, starting with the worker.
254 registry()->DisconnectSyncWorker(syncer::THEMES);
255 themes_sync_proxy.reset();
257 // Tear down sessions processing, starting with the type sync proxy.
258 sessions_sync_proxy.reset();
259 registry()->DisconnectSyncWorker(syncer::SESSIONS);
261 EXPECT_TRUE(registry()->GetEnabledTypes().Empty());
264 } // namespace syncer