Home | History | Annotate | Download | only in attachments
      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/internal_api/public/attachments/attachment_service_impl.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/memory/weak_ptr.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/run_loop.h"
     11 #include "base/timer/mock_timer.h"
     12 #include "sync/internal_api/public/attachments/fake_attachment_downloader.h"
     13 #include "sync/internal_api/public/attachments/fake_attachment_uploader.h"
     14 #include "testing/gmock/include/gmock/gmock-matchers.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace syncer {
     18 
     19 class MockAttachmentStore : public AttachmentStore,
     20                             public base::SupportsWeakPtr<MockAttachmentStore> {
     21  public:
     22   MockAttachmentStore() {}
     23 
     24   virtual void Read(const AttachmentIdList& ids,
     25                     const ReadCallback& callback) OVERRIDE {
     26     read_ids.push_back(ids);
     27     read_callbacks.push_back(callback);
     28   }
     29 
     30   virtual void Write(const AttachmentList& attachments,
     31                      const WriteCallback& callback) OVERRIDE {
     32     write_attachments.push_back(attachments);
     33     write_callbacks.push_back(callback);
     34   }
     35 
     36   virtual void Drop(const AttachmentIdList& ids,
     37                     const DropCallback& callback) OVERRIDE {
     38     NOTREACHED();
     39   }
     40 
     41   // Respond to Read request. Attachments found in local_attachments should be
     42   // returned, everything else should be reported unavailable.
     43   void RespondToRead(const AttachmentIdSet& local_attachments) {
     44     scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
     45     ReadCallback callback = read_callbacks.back();
     46     AttachmentIdList ids = read_ids.back();
     47     read_callbacks.pop_back();
     48     read_ids.pop_back();
     49 
     50     scoped_ptr<AttachmentMap> attachments(new AttachmentMap());
     51     scoped_ptr<AttachmentIdList> unavailable_attachments(
     52         new AttachmentIdList());
     53     for (AttachmentIdList::const_iterator iter = ids.begin(); iter != ids.end();
     54          ++iter) {
     55       if (local_attachments.find(*iter) != local_attachments.end()) {
     56         Attachment attachment = Attachment::CreateWithId(*iter, data);
     57         attachments->insert(std::make_pair(*iter, attachment));
     58       } else {
     59         unavailable_attachments->push_back(*iter);
     60       }
     61     }
     62     Result result =
     63         unavailable_attachments->empty() ? SUCCESS : UNSPECIFIED_ERROR;
     64 
     65     base::MessageLoop::current()->PostTask(
     66         FROM_HERE,
     67         base::Bind(callback,
     68                    result,
     69                    base::Passed(&attachments),
     70                    base::Passed(&unavailable_attachments)));
     71   }
     72 
     73   // Respond to Write request with |result|.
     74   void RespondToWrite(const Result& result) {
     75     WriteCallback callback = write_callbacks.back();
     76     AttachmentList attachments = write_attachments.back();
     77     write_callbacks.pop_back();
     78     write_attachments.pop_back();
     79     base::MessageLoop::current()->PostTask(FROM_HERE,
     80                                            base::Bind(callback, result));
     81   }
     82 
     83   std::vector<AttachmentIdList> read_ids;
     84   std::vector<ReadCallback> read_callbacks;
     85   std::vector<AttachmentList> write_attachments;
     86   std::vector<WriteCallback> write_callbacks;
     87 
     88  private:
     89   virtual ~MockAttachmentStore() {}
     90 
     91   DISALLOW_COPY_AND_ASSIGN(MockAttachmentStore);
     92 };
     93 
     94 class MockAttachmentDownloader
     95     : public AttachmentDownloader,
     96       public base::SupportsWeakPtr<MockAttachmentDownloader> {
     97  public:
     98   MockAttachmentDownloader() {}
     99 
    100   virtual void DownloadAttachment(const AttachmentId& id,
    101                                   const DownloadCallback& callback) OVERRIDE {
    102     ASSERT_TRUE(download_requests.find(id) == download_requests.end());
    103     download_requests.insert(std::make_pair(id, callback));
    104   }
    105 
    106   // Multiple requests to download will be active at the same time.
    107   // RespondToDownload should respond to only one of them.
    108   void RespondToDownload(const AttachmentId& id, const DownloadResult& result) {
    109     ASSERT_TRUE(download_requests.find(id) != download_requests.end());
    110     scoped_ptr<Attachment> attachment;
    111     if (result == DOWNLOAD_SUCCESS) {
    112       scoped_refptr<base::RefCountedString> data = new base::RefCountedString();
    113       attachment.reset(new Attachment(Attachment::CreateWithId(id, data)));
    114     }
    115     base::MessageLoop::current()->PostTask(
    116         FROM_HERE,
    117         base::Bind(download_requests[id], result, base::Passed(&attachment)));
    118 
    119     download_requests.erase(id);
    120   }
    121 
    122   std::map<AttachmentId, DownloadCallback> download_requests;
    123 
    124   DISALLOW_COPY_AND_ASSIGN(MockAttachmentDownloader);
    125 };
    126 
    127 class MockAttachmentUploader
    128     : public AttachmentUploader,
    129       public base::SupportsWeakPtr<MockAttachmentUploader> {
    130  public:
    131   MockAttachmentUploader() {}
    132 
    133   // AttachmentUploader implementation.
    134   virtual void UploadAttachment(const Attachment& attachment,
    135                                 const UploadCallback& callback) OVERRIDE {
    136     const AttachmentId id = attachment.GetId();
    137     ASSERT_TRUE(upload_requests.find(id) == upload_requests.end());
    138     upload_requests.insert(std::make_pair(id, callback));
    139   }
    140 
    141   void RespondToUpload(const AttachmentId& id, const UploadResult& result) {
    142     ASSERT_TRUE(upload_requests.find(id) != upload_requests.end());
    143     base::MessageLoop::current()->PostTask(
    144         FROM_HERE, base::Bind(upload_requests[id], result, id));
    145     upload_requests.erase(id);
    146   }
    147 
    148   std::map<AttachmentId, UploadCallback> upload_requests;
    149 
    150   DISALLOW_COPY_AND_ASSIGN(MockAttachmentUploader);
    151 };
    152 
    153 class AttachmentServiceImplTest : public testing::Test,
    154                                   public AttachmentService::Delegate {
    155  protected:
    156   AttachmentServiceImplTest() {}
    157 
    158   virtual void SetUp() OVERRIDE {
    159     network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock());
    160     InitializeAttachmentService(make_scoped_ptr(new MockAttachmentUploader()),
    161                                 make_scoped_ptr(new MockAttachmentDownloader()),
    162                                 this);
    163   }
    164 
    165   virtual void TearDown() OVERRIDE {
    166     attachment_service_.reset();
    167     ASSERT_FALSE(attachment_store_);
    168     ASSERT_FALSE(attachment_uploader_);
    169     ASSERT_FALSE(attachment_downloader_);
    170   }
    171 
    172   // AttachmentService::Delegate implementation.
    173   virtual void OnAttachmentUploaded(
    174       const AttachmentId& attachment_id) OVERRIDE {
    175     on_attachment_uploaded_list_.push_back(attachment_id);
    176   }
    177 
    178   void InitializeAttachmentService(
    179       scoped_ptr<MockAttachmentUploader> uploader,
    180       scoped_ptr<MockAttachmentDownloader> downloader,
    181       AttachmentService::Delegate* delegate) {
    182     scoped_refptr<MockAttachmentStore> attachment_store(
    183         new MockAttachmentStore());
    184     attachment_store_ = attachment_store->AsWeakPtr();
    185 
    186     if (uploader.get()) {
    187       attachment_uploader_ = uploader->AsWeakPtr();
    188     }
    189     if (downloader.get()) {
    190       attachment_downloader_ = downloader->AsWeakPtr();
    191     }
    192     attachment_service_.reset(
    193         new AttachmentServiceImpl(attachment_store,
    194                                   uploader.PassAs<AttachmentUploader>(),
    195                                   downloader.PassAs<AttachmentDownloader>(),
    196                                   delegate,
    197                                   base::TimeDelta::FromMinutes(1),
    198                                   base::TimeDelta::FromMinutes(8)));
    199 
    200     scoped_ptr<base::MockTimer> timer_to_pass(
    201         new base::MockTimer(false, false));
    202     mock_timer_ = timer_to_pass.get();
    203     attachment_service_->SetTimerForTest(timer_to_pass.PassAs<base::Timer>());
    204   }
    205 
    206   AttachmentService* attachment_service() { return attachment_service_.get(); }
    207 
    208   base::MockTimer* mock_timer() { return mock_timer_; }
    209 
    210   AttachmentService::GetOrDownloadCallback download_callback() {
    211     return base::Bind(&AttachmentServiceImplTest::DownloadDone,
    212                       base::Unretained(this));
    213   }
    214 
    215   void DownloadDone(const AttachmentService::GetOrDownloadResult& result,
    216                     scoped_ptr<AttachmentMap> attachments) {
    217     download_results_.push_back(result);
    218     last_download_attachments_ = attachments.Pass();
    219   }
    220 
    221   void RunLoop() {
    222     base::RunLoop run_loop;
    223     run_loop.RunUntilIdle();
    224   }
    225 
    226   void RunLoopAndFireTimer() {
    227     RunLoop();
    228     if (mock_timer()->IsRunning()) {
    229       mock_timer()->Fire();
    230     }
    231     RunLoop();
    232   }
    233 
    234   const std::vector<AttachmentService::GetOrDownloadResult>&
    235   download_results() const {
    236     return download_results_;
    237   }
    238 
    239   const AttachmentMap& last_download_attachments() const {
    240     return *last_download_attachments_.get();
    241   }
    242 
    243   net::NetworkChangeNotifier* network_change_notifier() {
    244     return network_change_notifier_.get();
    245   }
    246 
    247   MockAttachmentStore* store() { return attachment_store_.get(); }
    248 
    249   MockAttachmentDownloader* downloader() {
    250     return attachment_downloader_.get();
    251   }
    252 
    253   MockAttachmentUploader* uploader() {
    254     return attachment_uploader_.get();
    255   }
    256 
    257   const std::vector<AttachmentId>& on_attachment_uploaded_list() const {
    258     return on_attachment_uploaded_list_;
    259   }
    260 
    261  private:
    262   base::MessageLoop message_loop_;
    263   scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_;
    264   base::WeakPtr<MockAttachmentStore> attachment_store_;
    265   base::WeakPtr<MockAttachmentDownloader> attachment_downloader_;
    266   base::WeakPtr<MockAttachmentUploader> attachment_uploader_;
    267   scoped_ptr<AttachmentServiceImpl> attachment_service_;
    268   base::MockTimer* mock_timer_;  // not owned
    269 
    270   std::vector<AttachmentService::GetOrDownloadResult> download_results_;
    271   scoped_ptr<AttachmentMap> last_download_attachments_;
    272   std::vector<AttachmentId> on_attachment_uploaded_list_;
    273 };
    274 
    275 TEST_F(AttachmentServiceImplTest, GetStore) {
    276   EXPECT_EQ(store(), attachment_service()->GetStore());
    277 }
    278 
    279 TEST_F(AttachmentServiceImplTest, GetOrDownload_EmptyAttachmentList) {
    280   AttachmentIdList attachment_ids;
    281   attachment_service()->GetOrDownloadAttachments(attachment_ids,
    282                                                  download_callback());
    283   store()->RespondToRead(AttachmentIdSet());
    284 
    285   RunLoop();
    286   EXPECT_EQ(1U, download_results().size());
    287   EXPECT_EQ(0U, last_download_attachments().size());
    288 }
    289 
    290 TEST_F(AttachmentServiceImplTest, GetOrDownload_Local) {
    291   AttachmentIdList attachment_ids;
    292   attachment_ids.push_back(AttachmentId::Create());
    293   attachment_service()->GetOrDownloadAttachments(attachment_ids,
    294                                                  download_callback());
    295   AttachmentIdSet local_attachments;
    296   local_attachments.insert(attachment_ids[0]);
    297   store()->RespondToRead(local_attachments);
    298 
    299   RunLoop();
    300   EXPECT_EQ(1U, download_results().size());
    301   EXPECT_EQ(1U, last_download_attachments().size());
    302   EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
    303               last_download_attachments().end());
    304 }
    305 
    306 TEST_F(AttachmentServiceImplTest, GetOrDownload_LocalRemoteUnavailable) {
    307   // Create attachment list with 3 ids.
    308   AttachmentIdList attachment_ids;
    309   attachment_ids.push_back(AttachmentId::Create());
    310   attachment_ids.push_back(AttachmentId::Create());
    311   attachment_ids.push_back(AttachmentId::Create());
    312   // Call attachment service.
    313   attachment_service()->GetOrDownloadAttachments(attachment_ids,
    314                                                  download_callback());
    315   // Ensure AttachmentStore is called.
    316   EXPECT_FALSE(store()->read_ids.empty());
    317 
    318   // make AttachmentStore return only attachment 0.
    319   AttachmentIdSet local_attachments;
    320   local_attachments.insert(attachment_ids[0]);
    321   store()->RespondToRead(local_attachments);
    322   RunLoop();
    323   // Ensure Downloader called with right attachment ids
    324   EXPECT_EQ(2U, downloader()->download_requests.size());
    325 
    326   // Make downloader return attachment 1.
    327   downloader()->RespondToDownload(attachment_ids[1],
    328                                   AttachmentDownloader::DOWNLOAD_SUCCESS);
    329   RunLoop();
    330   // Ensure consumer callback is not called.
    331   EXPECT_TRUE(download_results().empty());
    332 
    333   // Make downloader fail attachment 2.
    334   downloader()->RespondToDownload(
    335       attachment_ids[2], AttachmentDownloader::DOWNLOAD_UNSPECIFIED_ERROR);
    336   RunLoop();
    337   // Ensure callback is called
    338   EXPECT_FALSE(download_results().empty());
    339   // There should be only two attachments returned, 0 and 1.
    340   EXPECT_EQ(2U, last_download_attachments().size());
    341   EXPECT_TRUE(last_download_attachments().find(attachment_ids[0]) !=
    342               last_download_attachments().end());
    343   EXPECT_TRUE(last_download_attachments().find(attachment_ids[1]) !=
    344               last_download_attachments().end());
    345   EXPECT_TRUE(last_download_attachments().find(attachment_ids[2]) ==
    346               last_download_attachments().end());
    347 }
    348 
    349 TEST_F(AttachmentServiceImplTest, GetOrDownload_NoDownloader) {
    350   // No downloader.
    351   InitializeAttachmentService(
    352       make_scoped_ptr<MockAttachmentUploader>(new MockAttachmentUploader()),
    353       make_scoped_ptr<MockAttachmentDownloader>(NULL),
    354       this);
    355 
    356   AttachmentIdList attachment_ids;
    357   attachment_ids.push_back(AttachmentId::Create());
    358   attachment_service()->GetOrDownloadAttachments(attachment_ids,
    359                                                  download_callback());
    360   EXPECT_FALSE(store()->read_ids.empty());
    361 
    362   AttachmentIdSet local_attachments;
    363   store()->RespondToRead(local_attachments);
    364   RunLoop();
    365   ASSERT_EQ(1U, download_results().size());
    366   EXPECT_EQ(AttachmentService::GET_UNSPECIFIED_ERROR, download_results()[0]);
    367   EXPECT_TRUE(last_download_attachments().empty());
    368 }
    369 
    370 TEST_F(AttachmentServiceImplTest, UploadAttachments_Success) {
    371   AttachmentIdSet attachment_ids;
    372   const unsigned num_attachments = 3;
    373   for (unsigned i = 0; i < num_attachments; ++i) {
    374     attachment_ids.insert(AttachmentId::Create());
    375   }
    376   attachment_service()->UploadAttachments(attachment_ids);
    377 
    378   for (unsigned i = 0; i < num_attachments; ++i) {
    379     RunLoopAndFireTimer();
    380     // See that the service has issued a read for at least one of the
    381     // attachments.
    382     ASSERT_GE(store()->read_ids.size(), 1U);
    383     store()->RespondToRead(attachment_ids);
    384     RunLoop();
    385     ASSERT_GE(uploader()->upload_requests.size(), 1U);
    386     uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
    387                                 AttachmentUploader::UPLOAD_SUCCESS);
    388   }
    389   RunLoop();
    390   ASSERT_EQ(0U, store()->read_ids.size());
    391   ASSERT_EQ(0U, uploader()->upload_requests.size());
    392 
    393   // See that all the attachments were uploaded.
    394   ASSERT_EQ(attachment_ids.size(), on_attachment_uploaded_list().size());
    395   AttachmentIdSet::const_iterator iter = attachment_ids.begin();
    396   const AttachmentIdSet::const_iterator end = attachment_ids.end();
    397   for (iter = attachment_ids.begin(); iter != end; ++iter) {
    398     EXPECT_THAT(on_attachment_uploaded_list(), testing::Contains(*iter));
    399   }
    400 }
    401 
    402 TEST_F(AttachmentServiceImplTest, UploadAttachments_Success_NoDelegate) {
    403   InitializeAttachmentService(make_scoped_ptr(new MockAttachmentUploader()),
    404                               make_scoped_ptr(new MockAttachmentDownloader()),
    405                               NULL);  // No delegate.
    406 
    407   AttachmentIdSet attachment_ids;
    408   attachment_ids.insert(AttachmentId::Create());
    409   attachment_service()->UploadAttachments(attachment_ids);
    410   RunLoopAndFireTimer();
    411   ASSERT_EQ(1U, store()->read_ids.size());
    412   ASSERT_EQ(0U, uploader()->upload_requests.size());
    413   store()->RespondToRead(attachment_ids);
    414   RunLoop();
    415   ASSERT_EQ(0U, store()->read_ids.size());
    416   ASSERT_EQ(1U, uploader()->upload_requests.size());
    417   uploader()->RespondToUpload(*attachment_ids.begin(),
    418                               AttachmentUploader::UPLOAD_SUCCESS);
    419   RunLoop();
    420   ASSERT_TRUE(on_attachment_uploaded_list().empty());
    421 }
    422 
    423 TEST_F(AttachmentServiceImplTest, UploadAttachments_SomeMissingFromStore) {
    424   AttachmentIdSet attachment_ids;
    425   attachment_ids.insert(AttachmentId::Create());
    426   attachment_ids.insert(AttachmentId::Create());
    427   attachment_service()->UploadAttachments(attachment_ids);
    428   RunLoopAndFireTimer();
    429   ASSERT_GE(store()->read_ids.size(), 1U);
    430 
    431   ASSERT_EQ(0U, uploader()->upload_requests.size());
    432   store()->RespondToRead(attachment_ids);
    433   RunLoop();
    434   ASSERT_EQ(1U, uploader()->upload_requests.size());
    435 
    436   uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
    437                               AttachmentUploader::UPLOAD_SUCCESS);
    438   RunLoopAndFireTimer();
    439   ASSERT_EQ(1U, on_attachment_uploaded_list().size());
    440   ASSERT_GE(store()->read_ids.size(), 1U);
    441   // Not found!
    442   store()->RespondToRead(AttachmentIdSet());
    443   RunLoop();
    444   // No upload requests since the read failed.
    445   ASSERT_EQ(0U, uploader()->upload_requests.size());
    446 }
    447 
    448 TEST_F(AttachmentServiceImplTest, UploadAttachments_AllMissingFromStore) {
    449   AttachmentIdSet attachment_ids;
    450   const unsigned num_attachments = 2;
    451   for (unsigned i = 0; i < num_attachments; ++i) {
    452     attachment_ids.insert(AttachmentId::Create());
    453   }
    454   attachment_service()->UploadAttachments(attachment_ids);
    455 
    456   for (unsigned i = 0; i < num_attachments; ++i) {
    457     RunLoopAndFireTimer();
    458     ASSERT_GE(store()->read_ids.size(), 1U);
    459     // None found!
    460     store()->RespondToRead(AttachmentIdSet());
    461   }
    462   RunLoop();
    463 
    464   // Nothing uploaded.
    465   EXPECT_EQ(0U, uploader()->upload_requests.size());
    466   // See that the delegate was never called.
    467   ASSERT_EQ(0U, on_attachment_uploaded_list().size());
    468 }
    469 
    470 TEST_F(AttachmentServiceImplTest, UploadAttachments_NoUploader) {
    471   InitializeAttachmentService(make_scoped_ptr<MockAttachmentUploader>(NULL),
    472                               make_scoped_ptr(new MockAttachmentDownloader()),
    473                               this);
    474 
    475   AttachmentIdSet attachment_ids;
    476   attachment_ids.insert(AttachmentId::Create());
    477   attachment_service()->UploadAttachments(attachment_ids);
    478   RunLoop();
    479   EXPECT_EQ(0U, store()->read_ids.size());
    480   ASSERT_EQ(0U, on_attachment_uploaded_list().size());
    481 }
    482 
    483 // Upload three attachments.  For one of them, server responds with error.
    484 TEST_F(AttachmentServiceImplTest, UploadAttachments_OneUploadFails) {
    485   AttachmentIdSet attachment_ids;
    486   const unsigned num_attachments = 3;
    487   for (unsigned i = 0; i < num_attachments; ++i) {
    488     attachment_ids.insert(AttachmentId::Create());
    489   }
    490   attachment_service()->UploadAttachments(attachment_ids);
    491 
    492   for (unsigned i = 0; i < 3; ++i) {
    493     RunLoopAndFireTimer();
    494     ASSERT_GE(store()->read_ids.size(), 1U);
    495     store()->RespondToRead(attachment_ids);
    496     RunLoop();
    497     ASSERT_EQ(1U, uploader()->upload_requests.size());
    498     AttachmentUploader::UploadResult result =
    499         AttachmentUploader::UPLOAD_SUCCESS;
    500     // Fail the 2nd one.
    501     if (i == 2U) {
    502       result = AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR;
    503     } else {
    504       result = AttachmentUploader::UPLOAD_SUCCESS;
    505     }
    506     uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
    507                                 result);
    508     RunLoop();
    509   }
    510   ASSERT_EQ(2U, on_attachment_uploaded_list().size());
    511 }
    512 
    513 // Attempt an upload, respond with transient error to trigger backoff, issue
    514 // network disconnect/connect events and see that backoff is cleared.
    515 TEST_F(AttachmentServiceImplTest,
    516        UploadAttachments_ResetBackoffAfterNetworkChange) {
    517   AttachmentIdSet attachment_ids;
    518   attachment_ids.insert(AttachmentId::Create());
    519   attachment_service()->UploadAttachments(attachment_ids);
    520 
    521   RunLoopAndFireTimer();
    522   ASSERT_EQ(1U, store()->read_ids.size());
    523   store()->RespondToRead(attachment_ids);
    524   RunLoop();
    525   ASSERT_EQ(1U, uploader()->upload_requests.size());
    526 
    527   uploader()->RespondToUpload(uploader()->upload_requests.begin()->first,
    528                               AttachmentUploader::UPLOAD_TRANSIENT_ERROR);
    529   RunLoop();
    530 
    531   // See that we are in backoff.
    532   ASSERT_TRUE(mock_timer()->IsRunning());
    533   ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
    534 
    535   // Issue a network disconnect event.
    536   network_change_notifier()->NotifyObserversOfNetworkChangeForTests(
    537       net::NetworkChangeNotifier::CONNECTION_NONE);
    538   RunLoop();
    539 
    540   // Still in backoff.
    541   ASSERT_TRUE(mock_timer()->IsRunning());
    542   ASSERT_GT(mock_timer()->GetCurrentDelay(), base::TimeDelta());
    543 
    544   // Issue a network connect event.
    545   net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
    546       net::NetworkChangeNotifier::CONNECTION_WIFI);
    547   RunLoop();
    548 
    549   // No longer in backoff.
    550   ASSERT_TRUE(mock_timer()->IsRunning());
    551   ASSERT_EQ(base::TimeDelta(), mock_timer()->GetCurrentDelay());
    552 }
    553 
    554 }  // namespace syncer
    555