// 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 <algorithm>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/task/task_runner.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "net/base/completion_once_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.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/file_system/file_stream_reader.h"
#include "storage/browser/file_system/file_system_context.h"
#include "storage/browser/file_system/file_system_file_util.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/test/async_file_test_helper.h"
#include "storage/browser/test/fake_blob_data_handle.h"
#include "storage/browser/test/test_file_system_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using base::FilePath;
using net::DrainableIOBuffer;
using net::IOBuffer;

namespace storage {
namespace {

using FileCreationInfo = BlobMemoryController::FileCreationInfo;

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));
  }
}

template <typename T>
void SetValue(T* address, T value) {
  *address = value;
}

class FakeFileStreamReader : public FileStreamReader {
 public:
  explicit FakeFileStreamReader(const std::string& contents)
      : buffer_(base::MakeRefCounted<DrainableIOBuffer>(
            base::MakeRefCounted<net::StringIOBuffer>(
                std::make_unique<std::string>(contents)),
            contents.size())),
        net_error_(net::OK),
        size_(contents.size()) {}
  FakeFileStreamReader(const std::string& contents, uint64_t size)
      : buffer_(base::MakeRefCounted<DrainableIOBuffer>(
            base::MakeRefCounted<net::StringIOBuffer>(
                std::make_unique<std::string>(contents)),
            contents.size())),
        net_error_(net::OK),
        size_(size) {}

  FakeFileStreamReader(const FakeFileStreamReader&) = delete;
  FakeFileStreamReader& operator=(const FakeFileStreamReader&) = delete;

  ~FakeFileStreamReader() override = default;

  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,
           net::CompletionOnceCallback 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::CompletionOnceCallback());
      } else {
        return net_error_;
      }
    }

    // Otherwise always return asynchronously.
    if (net_error_ == net::OK) {
      async_task_runner_->PostTask(
          FROM_HERE,
          base::BindOnce(base::IgnoreResult(&FakeFileStreamReader::ReadImpl),
                         base::Unretained(this), base::WrapRefCounted(buf),
                         buf_length, std::move(done)));
    } else {
      async_task_runner_->PostTask(FROM_HERE,
                                   base::BindOnce(std::move(done), net_error_));
    }
    return net::ERR_IO_PENDING;
  }

  int64_t GetLength(net::Int64CompletionOnceCallback 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::BindOnce(std::move(size_callback), size_));
    } else {
      async_task_runner_->PostTask(
          FROM_HERE, base::BindOnce(std::move(size_callback),
                                    static_cast<int64_t>(net_error_)));
    }
    return net::ERR_IO_PENDING;
  }

 private:
  int ReadImpl(scoped_refptr<net::IOBuffer> buf,
               int buf_length,
               net::CompletionOnceCallback 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;
    }
    std::move(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_;
};

