Index: content/browser/blob_storage/blob_reader_unittest.cc |
diff --git a/content/browser/blob_storage/blob_reader_unittest.cc b/content/browser/blob_storage/blob_reader_unittest.cc |
deleted file mode 100644 |
index 399af8f4731de47bac1954b246d91678250d5e4d..0000000000000000000000000000000000000000 |
--- a/content/browser/blob_storage/blob_reader_unittest.cc |
+++ /dev/null |
@@ -1,1249 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include <stddef.h> |
-#include <stdint.h> |
-#include <string.h> |
- |
-#include <memory> |
-#include <utility> |
- |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/callback.h" |
-#include "base/files/file_path.h" |
-#include "base/location.h" |
-#include "base/macros.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/run_loop.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/task_runner.h" |
-#include "base/time/time.h" |
-#include "content/public/test/async_file_test_helper.h" |
-#include "content/public/test/test_file_system_context.h" |
-#include "net/base/completion_callback.h" |
-#include "net/base/io_buffer.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/test_completion_callback.h" |
-#include "net/disk_cache/disk_cache.h" |
-#include "storage/browser/blob/blob_data_builder.h" |
-#include "storage/browser/blob/blob_data_handle.h" |
-#include "storage/browser/blob/blob_reader.h" |
-#include "storage/browser/blob/blob_storage_context.h" |
-#include "storage/browser/fileapi/file_stream_reader.h" |
-#include "storage/browser/fileapi/file_system_context.h" |
-#include "storage/browser/fileapi/file_system_file_util.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
-#include "url/gurl.h" |
- |
-using base::FilePath; |
-using content::AsyncFileTestHelper; |
-using net::DrainableIOBuffer; |
-using net::IOBuffer; |
-using FileCreationInfo = storage::BlobMemoryController::FileCreationInfo; |
- |
-namespace storage { |
-namespace { |
- |
-const int kTestDiskCacheStreamIndex = 0; |
-const int kTestDiskCacheSideStreamIndex = 1; |
- |
-void SaveBlobStatusAndFiles(BlobStatus* status_ptr, |
- std::vector<FileCreationInfo>* files_ptr, |
- BlobStatus status, |
- std::vector<FileCreationInfo> files) { |
- *status_ptr = status; |
- for (FileCreationInfo& info : files) { |
- files_ptr->push_back(std::move(info)); |
- } |
-} |
- |
-// Our disk cache tests don't need a real data handle since the tests themselves |
-// scope the disk cache and entries. |
-class EmptyDataHandle : public storage::BlobDataBuilder::DataHandle { |
- private: |
- ~EmptyDataHandle() override {} |
-}; |
- |
-// A disk_cache::Entry that arbitrarily delays the completion of a read |
-// operation to allow testing some races without flake. This is particularly |
-// relevant in this unit test, which uses the always-synchronous MEMORY_CACHE. |
-class DelayedReadEntry : public disk_cache::Entry { |
- public: |
- explicit DelayedReadEntry(disk_cache::ScopedEntryPtr entry) |
- : entry_(std::move(entry)) {} |
- ~DelayedReadEntry() override { EXPECT_FALSE(HasPendingReadCallbacks()); } |
- |
- bool HasPendingReadCallbacks() { return !pending_read_callbacks_.empty(); } |
- |
- void RunPendingReadCallbacks() { |
- std::vector<base::Callback<void(void)>> callbacks; |
- pending_read_callbacks_.swap(callbacks); |
- for (const auto& callback : callbacks) |
- callback.Run(); |
- } |
- |
- // From disk_cache::Entry: |
- void Doom() override { entry_->Doom(); } |
- |
- void Close() override { delete this; } // Note this is required by the API. |
- |
- std::string GetKey() const override { return entry_->GetKey(); } |
- |
- base::Time GetLastUsed() const override { return entry_->GetLastUsed(); } |
- |
- base::Time GetLastModified() const override { |
- return entry_->GetLastModified(); |
- } |
- |
- int32_t GetDataSize(int index) const override { |
- return entry_->GetDataSize(index); |
- } |
- |
- int ReadData(int index, |
- int offset, |
- IOBuffer* buf, |
- int buf_len, |
- const CompletionCallback& original_callback) override { |
- net::TestCompletionCallback callback; |
- int rv = entry_->ReadData(index, offset, buf, buf_len, callback.callback()); |
- DCHECK_NE(rv, net::ERR_IO_PENDING) |
- << "Test expects to use a MEMORY_CACHE instance, which is synchronous."; |
- pending_read_callbacks_.push_back(base::Bind(original_callback, rv)); |
- return net::ERR_IO_PENDING; |
- } |
- |
- int WriteData(int index, |
- int offset, |
- IOBuffer* buf, |
- int buf_len, |
- const CompletionCallback& callback, |
- bool truncate) override { |
- return entry_->WriteData(index, offset, buf, buf_len, callback, truncate); |
- } |
- |
- int ReadSparseData(int64_t offset, |
- IOBuffer* buf, |
- int buf_len, |
- const CompletionCallback& callback) override { |
- return entry_->ReadSparseData(offset, buf, buf_len, callback); |
- } |
- |
- int WriteSparseData(int64_t offset, |
- IOBuffer* buf, |
- int buf_len, |
- const CompletionCallback& callback) override { |
- return entry_->WriteSparseData(offset, buf, buf_len, callback); |
- } |
- |
- int GetAvailableRange(int64_t offset, |
- int len, |
- int64_t* start, |
- const CompletionCallback& callback) override { |
- return entry_->GetAvailableRange(offset, len, start, callback); |
- } |
- |
- bool CouldBeSparse() const override { return entry_->CouldBeSparse(); } |
- |
- void CancelSparseIO() override { entry_->CancelSparseIO(); } |
- |
- int ReadyForSparseIO(const CompletionCallback& callback) override { |
- return entry_->ReadyForSparseIO(callback); |
- } |
- |
- private: |
- disk_cache::ScopedEntryPtr entry_; |
- std::vector<base::Callback<void(void)>> pending_read_callbacks_; |
-}; |
- |
-std::unique_ptr<disk_cache::Backend> CreateInMemoryDiskCache( |
- const scoped_refptr<base::SingleThreadTaskRunner>& thread) { |
- std::unique_ptr<disk_cache::Backend> cache; |
- net::TestCompletionCallback callback; |
- int rv = disk_cache::CreateCacheBackend( |
- net::MEMORY_CACHE, net::CACHE_BACKEND_DEFAULT, FilePath(), 0, false, |
- thread, nullptr, &cache, callback.callback()); |
- EXPECT_EQ(net::OK, callback.GetResult(rv)); |
- |
- return cache; |
-} |
- |
-disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache, |
- const char* key, |
- const std::string& data) { |
- disk_cache::Entry* temp_entry = nullptr; |
- net::TestCompletionCallback callback; |
- int rv = cache->CreateEntry(key, &temp_entry, callback.callback()); |
- if (callback.GetResult(rv) != net::OK) |
- return nullptr; |
- disk_cache::ScopedEntryPtr entry(temp_entry); |
- |
- scoped_refptr<net::StringIOBuffer> iobuffer = new net::StringIOBuffer(data); |
- rv = entry->WriteData(kTestDiskCacheStreamIndex, 0, iobuffer.get(), |
- iobuffer->size(), callback.callback(), false); |
- EXPECT_EQ(static_cast<int>(data.size()), callback.GetResult(rv)); |
- return entry; |
-} |
- |
-disk_cache::ScopedEntryPtr CreateDiskCacheEntryWithSideData( |
- disk_cache::Backend* cache, |
- const char* key, |
- const std::string& data, |
- const std::string& side_data) { |
- disk_cache::ScopedEntryPtr entry = CreateDiskCacheEntry(cache, key, data); |
- scoped_refptr<net::StringIOBuffer> iobuffer = |
- new net::StringIOBuffer(side_data); |
- net::TestCompletionCallback callback; |
- int rv = entry->WriteData(kTestDiskCacheSideStreamIndex, 0, iobuffer.get(), |
- iobuffer->size(), callback.callback(), false); |
- EXPECT_EQ(static_cast<int>(side_data.size()), callback.GetResult(rv)); |
- return entry; |
-} |
- |
-template <typename T> |
-void SetValue(T* address, T value) { |
- *address = value; |
-} |
- |
-class FakeFileStreamReader : public FileStreamReader { |
- public: |
- explicit FakeFileStreamReader(const std::string& contents) |
- : buffer_(new DrainableIOBuffer( |
- new net::StringIOBuffer( |
- std::unique_ptr<std::string>(new std::string(contents))), |
- contents.size())), |
- net_error_(net::OK), |
- size_(contents.size()) {} |
- FakeFileStreamReader(const std::string& contents, uint64_t size) |
- : buffer_(new DrainableIOBuffer( |
- new net::StringIOBuffer( |
- std::unique_ptr<std::string>(new std::string(contents))), |
- contents.size())), |
- net_error_(net::OK), |
- size_(size) {} |
- |
- ~FakeFileStreamReader() override {} |
- |
- void SetReturnError(int net_error) { net_error_ = net_error; } |
- |
- void SetAsyncRunner(base::SingleThreadTaskRunner* runner) { |
- async_task_runner_ = runner; |
- } |
- |
- int Read(net::IOBuffer* buf, |
- int buf_length, |
- const net::CompletionCallback& done) override { |
- DCHECK(buf); |
- // When async_task_runner_ is not set, return synchronously. |
- if (!async_task_runner_.get()) { |
- if (net_error_ == net::OK) { |
- return ReadImpl(buf, buf_length, net::CompletionCallback()); |
- } else { |
- return net_error_; |
- } |
- } |
- |
- // Otherwise always return asynchronously. |
- if (net_error_ == net::OK) { |
- async_task_runner_->PostTask( |
- FROM_HERE, |
- base::Bind(base::IgnoreResult(&FakeFileStreamReader::ReadImpl), |
- base::Unretained(this), make_scoped_refptr(buf), |
- buf_length, done)); |
- } else { |
- async_task_runner_->PostTask(FROM_HERE, base::Bind(done, net_error_)); |
- } |
- return net::ERR_IO_PENDING; |
- } |
- |
- int64_t GetLength( |
- const net::Int64CompletionCallback& size_callback) override { |
- // When async_task_runner_ is not set, return synchronously. |
- if (!async_task_runner_.get()) { |
- if (net_error_ == net::OK) { |
- return size_; |
- } else { |
- return net_error_; |
- } |
- } |
- if (net_error_ == net::OK) { |
- async_task_runner_->PostTask(FROM_HERE, base::Bind(size_callback, size_)); |
- } else { |
- async_task_runner_->PostTask( |
- FROM_HERE, |
- base::Bind(size_callback, static_cast<int64_t>(net_error_))); |
- } |
- return net::ERR_IO_PENDING; |
- } |
- |
- private: |
- int ReadImpl(scoped_refptr<net::IOBuffer> buf, |
- int buf_length, |
- const net::CompletionCallback& done) { |
- CHECK_GE(buf_length, 0); |
- int length = std::min(buf_length, buffer_->BytesRemaining()); |
- memcpy(buf->data(), buffer_->data(), length); |
- buffer_->DidConsume(length); |
- if (done.is_null()) { |
- return length; |
- } |
- done.Run(length); |
- return net::ERR_IO_PENDING; |
- } |
- |
- scoped_refptr<net::DrainableIOBuffer> buffer_; |
- scoped_refptr<base::SingleThreadTaskRunner> async_task_runner_; |
- int net_error_; |
- uint64_t size_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeFileStreamReader); |
-}; |
- |
-class MockFileStreamReaderProvider |
- : public BlobReader::FileStreamReaderProvider { |
- public: |
- ~MockFileStreamReaderProvider() override {} |
- |
- MOCK_METHOD4(CreateForLocalFileMock, |
- FileStreamReader*(base::TaskRunner* task_runner, |
- const FilePath& file_path, |
- int64_t initial_offset, |
- const base::Time& expected_modification_time)); |
- MOCK_METHOD4(CreateFileStreamReaderMock, |
- FileStreamReader*(const GURL& filesystem_url, |
- int64_t offset, |
- int64_t max_bytes_to_read, |
- const base::Time& expected_modification_time)); |
- // Since we're returning a move-only type, we have to do some delegation for |
- // gmock. |
- std::unique_ptr<FileStreamReader> CreateForLocalFile( |
- base::TaskRunner* task_runner, |
- const base::FilePath& file_path, |
- int64_t initial_offset, |
- const base::Time& expected_modification_time) override { |
- return base::WrapUnique(CreateForLocalFileMock( |
- task_runner, file_path, initial_offset, expected_modification_time)); |
- } |
- |
- std::unique_ptr<FileStreamReader> CreateFileStreamReader( |
- const GURL& filesystem_url, |
- int64_t offset, |
- int64_t max_bytes_to_read, |
- const base::Time& expected_modification_time) override { |
- return base::WrapUnique(CreateFileStreamReaderMock( |
- filesystem_url, offset, max_bytes_to_read, expected_modification_time)); |
- } |
-}; |
- |
-} // namespace |
- |
-class BlobReaderTest : public ::testing::Test { |
- public: |
- BlobReaderTest() {} |
- ~BlobReaderTest() override {} |
- |
- void TearDown() override { |
- reader_.reset(); |
- blob_handle_.reset(); |
- base::RunLoop().RunUntilIdle(); |
- base::RunLoop().RunUntilIdle(); |
- } |
- |
- protected: |
- void InitializeReader(BlobDataBuilder* builder) { |
- blob_handle_ = builder ? context_.AddFinishedBlob(builder) : nullptr; |
- provider_ = new MockFileStreamReaderProvider(); |
- reader_.reset(new BlobReader(blob_handle_.get(), |
- base::WrapUnique(provider_), |
- message_loop_.task_runner().get())); |
- } |
- |
- // Takes ownership of the file reader (the blob reader takes ownership). |
- void ExpectLocalFileCall(const FilePath& file_path, |
- base::Time modification_time, |
- uint64_t initial_offset, |
- FakeFileStreamReader* reader) { |
- EXPECT_CALL(*provider_, CreateForLocalFileMock( |
- message_loop_.task_runner().get(), file_path, |
- initial_offset, modification_time)) |
- .WillOnce(testing::Return(reader)); |
- } |
- |
- // Takes ownership of the file reader (the blob reader takes ownership). |
- void ExpectFileSystemCall(const GURL& filesystem_url, |
- int64_t offset, |
- int64_t max_bytes_to_read, |
- base::Time expected_modification_time, |
- FakeFileStreamReader* reader) { |
- EXPECT_CALL(*provider_, CreateFileStreamReaderMock( |
- filesystem_url, offset, max_bytes_to_read, |
- expected_modification_time)) |
- .WillOnce(testing::Return(reader)); |
- } |
- |
- void CheckSizeCalculatedSynchronously(size_t expected_size, int async_size) { |
- EXPECT_EQ(-1, async_size); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(expected_size, reader_->total_size()); |
- EXPECT_TRUE(reader_->total_size_calculated()); |
- } |
- |
- void CheckSizeNotCalculatedYet(int async_size) { |
- EXPECT_EQ(-1, async_size); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_FALSE(reader_->total_size_calculated()); |
- } |
- |
- void CheckSizeCalculatedAsynchronously(size_t expected_size, |
- int async_result) { |
- EXPECT_EQ(net::OK, async_result); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(expected_size, reader_->total_size()); |
- EXPECT_TRUE(reader_->total_size_calculated()); |
- } |
- |
- scoped_refptr<net::IOBuffer> CreateBuffer(uint64_t size) { |
- return scoped_refptr<net::IOBuffer>( |
- new net::IOBuffer(static_cast<size_t>(size))); |
- } |
- |
- bool IsReaderTotalSizeCalculated() { |
- return reader_->total_size_calculated(); |
- } |
- |
- BlobStorageContext context_; |
- std::unique_ptr<BlobDataHandle> blob_handle_; |
- MockFileStreamReaderProvider* provider_ = nullptr; |
- base::MessageLoop message_loop_; |
- std::unique_ptr<BlobReader> reader_; |
- |
- private: |
- DISALLOW_COPY_AND_ASSIGN(BlobReaderTest); |
-}; |
- |
-TEST_F(BlobReaderTest, BasicMemory) { |
- BlobDataBuilder b("uuid"); |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- b.AppendData(kData); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_TRUE(reader_->IsInMemory()); |
- CheckSizeCalculatedSynchronously(kDataSize, size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kDataSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kDataSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Hello!!!", kDataSize)); |
-} |
- |
-TEST_F(BlobReaderTest, BasicFile) { |
- BlobDataBuilder b("uuid"); |
- const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- b.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&b); |
- |
- // Non-async reader. |
- ExpectLocalFileCall(kPath, kTime, 0, new FakeFileStreamReader(kData)); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, BasicFileSystem) { |
- BlobDataBuilder b("uuid"); |
- const GURL kURL("file://test_file/here.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- b.AppendFileSystemFile(kURL, 0, kData.size(), kTime); |
- this->InitializeReader(&b); |
- // Non-async reader. |
- ExpectFileSystemCall(kURL, 0, kData.size(), kTime, |
- new FakeFileStreamReader(kData)); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, BasicDiskCache) { |
- std::unique_ptr<disk_cache::Backend> cache = |
- CreateInMemoryDiskCache(message_loop_.task_runner()); |
- ASSERT_TRUE(cache); |
- |
- BlobDataBuilder b("uuid"); |
- const std::string kData = "Test Blob Data"; |
- scoped_refptr<BlobDataBuilder::DataHandle> data_handle = |
- new EmptyDataHandle(); |
- disk_cache::ScopedEntryPtr entry = |
- CreateDiskCacheEntry(cache.get(), "test entry", kData); |
- b.AppendDiskCacheEntry(data_handle, entry.get(), kTestDiskCacheStreamIndex); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- EXPECT_FALSE(reader_->has_side_data()); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Test Blob Data", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, DiskCacheWithSideData) { |
- std::unique_ptr<disk_cache::Backend> cache = |
- CreateInMemoryDiskCache(message_loop_.task_runner()); |
- ASSERT_TRUE(cache); |
- |
- BlobDataBuilder b("uuid"); |
- const std::string kData = "Test Blob Data"; |
- const std::string kSideData = "Test side data"; |
- scoped_refptr<BlobDataBuilder::DataHandle> data_handle = |
- new EmptyDataHandle(); |
- disk_cache::ScopedEntryPtr entry = CreateDiskCacheEntryWithSideData( |
- cache.get(), "test entry", kData, kSideData); |
- b.AppendDiskCacheEntryWithSideData(data_handle, entry.get(), |
- kTestDiskCacheStreamIndex, |
- kTestDiskCacheSideStreamIndex); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- EXPECT_TRUE(reader_->has_side_data()); |
- BlobReader::Status status = BlobReader::Status::DONE; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->ReadSideData( |
- base::Bind(&SetValue<BlobReader::Status>, &status))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_TRUE(reader_->side_data()); |
- std::string result(reader_->side_data()->data(), |
- reader_->side_data()->size()); |
- EXPECT_EQ(kSideData, result); |
-} |
- |
-TEST_F(BlobReaderTest, BufferLargerThanMemory) { |
- BlobDataBuilder b("uuid"); |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- const size_t kBufferSize = 10ul; |
- b.AppendData(kData); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kBufferSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kDataSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Hello!!!", kDataSize)); |
-} |
- |
-TEST_F(BlobReaderTest, MemoryRange) { |
- BlobDataBuilder b("uuid"); |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- const size_t kSeekOffset = 2ul; |
- const uint64_t kReadLength = 4ull; |
- b.AppendData(kData); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength); |
- |
- reader_->SetReadRange(kSeekOffset, kReadLength); |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kDataSize - kSeekOffset, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kReadLength, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "llo!", kReadLength)); |
-} |
- |
-TEST_F(BlobReaderTest, BufferSmallerThanMemory) { |
- BlobDataBuilder b("uuid"); |
- const std::string kData("Hello!!!"); |
- const size_t kBufferSize = 4ul; |
- b.AppendData(kData); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kBufferSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Hell", kBufferSize)); |
- |
- bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kBufferSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "o!!!", kBufferSize)); |
-} |
- |
-TEST_F(BlobReaderTest, SegmentedBufferAndMemory) { |
- BlobDataBuilder b("uuid"); |
- const size_t kNumItems = 10; |
- const size_t kItemSize = 6; |
- const size_t kBufferSize = 10; |
- const size_t kTotalSize = kNumItems * kItemSize; |
- char current_value = 0; |
- for (size_t i = 0; i < kNumItems; i++) { |
- char buf[kItemSize]; |
- for (size_t j = 0; j < kItemSize; j++) { |
- buf[j] = current_value++; |
- } |
- b.AppendData(buf, kItemSize); |
- } |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kTotalSize, size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); |
- |
- current_value = 0; |
- for (size_t i = 0; i < kTotalSize / kBufferSize; i++) { |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kBufferSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kBufferSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- for (size_t j = 0; j < kBufferSize; j++) { |
- EXPECT_EQ(current_value, buffer->data()[j]); |
- current_value++; |
- } |
- } |
-} |
- |
-TEST_F(BlobReaderTest, FileAsync) { |
- BlobDataBuilder b("uuid"); |
- const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- b.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&b); |
- |
- std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData)); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- |
- ExpectLocalFileCall(kPath, kTime, 0, reader.release()); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- CheckSizeNotCalculatedYet(size_result); |
- base::RunLoop().RunUntilIdle(); |
- CheckSizeCalculatedAsynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read)); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, FileSystemAsync) { |
- BlobDataBuilder b("uuid"); |
- const GURL kURL("file://test_file/here.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- b.AppendFileSystemFile(kURL, 0, kData.size(), kTime); |
- this->InitializeReader(&b); |
- |
- std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData)); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- |
- ExpectFileSystemCall(kURL, 0, kData.size(), kTime, reader.release()); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeNotCalculatedYet(size_result); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- base::RunLoop().RunUntilIdle(); |
- CheckSizeCalculatedAsynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read)); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "FileData!!!", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, DiskCacheAsync) { |
- std::unique_ptr<disk_cache::Backend> cache = |
- CreateInMemoryDiskCache(message_loop_.task_runner()); |
- ASSERT_TRUE(cache); |
- |
- BlobDataBuilder b("uuid"); |
- const std::string kData = "Test Blob Data"; |
- scoped_refptr<BlobDataBuilder::DataHandle> data_handle = |
- new EmptyDataHandle(); |
- std::unique_ptr<DelayedReadEntry> delayed_read_entry(new DelayedReadEntry( |
- CreateDiskCacheEntry(cache.get(), "test entry", kData))); |
- b.AppendDiskCacheEntry(data_handle, delayed_read_entry.get(), |
- kTestDiskCacheStreamIndex); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeCalculatedSynchronously(kData.size(), size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_TRUE(delayed_read_entry->HasPendingReadCallbacks()); |
- delayed_read_entry->RunPendingReadCallbacks(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(kData.size(), static_cast<size_t>(async_bytes_read)); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Test Blob Data", kData.size())); |
-} |
- |
-TEST_F(BlobReaderTest, FileRange) { |
- BlobDataBuilder b("uuid"); |
- const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- // We check the offset in the ExpectLocalFileCall mock. |
- const std::string kRangeData = "leD"; |
- const std::string kData = "FileData!!!"; |
- const uint64_t kOffset = 2; |
- const uint64_t kReadLength = 3; |
- const base::Time kTime = base::Time::Now(); |
- b.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&b); |
- |
- std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData)); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- ExpectLocalFileCall(kPath, kTime, 0, reader.release()); |
- |
- // We create the reader again with the offset after the seek. |
- reader.reset(new FakeFileStreamReader(kRangeData)); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- ExpectLocalFileCall(kPath, kTime, kOffset, reader.release()); |
- |
- int size_result = -1; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- base::RunLoop().RunUntilIdle(); |
- |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->SetReadRange(kOffset, kReadLength)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kReadLength, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kReadLength, static_cast<size_t>(async_bytes_read)); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "leD", kReadLength)); |
-} |
- |
-TEST_F(BlobReaderTest, DiskCacheRange) { |
- std::unique_ptr<disk_cache::Backend> cache = |
- CreateInMemoryDiskCache(message_loop_.task_runner()); |
- ASSERT_TRUE(cache); |
- |
- BlobDataBuilder b("uuid"); |
- const std::string kData = "Test Blob Data"; |
- const uint64_t kOffset = 2; |
- const uint64_t kReadLength = 3; |
- scoped_refptr<BlobDataBuilder::DataHandle> data_handle = |
- new EmptyDataHandle(); |
- disk_cache::ScopedEntryPtr entry = |
- CreateDiskCacheEntry(cache.get(), "test entry", kData); |
- b.AppendDiskCacheEntry(data_handle, entry.get(), kTestDiskCacheStreamIndex); |
- this->InitializeReader(&b); |
- |
- int size_result = -1; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kReadLength); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->SetReadRange(kOffset, kReadLength)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kReadLength, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kReadLength, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(0, memcmp(buffer->data(), "st ", kReadLength)); |
-} |
- |
-TEST_F(BlobReaderTest, FileSomeAsyncSegmentedOffsetsUnknownSizes) { |
- // This tests includes: |
- // * Unknown file sizes (item length of uint64_t::max) for every other item. |
- // * Offsets for every 3rd file item. |
- // * Non-async reader for every 4th file item. |
- BlobDataBuilder b("uuid"); |
- const FilePath kPathBase = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- const base::Time kTime = base::Time::Now(); |
- const size_t kNumItems = 10; |
- const size_t kItemSize = 6; |
- const size_t kBufferSize = 10; |
- const size_t kTotalSize = kNumItems * kItemSize; |
- char current_value = 0; |
- // Create blob and reader. |
- for (size_t i = 0; i < kNumItems; i++) { |
- current_value += kItemSize; |
- FilePath path = kPathBase.Append( |
- FilePath::FromUTF8Unsafe(base::StringPrintf("%d", current_value))); |
- uint64_t offset = i % 3 == 0 ? 1 : 0; |
- uint64_t size = kItemSize; |
- b.AppendFile(path, offset, size, kTime); |
- } |
- this->InitializeReader(&b); |
- |
- // Set expectations. |
- current_value = 0; |
- for (size_t i = 0; i < kNumItems; i++) { |
- uint64_t offset = i % 3 == 0 ? 1 : 0; |
- std::unique_ptr<char[]> buf(new char[kItemSize + offset]); |
- if (offset > 0) { |
- memset(buf.get(), 7, offset); |
- } |
- for (size_t j = 0; j < kItemSize; j++) { |
- buf.get()[j + offset] = current_value++; |
- } |
- std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader( |
- std::string(buf.get() + offset, kItemSize), kItemSize + offset)); |
- if (i % 4 != 0) { |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- } |
- FilePath path = kPathBase.Append( |
- FilePath::FromUTF8Unsafe(base::StringPrintf("%d", current_value))); |
- ExpectLocalFileCall(path, kTime, offset, reader.release()); |
- } |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeNotCalculatedYet(size_result); |
- base::RunLoop().RunUntilIdle(); |
- CheckSizeCalculatedAsynchronously(kTotalSize, size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); |
- |
- current_value = 0; |
- for (size_t i = 0; i < kTotalSize / kBufferSize; i++) { |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kBufferSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(kBufferSize, static_cast<size_t>(async_bytes_read)); |
- for (size_t j = 0; j < kBufferSize; j++) { |
- EXPECT_EQ(current_value, buffer->data()[j]); |
- current_value++; |
- } |
- } |
-} |
- |
-TEST_F(BlobReaderTest, MixedContent) { |
- // Includes data, a file, and a disk cache entry. |
- std::unique_ptr<disk_cache::Backend> cache = |
- CreateInMemoryDiskCache(message_loop_.task_runner()); |
- ASSERT_TRUE(cache); |
- |
- BlobDataBuilder b("uuid"); |
- const std::string kData1("Hello "); |
- const std::string kData2("there. "); |
- const std::string kData3("This "); |
- const std::string kData4("is multi-content."); |
- const uint64_t kDataSize = 35; |
- |
- const base::Time kTime = base::Time::Now(); |
- const FilePath kData1Path = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- |
- disk_cache::ScopedEntryPtr entry3 = |
- CreateDiskCacheEntry(cache.get(), "test entry", kData3); |
- |
- b.AppendFile(kData1Path, 0, kData1.size(), kTime); |
- b.AppendData(kData2); |
- b.AppendDiskCacheEntry( |
- scoped_refptr<BlobDataBuilder::DataHandle>(new EmptyDataHandle()), |
- entry3.get(), kTestDiskCacheStreamIndex); |
- b.AppendData(kData4); |
- |
- this->InitializeReader(&b); |
- |
- std::unique_ptr<FakeFileStreamReader> reader( |
- new FakeFileStreamReader(kData1)); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- ExpectLocalFileCall(kData1Path, kTime, 0, reader.release()); |
- |
- int size_result = -1; |
- EXPECT_FALSE(IsReaderTotalSizeCalculated()); |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- CheckSizeNotCalculatedYet(size_result); |
- base::RunLoop().RunUntilIdle(); |
- CheckSizeCalculatedAsynchronously(kDataSize, size_result); |
- |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kDataSize); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kDataSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(0, async_bytes_read); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(0, bytes_read); |
- EXPECT_EQ(kDataSize, static_cast<size_t>(async_bytes_read)); |
- EXPECT_EQ(0, memcmp(buffer->data(), "Hello there. This is multi-content.", |
- kDataSize)); |
-} |
- |
-TEST_F(BlobReaderTest, StateErrors) { |
- // Test common variables |
- int bytes_read = -1; |
- int async_bytes_read = -1; |
- int size_result = -1; |
- const std::string kData("Hello!!!"); |
- |
- // Case: Blob handle is a nullptr. |
- InitializeReader(nullptr); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, reader_->SetReadRange(0, 10)); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(10); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->Read(buffer.get(), 10, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- |
- // Case: Not calling CalculateSize before SetReadRange. |
- BlobDataBuilder builder1("uuid1"); |
- builder1.AppendData(kData); |
- InitializeReader(&builder1); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, reader_->SetReadRange(0, 10)); |
- EXPECT_EQ(net::ERR_FAILED, reader_->net_error()); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->Read(buffer.get(), 10, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- |
- // Case: Not calling CalculateSize before Read. |
- BlobDataBuilder builder2("uuid2"); |
- builder2.AppendData(kData); |
- InitializeReader(&builder2); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->Read(buffer.get(), 10, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
-} |
- |
-TEST_F(BlobReaderTest, FileErrorsSync) { |
- int size_result = -1; |
- const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- |
- // Case: Error on length query. |
- BlobDataBuilder builder1("uuid1"); |
- builder1.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&builder1); |
- FakeFileStreamReader* reader = new FakeFileStreamReader(kData); |
- reader->SetReturnError(net::ERR_FILE_NOT_FOUND); |
- ExpectLocalFileCall(kPath, kTime, 0, reader); |
- |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- |
- // Case: Error on read. |
- BlobDataBuilder builder2("uuid2"); |
- builder2.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&builder2); |
- reader = new FakeFileStreamReader(kData); |
- ExpectLocalFileCall(kPath, kTime, 0, reader); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- reader->SetReturnError(net::ERR_FILE_NOT_FOUND); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
-} |
- |
-TEST_F(BlobReaderTest, FileErrorsAsync) { |
- int size_result = -1; |
- const FilePath kPath = FilePath::FromUTF8Unsafe("/fake/file.txt"); |
- const std::string kData = "FileData!!!"; |
- const base::Time kTime = base::Time::Now(); |
- |
- // Case: Error on length query. |
- BlobDataBuilder builder1("uuid1"); |
- builder1.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&builder1); |
- FakeFileStreamReader* reader = new FakeFileStreamReader(kData); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- reader->SetReturnError(net::ERR_FILE_NOT_FOUND); |
- ExpectLocalFileCall(kPath, kTime, 0, reader); |
- |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, size_result); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- |
- // Case: Error on read. |
- BlobDataBuilder builder2("uuid2"); |
- builder2.AppendFile(kPath, 0, kData.size(), kTime); |
- this->InitializeReader(&builder2); |
- reader = new FakeFileStreamReader(kData); |
- ExpectLocalFileCall(kPath, kTime, 0, reader); |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- reader->SetReturnError(net::ERR_FILE_NOT_FOUND); |
- reader->SetAsyncRunner(message_loop_.task_runner().get()); |
- |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kData.size())); |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->Read(buffer.get(), kData.size(), &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, async_bytes_read); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
-} |
- |
-TEST_F(BlobReaderTest, RangeError) { |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- const uint64_t kReadLength = 4ull; |
- |
- // Case: offset too high. |
- BlobDataBuilder b("uuid1"); |
- b.AppendData(kData); |
- this->InitializeReader(&b); |
- int size_result = -1; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- scoped_refptr<net::IOBuffer> buffer = CreateBuffer(kDataSize); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->SetReadRange(kDataSize + 1, kReadLength)); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
- |
- // Case: length too long. |
- BlobDataBuilder b2("uuid2"); |
- b2.AppendData(kData); |
- this->InitializeReader(&b2); |
- size_result = -1; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- buffer = CreateBuffer(kDataSize + 1); |
- EXPECT_EQ(BlobReader::Status::NET_ERROR, |
- reader_->SetReadRange(0, kDataSize + 1)); |
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error()); |
-} |
- |
-TEST_F(BlobReaderTest, HandleBeforeAsyncCancel) { |
- const std::string kUuid("uuid1"); |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- std::vector<FileCreationInfo> files; |
- |
- BlobDataBuilder b(kUuid); |
- b.AppendFutureData(kDataSize); |
- BlobStatus can_populate_status = |
- BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
- blob_handle_ = context_.BuildBlob( |
- b, base::Bind(&SaveBlobStatusAndFiles, &can_populate_status, &files)); |
- EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, can_populate_status); |
- provider_ = new MockFileStreamReaderProvider(); |
- reader_.reset(new BlobReader(blob_handle_.get(), base::WrapUnique(provider_), |
- message_loop_.task_runner().get())); |
- int size_result = -1; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- context_.CancelBuildingBlob(kUuid, |
- BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS); |
- base::RunLoop().RunUntilIdle(); |
- EXPECT_EQ(net::ERR_FAILED, size_result); |
-} |
- |
-TEST_F(BlobReaderTest, ReadFromIncompleteBlob) { |
- const std::string kUuid("uuid1"); |
- const std::string kData("Hello!!!"); |
- const size_t kDataSize = 8ul; |
- std::vector<FileCreationInfo> files; |
- |
- BlobDataBuilder b(kUuid); |
- b.AppendFutureData(kDataSize); |
- BlobStatus can_populate_status = |
- BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS; |
- blob_handle_ = context_.BuildBlob( |
- b, base::Bind(&SaveBlobStatusAndFiles, &can_populate_status, &files)); |
- EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, can_populate_status); |
- provider_ = new MockFileStreamReaderProvider(); |
- reader_.reset(new BlobReader(blob_handle_.get(), base::WrapUnique(provider_), |
- message_loop_.task_runner().get())); |
- int size_result = -1; |
- EXPECT_EQ(BlobReader::Status::IO_PENDING, |
- reader_->CalculateSize(base::Bind(&SetValue<int>, &size_result))); |
- EXPECT_FALSE(reader_->IsInMemory()); |
- b.PopulateFutureData(0, kData.data(), 0, kDataSize); |
- context_.NotifyTransportComplete(kUuid); |
- base::RunLoop().RunUntilIdle(); |
- CheckSizeCalculatedAsynchronously(kDataSize, size_result); |
- scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize)); |
- |
- int bytes_read = 0; |
- int async_bytes_read = 0; |
- EXPECT_EQ(BlobReader::Status::DONE, |
- reader_->Read(buffer.get(), kDataSize, &bytes_read, |
- base::Bind(&SetValue<int>, &async_bytes_read))); |
- EXPECT_EQ(net::OK, reader_->net_error()); |
- EXPECT_EQ(kDataSize, static_cast<size_t>(bytes_read)); |
- EXPECT_EQ(0, async_bytes_read); |
- EXPECT_EQ(kData, std::string(buffer->data(), kDataSize)); |
- EXPECT_EQ(net::OK, size_result); |
-} |
- |
-} // namespace storage |