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