Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: chrome/browser/sync/glue/sync_backend_host_unittest.cc

Issue 10701085: Revert "Revert 142517 - [Sync] Refactor sync configuration logic." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile/test Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/glue/sync_backend_host.h" 5 #include "chrome/browser/sync/glue/sync_backend_host.h"
6 6
7 #include <cstddef> 7 #include <cstddef>
8 8
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "base/test/test_timeouts.h"
11 #include "chrome/browser/sync/invalidations/invalidator_storage.h" 13 #include "chrome/browser/sync/invalidations/invalidator_storage.h"
12 #include "chrome/browser/sync/sync_prefs.h" 14 #include "chrome/browser/sync/sync_prefs.h"
13 #include "chrome/test/base/testing_profile.h" 15 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/test/test_browser_thread.h" 16 #include "content/public/test/test_browser_thread.h"
15 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
16 #include "net/url_request/test_url_fetcher_factory.h" 18 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "sync/internal_api/public/base/model_type.h" 19 #include "sync/internal_api/public/base/model_type.h"
18 #include "sync/internal_api/public/engine/model_safe_worker.h" 20 #include "sync/internal_api/public/engine/model_safe_worker.h"
21 #include "sync/internal_api/public/sync_manager_factory.h"
22 #include "sync/internal_api/public/test/fake_sync_manager.h"
19 #include "sync/internal_api/public/util/experiments.h" 23 #include "sync/internal_api/public/util/experiments.h"
20 #include "sync/protocol/encryption.pb.h" 24 #include "sync/protocol/encryption.pb.h"
21 #include "sync/protocol/sync_protocol_error.h" 25 #include "sync/protocol/sync_protocol_error.h"
22 #include "sync/util/test_unrecoverable_error_handler.h" 26 #include "sync/util/test_unrecoverable_error_handler.h"
23 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
25 29
26 using content::BrowserThread; 30 using content::BrowserThread;
31 using syncer::FakeSyncManager;
32 using syncer::SyncManager;
33 using ::testing::InvokeWithoutArgs;
34 using ::testing::_;
27 35
28 namespace browser_sync { 36 namespace browser_sync {
29 37
30 namespace { 38 namespace {
31 39
40 ACTION_P(Signal, event) {
41 event->Signal();
42 }
43
44 void SignalEvent(base::WaitableEvent* event) {
45 event->Signal();
46 }
47
48 static void QuitMessageLoop() {
49 MessageLoop::current()->Quit();
50 }
51
32 class MockSyncFrontend : public SyncFrontend { 52 class MockSyncFrontend : public SyncFrontend {
33 public: 53 public:
34 virtual ~MockSyncFrontend() {} 54 virtual ~MockSyncFrontend() {}
35 55
36 MOCK_METHOD2(OnBackendInitialized, 56 MOCK_METHOD2(OnBackendInitialized,
37 void(const syncer::WeakHandle<syncer::JsBackend>&, bool)); 57 void(const syncer::WeakHandle<syncer::JsBackend>&, bool));
38 MOCK_METHOD0(OnSyncCycleCompleted, void()); 58 MOCK_METHOD0(OnSyncCycleCompleted, void());
39 MOCK_METHOD1(OnConnectionStatusChange, 59 MOCK_METHOD1(OnConnectionStatusChange,
40 void(syncer::ConnectionStatus status)); 60 void(syncer::ConnectionStatus status));
41 MOCK_METHOD0(OnStopSyncingPermanently, void()); 61 MOCK_METHOD0(OnStopSyncingPermanently, void());
42 MOCK_METHOD0(OnClearServerDataSucceeded, void()); 62 MOCK_METHOD0(OnClearServerDataSucceeded, void());
43 MOCK_METHOD0(OnClearServerDataFailed, void()); 63 MOCK_METHOD0(OnClearServerDataFailed, void());
44 MOCK_METHOD2(OnPassphraseRequired, 64 MOCK_METHOD2(OnPassphraseRequired,
45 void(syncer::PassphraseRequiredReason, 65 void(syncer::PassphraseRequiredReason,
46 const sync_pb::EncryptedData&)); 66 const sync_pb::EncryptedData&));
47 MOCK_METHOD0(OnPassphraseAccepted, void()); 67 MOCK_METHOD0(OnPassphraseAccepted, void());
48 MOCK_METHOD2(OnEncryptedTypesChanged, 68 MOCK_METHOD2(OnEncryptedTypesChanged,
49 void(syncer::ModelTypeSet, bool)); 69 void(syncer::ModelTypeSet, bool));
50 MOCK_METHOD0(OnEncryptionComplete, void()); 70 MOCK_METHOD0(OnEncryptionComplete, void());
51 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet)); 71 MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet));
52 MOCK_METHOD1(OnExperimentsChanged, 72 MOCK_METHOD1(OnExperimentsChanged,
53 void(const syncer::Experiments&)); 73 void(const syncer::Experiments&));
54 MOCK_METHOD1(OnActionableError, 74 MOCK_METHOD1(OnActionableError,
55 void(const syncer::SyncProtocolError& sync_error)); 75 void(const syncer::SyncProtocolError& sync_error));
56 MOCK_METHOD0(OnSyncConfigureRetry, void()); 76 MOCK_METHOD0(OnSyncConfigureRetry, void());
57 }; 77 };
58 78
59 } // namespace 79 class FakeSyncManagerFactory : public syncer::SyncManagerFactory {
80 public:
81 FakeSyncManagerFactory() : manager_(NULL) {}
82 virtual ~FakeSyncManagerFactory() {}
83
84 // Takes ownership of |manager|.
85 void SetSyncManager(FakeSyncManager* manager) {
86 DCHECK(!manager_.get());
87 manager_.reset(manager);
88 }
89
90 // Passes ownership of |manager_|.
91 // SyncManagerFactory implementation.
92 virtual scoped_ptr<SyncManager> CreateSyncManager(std::string name) OVERRIDE {
93 DCHECK(manager_.get());
94 return manager_.Pass();
95 }
96
97 private:
98 scoped_ptr<SyncManager> manager_;
99 };
100
101 class TestSyncBackendHost : public SyncBackendHost {
102 public:
103 TestSyncBackendHost(
104 const std::string& name,
105 Profile* profile,
106 const base::WeakPtr<SyncPrefs>& sync_prefs,
107 const base::WeakPtr<InvalidatorStorage>& invalidator_storage)
108 : SyncBackendHost(name, profile, sync_prefs, invalidator_storage) {
109 StartSyncThread();
110 }
111 virtual ~TestSyncBackendHost() {}
112
113 void PumpSyncLoop() {
rlarocque 2012/07/04 06:39:35 I'm amazed that there isn't a better way to do thi
Nicolas Zea 2012/07/09 18:40:45 How would MessageLoop::Quit help? The issue is tha
rlarocque 2012/07/09 19:22:58 My point is that it shouldn't be the test's respon
Nicolas Zea 2012/07/09 19:42:50 We do these kind of checks anywhere a single actio
114 DCHECK(sync_loop());
115 base::WaitableEvent done(true, false);
116 sync_loop()->PostTask(FROM_HERE, base::Bind(&SignalEvent, &done));
117 done.TimedWait(base::TimeDelta::FromMilliseconds(
118 TestTimeouts::action_timeout_ms()));
119 if (!done.IsSignaled())
120 FAIL() << "Timed out waiting for sync loop.";
121 }
122
123 void PostToSyncLoop(const base::Closure& closure) {
124 DCHECK(sync_loop());
125 sync_loop()->PostTask(FROM_HERE, closure);
126 }
127 };
60 128
61 class SyncBackendHostTest : public testing::Test { 129 class SyncBackendHostTest : public testing::Test {
62 protected: 130 protected:
63 SyncBackendHostTest() 131 SyncBackendHostTest()
64 : ui_thread_(BrowserThread::UI, &ui_loop_), 132 : ui_thread_(BrowserThread::UI, &ui_loop_),
65 io_thread_(BrowserThread::IO) {} 133 io_thread_(BrowserThread::IO),
134 fake_manager_(NULL) {}
66 135
67 virtual ~SyncBackendHostTest() {} 136 virtual ~SyncBackendHostTest() {}
68 137
69 virtual void SetUp() { 138 virtual void SetUp() OVERRIDE {
70 io_thread_.StartIOThread(); 139 io_thread_.StartIOThread();
140 profile_.reset(new TestingProfile());
141 profile_->CreateRequestContext();
142 sync_prefs_.reset(new SyncPrefs(profile_->GetPrefs()));
143 invalidator_storage_.reset(new InvalidatorStorage(profile_->GetPrefs()));
144 backend_.reset(new TestSyncBackendHost(
145 profile_->GetDebugName(),
146 profile_.get(),
147 sync_prefs_->AsWeakPtr(),
148 invalidator_storage_->AsWeakPtr()));
149 credentials_.email = "user@example.com";
150 credentials_.sync_token = "sync_token";
151
152 // The sync manager must be created on the sync loop in order to allow
153 // thread safety enforcement.
154 PostToSyncLoop(base::Bind(&SyncBackendHostTest::BuildSyncManager,
155 base::Unretained(this)));
156 PumpSyncLoop();
157 fake_sync_manager_factory_.SetSyncManager(fake_manager_);
158
159 // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend
160 // Registrar removing them if it can't find their model workers.
161 enabled_types_.Put(syncer::BOOKMARKS);
162 enabled_types_.Put(syncer::NIGORI);
163 enabled_types_.Put(syncer::PREFERENCES);
164 enabled_types_.Put(syncer::SESSIONS);
165 enabled_types_.Put(syncer::SEARCH_ENGINES);
166 enabled_types_.Put(syncer::AUTOFILL);
71 } 167 }
72 168
73 virtual void TearDown() { 169 virtual void TearDown() OVERRIDE {
170 backend_->StopSyncingForShutdown();
171 backend_->Shutdown(false);
172 backend_.reset();
173 sync_prefs_.reset();
174 invalidator_storage_.reset();
175 profile_.reset();
74 // Pump messages posted by the sync core thread (which may end up 176 // Pump messages posted by the sync core thread (which may end up
75 // posting on the IO thread). 177 // posting on the IO thread).
76 ui_loop_.RunAllPending(); 178 ui_loop_.RunAllPending();
77 io_thread_.Stop(); 179 io_thread_.Stop();
78 // Pump any messages posted by the IO thread. 180 // Pump any messages posted by the IO thread.
79 ui_loop_.RunAllPending(); 181 ui_loop_.RunAllPending();
80 } 182 }
81 183
82 private: 184 // Synchronously initializes the backend.
185 void InitializeBackend(syncer::ModelTypeSet enabled_types) {
186 EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, true)).
187 WillOnce(InvokeWithoutArgs(QuitMessageLoop));
188 backend_->Initialize(&mock_frontend_,
189 syncer::WeakHandle<syncer::JsEventHandler>(),
190 GURL(""),
191 enabled_types,
192 credentials_,
193 true,
194 &fake_sync_manager_factory_,
195 &handler_,
196 NULL);
197 ui_loop_.PostDelayedTask(
198 FROM_HERE,
199 ui_loop_.QuitClosure(),
200 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()));
201 ui_loop_.Run();
202 }
203
204 // Synchronously configures the backend's datatypes.
205 void ConfigureDataTypes(syncer::ModelTypeSet types_to_add,
206 syncer::ModelTypeSet types_to_remove,
207 BackendDataTypeConfigurer::NigoriState nigori_state) {
208 backend_->ConfigureDataTypes(
209 syncer::CONFIGURE_REASON_RECONFIGURATION,
210 types_to_add,
211 types_to_remove,
212 nigori_state,
213 base::Bind(&SyncBackendHostTest::DownloadReady,
214 base::Unretained(this)),
215 base::Bind(&SyncBackendHostTest::OnDownloadRetry,
216 base::Unretained(this)));
217 ui_loop_.PostDelayedTask(
218 FROM_HERE,
219 ui_loop_.QuitClosure(),
220 base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms()));
221 ui_loop_.Run();
222 }
223
224 protected:
225 // Note: should run on the sync thread.
226 void BuildSyncManager() {
227 DCHECK(!fake_manager_);
228 fake_manager_ = new FakeSyncManager("name");
229 }
230
231 void PumpSyncLoop() {
232 backend_->PumpSyncLoop();
233 }
234
235 void PostToSyncLoop(const base::Closure& closure) {
236 backend_->PostToSyncLoop(closure);
237 }
238
239 void DownloadReady(syncer::ModelTypeSet types) {
240 MessageLoop::current()->Quit();
241 }
242
243 void OnDownloadRetry() {
244 NOTIMPLEMENTED();
245 }
246
83 MessageLoop ui_loop_; 247 MessageLoop ui_loop_;
84 content::TestBrowserThread ui_thread_; 248 content::TestBrowserThread ui_thread_;
85 content::TestBrowserThread io_thread_; 249 content::TestBrowserThread io_thread_;
250 MockSyncFrontend mock_frontend_;
251 syncer::SyncCredentials credentials_;
252 syncer::TestUnrecoverableErrorHandler handler_;
253 scoped_ptr<TestingProfile> profile_;
254 scoped_ptr<SyncPrefs> sync_prefs_;
255 scoped_ptr<InvalidatorStorage> invalidator_storage_;
256 scoped_ptr<TestSyncBackendHost> backend_;
257 FakeSyncManagerFactory fake_sync_manager_factory_;
258 FakeSyncManager* fake_manager_;
259 syncer::ModelTypeSet enabled_types_;
86 }; 260 };
87 261
262 // Test basic initialization with no initial types (first time initialization).
263 // Only the nigori should be configured.
88 TEST_F(SyncBackendHostTest, InitShutdown) { 264 TEST_F(SyncBackendHostTest, InitShutdown) {
89 std::string k_mock_url = "http://www.example.com"; 265 InitializeBackend(syncer::ModelTypeSet());
90 net::FakeURLFetcherFactory test_factory_;
91 test_factory_.SetFakeResponse(k_mock_url + "/time?command=get_time", "",
92 false);
93 266
94 TestingProfile profile; 267 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Has(syncer::NIGORI));
95 profile.CreateRequestContext(); 268 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
96 269 syncer::ModelTypeSet(syncer::NIGORI)).Empty());
97 SyncPrefs sync_prefs(profile.GetPrefs());
98 InvalidatorStorage invalidator_storage(profile.GetPrefs());
99 SyncBackendHost backend(profile.GetDebugName(),
100 &profile, sync_prefs.AsWeakPtr(),
101 invalidator_storage.AsWeakPtr());
102
103 MockSyncFrontend mock_frontend;
104 syncer::SyncCredentials credentials;
105 credentials.email = "user@example.com";
106 credentials.sync_token = "sync_token";
107 syncer::TestUnrecoverableErrorHandler handler;
108 backend.Initialize(&mock_frontend,
109 syncer::WeakHandle<syncer::JsEventHandler>(),
110 GURL(k_mock_url),
111 syncer::ModelTypeSet(),
112 credentials,
113 true,
114 &handler,
115 NULL);
116 backend.StopSyncingForShutdown();
117 backend.Shutdown(false);
118 } 270 }
119 271
120 // TODO(akalin): Write more SyncBackendHost unit tests. 272 // Test first time sync scenario. All types should be properly configured.
273 TEST_F(SyncBackendHostTest, FirstTimeSync) {
274 InitializeBackend(syncer::ModelTypeSet());
275 ConfigureDataTypes(enabled_types_,
276 syncer::ModelTypeSet(),
277 BackendDataTypeConfigurer::WITH_NIGORI);
278
279 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
280 enabled_types_));
281 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
282 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
283 enabled_types_).Empty());
284 }
285
286 // Test the restart after setting up sync scenario. No enabled types should be
287 // downloaded or cleaned.
288 TEST_F(SyncBackendHostTest, Restart) {
289 syncer::ModelTypeSet all_but_nigori = enabled_types_;
290 fake_manager_->set_progress_marker_types(
291 enabled_types_);
292 fake_manager_->set_initial_sync_ended_types(enabled_types_);
293 InitializeBackend(enabled_types_);
294 ConfigureDataTypes(enabled_types_,
295 syncer::ModelTypeSet(),
296 BackendDataTypeConfigurer::WITH_NIGORI);
297
298 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty());
299 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
300 enabled_types_).Empty());
301 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
302 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
303 enabled_types_).Empty());
304 }
305
306 // Test a sync restart scenario where the nigori had never finished configuring.
307 // The nigori should be cleaned up, then reconfigured properly.
308 TEST_F(SyncBackendHostTest, PartialNigori) {
309 // Set sync manager behavior before passing it down. All types have progress
310 // markers, but nigori is missing initial sync ended.
311 syncer::ModelTypeSet all_but_nigori = enabled_types_;
312 all_but_nigori.Remove(syncer::NIGORI);
313 fake_manager_->set_progress_marker_types(
314 enabled_types_);
315 fake_manager_->set_initial_sync_ended_types(all_but_nigori);
316 InitializeBackend(enabled_types_);
317
318 // Nigori should have been cleaned up, then configured.
319 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
320 enabled_types_).
321 Equals(syncer::ModelTypeSet(syncer::NIGORI)));
322 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Equals(
323 syncer::ModelTypeSet(syncer::NIGORI)));
324 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Has(syncer::NIGORI));
325 }
326
327 // Test the behavior when we lose the sync db. Although we already have types
328 // enabled, we should re-download all of them because we lost their data.
329 TEST_F(SyncBackendHostTest, LostDB) {
330 // Don't set any progress marker or initial_sync_ended types before
331 // initializing.
332 InitializeBackend(enabled_types_);
333 ConfigureDataTypes(enabled_types_,
334 syncer::ModelTypeSet(),
335 BackendDataTypeConfigurer::WITH_NIGORI);
336
337 EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll(
338 enabled_types_));
339 EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(),
340 enabled_types_).Empty());
341 EXPECT_TRUE(fake_manager_->InitialSyncEndedTypes().Equals(enabled_types_));
342 EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken(
343 enabled_types_).Empty());
344 }
345
346 } // namespace
121 347
122 } // namespace browser_sync 348 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698