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

Side by Side Diff: content/browser/fileapi/blob_reader_unittest.cc

Issue 1376123002: Revert of [Blob] BlobReader class & tests, and removal of all redundant reading. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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
« no previous file with comments | « no previous file | content/browser/fileapi/blob_url_request_job_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "storage/browser/blob/blob_reader.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/location.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/task_runner.h"
17 #include "base/time/time.h"
18 #include "content/public/test/async_file_test_helper.h"
19 #include "content/public/test/test_file_system_context.h"
20 #include "net/base/completion_callback.h"
21 #include "net/base/io_buffer.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/test_completion_callback.h"
24 #include "net/disk_cache/disk_cache.h"
25 #include "storage/browser/blob/blob_data_builder.h"
26 #include "storage/browser/blob/blob_data_handle.h"
27 #include "storage/browser/blob/blob_storage_context.h"
28 #include "storage/browser/fileapi/file_stream_reader.h"
29 #include "storage/browser/fileapi/file_system_context.h"
30 #include "storage/browser/fileapi/file_system_file_util.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "url/gurl.h"
34
35 using base::FilePath;
36 using content::AsyncFileTestHelper;
37 using net::DrainableIOBuffer;
38 using net::IOBuffer;
39
40 namespace storage {
41 namespace {
42
43 const int kTestDiskCacheStreamIndex = 0;
44
45 // Our disk cache tests don't need a real data handle since the tests themselves
46 // scope the disk cache and entries.
47 class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle {
48 private:
49 ~EmptyDataHandle() override {}
50 };
51
52 // A disk_cache::Entry that arbitrarily delays the completion of a read
53 // operation to allow testing some races without flake. This is particularly
54 // relevant in this unit test, which uses the always-synchronous MEMORY_CACHE.
55 class DelayedReadEntry : public disk_cache::Entry {
56 public:
57 explicit DelayedReadEntry(disk_cache::ScopedEntryPtr entry)
58 : entry_(entry.Pass()) {}
59 ~DelayedReadEntry() override { EXPECT_FALSE(HasPendingReadCallbacks()); }
60
61 bool HasPendingReadCallbacks() { return !pending_read_callbacks_.empty(); }
62
63 void RunPendingReadCallbacks() {
64 std::vector<base::Callback<void(void)>> callbacks;
65 pending_read_callbacks_.swap(callbacks);
66 for (const auto& callback : callbacks)
67 callback.Run();
68 }
69
70 // From disk_cache::Entry:
71 void Doom() override { entry_->Doom(); }
72
73 void Close() override { delete this; } // Note this is required by the API.
74
75 std::string GetKey() const override { return entry_->GetKey(); }
76
77 base::Time GetLastUsed() const override { return entry_->GetLastUsed(); }
78
79 base::Time GetLastModified() const override {
80 return entry_->GetLastModified();
81 }
82
83 int32 GetDataSize(int index) const override {
84 return entry_->GetDataSize(index);
85 }
86
87 int ReadData(int index,
88 int offset,
89 IOBuffer* buf,
90 int buf_len,
91 const CompletionCallback& original_callback) override {
92 net::TestCompletionCallback callback;
93 int rv = entry_->ReadData(index, offset, buf, buf_len, callback.callback());
94 DCHECK_NE(rv, net::ERR_IO_PENDING)
95 << "Test expects to use a MEMORY_CACHE instance, which is synchronous.";
96 pending_read_callbacks_.push_back(base::Bind(original_callback, rv));
97 return net::ERR_IO_PENDING;
98 }
99
100 int WriteData(int index,
101 int offset,
102 IOBuffer* buf,
103 int buf_len,
104 const CompletionCallback& callback,
105 bool truncate) override {
106 return entry_->WriteData(index, offset, buf, buf_len, callback, truncate);
107 }
108
109 int ReadSparseData(int64 offset,
110 IOBuffer* buf,
111 int buf_len,
112 const CompletionCallback& callback) override {
113 return entry_->ReadSparseData(offset, buf, buf_len, callback);
114 }
115
116 int WriteSparseData(int64 offset,
117 IOBuffer* buf,
118 int buf_len,
119 const CompletionCallback& callback) override {
120 return entry_->WriteSparseData(offset, buf, buf_len, callback);
121 }
122
123 int GetAvailableRange(int64 offset,
124 int len,
125 int64* start,
126 const CompletionCallback& callback) override {
127 return entry_->GetAvailableRange(offset, len, start, callback);
128 }
129
130 bool CouldBeSparse() const override { return entry_->CouldBeSparse(); }
131
132 void CancelSparseIO() override { entry_->CancelSparseIO(); }
133
134 int ReadyForSparseIO(const CompletionCallback& callback) override {
135 return entry_->ReadyForSparseIO(callback);
136 }
137
138 private:
139 disk_cache::ScopedEntryPtr entry_;
140 std::vector<base::Callback<void(void)>> pending_read_callbacks_;
141 };
142
143 scoped_ptr<disk_cache::Backend> CreateInMemoryDiskCache(
144 const scoped_refptr<base::SingleThreadTaskRunner>& thread) {
145 scoped_ptr<disk_cache::Backend> cache;
146 net::TestCompletionCallback callback;
147 int rv = disk_cache::CreateCacheBackend(
148 net::MEMORY_CACHE, net::CACHE_BACKEND_DEFAULT, FilePath(), 0, false,
149 thread, nullptr, &cache, callback.callback());
150 EXPECT_EQ(net::OK, callback.GetResult(rv));
151
152 return cache.Pass();
153 }
154
155 disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
156 const char* key,
157 const std::string& data) {
158 disk_cache::Entry* temp_entry = nullptr;
159 net::TestCompletionCallback callback;
160 int rv = cache->CreateEntry(key, &temp_entry, callback.callback());
161 if (callback.GetResult(rv) != net::OK)
162 return nullptr;
163 disk_cache::ScopedEntryPtr entry(temp_entry);
164
165 scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data);
166 rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(),
167 iobuffer->size(), callback.callback(), false);
168 EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv));
169 return entry.Pass();
170 }
171
172 template <typename T>
173 void SetValue(T* address, T value) {
174 *address = value;
175 }
176
177 class FakeFileStreamReader : public FileStreamReader {
178 public:
179 explicit FakeFileStreamReader(const std::string& contents)
180 : buffer_(new DrainableIOBuffer(
181 new net::StringIOBuffer(
182 scoped_ptr<std::string>(new std::string(contents))),
183 contents.size())),
184 net_error_(net::OK),
185 size_(contents.size()) {}
186 FakeFileStreamReader(const std::string& contents, uint64_t size)
187 : buffer_(new DrainableIOBuffer(
188 new net::StringIOBuffer(
189 scoped_ptr<std::string>(new std::string(contents))),
190 contents.size())),
191 net_error_(net::OK),
192 size_(size) {}
193
194 ~FakeFileStreamReader() override {}
195
196 void SetReturnError(int net_error) { net_error_ = net_error; }
197
198 void SetAsyncRunner(base::SingleThreadTaskRunner* runner) {
199 async_task_runner_ = runner;
200 }
201
202 int Read(net::IOBuffer* buf,
203 int buf_length,
204 const net::CompletionCallback& done) override {
205 DCHECK(buf);
206 // When async_task_runner_ is not set, return synchronously.
207 if (!async_task_runner_.get()) {
208 if (net_error_ == net::OK) {
209 return ReadImpl(buf, buf_length, net::CompletionCallback());
210 } else {
211 return net_error_;
212 }
213 }
214
215 // Otherwise always return asynchronously.
216 if (net_error_ == net::OK) {
217 async_task_runner_->PostTask(
218 FROM_HERE,
219 base::Bind(base::IgnoreResult(&FakeFileStreamReader::ReadImpl),
220 base::Unretained(this), make_scoped_refptr(buf),
221 buf_length, done));
222 } else {
223 async_task_runner_->PostTask(FROM_HERE, base::Bind(done, net_error_));
224 }
225 return net::ERR_IO_PENDING;
226 }
227
228 int64 GetLength(const net::Int64CompletionCallback& size_callback) override {
229 // When async_task_runner_ is not set, return synchronously.
230 if (!async_task_runner_.get()) {
231 if (net_error_ == net::OK) {
232 return size_;
233 } else {
234 return net_error_;
235 }
236 }
237 if (net_error_ == net::OK) {
238 async_task_runner_->PostTask(FROM_HERE, base::Bind(size_callback, size_));
239 } else {
240 async_task_runner_->PostTask(
241 FROM_HERE,
242 base::Bind(size_callback, static_cast<int64_t>(net_error_)));
243 }
244 return net::ERR_IO_PENDING;
245 }
246
247 private:
248 int ReadImpl(scoped_refptr<net::IOBuffer> buf, int buf_length,
249 const net::CompletionCallback& done) {
250 CHECK_GE(buf_length, 0);
251 int length = std::min(buf_length, buffer_->BytesRemaining());
252 memcpy(buf->data(), buffer_->data(), length);
253 buffer_->DidConsume(length);
254 if (done.is_null()) {
255 return length;
256 }
257 done.Run(length);
258 return net::ERR_IO_PENDING;
259 }
260
261 scoped_refptr<net::DrainableIOBuffer> buffer_;
262 scoped_refptr<base::SingleThreadTaskRunner> async_task_runner_;
263 int net_error_;
264 uint64_t size_;
265
266 DISALLOW_COPY_AND_ASSIGN(FakeFileStreamReader);
267 };
268
269 class MockFileStreamReaderProvider
270 : public BlobReader::FileStreamReaderProvider {
271 public:
272 ~MockFileStreamReaderProvider() override {}
273
274 MOCK_METHOD4(CreateForLocalFileMock,
275 FileStreamReader*(base::TaskRunner* task_runner,
276 const FilePath& file_path,
277 int64_t initial_offset,
278 const base::Time& expected_modification_time));
279 MOCK_METHOD4(CreateFileStreamReaderMock,
280 FileStreamReader*(const GURL& filesystem_url,
281 int64_t offset,
282 int64_t max_bytes_to_read,
283 const base::Time& expected_modification_time));
284 // Since we're returning a move-only type, we have to do some delegation for
285 // gmock.
286 scoped_ptr<FileStreamReader> CreateForLocalFile(
287 base::TaskRunner* task_runner,
288 const base::FilePath& file_path,
289 int64_t initial_offset,
290 const base::Time& expected_modification_time) override {
291 return make_scoped_ptr(CreateForLocalFileMock(
292 task_runner, file_path, initial_offset, expected_modification_time));
293 }
294
295 scoped_ptr<FileStreamReader> CreateFileStreamReader(
296 const GURL& filesystem_url,
297 int64_t offset,
298 int64_t max_bytes_to_read,
299 const base::Time& expected_modification_time) override {
300 return make_scoped_ptr(CreateFileStreamReaderMock(
301 filesystem_url, offset, max_bytes_to_read, expected_modification_time));
302 }
303 };
304
305 } // namespace
306
307 class BlobReaderTest : public ::testing::Test {
308 public:
309 BlobReaderTest() {}
310 ~BlobReaderTest() override {}
311
312 void TearDown() override {
313 reader_.reset();
314 blob_handle_.reset();
315 message_loop_.RunUntilIdle();
316 base::RunLoop().RunUntilIdle();
317 }
318
319 protected:
320 void InitializeReader(BlobDataBuilder* builder) {
321 blob_handle_ = builder ? context_.AddFinishedBlob(builder).Pass() : nullptr;
322 provider_ = new MockFileStreamReaderProvider();
323 scoped_ptr<BlobReader::FileStreamReaderProvider> temp_ptr(provider_);
324 reader_.reset(new BlobReader(blob_handle_.get(), temp_ptr.Pass(),
325 message_loop_.task_runner().get()));
326 }
327
328 // Takes ownership of the file reader (the blob reader takes ownership).
329 void ExpectLocalFileCall(const FilePath& file_path,
330 base::Time modification_time,
331 uint64_t initial_offset,
332 FakeFileStreamReader* reader) {
333 EXPECT_CALL(*provider_, CreateForLocalFileMock(
334 message_loop_.task_runner().get(), file_path,
335 initial_offset, modification_time))
336 .WillOnce(testing::Return(reader));
337 }
338
339 // Takes ownership of the file reader (the blob reader takes ownership).
340 void ExpectFileSystemCall(const GURL& filesystem_url,
341 int64_t offset,
342 int64_t max_bytes_to_read,
343 base::Time expected_modification_time,
344 FakeFileStreamReader* reader) {
345 EXPECT_CALL(*provider_, CreateFileStreamReaderMock(
346 filesystem_url, offset, max_bytes_to_read,
347 expected_modification_time))
348 .WillOnce(testing::Return(reader));
349 }
350
351 void CheckSizeCalculatedSynchronously(size_t expected_size, int async_size) {
352 EXPECT_EQ(-1, async_size);
353 EXPECT_EQ(net::OK, reader_->net_error());
354 EXPECT_EQ(expected_size, reader_->total_size());
355 EXPECT_TRUE(reader_->total_size_calculated());
356 }
357
358 void CheckSizeNotCalculatedYet(int async_size) {
359 EXPECT_EQ(-1, async_size);
360 EXPECT_EQ(net::OK, reader_->net_error());
361 EXPECT_FALSE(reader_->total_size_calculated());
362 }
363
364 void CheckSizeCalculatedAsynchronously(size_t expected_size,
365 int async_result) {
366 EXPECT_EQ(net::OK, async_result);
367 EXPECT_EQ(net::OK, reader_->net_error());
368 EXPECT_EQ(expected_size, reader_->total_size());
369 EXPECT_TRUE(reader_->total_size_calculated());
370 }
371
372 scoped_refptr<net::IOBuffer> CreateBuffer(uint64_t size) {
373 return scoped_refptr<net::IOBuffer>(
374 new net::IOBuffer(static_cast<size_t>(size)));
375 }
376
377 bool IsReaderTotalSizeCalculated() {
378 return reader_->total_size_calculated();
379 }
380
381 BlobStorageContext context_;
382 scoped_ptr<BlobDataHandle> blob_handle_;
383 MockFileStreamReaderProvider* provider_ = nullptr;
384 base::MessageLoop message_loop_;
385 scoped_ptr<BlobReader> reader_;
386
387 private:
388 DISALLOW_COPY_AND_ASSIGN(BlobReaderTest);
389 };
390
391 namespace {
392
393 TEST_F(BlobReaderTest, BasicMemory) {
394 BlobDataBuilder b("uuid");
395 const std::string kData("Hello!!!");
396 const size_t kDataSize = 8ul;
397 b.AppendData(kData);
398 this->InitializeReader(&b);
399
400 int size_result = -1;
401 EXPECT_FALSE(IsReaderTotalSizeCalculated());
402 EXPECT_EQ(BlobReader::Status::DONE,
403 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
404 CheckSizeCalculatedSynchronously(kDataSize, size_result);
405
406 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize));
407
408 int bytes_read = 0;
409 int async_bytes_read = 0;
410 EXPECT_EQ(BlobReader::Status::DONE,
411 reader_->Read(buffer.get(), kDataSize, &bytes_read,
412 base::Bind(&SetValue<int>, &async_bytes_read)));
413 EXPECT_EQ(net::OK, reader_->net_error());
414 EXPECT_EQ(kDataSize, static_cast<size_t>(bytes_read));
415 EXPECT_EQ(0, async_bytes_read);
416 EXPECT_EQ(0, memcmp(buffer->data(), "Hello!!!", kDataSize));
417 }
418
419 TEST_F(BlobReaderTest, BasicFile) {
420 BlobDataBuilder b("uuid");
421 const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt");
422 const std::string kData = "FileData!!!";
423 const base::Time kTime = base::Time::Now();
424 b.AppendFile(kPath, 0, kData.size(), kTime);
425 this->InitializeReader(&b);
426
427 // Non-async reader.
428 ExpectLocalFileCall(kPath, kTime, 0, new FakeFileStreamReader(kData));
429
430 int size_result = -1;
431 EXPECT_FALSE(IsReaderTotalSizeCalculated());
432 EXPECT_EQ(BlobReader::Status::DONE,
433 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
434 CheckSizeCalculatedSynchronously(kData.size(), size_result);
435
436 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
437
438 int bytes_read = 0;
439 int async_bytes_read = 0;
440 EXPECT_EQ(BlobReader::Status::DONE,
441 reader_->Read(buffer.get(), kData.size(), &bytes_read,
442 base::Bind(&SetValue<int>, &async_bytes_read)));
443 EXPECT_EQ(net::OK, reader_->net_error());
444 EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read));
445 EXPECT_EQ(0, async_bytes_read);
446 EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size()));
447 }
448
449 TEST_F(BlobReaderTest, BasicFileSystem) {
450 BlobDataBuilder b("uuid");
451 const GURL kURL("file://test_file/here.txt");
452 const std::string kData = "FileData!!!";
453 const base::Time kTime = base::Time::Now();
454 b.AppendFileSystemFile(kURL, 0, kData.size(), kTime);
455 this->InitializeReader(&b);
456
457 // Non-async reader.
458 ExpectFileSystemCall(kURL, 0, kData.size(), kTime,
459 new FakeFileStreamReader(kData));
460
461 int size_result = -1;
462 EXPECT_FALSE(IsReaderTotalSizeCalculated());
463 EXPECT_EQ(BlobReader::Status::DONE,
464 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
465 CheckSizeCalculatedSynchronously(kData.size(), size_result);
466
467 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
468
469 int bytes_read = 0;
470 int async_bytes_read = 0;
471 EXPECT_EQ(BlobReader::Status::DONE,
472 reader_->Read(buffer.get(), kData.size(), &bytes_read,
473 base::Bind(&SetValue<int>, &async_bytes_read)));
474 EXPECT_EQ(net::OK, reader_->net_error());
475 EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read));
476 EXPECT_EQ(0, async_bytes_read);
477 EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size()));
478 }
479
480 TEST_F(BlobReaderTest, BasicDiskCache) {
481 scoped_ptr<disk_cache::Backend> cache =
482 CreateInMemoryDiskCache(message_loop_.task_runner());
483 ASSERT_TRUE(cache);
484
485 BlobDataBuilder b("uuid");
486 const std::string kData = "Test Blob Data";
487 scoped_refptr<BlobDataBuilder::DataHandle> data_handle =
488 new EmptyDataHandle();
489 disk_cache::ScopedEntryPtr entry =
490 CreateDiskCacheEntry(cache.get(), "test entry", kData);
491 b.AppendDiskCacheEntry(data_handle, entry.get(), kTestDiskCacheStreamIndex);
492 this->InitializeReader(&b);
493
494 int size_result = -1;
495 EXPECT_FALSE(IsReaderTotalSizeCalculated());
496 EXPECT_EQ(BlobReader::Status::DONE,
497 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
498 CheckSizeCalculatedSynchronously(kData.size(), size_result);
499
500 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
501
502 int bytes_read = 0;
503 int async_bytes_read = 0;
504 EXPECT_EQ(BlobReader::Status::DONE,
505 reader_->Read(buffer.get(), kData.size(), &bytes_read,
506 base::Bind(&SetValue<int>, &async_bytes_read)));
507 EXPECT_EQ(net::OK, reader_->net_error());
508 EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read));
509 EXPECT_EQ(0, async_bytes_read);
510 EXPECT_EQ(0, memcmp(buffer->data(), "Test Blob Data", kData.size()));
511 }
512
513 TEST_F(BlobReaderTest, BufferLargerThanMemory) {
514 BlobDataBuilder b("uuid");
515 const std::string kData("Hello!!!");
516 const size_t kDataSize = 8ul;
517 const size_t kBufferSize = 10ul;
518 b.AppendData(kData);
519 this->InitializeReader(&b);
520
521 int size_result = -1;
522 EXPECT_FALSE(IsReaderTotalSizeCalculated());
523 EXPECT_EQ(BlobReader::Status::DONE,
524 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
525 CheckSizeCalculatedSynchronously(kData.size(), size_result);
526
527 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
528
529 int bytes_read = 0;
530 int async_bytes_read = 0;
531 EXPECT_EQ(BlobReader::Status::DONE,
532 reader_->Read(buffer.get(), kBufferSize, &bytes_read,
533 base::Bind(&SetValue<int>, &async_bytes_read)));
534 EXPECT_EQ(net::OK, reader_->net_error());
535 EXPECT_EQ(kDataSize, static_cast<size_t>(bytes_read));
536 EXPECT_EQ(0, async_bytes_read);
537 EXPECT_EQ(0, memcmp(buffer->data(), "Hello!!!", kDataSize));
538 }
539
540 TEST_F(BlobReaderTest, MemoryRange) {
541 BlobDataBuilder b("uuid");
542 const std::string kData("Hello!!!");
543 const size_t kDataSize = 8ul;
544 const size_t kSeekOffset = 2ul;
545 const uint64_t kReadLength = 4ull;
546 b.AppendData(kData);
547 this->InitializeReader(&b);
548
549 int size_result = -1;
550 EXPECT_FALSE(IsReaderTotalSizeCalculated());
551 EXPECT_EQ(BlobReader::Status::DONE,
552 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
553 CheckSizeCalculatedSynchronously(kData.size(), size_result);
554
555 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength);
556
557 reader_->SetReadRange(kSeekOffset, kReadLength);
558 int bytes_read = 0;
559 int async_bytes_read = 0;
560 EXPECT_EQ(BlobReader::Status::DONE,
561 reader_->Read(buffer.get(), kDataSize - kSeekOffset, &bytes_read,
562 base::Bind(&SetValue<int>, &async_bytes_read)));
563 EXPECT_EQ(net::OK, reader_->net_error());
564 EXPECT_EQ(kReadLength, static_cast<size_t>(bytes_read));
565 EXPECT_EQ(0, async_bytes_read);
566 EXPECT_EQ(0, memcmp(buffer->data(), "llo!", kReadLength));
567 }
568
569 TEST_F(BlobReaderTest, BufferSmallerThanMemory) {
570 BlobDataBuilder b("uuid");
571 const std::string kData("Hello!!!");
572 const size_t kBufferSize = 4ul;
573 b.AppendData(kData);
574 this->InitializeReader(&b);
575
576 int size_result = -1;
577 EXPECT_FALSE(IsReaderTotalSizeCalculated());
578 EXPECT_EQ(BlobReader::Status::DONE,
579 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
580 CheckSizeCalculatedSynchronously(kData.size(), size_result);
581
582 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
583
584 int bytes_read = 0;
585 int async_bytes_read = 0;
586 EXPECT_EQ(BlobReader::Status::DONE,
587 reader_->Read(buffer.get(), kBufferSize, &bytes_read,
588 base::Bind(&SetValue<int>, &async_bytes_read)));
589 EXPECT_EQ(net::OK, reader_->net_error());
590 EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read));
591 EXPECT_EQ(0, async_bytes_read);
592 EXPECT_EQ(0, memcmp(buffer->data(), "Hell", kBufferSize));
593
594 bytes_read = 0;
595 EXPECT_EQ(BlobReader::Status::DONE,
596 reader_->Read(buffer.get(), kBufferSize, &bytes_read,
597 base::Bind(&SetValue<int>, &async_bytes_read)));
598 EXPECT_EQ(net::OK, reader_->net_error());
599 EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read));
600 EXPECT_EQ(0, async_bytes_read);
601 EXPECT_EQ(0, memcmp(buffer->data(), "o!!!", kBufferSize));
602 }
603
604 TEST_F(BlobReaderTest, SegmentedBufferAndMemory) {
605 BlobDataBuilder b("uuid");
606 const size_t kNumItems = 10;
607 const size_t kItemSize = 6;
608 const size_t kBufferSize = 10;
609 const size_t kTotalSize = kNumItems * kItemSize;
610 char current_value = 0;
611 for (size_t i = 0; i < kNumItems; i++) {
612 char buf[kItemSize];
613 for (size_t j = 0; j < kItemSize; j++) {
614 buf[j] = current_value++;
615 }
616 b.AppendData(buf, kItemSize);
617 }
618 this->InitializeReader(&b);
619
620 int size_result = -1;
621 EXPECT_FALSE(IsReaderTotalSizeCalculated());
622 EXPECT_EQ(BlobReader::Status::DONE,
623 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
624 CheckSizeCalculatedSynchronously(kTotalSize, size_result);
625
626 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
627
628 current_value = 0;
629 for (size_t i = 0; i < kTotalSize / kBufferSize; i++) {
630 int bytes_read = 0;
631 int async_bytes_read = 0;
632 EXPECT_EQ(BlobReader::Status::DONE,
633 reader_->Read(buffer.get(), kBufferSize, &bytes_read,
634 base::Bind(&SetValue<int>, &async_bytes_read)));
635 EXPECT_EQ(net::OK, reader_->net_error());
636 EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read));
637 EXPECT_EQ(0, async_bytes_read);
638 for (size_t j = 0; j < kBufferSize; j++) {
639 EXPECT_EQ(current_value, buffer->data()[j]);
640 current_value++;
641 }
642 }
643 }
644
645 TEST_F(BlobReaderTest, FileAsync) {
646 BlobDataBuilder b("uuid");
647 const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt");
648 const std::string kData = "FileData!!!";
649 const base::Time kTime = base::Time::Now();
650 b.AppendFile(kPath, 0, kData.size(), kTime);
651 this->InitializeReader(&b);
652
653 scoped_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
654 reader->SetAsyncRunner(message_loop_.task_runner().get());
655
656 ExpectLocalFileCall(kPath, kTime, 0, reader.release());
657
658 int size_result = -1;
659 EXPECT_FALSE(IsReaderTotalSizeCalculated());
660 EXPECT_EQ(BlobReader::Status::IO_PENDING,
661 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
662 CheckSizeNotCalculatedYet(size_result);
663 message_loop_.RunUntilIdle();
664 CheckSizeCalculatedAsynchronously(kData.size(), size_result);
665
666 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
667
668 int bytes_read = 0;
669 int async_bytes_read = 0;
670 EXPECT_EQ(BlobReader::Status::IO_PENDING,
671 reader_->Read(buffer.get(), kData.size(), &bytes_read,
672 base::Bind(&SetValue<int>, &async_bytes_read)));
673 message_loop_.RunUntilIdle();
674 EXPECT_EQ(net::OK, reader_->net_error());
675 EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read));
676 EXPECT_EQ(0, bytes_read);
677 EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size()));
678 }
679
680 TEST_F(BlobReaderTest, FileSystemAsync) {
681 BlobDataBuilder b("uuid");
682 const GURL kURL("file://test_file/here.txt");
683 const std::string kData = "FileData!!!";
684 const base::Time kTime = base::Time::Now();
685 b.AppendFileSystemFile(kURL, 0, kData.size(), kTime);
686 this->InitializeReader(&b);
687
688 scoped_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
689 reader->SetAsyncRunner(message_loop_.task_runner().get());
690
691 ExpectFileSystemCall(kURL, 0, kData.size(), kTime, reader.release());
692
693 int size_result = -1;
694 EXPECT_FALSE(IsReaderTotalSizeCalculated());
695 EXPECT_EQ(BlobReader::Status::IO_PENDING,
696 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
697 CheckSizeNotCalculatedYet(size_result);
698 message_loop_.RunUntilIdle();
699 CheckSizeCalculatedAsynchronously(kData.size(), size_result);
700
701 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
702
703 int bytes_read = 0;
704 int async_bytes_read = 0;
705 EXPECT_EQ(BlobReader::Status::IO_PENDING,
706 reader_->Read(buffer.get(), kData.size(), &bytes_read,
707 base::Bind(&SetValue<int>, &async_bytes_read)));
708 message_loop_.RunUntilIdle();
709 EXPECT_EQ(net::OK, reader_->net_error());
710 EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read));
711 EXPECT_EQ(0, bytes_read);
712 EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size()));
713 }
714
715 TEST_F(BlobReaderTest, DiskCacheAsync) {
716 scoped_ptr<disk_cache::Backend> cache =
717 CreateInMemoryDiskCache(message_loop_.task_runner());
718 ASSERT_TRUE(cache);
719
720 BlobDataBuilder b("uuid");
721 const std::string kData = "Test Blob Data";
722 scoped_refptr<BlobDataBuilder::DataHandle> data_handle =
723 new EmptyDataHandle();
724 scoped_ptr<DelayedReadEntry> delayed_read_entry(new DelayedReadEntry(
725 CreateDiskCacheEntry(cache.get(), "test entry", kData).Pass()));
726 b.AppendDiskCacheEntry(data_handle, delayed_read_entry.get(),
727 kTestDiskCacheStreamIndex);
728 this->InitializeReader(&b);
729
730 int size_result = -1;
731 EXPECT_FALSE(IsReaderTotalSizeCalculated());
732 EXPECT_EQ(BlobReader::Status::DONE,
733 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
734 CheckSizeCalculatedSynchronously(kData.size(), size_result);
735
736 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
737
738 int bytes_read = 0;
739 int async_bytes_read = 0;
740 EXPECT_EQ(BlobReader::Status::IO_PENDING,
741 reader_->Read(buffer.get(), kData.size(), &bytes_read,
742 base::Bind(&SetValue<int>, &async_bytes_read)));
743 EXPECT_TRUE(delayed_read_entry->HasPendingReadCallbacks());
744 delayed_read_entry->RunPendingReadCallbacks();
745 EXPECT_EQ(net::OK, reader_->net_error());
746 EXPECT_EQ(0, bytes_read);
747 EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read));
748 EXPECT_EQ(0, memcmp(buffer->data(), "Test Blob Data", kData.size()));
749 }
750
751 TEST_F(BlobReaderTest, FileRange) {
752 BlobDataBuilder b("uuid");
753 const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt");
754 // We check the offset in the ExpectLocalFileCall mock.
755 const std::string kRangeData = "leD";
756 const std::string kData = "FileData!!!";
757 const uint64_t kOffset = 2;
758 const uint64_t kReadLength = 3;
759 const base::Time kTime = base::Time::Now();
760 b.AppendFile(kPath, 0, kData.size(), kTime);
761 this->InitializeReader(&b);
762
763 scoped_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
764 reader->SetAsyncRunner(message_loop_.task_runner().get());
765 ExpectLocalFileCall(kPath, kTime, 0, reader.release());
766
767 // We create the reader again with the offset after the seek.
768 reader.reset(new FakeFileStreamReader(kRangeData));
769 reader->SetAsyncRunner(message_loop_.task_runner().get());
770 ExpectLocalFileCall(kPath, kTime, kOffset, reader.release());
771
772 int size_result = -1;
773 EXPECT_EQ(BlobReader::Status::IO_PENDING,
774 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
775 message_loop_.RunUntilIdle();
776
777 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength);
778 EXPECT_EQ(BlobReader::Status::DONE,
779 reader_->SetReadRange(kOffset, kReadLength));
780
781 int bytes_read = 0;
782 int async_bytes_read = 0;
783 EXPECT_EQ(BlobReader::Status::IO_PENDING,
784 reader_->Read(buffer.get(), kReadLength, &bytes_read,
785 base::Bind(&SetValue<int>, &async_bytes_read)));
786 message_loop_.RunUntilIdle();
787 EXPECT_EQ(net::OK, reader_->net_error());
788 EXPECT_EQ(kReadLength, static_cast<size_t>(async_bytes_read));
789 EXPECT_EQ(0, bytes_read);
790 EXPECT_EQ(0, memcmp(buffer->data(), "leD", kReadLength));
791 }
792
793 TEST_F(BlobReaderTest, DiskCacheRange) {
794 scoped_ptr<disk_cache::Backend> cache =
795 CreateInMemoryDiskCache(message_loop_.task_runner());
796 ASSERT_TRUE(cache);
797
798 BlobDataBuilder b("uuid");
799 const std::string kData = "Test Blob Data";
800 const uint64_t kOffset = 2;
801 const uint64_t kReadLength = 3;
802 scoped_refptr<BlobDataBuilder::DataHandle> data_handle =
803 new EmptyDataHandle();
804 disk_cache::ScopedEntryPtr entry =
805 CreateDiskCacheEntry(cache.get(), "test entry", kData);
806 b.AppendDiskCacheEntry(data_handle, entry.get(), kTestDiskCacheStreamIndex);
807 this->InitializeReader(&b);
808
809 int size_result = -1;
810 EXPECT_EQ(BlobReader::Status::DONE,
811 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
812
813 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength);
814 EXPECT_EQ(BlobReader::Status::DONE,
815 reader_->SetReadRange(kOffset, kReadLength));
816
817 int bytes_read = 0;
818 int async_bytes_read = 0;
819 EXPECT_EQ(BlobReader::Status::DONE,
820 reader_->Read(buffer.get(), kReadLength, &bytes_read,
821 base::Bind(&SetValue<int>, &async_bytes_read)));
822 EXPECT_EQ(net::OK, reader_->net_error());
823 EXPECT_EQ(kReadLength, static_cast<size_t>(bytes_read));
824 EXPECT_EQ(0, async_bytes_read);
825 EXPECT_EQ(0, memcmp(buffer->data(), "st ", kReadLength));
826 }
827
828 TEST_F(BlobReaderTest, FileSomeAsyncSegmentedOffsetsUnknownSizes) {
829 // This tests includes:
830 // * Unknown file sizes (item length of uint64::max) for every other item.
831 // * Offsets for every 3rd file item.
832 // * Non-async reader for every 4th file item.
833 BlobDataBuilder b("uuid");
834 const FilePath kPathBase = FilePath::FromUTF8Unsafe("/fake/file.txt");
835 const base::Time kTime = base::Time::Now();
836 const size_t kNumItems = 10;
837 const size_t kItemSize = 6;
838 const size_t kBufferSize = 10;
839 const size_t kTotalSize = kNumItems * kItemSize;
840 char current_value = 0;
841 // Create blob and reader.
842 for (size_t i = 0; i < kNumItems; i++) {
843 current_value += kItemSize;
844 FilePath path = kPathBase.Append(
845 FilePath::FromUTF8Unsafe(base::StringPrintf("%d", current_value)));
846 uint64_t offset = i % 3 == 0 ? 1 : 0;
847 uint64_t size =
848 i % 2 == 0 ? kItemSize : std::numeric_limits<uint64_t>::max();
849 b.AppendFile(path, offset, size, kTime);
850 }
851 this->InitializeReader(&b);
852
853 // Set expectations.
854 current_value = 0;
855 for (size_t i = 0; i < kNumItems; i++) {
856 uint64_t offset = i % 3 == 0 ? 1 : 0;
857 scoped_ptr<char[]> buf(new char[kItemSize + offset]);
858 if (offset > 0) {
859 memset(buf.get(), 7, offset);
860 }
861 for (size_t j = 0; j < kItemSize; j++) {
862 buf.get()[j + offset] = current_value++;
863 }
864 scoped_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(
865 std::string(buf.get() + offset, kItemSize), kItemSize + offset));
866 if (i % 4 != 0) {
867 reader->SetAsyncRunner(message_loop_.task_runner().get());
868 }
869 FilePath path = kPathBase.Append(
870 FilePath::FromUTF8Unsafe(base::StringPrintf("%d", current_value)));
871 ExpectLocalFileCall(path, kTime, offset, reader.release());
872 }
873
874 int size_result = -1;
875 EXPECT_FALSE(IsReaderTotalSizeCalculated());
876 EXPECT_EQ(BlobReader::Status::IO_PENDING,
877 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
878 CheckSizeNotCalculatedYet(size_result);
879 message_loop_.RunUntilIdle();
880 CheckSizeCalculatedAsynchronously(kTotalSize, size_result);
881
882 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
883
884 current_value = 0;
885 for (size_t i = 0; i < kTotalSize / kBufferSize; i++) {
886 int bytes_read = 0;
887 int async_bytes_read = 0;
888 EXPECT_EQ(BlobReader::Status::IO_PENDING,
889 reader_->Read(buffer.get(), kBufferSize, &bytes_read,
890 base::Bind(&SetValue<int>, &async_bytes_read)));
891 message_loop_.RunUntilIdle();
892 EXPECT_EQ(net::OK, reader_->net_error());
893 EXPECT_EQ(0, bytes_read);
894 EXPECT_EQ(kBufferSize, static_cast<size_t>(async_bytes_read));
895 for (size_t j = 0; j < kBufferSize; j++) {
896 EXPECT_EQ(current_value, buffer->data()[j]);
897 current_value++;
898 }
899 }
900 }
901
902 TEST_F(BlobReaderTest, MixedContent) {
903 // Includes data, a file, and a disk cache entry.
904 scoped_ptr<disk_cache::Backend> cache =
905 CreateInMemoryDiskCache(message_loop_.task_runner());
906 ASSERT_TRUE(cache);
907
908 BlobDataBuilder b("uuid");
909 const std::string kData1("Hello ");
910 const std::string kData2("there. ");
911 const std::string kData3("This ");
912 const std::string kData4("is multi-content.");
913 const uint64_t kDataSize = 35;
914
915 const base::Time kTime = base::Time::Now();
916 const FilePath kData1Path = FilePath::FromUTF8Unsafe("/fake/file.txt");
917
918 disk_cache::ScopedEntryPtr entry3 =
919 CreateDiskCacheEntry(cache.get(), "test entry", kData3);
920
921 b.AppendFile(kData1Path, 0, kData1.size(), kTime);
922 b.AppendData(kData2);
923 b.AppendDiskCacheEntry(
924 scoped_refptr<BlobDataBuilder::DataHandle>(new EmptyDataHandle()),
925 entry3.get(), kTestDiskCacheStreamIndex);
926 b.AppendData(kData4);
927
928 this->InitializeReader(&b);
929
930 scoped_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData1));
931 reader->SetAsyncRunner(message_loop_.task_runner().get());
932 ExpectLocalFileCall(kData1Path, kTime, 0, reader.release());
933
934 int size_result = -1;
935 EXPECT_FALSE(IsReaderTotalSizeCalculated());
936 EXPECT_EQ(BlobReader::Status::IO_PENDING,
937 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
938 CheckSizeNotCalculatedYet(size_result);
939 message_loop_.RunUntilIdle();
940 CheckSizeCalculatedAsynchronously(kDataSize, size_result);
941
942 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kDataSize);
943
944 int bytes_read = 0;
945 int async_bytes_read = 0;
946 EXPECT_EQ(BlobReader::Status::IO_PENDING,
947 reader_->Read(buffer.get(), kDataSize, &bytes_read,
948 base::Bind(&SetValue<int>, &async_bytes_read)));
949 EXPECT_EQ(0, async_bytes_read);
950 message_loop_.RunUntilIdle();
951 EXPECT_EQ(net::OK, reader_->net_error());
952 EXPECT_EQ(0, bytes_read);
953 EXPECT_EQ(kDataSize, static_cast<size_t>(async_bytes_read));
954 EXPECT_EQ(0, memcmp(buffer->data(), "Hello there. This is multi-content.",
955 kDataSize));
956 }
957
958 TEST_F(BlobReaderTest, StateErrors) {
959 // Test common variables
960 int bytes_read = -1;
961 int async_bytes_read = -1;
962 int size_result = -1;
963 const std::string kData("Hello!!!");
964
965 // Case: Blob handle is a nullptr.
966 InitializeReader(nullptr);
967 EXPECT_EQ(BlobReader::Status::NET_ERROR,
968 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
969 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
970 EXPECT_EQ(BlobReader::Status::NET_ERROR, reader_->SetReadRange(0, 10));
971 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
972 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(10);
973 EXPECT_DEATH(reader_->Read(buffer.get(), 10, &bytes_read,
974 base::Bind(&SetValue<int>, &async_bytes_read)),
975 ".*total_size_calculated_.*");
976
977 // Case: Not calling CalculateSize before SetReadRange.
978 BlobDataBuilder builder1("uuid1");
979 builder1.AppendData(kData);
980 InitializeReader(&builder1);
981 EXPECT_EQ(BlobReader::Status::NET_ERROR, reader_->SetReadRange(0, 10));
982 EXPECT_EQ(net::ERR_FAILED, reader_->net_error());
983 EXPECT_DEATH(reader_->Read(buffer.get(), 10, &bytes_read,
984 base::Bind(&SetValue<int>, &async_bytes_read)),
985 ".*total_size_calculated_.*");
986
987 // Case: Not calling CalculateSize before Read.
988 BlobDataBuilder builder2("uuid2");
989 builder2.AppendData(kData);
990 InitializeReader(&builder2);
991 EXPECT_DEATH(reader_->Read(buffer.get(), 10, &bytes_read,
992 base::Bind(&SetValue<int>, &async_bytes_read)),
993 ".*total_size_calculated_.*");
994 }
995
996 TEST_F(BlobReaderTest, FileErrorsSync) {
997 int size_result = -1;
998 const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt");
999 const std::string kData = "FileData!!!";
1000 const base::Time kTime = base::Time::Now();
1001
1002 // Case: Error on length query.
1003 BlobDataBuilder builder1("uuid1");
1004 builder1.AppendFile(kPath, 0, kData.size(), kTime);
1005 this->InitializeReader(&builder1);
1006 FakeFileStreamReader* reader = new FakeFileStreamReader(kData);
1007 reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
1008 ExpectLocalFileCall(kPath, kTime, 0, reader);
1009
1010 EXPECT_EQ(BlobReader::Status::NET_ERROR,
1011 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1012 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1013
1014 // Case: Error on read.
1015 BlobDataBuilder builder2("uuid2");
1016 builder2.AppendFile(kPath, 0, kData.size(), kTime);
1017 this->InitializeReader(&builder2);
1018 reader = new FakeFileStreamReader(kData);
1019 ExpectLocalFileCall(kPath, kTime, 0, reader);
1020 EXPECT_EQ(BlobReader::Status::DONE,
1021 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1022 reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
1023
1024 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
1025 int bytes_read = 0;
1026 int async_bytes_read = 0;
1027 EXPECT_EQ(BlobReader::Status::NET_ERROR,
1028 reader_->Read(buffer.get(), kData.size(), &bytes_read,
1029 base::Bind(&SetValue<int>, &async_bytes_read)));
1030 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1031 }
1032
1033 TEST_F(BlobReaderTest, FileErrorsAsync) {
1034 int size_result = -1;
1035 const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt");
1036 const std::string kData = "FileData!!!";
1037 const base::Time kTime = base::Time::Now();
1038
1039 // Case: Error on length query.
1040 BlobDataBuilder builder1("uuid1");
1041 builder1.AppendFile(kPath, 0, kData.size(), kTime);
1042 this->InitializeReader(&builder1);
1043 FakeFileStreamReader* reader = new FakeFileStreamReader(kData);
1044 reader->SetAsyncRunner(message_loop_.task_runner().get());
1045 reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
1046 ExpectLocalFileCall(kPath, kTime, 0, reader);
1047
1048 EXPECT_EQ(BlobReader::Status::IO_PENDING,
1049 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1050 EXPECT_EQ(net::OK, reader_->net_error());
1051 message_loop_.RunUntilIdle();
1052 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, size_result);
1053 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1054
1055 // Case: Error on read.
1056 BlobDataBuilder builder2("uuid2");
1057 builder2.AppendFile(kPath, 0, kData.size(), kTime);
1058 this->InitializeReader(&builder2);
1059 reader = new FakeFileStreamReader(kData);
1060 ExpectLocalFileCall(kPath, kTime, 0, reader);
1061 EXPECT_EQ(BlobReader::Status::DONE,
1062 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1063 reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
1064 reader->SetAsyncRunner(message_loop_.task_runner().get());
1065
1066 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size()));
1067 int bytes_read = 0;
1068 int async_bytes_read = 0;
1069 EXPECT_EQ(BlobReader::Status::IO_PENDING,
1070 reader_->Read(buffer.get(), kData.size(), &bytes_read,
1071 base::Bind(&SetValue<int>, &async_bytes_read)));
1072 EXPECT_EQ(net::OK, reader_->net_error());
1073 message_loop_.RunUntilIdle();
1074 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, async_bytes_read);
1075 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1076 }
1077
1078 TEST_F(BlobReaderTest, RangeError) {
1079 const std::string kData("Hello!!!");
1080 const size_t kDataSize = 8ul;
1081 const uint64_t kReadLength = 4ull;
1082
1083 // Case: offset too high.
1084 BlobDataBuilder b("uuid1");
1085 b.AppendData(kData);
1086 this->InitializeReader(&b);
1087 int size_result = -1;
1088 EXPECT_EQ(BlobReader::Status::DONE,
1089 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1090 scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kDataSize);
1091 EXPECT_EQ(BlobReader::Status::NET_ERROR,
1092 reader_->SetReadRange(kDataSize + 1, kReadLength));
1093 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1094
1095 // Case: length too long.
1096 BlobDataBuilder b2("uuid2");
1097 b2.AppendData(kData);
1098 this->InitializeReader(&b2);
1099 size_result = -1;
1100 EXPECT_EQ(BlobReader::Status::DONE,
1101 reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result)));
1102 buffer = CreateBuffer(kDataSize + 1);
1103 EXPECT_EQ(BlobReader::Status::NET_ERROR,
1104 reader_->SetReadRange(0, kDataSize + 1));
1105 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());
1106 }
1107
1108 } // namespace
1109 } // namespace storage
OLDNEW
« no previous file with comments | « no previous file | content/browser/fileapi/blob_url_request_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698