Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / device_info_sync_service_unittest.cc
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.
4
5 #include "base/message_loop/message_loop.h"
6 #include "chrome/browser/sync/glue/local_device_info_provider_mock.h"
7 #include "components/sync_driver/device_info_sync_service.h"
8 #include "content/public/test/test_browser_thread_bundle.h"
9 #include "sync/api/sync_change.h"
10 #include "sync/api/sync_change_processor.h"
11 #include "sync/api/sync_change_processor_wrapper_for_test.h"
12 #include "sync/api/sync_error_factory_mock.h"
13 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
14 #include "sync/util/time.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using sync_driver::DeviceInfoSyncService;
18 using sync_driver::DeviceInfoTracker;
19 using syncer::AttachmentIdList;
20 using syncer::AttachmentServiceProxyForTest;
21 using syncer::ModelType;
22 using syncer::SyncChange;
23 using syncer::SyncChangeList;
24 using syncer::SyncChangeProcessor;
25 using syncer::SyncChangeProcessorWrapperForTest;
26 using syncer::SyncData;
27 using syncer::SyncDataList;
28 using syncer::SyncError;
29 using syncer::SyncErrorFactory;
30 using syncer::SyncErrorFactoryMock;
31 using syncer::SyncMergeResult;
32
33 namespace browser_sync {
34
35 namespace {
36
37 class TestChangeProcessor : public SyncChangeProcessor {
38  public:
39   TestChangeProcessor() {}
40   virtual ~TestChangeProcessor() {}
41
42   // SyncChangeProcessor implementation.
43   // Store a copy of all the changes passed in so we can examine them later.
44   virtual SyncError ProcessSyncChanges(
45       const tracked_objects::Location& from_here,
46       const SyncChangeList& change_list) OVERRIDE {
47     change_list_ = change_list;
48     return SyncError();
49   }
50
51   // This method isn't used in these tests.
52   virtual SyncDataList GetAllSyncData(ModelType type) const OVERRIDE {
53     return SyncDataList();
54   }
55
56   size_t change_list_size() const { return change_list_.size(); }
57
58   SyncChange::SyncChangeType change_type_at(size_t index) const {
59     CHECK_LT(index, change_list_size());
60     return change_list_[index].change_type();
61   }
62
63   const sync_pb::DeviceInfoSpecifics& device_info_at(size_t index) const {
64     CHECK_LT(index, change_list_size());
65     return change_list_[index].sync_data().GetSpecifics().device_info();
66   }
67
68   const std::string& cache_guid_at(size_t index) const {
69     return device_info_at(index).cache_guid();
70   }
71
72   const std::string& client_name_at(size_t index) const {
73     return device_info_at(index).client_name();
74   }
75
76  private:
77   SyncChangeList change_list_;
78 };
79
80 class DeviceInfoSyncServiceTest : public testing::Test,
81                                   public DeviceInfoTracker::Observer {
82  public:
83   DeviceInfoSyncServiceTest() : num_device_info_changed_callbacks_(0) {}
84   virtual ~DeviceInfoSyncServiceTest() {}
85
86   virtual void SetUp() OVERRIDE {
87     local_device_.reset(new LocalDeviceInfoProviderMock(
88         "guid_1",
89         "client_1",
90         "Chromium 10k",
91         "Chrome 10k",
92         sync_pb::SyncEnums_DeviceType_TYPE_LINUX,
93         "device_id"));
94     sync_service_.reset(new DeviceInfoSyncService(local_device_.get()));
95     sync_processor_.reset(new TestChangeProcessor());
96     // Register observer
97     sync_service_->AddObserver(this);
98   }
99
100   virtual void TearDown() OVERRIDE {
101     sync_service_->RemoveObserver(this);
102   }
103
104   virtual void OnDeviceInfoChange() OVERRIDE {
105     num_device_info_changed_callbacks_++;
106   }
107
108   scoped_ptr<SyncChangeProcessor> PassProcessor() {
109     return scoped_ptr<SyncChangeProcessor>(
110         new SyncChangeProcessorWrapperForTest(sync_processor_.get()));
111   }
112
113   scoped_ptr<SyncErrorFactory> CreateAndPassSyncErrorFactory() {
114     return scoped_ptr<SyncErrorFactory>(new SyncErrorFactoryMock());
115   }
116
117   SyncData CreateRemoteData(const std::string& client_id,
118                             const std::string& client_name,
119                             int64 backup_timestamp = 0) {
120     sync_pb::EntitySpecifics entity;
121     sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info();
122
123     specifics.set_cache_guid(client_id);
124     specifics.set_client_name(client_name);
125     specifics.set_chrome_version("Chromium 10k");
126     specifics.set_sync_user_agent("Chrome 10k");
127     specifics.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX);
128     specifics.set_signin_scoped_device_id("device_id");
129
130     if (backup_timestamp != 0) {
131       specifics.set_backup_timestamp(backup_timestamp);
132     }
133
134     return SyncData::CreateRemoteData(1,
135                                       entity,
136                                       base::Time(),
137                                       AttachmentIdList(),
138                                       AttachmentServiceProxyForTest::Create());
139   }
140
141   void AddInitialData(SyncDataList& sync_data_list,
142                       const std::string& client_id,
143                       const std::string& client_name) {
144     SyncData sync_data = CreateRemoteData(client_id, client_name);
145     sync_data_list.push_back(sync_data);
146   }
147
148   void AddChange(SyncChangeList& change_list,
149                  SyncChange::SyncChangeType change_type,
150                  const std::string& client_id,
151                  const std::string& client_name) {
152     SyncData sync_data = CreateRemoteData(client_id, client_name);
153     SyncChange sync_change(FROM_HERE, change_type, sync_data);
154     change_list.push_back(sync_change);
155   }
156
157  protected:
158   int num_device_info_changed_callbacks_;
159   scoped_ptr<LocalDeviceInfoProviderMock> local_device_;
160   scoped_ptr<DeviceInfoSyncService> sync_service_;
161   scoped_ptr<TestChangeProcessor> sync_processor_;
162   content::TestBrowserThreadBundle thread_bundle_;
163 };
164
165 // Sync with empty initial data.
166 TEST_F(DeviceInfoSyncServiceTest, StartSyncEmptyInitialData) {
167   SyncMergeResult merge_result =
168       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
169                                               SyncDataList(),
170                                               PassProcessor(),
171                                               CreateAndPassSyncErrorFactory());
172
173   EXPECT_EQ(0, merge_result.num_items_added());
174   EXPECT_EQ(0, merge_result.num_items_modified());
175   EXPECT_EQ(0, merge_result.num_items_deleted());
176   EXPECT_EQ(1, merge_result.num_items_before_association());
177   EXPECT_EQ(1, merge_result.num_items_after_association());
178   EXPECT_EQ(SyncChange::ACTION_ADD, sync_processor_->change_type_at(0));
179
180   EXPECT_EQ(1U, sync_processor_->change_list_size());
181   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
182
183   // Should have one device info corresponding to local device info.
184   EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size());
185   EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size());
186   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1"));
187   EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0"));
188 }
189
190 // Sync with initial data matching the local device data.
191 TEST_F(DeviceInfoSyncServiceTest, StartSyncMatchingInitialData) {
192   SyncDataList sync_data;
193   AddInitialData(sync_data, "guid_1", "client_1");
194
195   SyncMergeResult merge_result =
196       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
197                                               sync_data,
198                                               PassProcessor(),
199                                               CreateAndPassSyncErrorFactory());
200   EXPECT_EQ(0, merge_result.num_items_added());
201   EXPECT_EQ(0, merge_result.num_items_modified());
202   EXPECT_EQ(0, merge_result.num_items_deleted());
203   EXPECT_EQ(1, merge_result.num_items_before_association());
204   EXPECT_EQ(1, merge_result.num_items_after_association());
205
206   // No changes expected because the device info matches.
207   EXPECT_EQ(0U, sync_processor_->change_list_size());
208
209   EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size());
210   EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size());
211   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1"));
212   EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0"));
213 }
214
215 // Sync with misc initial data.
216 TEST_F(DeviceInfoSyncServiceTest, StartSync) {
217   SyncDataList sync_data;
218   AddInitialData(sync_data, "guid_2", "foo");
219   AddInitialData(sync_data, "guid_3", "bar");
220   // This guid matches the local device but the client name is different.
221   AddInitialData(sync_data, "guid_1", "baz");
222
223   SyncMergeResult merge_result =
224       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
225                                               sync_data,
226                                               PassProcessor(),
227                                               CreateAndPassSyncErrorFactory());
228
229   EXPECT_EQ(2, merge_result.num_items_added());
230   EXPECT_EQ(1, merge_result.num_items_modified());
231   EXPECT_EQ(0, merge_result.num_items_deleted());
232   EXPECT_EQ(1, merge_result.num_items_before_association());
233   EXPECT_EQ(3, merge_result.num_items_after_association());
234
235   EXPECT_EQ(1U, sync_processor_->change_list_size());
236   EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0));
237   EXPECT_EQ("client_1", sync_processor_->client_name_at(0));
238
239   EXPECT_EQ(3U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size());
240   EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size());
241   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1"));
242   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2"));
243   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_3"));
244   EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0"));
245 }
246
247 // Process sync change with ACTION_ADD.
248 // Verify callback.
249 TEST_F(DeviceInfoSyncServiceTest, ProcessAddChange) {
250   EXPECT_EQ(0, num_device_info_changed_callbacks_);
251
252   // Start with an empty initial data.
253   SyncMergeResult merge_result =
254       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
255                                               SyncDataList(),
256                                               PassProcessor(),
257                                               CreateAndPassSyncErrorFactory());
258   // There should be only one item corresponding to the local device
259   EXPECT_EQ(1, merge_result.num_items_after_association());
260   EXPECT_EQ(1, num_device_info_changed_callbacks_);
261
262   // Add a new device info with a non-matching guid.
263   SyncChangeList change_list;
264   AddChange(change_list, SyncChange::ACTION_ADD, "guid_2", "foo");
265
266   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
267   EXPECT_FALSE(error.IsSet());
268   EXPECT_EQ(2, num_device_info_changed_callbacks_);
269
270   EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size());
271
272   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1"));
273   EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2"));
274   EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0"));
275 }
276
277 // Process multiple sync change with ACTION_UPDATE and ACTION_ADD.
278 // Verify that callback is called multiple times.
279 TEST_F(DeviceInfoSyncServiceTest, ProcessMultipleChanges) {
280   SyncDataList sync_data;
281   AddInitialData(sync_data, "guid_2", "foo");
282   AddInitialData(sync_data, "guid_3", "bar");
283
284   SyncMergeResult merge_result =
285       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
286                                               sync_data,
287                                               PassProcessor(),
288                                               CreateAndPassSyncErrorFactory());
289   EXPECT_EQ(3, merge_result.num_items_after_association());
290   // reset callbacks counter
291   num_device_info_changed_callbacks_ = 0;
292
293   SyncChangeList change_list;
294   AddChange(change_list, SyncChange::ACTION_UPDATE, "guid_2", "foo_2");
295
296   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
297   EXPECT_FALSE(error.IsSet());
298
299   EXPECT_EQ(1, num_device_info_changed_callbacks_);
300   EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size());
301   EXPECT_EQ("foo_2", sync_service_->GetDeviceInfo("guid_2")->client_name());
302
303   change_list.clear();
304   AddChange(change_list, SyncChange::ACTION_UPDATE, "guid_3", "bar_3");
305   AddChange(change_list, SyncChange::ACTION_ADD, "guid_4", "baz_4");
306
307   error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
308   EXPECT_FALSE(error.IsSet());
309
310   EXPECT_EQ(2, num_device_info_changed_callbacks_);
311   EXPECT_EQ(4U, sync_service_->GetAllDeviceInfo().size());
312   EXPECT_EQ("bar_3", sync_service_->GetDeviceInfo("guid_3")->client_name());
313   EXPECT_EQ("baz_4", sync_service_->GetDeviceInfo("guid_4")->client_name());
314 }
315
316 // Process update to the local device info and verify that it is ignored.
317 TEST_F(DeviceInfoSyncServiceTest, ProcessUpdateChangeMatchingLocalDevice) {
318   SyncMergeResult merge_result =
319       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
320                                               SyncDataList(),
321                                               PassProcessor(),
322                                               CreateAndPassSyncErrorFactory());
323   EXPECT_EQ(1, merge_result.num_items_after_association());
324   // reset callbacks counter
325   num_device_info_changed_callbacks_ = 0;
326
327   SyncChangeList change_list;
328   AddChange(change_list, SyncChange::ACTION_UPDATE, "guid_1", "foo_1");
329
330   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
331   EXPECT_FALSE(error.IsSet());
332   // Callback shouldn't be sent in this case.
333   EXPECT_EQ(0, num_device_info_changed_callbacks_);
334   // Should still have the old local device Info.
335   EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size());
336   EXPECT_EQ("client_1", sync_service_->GetDeviceInfo("guid_1")->client_name());
337 }
338
339 // Process sync change with ACTION_DELETE.
340 TEST_F(DeviceInfoSyncServiceTest, ProcessDeleteChange) {
341   SyncDataList sync_data;
342   AddInitialData(sync_data, "guid_2", "foo");
343   AddInitialData(sync_data, "guid_3", "bar");
344
345   SyncMergeResult merge_result =
346       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
347                                               sync_data,
348                                               PassProcessor(),
349                                               CreateAndPassSyncErrorFactory());
350   EXPECT_EQ(3, merge_result.num_items_after_association());
351   // reset callbacks counter
352   num_device_info_changed_callbacks_ = 0;
353
354   SyncChangeList change_list;
355   AddChange(change_list, SyncChange::ACTION_DELETE, "guid_2", "foo_2");
356
357   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
358   EXPECT_FALSE(error.IsSet());
359
360   EXPECT_EQ(1, num_device_info_changed_callbacks_);
361   EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size());
362   EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_2"));
363 }
364
365 // Process sync change with unexpected action.
366 TEST_F(DeviceInfoSyncServiceTest, ProcessInvalidChange) {
367   SyncMergeResult merge_result =
368       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
369                                               SyncDataList(),
370                                               PassProcessor(),
371                                               CreateAndPassSyncErrorFactory());
372   EXPECT_EQ(1, merge_result.num_items_after_association());
373   // reset callbacks counter
374   num_device_info_changed_callbacks_ = 0;
375
376   SyncChangeList change_list;
377   AddChange(change_list, (SyncChange::SyncChangeType)100, "guid_2", "foo_2");
378
379   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
380   EXPECT_TRUE(error.IsSet());
381
382   // The number of callback should still be zero.
383   EXPECT_EQ(0, num_device_info_changed_callbacks_);
384   EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size());
385 }
386
387 // Process sync change after unsubscribing from notifications.
388 TEST_F(DeviceInfoSyncServiceTest, ProcessChangesAfterUnsubscribing) {
389   SyncMergeResult merge_result =
390       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
391                                               SyncDataList(),
392                                               PassProcessor(),
393                                               CreateAndPassSyncErrorFactory());
394   EXPECT_EQ(1, merge_result.num_items_after_association());
395   // reset callbacks counter
396   num_device_info_changed_callbacks_ = 0;
397
398   SyncChangeList change_list;
399   AddChange(change_list, SyncChange::ACTION_ADD, "guid_2", "foo_2");
400
401   // Unsubscribe observer before processing changes.
402   sync_service_->RemoveObserver(this);
403
404   SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list);
405   EXPECT_FALSE(error.IsSet());
406
407   // The number of callback should still be zero.
408   EXPECT_EQ(0, num_device_info_changed_callbacks_);
409 }
410
411 // Verifies setting backup timestamp after the initial sync.
412 TEST_F(DeviceInfoSyncServiceTest, UpdateLocalDeviceBackupTime) {
413   // Shouldn't have backuptime initially.
414   base::Time backup_time = sync_service_->GetLocalDeviceBackupTime();
415   EXPECT_TRUE(backup_time.is_null());
416
417   // Perform the initial sync with empty data.
418   SyncMergeResult merge_result =
419       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
420                                               SyncDataList(),
421                                               PassProcessor(),
422                                               CreateAndPassSyncErrorFactory());
423
424   // Should have local device after the initial sync.
425   EXPECT_EQ(1U, sync_processor_->change_list_size());
426   EXPECT_EQ(SyncChange::ACTION_ADD, sync_processor_->change_type_at(0));
427
428   // Shouldn't have backup time initially.
429   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
430   EXPECT_FALSE(sync_processor_->device_info_at(0).has_backup_timestamp());
431
432   sync_service_->UpdateLocalDeviceBackupTime(base::Time::FromTimeT(1000));
433
434   // Should have local device info updated with the specified backup timestamp.
435   EXPECT_EQ(1U, sync_processor_->change_list_size());
436   EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0));
437   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
438   EXPECT_TRUE(sync_processor_->device_info_at(0).has_backup_timestamp());
439
440   backup_time = syncer::ProtoTimeToTime(
441       sync_processor_->device_info_at(0).backup_timestamp());
442   EXPECT_EQ(1000, backup_time.ToTimeT());
443
444   // Also verify that we get the same backup time directly from the service.
445   backup_time = sync_service_->GetLocalDeviceBackupTime();
446   EXPECT_EQ(1000, backup_time.ToTimeT());
447 }
448
449 // Verifies setting backup timestamp prior to the initial sync.
450 TEST_F(DeviceInfoSyncServiceTest, UpdateLocalDeviceBackupTimeBeforeSync) {
451   // Set the backup timestamp.
452   sync_service_->UpdateLocalDeviceBackupTime(base::Time::FromTimeT(2000));
453   // Verify that we get it back.
454   base::Time backup_time = sync_service_->GetLocalDeviceBackupTime();
455   EXPECT_EQ(2000, backup_time.ToTimeT());
456
457   // Now perform the initial sync with empty data.
458   SyncMergeResult merge_result =
459       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
460                                               SyncDataList(),
461                                               PassProcessor(),
462                                               CreateAndPassSyncErrorFactory());
463
464   // Should have local device after the initial sync.
465   // Should have the backup timestamp set.
466   EXPECT_EQ(1U, sync_processor_->change_list_size());
467   EXPECT_EQ(SyncChange::ACTION_ADD, sync_processor_->change_type_at(0));
468   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
469   EXPECT_TRUE(sync_processor_->device_info_at(0).has_backup_timestamp());
470
471   backup_time = syncer::ProtoTimeToTime(
472       sync_processor_->device_info_at(0).backup_timestamp());
473   EXPECT_EQ(2000, backup_time.ToTimeT());
474 }
475
476 // Verifies that the backup timestamp that comes in the intial sync data
477 // gets preserved when there are no changes to the local device.
478 TEST_F(DeviceInfoSyncServiceTest, PreserveBackupTimeWithMatchingLocalDevice) {
479   base::Time backup_time = base::Time::FromTimeT(3000);
480   SyncDataList sync_data;
481   sync_data.push_back(CreateRemoteData(
482       "guid_1", "client_1", syncer::TimeToProtoTime(backup_time)));
483
484   SyncMergeResult merge_result =
485       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
486                                               sync_data,
487                                               PassProcessor(),
488                                               CreateAndPassSyncErrorFactory());
489
490   // Everything is matching so there should be no updates.
491   EXPECT_EQ(0U, sync_processor_->change_list_size());
492
493   // Verify that we get back the same time.
494   backup_time = sync_service_->GetLocalDeviceBackupTime();
495   EXPECT_EQ(3000, backup_time.ToTimeT());
496 }
497
498 // Verifies that the backup timestamp that comes in the intial sync data
499 // gets merged with the local device data.
500 TEST_F(DeviceInfoSyncServiceTest, MergeBackupTimeWithMatchingLocalDevice) {
501   base::Time backup_time = base::Time::FromTimeT(4000);
502   SyncDataList sync_data;
503   sync_data.push_back(CreateRemoteData(
504       "guid_1", "foo_1", syncer::TimeToProtoTime(backup_time)));
505
506   SyncMergeResult merge_result =
507       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
508                                               sync_data,
509                                               PassProcessor(),
510                                               CreateAndPassSyncErrorFactory());
511
512   // Should be one change because of the client name mismatch.
513   // However the backup time passed in the initial data should be merged into
514   // the change.
515   EXPECT_EQ(1U, sync_processor_->change_list_size());
516
517   EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0));
518   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
519   EXPECT_EQ("client_1", sync_processor_->client_name_at(0));
520
521   backup_time = syncer::ProtoTimeToTime(
522       sync_processor_->device_info_at(0).backup_timestamp());
523   EXPECT_EQ(4000, backup_time.ToTimeT());
524 }
525
526 // Verifies that mismatching backup timestamp generates an update even
527 // when the rest of local device data is matching.
528 TEST_F(DeviceInfoSyncServiceTest,
529        MergeMismatchingBackupTimeWithMatchingLocalDevice) {
530   base::Time backup_time = base::Time::FromTimeT(5000);
531   SyncDataList sync_data;
532   sync_data.push_back(CreateRemoteData(
533       "guid_1", "client_1", syncer::TimeToProtoTime(backup_time)));
534
535   // Set the backup timestamp different than the one in the sync data.
536   sync_service_->UpdateLocalDeviceBackupTime(base::Time::FromTimeT(6000));
537
538   SyncMergeResult merge_result =
539       sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO,
540                                               sync_data,
541                                               PassProcessor(),
542                                               CreateAndPassSyncErrorFactory());
543
544   // Should generate and update due to timestamp mismatch.
545   // The locally set timestamp wins.
546   EXPECT_EQ(1U, sync_processor_->change_list_size());
547
548   EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0));
549   EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0));
550   EXPECT_EQ("client_1", sync_processor_->client_name_at(0));
551
552   backup_time = syncer::ProtoTimeToTime(
553       sync_processor_->device_info_at(0).backup_timestamp());
554   EXPECT_EQ(6000, backup_time.ToTimeT());
555 }
556
557 }  // namespace
558
559 }  // namespace browser_sync