Home | History | Annotate | Download | only in engine
      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 "sync/engine/get_updates_processor.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "base/stl_util.h"
      9 #include "sync/engine/get_updates_delegate.h"
     10 #include "sync/engine/update_handler.h"
     11 #include "sync/internal_api/public/base/model_type_test_util.h"
     12 #include "sync/protocol/sync.pb.h"
     13 #include "sync/sessions/debug_info_getter.h"
     14 #include "sync/sessions/nudge_tracker.h"
     15 #include "sync/sessions/status_controller.h"
     16 #include "sync/test/engine/fake_model_worker.h"
     17 #include "sync/test/engine/mock_update_handler.h"
     18 #include "sync/test/mock_invalidation.h"
     19 #include "sync/test/sessions/mock_debug_info_getter.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 namespace syncer {
     23 
     24 namespace {
     25 
     26 scoped_ptr<InvalidationInterface> BuildInvalidation(
     27     int64 version,
     28     const std::string& payload) {
     29   return MockInvalidation::Build(version, payload)
     30       .PassAs<InvalidationInterface>();
     31 }
     32 
     33 }  // namespace
     34 
     35 using sessions::MockDebugInfoGetter;
     36 
     37 // A test fixture for tests exercising download updates functions.
     38 class GetUpdatesProcessorTest : public ::testing::Test {
     39  protected:
     40   GetUpdatesProcessorTest() :
     41     kTestStartTime(base::TimeTicks::Now()),
     42     update_handler_deleter_(&update_handler_map_) {}
     43 
     44   virtual void SetUp() {
     45     AddUpdateHandler(AUTOFILL);
     46     AddUpdateHandler(BOOKMARKS);
     47     AddUpdateHandler(PREFERENCES);
     48   }
     49 
     50   ModelTypeSet enabled_types() {
     51     return enabled_types_;
     52   }
     53 
     54   scoped_ptr<GetUpdatesProcessor> BuildGetUpdatesProcessor(
     55       const GetUpdatesDelegate& delegate) {
     56     return scoped_ptr<GetUpdatesProcessor>(
     57         new GetUpdatesProcessor(&update_handler_map_, delegate));
     58   }
     59 
     60   void InitFakeUpdateResponse(sync_pb::GetUpdatesResponse* response) {
     61     ModelTypeSet types = enabled_types();
     62 
     63     for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
     64       sync_pb::DataTypeProgressMarker* marker =
     65           response->add_new_progress_marker();
     66       marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
     67       marker->set_token("foobarbaz");
     68       sync_pb::DataTypeContext* context = response->add_context_mutations();
     69       context->set_data_type_id(GetSpecificsFieldNumberFromModelType(it.Get()));
     70       context->set_version(1);
     71       context->set_context("context");
     72     }
     73 
     74     response->set_changes_remaining(0);
     75   }
     76 
     77   const UpdateHandler* GetHandler(ModelType type) {
     78     UpdateHandlerMap::iterator it = update_handler_map_.find(type);
     79     if (it == update_handler_map_.end())
     80       return NULL;
     81     return it->second;
     82   }
     83 
     84   const base::TimeTicks kTestStartTime;
     85 
     86  protected:
     87   MockUpdateHandler* AddUpdateHandler(ModelType type) {
     88     enabled_types_.Put(type);
     89 
     90     MockUpdateHandler* handler = new MockUpdateHandler(type);
     91     update_handler_map_.insert(std::make_pair(type, handler));
     92 
     93     return handler;
     94   }
     95 
     96  private:
     97   ModelTypeSet enabled_types_;
     98   UpdateHandlerMap update_handler_map_;
     99   STLValueDeleter<UpdateHandlerMap> update_handler_deleter_;
    100   scoped_ptr<GetUpdatesProcessor> get_updates_processor_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
    103 };
    104 
    105 // Basic test to make sure nudges are expressed properly in the request.
    106 TEST_F(GetUpdatesProcessorTest, BookmarkNudge) {
    107   sessions::NudgeTracker nudge_tracker;
    108   nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
    109 
    110   sync_pb::ClientToServerMessage message;
    111   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    112   scoped_ptr<GetUpdatesProcessor> processor(
    113       BuildGetUpdatesProcessor(normal_delegate));
    114   processor->PrepareGetUpdates(enabled_types(), &message);
    115 
    116   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    117   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL,
    118             gu_msg.caller_info().source());
    119   EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
    120   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    121     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    122         gu_msg.from_progress_marker(i).data_type_id());
    123 
    124     const sync_pb::DataTypeProgressMarker& progress_marker =
    125         gu_msg.from_progress_marker(i);
    126     const sync_pb::GetUpdateTriggers& gu_trigger =
    127         progress_marker.get_update_triggers();
    128 
    129     // We perform some basic tests of GU trigger and source fields here.  The
    130     // more complicated scenarios are tested by the NudgeTracker tests.
    131     if (type == BOOKMARKS) {
    132       EXPECT_TRUE(progress_marker.has_notification_hint());
    133       EXPECT_EQ("", progress_marker.notification_hint());
    134       EXPECT_EQ(1, gu_trigger.local_modification_nudges());
    135       EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
    136     } else {
    137       EXPECT_FALSE(progress_marker.has_notification_hint());
    138       EXPECT_EQ(0, gu_trigger.local_modification_nudges());
    139       EXPECT_EQ(0, gu_trigger.datatype_refresh_nudges());
    140     }
    141   }
    142 }
    143 
    144 // Basic test to ensure invalidation payloads are expressed in the request.
    145 TEST_F(GetUpdatesProcessorTest, NotifyMany) {
    146   sessions::NudgeTracker nudge_tracker;
    147   nudge_tracker.RecordRemoteInvalidation(
    148       AUTOFILL, BuildInvalidation(1, "autofill_payload"));
    149   nudge_tracker.RecordRemoteInvalidation(
    150       BOOKMARKS, BuildInvalidation(1, "bookmark_payload"));
    151   nudge_tracker.RecordRemoteInvalidation(
    152       PREFERENCES, BuildInvalidation(1, "preferences_payload"));
    153   ModelTypeSet notified_types;
    154   notified_types.Put(AUTOFILL);
    155   notified_types.Put(BOOKMARKS);
    156   notified_types.Put(PREFERENCES);
    157 
    158   sync_pb::ClientToServerMessage message;
    159   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    160   scoped_ptr<GetUpdatesProcessor> processor(
    161       BuildGetUpdatesProcessor(normal_delegate));
    162   processor->PrepareGetUpdates(enabled_types(), &message);
    163 
    164   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    165   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION,
    166             gu_msg.caller_info().source());
    167   EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
    168   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    169     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    170         gu_msg.from_progress_marker(i).data_type_id());
    171 
    172     const sync_pb::DataTypeProgressMarker& progress_marker =
    173         gu_msg.from_progress_marker(i);
    174     const sync_pb::GetUpdateTriggers& gu_trigger =
    175         progress_marker.get_update_triggers();
    176 
    177     // We perform some basic tests of GU trigger and source fields here.  The
    178     // more complicated scenarios are tested by the NudgeTracker tests.
    179     if (notified_types.Has(type)) {
    180       EXPECT_TRUE(progress_marker.has_notification_hint());
    181       EXPECT_FALSE(progress_marker.notification_hint().empty());
    182       EXPECT_EQ(1, gu_trigger.notification_hint_size());
    183     } else {
    184       EXPECT_FALSE(progress_marker.has_notification_hint());
    185       EXPECT_EQ(0, gu_trigger.notification_hint_size());
    186     }
    187   }
    188 }
    189 
    190 // Basic test to ensure initial sync requests are expressed in the request.
    191 TEST_F(GetUpdatesProcessorTest, InitialSyncRequest) {
    192   sessions::NudgeTracker nudge_tracker;
    193   nudge_tracker.RecordInitialSyncRequired(AUTOFILL);
    194   nudge_tracker.RecordInitialSyncRequired(PREFERENCES);
    195 
    196   ModelTypeSet initial_sync_types = ModelTypeSet(AUTOFILL, PREFERENCES);
    197 
    198   sync_pb::ClientToServerMessage message;
    199   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    200   scoped_ptr<GetUpdatesProcessor> processor(
    201       BuildGetUpdatesProcessor(normal_delegate));
    202   processor->PrepareGetUpdates(enabled_types(), &message);
    203 
    204   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    205   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH,
    206             gu_msg.caller_info().source());
    207   EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin());
    208   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    209     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    210         gu_msg.from_progress_marker(i).data_type_id());
    211 
    212     const sync_pb::DataTypeProgressMarker& progress_marker =
    213         gu_msg.from_progress_marker(i);
    214     const sync_pb::GetUpdateTriggers& gu_trigger =
    215         progress_marker.get_update_triggers();
    216 
    217     // We perform some basic tests of GU trigger and source fields here.  The
    218     // more complicated scenarios are tested by the NudgeTracker tests.
    219     if (initial_sync_types.Has(type)) {
    220       EXPECT_TRUE(gu_trigger.initial_sync_in_progress());
    221     } else {
    222       EXPECT_TRUE(gu_trigger.has_initial_sync_in_progress());
    223       EXPECT_FALSE(gu_trigger.initial_sync_in_progress());
    224     }
    225   }
    226 }
    227 
    228 TEST_F(GetUpdatesProcessorTest, ConfigureTest) {
    229   sync_pb::ClientToServerMessage message;
    230   ConfigureGetUpdatesDelegate configure_delegate(
    231       sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
    232   scoped_ptr<GetUpdatesProcessor> processor(
    233       BuildGetUpdatesProcessor(configure_delegate));
    234   processor->PrepareGetUpdates(enabled_types(), &message);
    235 
    236   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    237   EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin());
    238   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION,
    239             gu_msg.caller_info().source());
    240 
    241   ModelTypeSet progress_types;
    242   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    243     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    244         gu_msg.from_progress_marker(i).data_type_id());
    245     progress_types.Put(type);
    246   }
    247   EXPECT_TRUE(enabled_types().Equals(progress_types));
    248 }
    249 
    250 TEST_F(GetUpdatesProcessorTest, PollTest) {
    251   sync_pb::ClientToServerMessage message;
    252   PollGetUpdatesDelegate poll_delegate;
    253   scoped_ptr<GetUpdatesProcessor> processor(
    254       BuildGetUpdatesProcessor(poll_delegate));
    255   processor->PrepareGetUpdates(enabled_types(), &message);
    256 
    257   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    258   EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin());
    259   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC,
    260             gu_msg.caller_info().source());
    261 
    262   ModelTypeSet progress_types;
    263   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    264     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    265         gu_msg.from_progress_marker(i).data_type_id());
    266     progress_types.Put(type);
    267   }
    268   EXPECT_TRUE(enabled_types().Equals(progress_types));
    269 }
    270 
    271 TEST_F(GetUpdatesProcessorTest, RetryTest) {
    272   sessions::NudgeTracker nudge_tracker;
    273 
    274   // Schedule a retry.
    275   base::TimeTicks t1 = kTestStartTime;
    276   nudge_tracker.SetNextRetryTime(t1);
    277 
    278   // Get the nudge tracker to think the retry is due.
    279   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
    280 
    281   sync_pb::ClientToServerMessage message;
    282   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    283   scoped_ptr<GetUpdatesProcessor> processor(
    284       BuildGetUpdatesProcessor(normal_delegate));
    285   processor->PrepareGetUpdates(enabled_types(), &message);
    286 
    287   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    288   EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
    289   EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY,
    290             gu_msg.caller_info().source());
    291   EXPECT_TRUE(gu_msg.is_retry());
    292 
    293   ModelTypeSet progress_types;
    294   for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) {
    295     syncer::ModelType type = GetModelTypeFromSpecificsFieldNumber(
    296         gu_msg.from_progress_marker(i).data_type_id());
    297     progress_types.Put(type);
    298   }
    299   EXPECT_TRUE(enabled_types().Equals(progress_types));
    300 }
    301 
    302 TEST_F(GetUpdatesProcessorTest, NudgeWithRetryTest) {
    303   sessions::NudgeTracker nudge_tracker;
    304 
    305   // Schedule a retry.
    306   base::TimeTicks t1 = kTestStartTime;
    307   nudge_tracker.SetNextRetryTime(t1);
    308 
    309   // Get the nudge tracker to think the retry is due.
    310   nudge_tracker.SetSyncCycleStartTime(t1 + base::TimeDelta::FromSeconds(1));
    311 
    312   // Record a local change, too.
    313   nudge_tracker.RecordLocalChange(ModelTypeSet(BOOKMARKS));
    314 
    315   sync_pb::ClientToServerMessage message;
    316   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    317   scoped_ptr<GetUpdatesProcessor> processor(
    318       BuildGetUpdatesProcessor(normal_delegate));
    319   processor->PrepareGetUpdates(enabled_types(), &message);
    320 
    321   const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates();
    322   EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin());
    323   EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY,
    324             gu_msg.caller_info().source());
    325 
    326   EXPECT_TRUE(gu_msg.is_retry());
    327 }
    328 
    329 // Verify that a bogus response message is detected.
    330 TEST_F(GetUpdatesProcessorTest, InvalidResponse) {
    331   sync_pb::GetUpdatesResponse gu_response;
    332   InitFakeUpdateResponse(&gu_response);
    333 
    334   // This field is essential for making the client stop looping.  If it's unset
    335   // then something is very wrong.  The client should detect this.
    336   gu_response.clear_changes_remaining();
    337 
    338   sessions::NudgeTracker nudge_tracker;
    339   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    340   sessions::StatusController status;
    341   scoped_ptr<GetUpdatesProcessor> processor(
    342       BuildGetUpdatesProcessor(normal_delegate));
    343   SyncerError error = processor->ProcessResponse(gu_response,
    344                                                  enabled_types(),
    345                                                  &status);
    346   EXPECT_EQ(error, SERVER_RESPONSE_VALIDATION_FAILED);
    347 }
    348 
    349 // Verify that we correctly detect when there's more work to be done.
    350 TEST_F(GetUpdatesProcessorTest, MoreToDownloadResponse) {
    351   sync_pb::GetUpdatesResponse gu_response;
    352   InitFakeUpdateResponse(&gu_response);
    353   gu_response.set_changes_remaining(1);
    354 
    355   sessions::NudgeTracker nudge_tracker;
    356   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    357   sessions::StatusController status;
    358   scoped_ptr<GetUpdatesProcessor> processor(
    359       BuildGetUpdatesProcessor(normal_delegate));
    360   SyncerError error = processor->ProcessResponse(gu_response,
    361                                                  enabled_types(),
    362                                                  &status);
    363   EXPECT_EQ(error, SERVER_MORE_TO_DOWNLOAD);
    364 }
    365 
    366 // A simple scenario: No updates returned and nothing more to download.
    367 TEST_F(GetUpdatesProcessorTest, NormalResponseTest) {
    368   sync_pb::GetUpdatesResponse gu_response;
    369   InitFakeUpdateResponse(&gu_response);
    370   gu_response.set_changes_remaining(0);
    371 
    372   sessions::NudgeTracker nudge_tracker;
    373   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    374   sessions::StatusController status;
    375   scoped_ptr<GetUpdatesProcessor> processor(
    376       BuildGetUpdatesProcessor(normal_delegate));
    377   SyncerError error = processor->ProcessResponse(gu_response,
    378                                                  enabled_types(),
    379                                                  &status);
    380   EXPECT_EQ(error, SYNCER_OK);
    381 }
    382 
    383 // Variant of GetUpdatesProcessor test designed to test update application.
    384 //
    385 // Maintains two enabled types, but requests that updates be applied for only
    386 // one of them.
    387 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
    388  public:
    389   GetUpdatesProcessorApplyUpdatesTest() {}
    390   virtual ~GetUpdatesProcessorApplyUpdatesTest() {}
    391 
    392   virtual void SetUp() OVERRIDE {
    393     bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
    394     autofill_handler_ = AddUpdateHandler(AUTOFILL);
    395   }
    396 
    397   ModelTypeSet GetGuTypes() {
    398     return ModelTypeSet(AUTOFILL);
    399   }
    400 
    401   MockUpdateHandler* GetNonAppliedHandler() {
    402     return bookmarks_handler_;
    403   }
    404 
    405   MockUpdateHandler* GetAppliedHandler() {
    406     return autofill_handler_;
    407   }
    408 
    409  private:
    410   MockUpdateHandler* bookmarks_handler_;
    411   MockUpdateHandler* autofill_handler_;
    412 };
    413 
    414 // Verify that a normal cycle applies updates non-passively to the specified
    415 // types.
    416 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Normal) {
    417   sessions::NudgeTracker nudge_tracker;
    418   NormalGetUpdatesDelegate normal_delegate(nudge_tracker);
    419   scoped_ptr<GetUpdatesProcessor> processor(
    420       BuildGetUpdatesProcessor(normal_delegate));
    421 
    422   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
    423   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
    424 
    425   sessions::StatusController status;
    426   processor->ApplyUpdates(GetGuTypes(), &status);
    427 
    428   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
    429   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
    430 
    431   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
    432   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
    433 }
    434 
    435 // Verify that a configure cycle applies updates passively to the specified
    436 // types.
    437 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) {
    438   ConfigureGetUpdatesDelegate configure_delegate(
    439       sync_pb::GetUpdatesCallerInfo::RECONFIGURATION);
    440   scoped_ptr<GetUpdatesProcessor> processor(
    441       BuildGetUpdatesProcessor(configure_delegate));
    442 
    443   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
    444   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
    445 
    446   sessions::StatusController status;
    447   processor->ApplyUpdates(GetGuTypes(), &status);
    448 
    449   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
    450   EXPECT_EQ(1, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
    451 
    452   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
    453   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
    454 }
    455 
    456 // Verify that a poll cycle applies updates non-passively to the specified
    457 // types.
    458 TEST_F(GetUpdatesProcessorApplyUpdatesTest, Poll) {
    459   PollGetUpdatesDelegate poll_delegate;
    460   scoped_ptr<GetUpdatesProcessor> processor(
    461       BuildGetUpdatesProcessor(poll_delegate));
    462 
    463   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
    464   EXPECT_EQ(0, GetAppliedHandler()->GetApplyUpdatesCount());
    465 
    466   sessions::StatusController status;
    467   processor->ApplyUpdates(GetGuTypes(), &status);
    468 
    469   EXPECT_EQ(0, GetNonAppliedHandler()->GetApplyUpdatesCount());
    470   EXPECT_EQ(1, GetAppliedHandler()->GetApplyUpdatesCount());
    471 
    472   EXPECT_EQ(0, GetNonAppliedHandler()->GetPassiveApplyUpdatesCount());
    473   EXPECT_EQ(0, GetAppliedHandler()->GetPassiveApplyUpdatesCount());
    474 }
    475 
    476 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
    477  public:
    478   DownloadUpdatesDebugInfoTest() {}
    479   virtual ~DownloadUpdatesDebugInfoTest() {}
    480 
    481   sessions::StatusController* status() {
    482     return &status_;
    483   }
    484 
    485   sessions::DebugInfoGetter* debug_info_getter() {
    486     return &debug_info_getter_;
    487   }
    488 
    489   void AddDebugEvent() {
    490     debug_info_getter_.AddDebugEvent();
    491   }
    492 
    493  private:
    494   sessions::StatusController status_;
    495   MockDebugInfoGetter debug_info_getter_;
    496 };
    497 
    498 // Verify CopyClientDebugInfo when there are no events to upload.
    499 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyClientDebugInfo_Empty) {
    500   sync_pb::DebugInfo debug_info;
    501   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
    502   EXPECT_EQ(0, debug_info.events_size());
    503 }
    504 
    505 TEST_F(DownloadUpdatesDebugInfoTest, VerifyCopyOverwrites) {
    506   sync_pb::DebugInfo debug_info;
    507   AddDebugEvent();
    508   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
    509   EXPECT_EQ(1, debug_info.events_size());
    510   GetUpdatesProcessor::CopyClientDebugInfo(debug_info_getter(), &debug_info);
    511   EXPECT_EQ(1, debug_info.events_size());
    512 }
    513 
    514 }  // namespace syncer
    515