mock_appcache_storage_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/run_loop.h" 6#include "content/browser/appcache/mock_appcache_service.h" 7#include "testing/gtest/include/gtest/gtest.h" 8#include "webkit/browser/appcache/appcache.h" 9#include "webkit/browser/appcache/appcache_group.h" 10#include "webkit/browser/appcache/appcache_response.h" 11#include "webkit/browser/appcache/appcache_storage.h" 12 13using appcache::AppCache; 14using appcache::AppCacheEntry; 15using appcache::AppCacheGroup; 16using appcache::AppCacheStorage; 17using appcache::APPCACHE_FALLBACK_NAMESPACE; 18using appcache::APPCACHE_INTERCEPT_NAMESPACE; 19using appcache::kAppCacheNoCacheId; 20using appcache::kAppCacheNoResponseId; 21using appcache::Manifest; 22using appcache::Namespace; 23using appcache::APPCACHE_NETWORK_NAMESPACE; 24 25namespace content { 26 27class MockAppCacheStorageTest : public testing::Test { 28 public: 29 class MockStorageDelegate : public AppCacheStorage::Delegate { 30 public: 31 explicit MockStorageDelegate() 32 : loaded_cache_id_(0), stored_group_success_(false), 33 obsoleted_success_(false), found_cache_id_(kAppCacheNoCacheId) { 34 } 35 36 virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE { 37 loaded_cache_ = cache; 38 loaded_cache_id_ = cache_id; 39 } 40 41 virtual void OnGroupLoaded(AppCacheGroup* group, 42 const GURL& manifest_url) OVERRIDE { 43 loaded_group_ = group; 44 loaded_manifest_url_ = manifest_url; 45 } 46 47 virtual void OnGroupAndNewestCacheStored( 48 AppCacheGroup* group, AppCache* newest_cache, bool success, 49 bool would_exceed_quota) OVERRIDE { 50 stored_group_ = group; 51 stored_group_success_ = success; 52 } 53 54 virtual void OnGroupMadeObsolete(AppCacheGroup* group, 55 bool success, 56 int response_code) OVERRIDE { 57 obsoleted_group_ = group; 58 obsoleted_success_ = success; 59 } 60 61 virtual void OnMainResponseFound(const GURL& url, 62 const AppCacheEntry& entry, 63 const GURL& fallback_url, 64 const AppCacheEntry& fallback_entry, 65 int64 cache_id, 66 int64 group_id, 67 const GURL& manifest_url) OVERRIDE { 68 found_url_ = url; 69 found_entry_ = entry; 70 found_fallback_url_ = fallback_url; 71 found_fallback_entry_ = fallback_entry; 72 found_cache_id_ = cache_id; 73 found_manifest_url_ = manifest_url; 74 } 75 76 scoped_refptr<AppCache> loaded_cache_; 77 int64 loaded_cache_id_; 78 scoped_refptr<AppCacheGroup> loaded_group_; 79 GURL loaded_manifest_url_; 80 scoped_refptr<AppCacheGroup> stored_group_; 81 bool stored_group_success_; 82 scoped_refptr<AppCacheGroup> obsoleted_group_; 83 bool obsoleted_success_; 84 GURL found_url_; 85 AppCacheEntry found_entry_; 86 GURL found_fallback_url_; 87 AppCacheEntry found_fallback_entry_; 88 int64 found_cache_id_; 89 GURL found_manifest_url_; 90 }; 91 92 private: 93 base::MessageLoop message_loop_; 94}; 95 96TEST_F(MockAppCacheStorageTest, LoadCache_Miss) { 97 // Attempt to load a cache that doesn't exist. Should 98 // complete asyncly. 99 MockAppCacheService service; 100 MockStorageDelegate delegate; 101 service.storage()->LoadCache(111, &delegate); 102 EXPECT_NE(111, delegate.loaded_cache_id_); 103 base::RunLoop().RunUntilIdle(); // Do async task execution. 104 EXPECT_EQ(111, delegate.loaded_cache_id_); 105 EXPECT_FALSE(delegate.loaded_cache_.get()); 106} 107 108TEST_F(MockAppCacheStorageTest, LoadCache_NearHit) { 109 // Attempt to load a cache that is currently in use 110 // and does not require loading from disk. This 111 // load should complete syncly. 112 MockAppCacheService service; 113 114 // Setup some preconditions. Make an 'unstored' cache for 115 // us to load. The ctor should put it in the working set. 116 int64 cache_id = service.storage()->NewCacheId(); 117 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 118 119 // Conduct the test. 120 MockStorageDelegate delegate; 121 service.storage()->LoadCache(cache_id, &delegate); 122 EXPECT_EQ(cache_id, delegate.loaded_cache_id_); 123 EXPECT_EQ(cache.get(), delegate.loaded_cache_.get()); 124} 125 126TEST_F(MockAppCacheStorageTest, CreateGroup) { 127 // Attempt to load/create a group that doesn't exist. 128 // Should complete asyncly. 129 MockAppCacheService service; 130 MockAppCacheStorage* storage = 131 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 132 MockStorageDelegate delegate; 133 GURL manifest_url("http://blah/"); 134 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); 135 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); 136 EXPECT_FALSE(delegate.loaded_group_.get()); 137 base::RunLoop().RunUntilIdle(); // Do async task execution. 138 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); 139 EXPECT_TRUE(delegate.loaded_group_.get()); 140 EXPECT_TRUE(delegate.loaded_group_->HasOneRef()); 141 EXPECT_FALSE(delegate.loaded_group_->newest_complete_cache()); 142 EXPECT_TRUE(storage->stored_groups_.empty()); 143} 144 145TEST_F(MockAppCacheStorageTest, LoadGroup_NearHit) { 146 // Attempt to load a group that is currently in use 147 // and does not require loading from disk. This 148 // load should complete syncly. 149 MockAppCacheService service; 150 MockStorageDelegate delegate; 151 152 // Setup some preconditions. Create a group that appears 153 // to be "unstored" and "currently in use". 154 GURL manifest_url("http://blah/"); 155 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); 156 base::RunLoop().RunUntilIdle(); // Do async task execution. 157 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); 158 EXPECT_TRUE(delegate.loaded_group_.get()); 159 160 // Reset our delegate, and take a reference to the new group. 161 scoped_refptr<AppCacheGroup> group; 162 group.swap(delegate.loaded_group_); 163 delegate.loaded_manifest_url_ = GURL(); 164 165 // Conduct the test. 166 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); 167 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); 168 EXPECT_EQ(group.get(), delegate.loaded_group_.get()); 169} 170 171TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) { 172 // Attempt to load a cache that is not currently in use 173 // and does require loading from disk. This 174 // load should complete asyncly. 175 MockAppCacheService service; 176 MockAppCacheStorage* storage = 177 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 178 179 // Setup some preconditions. Create a group and newest cache that 180 // appears to be "stored" and "not currently in use". 181 GURL manifest_url("http://blah/"); 182 scoped_refptr<AppCacheGroup> group( 183 new AppCacheGroup(service.storage(), manifest_url, 111)); 184 int64 cache_id = storage->NewCacheId(); 185 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 186 cache->set_complete(true); 187 group->AddCache(cache.get()); 188 storage->AddStoredGroup(group.get()); 189 storage->AddStoredCache(cache.get()); 190 191 // Drop the references from above so the only refs to these 192 // objects are from within the storage class. This is to make 193 // these objects appear as "not currently in use". 194 AppCache* cache_ptr = cache.get(); 195 AppCacheGroup* group_ptr = group.get(); 196 cache = NULL; 197 group = NULL; 198 199 // Setup a delegate to receive completion callbacks. 200 MockStorageDelegate delegate; 201 202 // Conduct the cache load test. 203 EXPECT_NE(cache_id, delegate.loaded_cache_id_); 204 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get()); 205 storage->LoadCache(cache_id, &delegate); 206 EXPECT_NE(cache_id, delegate.loaded_cache_id_); 207 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get()); 208 base::RunLoop().RunUntilIdle(); // Do async task execution. 209 EXPECT_EQ(cache_id, delegate.loaded_cache_id_); 210 EXPECT_EQ(cache_ptr, delegate.loaded_cache_.get()); 211 delegate.loaded_cache_ = NULL; 212 213 // Conduct the group load test. 214 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); 215 EXPECT_FALSE(delegate.loaded_group_.get()); 216 storage->LoadOrCreateGroup(manifest_url, &delegate); 217 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); 218 EXPECT_FALSE(delegate.loaded_group_.get()); 219 base::RunLoop().RunUntilIdle(); // Do async task execution. 220 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); 221 EXPECT_EQ(group_ptr, delegate.loaded_group_.get()); 222} 223 224TEST_F(MockAppCacheStorageTest, StoreNewGroup) { 225 // Store a group and its newest cache. Should complete asyncly. 226 MockAppCacheService service; 227 MockAppCacheStorage* storage = 228 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 229 230 // Setup some preconditions. Create a group and newest cache that 231 // appears to be "unstored". 232 GURL manifest_url("http://blah/"); 233 scoped_refptr<AppCacheGroup> group( 234 new AppCacheGroup(service.storage(), manifest_url, 111)); 235 int64 cache_id = storage->NewCacheId(); 236 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 237 // Hold a ref to the cache simulate the UpdateJob holding that ref, 238 // and hold a ref to the group to simulate the CacheHost holding that ref. 239 240 // Conduct the store test. 241 MockStorageDelegate delegate; 242 EXPECT_TRUE(storage->stored_caches_.empty()); 243 EXPECT_TRUE(storage->stored_groups_.empty()); 244 storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate); 245 EXPECT_FALSE(delegate.stored_group_success_); 246 EXPECT_TRUE(storage->stored_caches_.empty()); 247 EXPECT_TRUE(storage->stored_groups_.empty()); 248 base::RunLoop().RunUntilIdle(); // Do async task execution. 249 EXPECT_TRUE(delegate.stored_group_success_); 250 EXPECT_FALSE(storage->stored_caches_.empty()); 251 EXPECT_FALSE(storage->stored_groups_.empty()); 252 EXPECT_EQ(cache, group->newest_complete_cache()); 253 EXPECT_TRUE(cache->is_complete()); 254} 255 256TEST_F(MockAppCacheStorageTest, StoreExistingGroup) { 257 // Store a group and its newest cache. Should complete asyncly. 258 MockAppCacheService service; 259 MockAppCacheStorage* storage = 260 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 261 262 // Setup some preconditions. Create a group and old complete cache 263 // that appear to be "stored", and a newest unstored complete cache. 264 GURL manifest_url("http://blah/"); 265 scoped_refptr<AppCacheGroup> group( 266 new AppCacheGroup(service.storage(), manifest_url, 111)); 267 int64 old_cache_id = storage->NewCacheId(); 268 scoped_refptr<AppCache> old_cache( 269 new AppCache(service.storage(), old_cache_id)); 270 old_cache->set_complete(true); 271 group->AddCache(old_cache.get()); 272 storage->AddStoredGroup(group.get()); 273 storage->AddStoredCache(old_cache.get()); 274 int64 new_cache_id = storage->NewCacheId(); 275 scoped_refptr<AppCache> new_cache( 276 new AppCache(service.storage(), new_cache_id)); 277 // Hold our refs to simulate the UpdateJob holding these refs. 278 279 // Conduct the test. 280 MockStorageDelegate delegate; 281 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 282 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 283 EXPECT_TRUE(storage->IsCacheStored(old_cache.get())); 284 EXPECT_FALSE(storage->IsCacheStored(new_cache.get())); 285 storage->StoreGroupAndNewestCache(group.get(), new_cache.get(), &delegate); 286 EXPECT_FALSE(delegate.stored_group_success_); 287 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 288 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 289 EXPECT_TRUE(storage->IsCacheStored(old_cache.get())); 290 EXPECT_FALSE(storage->IsCacheStored(new_cache.get())); 291 base::RunLoop().RunUntilIdle(); // Do async task execution. 292 EXPECT_TRUE(delegate.stored_group_success_); 293 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 294 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 295 EXPECT_FALSE(storage->IsCacheStored(old_cache.get())); 296 EXPECT_TRUE(storage->IsCacheStored(new_cache.get())); 297 EXPECT_EQ(new_cache.get(), group->newest_complete_cache()); 298 EXPECT_TRUE(new_cache->is_complete()); 299} 300 301TEST_F(MockAppCacheStorageTest, StoreExistingGroupExistingCache) { 302 // Store a group with updates to its existing newest complete cache. 303 MockAppCacheService service; 304 MockAppCacheStorage* storage = 305 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 306 307 // Setup some preconditions. Create a group and a complete cache that 308 // appear to be "stored". 309 GURL manifest_url("http://blah"); 310 scoped_refptr<AppCacheGroup> group( 311 new AppCacheGroup(service.storage(), manifest_url, 111)); 312 int64 cache_id = storage->NewCacheId(); 313 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 314 cache->set_complete(true); 315 group->AddCache(cache.get()); 316 storage->AddStoredGroup(group.get()); 317 storage->AddStoredCache(cache.get()); 318 // Hold our refs to simulate the UpdateJob holding these refs. 319 320 // Change the group's newest cache. 321 EXPECT_EQ(cache, group->newest_complete_cache()); 322 GURL entry_url("http://blah/blah"); 323 cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::MASTER)); 324 325 // Conduct the test. 326 MockStorageDelegate delegate; 327 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 328 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 329 EXPECT_TRUE(storage->IsCacheStored(cache.get())); 330 storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate); 331 EXPECT_FALSE(delegate.stored_group_success_); 332 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 333 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 334 base::RunLoop().RunUntilIdle(); // Do async task execution. 335 EXPECT_TRUE(delegate.stored_group_success_); 336 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 337 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 338 EXPECT_TRUE(storage->IsCacheStored(cache.get())); 339 EXPECT_EQ(cache, group->newest_complete_cache()); 340 EXPECT_TRUE(cache->GetEntry(entry_url)); 341} 342 343TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) { 344 // Make a group obsolete, should complete asyncly. 345 MockAppCacheService service; 346 MockAppCacheStorage* storage = 347 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 348 349 // Setup some preconditions. Create a group and newest cache that 350 // appears to be "stored" and "currently in use". 351 GURL manifest_url("http://blah/"); 352 scoped_refptr<AppCacheGroup> group( 353 new AppCacheGroup(service.storage(), manifest_url, 111)); 354 int64 cache_id = storage->NewCacheId(); 355 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 356 cache->set_complete(true); 357 group->AddCache(cache.get()); 358 storage->AddStoredGroup(group.get()); 359 storage->AddStoredCache(cache.get()); 360 // Hold our refs to simulate the UpdateJob holding these refs. 361 362 // Conduct the test. 363 MockStorageDelegate delegate; 364 EXPECT_FALSE(group->is_obsolete()); 365 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 366 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 367 EXPECT_FALSE(cache->HasOneRef()); 368 EXPECT_FALSE(group->HasOneRef()); 369 storage->MakeGroupObsolete(group.get(), &delegate, 0); 370 EXPECT_FALSE(group->is_obsolete()); 371 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); 372 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); 373 EXPECT_FALSE(cache->HasOneRef()); 374 EXPECT_FALSE(group->HasOneRef()); 375 base::RunLoop().RunUntilIdle(); // Do async task execution. 376 EXPECT_TRUE(delegate.obsoleted_success_); 377 EXPECT_EQ(group.get(), delegate.obsoleted_group_.get()); 378 EXPECT_TRUE(group->is_obsolete()); 379 EXPECT_TRUE(storage->stored_caches_.empty()); 380 EXPECT_TRUE(storage->stored_groups_.empty()); 381 EXPECT_TRUE(cache->HasOneRef()); 382 EXPECT_FALSE(group->HasOneRef()); 383 delegate.obsoleted_group_ = NULL; 384 cache = NULL; 385 EXPECT_TRUE(group->HasOneRef()); 386} 387 388TEST_F(MockAppCacheStorageTest, MarkEntryAsForeign) { 389 // Should complete syncly. 390 MockAppCacheService service; 391 MockAppCacheStorage* storage = 392 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 393 394 // Setup some preconditions. Create a cache with an entry. 395 GURL entry_url("http://blah/entry"); 396 int64 cache_id = storage->NewCacheId(); 397 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id)); 398 cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::EXPLICIT)); 399 400 // Conduct the test. 401 MockStorageDelegate delegate; 402 EXPECT_FALSE(cache->GetEntry(entry_url)->IsForeign()); 403 storage->MarkEntryAsForeign(entry_url, cache_id); 404 EXPECT_TRUE(cache->GetEntry(entry_url)->IsForeign()); 405 EXPECT_TRUE(cache->GetEntry(entry_url)->IsExplicit()); 406} 407 408TEST_F(MockAppCacheStorageTest, FindNoMainResponse) { 409 // Should complete asyncly. 410 MockAppCacheService service; 411 MockAppCacheStorage* storage = 412 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 413 414 // Conduct the test. 415 MockStorageDelegate delegate; 416 GURL url("http://blah/some_url"); 417 EXPECT_NE(url, delegate.found_url_); 418 storage->FindResponseForMainRequest(url, GURL(), &delegate); 419 EXPECT_NE(url, delegate.found_url_); 420 base::RunLoop().RunUntilIdle(); // Do async task execution. 421 EXPECT_EQ(url, delegate.found_url_); 422 EXPECT_TRUE(delegate.found_manifest_url_.is_empty()); 423 EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_); 424 EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id()); 425 EXPECT_EQ(kAppCacheNoResponseId, 426 delegate.found_fallback_entry_.response_id()); 427 EXPECT_TRUE(delegate.found_fallback_url_.is_empty()); 428 EXPECT_EQ(0, delegate.found_entry_.types()); 429 EXPECT_EQ(0, delegate.found_fallback_entry_.types()); 430} 431 432TEST_F(MockAppCacheStorageTest, BasicFindMainResponse) { 433 // Should complete asyncly. 434 MockAppCacheService service; 435 MockAppCacheStorage* storage = 436 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 437 438 // Setup some preconditions. Create a complete cache with an entry. 439 const int64 kCacheId = storage->NewCacheId(); 440 const GURL kEntryUrl("http://blah/entry"); 441 const GURL kManifestUrl("http://blah/manifest"); 442 const int64 kResponseId = 1; 443 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId)); 444 cache->AddEntry( 445 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId)); 446 cache->set_complete(true); 447 scoped_refptr<AppCacheGroup> group( 448 new AppCacheGroup(service.storage(), kManifestUrl, 111)); 449 group->AddCache(cache.get()); 450 storage->AddStoredGroup(group.get()); 451 storage->AddStoredCache(cache.get()); 452 453 // Conduct the test. 454 MockStorageDelegate delegate; 455 EXPECT_NE(kEntryUrl, delegate.found_url_); 456 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate); 457 EXPECT_NE(kEntryUrl, delegate.found_url_); 458 base::RunLoop().RunUntilIdle(); // Do async task execution. 459 EXPECT_EQ(kEntryUrl, delegate.found_url_); 460 EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_); 461 EXPECT_EQ(kCacheId, delegate.found_cache_id_); 462 EXPECT_EQ(kResponseId, delegate.found_entry_.response_id()); 463 EXPECT_TRUE(delegate.found_entry_.IsExplicit()); 464 EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id()); 465} 466 467TEST_F(MockAppCacheStorageTest, BasicFindMainFallbackResponse) { 468 // Should complete asyncly. 469 MockAppCacheService service; 470 MockAppCacheStorage* storage = 471 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 472 473 // Setup some preconditions. Create a complete cache with a 474 // fallback namespace and entry. 475 const int64 kCacheId = storage->NewCacheId(); 476 const GURL kFallbackEntryUrl1("http://blah/fallback_entry1"); 477 const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/"); 478 const GURL kFallbackEntryUrl2("http://blah/fallback_entry2"); 479 const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer"); 480 const GURL kManifestUrl("http://blah/manifest"); 481 const int64 kResponseId1 = 1; 482 const int64 kResponseId2 = 2; 483 484 Manifest manifest; 485 manifest.fallback_namespaces.push_back( 486 Namespace(APPCACHE_FALLBACK_NAMESPACE, kFallbackNamespaceUrl1, 487 kFallbackEntryUrl1, false)); 488 manifest.fallback_namespaces.push_back( 489 Namespace(APPCACHE_FALLBACK_NAMESPACE, kFallbackNamespaceUrl2, 490 kFallbackEntryUrl2, false)); 491 492 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId)); 493 cache->InitializeWithManifest(&manifest); 494 cache->AddEntry(kFallbackEntryUrl1, 495 AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId1)); 496 cache->AddEntry(kFallbackEntryUrl2, 497 AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId2)); 498 cache->set_complete(true); 499 500 scoped_refptr<AppCacheGroup> group( 501 new AppCacheGroup(service.storage(), kManifestUrl, 111)); 502 group->AddCache(cache.get()); 503 storage->AddStoredGroup(group.get()); 504 storage->AddStoredCache(cache.get()); 505 506 // The test url is in both fallback namespace urls, but should match 507 // the longer of the two. 508 const GURL kTestUrl("http://blah/fallback_namespace/longer/test"); 509 510 // Conduct the test. 511 MockStorageDelegate delegate; 512 EXPECT_NE(kTestUrl, delegate.found_url_); 513 storage->FindResponseForMainRequest(kTestUrl, GURL(), &delegate); 514 EXPECT_NE(kTestUrl, delegate.found_url_); 515 base::RunLoop().RunUntilIdle(); // Do async task execution. 516 EXPECT_EQ(kTestUrl, delegate.found_url_); 517 EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_); 518 EXPECT_EQ(kCacheId, delegate.found_cache_id_); 519 EXPECT_FALSE(delegate.found_entry_.has_response_id()); 520 EXPECT_EQ(kResponseId2, delegate.found_fallback_entry_.response_id()); 521 EXPECT_EQ(kFallbackEntryUrl2, delegate.found_fallback_url_); 522 EXPECT_TRUE(delegate.found_fallback_entry_.IsFallback()); 523} 524 525TEST_F(MockAppCacheStorageTest, FindMainResponseWithMultipleCandidates) { 526 // Should complete asyncly. 527 MockAppCacheService service; 528 MockAppCacheStorage* storage = 529 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 530 531 // Setup some preconditions. Create 2 complete caches with an entry 532 // for the same url. 533 534 const GURL kEntryUrl("http://blah/entry"); 535 const int64 kCacheId1 = storage->NewCacheId(); 536 const int64 kCacheId2 = storage->NewCacheId(); 537 const GURL kManifestUrl1("http://blah/manifest1"); 538 const GURL kManifestUrl2("http://blah/manifest2"); 539 const int64 kResponseId1 = 1; 540 const int64 kResponseId2 = 2; 541 542 // The first cache. 543 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId1)); 544 cache->AddEntry( 545 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId1)); 546 cache->set_complete(true); 547 scoped_refptr<AppCacheGroup> group( 548 new AppCacheGroup(service.storage(), kManifestUrl1, 111)); 549 group->AddCache(cache.get()); 550 storage->AddStoredGroup(group.get()); 551 storage->AddStoredCache(cache.get()); 552 // Drop our references to cache1 so it appears as "not in use". 553 cache = NULL; 554 group = NULL; 555 556 // The second cache. 557 cache = new AppCache(service.storage(), kCacheId2); 558 cache->AddEntry( 559 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId2)); 560 cache->set_complete(true); 561 group = new AppCacheGroup(service.storage(), kManifestUrl2, 222); 562 group->AddCache(cache.get()); 563 storage->AddStoredGroup(group.get()); 564 storage->AddStoredCache(cache.get()); 565 566 // Conduct the test, we should find the response from the second cache 567 // since it's "in use". 568 MockStorageDelegate delegate; 569 EXPECT_NE(kEntryUrl, delegate.found_url_); 570 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate); 571 EXPECT_NE(kEntryUrl, delegate.found_url_); 572 base::RunLoop().RunUntilIdle(); // Do async task execution. 573 EXPECT_EQ(kEntryUrl, delegate.found_url_); 574 EXPECT_EQ(kManifestUrl2, delegate.found_manifest_url_); 575 EXPECT_EQ(kCacheId2, delegate.found_cache_id_); 576 EXPECT_EQ(kResponseId2, delegate.found_entry_.response_id()); 577 EXPECT_TRUE(delegate.found_entry_.IsExplicit()); 578 EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id()); 579} 580 581TEST_F(MockAppCacheStorageTest, FindMainResponseExclusions) { 582 // Should complete asyncly. 583 MockAppCacheService service; 584 MockAppCacheStorage* storage = 585 reinterpret_cast<MockAppCacheStorage*>(service.storage()); 586 587 // Setup some preconditions. Create a complete cache with a 588 // foreign entry and an online namespace. 589 590 const int64 kCacheId = storage->NewCacheId(); 591 const GURL kEntryUrl("http://blah/entry"); 592 const GURL kManifestUrl("http://blah/manifest"); 593 const GURL kOnlineNamespaceUrl("http://blah/online_namespace"); 594 const int64 kResponseId = 1; 595 596 Manifest manifest; 597 manifest.online_whitelist_namespaces.push_back( 598 Namespace(APPCACHE_NETWORK_NAMESPACE, kOnlineNamespaceUrl, 599 GURL(), false)); 600 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId)); 601 cache->InitializeWithManifest(&manifest); 602 cache->AddEntry( 603 kEntryUrl, 604 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 605 kResponseId)); 606 cache->set_complete(true); 607 scoped_refptr<AppCacheGroup> group( 608 new AppCacheGroup(service.storage(), kManifestUrl, 111)); 609 group->AddCache(cache.get()); 610 storage->AddStoredGroup(group.get()); 611 storage->AddStoredCache(cache.get()); 612 613 MockStorageDelegate delegate; 614 615 // We should not find anything for the foreign entry. 616 EXPECT_NE(kEntryUrl, delegate.found_url_); 617 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate); 618 EXPECT_NE(kEntryUrl, delegate.found_url_); 619 base::RunLoop().RunUntilIdle(); // Do async task execution. 620 EXPECT_EQ(kEntryUrl, delegate.found_url_); 621 EXPECT_TRUE(delegate.found_manifest_url_.is_empty()); 622 EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_); 623 EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id()); 624 EXPECT_EQ(kAppCacheNoResponseId, 625 delegate.found_fallback_entry_.response_id()); 626 EXPECT_TRUE(delegate.found_fallback_url_.is_empty()); 627 EXPECT_EQ(0, delegate.found_entry_.types()); 628 EXPECT_EQ(0, delegate.found_fallback_entry_.types()); 629 630 // We should not find anything for the online namespace. 631 EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_); 632 storage->FindResponseForMainRequest(kOnlineNamespaceUrl, GURL(), &delegate); 633 EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_); 634 base::RunLoop().RunUntilIdle(); // Do async task execution. 635 EXPECT_EQ(kOnlineNamespaceUrl, delegate.found_url_); 636 EXPECT_TRUE(delegate.found_manifest_url_.is_empty()); 637 EXPECT_EQ(kAppCacheNoCacheId, delegate.found_cache_id_); 638 EXPECT_EQ(kAppCacheNoResponseId, delegate.found_entry_.response_id()); 639 EXPECT_EQ(kAppCacheNoResponseId, 640 delegate.found_fallback_entry_.response_id()); 641 EXPECT_TRUE(delegate.found_fallback_url_.is_empty()); 642 EXPECT_EQ(0, delegate.found_entry_.types()); 643 EXPECT_EQ(0, delegate.found_fallback_entry_.types()); 644} 645 646} // namespace content 647