15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stack>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_response.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_url_request_job.h"
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/mock_appcache_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::IOBuffer;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using net::WrappedIOBuffer;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kHttpBasicHeaders[] =
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.0 200 OK\0Content-Length: 5\0\0";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kHttpBasicBody[] = "Hello";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kNumBlocks = 4;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBlockSize = 1024;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheURLRequestJobTest : public testing::Test {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test Harness -------------------------------------------------------------
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): share this test harness with AppCacheResponseTest
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockStorageDelegate : public AppCacheStorage::Delegate {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit MockStorageDelegate(AppCacheURLRequestJobTest* test)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : loaded_info_id_(0), test_(test) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnResponseInfoLoaded(AppCacheResponseInfo* info,
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      int64 response_id) OVERRIDE {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loaded_info_ = info;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loaded_info_id_ = response_id;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_->ScheduleNextTask();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheResponseInfo> loaded_info_;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 loaded_info_id_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJobTest* test_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockURLRequestDelegate : public net::URLRequest::Delegate {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explicit MockURLRequestDelegate(AppCacheURLRequestJobTest* test)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : test_(test),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          received_data_(new net::IOBuffer(kNumBlocks * kBlockSize)),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          did_receive_headers_(false), amount_received_(0),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kill_after_amount_received_(0), kill_with_io_pending_(false) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      amount_received_ = 0;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_receive_headers_ = false;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (request->status().is_success()) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(request->response_headers());
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        did_receive_headers_ = true;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        received_info_ = request->response_info();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReadSome(request);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RequestComplete();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnReadCompleted(net::URLRequest* request,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 int bytes_read) OVERRIDE {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (bytes_read > 0) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        amount_received_ += bytes_read;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (kill_after_amount_received_ && !kill_with_io_pending_) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (amount_received_ >= kill_after_amount_received_) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request->Cancel();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReadSome(request);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (kill_after_amount_received_ && kill_with_io_pending_) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (amount_received_ >= kill_after_amount_received_) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request->Cancel();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RequestComplete();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ReadSome(net::URLRequest* request) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(amount_received_ + kBlockSize <= kNumBlocks * kBlockSize);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<IOBuffer> wrapped_buffer(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          new net::WrappedIOBuffer(received_data_->data() + amount_received_));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int bytes_read = 0;
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      EXPECT_FALSE(
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          request->Read(wrapped_buffer.get(), kBlockSize, &bytes_read));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(0, bytes_read);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void RequestComplete() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_->ScheduleNextTask();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJobTest* test_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseInfo received_info_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBuffer> received_data_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool did_receive_headers_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int amount_received_;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int kill_after_amount_received_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool kill_with_io_pending_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static net::URLRequestJob* MockHttpJobFactory(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequest* request,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::NetworkDelegate* network_delegate,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& scheme) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mock_factory_job_) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestJob* temp = mock_factory_job_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mock_factory_job_ = NULL;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return temp;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return new net::URLRequestErrorJob(request,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         network_delegate,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         net::ERR_INTERNET_DISCONNECTED);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper callback to run a test on our io_thread. The io_thread is spun up
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // once and reused for all tests.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class Method>
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MethodWrapper(Method method) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUpTest();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (this->*method)();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetUpTestCase() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(new base::Thread("AppCacheURLRequestJobTest Thread"));
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->StartWithOptions(options);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void TearDownTestCase() {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(NULL);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheURLRequestJobTest() {}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class Method>
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunTestOnIOThread(Method method) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_ .reset(new base::WaitableEvent(false, false));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->message_loop()->PostTask(
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE, base::Bind(&AppCacheURLRequestJobTest::MethodWrapper<Method>,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              base::Unretained(this), method));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Wait();
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUpTest() {
177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(task_stack_.empty());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    orig_http_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "http", MockHttpJobFactory);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_.reset(new MockURLRequestDelegate(this));
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage_delegate_.reset(new MockStorageDelegate(this));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_.reset(new MockAppCacheService());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_read_result_ = 0;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_write_result_ = 0;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = 0;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reader_deletion_count_down_ = 0;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_deletion_count_down_ = 0;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TearDownTest() {
192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
193b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    net::URLRequest::Deprecated::RegisterProtocolFactory("http",
194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                         orig_http_factory_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    orig_http_factory_ = NULL;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_.reset();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!mock_factory_job_);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (!task_stack_.empty())
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task_stack_.pop();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reader_.reset();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_buffer_ = NULL;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_info_buffer_ = NULL;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    write_buffer_ = NULL;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    write_info_buffer_ = NULL;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage_delegate_.reset();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_.reset();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinished() {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We unwind the stack prior to finishing up to let stack
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // based objects get deleted.
216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        FROM_HERE,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheURLRequestJobTest::TestFinishedUnwound,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinishedUnwound() {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TearDownTest();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Signal();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PushNextTask(const base::Closure& task) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.push(std::pair<base::Closure, bool>(task, false));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PushNextTaskAsImmediate(const base::Closure& task) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.push(std::pair<base::Closure, bool>(task, true));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleNextTask() {
237b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (task_stack_.empty()) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestFinished();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure task =task_stack_.top().first;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool immediate = task_stack_.top().second;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.pop();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (immediate)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      task.Run();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
248b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      base::MessageLoop::current()->PostTask(FROM_HERE, task);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrappers to call AppCacheResponseReader/Writer Read and Write methods
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteBasicResponse() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<IOBuffer> body(new WrappedIOBuffer(kHttpBasicBody));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string raw_headers(kHttpBasicHeaders, arraysize(kHttpBasicHeaders));
256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WriteResponse(
257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        MakeHttpResponseInfo(raw_headers), body.get(), strlen(kHttpBasicBody));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteResponse(net::HttpResponseInfo* head,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     IOBuffer* body, int body_len) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(body);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<IOBuffer> body_ref(body);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(&AppCacheURLRequestJobTest::WriteResponseBody,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            base::Unretained(this), body_ref, body_len));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteResponseHead(head);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteResponseHead(net::HttpResponseInfo* head) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(writer_->IsWritePending());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_write_result_ = GetHttpResponseInfoSize(head);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    write_info_buffer_ = new HttpResponseInfoIOBuffer(head);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_->WriteInfo(
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        write_info_buffer_.get(),
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheURLRequestJobTest::OnWriteInfoComplete,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(writer_->IsWritePending());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    write_buffer_ = io_buffer;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_write_result_ = buf_len;
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    writer_->WriteData(write_buffer_.get(),
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       buf_len,
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       base::Bind(&AppCacheURLRequestJobTest::OnWriteComplete,
286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                  base::Unretained(this)));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReadResponseBody(scoped_refptr<IOBuffer> io_buffer, int buf_len) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(reader_->IsReadPending());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    read_buffer_ = io_buffer;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_read_result_ = buf_len;
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    reader_->ReadData(read_buffer_.get(),
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      buf_len,
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      base::Bind(&AppCacheURLRequestJobTest::OnReadComplete,
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                 base::Unretained(this)));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AppCacheResponseReader / Writer completion callbacks
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWriteInfoComplete(int result) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(writer_->IsWritePending());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_write_result_, result);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnWriteComplete(int result) {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(writer_->IsWritePending());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_write_result_, result);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnReadInfoComplete(int result) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(reader_->IsReadPending());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_read_result_, result);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnReadComplete(int result) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(reader_->IsReadPending());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_read_result_, result);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helpers to work with HttpResponseInfo objects
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpResponseInfo* MakeHttpResponseInfo(const std::string& raw_headers) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseInfo* info = new net::HttpResponseInfo;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->request_time = base::Time::Now();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->response_time = base::Time::Now();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->was_cached = false;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->headers = new net::HttpResponseHeaders(raw_headers);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return info;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetHttpResponseInfoSize(const net::HttpResponseInfo* info) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pickle pickle;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PickleHttpResonseInfo(&pickle, info);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CompareHttpResponseInfos(const net::HttpResponseInfo* info1,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const net::HttpResponseInfo* info2) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pickle pickle1;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pickle pickle2;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PickleHttpResonseInfo(&pickle1, info1);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PickleHttpResonseInfo(&pickle2, info2);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (pickle1.size() == pickle2.size()) &&
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (0 == memcmp(pickle1.data(), pickle2.data(), pickle1.size()));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int PickleHttpResonseInfo(Pickle* pickle, const net::HttpResponseInfo* info) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool kSkipTransientHeaders = true;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool kTruncated = false;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info->Persist(pickle, kSkipTransientHeaders, kTruncated);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return pickle->size();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helpers to fill and verify blocks of memory with a value
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FillData(char value, char* data, int data_len) {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(data, value, data_len);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CheckData(char value, const char* data, int data_len) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < data_len; ++i, ++data) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*data != value)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Individual Tests ---------------------------------------------------------
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Some of the individual tests involve multiple async steps. Each test
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is delineated with a section header.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Basic -------------------------------------------------------------------
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Basic() {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest request(GURL("http://blah/"), NULL, &empty_context_);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheURLRequestJob> job;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create an instance and see that it looks as expected.
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job = new AppCacheURLRequestJob(
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &request, NULL, storage, NULL);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->is_waiting());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->is_delivering_appcache_response());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->is_delivering_network_response());
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->is_delivering_error_response());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_killed());
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL(), job->manifest_url());
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kNoCacheId, job->cache_id());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->entry().has_response_id());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliveryOrders -----------------------------------------------------
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliveryOrders() {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest request(GURL("http://blah/"), NULL, &empty_context_);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheURLRequestJob> job;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create an instance, give it a delivery order and see that
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it looks as expected.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    job = new AppCacheURLRequestJob(&request, NULL, storage, NULL);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->DeliverErrorResponse();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->is_delivering_error_response());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    job = new AppCacheURLRequestJob(&request, NULL, storage, NULL);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->DeliverNetworkResponse();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->is_delivering_network_response());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    job = new AppCacheURLRequestJob(&request, NULL, storage, NULL);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL kManifestUrl("http://blah/");
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int64 kCacheId(1);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int64 kGroupId(1);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheEntry kEntry(AppCacheEntry::EXPLICIT, 1);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->DeliverAppCachedResponse(kManifestUrl, kCacheId, kGroupId,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  kEntry, false);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->is_waiting());
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->is_delivering_appcache_response());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kManifestUrl, job->manifest_url());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kCacheId, job->cache_id());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kGroupId, job->group_id());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kEntry.types(), job->entry().types());
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kEntry.response_id(), job->entry().response_id());
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliverNetworkResponse --------------------------------------------------
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverNetworkResponse() {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has async steps.
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheURLRequestJobTest::VerifyDeliverNetworkResponse,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset(empty_context_.CreateRequest(
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/"), url_request_delegate_.get()));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Setup to create an AppCacheURLRequestJob with orders to deliver
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a network response.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_factory_job_ = new AppCacheURLRequestJob(
4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        request_.get(), NULL, storage, NULL);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_factory_job_->DeliverNetworkResponse();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(mock_factory_job_->is_delivering_network_response());
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_->has_been_started());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the request.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The job should have been picked up.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Completion is async.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyDeliverNetworkResponse() {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(request_->status().error(),
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              net::ERR_INTERNET_DISCONNECTED);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliverErrorResponse --------------------------------------------------
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverErrorResponse() {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has async steps.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheURLRequestJobTest::VerifyDeliverErrorResponse,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset(empty_context_.CreateRequest(GURL(
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "http://blah/"), url_request_delegate_.get()));
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Setup to create an AppCacheURLRequestJob with orders to deliver
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a network response.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_factory_job_ = new AppCacheURLRequestJob(
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        request_.get(), NULL, storage, NULL);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_factory_job_->DeliverErrorResponse();
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(mock_factory_job_->is_delivering_error_response());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_->has_been_started());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the request.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The job should have been picked up.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Completion is async.
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyDeliverErrorResponse() {
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(request_->status().error(), net::ERR_FAILED);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliverSmallAppCachedResponse --------------------------------------
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "Small" being small enough to read completely in a single
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request->Read call.
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverSmallAppCachedResponse() {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has several async steps.
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. Write a small response to response storage.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. Use net::URLRequest to retrieve it.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3. Verify we received what we expected to receive.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &AppCacheURLRequestJobTest::VerifyDeliverSmallAppCachedResponse,
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Unretained(this)));
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheURLRequestJobTest::RequestAppCachedResource,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), false));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset(service_->storage()->CreateResponseWriter(GURL(), 0));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = writer_->response_id();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteBasicResponse();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Continues async
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RequestAppCachedResource(bool start_after_delivery_orders) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset(empty_context_.CreateRequest(
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/"), url_request_delegate_.get()));
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Setup to create an AppCacheURLRequestJob with orders to deliver
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // a network response.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheURLRequestJob> job(new AppCacheURLRequestJob(
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        request_.get(), NULL, storage, NULL));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start_after_delivery_orders) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      job->DeliverAppCachedResponse(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL(), 0, 111,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_),
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          false);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(job->is_delivering_appcache_response());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the request.
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mock_factory_job_ = job.get();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->has_been_started());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!start_after_delivery_orders) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      job->DeliverAppCachedResponse(
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL(), 0, 111,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_),
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          false);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(job->is_delivering_appcache_response());
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Completion is async.
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyDeliverSmallAppCachedResponse() {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(request_->status().is_success());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CompareHttpResponseInfos(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        write_info_buffer_->http_info.get(),
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &url_request_delegate_->received_info_));
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(5, url_request_delegate_->amount_received_);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(kHttpBasicBody,
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        url_request_delegate_->received_data_->data(),
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        strlen(kHttpBasicBody)));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliverLargeAppCachedResponse --------------------------------------
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "Large" enough to require multiple calls to request->Read to complete.
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverLargeAppCachedResponse() {
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has several async steps.
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. Write a large response to response storage.
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. Use net::URLRequest to retrieve it.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3. Verify we received what we expected to receive.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::VerifyDeliverLargeAppCachedResponse,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Unretained(this)));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::RequestAppCachedResource,
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Unretained(this), true));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset(service_->storage()->CreateResponseWriter(GURL(), 0));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = writer_->response_id();
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteLargeResponse();
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Continues async
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteLargeResponse() {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3, 1k blocks
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const char kHttpHeaders[] =
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HTTP/1.0 200 OK\0Content-Length: 3072\0\0";
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<IOBuffer> body(new IOBuffer(kBlockSize * 3));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* p = body->data();
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < 3; ++i, p += kBlockSize)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FillData(i + 1, p, kBlockSize);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string raw_headers(kHttpHeaders, arraysize(kHttpHeaders));
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    WriteResponse(
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        MakeHttpResponseInfo(raw_headers), body.get(), kBlockSize * 3);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyDeliverLargeAppCachedResponse() {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(request_->status().is_success());
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CompareHttpResponseInfos(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        write_info_buffer_->http_info.get(),
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &url_request_delegate_->received_info_));
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3072, url_request_delegate_->amount_received_);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* p = url_request_delegate_->received_data_->data();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < 3; ++i, p += kBlockSize)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(CheckData(i + 1, p, kBlockSize));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DeliverPartialResponse --------------------------------------
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeliverPartialResponse() {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has several async steps.
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. Write a small response to response storage.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. Use net::URLRequest to retrieve it a subset using a range request
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3. Verify we received what we expected to receive.
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::VerifyDeliverPartialResponse,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Unretained(this)));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::MakeRangeRequest, base::Unretained(this)));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset(service_->storage()->CreateResponseWriter(GURL(), 0));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = writer_->response_id();
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteBasicResponse();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Continues async
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MakeRangeRequest() {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheStorage* storage = service_->storage();
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset(empty_context_.CreateRequest(
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/"), url_request_delegate_.get()));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Request a range, the 3 middle chars out of 'Hello'
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpRequestHeaders extra_headers;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extra_headers.SetHeader("Range", "bytes= 1-3");
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->SetExtraRequestHeaders(extra_headers);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create job with orders to deliver an appcached entry.
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheURLRequestJob> job(new AppCacheURLRequestJob(
6527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        request_.get(), NULL, storage, NULL));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->DeliverAppCachedResponse(
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL(), 0, 111,
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, written_response_id_),
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        false);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->is_delivering_appcache_response());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start the request.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job->has_been_started());
661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mock_factory_job_ = job.get();
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_factory_job_);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->has_been_started());
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Completion is async.
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyDeliverPartialResponse() {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(request_->status().is_success());
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3, url_request_delegate_->amount_received_);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(kHttpBasicBody + 1,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        url_request_delegate_->received_data_->data(),
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        3));
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseHeaders* headers =
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        url_request_delegate_->received_info_.headers.get();
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(206, headers->response_code());
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3, headers->GetContentLength());
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 range_start, range_end, object_size;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        headers->GetContentRange(&range_start, &range_end, &object_size));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, range_start);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3, range_end);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(5, object_size);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CancelRequest --------------------------------------
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelRequest() {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has several async steps.
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. Write a large response to response storage.
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. Use net::URLRequest to retrieve it.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3. Cancel the request after data starts coming in.
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::VerifyCancel, base::Unretained(this)));
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::RequestAppCachedResource,
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Unretained(this), true));
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset(service_->storage()->CreateResponseWriter(GURL(), 0));
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = writer_->response_id();
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteLargeResponse();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_->kill_after_amount_received_ = kBlockSize;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_->kill_with_io_pending_ = false;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Continues async
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyCancel() {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(net::URLRequestStatus::CANCELED,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              request_->status().status());
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CancelRequestWithIOPending --------------------------------------
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelRequestWithIOPending() {
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This test has several async steps.
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1. Write a large response to response storage.
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2. Use net::URLRequest to retrieve it.
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 3. Cancel the request after data starts coming in.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::VerifyCancel, base::Unretained(this)));
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       &AppCacheURLRequestJobTest::RequestAppCachedResource,
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       base::Unretained(this), true));
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    writer_.reset(service_->storage()->CreateResponseWriter(GURL(), 0));
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    written_response_id_ = writer_->response_id();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WriteLargeResponse();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_->kill_after_amount_received_ = kBlockSize;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url_request_delegate_->kill_with_io_pending_ = true;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Continues async
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Data members --------------------------------------------------------
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::WaitableEvent> test_finished_event_;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockStorageDelegate> storage_delegate_;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockAppCacheService> service_;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::stack<std::pair<base::Closure, bool> > task_stack_;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseReader> reader_;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpResponseInfoIOBuffer> read_info_buffer_;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> read_buffer_;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_read_result_;
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int reader_deletion_count_down_;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 written_response_id_;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseWriter> writer_;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpResponseInfoIOBuffer> write_info_buffer_;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBuffer> write_buffer_;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_write_result_;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int writer_deletion_count_down_;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequest::ProtocolFactory* orig_http_factory_;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContext empty_context_;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLRequest> request_;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockURLRequestDelegate> url_request_delegate_;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<base::Thread> io_thread_;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static AppCacheURLRequestJob* mock_factory_job_;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<base::Thread> AppCacheURLRequestJobTest::io_thread_;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheURLRequestJob* AppCacheURLRequestJobTest::mock_factory_job_ = NULL;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, Basic) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::Basic);
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliveryOrders) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliveryOrders);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliverNetworkResponse) {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverNetworkResponse);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliverErrorResponse) {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverErrorResponse);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliverSmallAppCachedResponse) {
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverSmallAppCachedResponse);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliverLargeAppCachedResponse) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverLargeAppCachedResponse);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, DeliverPartialResponse) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::DeliverPartialResponse);
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, CancelRequest) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequest);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheURLRequestJobTest, CancelRequestWithIOPending) {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheURLRequestJobTest::CancelRequestWithIOPending);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace appcache
810