class MockFileStreamReaderProvider
    : public BlobReader::FileStreamReaderProvider {
 public:
  ~MockFileStreamReaderProvider() override = default;

  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() = default;

  BlobReaderTest(const BlobReaderTest&) = delete;
  BlobReaderTest& operator=(const BlobReaderTest&) = delete;

  ~BlobReaderTest() override = default;

  void SetUp() override {
    file_system_context_ = CreateFileSystemContextForTesting(
        /*quota_manager_proxy=*/nullptr, base::FilePath());
  }

  void TearDown() override {
    reader_.reset();
    blob_handle_.reset();
    base::RunLoop().RunUntilIdle();
    base::RunLoop().RunUntilIdle();
  }

 protected:
  void InitializeReader(std::unique_ptr<BlobDataBuilder> builder) {
    blob_handle_ =
        builder ? context_.AddFinishedBlob(std::move(builder)) : nullptr;
    provider_ = new MockFileStreamReaderProvider();
    reader_.reset(new BlobReader(blob_handle_.get()));
    reader_->SetFileStreamProviderForTesting(base::WrapUnique(provider_.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(testing::_, 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 base::MakeRefCounted<net::IOBuffer>(static_cast<size_t>(size));
  }

  bool IsReaderTotalSizeCalculated() {
    return reader_->total_size_calculated();
  }

  base::test::TaskEnvironment task_environment_;

  BlobStorageContext context_;
  std::unique_ptr<BlobDataHandle> blob_handle_;
  raw_ptr<MockFileStreamReaderProvider> provider_ = nullptr;
  std::unique_ptr<BlobReader> reader_;
  scoped_refptr<FileSystemContext> file_system_context_;
};

TEST_F(BlobReaderTest, BasicMemory) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData("Hello!!!");
  const size_t kDataSize = 8ul;
  b->AppendData(kData);
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  EXPECT_TRUE(reader_->IsInMemory());
  CheckSizeCalculatedSynchronously(kDataSize, size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("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(std::move(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::BindOnce(
                                          &SetValue<int>, &size_result)));
  EXPECT_FALSE(reader_->IsInMemory());
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const GURL kURL("filesystem:http://example.com/temporary/test_file/here.txt");
  const std::string kData = "FileData!!!";
  const base::Time kTime = base::Time::Now();
  b->AppendFileSystemFile(
      file_system_context_->CrackURLInFirstPartyContext(kURL), 0, kData.size(),
      kTime, file_system_context_);
  this->InitializeReader(std::move(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::BindOnce(
                                          &SetValue<int>, &size_result)));
  EXPECT_FALSE(reader_->IsInMemory());

  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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, BasicReadableDataHandle) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData = "Test Blob Data";
  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kData, "");
  b->AppendReadableDataHandle(std::move(data_handle));
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  EXPECT_FALSE(reader_->has_side_data());

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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, ReadableDataHandleWithSideData) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData = "Test Blob Data";
  const std::string kSideData = "Test side data";
  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kData, kSideData);
  b->AppendReadableDataHandle(std::move(data_handle));
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  EXPECT_TRUE(reader_->has_side_data());
  BlobReader::Status status = BlobReader::Status::NET_ERROR;
  // As this is using a FakeBlobDataHandle, expect this to be synchronous.
  reader_->ReadSideData(base::BindOnce(&SetValue<BlobReader::Status>, &status));
  EXPECT_EQ(net::OK, reader_->net_error());
  EXPECT_EQ(BlobReader::Status::DONE, status);
  auto side_data = reader_->TakeSideData();
  EXPECT_TRUE(side_data.has_value());
  std::string result(reinterpret_cast<const char*>(side_data->data()),
                     side_data->size());
  EXPECT_EQ(kSideData, result);
}

TEST_F(BlobReaderTest, BufferLargerThanMemory) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData("Hello!!!");
  const size_t kDataSize = 8ul;
  const size_t kBufferSize = 10ul;
  b->AppendData(kData);
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("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(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData("Hello!!!");
  const size_t kBufferSize = 4ul;
  b->AppendData(kData);
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("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(std::string(buf, kItemSize));
  }
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kTotalSize, size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("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(std::move(b));

  std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());

  ExpectLocalFileCall(kPath, kTime, 0, reader.release());

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&SetValue<int>, &size_result)));
  EXPECT_FALSE(reader_->IsInMemory());
  CheckSizeNotCalculatedYet(size_result);
  base::RunLoop().RunUntilIdle();
  CheckSizeCalculatedAsynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const GURL kURL("filesystem:http://example.com/temporary/test_file/here.txt");
  const std::string kData = "FileData!!!";
  const base::Time kTime = base::Time::Now();
  b->AppendFileSystemFile(
      file_system_context_->CrackURLInFirstPartyContext(kURL), 0, kData.size(),
      kTime, file_system_context_);
  this->InitializeReader(std::move(b));

  std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().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::BindOnce(&SetValue<int>, &size_result)));
  CheckSizeNotCalculatedYet(size_result);
  EXPECT_FALSE(reader_->IsInMemory());
  base::RunLoop().RunUntilIdle();
  CheckSizeCalculatedAsynchronously(kData.size(), size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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, ReadableDataHandleSingle) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kOrigData = "12345 Test Blob Data 12345";
  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kOrigData, "");
  b->AppendReadableDataHandle(data_handle, 6, 14);
  this->InitializeReader(std::move(b));
  const std::string kData = kOrigData.substr(6, 14);

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  // This test checks the optimized single mojo data item path, where the
  // data pipe passed in gets passed directly to the MojoDataItem.
  EXPECT_TRUE(reader_->IsSingleMojoDataItem());

  mojo::ScopedDataPipeProducerHandle producer;
  mojo::ScopedDataPipeConsumerHandle consumer;
  MojoResult pipe_result = mojo::CreateDataPipe(nullptr, producer, consumer);
  ASSERT_EQ(MOJO_RESULT_OK, pipe_result);

  int bytes_read = net::ERR_UNEXPECTED;
  reader_->ReadSingleMojoDataItem(
      std::move(producer),
      base::BindLambdaForTesting([&](int result) { bytes_read = result; }));
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(kData.size(), static_cast<size_t>(bytes_read));

  std::vector<uint8_t> buffer(bytes_read);
  uint32_t num_bytes = bytes_read;
  MojoReadDataFlags flags = MOJO_READ_DATA_FLAG_ALL_OR_NONE;
  MojoResult read_result = consumer->ReadData(buffer.data(), &num_bytes, flags);
  ASSERT_EQ(MOJO_RESULT_OK, read_result);
  ASSERT_EQ(kData.size(), num_bytes);

  EXPECT_EQ(0, memcmp(buffer.data(), kData.c_str(), kData.size()));
}

