// Copyright 2014 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 "content/browser/appcache/appcache_url_request_job.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/compiler_specific.h"
#include "base/containers/stack.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/pickle.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/appcache/appcache_response.h"
#include "content/browser/appcache/mock_appcache_service.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_error_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/appcache/appcache_info.mojom.h"
#include "url/gurl.h"

using net::IOBuffer;
using net::WrappedIOBuffer;

namespace content {
namespace appcache_url_request_job_unittest {

const char kHttpBasicHeaders[] = "HTTP/1.0 200 OK\0Content-Length: 5\0\0";
const char kHttpBasicBody[] = "Hello";

const int kNumBlocks = 4;
const int kBlockSize = 1024;

// Used as an AppCacheURLRequestJob::OnPrepareToRestartCallback for requests
// that aren't expected to be restarted.
void ExpectNotRestarted() {
  ADD_FAILURE() << "Request unexpectedly restarted";
}

// Used as an AppCacheURLRequestJob::OnPrepareToRestartCallback for requests
// that are expected to be restarted. Allows tests to verify it was called by
// setting |*value| to true when invoked.
void SetIfCalled(bool* value) {
  // Expected to be called only once.
  EXPECT_FALSE(*value);
  *value = true;
}

class MockURLRequestJobFactory : public net::URLRequestJobFactory {
 public:
  MockURLRequestJobFactory() {}

  ~MockURLRequestJobFactory() override { DCHECK(!job_); }

  void SetJob(std::unique_ptr<net::URLRequestJob> job) {
    job_ = std::move(job);
  }

  bool has_job() const { return job_.get() != nullptr; }

  // net::URLRequestJobFactory implementation.
  net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
      const std::string& scheme,
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    if (job_) {
      return job_.release();
    } else {
      return new net::URLRequestErrorJob(request,
                                         network_delegate,
                                         net::ERR_INTERNET_DISCONNECTED);
    }
  }

  net::URLRequestJob* MaybeInterceptRedirect(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      const GURL& location) const override {
    return nullptr;
  }

  net::URLRequestJob* MaybeInterceptResponse(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate) const override {
    return nullptr;
  }

  bool IsHandledProtocol(const std::string& scheme) const override {
    return scheme == "http";
  }

  bool IsSafeRedirectTarget(const GURL& location) const override {
    return false;
  }

 private:
  // This is mutable because MaybeCreateJobWithProtocolHandler is const.
  mutable std::unique_ptr<net::URLRequestJob> job_;
};

class AppCacheURLRequestJobTest : public testing::Test {
 public:

  // Test Harness -------------------------------------------------------------
  // TODO(michaeln): share this test harness with AppCacheResponseTest

  class MockStorageDelegate : public AppCacheStorage::Delegate {
   public:
    explicit MockStorageDelegate(AppCacheURLRequestJobTest* test)
        : loaded_info_id_(0), test_(test) {
    }

    void OnResponseInfoLoaded(AppCacheResponseInfo* info,
                              int64_t response_id) override {
      loaded_info_ = info;
      loaded_info_id_ = response_id;
      test_->ScheduleNextTask();
    }

    scoped_refptr<AppCacheResponseInfo> loaded_info_;
    int64_t loaded_info_id_;
    AppCacheURLRequestJobTest* test_;
  };

  class MockURLRequestDelegate : public net::URLRequest::Delegate {
   public:
    explicit MockURLRequestDelegate(AppCacheURLRequestJobTest* test)
        : test_(test),
          received_data_(
              base::MakeRefCounted<net::IOBuffer>(kNumBlocks * kBlockSize)),
          did_receive_headers_(false),
          amount_received_(0),
          kill_after_amount_received_(0),
          kill_with_io_pending_(false),
          request_status_(net::ERR_IO_PENDING) {}

