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

Side by Side Diff: sync/internal_api/attachments/attachment_service_impl_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698