// This test is the same as ReadableDataHandleSingle, but adds the
// additional wrinkle of a SetReadRange call.
TEST_F(BlobReaderTest, ReadableDataHandleSingleRange) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kOrigData = "12345 Test Blob Data 12345";
  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kOrigData, "");
  b->AppendReadableDataHandle(data_handle, 6, 14);
  this->InitializeReader(std::move(b));
  const std::string kData = kOrigData.substr(6, 14);

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  // This test checks the optimized single mojo data item path, where the
  // data pipe passed in gets passed directly to the MojoDataItem.
  EXPECT_TRUE(reader_->IsSingleMojoDataItem());

  uint64_t range_start = 3;
  uint64_t range_length = 6;
  reader_->SetReadRange(range_start, range_length);

  mojo::ScopedDataPipeProducerHandle producer;
  mojo::ScopedDataPipeConsumerHandle consumer;
  MojoResult pipe_result = mojo::CreateDataPipe(nullptr, producer, consumer);
  ASSERT_EQ(MOJO_RESULT_OK, pipe_result);

  int bytes_read = net::ERR_UNEXPECTED;
  reader_->ReadSingleMojoDataItem(
      std::move(producer),
      base::BindLambdaForTesting([&](int result) { bytes_read = result; }));
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(range_length, static_cast<uint64_t>(bytes_read));

  std::vector<uint8_t> buffer(bytes_read);
  uint32_t num_bytes = bytes_read;
  MojoReadDataFlags flags = MOJO_READ_DATA_FLAG_ALL_OR_NONE;
  MojoResult read_result = consumer->ReadData(buffer.data(), &num_bytes, flags);
  ASSERT_EQ(MOJO_RESULT_OK, read_result);
  ASSERT_EQ(range_length, num_bytes);

  EXPECT_EQ(0,
            memcmp(buffer.data(), kData.c_str() + range_start, range_length));
}

TEST_F(BlobReaderTest, ReadableDataHandleMultipleSlices) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData1 = "Test Blob Data";
  const std::string kData2 = "Extra test blob data";

  // Create readable data handles with various slices of data.
  // It's important to test that both the first element we read and a
  // non-first element that we read handle slices, as these touch different
  // pieces of code.
  b->AppendReadableDataHandle(
      base::MakeRefCounted<FakeBlobDataHandle>(kData1, ""), 5, 4);
  b->AppendReadableDataHandle(
      base::MakeRefCounted<FakeBlobDataHandle>(kData2, ""), 6, 9);
  this->InitializeReader(std::move(b));

  std::string kData = kData1.substr(5, 4) + kData2.substr(6, 9);

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  CheckSizeCalculatedSynchronously(kData.size(), size_result);

  // Verify this condition while we are here.
  EXPECT_FALSE(reader_->IsSingleMojoDataItem());

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<net::IOBuffer>(kData.size());

  int bytes_read = 0;
  int async_bytes_read = 0;
  BlobReader::Status result =
      reader_->Read(buffer.get(), kData.size(), &bytes_read,
                    base::BindOnce(&SetValue<int>, &async_bytes_read));
  EXPECT_EQ(net::OK, reader_->net_error());
  EXPECT_EQ(result, BlobReader::Status::DONE);
  EXPECT_EQ(0, async_bytes_read);
  EXPECT_EQ(kData.size(), static_cast<size_t>(bytes_read));

  EXPECT_EQ(0, memcmp(buffer->data(), kData.data(), kData.size()));
}

