blob: c41fe53028020e7697a15aca506f873f1886e37d [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/run_loop.h"
#include "content/browser/appcache/appcache.h"
#include "content/browser/appcache/appcache_group.h"
#include "content/browser/appcache/appcache_response.h"
#include "content/browser/appcache/appcache_storage.h"
#include "content/browser/appcache/mock_appcache_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
class MockAppCacheStorageTest : public testing::Test {
public:
class MockStorageDelegate : public AppCacheStorage::Delegate {
public:
explicit MockStorageDelegate()
: loaded_cache_id_(0), stored_group_success_(false),
obsoleted_success_(false), found_cache_id_(kAppCacheNoCacheId) {
}
virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE {
loaded_cache_ = cache;
loaded_cache_id_ = cache_id;
}
virtual void OnGroupLoaded(AppCacheGroup* group,
const GURL& manifest_url) OVERRIDE {
loaded_group_ = group;
loaded_manifest_url_ = manifest_url;
}
virtual void OnGroupAndNewestCacheStored(
AppCacheGroup* group, AppCache* newest_cache, bool success,
bool would_exceed_quota) OVERRIDE {
stored_group_ = group;
stored_group_success_ = success;
}
virtual void OnGroupMadeObsolete(AppCacheGroup* group,
bool success,
int response_code) OVERRIDE {
obsoleted_group_ = group;
obsoleted_success_ = success;
}
virtual void OnMainResponseFound(const GURL& url,
const AppCacheEntry& entry,
const GURL& fallback_url,
const AppCacheEntry& fallback_entry,
int64 cache_id,
int64 group_id,
const GURL& manifest_url) OVERRIDE {
found_url_ = url;
found_entry_ = entry;
found_fallback_url_ = fallback_url;
found_fallback_entry_ = fallback_entry;
found_cache_id_ = cache_id;
found_manifest_url_ = manifest_url;
}
scoped_refptr<AppCache> loaded_cache_;
int64 loaded_cache_id_;
scoped_refptr<AppCacheGroup> loaded_group_;
GURL loaded_manifest_url_;
scoped_refptr<AppCacheGroup> stored_group_;
bool stored_group_success_;
scoped_refptr<AppCacheGroup> obsoleted_group_;
bool obsoleted_success_;
GURL found_url_;
AppCacheEntry found_entry_;
GURL found_fallback_url_;
AppCacheEntry found_fallback_entry_;
int64 found_cache_id_;
GURL found_manifest_url_;
};
private:
base::MessageLoop message_loop_;
};
TEST_F(MockAppCacheStorageTest, LoadCache_Miss) {
// Attempt to load a cache that doesn't exist. Should
// complete asyncly.
MockAppCacheService service;
MockStorageDelegate delegate;
service.storage()->LoadCache(111, &delegate);
EXPECT_NE(111, delegate.loaded_cache_id_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(111, delegate.loaded_cache_id_);
EXPECT_FALSE(delegate.loaded_cache_.get());
}
TEST_F(MockAppCacheStorageTest, LoadCache_NearHit) {
// Attempt to load a cache that is currently in use
// and does not require loading from disk. This
// load should complete syncly.
MockAppCacheService service;
// Setup some preconditions. Make an 'unstored' cache for
// us to load. The ctor should put it in the working set.
int64 cache_id = service.storage()->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
// Conduct the test.
MockStorageDelegate delegate;
service.storage()->LoadCache(cache_id, &delegate);
EXPECT_EQ(cache_id, delegate.loaded_cache_id_);
EXPECT_EQ(cache.get(), delegate.loaded_cache_.get());
}
TEST_F(MockAppCacheStorageTest, CreateGroup) {
// Attempt to load/create a group that doesn't exist.
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
MockStorageDelegate delegate;
GURL manifest_url("http://blah/");
service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
EXPECT_FALSE(delegate.loaded_group_.get());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
EXPECT_TRUE(delegate.loaded_group_.get());
EXPECT_TRUE(delegate.loaded_group_->HasOneRef());
EXPECT_FALSE(delegate.loaded_group_->newest_complete_cache());
EXPECT_TRUE(storage->stored_groups_.empty());
}
TEST_F(MockAppCacheStorageTest, LoadGroup_NearHit) {
// Attempt to load a group that is currently in use
// and does not require loading from disk. This
// load should complete syncly.
MockAppCacheService service;
MockStorageDelegate delegate;
// Setup some preconditions. Create a group that appears
// to be "unstored" and "currently in use".
GURL manifest_url("http://blah/");
service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
EXPECT_TRUE(delegate.loaded_group_.get());
// Reset our delegate, and take a reference to the new group.
scoped_refptr<AppCacheGroup> group;
group.swap(delegate.loaded_group_);
delegate.loaded_manifest_url_ = GURL();
// Conduct the test.
service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
EXPECT_EQ(group.get(), delegate.loaded_group_.get());
}
TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) {
// Attempt to load a cache that is not currently in use
// and does require loading from disk. This
// load should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a group and newest cache that
// appears to be "stored" and "not currently in use".
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
int64 cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Drop the references from above so the only refs to these
// objects are from within the storage class. This is to make
// these objects appear as "not currently in use".
AppCache* cache_ptr = cache.get();
AppCacheGroup* group_ptr = group.get();
cache = NULL;
group = NULL;
// Setup a delegate to receive completion callbacks.
MockStorageDelegate delegate;
// Conduct the cache load test.
EXPECT_NE(cache_id, delegate.loaded_cache_id_);
EXPECT_NE(cache_ptr, delegate.loaded_cache_.get());
storage->LoadCache(cache_id, &delegate);
EXPECT_NE(cache_id, delegate.loaded_cache_id_);
EXPECT_NE(cache_ptr, delegate.loaded_cache_.get());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(cache_id, delegate.loaded_cache_id_);
EXPECT_EQ(cache_ptr, delegate.loaded_cache_.get());
delegate.loaded_cache_ = NULL;
// Conduct the group load test.
EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
EXPECT_FALSE(delegate.loaded_group_.get());
storage->LoadOrCreateGroup(manifest_url, &delegate);
EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
EXPECT_FALSE(delegate.loaded_group_.get());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
EXPECT_EQ(group_ptr, delegate.loaded_group_.get());
}
TEST_F(MockAppCacheStorageTest, StoreNewGroup) {
// Store a group and its newest cache. Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a group and newest cache that
// appears to be "unstored".
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
int64 cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
// Hold a ref to the cache simulate the UpdateJob holding that ref,
// and hold a ref to the group to simulate the CacheHost holding that ref.
// Conduct the store test.
MockStorageDelegate delegate;
EXPECT_TRUE(storage->stored_caches_.empty());
EXPECT_TRUE(storage->stored_groups_.empty());
storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate);
EXPECT_FALSE(delegate.stored_group_success_);
EXPECT_TRUE(storage->stored_caches_.empty());
EXPECT_TRUE(storage->stored_groups_.empty());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_TRUE(delegate.stored_group_success_);
EXPECT_FALSE(storage->stored_caches_.empty());
EXPECT_FALSE(storage->stored_groups_.empty());
EXPECT_EQ(cache, group->newest_complete_cache());
EXPECT_TRUE(cache->is_complete());
}
TEST_F(MockAppCacheStorageTest, StoreExistingGroup) {
// Store a group and its newest cache. Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a group and old complete cache
// that appear to be "stored", and a newest unstored complete cache.
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
int64 old_cache_id = storage->NewCacheId();
scoped_refptr<AppCache> old_cache(
new AppCache(service.storage(), old_cache_id));
old_cache->set_complete(true);
group->AddCache(old_cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(old_cache.get());
int64 new_cache_id = storage->NewCacheId();
scoped_refptr<AppCache> new_cache(
new AppCache(service.storage(), new_cache_id));
// Hold our refs to simulate the UpdateJob holding these refs.
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_TRUE(storage->IsCacheStored(old_cache.get()));
EXPECT_FALSE(storage->IsCacheStored(new_cache.get()));
storage->StoreGroupAndNewestCache(group.get(), new_cache.get(), &delegate);
EXPECT_FALSE(delegate.stored_group_success_);
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_TRUE(storage->IsCacheStored(old_cache.get()));
EXPECT_FALSE(storage->IsCacheStored(new_cache.get()));
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_TRUE(delegate.stored_group_success_);
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_FALSE(storage->IsCacheStored(old_cache.get()));
EXPECT_TRUE(storage->IsCacheStored(new_cache.get()));
EXPECT_EQ(new_cache.get(), group->newest_complete_cache());
EXPECT_TRUE(new_cache->is_complete());
}
TEST_F(MockAppCacheStorageTest, StoreExistingGroupExistingCache) {
// Store a group with updates to its existing newest complete cache.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a group and a complete cache that
// appear to be "stored".
GURL manifest_url("http://blah");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
int64 cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Hold our refs to simulate the UpdateJob holding these refs.
// Change the group's newest cache.
EXPECT_EQ(cache, group->newest_complete_cache());
GURL entry_url("http://blah/blah");
cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::MASTER));
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_TRUE(storage->IsCacheStored(cache.get()));
storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate);
EXPECT_FALSE(delegate.stored_group_success_);
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_TRUE(delegate.stored_group_success_);
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_TRUE(storage->IsCacheStored(cache.get()));
EXPECT_EQ(cache, group->newest_complete_cache());
EXPECT_TRUE(cache->GetEntry(entry_url));
}
TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) {
// Make a group obsolete, should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a group and newest cache that
// appears to be "stored" and "currently in use".
GURL manifest_url("http://blah/");
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), manifest_url, 111));
int64 cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->set_complete(true);
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Hold our refs to simulate the UpdateJob holding these refs.
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_FALSE(group->is_obsolete());
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_FALSE(cache->HasOneRef());
EXPECT_FALSE(group->HasOneRef());
storage->MakeGroupObsolete(group.get(), &delegate, 0);
EXPECT_FALSE(group->is_obsolete());
EXPECT_EQ(size_t(1), storage->stored_caches_.size());
EXPECT_EQ(size_t(1), storage->stored_groups_.size());
EXPECT_FALSE(cache->HasOneRef());
EXPECT_FALSE(group->HasOneRef());
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_TRUE(delegate.obsoleted_success_);
EXPECT_EQ(group.get(), delegate.obsoleted_group_.get());
EXPECT_TRUE(group->is_obsolete());
EXPECT_TRUE(storage->stored_caches_.empty());
EXPECT_TRUE(storage->stored_groups_.empty());
EXPECT_TRUE(cache->HasOneRef());
EXPECT_FALSE(group->HasOneRef());
delegate.obsoleted_group_ = NULL;
cache = NULL;
EXPECT_TRUE(group->HasOneRef());
}
TEST_F(MockAppCacheStorageTest, MarkEntryAsForeign) {
// Should complete syncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a cache with an entry.
GURL entry_url("http://blah/entry");
int64 cache_id = storage->NewCacheId();
scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::EXPLICIT));
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_FALSE(cache->GetEntry(entry_url)->IsForeign());
storage->MarkEntryAsForeign(entry_url, cache_id);
EXPECT_TRUE(cache->GetEntry(entry_url)->IsForeign());
EXPECT_TRUE(cache->GetEntry(entry_url)->IsExplicit());
}
TEST_F(MockAppCacheStorageTest, FindNoMainResponse) {
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Conduct the test.
MockStorageDelegate delegate;
GURL url("http://blah/some_url");
EXPECT_NE(url, delegate.found_url_);
storage->FindResponseForMainRequest(url, GURL(), &delegate);
EXPECT_NE(url, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(url, delegate.found_url_);
EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_);
EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id());
EXPECT_EQ(kAppCacheNoResponseId,
delegate.found_fallback_entry_.response_id());
EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
EXPECT_EQ(0, delegate.found_entry_.types());
EXPECT_EQ(0, delegate.found_fallback_entry_.types());
}
TEST_F(MockAppCacheStorageTest, BasicFindMainResponse) {
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a complete cache with an entry.
const int64 kCacheId = storage->NewCacheId();
const GURL kEntryUrl("http://blah/entry");
const GURL kManifestUrl("http://blah/manifest");
const int64 kResponseId = 1;
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
cache->AddEntry(
kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId));
cache->set_complete(true);
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), kManifestUrl, 111));
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_NE(kEntryUrl, delegate.found_url_);
storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
EXPECT_NE(kEntryUrl, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(kEntryUrl, delegate.found_url_);
EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_);
EXPECT_EQ(kCacheId, delegate.found_cache_id_);
EXPECT_EQ(kResponseId, delegate.found_entry_.response_id());
EXPECT_TRUE(delegate.found_entry_.IsExplicit());
EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id());
}
TEST_F(MockAppCacheStorageTest, BasicFindMainFallbackResponse) {
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a complete cache with a
// fallback namespace and entry.
const int64 kCacheId = storage->NewCacheId();
const GURL kFallbackEntryUrl1("http://blah/fallback_entry1");
const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
const GURL kFallbackEntryUrl2("http://blah/fallback_entry2");
const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
const GURL kManifestUrl("http://blah/manifest");
const int64 kResponseId1 = 1;
const int64 kResponseId2 = 2;
Manifest manifest;
manifest.fallback_namespaces.push_back(
AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE, kFallbackNamespaceUrl1,
kFallbackEntryUrl1, false));
manifest.fallback_namespaces.push_back(
AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE, kFallbackNamespaceUrl2,
kFallbackEntryUrl2, false));
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
cache->InitializeWithManifest(&manifest);
cache->AddEntry(kFallbackEntryUrl1,
AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId1));
cache->AddEntry(kFallbackEntryUrl2,
AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId2));
cache->set_complete(true);
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), kManifestUrl, 111));
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// The test url is in both fallback namespace urls, but should match
// the longer of the two.
const GURL kTestUrl("http://blah/fallback_namespace/longer/test");
// Conduct the test.
MockStorageDelegate delegate;
EXPECT_NE(kTestUrl, delegate.found_url_);
storage->FindResponseForMainRequest(kTestUrl, GURL(), &delegate);
EXPECT_NE(kTestUrl, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(kTestUrl, delegate.found_url_);
EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_);
EXPECT_EQ(kCacheId, delegate.found_cache_id_);
EXPECT_FALSE(delegate.found_entry_.has_response_id());
EXPECT_EQ(kResponseId2, delegate.found_fallback_entry_.response_id());
EXPECT_EQ(kFallbackEntryUrl2, delegate.found_fallback_url_);
EXPECT_TRUE(delegate.found_fallback_entry_.IsFallback());
}
TEST_F(MockAppCacheStorageTest, FindMainResponseWithMultipleCandidates) {
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create 2 complete caches with an entry
// for the same url.
const GURL kEntryUrl("http://blah/entry");
const int64 kCacheId1 = storage->NewCacheId();
const int64 kCacheId2 = storage->NewCacheId();
const GURL kManifestUrl1("http://blah/manifest1");
const GURL kManifestUrl2("http://blah/manifest2");
const int64 kResponseId1 = 1;
const int64 kResponseId2 = 2;
// The first cache.
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId1));
cache->AddEntry(
kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId1));
cache->set_complete(true);
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), kManifestUrl1, 111));
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Drop our references to cache1 so it appears as "not in use".
cache = NULL;
group = NULL;
// The second cache.
cache = new AppCache(service.storage(), kCacheId2);
cache->AddEntry(
kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId2));
cache->set_complete(true);
group = new AppCacheGroup(service.storage(), kManifestUrl2, 222);
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
// Conduct the test, we should find the response from the second cache
// since it's "in use".
MockStorageDelegate delegate;
EXPECT_NE(kEntryUrl, delegate.found_url_);
storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
EXPECT_NE(kEntryUrl, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(kEntryUrl, delegate.found_url_);
EXPECT_EQ(kManifestUrl2, delegate.found_manifest_url_);
EXPECT_EQ(kCacheId2, delegate.found_cache_id_);
EXPECT_EQ(kResponseId2, delegate.found_entry_.response_id());
EXPECT_TRUE(delegate.found_entry_.IsExplicit());
EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id());
}
TEST_F(MockAppCacheStorageTest, FindMainResponseExclusions) {
// Should complete asyncly.
MockAppCacheService service;
MockAppCacheStorage* storage =
reinterpret_cast<MockAppCacheStorage*>(service.storage());
// Setup some preconditions. Create a complete cache with a
// foreign entry and an online namespace.
const int64 kCacheId = storage->NewCacheId();
const GURL kEntryUrl("http://blah/entry");
const GURL kManifestUrl("http://blah/manifest");
const GURL kOnlineNamespaceUrl("http://blah/online_namespace");
const int64 kResponseId = 1;
Manifest manifest;
manifest.online_whitelist_namespaces.push_back(
AppCacheNamespace(APPCACHE_NETWORK_NAMESPACE, kOnlineNamespaceUrl,
GURL(), false));
scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
cache->InitializeWithManifest(&manifest);
cache->AddEntry(
kEntryUrl,
AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
kResponseId));
cache->set_complete(true);
scoped_refptr<AppCacheGroup> group(
new AppCacheGroup(service.storage(), kManifestUrl, 111));
group->AddCache(cache.get());
storage->AddStoredGroup(group.get());
storage->AddStoredCache(cache.get());
MockStorageDelegate delegate;
// We should not find anything for the foreign entry.
EXPECT_NE(kEntryUrl, delegate.found_url_);
storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
EXPECT_NE(kEntryUrl, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(kEntryUrl, delegate.found_url_);
EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_);
EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id());
EXPECT_EQ(kAppCacheNoResponseId,
delegate.found_fallback_entry_.response_id());
EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
EXPECT_EQ(0, delegate.found_entry_.types());
EXPECT_EQ(0, delegate.found_fallback_entry_.types());
// We should not find anything for the online namespace.
EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_);
storage->FindResponseForMainRequest(kOnlineNamespaceUrl, GURL(), &delegate);
EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_);
base::RunLoop().RunUntilIdle(); // Do async task execution.
EXPECT_EQ(kOnlineNamespaceUrl, delegate.found_url_);
EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_);
EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id());
EXPECT_EQ(kAppCacheNoResponseId,
delegate.found_fallback_entry_.response_id());
EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
EXPECT_EQ(0, delegate.found_entry_.types());
EXPECT_EQ(0, delegate.found_fallback_entry_.types());
}
} // namespace content