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

Side by Side Diff: components/sync/api_impl/attachments/attachment_service_impl_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698