    void OnResponseStarted(net::URLRequest* request, int net_error) override {
      DCHECK_NE(net::ERR_IO_PENDING, net_error);
      amount_received_ = 0;
      did_receive_headers_ = false;
      request_status_ = net_error;
      if (net_error == net::OK) {
        EXPECT_TRUE(request->response_headers());
        did_receive_headers_ = true;
        received_info_ = request->response_info();
        ReadSome(request);
      } else {
        RequestComplete();
      }
    }

    void OnReadCompleted(net::URLRequest* request, int bytes_read) override {
      if (bytes_read > 0) {
        amount_received_ += bytes_read;
        request_status_ = net::OK;

        if (kill_after_amount_received_ && !kill_with_io_pending_) {
          if (amount_received_ >= kill_after_amount_received_) {
            request->Cancel();
            return;
          }
        }

        ReadSome(request);

        if (kill_after_amount_received_ && kill_with_io_pending_) {
          if (amount_received_ >= kill_after_amount_received_) {
            request->Cancel();
            return;
          }
        }
      } else {
        request_status_ = bytes_read;
        RequestComplete();
      }
    }

    void ReadSome(net::URLRequest* request) {
      DCHECK(amount_received_ + kBlockSize <= kNumBlocks * kBlockSize);
      scoped_refptr<IOBuffer> wrapped_buffer =
          base::MakeRefCounted<net::WrappedIOBuffer>(received_data_->data() +
                                                     amount_received_);
      EXPECT_EQ(net::ERR_IO_PENDING,
                request->Read(wrapped_buffer.get(), kBlockSize));
    }

    void RequestComplete() {
      test_->ScheduleNextTask();
    }

    int request_status() { return request_status_; }

    AppCacheURLRequestJobTest* test_;
    net::HttpResponseInfo received_info_;
    scoped_refptr<net::IOBuffer> received_data_;
    bool did_receive_headers_;
    int amount_received_;
    int kill_after_amount_received_;
    bool kill_with_io_pending_;
    int request_status_;
  };

  // Helper callback to run a test on our io_thread. The io_thread is spun up
  // once and reused for all tests.
  template <class Method>
  void MethodWrapper(Method method) {
    SetUpTest();
    (this->*method)();
  }

  static void SetUpTestCase() {
    scoped_task_environment_.reset(new base::test::ScopedTaskEnvironment());
    io_thread_.reset(new base::Thread("AppCacheURLRequestJobTest Thread"));
    base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
    io_thread_->StartWithOptions(options);
  }

  static void TearDownTestCase() {
    io_thread_.reset();
    scoped_task_environment_.reset();
  }

  AppCacheURLRequestJobTest() {}

