1 // Copyright (c) 2012 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 <stack> 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/callback.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/synchronization/waitable_event.h" 12 #include "base/threading/thread.h" 13 #include "net/base/net_errors.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "webkit/browser/appcache/appcache.h" 16 #include "webkit/browser/appcache/appcache_database.h" 17 #include "webkit/browser/appcache/appcache_entry.h" 18 #include "webkit/browser/appcache/appcache_group.h" 19 #include "webkit/browser/appcache/appcache_service.h" 20 #include "webkit/browser/appcache/appcache_storage_impl.h" 21 #include "webkit/browser/quota/quota_manager.h" 22 23 namespace appcache { 24 25 namespace { 26 27 const base::Time kZeroTime; 28 const GURL kManifestUrl("http://blah/manifest"); 29 const GURL kManifestUrl2("http://blah/manifest2"); 30 const GURL kManifestUrl3("http://blah/manifest3"); 31 const GURL kEntryUrl("http://blah/entry"); 32 const GURL kEntryUrl2("http://blah/entry2"); 33 const GURL kFallbackNamespace("http://blah/fallback_namespace/"); 34 const GURL kFallbackNamespace2("http://blah/fallback_namespace/longer"); 35 const GURL kFallbackTestUrl("http://blah/fallback_namespace/longer/test"); 36 const GURL kOnlineNamespace("http://blah/online_namespace"); 37 const GURL kOnlineNamespaceWithinFallback( 38 "http://blah/fallback_namespace/online/"); 39 const GURL kInterceptNamespace("http://blah/intercept_namespace/"); 40 const GURL kInterceptNamespace2("http://blah/intercept_namespace/longer/"); 41 const GURL kInterceptTestUrl("http://blah/intercept_namespace/longer/test"); 42 const GURL kInterceptPatternNamespace("http://blah/intercept_pattern/*/bar"); 43 const GURL kInterceptPatternTestPositiveUrl( 44 "http://blah/intercept_pattern/foo/bar"); 45 const GURL kInterceptPatternTestNegativeUrl( 46 "http://blah/intercept_pattern/foo/not_bar"); 47 const GURL kFallbackPatternNamespace("http://blah/fallback_pattern/*/bar"); 48 const GURL kFallbackPatternTestPositiveUrl( 49 "http://blah/fallback_pattern/foo/bar"); 50 const GURL kFallbackPatternTestNegativeUrl( 51 "http://blah/fallback_pattern/foo/not_bar"); 52 const GURL kOrigin(kManifestUrl.GetOrigin()); 53 54 const int kManifestEntryIdOffset = 100; 55 const int kFallbackEntryIdOffset = 1000; 56 57 const GURL kDefaultEntryUrl("http://blah/makecacheandgroup_default_entry"); 58 const int kDefaultEntrySize = 10; 59 const int kDefaultEntryIdOffset = 12345; 60 61 const int kMockQuota = 5000; 62 63 scoped_ptr<base::Thread> io_thread; 64 scoped_ptr<base::Thread> db_thread; 65 66 } // namespace 67 68 class AppCacheStorageImplTest : public testing::Test { 69 public: 70 class MockStorageDelegate : public AppCacheStorage::Delegate { 71 public: 72 explicit MockStorageDelegate(AppCacheStorageImplTest* test) 73 : loaded_cache_id_(0), stored_group_success_(false), 74 would_exceed_quota_(false), obsoleted_success_(false), 75 found_cache_id_(kNoCacheId), test_(test) { 76 } 77 78 virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE { 79 loaded_cache_ = cache; 80 loaded_cache_id_ = cache_id; 81 test_->ScheduleNextTask(); 82 } 83 84 virtual void OnGroupLoaded(AppCacheGroup* group, 85 const GURL& manifest_url) OVERRIDE { 86 loaded_group_ = group; 87 loaded_manifest_url_ = manifest_url; 88 loaded_groups_newest_cache_ = group ? group->newest_complete_cache() 89 : NULL; 90 test_->ScheduleNextTask(); 91 } 92 93 virtual void OnGroupAndNewestCacheStored( 94 AppCacheGroup* group, AppCache* newest_cache, bool success, 95 bool would_exceed_quota) OVERRIDE { 96 stored_group_ = group; 97 stored_group_success_ = success; 98 would_exceed_quota_ = would_exceed_quota; 99 test_->ScheduleNextTask(); 100 } 101 102 virtual void OnGroupMadeObsolete(AppCacheGroup* group, 103 bool success) OVERRIDE { 104 obsoleted_group_ = group; 105 obsoleted_success_ = success; 106 test_->ScheduleNextTask(); 107 } 108 109 virtual void OnMainResponseFound(const GURL& url, 110 const AppCacheEntry& entry, 111 const GURL& namespace_entry_url, 112 const AppCacheEntry& fallback_entry, 113 int64 cache_id, 114 int64 group_id, 115 const GURL& manifest_url) OVERRIDE { 116 found_url_ = url; 117 found_entry_ = entry; 118 found_namespace_entry_url_ = namespace_entry_url; 119 found_fallback_entry_ = fallback_entry; 120 found_cache_id_ = cache_id; 121 found_group_id_ = group_id; 122 found_manifest_url_ = manifest_url; 123 test_->ScheduleNextTask(); 124 } 125 126 scoped_refptr<AppCache> loaded_cache_; 127 int64 loaded_cache_id_; 128 scoped_refptr<AppCacheGroup> loaded_group_; 129 GURL loaded_manifest_url_; 130 scoped_refptr<AppCache> loaded_groups_newest_cache_; 131 scoped_refptr<AppCacheGroup> stored_group_; 132 bool stored_group_success_; 133 bool would_exceed_quota_; 134 scoped_refptr<AppCacheGroup> obsoleted_group_; 135 bool obsoleted_success_; 136 GURL found_url_; 137 AppCacheEntry found_entry_; 138 GURL found_namespace_entry_url_; 139 AppCacheEntry found_fallback_entry_; 140 int64 found_cache_id_; 141 int64 found_group_id_; 142 GURL found_manifest_url_; 143 AppCacheStorageImplTest* test_; 144 }; 145 146 class MockQuotaManager : public quota::QuotaManager { 147 public: 148 MockQuotaManager() 149 : QuotaManager(true /* is_incognito */, 150 base::FilePath(), 151 io_thread->message_loop_proxy().get(), 152 db_thread->message_loop_proxy().get(), 153 NULL), 154 async_(false) {} 155 156 virtual void GetUsageAndQuota( 157 const GURL& origin, 158 quota::StorageType type, 159 const GetUsageAndQuotaCallback& callback) OVERRIDE { 160 EXPECT_EQ(kOrigin, origin); 161 EXPECT_EQ(quota::kStorageTypeTemporary, type); 162 if (async_) { 163 base::MessageLoop::current()->PostTask( 164 FROM_HERE, 165 base::Bind(&MockQuotaManager::CallCallback, 166 base::Unretained(this), 167 callback)); 168 return; 169 } 170 CallCallback(callback); 171 } 172 173 void CallCallback(const GetUsageAndQuotaCallback& callback) { 174 callback.Run(quota::kQuotaStatusOk, 0, kMockQuota); 175 } 176 177 bool async_; 178 179 protected: 180 virtual ~MockQuotaManager() {} 181 }; 182 183 class MockQuotaManagerProxy : public quota::QuotaManagerProxy { 184 public: 185 MockQuotaManagerProxy() 186 : QuotaManagerProxy(NULL, NULL), 187 notify_storage_accessed_count_(0), 188 notify_storage_modified_count_(0), 189 last_delta_(0), 190 mock_manager_(new MockQuotaManager) { 191 manager_ = mock_manager_.get(); 192 } 193 194 virtual void NotifyStorageAccessed(quota::QuotaClient::ID client_id, 195 const GURL& origin, 196 quota::StorageType type) OVERRIDE { 197 EXPECT_EQ(quota::QuotaClient::kAppcache, client_id); 198 EXPECT_EQ(quota::kStorageTypeTemporary, type); 199 ++notify_storage_accessed_count_; 200 last_origin_ = origin; 201 } 202 203 virtual void NotifyStorageModified(quota::QuotaClient::ID client_id, 204 const GURL& origin, 205 quota::StorageType type, 206 int64 delta) OVERRIDE { 207 EXPECT_EQ(quota::QuotaClient::kAppcache, client_id); 208 EXPECT_EQ(quota::kStorageTypeTemporary, type); 209 ++notify_storage_modified_count_; 210 last_origin_ = origin; 211 last_delta_ = delta; 212 } 213 214 // Not needed for our tests. 215 virtual void RegisterClient(quota::QuotaClient* client) OVERRIDE {} 216 virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {} 217 virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {} 218 219 int notify_storage_accessed_count_; 220 int notify_storage_modified_count_; 221 GURL last_origin_; 222 int last_delta_; 223 scoped_refptr<MockQuotaManager> mock_manager_; 224 225 protected: 226 virtual ~MockQuotaManagerProxy() {} 227 }; 228 229 template <class Method> 230 void RunMethod(Method method) { 231 (this->*method)(); 232 } 233 234 // Helper callback to run a test on our io_thread. The io_thread is spun up 235 // once and reused for all tests. 236 template <class Method> 237 void MethodWrapper(Method method) { 238 SetUpTest(); 239 240 // Ensure InitTask execution prior to conducting a test. 241 FlushDbThreadTasks(); 242 243 // We also have to wait for InitTask completion call to be performed 244 // on the IO thread prior to running the test. Its guaranteed to be 245 // queued by this time. 246 base::MessageLoop::current()->PostTask( 247 FROM_HERE, 248 base::Bind(&AppCacheStorageImplTest::RunMethod<Method>, 249 base::Unretained(this), 250 method)); 251 } 252 253 static void SetUpTestCase() { 254 io_thread.reset(new base::Thread("AppCacheTest.IOThread")); 255 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); 256 ASSERT_TRUE(io_thread->StartWithOptions(options)); 257 258 db_thread.reset(new base::Thread("AppCacheTest::DBThread")); 259 ASSERT_TRUE(db_thread->Start()); 260 } 261 262 static void TearDownTestCase() { 263 io_thread.reset(NULL); 264 db_thread.reset(NULL); 265 } 266 267 // Test harness -------------------------------------------------- 268 269 AppCacheStorageImplTest() { 270 } 271 272 template <class Method> 273 void RunTestOnIOThread(Method method) { 274 test_finished_event_ .reset(new base::WaitableEvent(false, false)); 275 io_thread->message_loop()->PostTask( 276 FROM_HERE, base::Bind(&AppCacheStorageImplTest::MethodWrapper<Method>, 277 base::Unretained(this), method)); 278 test_finished_event_->Wait(); 279 } 280 281 void SetUpTest() { 282 DCHECK(base::MessageLoop::current() == io_thread->message_loop()); 283 service_.reset(new AppCacheService(NULL)); 284 service_->Initialize( 285 base::FilePath(), db_thread->message_loop_proxy().get(), NULL); 286 mock_quota_manager_proxy_ = new MockQuotaManagerProxy(); 287 service_->quota_manager_proxy_ = mock_quota_manager_proxy_; 288 delegate_.reset(new MockStorageDelegate(this)); 289 } 290 291 void TearDownTest() { 292 DCHECK(base::MessageLoop::current() == io_thread->message_loop()); 293 storage()->CancelDelegateCallbacks(delegate()); 294 group_ = NULL; 295 cache_ = NULL; 296 cache2_ = NULL; 297 mock_quota_manager_proxy_ = NULL; 298 delegate_.reset(); 299 service_.reset(); 300 FlushDbThreadTasks(); 301 } 302 303 void TestFinished() { 304 // We unwind the stack prior to finishing up to let stack 305 // based objects get deleted. 306 DCHECK(base::MessageLoop::current() == io_thread->message_loop()); 307 base::MessageLoop::current()->PostTask( 308 FROM_HERE, 309 base::Bind(&AppCacheStorageImplTest::TestFinishedUnwound, 310 base::Unretained(this))); 311 } 312 313 void TestFinishedUnwound() { 314 TearDownTest(); 315 test_finished_event_->Signal(); 316 } 317 318 void PushNextTask(const base::Closure& task) { 319 task_stack_.push(task); 320 } 321 322 void ScheduleNextTask() { 323 DCHECK(base::MessageLoop::current() == io_thread->message_loop()); 324 if (task_stack_.empty()) { 325 return; 326 } 327 base::MessageLoop::current()->PostTask(FROM_HERE, task_stack_.top()); 328 task_stack_.pop(); 329 } 330 331 static void SignalEvent(base::WaitableEvent* event) { 332 event->Signal(); 333 } 334 335 void FlushDbThreadTasks() { 336 // We pump a task thru the db thread to ensure any tasks previously 337 // scheduled on that thread have been performed prior to return. 338 base::WaitableEvent event(false, false); 339 db_thread->message_loop()->PostTask( 340 FROM_HERE, base::Bind(&AppCacheStorageImplTest::SignalEvent, &event)); 341 event.Wait(); 342 } 343 344 // LoadCache_Miss ---------------------------------------------------- 345 346 void LoadCache_Miss() { 347 // Attempt to load a cache that doesn't exist. Should 348 // complete asynchronously. 349 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_LoadCache_Miss, 350 base::Unretained(this))); 351 352 storage()->LoadCache(111, delegate()); 353 EXPECT_NE(111, delegate()->loaded_cache_id_); 354 } 355 356 void Verify_LoadCache_Miss() { 357 EXPECT_EQ(111, delegate()->loaded_cache_id_); 358 EXPECT_FALSE(delegate()->loaded_cache_.get()); 359 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_accessed_count_); 360 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 361 TestFinished(); 362 } 363 364 // LoadCache_NearHit ------------------------------------------------- 365 366 void LoadCache_NearHit() { 367 // Attempt to load a cache that is currently in use 368 // and does not require loading from storage. This 369 // load should complete syncly. 370 371 // Setup some preconditions. Make an 'unstored' cache for 372 // us to load. The ctor should put it in the working set. 373 int64 cache_id = storage()->NewCacheId(); 374 scoped_refptr<AppCache> cache(new AppCache(storage(), cache_id)); 375 376 // Conduct the test. 377 storage()->LoadCache(cache_id, delegate()); 378 EXPECT_EQ(cache_id, delegate()->loaded_cache_id_); 379 EXPECT_EQ(cache.get(), delegate()->loaded_cache_.get()); 380 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_accessed_count_); 381 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 382 TestFinished(); 383 } 384 385 // CreateGroup -------------------------------------------- 386 387 void CreateGroupInEmptyOrigin() { 388 // Attempt to load a group that doesn't exist, one should 389 // be created for us, but not stored. 390 391 // Since the origin has no groups, the storage class will respond 392 // syncly. 393 storage()->LoadOrCreateGroup(kManifestUrl, delegate()); 394 Verify_CreateGroup(); 395 } 396 397 void CreateGroupInPopulatedOrigin() { 398 // Attempt to load a group that doesn't exist, one should 399 // be created for us, but not stored. 400 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_CreateGroup, 401 base::Unretained(this))); 402 403 // Since the origin has groups, storage class will have to 404 // consult the database and completion will be async. 405 storage()->usage_map_[kOrigin] = kDefaultEntrySize; 406 407 storage()->LoadOrCreateGroup(kManifestUrl, delegate()); 408 EXPECT_FALSE(delegate()->loaded_group_.get()); 409 } 410 411 void Verify_CreateGroup() { 412 EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_); 413 EXPECT_TRUE(delegate()->loaded_group_.get()); 414 EXPECT_TRUE(delegate()->loaded_group_->HasOneRef()); 415 EXPECT_FALSE(delegate()->loaded_group_->newest_complete_cache()); 416 417 // Should not have been stored in the database. 418 AppCacheDatabase::GroupRecord record; 419 EXPECT_FALSE(database()->FindGroup( 420 delegate()->loaded_group_->group_id(), &record)); 421 422 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_accessed_count_); 423 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 424 425 TestFinished(); 426 } 427 428 // LoadGroupAndCache_FarHit -------------------------------------- 429 430 void LoadGroupAndCache_FarHit() { 431 // Attempt to load a cache that is not currently in use 432 // and does require loading from disk. This 433 // load should complete asynchronously. 434 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_LoadCache_Far_Hit, 435 base::Unretained(this))); 436 437 // Setup some preconditions. Create a group and newest cache that 438 // appear to be "stored" and "not currently in use". 439 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 440 group_ = NULL; 441 cache_ = NULL; 442 443 // Conduct the cache load test, completes async 444 storage()->LoadCache(1, delegate()); 445 } 446 447 void Verify_LoadCache_Far_Hit() { 448 EXPECT_TRUE(delegate()->loaded_cache_.get()); 449 EXPECT_TRUE(delegate()->loaded_cache_->HasOneRef()); 450 EXPECT_EQ(1, delegate()->loaded_cache_id_); 451 452 // The group should also have been loaded. 453 EXPECT_TRUE(delegate()->loaded_cache_->owning_group()); 454 EXPECT_TRUE(delegate()->loaded_cache_->owning_group()->HasOneRef()); 455 EXPECT_EQ(1, delegate()->loaded_cache_->owning_group()->group_id()); 456 457 EXPECT_EQ(1, mock_quota_manager_proxy_->notify_storage_accessed_count_); 458 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 459 460 // Drop things from the working set. 461 delegate()->loaded_cache_ = NULL; 462 EXPECT_FALSE(delegate()->loaded_group_.get()); 463 464 // Conduct the group load test, also complete asynchronously. 465 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_LoadGroup_Far_Hit, 466 base::Unretained(this))); 467 468 storage()->LoadOrCreateGroup(kManifestUrl, delegate()); 469 } 470 471 void Verify_LoadGroup_Far_Hit() { 472 EXPECT_TRUE(delegate()->loaded_group_.get()); 473 EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_); 474 EXPECT_TRUE(delegate()->loaded_group_->newest_complete_cache()); 475 delegate()->loaded_groups_newest_cache_ = NULL; 476 EXPECT_TRUE(delegate()->loaded_group_->HasOneRef()); 477 EXPECT_EQ(2, mock_quota_manager_proxy_->notify_storage_accessed_count_); 478 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 479 TestFinished(); 480 } 481 482 // StoreNewGroup -------------------------------------- 483 484 void StoreNewGroup() { 485 // Store a group and its newest cache. Should complete asynchronously. 486 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_StoreNewGroup, 487 base::Unretained(this))); 488 489 // Setup some preconditions. Create a group and newest cache that 490 // appear to be "unstored". 491 group_ = new AppCacheGroup( 492 storage(), kManifestUrl, storage()->NewGroupId()); 493 cache_ = new AppCache(storage(), storage()->NewCacheId()); 494 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1, 495 kDefaultEntrySize)); 496 // Hold a ref to the cache simulate the UpdateJob holding that ref, 497 // and hold a ref to the group to simulate the CacheHost holding that ref. 498 499 // Have the quota manager retrun asynchronously for this test. 500 mock_quota_manager_proxy_->mock_manager_->async_ = true; 501 502 // Conduct the store test. 503 storage()->StoreGroupAndNewestCache(group_.get(), cache_.get(), delegate()); 504 EXPECT_FALSE(delegate()->stored_group_success_); 505 } 506 507 void Verify_StoreNewGroup() { 508 EXPECT_TRUE(delegate()->stored_group_success_); 509 EXPECT_EQ(group_.get(), delegate()->stored_group_.get()); 510 EXPECT_EQ(cache_.get(), group_->newest_complete_cache()); 511 EXPECT_TRUE(cache_->is_complete()); 512 513 // Should have been stored in the database. 514 AppCacheDatabase::GroupRecord group_record; 515 AppCacheDatabase::CacheRecord cache_record; 516 EXPECT_TRUE(database()->FindGroup(group_->group_id(), &group_record)); 517 EXPECT_TRUE(database()->FindCache(cache_->cache_id(), &cache_record)); 518 519 // Verify quota bookkeeping 520 EXPECT_EQ(kDefaultEntrySize, storage()->usage_map_[kOrigin]); 521 EXPECT_EQ(1, mock_quota_manager_proxy_->notify_storage_modified_count_); 522 EXPECT_EQ(kOrigin, mock_quota_manager_proxy_->last_origin_); 523 EXPECT_EQ(kDefaultEntrySize, mock_quota_manager_proxy_->last_delta_); 524 525 TestFinished(); 526 } 527 528 // StoreExistingGroup -------------------------------------- 529 530 void StoreExistingGroup() { 531 // Store a group and its newest cache. Should complete asynchronously. 532 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_StoreExistingGroup, 533 base::Unretained(this))); 534 535 // Setup some preconditions. Create a group and old complete cache 536 // that appear to be "stored" 537 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 538 EXPECT_EQ(kDefaultEntrySize, storage()->usage_map_[kOrigin]); 539 540 // And a newest unstored complete cache. 541 cache2_ = new AppCache(storage(), 2); 542 cache2_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::MASTER, 1, 543 kDefaultEntrySize + 100)); 544 545 // Conduct the test. 546 storage()->StoreGroupAndNewestCache( 547 group_.get(), cache2_.get(), delegate()); 548 EXPECT_FALSE(delegate()->stored_group_success_); 549 } 550 551 void Verify_StoreExistingGroup() { 552 EXPECT_TRUE(delegate()->stored_group_success_); 553 EXPECT_EQ(group_.get(), delegate()->stored_group_.get()); 554 EXPECT_EQ(cache2_.get(), group_->newest_complete_cache()); 555 EXPECT_TRUE(cache2_->is_complete()); 556 557 // The new cache should have been stored in the database. 558 AppCacheDatabase::GroupRecord group_record; 559 AppCacheDatabase::CacheRecord cache_record; 560 EXPECT_TRUE(database()->FindGroup(1, &group_record)); 561 EXPECT_TRUE(database()->FindCache(2, &cache_record)); 562 563 // The old cache should have been deleted 564 EXPECT_FALSE(database()->FindCache(1, &cache_record)); 565 566 // Verify quota bookkeeping 567 EXPECT_EQ(kDefaultEntrySize + 100, storage()->usage_map_[kOrigin]); 568 EXPECT_EQ(1, mock_quota_manager_proxy_->notify_storage_modified_count_); 569 EXPECT_EQ(kOrigin, mock_quota_manager_proxy_->last_origin_); 570 EXPECT_EQ(100, mock_quota_manager_proxy_->last_delta_); 571 572 TestFinished(); 573 } 574 575 // StoreExistingGroupExistingCache ------------------------------- 576 577 void StoreExistingGroupExistingCache() { 578 // Store a group with updates to its existing newest complete cache. 579 // Setup some preconditions. Create a group and a complete cache that 580 // appear to be "stored". 581 582 // Setup some preconditions. Create a group and old complete cache 583 // that appear to be "stored" 584 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 585 EXPECT_EQ(kDefaultEntrySize, storage()->usage_map_[kOrigin]); 586 587 // Change the cache. 588 base::Time now = base::Time::Now(); 589 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::MASTER, 1, 100)); 590 cache_->set_update_time(now); 591 592 PushNextTask(base::Bind( 593 &AppCacheStorageImplTest::Verify_StoreExistingGroupExistingCache, 594 base::Unretained(this), now)); 595 596 // Conduct the test. 597 EXPECT_EQ(cache_, group_->newest_complete_cache()); 598 storage()->StoreGroupAndNewestCache(group_.get(), cache_.get(), delegate()); 599 EXPECT_FALSE(delegate()->stored_group_success_); 600 } 601 602 void Verify_StoreExistingGroupExistingCache( 603 base::Time expected_update_time) { 604 EXPECT_TRUE(delegate()->stored_group_success_); 605 EXPECT_EQ(cache_, group_->newest_complete_cache()); 606 607 AppCacheDatabase::CacheRecord cache_record; 608 EXPECT_TRUE(database()->FindCache(1, &cache_record)); 609 EXPECT_EQ(1, cache_record.cache_id); 610 EXPECT_EQ(1, cache_record.group_id); 611 EXPECT_FALSE(cache_record.online_wildcard); 612 EXPECT_TRUE(expected_update_time == cache_record.update_time); 613 EXPECT_EQ(100 + kDefaultEntrySize, cache_record.cache_size); 614 615 std::vector<AppCacheDatabase::EntryRecord> entry_records; 616 EXPECT_TRUE(database()->FindEntriesForCache(1, &entry_records)); 617 EXPECT_EQ(2U, entry_records.size()); 618 if (entry_records[0].url == kDefaultEntryUrl) 619 entry_records.erase(entry_records.begin()); 620 EXPECT_EQ(1 , entry_records[0].cache_id); 621 EXPECT_EQ(kEntryUrl, entry_records[0].url); 622 EXPECT_EQ(AppCacheEntry::MASTER, entry_records[0].flags); 623 EXPECT_EQ(1, entry_records[0].response_id); 624 EXPECT_EQ(100, entry_records[0].response_size); 625 626 // Verify quota bookkeeping 627 EXPECT_EQ(100 + kDefaultEntrySize, storage()->usage_map_[kOrigin]); 628 EXPECT_EQ(1, mock_quota_manager_proxy_->notify_storage_modified_count_); 629 EXPECT_EQ(kOrigin, mock_quota_manager_proxy_->last_origin_); 630 EXPECT_EQ(100, mock_quota_manager_proxy_->last_delta_); 631 632 TestFinished(); 633 } 634 635 // FailStoreGroup -------------------------------------- 636 637 void FailStoreGroup() { 638 // Store a group and its newest cache. Should complete asynchronously. 639 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_FailStoreGroup, 640 base::Unretained(this))); 641 642 // Setup some preconditions. Create a group and newest cache that 643 // appear to be "unstored" and big enough to exceed the 5M limit. 644 const int64 kTooBig = 10 * 1024 * 1024; // 10M 645 group_ = new AppCacheGroup( 646 storage(), kManifestUrl, storage()->NewGroupId()); 647 cache_ = new AppCache(storage(), storage()->NewCacheId()); 648 cache_->AddEntry(kManifestUrl, 649 AppCacheEntry(AppCacheEntry::MANIFEST, 1, kTooBig)); 650 // Hold a ref to the cache simulate the UpdateJob holding that ref, 651 // and hold a ref to the group to simulate the CacheHost holding that ref. 652 653 // Conduct the store test. 654 storage()->StoreGroupAndNewestCache(group_.get(), cache_.get(), delegate()); 655 EXPECT_FALSE(delegate()->stored_group_success_); // Expected to be async. 656 } 657 658 void Verify_FailStoreGroup() { 659 EXPECT_FALSE(delegate()->stored_group_success_); 660 EXPECT_TRUE(delegate()->would_exceed_quota_); 661 662 // Should not have been stored in the database. 663 AppCacheDatabase::GroupRecord group_record; 664 AppCacheDatabase::CacheRecord cache_record; 665 EXPECT_FALSE(database()->FindGroup(group_->group_id(), &group_record)); 666 EXPECT_FALSE(database()->FindCache(cache_->cache_id(), &cache_record)); 667 668 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_accessed_count_); 669 EXPECT_EQ(0, mock_quota_manager_proxy_->notify_storage_modified_count_); 670 671 TestFinished(); 672 } 673 674 // MakeGroupObsolete ------------------------------- 675 676 void MakeGroupObsolete() { 677 // Make a group obsolete, should complete asynchronously. 678 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_MakeGroupObsolete, 679 base::Unretained(this))); 680 681 // Setup some preconditions. Create a group and newest cache that 682 // appears to be "stored" and "currently in use". 683 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 684 EXPECT_EQ(kDefaultEntrySize, storage()->usage_map_[kOrigin]); 685 686 // Also insert some related records. 687 AppCacheDatabase::EntryRecord entry_record; 688 entry_record.cache_id = 1; 689 entry_record.flags = AppCacheEntry::FALLBACK; 690 entry_record.response_id = 1; 691 entry_record.url = kEntryUrl; 692 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 693 694 AppCacheDatabase::NamespaceRecord fallback_namespace_record; 695 fallback_namespace_record.cache_id = 1; 696 fallback_namespace_record.namespace_.target_url = kEntryUrl; 697 fallback_namespace_record.namespace_.namespace_url = kFallbackNamespace; 698 fallback_namespace_record.origin = kManifestUrl.GetOrigin(); 699 EXPECT_TRUE(database()->InsertNamespace(&fallback_namespace_record)); 700 701 AppCacheDatabase::OnlineWhiteListRecord online_whitelist_record; 702 online_whitelist_record.cache_id = 1; 703 online_whitelist_record.namespace_url = kOnlineNamespace; 704 EXPECT_TRUE(database()->InsertOnlineWhiteList(&online_whitelist_record)); 705 706 // Conduct the test. 707 storage()->MakeGroupObsolete(group_.get(), delegate()); 708 EXPECT_FALSE(group_->is_obsolete()); 709 } 710 711 void Verify_MakeGroupObsolete() { 712 EXPECT_TRUE(delegate()->obsoleted_success_); 713 EXPECT_EQ(group_.get(), delegate()->obsoleted_group_.get()); 714 EXPECT_TRUE(group_->is_obsolete()); 715 EXPECT_TRUE(storage()->usage_map_.empty()); 716 717 // The cache and group have been deleted from the database. 718 AppCacheDatabase::GroupRecord group_record; 719 AppCacheDatabase::CacheRecord cache_record; 720 EXPECT_FALSE(database()->FindGroup(1, &group_record)); 721 EXPECT_FALSE(database()->FindCache(1, &cache_record)); 722 723 // The related records should have been deleted too. 724 std::vector<AppCacheDatabase::EntryRecord> entry_records; 725 database()->FindEntriesForCache(1, &entry_records); 726 EXPECT_TRUE(entry_records.empty()); 727 std::vector<AppCacheDatabase::NamespaceRecord> intercept_records; 728 std::vector<AppCacheDatabase::NamespaceRecord> fallback_records; 729 database()->FindNamespacesForCache( 730 1, &intercept_records, &fallback_records); 731 EXPECT_TRUE(fallback_records.empty()); 732 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelist_records; 733 database()->FindOnlineWhiteListForCache(1, &whitelist_records); 734 EXPECT_TRUE(whitelist_records.empty()); 735 736 // Verify quota bookkeeping 737 EXPECT_TRUE(storage()->usage_map_.empty()); 738 EXPECT_EQ(1, mock_quota_manager_proxy_->notify_storage_modified_count_); 739 EXPECT_EQ(kOrigin, mock_quota_manager_proxy_->last_origin_); 740 EXPECT_EQ(-kDefaultEntrySize, mock_quota_manager_proxy_->last_delta_); 741 742 TestFinished(); 743 } 744 745 // MarkEntryAsForeign ------------------------------- 746 747 void MarkEntryAsForeign() { 748 // Setup some preconditions. Create a cache with an entry 749 // in storage and in the working set. 750 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 751 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT)); 752 AppCacheDatabase::EntryRecord entry_record; 753 entry_record.cache_id = 1; 754 entry_record.url = kEntryUrl; 755 entry_record.flags = AppCacheEntry::EXPLICIT; 756 entry_record.response_id = 0; 757 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 758 EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign()); 759 760 // Conduct the test. 761 storage()->MarkEntryAsForeign(kEntryUrl, 1); 762 763 // The entry in the working set should have been updated syncly. 764 EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsForeign()); 765 EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsExplicit()); 766 767 // And the entry in storage should also be updated, but that 768 // happens asynchronously on the db thread. 769 FlushDbThreadTasks(); 770 AppCacheDatabase::EntryRecord entry_record2; 771 EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record2)); 772 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 773 entry_record2.flags); 774 TestFinished(); 775 } 776 777 // MarkEntryAsForeignWithLoadInProgress ------------------------------- 778 779 void MarkEntryAsForeignWithLoadInProgress() { 780 PushNextTask(base::Bind( 781 &AppCacheStorageImplTest::Verify_MarkEntryAsForeignWithLoadInProgress, 782 base::Unretained(this))); 783 784 // Setup some preconditions. Create a cache with an entry 785 // in storage, but not in the working set. 786 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 787 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT)); 788 AppCacheDatabase::EntryRecord entry_record; 789 entry_record.cache_id = 1; 790 entry_record.url = kEntryUrl; 791 entry_record.flags = AppCacheEntry::EXPLICIT; 792 entry_record.response_id = 0; 793 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 794 EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign()); 795 EXPECT_TRUE(cache_->HasOneRef()); 796 cache_ = NULL; 797 group_ = NULL; 798 799 // Conduct the test, start a cache load, and prior to completion 800 // of that load, mark the entry as foreign. 801 storage()->LoadCache(1, delegate()); 802 storage()->MarkEntryAsForeign(kEntryUrl, 1); 803 } 804 805 void Verify_MarkEntryAsForeignWithLoadInProgress() { 806 EXPECT_EQ(1, delegate()->loaded_cache_id_); 807 EXPECT_TRUE(delegate()->loaded_cache_.get()); 808 809 // The entry in the working set should have been updated upon load. 810 EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsForeign()); 811 EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsExplicit()); 812 813 // And the entry in storage should also be updated. 814 FlushDbThreadTasks(); 815 AppCacheDatabase::EntryRecord entry_record; 816 EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record)); 817 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 818 entry_record.flags); 819 TestFinished(); 820 } 821 822 // FindNoMainResponse ------------------------------- 823 824 void FindNoMainResponse() { 825 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_FindNoMainResponse, 826 base::Unretained(this))); 827 828 // Conduct the test. 829 storage()->FindResponseForMainRequest(kEntryUrl, GURL(), delegate()); 830 EXPECT_NE(kEntryUrl, delegate()->found_url_); 831 } 832 833 void Verify_FindNoMainResponse() { 834 EXPECT_EQ(kEntryUrl, delegate()->found_url_); 835 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); 836 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); 837 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); 838 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); 839 EXPECT_TRUE(delegate()->found_namespace_entry_url_.is_empty()); 840 EXPECT_EQ(0, delegate()->found_entry_.types()); 841 EXPECT_EQ(0, delegate()->found_fallback_entry_.types()); 842 TestFinished(); 843 } 844 845 // BasicFindMainResponse ------------------------------- 846 847 void BasicFindMainResponseInDatabase() { 848 BasicFindMainResponse(true); 849 } 850 851 void BasicFindMainResponseInWorkingSet() { 852 BasicFindMainResponse(false); 853 } 854 855 void BasicFindMainResponse(bool drop_from_working_set) { 856 PushNextTask(base::Bind( 857 &AppCacheStorageImplTest::Verify_BasicFindMainResponse, 858 base::Unretained(this))); 859 860 // Setup some preconditions. Create a complete cache with an entry 861 // in storage. 862 MakeCacheAndGroup(kManifestUrl, 2, 1, true); 863 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1)); 864 AppCacheDatabase::EntryRecord entry_record; 865 entry_record.cache_id = 1; 866 entry_record.url = kEntryUrl; 867 entry_record.flags = AppCacheEntry::EXPLICIT; 868 entry_record.response_id = 1; 869 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 870 871 // Optionally drop the cache/group pair from the working set. 872 if (drop_from_working_set) { 873 EXPECT_TRUE(cache_->HasOneRef()); 874 cache_ = NULL; 875 EXPECT_TRUE(group_->HasOneRef()); 876 group_ = NULL; 877 } 878 879 // Conduct the test. 880 storage()->FindResponseForMainRequest(kEntryUrl, GURL(), delegate()); 881 EXPECT_NE(kEntryUrl, delegate()->found_url_); 882 } 883 884 void Verify_BasicFindMainResponse() { 885 EXPECT_EQ(kEntryUrl, delegate()->found_url_); 886 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 887 EXPECT_EQ(1, delegate()->found_cache_id_); 888 EXPECT_EQ(2, delegate()->found_group_id_); 889 EXPECT_EQ(1, delegate()->found_entry_.response_id()); 890 EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); 891 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 892 TestFinished(); 893 } 894 895 // BasicFindMainFallbackResponse ------------------------------- 896 897 void BasicFindMainFallbackResponseInDatabase() { 898 BasicFindMainFallbackResponse(true); 899 } 900 901 void BasicFindMainFallbackResponseInWorkingSet() { 902 BasicFindMainFallbackResponse(false); 903 } 904 905 void BasicFindMainFallbackResponse(bool drop_from_working_set) { 906 PushNextTask(base::Bind( 907 &AppCacheStorageImplTest::Verify_BasicFindMainFallbackResponse, 908 base::Unretained(this))); 909 910 // Setup some preconditions. Create a complete cache with a 911 // fallback namespace and entry. 912 MakeCacheAndGroup(kManifestUrl, 2, 1, true); 913 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::FALLBACK, 1)); 914 cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2)); 915 cache_->fallback_namespaces_.push_back( 916 Namespace(FALLBACK_NAMESPACE, kFallbackNamespace2, kEntryUrl2, false)); 917 cache_->fallback_namespaces_.push_back( 918 Namespace(FALLBACK_NAMESPACE, kFallbackNamespace, kEntryUrl, false)); 919 AppCacheDatabase::CacheRecord cache_record; 920 std::vector<AppCacheDatabase::EntryRecord> entries; 921 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; 922 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; 923 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; 924 cache_->ToDatabaseRecords(group_.get(), 925 &cache_record, 926 &entries, 927 &intercepts, 928 &fallbacks, 929 &whitelists); 930 931 std::vector<AppCacheDatabase::EntryRecord>::const_iterator iter = 932 entries.begin(); 933 while (iter != entries.end()) { 934 // MakeCacheAndGroup has inserted the default entry record already. 935 if (iter->url != kDefaultEntryUrl) 936 EXPECT_TRUE(database()->InsertEntry(&(*iter))); 937 ++iter; 938 } 939 940 EXPECT_TRUE(database()->InsertNamespaceRecords(fallbacks)); 941 EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists)); 942 if (drop_from_working_set) { 943 EXPECT_TRUE(cache_->HasOneRef()); 944 cache_ = NULL; 945 EXPECT_TRUE(group_->HasOneRef()); 946 group_ = NULL; 947 } 948 949 // Conduct the test. The test url is in both fallback namespace urls, 950 // but should match the longer of the two. 951 storage()->FindResponseForMainRequest(kFallbackTestUrl, GURL(), delegate()); 952 EXPECT_NE(kFallbackTestUrl, delegate()->found_url_); 953 } 954 955 void Verify_BasicFindMainFallbackResponse() { 956 EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); 957 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 958 EXPECT_EQ(1, delegate()->found_cache_id_); 959 EXPECT_EQ(2, delegate()->found_group_id_); 960 EXPECT_FALSE(delegate()->found_entry_.has_response_id()); 961 EXPECT_EQ(2, delegate()->found_fallback_entry_.response_id()); 962 EXPECT_EQ(kEntryUrl2, delegate()->found_namespace_entry_url_); 963 EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback()); 964 TestFinished(); 965 } 966 967 // BasicFindMainInterceptResponse ------------------------------- 968 969 void BasicFindMainInterceptResponseInDatabase() { 970 BasicFindMainInterceptResponse(true); 971 } 972 973 void BasicFindMainInterceptResponseInWorkingSet() { 974 BasicFindMainInterceptResponse(false); 975 } 976 977 void BasicFindMainInterceptResponse(bool drop_from_working_set) { 978 PushNextTask(base::Bind( 979 &AppCacheStorageImplTest::Verify_BasicFindMainInterceptResponse, 980 base::Unretained(this))); 981 982 // Setup some preconditions. Create a complete cache with an 983 // intercept namespace and entry. 984 MakeCacheAndGroup(kManifestUrl, 2, 1, true); 985 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::INTERCEPT, 1)); 986 cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::INTERCEPT, 2)); 987 cache_->intercept_namespaces_.push_back( 988 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespace2, 989 kEntryUrl2, false)); 990 cache_->intercept_namespaces_.push_back( 991 Namespace(INTERCEPT_NAMESPACE, kInterceptNamespace, 992 kEntryUrl, false)); 993 AppCacheDatabase::CacheRecord cache_record; 994 std::vector<AppCacheDatabase::EntryRecord> entries; 995 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; 996 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; 997 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; 998 cache_->ToDatabaseRecords(group_.get(), 999 &cache_record, 1000 &entries, 1001 &intercepts, 1002 &fallbacks, 1003 &whitelists); 1004 1005 std::vector<AppCacheDatabase::EntryRecord>::const_iterator iter = 1006 entries.begin(); 1007 while (iter != entries.end()) { 1008 // MakeCacheAndGroup has inserted the default entry record already 1009 if (iter->url != kDefaultEntryUrl) 1010 EXPECT_TRUE(database()->InsertEntry(&(*iter))); 1011 ++iter; 1012 } 1013 1014 EXPECT_TRUE(database()->InsertNamespaceRecords(intercepts)); 1015 EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists)); 1016 if (drop_from_working_set) { 1017 EXPECT_TRUE(cache_->HasOneRef()); 1018 cache_ = NULL; 1019 EXPECT_TRUE(group_->HasOneRef()); 1020 group_ = NULL; 1021 } 1022 1023 // Conduct the test. The test url is in both intercept namespaces, 1024 // but should match the longer of the two. 1025 storage()->FindResponseForMainRequest( 1026 kInterceptTestUrl, GURL(), delegate()); 1027 EXPECT_NE(kInterceptTestUrl, delegate()->found_url_); 1028 } 1029 1030 void Verify_BasicFindMainInterceptResponse() { 1031 EXPECT_EQ(kInterceptTestUrl, delegate()->found_url_); 1032 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 1033 EXPECT_EQ(1, delegate()->found_cache_id_); 1034 EXPECT_EQ(2, delegate()->found_group_id_); 1035 EXPECT_EQ(2, delegate()->found_entry_.response_id()); 1036 EXPECT_TRUE(delegate()->found_entry_.IsIntercept()); 1037 EXPECT_EQ(kEntryUrl2, delegate()->found_namespace_entry_url_); 1038 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 1039 TestFinished(); 1040 } 1041 1042 // FindInterceptPatternMatch ---------------------------------------- 1043 1044 void FindInterceptPatternMatchInDatabase() { 1045 FindInterceptPatternMatch(true); 1046 } 1047 1048 void FindInterceptPatternMatchInWorkingSet() { 1049 FindInterceptPatternMatch(false); 1050 } 1051 1052 void FindInterceptPatternMatch(bool drop_from_working_set) { 1053 // Setup some preconditions. Create a complete cache with an 1054 // pattern matching intercept namespace and entry. 1055 MakeCacheAndGroup(kManifestUrl, 2, 1, true); 1056 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::INTERCEPT, 1)); 1057 cache_->intercept_namespaces_.push_back( 1058 Namespace(INTERCEPT_NAMESPACE, kInterceptPatternNamespace, 1059 kEntryUrl, true)); 1060 AppCacheDatabase::CacheRecord cache_record; 1061 std::vector<AppCacheDatabase::EntryRecord> entries; 1062 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; 1063 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; 1064 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; 1065 cache_->ToDatabaseRecords(group_.get(), 1066 &cache_record, 1067 &entries, 1068 &intercepts, 1069 &fallbacks, 1070 &whitelists); 1071 1072 std::vector<AppCacheDatabase::EntryRecord>::const_iterator iter = 1073 entries.begin(); 1074 while (iter != entries.end()) { 1075 // MakeCacheAndGroup has inserted the default entry record already 1076 if (iter->url != kDefaultEntryUrl) 1077 EXPECT_TRUE(database()->InsertEntry(&(*iter))); 1078 ++iter; 1079 } 1080 1081 EXPECT_TRUE(database()->InsertNamespaceRecords(intercepts)); 1082 if (drop_from_working_set) { 1083 EXPECT_TRUE(cache_->HasOneRef()); 1084 cache_ = NULL; 1085 EXPECT_TRUE(group_->HasOneRef()); 1086 group_ = NULL; 1087 } 1088 1089 // First test something that does not match the pattern. 1090 PushNextTask(base::Bind( 1091 &AppCacheStorageImplTest::Verify_FindInterceptPatternMatchNegative, 1092 base::Unretained(this))); 1093 storage()->FindResponseForMainRequest( 1094 kInterceptPatternTestNegativeUrl, GURL(), delegate()); 1095 EXPECT_EQ(GURL(), delegate()->found_url_); // Is always async. 1096 } 1097 1098 void Verify_FindInterceptPatternMatchNegative() { 1099 EXPECT_EQ(kInterceptPatternTestNegativeUrl, delegate()->found_url_); 1100 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); 1101 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); 1102 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); 1103 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); 1104 EXPECT_TRUE(delegate()->found_namespace_entry_url_.is_empty()); 1105 EXPECT_EQ(0, delegate()->found_entry_.types()); 1106 EXPECT_EQ(0, delegate()->found_fallback_entry_.types()); 1107 1108 // Then test something that matches. 1109 PushNextTask(base::Bind( 1110 &AppCacheStorageImplTest::Verify_FindInterceptPatternMatchPositive, 1111 base::Unretained(this))); 1112 storage()->FindResponseForMainRequest( 1113 kInterceptPatternTestPositiveUrl, GURL(), delegate()); 1114 } 1115 1116 void Verify_FindInterceptPatternMatchPositive() { 1117 EXPECT_EQ(kInterceptPatternTestPositiveUrl, delegate()->found_url_); 1118 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 1119 EXPECT_EQ(1, delegate()->found_cache_id_); 1120 EXPECT_EQ(2, delegate()->found_group_id_); 1121 EXPECT_EQ(1, delegate()->found_entry_.response_id()); 1122 EXPECT_TRUE(delegate()->found_entry_.IsIntercept()); 1123 EXPECT_EQ(kEntryUrl, delegate()->found_namespace_entry_url_); 1124 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 1125 TestFinished(); 1126 } 1127 1128 // FindFallbackPatternMatch ------------------------------- 1129 1130 void FindFallbackPatternMatchInDatabase() { 1131 FindFallbackPatternMatch(true); 1132 } 1133 1134 void FindFallbackPatternMatchInWorkingSet() { 1135 FindFallbackPatternMatch(false); 1136 } 1137 1138 void FindFallbackPatternMatch(bool drop_from_working_set) { 1139 // Setup some preconditions. Create a complete cache with a 1140 // pattern matching fallback namespace and entry. 1141 MakeCacheAndGroup(kManifestUrl, 2, 1, true); 1142 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::FALLBACK, 1)); 1143 cache_->fallback_namespaces_.push_back( 1144 Namespace(FALLBACK_NAMESPACE, kFallbackPatternNamespace, 1145 kEntryUrl, true)); 1146 AppCacheDatabase::CacheRecord cache_record; 1147 std::vector<AppCacheDatabase::EntryRecord> entries; 1148 std::vector<AppCacheDatabase::NamespaceRecord> intercepts; 1149 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks; 1150 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists; 1151 cache_->ToDatabaseRecords(group_.get(), 1152 &cache_record, 1153 &entries, 1154 &intercepts, 1155 &fallbacks, 1156 &whitelists); 1157 1158 std::vector<AppCacheDatabase::EntryRecord>::const_iterator iter = 1159 entries.begin(); 1160 while (iter != entries.end()) { 1161 // MakeCacheAndGroup has inserted the default entry record already. 1162 if (iter->url != kDefaultEntryUrl) 1163 EXPECT_TRUE(database()->InsertEntry(&(*iter))); 1164 ++iter; 1165 } 1166 1167 EXPECT_TRUE(database()->InsertNamespaceRecords(fallbacks)); 1168 if (drop_from_working_set) { 1169 EXPECT_TRUE(cache_->HasOneRef()); 1170 cache_ = NULL; 1171 EXPECT_TRUE(group_->HasOneRef()); 1172 group_ = NULL; 1173 } 1174 1175 // First test something that does not match the pattern. 1176 PushNextTask(base::Bind( 1177 &AppCacheStorageImplTest::Verify_FindFallbackPatternMatchNegative, 1178 base::Unretained(this))); 1179 storage()->FindResponseForMainRequest( 1180 kFallbackPatternTestNegativeUrl, GURL(), delegate()); 1181 EXPECT_EQ(GURL(), delegate()->found_url_); // Is always async. 1182 } 1183 1184 void Verify_FindFallbackPatternMatchNegative() { 1185 EXPECT_EQ(kFallbackPatternTestNegativeUrl, delegate()->found_url_); 1186 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); 1187 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); 1188 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); 1189 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); 1190 EXPECT_TRUE(delegate()->found_namespace_entry_url_.is_empty()); 1191 EXPECT_EQ(0, delegate()->found_entry_.types()); 1192 EXPECT_EQ(0, delegate()->found_fallback_entry_.types()); 1193 1194 // Then test something that matches. 1195 PushNextTask(base::Bind( 1196 &AppCacheStorageImplTest::Verify_FindFallbackPatternMatchPositive, 1197 base::Unretained(this))); 1198 storage()->FindResponseForMainRequest( 1199 kFallbackPatternTestPositiveUrl, GURL(), delegate()); 1200 } 1201 1202 void Verify_FindFallbackPatternMatchPositive() { 1203 EXPECT_EQ(kFallbackPatternTestPositiveUrl, delegate()->found_url_); 1204 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 1205 EXPECT_EQ(1, delegate()->found_cache_id_); 1206 EXPECT_EQ(2, delegate()->found_group_id_); 1207 EXPECT_EQ(1, delegate()->found_fallback_entry_.response_id()); 1208 EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback()); 1209 EXPECT_EQ(kEntryUrl, delegate()->found_namespace_entry_url_); 1210 EXPECT_FALSE(delegate()->found_entry_.has_response_id()); 1211 TestFinished(); 1212 } 1213 1214 // FindMainResponseWithMultipleHits ------------------------------- 1215 1216 void FindMainResponseWithMultipleHits() { 1217 PushNextTask(base::Bind( 1218 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits, 1219 base::Unretained(this))); 1220 1221 // Setup some preconditions, create a few caches with an identical set 1222 // of entries and fallback namespaces. Only the last one remains in 1223 // the working set to simulate appearing as "in use". 1224 MakeMultipleHitCacheAndGroup(kManifestUrl, 1); 1225 MakeMultipleHitCacheAndGroup(kManifestUrl2, 2); 1226 MakeMultipleHitCacheAndGroup(kManifestUrl3, 3); 1227 1228 // Conduct the test, we should find the response from the last cache 1229 // since it's "in use". 1230 storage()->FindResponseForMainRequest(kEntryUrl, GURL(), delegate()); 1231 EXPECT_NE(kEntryUrl, delegate()->found_url_); 1232 } 1233 1234 void MakeMultipleHitCacheAndGroup(const GURL& manifest_url, int id) { 1235 MakeCacheAndGroup(manifest_url, id, id, true); 1236 AppCacheDatabase::EntryRecord entry_record; 1237 1238 // Add an entry for kEntryUrl 1239 entry_record.cache_id = id; 1240 entry_record.url = kEntryUrl; 1241 entry_record.flags = AppCacheEntry::EXPLICIT; 1242 entry_record.response_id = id; 1243 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 1244 cache_->AddEntry( 1245 entry_record.url, 1246 AppCacheEntry(entry_record.flags, entry_record.response_id)); 1247 1248 // Add an entry for the manifestUrl 1249 entry_record.cache_id = id; 1250 entry_record.url = manifest_url; 1251 entry_record.flags = AppCacheEntry::MANIFEST; 1252 entry_record.response_id = id + kManifestEntryIdOffset; 1253 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 1254 cache_->AddEntry( 1255 entry_record.url, 1256 AppCacheEntry(entry_record.flags, entry_record.response_id)); 1257 1258 // Add a fallback entry and namespace 1259 entry_record.cache_id = id; 1260 entry_record.url = kEntryUrl2; 1261 entry_record.flags = AppCacheEntry::FALLBACK; 1262 entry_record.response_id = id + kFallbackEntryIdOffset; 1263 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 1264 cache_->AddEntry( 1265 entry_record.url, 1266 AppCacheEntry(entry_record.flags, entry_record.response_id)); 1267 AppCacheDatabase::NamespaceRecord fallback_namespace_record; 1268 fallback_namespace_record.cache_id = id; 1269 fallback_namespace_record.namespace_.target_url = entry_record.url; 1270 fallback_namespace_record.namespace_.namespace_url = kFallbackNamespace; 1271 fallback_namespace_record.origin = manifest_url.GetOrigin(); 1272 EXPECT_TRUE(database()->InsertNamespace(&fallback_namespace_record)); 1273 cache_->fallback_namespaces_.push_back( 1274 Namespace(FALLBACK_NAMESPACE, kFallbackNamespace, kEntryUrl2, false)); 1275 } 1276 1277 void Verify_FindMainResponseWithMultipleHits() { 1278 EXPECT_EQ(kEntryUrl, delegate()->found_url_); 1279 EXPECT_EQ(kManifestUrl3, delegate()->found_manifest_url_); 1280 EXPECT_EQ(3, delegate()->found_cache_id_); 1281 EXPECT_EQ(3, delegate()->found_group_id_); 1282 EXPECT_EQ(3, delegate()->found_entry_.response_id()); 1283 EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); 1284 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 1285 1286 // Conduct another test perferring kManifestUrl 1287 delegate_.reset(new MockStorageDelegate(this)); 1288 PushNextTask(base::Bind( 1289 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits2, 1290 base::Unretained(this))); 1291 storage()->FindResponseForMainRequest(kEntryUrl, kManifestUrl, delegate()); 1292 EXPECT_NE(kEntryUrl, delegate()->found_url_); 1293 } 1294 1295 void Verify_FindMainResponseWithMultipleHits2() { 1296 EXPECT_EQ(kEntryUrl, delegate()->found_url_); 1297 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_); 1298 EXPECT_EQ(1, delegate()->found_cache_id_); 1299 EXPECT_EQ(1, delegate()->found_group_id_); 1300 EXPECT_EQ(1, delegate()->found_entry_.response_id()); 1301 EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); 1302 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 1303 1304 // Conduct the another test perferring kManifestUrl2 1305 delegate_.reset(new MockStorageDelegate(this)); 1306 PushNextTask(base::Bind( 1307 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits3, 1308 base::Unretained(this))); 1309 storage()->FindResponseForMainRequest(kEntryUrl, kManifestUrl2, delegate()); 1310 EXPECT_NE(kEntryUrl, delegate()->found_url_); 1311 } 1312 1313 void Verify_FindMainResponseWithMultipleHits3() { 1314 EXPECT_EQ(kEntryUrl, delegate()->found_url_); 1315 EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_); 1316 EXPECT_EQ(2, delegate()->found_cache_id_); 1317 EXPECT_EQ(2, delegate()->found_group_id_); 1318 EXPECT_EQ(2, delegate()->found_entry_.response_id()); 1319 EXPECT_TRUE(delegate()->found_entry_.IsExplicit()); 1320 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id()); 1321 1322 // Conduct another test with no preferred manifest that hits the fallback. 1323 delegate_.reset(new MockStorageDelegate(this)); 1324 PushNextTask(base::Bind( 1325 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits4, 1326 base::Unretained(this))); 1327 storage()->FindResponseForMainRequest( 1328 kFallbackTestUrl, GURL(), delegate()); 1329 EXPECT_NE(kFallbackTestUrl, delegate()->found_url_); 1330 } 1331 1332 void Verify_FindMainResponseWithMultipleHits4() { 1333 EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); 1334 EXPECT_EQ(kManifestUrl3, delegate()->found_manifest_url_); 1335 EXPECT_EQ(3, delegate()->found_cache_id_); 1336 EXPECT_EQ(3, delegate()->found_group_id_); 1337 EXPECT_FALSE(delegate()->found_entry_.has_response_id()); 1338 EXPECT_EQ(3 + kFallbackEntryIdOffset, 1339 delegate()->found_fallback_entry_.response_id()); 1340 EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback()); 1341 EXPECT_EQ(kEntryUrl2, delegate()->found_namespace_entry_url_); 1342 1343 // Conduct another test preferring kManifestUrl2 that hits the fallback. 1344 delegate_.reset(new MockStorageDelegate(this)); 1345 PushNextTask(base::Bind( 1346 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits5, 1347 base::Unretained(this))); 1348 storage()->FindResponseForMainRequest( 1349 kFallbackTestUrl, kManifestUrl2, delegate()); 1350 EXPECT_NE(kFallbackTestUrl, delegate()->found_url_); 1351 } 1352 1353 void Verify_FindMainResponseWithMultipleHits5() { 1354 EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_); 1355 EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_); 1356 EXPECT_EQ(2, delegate()->found_cache_id_); 1357 EXPECT_EQ(2, delegate()->found_group_id_); 1358 EXPECT_FALSE(delegate()->found_entry_.has_response_id()); 1359 EXPECT_EQ(2 + kFallbackEntryIdOffset, 1360 delegate()->found_fallback_entry_.response_id()); 1361 EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback()); 1362 EXPECT_EQ(kEntryUrl2, delegate()->found_namespace_entry_url_); 1363 1364 TestFinished(); 1365 } 1366 1367 // FindMainResponseExclusions ------------------------------- 1368 1369 void FindMainResponseExclusionsInDatabase() { 1370 FindMainResponseExclusions(true); 1371 } 1372 1373 void FindMainResponseExclusionsInWorkingSet() { 1374 FindMainResponseExclusions(false); 1375 } 1376 1377 void FindMainResponseExclusions(bool drop_from_working_set) { 1378 // Setup some preconditions. Create a complete cache with a 1379 // foreign entry, an online namespace, and a second online 1380 // namespace nested within a fallback namespace. 1381 MakeCacheAndGroup(kManifestUrl, 1, 1, true); 1382 cache_->AddEntry(kEntryUrl, 1383 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 1)); 1384 cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2)); 1385 cache_->fallback_namespaces_.push_back( 1386 Namespace(FALLBACK_NAMESPACE, kFallbackNamespace, kEntryUrl2, false)); 1387 cache_->online_whitelist_namespaces_.push_back( 1388 Namespace(NETWORK_NAMESPACE, kOnlineNamespace, 1389 GURL(), false)); 1390 cache_->online_whitelist_namespaces_.push_back( 1391 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceWithinFallback, 1392 GURL(), false)); 1393 1394 AppCacheDatabase::EntryRecord entry_record; 1395 entry_record.cache_id = 1; 1396 entry_record.url = kEntryUrl; 1397 entry_record.flags = AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN; 1398 entry_record.response_id = 1; 1399 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 1400 AppCacheDatabase::OnlineWhiteListRecord whitelist_record; 1401 whitelist_record.cache_id = 1; 1402 whitelist_record.namespace_url = kOnlineNamespace; 1403 EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record)); 1404 AppCacheDatabase::NamespaceRecord fallback_namespace_record; 1405 fallback_namespace_record.cache_id = 1; 1406 fallback_namespace_record.namespace_.target_url = kEntryUrl2; 1407 fallback_namespace_record.namespace_.namespace_url = kFallbackNamespace; 1408 fallback_namespace_record.origin = kManifestUrl.GetOrigin(); 1409 EXPECT_TRUE(database()->InsertNamespace(&fallback_namespace_record)); 1410 whitelist_record.cache_id = 1; 1411 whitelist_record.namespace_url = kOnlineNamespaceWithinFallback; 1412 EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record)); 1413 if (drop_from_working_set) { 1414 cache_ = NULL; 1415 group_ = NULL; 1416 } 1417 1418 // We should not find anything for the foreign entry. 1419 PushNextTask(base::Bind(&AppCacheStorageImplTest::Verify_ExclusionNotFound, 1420 base::Unretained(this), kEntryUrl, 1)); 1421 storage()->FindResponseForMainRequest(kEntryUrl, GURL(), delegate()); 1422 } 1423 1424 void Verify_ExclusionNotFound(GURL expected_url, int phase) { 1425 EXPECT_EQ(expected_url, delegate()->found_url_); 1426 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); 1427 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_); 1428 EXPECT_EQ(0, delegate()->found_group_id_); 1429 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id()); 1430 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id()); 1431 EXPECT_TRUE(delegate()->found_namespace_entry_url_.is_empty()); 1432 EXPECT_EQ(0, delegate()->found_entry_.types()); 1433 EXPECT_EQ(0, delegate()->found_fallback_entry_.types()); 1434 1435 if (phase == 1) { 1436 // We should not find anything for the online namespace. 1437 PushNextTask( 1438 base::Bind(&AppCacheStorageImplTest::Verify_ExclusionNotFound, 1439 base::Unretained(this), kOnlineNamespace, 2)); 1440 storage()->FindResponseForMainRequest( 1441 kOnlineNamespace, GURL(), delegate()); 1442 return; 1443 } 1444 if (phase == 2) { 1445 // We should not find anything for the online namespace nested within 1446 // the fallback namespace. 1447 PushNextTask(base::Bind( 1448 &AppCacheStorageImplTest::Verify_ExclusionNotFound, 1449 base::Unretained(this), kOnlineNamespaceWithinFallback, 3)); 1450 storage()->FindResponseForMainRequest( 1451 kOnlineNamespaceWithinFallback, GURL(), delegate()); 1452 return; 1453 } 1454 1455 TestFinished(); 1456 } 1457 1458 // Test case helpers -------------------------------------------------- 1459 1460 AppCacheService* service() { 1461 return service_.get(); 1462 } 1463 1464 AppCacheStorageImpl* storage() { 1465 return static_cast<AppCacheStorageImpl*>(service()->storage()); 1466 } 1467 1468 AppCacheDatabase* database() { 1469 return storage()->database_; 1470 } 1471 1472 MockStorageDelegate* delegate() { 1473 return delegate_.get(); 1474 } 1475 1476 void MakeCacheAndGroup( 1477 const GURL& manifest_url, int64 group_id, int64 cache_id, 1478 bool add_to_database) { 1479 AppCacheEntry default_entry( 1480 AppCacheEntry::EXPLICIT, cache_id + kDefaultEntryIdOffset, 1481 kDefaultEntrySize); 1482 group_ = new AppCacheGroup(storage(), manifest_url, group_id); 1483 cache_ = new AppCache(storage(), cache_id); 1484 cache_->AddEntry(kDefaultEntryUrl, default_entry); 1485 cache_->set_complete(true); 1486 group_->AddCache(cache_.get()); 1487 if (add_to_database) { 1488 AppCacheDatabase::GroupRecord group_record; 1489 group_record.group_id = group_id; 1490 group_record.manifest_url = manifest_url; 1491 group_record.origin = manifest_url.GetOrigin(); 1492 EXPECT_TRUE(database()->InsertGroup(&group_record)); 1493 AppCacheDatabase::CacheRecord cache_record; 1494 cache_record.cache_id = cache_id; 1495 cache_record.group_id = group_id; 1496 cache_record.online_wildcard = false; 1497 cache_record.update_time = kZeroTime; 1498 cache_record.cache_size = kDefaultEntrySize; 1499 EXPECT_TRUE(database()->InsertCache(&cache_record)); 1500 AppCacheDatabase::EntryRecord entry_record; 1501 entry_record.cache_id = cache_id; 1502 entry_record.url = kDefaultEntryUrl; 1503 entry_record.flags = default_entry.types(); 1504 entry_record.response_id = default_entry.response_id(); 1505 entry_record.response_size = default_entry.response_size(); 1506 EXPECT_TRUE(database()->InsertEntry(&entry_record)); 1507 1508 storage()->usage_map_[manifest_url.GetOrigin()] = 1509 default_entry.response_size(); 1510 } 1511 } 1512 1513 // Data members -------------------------------------------------- 1514 1515 scoped_ptr<base::WaitableEvent> test_finished_event_; 1516 std::stack<base::Closure> task_stack_; 1517 scoped_ptr<AppCacheService> service_; 1518 scoped_ptr<MockStorageDelegate> delegate_; 1519 scoped_refptr<MockQuotaManagerProxy> mock_quota_manager_proxy_; 1520 scoped_refptr<AppCacheGroup> group_; 1521 scoped_refptr<AppCache> cache_; 1522 scoped_refptr<AppCache> cache2_; 1523 }; 1524 1525 1526 TEST_F(AppCacheStorageImplTest, LoadCache_Miss) { 1527 RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_Miss); 1528 } 1529 1530 TEST_F(AppCacheStorageImplTest, LoadCache_NearHit) { 1531 RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_NearHit); 1532 } 1533 1534 TEST_F(AppCacheStorageImplTest, CreateGroupInEmptyOrigin) { 1535 RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInEmptyOrigin); 1536 } 1537 1538 TEST_F(AppCacheStorageImplTest, CreateGroupInPopulatedOrigin) { 1539 RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInPopulatedOrigin); 1540 } 1541 1542 TEST_F(AppCacheStorageImplTest, LoadGroupAndCache_FarHit) { 1543 RunTestOnIOThread(&AppCacheStorageImplTest::LoadGroupAndCache_FarHit); 1544 } 1545 1546 TEST_F(AppCacheStorageImplTest, StoreNewGroup) { 1547 RunTestOnIOThread(&AppCacheStorageImplTest::StoreNewGroup); 1548 } 1549 1550 TEST_F(AppCacheStorageImplTest, StoreExistingGroup) { 1551 RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroup); 1552 } 1553 1554 TEST_F(AppCacheStorageImplTest, StoreExistingGroupExistingCache) { 1555 RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroupExistingCache); 1556 } 1557 1558 TEST_F(AppCacheStorageImplTest, FailStoreGroup) { 1559 RunTestOnIOThread(&AppCacheStorageImplTest::FailStoreGroup); 1560 } 1561 1562 TEST_F(AppCacheStorageImplTest, MakeGroupObsolete) { 1563 RunTestOnIOThread(&AppCacheStorageImplTest::MakeGroupObsolete); 1564 } 1565 1566 TEST_F(AppCacheStorageImplTest, MarkEntryAsForeign) { 1567 RunTestOnIOThread(&AppCacheStorageImplTest::MarkEntryAsForeign); 1568 } 1569 1570 TEST_F(AppCacheStorageImplTest, MarkEntryAsForeignWithLoadInProgress) { 1571 RunTestOnIOThread( 1572 &AppCacheStorageImplTest::MarkEntryAsForeignWithLoadInProgress); 1573 } 1574 1575 TEST_F(AppCacheStorageImplTest, FindNoMainResponse) { 1576 RunTestOnIOThread(&AppCacheStorageImplTest::FindNoMainResponse); 1577 } 1578 1579 TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInDatabase) { 1580 RunTestOnIOThread( 1581 &AppCacheStorageImplTest::BasicFindMainResponseInDatabase); 1582 } 1583 1584 TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInWorkingSet) { 1585 RunTestOnIOThread( 1586 &AppCacheStorageImplTest::BasicFindMainResponseInWorkingSet); 1587 } 1588 1589 TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInDatabase) { 1590 RunTestOnIOThread( 1591 &AppCacheStorageImplTest::BasicFindMainFallbackResponseInDatabase); 1592 } 1593 1594 TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInWorkingSet) { 1595 RunTestOnIOThread( 1596 &AppCacheStorageImplTest::BasicFindMainFallbackResponseInWorkingSet); 1597 } 1598 1599 TEST_F(AppCacheStorageImplTest, BasicFindMainInterceptResponseInDatabase) { 1600 RunTestOnIOThread( 1601 &AppCacheStorageImplTest::BasicFindMainInterceptResponseInDatabase); 1602 } 1603 1604 TEST_F(AppCacheStorageImplTest, BasicFindMainInterceptResponseInWorkingSet) { 1605 RunTestOnIOThread( 1606 &AppCacheStorageImplTest::BasicFindMainInterceptResponseInWorkingSet); 1607 } 1608 1609 TEST_F(AppCacheStorageImplTest, FindMainResponseWithMultipleHits) { 1610 RunTestOnIOThread( 1611 &AppCacheStorageImplTest::FindMainResponseWithMultipleHits); 1612 } 1613 1614 TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInDatabase) { 1615 RunTestOnIOThread( 1616 &AppCacheStorageImplTest::FindMainResponseExclusionsInDatabase); 1617 } 1618 1619 TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInWorkingSet) { 1620 RunTestOnIOThread( 1621 &AppCacheStorageImplTest::FindMainResponseExclusionsInWorkingSet); 1622 } 1623 1624 TEST_F(AppCacheStorageImplTest, FindInterceptPatternMatchInWorkingSet) { 1625 RunTestOnIOThread( 1626 &AppCacheStorageImplTest::FindInterceptPatternMatchInWorkingSet); 1627 } 1628 1629 TEST_F(AppCacheStorageImplTest, FindInterceptPatternMatchInDatabase) { 1630 RunTestOnIOThread( 1631 &AppCacheStorageImplTest::FindInterceptPatternMatchInDatabase); 1632 } 1633 1634 TEST_F(AppCacheStorageImplTest, FindFallbackPatternMatchInWorkingSet) { 1635 RunTestOnIOThread( 1636 &AppCacheStorageImplTest::FindFallbackPatternMatchInWorkingSet); 1637 } 1638 1639 TEST_F(AppCacheStorageImplTest, FindFallbackPatternMatchInDatabase) { 1640 RunTestOnIOThread( 1641 &AppCacheStorageImplTest::FindFallbackPatternMatchInDatabase); 1642 } 1643 1644 // That's all folks! 1645 1646 } // namespace appcache 1647