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)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (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)
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (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)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetUpTestCase() {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(new base::Thread("AppCacheRequestHandlerTest Thread"));
169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->StartWithOptions(options);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void TearDownTestCase() {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_.reset(NULL);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test harness --------------------------------------------------
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppCacheRequestHandlerTest() : host_(NULL) {}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class Method>
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunTestOnIOThread(Method method) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_ .reset(new base::WaitableEvent(false, false));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_thread_->message_loop()->PostTask(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::MethodWrapper<Method>,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), method));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Wait();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUpTest() {
192b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_.reset(new MockAppCacheService);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_->set_request_context(&empty_context_);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_.reset(new MockAppCachePolicy);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_->set_appcache_policy(mock_policy_.get());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_frontend_.reset(new MockFrontend);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_.reset(new AppCacheBackendImpl);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->Initialize(mock_service_.get(), mock_frontend_.get(),
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kMockProcessId);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kHostId = 1;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kHostId);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = backend_impl_->GetHost(kHostId);
20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_.reset(new MockURLRequestJobFactory());
20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    empty_context_.set_job_factory(job_factory_.get());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TearDownTest() {
209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = NULL;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_.reset();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_.reset();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_frontend_.reset();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_service_.reset();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_.reset();
21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_.reset();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinished() {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We unwind the stack prior to finishing up to let stack
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // based objects get deleted.
224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::TestFinishedUnwound,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestFinishedUnwound() {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TearDownTest();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_finished_event_->Signal();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PushNextTask(const base::Closure& task) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.push(task);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleNextTask() {
241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    DCHECK(base::MessageLoop::current() == io_thread_->message_loop());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (task_stack_.empty()) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestFinished();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
246b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    base::MessageLoop::current()->PostTask(FROM_HERE, task_stack_.top());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    task_stack_.pop();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Miss --------------------------------------------------
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Miss() {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Miss,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
2640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Miss() {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(kAppCacheNoCacheId, cache_id);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL(), manifest_url);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_group_id_);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(),
2860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/redirect"));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
2900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Hit --------------------------------------------------
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Hit() {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Hit,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL(), AppCacheEntry(),
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Hit() {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, cache_id);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2, handler_->found_group_id_);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
3380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"),
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_->preferred_manifest_url());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Fallback --------------------------------------------------
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Fallback() {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Fallback,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(),
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/fallbackurl"),
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
3670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
37546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SimulateResponseCode(int response_code) {
37646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_->SetJob(
37746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new MockURLRequestJob(
37846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_.get(),
37946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_->context()->network_delegate(),
38046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            response_code));
38146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_->Start();
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // All our simulation needs  to satisfy are the following two DCHECKs
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK(request_->status().is_success());
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    DCHECK_EQ(response_code, request_->GetResponseCode());
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
38646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  void SimulateResponseInfo(const net::HttpResponseInfo& info) {
38846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    job_factory_->SetJob(
38946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new MockURLRequestJob(
39046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_.get(),
39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            request_->context()->network_delegate(), info));
39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    request_->Start();
39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Fallback() {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the request is restarted, the existing job is dropped so a
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // real network job gets created. We expect NULL here which will cause
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the net library to create a real job.
4020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate an http error of the real network job.
40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SimulateResponseCode(500);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForResponse(
4100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(job_.get());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int64 cache_id = kAppCacheNoCacheId;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL manifest_url;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_->GetExtraResponseInfo(&cache_id, &manifest_url);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, cache_id);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"), manifest_url);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->main_resource_was_namespace_entry_);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/fallbackurl"), host_->namespace_entry_url_);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(GURL("http://blah/manifest/"),
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              host_->preferred_manifest_url());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_FallbackOverride --------------------------------------------
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_FallbackOverride() {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(base::Bind(
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &AppCacheRequestHandlerTest::Verify_MainResource_FallbackOverride,
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Unretained(this)));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
43603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/fallback-override"), net::DEFAULT_PRIORITY,
43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        &delegate_, NULL);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(),
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://blah/fallbackurl"),
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_FallbackOverride() {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_network_response());
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the request is restarted, the existing job is dropped so a
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // real network job gets created. We expect NULL here which will cause
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the net library to create a real job.
4640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
4650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Simulate an http error of the real network job, but with custom
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // headers that override the fallback behavior.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char kOverrideHeaders[] =
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "HTTP/1.1 404 BOO HOO\0"
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "x-chromium-appcache-fallback-override: disallow-fallback\0"
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "\0";
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::HttpResponseInfo info;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.headers = new net::HttpResponseHeaders(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string(kOverrideHeaders, arraysize(kOverrideHeaders)));
47746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    SimulateResponseInfo(info);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForResponse(
4800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_FALSE(job_.get());
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithNoCacheSelected ----------------------------------
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithNoCacheSelected() {
48903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
49003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We avoid creating handler when possible, sub-resource requests are not
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // subject to retrieval from an appcache when there's no associated cache.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_.get());
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithCacheSelected ----------------------------------
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithCacheSelected() {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A sub-resource load where the resource is not in an appcache, or
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in a network or fallback namespace, should result in a failed request.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
50903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_error_response());
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Miss_WithWaitForCacheSelection -----------------------------
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Miss_WithWaitForCacheSelection() {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCache> cache(MakeNewCache());
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = cache->cache_id();
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->set_preferred_manifest_url(cache->owning_group()->manifest_url());
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
54103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    host_->FinishCacheSelection(cache.get(), NULL);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_error_response());
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_Hit -----------------------------
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_Hit() {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
57603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
5800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
5810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
5880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
5920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_RedirectFallback -----------------------------
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_RedirectFallback() {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Redirects to resources in the a different origin are subject to
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fallback namespaces.
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
6130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
6140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_.get());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job_ = handler_->MaybeLoadFallbackForRedirect(
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_.get(),
6190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL("http://not_blah/redirect"));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_delivering_appcache_response());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
6260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SubResource_NoRedirectFallback -----------------------------
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SubResource_NoRedirectFallback() {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Redirects to resources in the same-origin are not subject to
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fallback namespaces.
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(), AppCacheEntry(AppCacheEntry::EXPLICIT, 1), false);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
64303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_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)
67703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
67803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
6820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
6830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_.get());
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheURLRequestJob* fallback_job;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForRedirect(
6880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
6890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
6900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect"));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fallback_job = handler_->MaybeLoadFallbackForResponse(
6930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(fallback_job);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DestroyedHost -----------------------------
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DestroyedHost() {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->AssociateCompleteCache(MakeNewCache());
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindSubResource(
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1), AppCacheEntry(), false);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
70803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(1);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect")));
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // DestroyedHostWithWaitingJob -----------------------------
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DestroyedHostWithWaitingJob() {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = 1;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
73503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
7410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(1);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_ = NULL;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_killed());
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("http://blah/redirect")));
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UnsupportedScheme -----------------------------
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnsupportedScheme() {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Precondition, the host is waiting on cache selection.
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_->pending_selected_cache_id_ = 1;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
76803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("ftp://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_SUB_RESOURCE));
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());  // we could redirect to http (conceivably)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadResource(
7740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForRedirect(
7760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(),
7770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_->context()->network_delegate(),
7780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        GURL("ftp://blah/redirect")));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
7800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CanceledRequest -----------------------------
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CanceledRequest() {
78803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
7950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->has_been_started());
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    job_factory_->SetJob(job_.get());
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Start();
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_started());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_->Cancel();
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->has_been_killed());
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_->MaybeLoadFallbackForResponse(
8080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        request_.get(), request_->context()->network_delegate()));
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WorkerRequest -----------------------------
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WorkerRequest() {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        RESOURCE_TYPE_MAIN_FRAME));
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        RESOURCE_TYPE_SUB_FRAME));
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(AppCacheRequestHandler::IsMainResourceType(
8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        RESOURCE_TYPE_SHARED_WORKER));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(AppCacheRequestHandler::IsMainResourceType(
8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        RESOURCE_TYPE_WORKER));
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
82603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kParentHostId = host_->host_id();
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kWorkerHostId = 2;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kAbandonedWorkerHostId = 3;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kNonExsitingHostId = 700;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kWorkerHostId);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost* worker_host = backend_impl_->GetHost(kWorkerHostId);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(worker_host->CreateRequestHandler(
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        request_.get(), RESOURCE_TYPE_SHARED_WORKER));
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Verify that the handler is associated with the parent host.
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(host_, handler_->host_);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a new worker host, but associate it with a parent host that
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // does not exists to simulate the host having been torn down.
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->UnregisterHost(kWorkerHostId);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backend_impl_->RegisterHost(kAbandonedWorkerHostId);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host = backend_impl_->GetHost(kAbandonedWorkerHostId);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, backend_impl_->GetHost(kNonExsitingHostId));
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    worker_host->SelectCacheForWorker(kNonExsitingHostId, kMockProcessId);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(worker_host->CreateRequestHandler(
8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        request_.get(), RESOURCE_TYPE_SHARED_WORKER));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(handler_.get());
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // MainResource_Blocked --------------------------------------------------
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MainResource_Blocked() {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PushNextTask(
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheRequestHandlerTest::Verify_MainResource_Blocked,
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    request_ = empty_context_.CreateRequest(
86403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        GURL("http://blah/"), net::DEFAULT_PRIORITY, &delegate_, NULL);
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handler_.reset(host_->CreateRequestHandler(request_.get(),
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                               RESOURCE_TYPE_MAIN_FRAME));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_.get());
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_policy_->can_load_return_value_ = false;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_storage()->SimulateFindMainResource(
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AppCacheEntry(AppCacheEntry::EXPLICIT, 1),
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL(), AppCacheEntry(),
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        1, 2, GURL("http://blah/manifest/"));
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    job_ = handler_->MaybeLoadResource(request_.get(),
8760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                       request_->context()->network_delegate());
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_.get());
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job_->is_waiting());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have to wait for completion of storage->FindResponseForMainRequest.
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleNextTask();
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Verify_MainResource_Blocked() {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_waiting());
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(job_->is_delivering_appcache_response());
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_cache_id_);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, handler_->found_group_id_);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(handler_->found_manifest_url_.is_empty());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->preferred_manifest_url().is_empty());
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->main_resource_blocked_);
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host_->blocked_manifest_url_ == GURL("http://blah/manifest/"));
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestFinished();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test case helpers --------------------------------------------------
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCache* MakeNewCache() {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCache* cache = new AppCache(
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mock_storage(), mock_storage()->NewCacheId());
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache->set_complete(true);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheGroup* group = new AppCacheGroup(
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mock_storage(), GURL("http://blah/manifest"),
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mock_storage()->NewGroupId());
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group->AddCache(cache);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return cache;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAppCacheStorage* mock_storage() {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<MockAppCacheStorage*>(mock_service_->storage());
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Data members --------------------------------------------------
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::WaitableEvent> test_finished_event_;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::stack<base::Closure> task_stack_;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockAppCacheService> mock_service_;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheBackendImpl> backend_impl_;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockFrontend> mock_frontend_;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockAppCachePolicy> mock_policy_;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost* host_;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContext empty_context_;
92546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<MockURLRequestJobFactory> job_factory_;
92603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  MockURLRequestDelegate delegate_;
92703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<net::URLRequest> request_;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheRequestHandler> handler_;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCacheURLRequestJob> job_;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static scoped_ptr<base::Thread> io_thread_;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<base::Thread> AppCacheRequestHandlerTest::io_thread_;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Miss) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Miss);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Hit) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Hit);
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Fallback) {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Fallback);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_FallbackOverride) {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::MainResource_FallbackOverride);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Miss_WithNoCacheSelected) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithNoCacheSelected);
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Miss_WithCacheSelected) {
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithCacheSelected);
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest,
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       SubResource_Miss_WithWaitForCacheSelection) {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppCacheRequestHandlerTest::SubResource_Miss_WithWaitForCacheSelection);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Hit) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Hit);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_RedirectFallback) {
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_RedirectFallback);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_NoRedirectFallback) {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    &AppCacheRequestHandlerTest::SubResource_NoRedirectFallback);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, SubResource_Network) {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::SubResource_Network);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, DestroyedHost) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHost);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, DestroyedHostWithWaitingJob) {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::DestroyedHostWithWaitingJob);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, UnsupportedScheme) {
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::UnsupportedScheme);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, CanceledRequest) {
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::CanceledRequest);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, WorkerRequest) {
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::WorkerRequest);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheRequestHandlerTest, MainResource_Blocked) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Blocked);
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1011c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace content
1012