  template <class Method>
  void RunTestOnIOThread(Method method) {
    test_finished_event_.reset(new base::WaitableEvent(
        base::WaitableEvent::ResetPolicy::AUTOMATIC,
        base::WaitableEvent::InitialState::NOT_SIGNALED));
    io_thread_->task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&AppCacheURLRequestJobTest::MethodWrapper<Method>,
                       base::Unretained(this), method));
    test_finished_event_->Wait();
  }

  void SetUpTest() {
    DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
    DCHECK(task_stack_.empty());

    storage_delegate_.reset(new MockStorageDelegate(this));
    service_.reset(new MockAppCacheService());
    expected_read_result_ = 0;
    expected_write_result_ = 0;
    written_response_id_ = 0;
    reader_deletion_count_down_ = 0;
    writer_deletion_count_down_ = 0;

    restart_callback_invoked_ = false;

    url_request_delegate_.reset(new MockURLRequestDelegate(this));
    job_factory_.reset(new MockURLRequestJobFactory());
    empty_context_.reset(new net::URLRequestContext());
    empty_context_->set_job_factory(job_factory_.get());
  }

  void TearDownTest() {
    DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
    request_.reset();

    while (!task_stack_.empty())
      task_stack_.pop();

    reader_.reset();
    read_buffer_ = nullptr;
    read_info_buffer_ = nullptr;
    writer_.reset();
    write_buffer_ = nullptr;
    write_info_buffer_ = nullptr;
    storage_delegate_.reset();
    service_.reset();

    DCHECK(!job_factory_->has_job());
    empty_context_.reset();
    job_factory_.reset();
    url_request_delegate_.reset();
  }

  void TestFinished() {
    // We unwind the stack prior to finishing up to let stack
    // based objects get deleted.
    DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&AppCacheURLRequestJobTest::TestFinishedUnwound,
                       base::Unretained(this)));
  }

  void TestFinishedUnwound() {
    TearDownTest();
    test_finished_event_->Signal();
  }

  void PushNextTask(base::OnceClosure task) {
    task_stack_.push(
        std::pair<base::OnceClosure, bool>(std::move(task), false));
  }

  void PushNextTaskAsImmediate(base::OnceClosure task) {
    task_stack_.push(std::pair<base::OnceClosure, bool>(std::move(task), true));
  }

  void ScheduleNextTask() {
    DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
    if (task_stack_.empty()) {
      TestFinished();
      return;
    }
    base::OnceClosure task = std::move(task_stack_.top().first);
    bool immediate = task_stack_.top().second;
    task_stack_.pop();
    if (immediate)
      std::move(task).Run();
    else
      base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(task));
  }

  // Wrappers to call AppCacheResponseReader/Writer Read and Write methods

  void WriteBasicResponse() {
    scoped_refptr<IOBuffer> body =
        base::MakeRefCounted<WrappedIOBuffer>(kHttpBasicBody);
    std::string raw_headers(kHttpBasicHeaders, base::size(kHttpBasicHeaders));
    WriteResponse(
        MakeHttpResponseInfo(raw_headers), body.get(), strlen(kHttpBasicBody));
  }

  void WriteResponse(std::unique_ptr<net::HttpResponseInfo> head,
                     IOBuffer* body,
                     int body_len) {
    DCHECK(body);
    scoped_refptr<IOBuffer> body_ref(body);
    PushNextTask(base::BindOnce(&AppCacheURLRequestJobTest::WriteResponseBody,
                                base::Unretained(this), body_ref, body_len));
    WriteResponseHead(std::move(head));
  }

  void WriteResponseHead(std::unique_ptr<net::HttpResponseInfo> head) {
    EXPECT_FALSE(writer_->IsWritePending());
    expected_write_result_ = GetHttpResponseInfoSize(*head);
    write_info_buffer_ =
        base::MakeRefCounted<HttpResponseInfoIOBuffer>(std::move(head));
    writer_->WriteInfo(
        write_info_buffer_.get(),
        base::BindOnce(&AppCacheURLRequestJobTest::OnWriteInfoComplete,
                       base::Unretained(this)));
  }

  void WriteResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
    EXPECT_FALSE(writer_->IsWritePending());
    write_buffer_ = io_buffer;
    expected_write_result_ = buf_len;
    writer_->WriteData(
        write_buffer_.get(), buf_len,
        base::BindOnce(&AppCacheURLRequestJobTest::OnWriteComplete,
                       base::Unretained(this)));
  }

  void ReadResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
    EXPECT_FALSE(reader_->IsReadPending());
    read_buffer_ = io_buffer;
    expected_read_result_ = buf_len;
    reader_->ReadData(read_buffer_.get(), buf_len,
                      base::BindOnce(&AppCacheURLRequestJobTest::OnReadComplete,
                                     base::Unretained(this)));
  }

  // AppCacheResponseReader / Writer completion callbacks

  void OnWriteInfoComplete(int result) {
    EXPECT_FALSE(writer_->IsWritePending());
    EXPECT_EQ(expected_write_result_, result);
    ScheduleNextTask();
  }

  void OnWriteComplete(int result) {
    EXPECT_FALSE(writer_->IsWritePending());
    EXPECT_EQ(expected_write_result_, result);
    ScheduleNextTask();
  }

  void OnReadInfoComplete(int result) {
    EXPECT_FALSE(reader_->IsReadPending());
    EXPECT_EQ(expected_read_result_, result);
    ScheduleNextTask();
  }

  void OnReadComplete(int result) {
    EXPECT_FALSE(reader_->IsReadPending());
    EXPECT_EQ(expected_read_result_, result);
    ScheduleNextTask();
  }

  // Helpers to work with HttpResponseInfo objects

  std::unique_ptr<net::HttpResponseInfo> MakeHttpResponseInfo(
      const std::string& raw_headers) {
    std::unique_ptr<net::HttpResponseInfo> info =
        std::make_unique<net::HttpResponseInfo>();
    info->request_time = base::Time::Now();
    info->response_time = base::Time::Now();
    info->was_cached = false;
    info->headers = base::MakeRefCounted<net::HttpResponseHeaders>(raw_headers);
    return info;
  }

  int GetHttpResponseInfoSize(const net::HttpResponseInfo& info) {
    base::Pickle pickle = PickleHttpResonseInfo(info);
    return pickle.size();
  }

  bool CompareHttpResponseInfos(const net::HttpResponseInfo& info1,
                                const net::HttpResponseInfo& info2) {
    base::Pickle pickle1 = PickleHttpResonseInfo(info1);
    base::Pickle pickle2 = PickleHttpResonseInfo(info2);
    return (pickle1.size() == pickle2.size()) &&
           (0 == memcmp(pickle1.data(), pickle2.data(), pickle1.size()));
  }

  base::Pickle PickleHttpResonseInfo(const net::HttpResponseInfo& info) {
    const bool kSkipTransientHeaders = true;
    const bool kTruncated = false;
    base::Pickle pickle;
    info.Persist(&pickle, kSkipTransientHeaders, kTruncated);
    return pickle;
  }

  // Helpers to fill and verify blocks of memory with a value

  void FillData(char value, char* data, int data_len) {
    memset(data, value, data_len);
  }

  bool CheckData(char value, const char* data, int data_len) {
    for (int i = 0; i < data_len; ++i, ++data) {
      if (*data != value)
        return false;
    }
    return true;
  }

  // Individual Tests ---------------------------------------------------------
  // Some of the individual tests involve multiple async steps. Each test
  // is delineated with a section header.

  // Basic -------------------------------------------------------------------
  void Basic() {
    AppCacheStorage* storage = service_->storage();
    request_ = empty_context_->CreateRequest(GURL("http://blah/"),
                                             net::DEFAULT_PRIORITY, nullptr,
                                             TRAFFIC_ANNOTATION_FOR_TESTS);

    // Create an instance and see that it looks as expected.

    std::unique_ptr<AppCacheURLRequestJob> job(
        new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
                                  false, base::BindOnce(&ExpectNotRestarted)));
    EXPECT_TRUE(job->IsWaiting());
    EXPECT_FALSE(job->IsDeliveringAppCacheResponse());
    EXPECT_FALSE(job->IsDeliveringNetworkResponse());
    EXPECT_FALSE(job->IsDeliveringErrorResponse());
    EXPECT_FALSE(job->IsStarted());
    EXPECT_FALSE(job->has_been_killed());
    EXPECT_EQ(GURL(), job->manifest_url());
    EXPECT_EQ(blink::mojom::kAppCacheNoCacheId, job->cache_id());
    EXPECT_FALSE(job->entry().has_response_id());

    TestFinished();
  }

  // DeliveryOrders -----------------------------------------------------
  void DeliveryOrders() {
    AppCacheStorage* storage = service_->storage();
    std::unique_ptr<net::URLRequest> request(empty_context_->CreateRequest(
        GURL("http://blah/"), net::DEFAULT_PRIORITY, nullptr,
        TRAFFIC_ANNOTATION_FOR_TESTS));

    // Create an instance, give it a delivery order and see that
    // it looks as expected.

    std::unique_ptr<AppCacheURLRequestJob> job(
        new AppCacheURLRequestJob(request.get(), nullptr, storage, nullptr,
                                  false, base::BindOnce(&ExpectNotRestarted)));
    job->DeliverErrorResponse();
    EXPECT_TRUE(job->IsDeliveringErrorResponse());
    EXPECT_FALSE(job->IsStarted());

    job.reset(new AppCacheURLRequestJob(request.get(), nullptr, storage,
                                        nullptr, false,
                                        base::BindOnce(&ExpectNotRestarted)));
    job->DeliverNetworkResponse();
    EXPECT_TRUE(job->IsDeliveringNetworkResponse());
    EXPECT_FALSE(job->IsStarted());

    job.reset(new AppCacheURLRequestJob(request.get(), nullptr, storage,
                                        nullptr, false,
                                        base::BindOnce(&ExpectNotRestarted)));
    const GURL kManifestUrl("http://blah/");
    const int64_t kCacheId(1);
    const AppCacheEntry kEntry(AppCacheEntry::EXPLICIT, 1);
    job->DeliverAppCachedResponse(kManifestUrl, kCacheId, kEntry, false);
    EXPECT_FALSE(job->IsWaiting());
    EXPECT_TRUE(job->IsDeliveringAppCacheResponse());
    EXPECT_FALSE(job->IsStarted());
    EXPECT_EQ(kManifestUrl, job->manifest_url());
    EXPECT_EQ(kCacheId, job->cache_id());
    EXPECT_EQ(kEntry.types(), job->entry().types());
    EXPECT_EQ(kEntry.response_id(), job->entry().response_id());

    TestFinished();
  }

  // DeliverNetworkResponse --------------------------------------------------

  void DeliverNetworkResponse() {
    // This test has async steps.
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::VerifyDeliverNetworkResponse,
                       base::Unretained(this)));

    AppCacheStorage* storage = service_->storage();
    request_ = empty_context_->CreateRequest(
        GURL("http://blah/"), net::DEFAULT_PRIORITY,
        url_request_delegate_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);

    // Set up to create an AppCacheURLRequestJob with orders to deliver
    // a network response.
    std::unique_ptr<AppCacheURLRequestJob> mock_job(new AppCacheURLRequestJob(
        request_.get(), nullptr, storage, nullptr, false,
        base::BindOnce(&SetIfCalled, &restart_callback_invoked_)));
    mock_job->DeliverNetworkResponse();
    EXPECT_TRUE(mock_job->IsDeliveringNetworkResponse());
    EXPECT_FALSE(mock_job->IsStarted());
    job_factory_->SetJob(std::move(mock_job));

    // Start the request.
    request_->Start();

    // The job should have been picked up.
    EXPECT_FALSE(job_factory_->has_job());
    // Completion is async.
  }

  void VerifyDeliverNetworkResponse() {
    EXPECT_EQ(net::ERR_INTERNET_DISCONNECTED,
              url_request_delegate_->request_status());
    EXPECT_TRUE(restart_callback_invoked_);
    TestFinished();
  }

  // DeliverErrorResponse --------------------------------------------------

  void DeliverErrorResponse() {
    // This test has async steps.
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::VerifyDeliverErrorResponse,
                       base::Unretained(this)));

    AppCacheStorage* storage = service_->storage();
    request_ = empty_context_->CreateRequest(
        GURL("http://blah/"), net::DEFAULT_PRIORITY,
        url_request_delegate_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);

    // Setup to create an AppCacheURLRequestJob with orders to deliver
    // a network response.
    std::unique_ptr<AppCacheURLRequestJob> mock_job(
        new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
                                  false, base::BindOnce(&ExpectNotRestarted)));
    mock_job->DeliverErrorResponse();
    EXPECT_TRUE(mock_job->IsDeliveringErrorResponse());
    EXPECT_FALSE(mock_job->IsStarted());
    job_factory_->SetJob(std::move(mock_job));

    // Start the request.
    request_->Start();

    // The job should have been picked up.
    EXPECT_FALSE(job_factory_->has_job());
    // Completion is async.
  }

  void VerifyDeliverErrorResponse() {
    EXPECT_EQ(net::ERR_FAILED, url_request_delegate_->request_status());
    TestFinished();
  }

  // DeliverSmallAppCachedResponse --------------------------------------
  // "Small" being small enough to read completely in a single
  // request->Read call.

  void DeliverSmallAppCachedResponse() {
    // This test has several async steps.
    // 1. Write a small response to response storage.
    // 2. Use net::URLRequest to retrieve it.
    // 3. Verify we received what we expected to receive.

    PushNextTask(base::BindOnce(
        &AppCacheURLRequestJobTest::VerifyDeliverSmallAppCachedResponse,
        base::Unretained(this)));
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
                       base::Unretained(this), false));

    writer_ = service_->storage()->CreateResponseWriter(GURL());
    written_response_id_ = writer_->response_id();
    WriteBasicResponse();
    // Continues async
  }

  void RequestAppCachedResource(bool start_after_delivery_orders) {
    AppCacheStorage* storage = service_->storage();
    request_ = empty_context_->CreateRequest(
        GURL("http://blah/"), net::DEFAULT_PRIORITY,
        url_request_delegate_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);

    // Setup to create an AppCacheURLRequestJob with orders to deliver
    // a network response.
    std::unique_ptr<AppCacheURLRequestJob> job(
        new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
                                  false, base::BindOnce(&ExpectNotRestarted)));

    if (start_after_delivery_orders) {
      job->DeliverAppCachedResponse(
          GURL(), 111,
          AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_), false);
      EXPECT_TRUE(job->IsDeliveringAppCacheResponse());
    }

    // Start the request.
    EXPECT_FALSE(job->IsStarted());
    base::WeakPtr<AppCacheJob> weak_job = job->GetWeakPtr();
    job_factory_->SetJob(std::move(job));
    request_->Start();
    EXPECT_FALSE(job_factory_->has_job());
    ASSERT_TRUE(weak_job);
    EXPECT_TRUE(weak_job->IsStarted());

    if (!start_after_delivery_orders) {
      weak_job->DeliverAppCachedResponse(
          GURL(), 111,
          AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_), false);
      ASSERT_TRUE(weak_job);
      EXPECT_TRUE(weak_job->IsDeliveringAppCacheResponse());
    }

    // Completion is async.
  }

  void VerifyDeliverSmallAppCachedResponse() {
    EXPECT_EQ(net::OK, url_request_delegate_->request_status());
    EXPECT_TRUE(CompareHttpResponseInfos(
        *write_info_buffer_->http_info, url_request_delegate_->received_info_));
    EXPECT_EQ(5, url_request_delegate_->amount_received_);
    EXPECT_EQ(0, memcmp(kHttpBasicBody,
                        url_request_delegate_->received_data_->data(),
                        strlen(kHttpBasicBody)));
    TestFinished();
  }

  // DeliverLargeAppCachedResponse --------------------------------------
  // "Large" enough to require multiple calls to request->Read to complete.

  void DeliverLargeAppCachedResponse() {
    // This test has several async steps.
    // 1. Write a large response to response storage.
    // 2. Use net::URLRequest to retrieve it.
    // 3. Verify we received what we expected to receive.

    PushNextTask(base::BindOnce(
        &AppCacheURLRequestJobTest::VerifyDeliverLargeAppCachedResponse,
        base::Unretained(this)));
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
                       base::Unretained(this), true));

    writer_ = service_->storage()->CreateResponseWriter(GURL());
    written_response_id_ = writer_->response_id();
    WriteLargeResponse();
    // Continues async
  }

  void WriteLargeResponse() {
    // 3, 1k blocks
    static const char kHttpHeaders[] =
        "HTTP/1.0 200 OK\0Content-Length: 3072\0\0";
    scoped_refptr<IOBuffer> body =
        base::MakeRefCounted<IOBuffer>(kBlockSize * 3);
    char* p = body->data();
    for (int i = 0; i < 3; ++i, p += kBlockSize)
      FillData(i + 1, p, kBlockSize);
    std::string raw_headers(kHttpHeaders, base::size(kHttpHeaders));
    WriteResponse(
        MakeHttpResponseInfo(raw_headers), body.get(), kBlockSize * 3);
  }

  void VerifyDeliverLargeAppCachedResponse() {
    EXPECT_EQ(net::OK, url_request_delegate_->request_status());
    EXPECT_TRUE(CompareHttpResponseInfos(
        *write_info_buffer_->http_info, url_request_delegate_->received_info_));
    EXPECT_EQ(3072, url_request_delegate_->amount_received_);
    char* p = url_request_delegate_->received_data_->data();
    for (int i = 0; i < 3; ++i, p += kBlockSize)
      EXPECT_TRUE(CheckData(i + 1, p, kBlockSize));
    TestFinished();
  }

  // DeliverPartialResponse --------------------------------------

  void DeliverPartialResponse() {
    // This test has several async steps.
    // 1. Write a small response to response storage.
    // 2. Use net::URLRequest to retrieve it a subset using a range request
    // 3. Verify we received what we expected to receive.
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::VerifyDeliverPartialResponse,
                       base::Unretained(this)));
    PushNextTask(base::BindOnce(&AppCacheURLRequestJobTest::MakeRangeRequest,
                                base::Unretained(this)));
    writer_ = service_->storage()->CreateResponseWriter(GURL());
    written_response_id_ = writer_->response_id();
    WriteBasicResponse();
    // Continues async
  }

  void MakeRangeRequest() {
    AppCacheStorage* storage = service_->storage();
    request_ = empty_context_->CreateRequest(
        GURL("http://blah/"), net::DEFAULT_PRIORITY,
        url_request_delegate_.get(), TRAFFIC_ANNOTATION_FOR_TESTS);

    // Request a range, the 3 middle chars out of 'Hello'
    net::HttpRequestHeaders extra_headers;
    extra_headers.SetHeader("Range", "bytes= 1-3");
    request_->SetExtraRequestHeaders(extra_headers);

    // Create job with orders to deliver an appcached entry.
    std::unique_ptr<AppCacheURLRequestJob> job(
        new AppCacheURLRequestJob(request_.get(), nullptr, storage, nullptr,
                                  false, base::BindOnce(&ExpectNotRestarted)));
    job->DeliverAppCachedResponse(
        GURL(), 111,
        AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_), false);
    EXPECT_TRUE(job->IsDeliveringAppCacheResponse());

    // Start the request.
    EXPECT_FALSE(job->IsStarted());
    job_factory_->SetJob(std::move(job));
    request_->Start();
    EXPECT_FALSE(job_factory_->has_job());
    // Completion is async.
  }

  void VerifyDeliverPartialResponse() {
    EXPECT_EQ(net::OK, url_request_delegate_->request_status());
    EXPECT_EQ(3, url_request_delegate_->amount_received_);
    EXPECT_EQ(0, memcmp(kHttpBasicBody + 1,
                        url_request_delegate_->received_data_->data(),
                        3));
    net::HttpResponseHeaders* headers =
        url_request_delegate_->received_info_.headers.get();
    EXPECT_EQ(206, headers->response_code());
    EXPECT_EQ(3, headers->GetContentLength());
    int64_t range_start, range_end, object_size;
    EXPECT_TRUE(
        headers->GetContentRangeFor206(&range_start, &range_end, &object_size));
    EXPECT_EQ(1, range_start);
    EXPECT_EQ(3, range_end);
    EXPECT_EQ(5, object_size);
    TestFinished();
  }

  // CancelRequest --------------------------------------

  void CancelRequest() {
    // This test has several async steps.
    // 1. Write a large response to response storage.
    // 2. Use net::URLRequest to retrieve it.
    // 3. Cancel the request after data starts coming in.

    PushNextTask(base::BindOnce(&AppCacheURLRequestJobTest::VerifyCancel,
                                base::Unretained(this)));
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
                       base::Unretained(this), true));

    writer_ = service_->storage()->CreateResponseWriter(GURL());
    written_response_id_ = writer_->response_id();
    WriteLargeResponse();

    url_request_delegate_->kill_after_amount_received_ = kBlockSize;
    url_request_delegate_->kill_with_io_pending_ = false;
    // Continues async
  }

  void VerifyCancel() {
    EXPECT_EQ(net::ERR_ABORTED, url_request_delegate_->request_status());
    TestFinished();
  }

  // CancelRequestWithIOPending --------------------------------------

  void CancelRequestWithIOPending() {
    // This test has several async steps.
    // 1. Write a large response to response storage.
    // 2. Use net::URLRequest to retrieve it.
    // 3. Cancel the request after data starts coming in.

    PushNextTask(base::BindOnce(&AppCacheURLRequestJobTest::VerifyCancel,
                                base::Unretained(this)));
    PushNextTask(
        base::BindOnce(&AppCacheURLRequestJobTest::RequestAppCachedResource,
                       base::Unretained(this), true));

    writer_ = service_->storage()->CreateResponseWriter(GURL());
    written_response_id_ = writer_->response_id();
    WriteLargeResponse();

    url_request_delegate_->kill_after_amount_received_ = kBlockSize;
    url_request_delegate_->kill_with_io_pending_ = true;
    // Continues async
  }


  // Data members --------------------------------------------------------

  std::unique_ptr<base::WaitableEvent> test_finished_event_;
  std::unique_ptr<MockStorageDelegate> storage_delegate_;
  std::unique_ptr<MockAppCacheService> service_;
  base::stack<std::pair<base::OnceClosure, bool>> task_stack_;

  std::unique_ptr<AppCacheResponseReader> reader_;
  scoped_refptr<HttpResponseInfoIOBuffer> read_info_buffer_;
  scoped_refptr<IOBuffer> read_buffer_;
  int expected_read_result_;
  int reader_deletion_count_down_;

  int64_t written_response_id_;
  std::unique_ptr<AppCacheResponseWriter> writer_;
  scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_;
  scoped_refptr<IOBuffer> write_buffer_;
  int expected_write_result_;
  int writer_deletion_count_down_;

  bool restart_callback_invoked_;

  std::unique_ptr<MockURLRequestJobFactory> job_factory_;
  std::unique_ptr<net::URLRequestContext> empty_context_;
  std::unique_ptr<net::URLRequest> request_;
  std::unique_ptr<MockURLRequestDelegate> url_request_delegate_;

  static std::unique_ptr<base::Thread> io_thread_;
  static std::unique_ptr<base::test::ScopedTaskEnvironment>
      scoped_task_environment_;
};

