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 "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_backend_impl.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_group.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_host.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/appcache/mock_appcache_policy.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/appcache/mock_appcache_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace content {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheHostTest : public testing::Test {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHostTest() {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    get_status_callback_ =
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheHostTest::GetStatusCallback,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this));
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start_update_callback_ =
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheHostTest::StartUpdateCallback,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this));
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    swap_cache_callback_ =
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AppCacheHostTest::SwapCacheCallback,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this));
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class MockFrontend : public AppCacheFrontend {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockFrontend()
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : last_host_id_(-222), last_cache_id_(-222),
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          last_status_(APPCACHE_STATUS_OBSOLETE),
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          last_status_changed_(APPCACHE_STATUS_OBSOLETE),
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          last_event_id_(APPCACHE_OBSOLETE_EVENT),
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content_blocked_(false) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnCacheSelected(
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        int host_id, const AppCacheInfo& info) OVERRIDE {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_host_id_ = host_id;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_cache_id_ = info.cache_id;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_status_ = info.status;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnStatusChanged(const std::vector<int>& host_ids,
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 AppCacheStatus status) OVERRIDE {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_status_changed_ = status;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnEventRaised(const std::vector<int>& host_ids,
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               AppCacheEventID event_id) OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_event_id_ = event_id;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    virtual void OnErrorEventRaised(
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        const std::vector<int>& host_ids,
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        const AppCacheErrorDetails& details) OVERRIDE {
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      last_event_id_ = APPCACHE_ERROR_EVENT;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnProgressEventRaised(const std::vector<int>& host_ids,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const GURL& url,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int num_total,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int num_complete) OVERRIDE {
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      last_event_id_ = APPCACHE_PROGRESS_EVENT;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnLogMessage(int host_id,
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              AppCacheLogLevel log_level,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const std::string& message) OVERRIDE {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void OnContentBlocked(int host_id,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const GURL& manifest_url) OVERRIDE {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content_blocked_ = true;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int last_host_id_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 last_cache_id_;
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppCacheStatus last_status_;
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppCacheStatus last_status_changed_;
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AppCacheEventID last_event_id_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool content_blocked_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  class MockQuotaManagerProxy : public storage::QuotaManagerProxy {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockQuotaManagerProxy() : QuotaManagerProxy(NULL, NULL) {}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not needed for our tests.
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual void RegisterClient(storage::QuotaClient* client) OVERRIDE {}
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual void NotifyStorageAccessed(storage::QuotaClient::ID client_id,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const GURL& origin,
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::StorageType type) OVERRIDE {}
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual void NotifyStorageModified(storage::QuotaClient::ID client_id,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const GURL& origin,
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                       storage::StorageType type,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       int64 delta) OVERRIDE {}
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      const GURL& origin,
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                      storage::StorageType type,
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                      bool enabled) OVERRIDE {}
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    virtual void GetUsageAndQuota(
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::SequencedTaskRunner* original_task_runner,
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        const GURL& origin,
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        storage::StorageType type,
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        const GetUsageAndQuotaCallback& callback) OVERRIDE {}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inuse_[origin] += 1;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inuse_[origin] -= 1;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int GetInUseCount(const GURL& origin) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return inuse_[origin];
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void reset() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inuse_.clear();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Map from origin to count of inuse notifications.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<GURL, int> inuse_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~MockQuotaManagerProxy() {}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void GetStatusCallback(AppCacheStatus status, void* param) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_status_result_ = status;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_callback_param_ = param;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartUpdateCallback(bool result, void* param) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_start_result_ = result;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_callback_param_ = param;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SwapCacheCallback(bool result, void* param) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_swap_result_ = result;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_callback_param_ = param;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  base::MessageLoop message_loop_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mock classes for the 'host' to work with
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAppCacheService service_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockFrontend mock_frontend_;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mock callbacks we expect to receive from the 'host'
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::GetStatusCallback get_status_callback_;
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::StartUpdateCallback start_update_callback_;
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  content::SwapCacheCallback swap_cache_callback_;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  AppCacheStatus last_status_result_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool last_swap_result_;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool last_start_result_;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* last_callback_param_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, Basic) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct a host and test what state it appears to be in.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, host.host_id());
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&service_, host.service());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&mock_frontend_, host.frontend());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, host.associated_cache());
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.is_selection_pending());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that the callbacks are delivered immediately
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and respond as if there is no cache selected.
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  last_status_result_ = APPCACHE_STATUS_OBSOLETE;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_start_result_ = true;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.StartUpdateWithCallback(start_update_callback_,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               reinterpret_cast<void*>(2));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(last_start_result_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(2), last_callback_param_);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_swap_result_ = true;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.SwapCacheWithCallback(swap_cache_callback_, reinterpret_cast<void*>(3));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(last_swap_result_);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(3), last_callback_param_);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, SelectNoCache) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockQuotaManagerProxy);
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service_.set_quota_manager_proxy(mock_quota_proxy.get());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost host(1, &mock_frontend_, &service_);
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, GURL());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should have received an OnCacheSelected msg
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, mock_frontend_.last_host_id_);
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, see that it respond as if there is no cache selected.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, host.host_id());
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(&service_, host.service());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(&mock_frontend_, host.frontend());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, host.associated_cache());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(host.is_selection_pending());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host.preferred_manifest_url().is_empty());
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.set_quota_manager_proxy(NULL);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, ForeignEntry) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Precondition, a cache with an entry that is not marked as foreign.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCacheId = 22;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDocumentURL("http://origin/document");
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<AppCache> cache = new AppCache(service_.storage(), kCacheId);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->AddEntry(kDocumentURL, AppCacheEntry(AppCacheEntry::EXPLICIT));
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.MarkAsForeignEntry(kDocumentURL, kCacheId);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mock_frontend_.last_host_id_);
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that it respond as if there is no cache selected.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, host.host_id());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&service_, host.service());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(&mock_frontend_, host.frontend());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, host.associated_cache());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.is_selection_pending());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that the entry was marked as foreign.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache->GetEntry(kDocumentURL)->IsForeign());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, ForeignFallbackEntry) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Precondition, a cache with a fallback entry that is not marked as foreign.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCacheId = 22;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kFallbackURL("http://origin/fallback_resource");
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<AppCache> cache = new AppCache(service_.storage(), kCacheId);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache->AddEntry(kFallbackURL, AppCacheEntry(AppCacheEntry::FALLBACK));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.NotifyMainResourceIsNamespaceEntry(kFallbackURL);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.MarkAsForeignEntry(GURL("http://origin/missing_document"), kCacheId);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // We should have received an OnCacheSelected msg for kAppCacheNoCacheId.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mock_frontend_.last_host_id_);
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See that the fallback entry was marked as foreign.
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(cache->GetEntry(kFallbackURL)->IsForeign());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, FailedCacheLoad) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.is_selection_pending());
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMockCacheId = 333;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put it in a state where we're waiting on a cache
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // load prior to finishing cache selection.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.pending_selected_cache_id_ = kMockCacheId;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(host.is_selection_pending());
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback should not occur until we finish cache selection.
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  last_status_result_ = APPCACHE_STATUS_OBSOLETE;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_callback_param_ = reinterpret_cast<void*>(-1);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Satisfy the load with NULL, a failure.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.OnCacheLoaded(NULL, kMockCacheId);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache selection should have finished
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.is_selection_pending());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mock_frontend_.last_host_id_);
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback should have fired upon completing the cache load too.
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, FailedGroupLoad) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kMockManifestUrl("http://foo.bar/baz");
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put it in a state where we're waiting on a cache
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // load prior to finishing cache selection.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.pending_selected_manifest_url_ = kMockManifestUrl;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(host.is_selection_pending());
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback should not occur until we finish cache selection.
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  last_status_result_ = APPCACHE_STATUS_OBSOLETE;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_callback_param_ = reinterpret_cast<void*>(-1);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.GetStatusWithCallback(get_status_callback_, reinterpret_cast<void*>(1));
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, last_status_result_);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(-1), last_callback_param_);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Satisfy the load will NULL, a failure.
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.OnGroupLoaded(NULL, kMockManifestUrl);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache selection should have finished
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.is_selection_pending());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, mock_frontend_.last_host_id_);
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback should have fired upon completing the group load.
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, last_status_result_);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(reinterpret_cast<void*>(1), last_callback_param_);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, SetSwappableCache) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost host(1, &mock_frontend_, &service_);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.SetSwappableCache(NULL);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.swappable_cache_.get());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<AppCacheGroup> group1(new AppCacheGroup(
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_.storage(), GURL(), service_.storage()->NewGroupId()));
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host.SetSwappableCache(group1.get());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.swappable_cache_.get());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache* cache1 = new AppCache(service_.storage(), 111);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache1->set_complete(true);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group1->AddCache(cache1);
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host.SetSwappableCache(group1.get());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache1, host.swappable_cache_.get());
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -222;  // to verify we received OnCacheSelected
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.AssociateCompleteCache(cache1);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.swappable_cache_.get());  // was same as associated cache
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(APPCACHE_STATUS_IDLE, host.GetStatus());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // verify OnCacheSelected was called
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(host.host_id(), mock_frontend_.last_host_id_);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache1->cache_id(), mock_frontend_.last_cache_id_);
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(APPCACHE_STATUS_IDLE, mock_frontend_.last_status_);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache* cache2 = new AppCache(service_.storage(), 222);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache2->set_complete(true);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group1->AddCache(cache2);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache2, host.swappable_cache_.get());  // updated to newest
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCacheGroup> group2(
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new AppCacheGroup(service_.storage(), GURL("http://foo.com"),
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        service_.storage()->NewGroupId()));
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache* cache3 = new AppCache(service_.storage(), 333);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache3->set_complete(true);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group2->AddCache(cache3);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache* cache4 = new AppCache(service_.storage(), 444);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache4->set_complete(true);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group2->AddCache(cache4);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache2, host.swappable_cache_.get());  // unchanged
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.AssociateCompleteCache(cache3);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache4, host.swappable_cache_.get());  // newest cache in group2
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(group1->HasCache());  // both caches in group1 have refcount 0
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.AssociateNoCache(GURL());
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.swappable_cache_.get());
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(group2->HasCache());  // both caches in group2 have refcount 0
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Host adds reference to newest cache when an update is complete.
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache* cache5 = new AppCache(service_.storage(), 555);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cache5->set_complete(true);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group2->AddCache(cache5);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.group_being_updated_ = group2;
412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host.OnUpdateComplete(group2.get());
413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(host.group_being_updated_.get());
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(cache5, host.swappable_cache_.get());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  group2->RemoveCache(cache5);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(group2->HasCache());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.group_being_updated_ = group2;
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host.OnUpdateComplete(group2.get());
420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(host.group_being_updated_.get());
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(host.swappable_cache_.get());  // group2 had no newest cache
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, ForDedicatedWorker) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMockProcessId = 1;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kParentHostId = 1;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kWorkerHostId = 2;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheBackendImpl backend_impl;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_impl.Initialize(&service_, &mock_frontend_, kMockProcessId);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_impl.RegisterHost(kParentHostId);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_impl.RegisterHost(kWorkerHostId);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost* parent_host = backend_impl.GetHost(kParentHostId);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parent_host->is_for_dedicated_worker());
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHost* worker_host = backend_impl.GetHost(kWorkerHostId);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  worker_host->SelectCacheForWorker(kParentHostId, kMockProcessId);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(worker_host->is_for_dedicated_worker());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parent_host, worker_host->GetParentAppCacheHost());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should have received an OnCacheSelected msg for the worker_host.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The host for workers always indicates 'no cache selected' regardless
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of its parent's state. This is OK because the worker cannot access
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the scriptable interface, the only function available is resource
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loading (see appcache_request_handler_unittests those tests).
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kWorkerHostId, mock_frontend_.last_host_id_);
448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the parent being torn down.
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  backend_impl.UnregisterHost(kParentHostId);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  parent_host = NULL;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, backend_impl.GetHost(kParentHostId));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, worker_host->GetParentAppCacheHost());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, SelectCacheAllowed) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockQuotaManagerProxy);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAppCachePolicy mock_appcache_policy;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_appcache_policy.can_create_return_value_ = true;
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service_.set_quota_manager_proxy(mock_quota_proxy.get());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.set_appcache_policy(&mock_appcache_policy);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
470f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.content_blocked_ = false;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kManifestUrl(GURL("http://whatever/cache.manifest"));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost host(1, &mock_frontend_, &service_);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host.first_party_url_ = kDocAndOriginUrl;
478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, kManifestUrl);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // MockAppCacheService::LoadOrCreateGroup is asynchronous, so we shouldn't
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // have received an OnCacheSelected msg yet.
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-333, mock_frontend_.last_host_id_);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-333, mock_frontend_.last_cache_id_);
485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(APPCACHE_STATUS_OBSOLETE, mock_frontend_.last_status_);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No error events either
487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(APPCACHE_OBSOLETE_EVENT, mock_frontend_.last_event_id_);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(mock_frontend_.content_blocked_);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host.is_selection_pending());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.set_quota_manager_proxy(NULL);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AppCacheHostTest, SelectCacheBlocked) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<MockQuotaManagerProxy> mock_quota_proxy(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new MockQuotaManagerProxy);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockAppCachePolicy mock_appcache_policy;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_appcache_policy.can_create_return_value_ = false;
501868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  service_.set_quota_manager_proxy(mock_quota_proxy.get());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.set_appcache_policy(&mock_appcache_policy);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset our mock frontend
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_cache_id_ = -333;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.last_host_id_ = -333;
507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_status_ = APPCACHE_STATUS_OBSOLETE;
508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  mock_frontend_.last_event_id_ = APPCACHE_OBSOLETE_EVENT;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_frontend_.content_blocked_ = false;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kDocAndOriginUrl(GURL("http://whatever/").GetOrigin());
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL kManifestUrl(GURL("http://whatever/cache.manifest"));
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheHost host(1, &mock_frontend_, &service_);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host.first_party_url_ = kDocAndOriginUrl;
516f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    host.SelectCache(kDocAndOriginUrl, kAppCacheNoCacheId, kManifestUrl);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We should have received an OnCacheSelected msg
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, mock_frontend_.last_host_id_);
521f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(kAppCacheNoCacheId, mock_frontend_.last_cache_id_);
522f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(APPCACHE_STATUS_UNCACHED, mock_frontend_.last_status_);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Also, an error event was raised
525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(APPCACHE_ERROR_EVENT, mock_frontend_.last_event_id_);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(mock_frontend_.content_blocked_);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Otherwise, see that it respond as if there is no cache selected.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, host.host_id());
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(&service_, host.service());
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(&mock_frontend_, host.frontend());
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(NULL, host.associated_cache());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(host.is_selection_pending());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(host.preferred_manifest_url().is_empty());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, mock_quota_proxy->GetInUseCount(kDocAndOriginUrl));
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.set_quota_manager_proxy(NULL);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace content
541