appcache_request_handler_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 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 <string>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/threading/thread.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_backend_impl.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_request_handler.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_url_request_job.h"
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/appcache/mock_appcache_policy.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/appcache/mock_appcache_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/base/request_priority.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_error_job.h"
2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/url_request/url_request_job_factory.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace content {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMockProcessId = 1;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheRequestHandlerTest : public testing::Test {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockFrontend : public AppCacheFrontend {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnCacheSelected(
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        int host_id, const AppCacheInfo& info) OVERRIDE {}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnStatusChanged(const std::vector<int>& host_ids,
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 AppCacheStatus status) OVERRIDE {}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnEventRaised(const std::vector<int>& host_ids,
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               AppCacheEventID event_id) OVERRIDE {}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    virtual void OnErrorEventRaised(
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        const std::vector<int>& host_ids,
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        const AppCacheErrorDetails& details) OVERRIDE {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnProgressEventRaised(const std::vector<int>& host_ids,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const GURL& url,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int num_total,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int num_complete) OVERRIDE {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnLogMessage(int host_id,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              AppCacheLogLevel log_level,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& message) OVERRIDE {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnContentBlocked(int host_id,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const GURL& manifest_url) OVERRIDE {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper callback to run a test on our io_thread. The io_thread is spun up
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // once and reused for all tests.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class Method>
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MethodWrapper(Method method) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetUpTest();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (this->*method)();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Subclasses to simulate particular responses so test cases can
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exercise fallback code paths.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockURLRequestDelegate : public net::URLRequest::Delegate {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnReadCompleted(net::URLRequest* request,
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 int bytes_read) OVERRIDE {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockURLRequestJob : public net::URLRequestJob {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockURLRequestJob(net::URLRequest* request,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      net::NetworkDelegate* network_delegate,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int response_code)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : net::URLRequestJob(request, network_delegate),
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response_code_(response_code),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          has_response_info_(false) {}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockURLRequestJob(net::URLRequest* request,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      net::NetworkDelegate* network_delegate,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const net::HttpResponseInfo& info)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : net::URLRequestJob(request, network_delegate),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response_code_(info.headers->response_code()),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          has_response_info_(true),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          response_info_(info) {}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protected:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~MockURLRequestJob() {}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void Start() OVERRIDE {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NotifyHeadersComplete();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int GetResponseCode() const OVERRIDE {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return response_code_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void GetResponseInfo(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::HttpResponseInfo* info) OVERRIDE {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!has_response_info_)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *info = response_info_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  private:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int response_code_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_response_info_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseInfo response_info_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  class MockURLRequestJobFactory : public net::URLRequestJobFactory {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockURLRequestJobFactory() : job_(NULL) {
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    virtual ~MockURLRequestJobFactory() {
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      DCHECK(!job_);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    void SetJob(net::URLRequestJob* job) {
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      job_ = job;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        const std::string& scheme,
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        net::URLRequest* request,
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        net::NetworkDelegate* network_delegate) const OVERRIDE {
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      if (job_) {
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        net::URLRequestJob* temp = job_;
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        job_ = NULL;
14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        return temp;
14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      } else {
14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // Some of these tests trigger UpdateJobs which start URLRequests.
14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // We short circuit those be returning error jobs.
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        return new net::URLRequestErrorJob(request,
14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           network_delegate,
14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                           net::ERR_INTERNET_DISCONNECTED);
14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      }
14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE {
15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return scheme == "http";
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    };
15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    virtual bool IsHandledURL(const GURL& url) const OVERRIDE {
15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return url.SchemeIs("http");
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE {
16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return false;
16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)   private:
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    mutable net::URLRequestJob* job_;
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  };
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  class MockURLRequest : public net::URLRequest {
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)   public:
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockURLRequest(const GURL& url, net::URLRequestContext* context)
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        : net::URLRequest(url, net::DEFAULT_PRIORITY, NULL, context) {}
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    MockURLRequestDelegate delegate_;
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  };
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetUpTestCase() {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(new base::Thread("AppCacheRequestHandlerTest Thread"));
178b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->StartWithOptions(options);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void TearDownTestCase() {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(NULL);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test harness --------------------------------------------------
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppCacheRequestHandlerTest() : host_(NULL) {}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class Method>
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunTestOnIOThread(Method method) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_ .reset(new base::WaitableEvent(false, false));
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->message_loop()->PostTask(
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::MethodWrapper<Method>,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), method));
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Wait();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUpTest() {
201b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_.reset(new MockAppCacheService);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_->set_request_context(&empty_context_);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_.reset(new MockAppCachePolicy);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_->set_appcache_policy(mock_policy_.get());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_frontend_.reset(new MockFrontend);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_.reset(new AppCacheBackendImpl);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->Initialize(mock_service_.get(), mock_frontend_.get(),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kMockProcessId);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kHostId = 1;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kHostId);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = backend_impl_->GetHost(kHostId);
21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_.reset(new MockURLRequestJobFactory());
21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    empty_context_.set_job_factory(job_factory_.get());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TearDownTest() {
218b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = NULL;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_.reset();
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_frontend_.reset();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_.reset();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_.reset();
22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_.reset();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinished() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We unwind the stack prior to finishing up to let stack
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // based objects get deleted.
233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::TestFinishedUnwound,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinishedUnwound() {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TearDownTest();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Signal();
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PushNextTask(const base::Closure& task) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.push(task);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleNextTask() {
250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (task_stack_.empty()) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestFinished();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, task_stack_.top());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.pop();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Miss --------------------------------------------------
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Miss() {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Miss,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Miss() {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(kAppCacheNoCacheId, cache_id);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL(), manifest_url);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_group_id_);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(),
2940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/redirect"));
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Hit --------------------------------------------------
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Hit() {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Hit,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL(), AppCacheEntry(),
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
3240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Hit() {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, cache_id);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, handler_->found_group_id_);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
3450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"),
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_->preferred_manifest_url());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Fallback --------------------------------------------------
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Fallback() {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Fallback,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(),
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/fallbackurl"),
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
3730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SimulateResponseCode(int response_code) {
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_->SetJob(
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new MockURLRequestJob(
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_.get(),
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_->context()->network_delegate(),
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            response_code));
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_->Start();
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // All our simulation needs  to satisfy are the following two DCHECKs
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK(request_->status().is_success());
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK_EQ(response_code, request_->GetResponseCode());
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SimulateResponseInfo(const net::HttpResponseInfo& info) {
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_->SetJob(
39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new MockURLRequestJob(
39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_.get(),
39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_->context()->network_delegate(), info));
39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_->set_delegate(&request_->delegate_);
39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_->Start();
40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Fallback() {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the request is restarted, the existing job is dropped so a
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // real network job gets created. We expect NULL here which will cause
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the net library to create a real job.
4090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate an http error of the real network job.
41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SimulateResponseCode(500);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForResponse(
4170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(job_.get());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, cache_id);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->main_resource_was_namespace_entry_);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/fallbackurl"), host_->namespace_entry_url_);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"),
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_->preferred_manifest_url());
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_FallbackOverride --------------------------------------------
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_FallbackOverride() {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &AppCacheRequestHandlerTest::Verify_MainResource_FallbackOverride,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Unretained(this)));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/fallback-override"),
4430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      &empty_context_));
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(),
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/fallbackurl"),
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_FallbackOverride() {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the request is restarted, the existing job is dropped so a
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // real network job gets created. We expect NULL here which will cause
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the net library to create a real job.
4700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate an http error of the real network job, but with custom
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // headers that override the fallback behavior.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kOverrideHeaders[] =
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HTTP/1.1 404 BOO HOO\0"
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "x-chromium-appcache-fallback-override: disallow-fallback\0"
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "\0";
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseInfo info;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.headers = new net::HttpResponseHeaders(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string(kOverrideHeaders, arraysize(kOverrideHeaders)));
48346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SimulateResponseInfo(info);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForResponse(
4860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithNoCacheSelected ----------------------------------
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithNoCacheSelected() {
4950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We avoid creating handler when possible, sub-resource requests are not
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // subject to retrieval from an appcache when there's no associated cache.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_.get());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithCacheSelected ----------------------------------
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithCacheSelected() {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A sub-resource load where the resource is not in an appcache, or
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in a network or fallback namespace, should result in a failed request.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_error_response());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithWaitForCacheSelection -----------------------------
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithWaitForCacheSelection() {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCache> cache(MakeNewCache());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = cache->cache_id();
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->set_preferred_manifest_url(cache->owning_group()->manifest_url());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    host_->FinishCacheSelection(cache.get(), NULL);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_error_response());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Hit -----------------------------
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Hit() {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_RedirectFallback -----------------------------
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_RedirectFallback() {
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Redirects to resources in the a different origin are subject to
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fallback namespaces.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
6140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
6150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_.get());
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForRedirect(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(),
6200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://not_blah/redirect"));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
6270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_NoRedirectFallback -----------------------------
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_NoRedirectFallback() {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Redirects to resources in the same-origin are not subject to
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fallback namespaces.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
6470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
6480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_.get());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
6530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
6540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
6550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SimulateResponseCode(200);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
6600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Network -----------------------------
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Network() {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A sub-resource load where the resource is in a network namespace,
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // should result in the system using a 'real' job to do the network
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // retrieval.
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(), AppCacheEntry(), true);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
6810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
6820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_.get());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
6870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
6880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
6890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
6920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DestroyedHost -----------------------------
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DestroyedHost() {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(1);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect")));
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DestroyedHostWithWaitingJob -----------------------------
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DestroyedHostWithWaitingJob() {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = 1;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
7380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(1);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_killed());
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect")));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UnsupportedScheme -----------------------------
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnsupportedScheme() {
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = 1;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("ftp://blah/"), &empty_context_));
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::SUB_RESOURCE));
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());  // we could redirect to http (conceivably)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("ftp://blah/redirect")));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CanceledRequest -----------------------------
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CanceledRequest() {
7840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
7900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->has_been_started());
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_->SetJob(job_);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_started());
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Cancel();
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_killed());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
8030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WorkerRequest -----------------------------
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WorkerRequest() {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ResourceType::MAIN_FRAME));
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ResourceType::SUB_FRAME));
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ResourceType::SHARED_WORKER));
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(AppCacheRequestHandler::IsMainResourceType(
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ResourceType::WORKER));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kParentHostId = host_->host_id();
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kWorkerHostId = 2;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kAbandonedWorkerHostId = 3;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kNonExsitingHostId = 700;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kWorkerHostId);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost* worker_host = backend_impl_->GetHost(kWorkerHostId);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(worker_host->CreateRequestHandler(
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(), ResourceType::SHARED_WORKER));
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the handler is associated with the parent host.
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(host_, handler_->host_);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a new worker host, but associate it with a parent host that
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // does not exists to simulate the host having been torn down.
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(kWorkerHostId);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kAbandonedWorkerHostId);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host = backend_impl_->GetHost(kAbandonedWorkerHostId);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, backend_impl_->GetHost(kNonExsitingHostId));
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host->SelectCacheForWorker(kNonExsitingHostId, kMockProcessId);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(worker_host->CreateRequestHandler(
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(), ResourceType::SHARED_WORKER));
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_.get());
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Blocked --------------------------------------------------
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Blocked() {
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Blocked,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    request_.reset(new MockURLRequest(GURL("http://blah/"), &empty_context_));
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               ResourceType::MAIN_FRAME));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_->can_load_return_value_ = false;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL(), AppCacheEntry(),
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
8690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Blocked() {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_delivering_appcache_response());
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_cache_id_);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_group_id_);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_->found_manifest_url_.is_empty());
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->main_resource_blocked_);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->blocked_manifest_url_ == GURL("http://blah/manifest/"));
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test case helpers --------------------------------------------------
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCache* MakeNewCache() {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCache* cache = new AppCache(
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mock_storage(), mock_storage()->NewCacheId());
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->set_complete(true);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheGroup* group = new AppCacheGroup(
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mock_storage(), GURL("http://blah/manifest"),
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mock_storage()->NewGroupId());
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group->AddCache(cache);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cache;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAppCacheStorage* mock_storage() {
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<MockAppCacheStorage*>(mock_service_->storage());
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Data members --------------------------------------------------
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::WaitableEvent> test_finished_event_;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::stack<base::Closure> task_stack_;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockAppCacheService> mock_service_;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheBackendImpl> backend_impl_;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockFrontend> mock_frontend_;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockAppCachePolicy> mock_policy_;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost* host_;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContext empty_context_;
91846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<MockURLRequestJobFactory> job_factory_;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockURLRequest> request_;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheRequestHandler> handler_;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCacheURLRequestJob> job_;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<base::Thread> io_thread_;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<base::Thread> AppCacheRequestHandlerTest::io_thread_;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Miss) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Miss);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Hit) {
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Hit);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Fallback) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Fallback);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_FallbackOverride) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::MainResource_FallbackOverride);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Miss_WithNoCacheSelected) {
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithNoCacheSelected);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Miss_WithCacheSelected) {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithCacheSelected);
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest,
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       SubResource_Miss_WithWaitForCacheSelection) {
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithWaitForCacheSelection);
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Hit) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Hit);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_RedirectFallback) {
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_RedirectFallback);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_NoRedirectFallback) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &AppCacheRequestHandlerTest::SubResource_NoRedirectFallback);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Network) {
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Network);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, DestroyedHost) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHost);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, DestroyedHostWithWaitingJob) {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHostWithWaitingJob);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, UnsupportedScheme) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::UnsupportedScheme);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, CanceledRequest) {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::CanceledRequest);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, WorkerRequest) {
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::WorkerRequest);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Blocked) {
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Blocked);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1003c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace content
1004