// static
std::unique_ptr<base::Thread> AppCacheURLRequestJobTest::io_thread_;
std::unique_ptr<base::test::ScopedTaskEnvironment>
    AppCacheURLRequestJobTest::scoped_task_environment_;

TEST_F(AppCacheURLRequestJobTest, Basic) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::Basic);
}

TEST_F(AppCacheURLRequestJobTest, DeliveryOrders) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliveryOrders);
}

TEST_F(AppCacheURLRequestJobTest, DeliverNetworkResponse) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverNetworkResponse);
}

TEST_F(AppCacheURLRequestJobTest, DeliverErrorResponse) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverErrorResponse);
}

TEST_F(AppCacheURLRequestJobTest, DeliverSmallAppCachedResponse) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverSmallAppCachedResponse);
}

TEST_F(AppCacheURLRequestJobTest, DeliverLargeAppCachedResponse) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverLargeAppCachedResponse);
}

TEST_F(AppCacheURLRequestJobTest, DeliverPartialResponse) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverPartialResponse);
}

TEST_F(AppCacheURLRequestJobTest, CancelRequest) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequest);
}

TEST_F(AppCacheURLRequestJobTest, CancelRequestWithIOPending) {
  RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequestWithIOPending);
}

}  // namespace appcache_url_request_job_unittest
}  // namespace content
