sync_backend_registrar_unittest.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
1// Copyright (c) 2012 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.
4
5#include "chrome/browser/sync/glue/sync_backend_registrar.h"
6
7#include "chrome/browser/sync/glue/ui_model_worker.h"
8#include "chrome/test/base/testing_profile.h"
9#include "components/sync_driver/change_processor_mock.h"
10#include "content/public/browser/browser_thread.h"
11#include "content/public/test/test_browser_thread_bundle.h"
12#include "sync/internal_api/public/base/model_type.h"
13#include "sync/internal_api/public/test/test_user_share.h"
14#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace browser_sync {
18
19namespace {
20
21using ::testing::_;
22using ::testing::InSequence;
23using ::testing::Return;
24using ::testing::StrictMock;
25using content::BrowserThread;
26using syncer::FIRST_REAL_MODEL_TYPE;
27using syncer::AUTOFILL;
28using syncer::BOOKMARKS;
29using syncer::PREFERENCES;
30using syncer::THEMES;
31using syncer::NIGORI;
32using syncer::PASSWORDS;
33using syncer::MODEL_TYPE_COUNT;
34using syncer::ModelTypeSet;
35using syncer::ModelType;
36using syncer::ModelTypeFromInt;
37
38void TriggerChanges(SyncBackendRegistrar* registrar, ModelType type) {
39  registrar->OnChangesApplied(type, 0, NULL,
40                              syncer::ImmutableChangeRecordList());
41  registrar->OnChangesComplete(type);
42}
43
44class SyncBackendRegistrarTest : public testing::Test {
45 public:
46  void TestNonUIDataTypeActivationAsync(ChangeProcessor* processor,
47                                        base::WaitableEvent* done) {
48    registrar_->ActivateDataType(AUTOFILL,
49                                 syncer::GROUP_DB,
50                                 processor,
51                                 test_user_share_.user_share());
52    syncer::ModelSafeRoutingInfo expected_routing_info;
53    expected_routing_info[AUTOFILL] = syncer::GROUP_DB;
54    ExpectRoutingInfo(registrar_.get(), expected_routing_info);
55    ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet(AUTOFILL));
56    TriggerChanges(registrar_.get(), AUTOFILL);
57    done->Signal();
58  }
59
60 protected:
61  SyncBackendRegistrarTest()
62      : sync_thread_(NULL),
63        thread_bundle_(content::TestBrowserThreadBundle::REAL_DB_THREAD |
64                       content::TestBrowserThreadBundle::REAL_FILE_THREAD |
65                       content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
66
67  virtual ~SyncBackendRegistrarTest() {}
68
69  virtual void SetUp() {
70    test_user_share_.SetUp();
71    registrar_.reset(new SyncBackendRegistrar("test", &profile_,
72                                              scoped_ptr<base::Thread>()));
73    sync_thread_ = registrar_->sync_thread();
74  }
75
76  virtual void TearDown() {
77    registrar_->RequestWorkerStopOnUIThread();
78    test_user_share_.TearDown();
79    sync_thread_->message_loop()->PostTask(
80        FROM_HERE,
81        base::Bind(&SyncBackendRegistrar::Shutdown,
82                   base::Unretained(registrar_.release())));
83    sync_thread_->message_loop()->RunUntilIdle();
84  }
85
86  void ExpectRoutingInfo(
87      SyncBackendRegistrar* registrar,
88      const syncer::ModelSafeRoutingInfo& expected_routing_info) {
89    syncer::ModelSafeRoutingInfo routing_info;
90    registrar->GetModelSafeRoutingInfo(&routing_info);
91    EXPECT_EQ(expected_routing_info, routing_info);
92  }
93
94  void ExpectHasProcessorsForTypes(const SyncBackendRegistrar& registrar,
95                                   ModelTypeSet types) {
96    for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
97      ModelType model_type = ModelTypeFromInt(i);
98      EXPECT_EQ(types.Has(model_type),
99                registrar_->IsTypeActivatedForTest(model_type));
100    }
101  }
102
103  syncer::TestUserShare test_user_share_;
104  TestingProfile profile_;
105  scoped_ptr<SyncBackendRegistrar> registrar_;
106
107  base::Thread* sync_thread_;
108  content::TestBrowserThreadBundle thread_bundle_;
109};
110
111TEST_F(SyncBackendRegistrarTest, ConstructorEmpty) {
112  registrar_->SetInitialTypes(ModelTypeSet());
113  EXPECT_FALSE(registrar_->IsNigoriEnabled());
114  {
115    std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers;
116    registrar_->GetWorkers(&workers);
117    EXPECT_EQ(4u, workers.size());
118  }
119  ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
120  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
121}
122
123TEST_F(SyncBackendRegistrarTest, ConstructorNonEmpty) {
124  const ModelTypeSet initial_types(BOOKMARKS, NIGORI, PASSWORDS);
125  registrar_->SetInitialTypes(initial_types);
126  EXPECT_TRUE(registrar_->IsNigoriEnabled());
127  {
128    std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers;
129    registrar_->GetWorkers(&workers);
130    EXPECT_EQ(4u, workers.size());
131  }
132  {
133    syncer::ModelSafeRoutingInfo expected_routing_info;
134    expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
135    expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
136    // Passwords dropped because of no password store.
137    ExpectRoutingInfo(registrar_.get(), expected_routing_info);
138  }
139  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
140}
141
142TEST_F(SyncBackendRegistrarTest, ConfigureDataTypes) {
143  registrar_->SetInitialTypes(ModelTypeSet());
144
145  // Add.
146  const ModelTypeSet types1(BOOKMARKS, NIGORI, AUTOFILL);
147  EXPECT_TRUE(
148      registrar_->ConfigureDataTypes(types1, ModelTypeSet()).Equals(types1));
149  {
150    syncer::ModelSafeRoutingInfo expected_routing_info;
151    expected_routing_info[BOOKMARKS] = syncer::GROUP_PASSIVE;
152    expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE;
153    expected_routing_info[AUTOFILL] = syncer::GROUP_PASSIVE;
154    ExpectRoutingInfo(registrar_.get(), expected_routing_info);
155  }
156  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
157  EXPECT_TRUE(types1.Equals(registrar_->GetLastConfiguredTypes()));
158
159  // Add and remove.
160  const ModelTypeSet types2(PREFERENCES, THEMES);
161  EXPECT_TRUE(registrar_->ConfigureDataTypes(types2, types1).Equals(types2));
162  {
163    syncer::ModelSafeRoutingInfo expected_routing_info;
164    expected_routing_info[PREFERENCES] = syncer::GROUP_PASSIVE;
165    expected_routing_info[THEMES] = syncer::GROUP_PASSIVE;
166    ExpectRoutingInfo(registrar_.get(), expected_routing_info);
167  }
168  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
169  EXPECT_TRUE(types2.Equals(registrar_->GetLastConfiguredTypes()));
170
171  // Remove.
172  EXPECT_TRUE(registrar_->ConfigureDataTypes(ModelTypeSet(), types2).Empty());
173  ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
174  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
175  EXPECT_TRUE(ModelTypeSet().Equals(registrar_->GetLastConfiguredTypes()));
176}
177
178TEST_F(SyncBackendRegistrarTest, ActivateDeactivateUIDataType) {
179  InSequence in_sequence;
180  registrar_->SetInitialTypes(ModelTypeSet());
181
182  // Should do nothing.
183  TriggerChanges(registrar_.get(), BOOKMARKS);
184
185  StrictMock<ChangeProcessorMock> change_processor_mock;
186  EXPECT_CALL(change_processor_mock, StartImpl());
187  EXPECT_CALL(change_processor_mock, IsRunning())
188      .WillRepeatedly(Return(true));
189  EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
190  EXPECT_CALL(change_processor_mock, IsRunning())
191      .WillRepeatedly(Return(true));
192  EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
193  EXPECT_CALL(change_processor_mock, IsRunning())
194      .WillRepeatedly(Return(false));
195
196  const ModelTypeSet types(BOOKMARKS);
197  EXPECT_TRUE(
198      registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
199  registrar_->ActivateDataType(BOOKMARKS, syncer::GROUP_UI,
200                             &change_processor_mock,
201                             test_user_share_.user_share());
202  {
203    syncer::ModelSafeRoutingInfo expected_routing_info;
204    expected_routing_info[BOOKMARKS] = syncer::GROUP_UI;
205    ExpectRoutingInfo(registrar_.get(), expected_routing_info);
206  }
207  ExpectHasProcessorsForTypes(*registrar_, types);
208
209  TriggerChanges(registrar_.get(), BOOKMARKS);
210
211  registrar_->DeactivateDataType(BOOKMARKS);
212  ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
213  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
214
215  // Should do nothing.
216  TriggerChanges(registrar_.get(), BOOKMARKS);
217}
218
219TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) {
220  InSequence in_sequence;
221  registrar_->SetInitialTypes(ModelTypeSet());
222
223  // Should do nothing.
224  TriggerChanges(registrar_.get(), AUTOFILL);
225
226  StrictMock<ChangeProcessorMock> change_processor_mock;
227  EXPECT_CALL(change_processor_mock, StartImpl());
228  EXPECT_CALL(change_processor_mock, IsRunning())
229      .WillRepeatedly(Return(true));
230  EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _));
231  EXPECT_CALL(change_processor_mock, IsRunning())
232      .WillRepeatedly(Return(true));
233  EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel());
234  EXPECT_CALL(change_processor_mock, IsRunning())
235      .WillRepeatedly(Return(false));
236
237  const ModelTypeSet types(AUTOFILL);
238  EXPECT_TRUE(
239      registrar_->ConfigureDataTypes(types, ModelTypeSet()).Equals(types));
240
241  base::WaitableEvent done(false, false);
242  BrowserThread::PostTask(
243      BrowserThread::DB,
244      FROM_HERE,
245      base::Bind(&SyncBackendRegistrarTest::TestNonUIDataTypeActivationAsync,
246                 base::Unretained(this),
247                 &change_processor_mock,
248                 &done));
249  done.Wait();
250
251  registrar_->DeactivateDataType(AUTOFILL);
252  ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo());
253  ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet());
254
255  // Should do nothing.
256  TriggerChanges(registrar_.get(), AUTOFILL);
257}
258
259}  // namespace
260
261}  // namespace browser_sync
262