TEST_F(BlobReaderTest, FileRange) {
  auto b = std::make_unique<BlobDataBuilder>("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(std::move(b));

  std::unique_ptr<FakeFileStreamReader> reader(new FakeFileStreamReader(kData));
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());
  ExpectLocalFileCall(kPath, kTime, 0, reader.release());

  // We create the reader again with the offset after the seek.
  reader = std::make_unique<FakeFileStreamReader>(kRangeData);
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());
  ExpectLocalFileCall(kPath, kTime, kOffset, reader.release());

  int size_result = -1;
  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&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::BindOnce(&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, ReadableDataHandleRange) {
  auto b = std::make_unique<BlobDataBuilder>("uuid");
  const std::string kData = "Test Blob Data";
  const uint64_t kOffset = 2;
  const uint64_t kReadLength = 3;
  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kData, "");
  b->AppendReadableDataHandle(std::move(data_handle));
  this->InitializeReader(std::move(b));

  int size_result = -1;
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &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::BindOnce(&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.
  auto b = std::make_unique<BlobDataBuilder>("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(std::move(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(base::ThreadTaskRunnerHandle::Get().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::BindOnce(&SetValue<int>, &size_result)));
  CheckSizeNotCalculatedYet(size_result);
  base::RunLoop().RunUntilIdle();
  CheckSizeCalculatedAsynchronously(kTotalSize, size_result);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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 data handle entry.

  auto b = std::make_unique<BlobDataBuilder>("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");

  auto data_handle = base::MakeRefCounted<FakeBlobDataHandle>(kData3, "");

  b->AppendFile(kData1Path, 0, kData1.size(), kTime);
  b->AppendData(kData2);
  b->AppendReadableDataHandle(std::move(data_handle));
  b->AppendData(kData4);

  this->InitializeReader(std::move(b));

  std::unique_ptr<FakeFileStreamReader> reader(
      new FakeFileStreamReader(kData1));
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());
  ExpectLocalFileCall(kData1Path, kTime, 0, reader.release());

  int size_result = -1;
  EXPECT_FALSE(IsReaderTotalSizeCalculated());
  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&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::BindOnce(&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::BindOnce(&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::BindOnce(&SetValue<int>, &async_bytes_read)));
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());

  // Case: Not calling CalculateSize before SetReadRange.
  auto builder1 = std::make_unique<BlobDataBuilder>("uuid1");
  builder1->AppendData(kData);
  InitializeReader(std::move(builder1));
  EXPECT_EQ(BlobReader::Status::NET_ERROR, reader_->SetReadRange(0, 10));
  EXPECT_EQ(net::ERR_UNEXPECTED, reader_->net_error());
  EXPECT_EQ(BlobReader::Status::NET_ERROR,
            reader_->Read(buffer.get(), 10, &bytes_read,
                          base::BindOnce(&SetValue<int>, &async_bytes_read)));

  // Case: Not calling CalculateSize before Read.
  auto builder2 = std::make_unique<BlobDataBuilder>("uuid2");
  builder2->AppendData(kData);
  InitializeReader(std::move(builder2));
  EXPECT_EQ(BlobReader::Status::NET_ERROR,
            reader_->Read(buffer.get(), 10, &bytes_read,
                          base::BindOnce(&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.
  auto builder1 = std::make_unique<BlobDataBuilder>("uuid1");
  builder1->AppendFile(kPath, 0, kData.size(), kTime);
  this->InitializeReader(std::move(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::BindOnce(&SetValue<int>, &size_result)));
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, reader_->net_error());

  // Case: Error on read.
  auto builder2 = std::make_unique<BlobDataBuilder>("uuid2");
  builder2->AppendFile(kPath, 0, kData.size(), kTime);
  this->InitializeReader(std::move(builder2));
  reader = new FakeFileStreamReader(kData);
  ExpectLocalFileCall(kPath, kTime, 0, reader);
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  reader->SetReturnError(net::ERR_FILE_NOT_FOUND);

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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.
  auto builder1 = std::make_unique<BlobDataBuilder>("uuid1");
  builder1->AppendFile(kPath, 0, kData.size(), kTime);
  this->InitializeReader(std::move(builder1));
  FakeFileStreamReader* reader = new FakeFileStreamReader(kData);
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());
  reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
  ExpectLocalFileCall(kPath, kTime, 0, reader);

  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&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.
  auto builder2 = std::make_unique<BlobDataBuilder>("uuid2");
  builder2->AppendFile(kPath, 0, kData.size(), kTime);
  this->InitializeReader(std::move(builder2));
  reader = new FakeFileStreamReader(kData);
  ExpectLocalFileCall(kPath, kTime, 0, reader);
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  reader->SetReturnError(net::ERR_FILE_NOT_FOUND);
  reader->SetAsyncRunner(base::ThreadTaskRunnerHandle::Get().get());

  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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.
  auto b = std::make_unique<BlobDataBuilder>("uuid1");
  b->AppendData(kData);
  this->InitializeReader(std::move(b));
  int size_result = -1;
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &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_REQUEST_RANGE_NOT_SATISFIABLE, reader_->net_error());

  // Case: length too long.
  auto b2 = std::make_unique<BlobDataBuilder>("uuid2");
  b2->AppendData(kData);
  this->InitializeReader(std::move(b2));
  size_result = -1;
  EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
                                          &SetValue<int>, &size_result)));
  buffer = CreateBuffer(kDataSize + 1);
  EXPECT_EQ(BlobReader::Status::NET_ERROR,
            reader_->SetReadRange(0, kDataSize + 1));
  EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, 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;

  auto b = std::make_unique<BlobDataBuilder>(kUuid);
  b->AppendFutureData(kDataSize);
  BlobStatus can_populate_status =
      BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
  blob_handle_ = context_.BuildBlob(
      std::move(b),
      base::BindOnce(&SaveBlobStatusAndFiles, &can_populate_status, &files));
  EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, can_populate_status);
  provider_ = new MockFileStreamReaderProvider();
  reader_.reset(new BlobReader(blob_handle_.get()));
  reader_->SetFileStreamProviderForTesting(base::WrapUnique(provider_.get()));
  int size_result = -1;
  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&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;

  auto b = std::make_unique<BlobDataBuilder>(kUuid);
  BlobDataBuilder::FutureData future_data = b->AppendFutureData(kDataSize);
  BlobStatus can_populate_status =
      BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS;
  blob_handle_ = context_.BuildBlob(
      std::move(b),
      base::BindOnce(&SaveBlobStatusAndFiles, &can_populate_status, &files));
  EXPECT_EQ(BlobStatus::PENDING_TRANSPORT, can_populate_status);
  provider_ = new MockFileStreamReaderProvider();
  reader_.reset(new BlobReader(blob_handle_.get()));
  reader_->SetFileStreamProviderForTesting(base::WrapUnique(provider_.get()));
  int size_result = -1;
  EXPECT_EQ(
      BlobReader::Status::IO_PENDING,
      reader_->CalculateSize(base::BindOnce(&SetValue<int>, &size_result)));
  EXPECT_FALSE(reader_->IsInMemory());
  future_data.Populate(base::as_bytes(base::make_span(kData.data(), kDataSize)),
                       0);
  context_.NotifyTransportComplete(kUuid);
  base::RunLoop().RunUntilIdle();
  CheckSizeCalculatedAsynchronously(kDataSize, size_result);
  scoped_refptr<net::IOBuffer> buffer =
      base::MakeRefCounted<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::BindOnce(&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
