diff options
Diffstat (limited to 'webkit/appcache/appcache_update_job_unittest.cc')
-rw-r--r-- | webkit/appcache/appcache_update_job_unittest.cc | 760 |
1 files changed, 727 insertions, 33 deletions
diff --git a/webkit/appcache/appcache_update_job_unittest.cc b/webkit/appcache/appcache_update_job_unittest.cc index 2f4d1b6..734f230 100644 --- a/webkit/appcache/appcache_update_job_unittest.cc +++ b/webkit/appcache/appcache_update_job_unittest.cc @@ -21,6 +21,8 @@ const wchar_t kDocRoot[] = L"webkit/appcache/data/appcache_unittest"; class MockFrontend : public AppCacheFrontend { public: + MockFrontend() : start_update_trigger_(CHECKING_EVENT), update_(NULL) { } + virtual void OnCacheSelected(int host_id, int64 cache_id, Status status) { } @@ -32,12 +34,33 @@ class MockFrontend : public AppCacheFrontend { virtual void OnEventRaised(const std::vector<int>& host_ids, EventID event_id) { raised_events_.push_back(RaisedEvent(host_ids, event_id)); + + // Trigger additional updates if requested. + if (event_id == start_update_trigger_ && update_) { + for (std::vector<AppCacheHost*>::iterator it = update_hosts_.begin(); + it != update_hosts_.end(); ++it) { + AppCacheHost* host = *it; + update_->StartUpdate(host, + (host ? host->pending_master_entry_url() : GURL::EmptyGURL())); + } + update_hosts_.clear(); // only trigger once + } } void AddExpectedEvent(const std::vector<int>& host_ids, EventID event_id) { expected_events_.push_back(RaisedEvent(host_ids, event_id)); } + void TriggerAdditionalUpdates(EventID trigger_event, + AppCacheUpdateJob* update) { + start_update_trigger_ = trigger_event; + update_ = update; + } + + void AdditionalUpdateHost(AppCacheHost* host) { + update_hosts_.push_back(host); + } + typedef std::vector<int> HostIds; typedef std::pair<HostIds, EventID> RaisedEvent; typedef std::vector<RaisedEvent> RaisedEvents; @@ -45,6 +68,11 @@ class MockFrontend : public AppCacheFrontend { // Set the expected events if verification needs to happen asynchronously. RaisedEvents expected_events_; + + // Add ability for frontend to add master entries to an inprogress update. + EventID start_update_trigger_; + AppCacheUpdateJob* update_; + std::vector<AppCacheHost*> update_hosts_; }; // Helper class to let us call methods of AppCacheUpdateJobTest on a @@ -1265,6 +1293,603 @@ class AppCacheUpdateJobTest : public testing::Test, WaitForUpdateToFinish(); } + void MasterEntryFetchManifestFailTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup(service_.get(), GURL("http://failme"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend = MakeMockFrontend(); + AppCacheHost* host = MakeHost(1, frontend); + host->new_master_entry_url_ = GURL("http://failme/blah"); + update->StartUpdate(host, host->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + update->manifest_url_request_->SimulateError(-100); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = false; + MockFrontend::HostIds ids1(1, host->host_id()); + frontend->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend->AddExpectedEvent(ids1, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntryBadManifestTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup(service_.get(), + http_server_->TestServerPage("files/bad-manifest"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend = MakeMockFrontend(); + AppCacheHost* host = MakeHost(1, frontend); + host->new_master_entry_url_ = http_server_->TestServerPage("files/blah"); + update->StartUpdate(host, host->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = false; + MockFrontend::HostIds ids1(1, host->host_id()); + frontend->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend->AddExpectedEvent(ids1, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntryManifestNotFoundTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/nosuchfile"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend = MakeMockFrontend(); + AppCacheHost* host = MakeHost(1, frontend); + host->new_master_entry_url_ = http_server_->TestServerPage("files/blah"); + + update->StartUpdate(host, host->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = true; + expect_group_has_cache_ = false; + MockFrontend::HostIds ids1(1, host->host_id()); + frontend->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend->AddExpectedEvent(ids1, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntryFailUrlFetchTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup(service_.get(), + http_server_->TestServerPage("files/manifest-fb-404"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend = MakeMockFrontend(); + AppCacheHost* host = MakeHost(1, frontend); + host->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + + update->StartUpdate(host, host->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = false; // 404 fallback url is cache failure + MockFrontend::HostIds ids1(1, host->host_id()); + frontend->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend->AddExpectedEvent(ids1, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntryAllFailTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + update->StartUpdate(host1, host1->new_master_entry_url_); + + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/servererror"); + update->StartUpdate(host2, host2->new_master_entry_url_); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = false; // all pending masters failed + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, ERROR_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, CHECKING_EVENT); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void UpgradeMasterEntryAllFailTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->AssociateCache(cache); + + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + update->StartUpdate(host2, host2->new_master_entry_url_); + + MockFrontend* frontend3 = MakeMockFrontend(); + AppCacheHost* host3 = MakeHost(3, frontend3); + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/servererror"); + update->StartUpdate(host3, host3->new_master_entry_url_); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + expect_old_cache_ = cache; + tested_manifest_ = MANIFEST1; + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, UPDATE_READY_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, ERROR_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend3->AddExpectedEvent(ids3, CHECKING_EVENT); + frontend3->AddExpectedEvent(ids3, DOWNLOADING_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, ERROR_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntrySomeFailTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + update->StartUpdate(host1, host1->new_master_entry_url_); + + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + update->StartUpdate(host2, host2->new_master_entry_url_); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; // as long as one pending master succeeds + tested_manifest_ = MANIFEST1; + expect_extra_entries_.insert(AppCache::EntryMap::value_type( + http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::MASTER))); + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, ERROR_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, CHECKING_EVENT); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, CACHED_EVENT); + + WaitForUpdateToFinish(); + } + + void UpgradeMasterEntrySomeFailTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->AssociateCache(cache); + + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + update->StartUpdate(host2, host2->new_master_entry_url_); + + MockFrontend* frontend3 = MakeMockFrontend(); + AppCacheHost* host3 = MakeHost(3, frontend3); + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + update->StartUpdate(host3, host3->new_master_entry_url_); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + expect_old_cache_ = cache; + tested_manifest_ = MANIFEST1; + expect_extra_entries_.insert(AppCache::EntryMap::value_type( + http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::MASTER))); + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, UPDATE_READY_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, ERROR_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend3->AddExpectedEvent(ids3, CHECKING_EVENT); + frontend3->AddExpectedEvent(ids3, DOWNLOADING_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, UPDATE_READY_EVENT); + + WaitForUpdateToFinish(); + } + + void MasterEntryNoUpdateTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup(service_.get(), + http_server_->TestServerPage("files/notmodified"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + AppCache* cache = MakeCacheForGroup(1, 111); + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->AssociateCache(cache); + + // Give cache an existing entry that can also be fetched. + cache->AddEntry(http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::EXPLICIT, 222)); + + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + update->StartUpdate(host2, host2->new_master_entry_url_); + + AppCacheHost* host3 = MakeHost(3, frontend2); // same frontend as host2 + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + update->StartUpdate(host3, host3->new_master_entry_url_); + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + expect_newest_cache_ = cache; // newest cache still the same cache + tested_manifest_ = PENDING_MASTER_NO_UPDATE; + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, NO_UPDATE_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend2->AddExpectedEvent(ids3, CHECKING_EVENT); + MockFrontend::HostIds ids2and3; + ids2and3.push_back(host2->host_id()); + ids2and3.push_back(host3->host_id()); + frontend2->AddExpectedEvent(ids2and3, NO_UPDATE_EVENT); + + WaitForUpdateToFinish(); + } + + void StartUpdateMidCacheAttemptTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), + service_->storage()->NewGroupId()); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + update->StartUpdate(host1, host1->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + // Set up additional updates to be started while update is in progress. + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + + MockFrontend* frontend3 = MakeMockFrontend(); + AppCacheHost* host3 = MakeHost(3, frontend3); + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + + MockFrontend* frontend4 = MakeMockFrontend(); + AppCacheHost* host4 = MakeHost(4, frontend4); + host4->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + + MockFrontend* frontend5 = MakeMockFrontend(); + AppCacheHost* host5 = MakeHost(5, frontend5); // no master entry url + + frontend1->TriggerAdditionalUpdates(DOWNLOADING_EVENT, update); + frontend1->AdditionalUpdateHost(host2); // fetch will fail + frontend1->AdditionalUpdateHost(host3); // same as an explicit entry + frontend1->AdditionalUpdateHost(host4); // same as another master entry + frontend1->AdditionalUpdateHost(NULL); // no host + frontend1->AdditionalUpdateHost(host5); // no master entry url + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + tested_manifest_ = MANIFEST1; + expect_extra_entries_.insert(AppCache::EntryMap::value_type( + http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::MASTER))); + MockFrontend::HostIds ids1(1, host1->host_id()); + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, CACHED_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, CHECKING_EVENT); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, ERROR_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend3->AddExpectedEvent(ids3, CHECKING_EVENT); + frontend3->AddExpectedEvent(ids3, DOWNLOADING_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, CACHED_EVENT); + MockFrontend::HostIds ids4(1, host4->host_id()); + frontend4->AddExpectedEvent(ids4, CHECKING_EVENT); + frontend4->AddExpectedEvent(ids4, DOWNLOADING_EVENT); + frontend4->AddExpectedEvent(ids4, PROGRESS_EVENT); + frontend4->AddExpectedEvent(ids4, PROGRESS_EVENT); + frontend4->AddExpectedEvent(ids4, CACHED_EVENT); + + // Host 5 is not associated with cache so no progress/cached events. + MockFrontend::HostIds ids5(1, host5->host_id()); + frontend5->AddExpectedEvent(ids5, CHECKING_EVENT); + frontend5->AddExpectedEvent(ids5, DOWNLOADING_EVENT); + + WaitForUpdateToFinish(); + } + + void StartUpdateMidNoUpdateTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/notmodified"), + service_->storage()->NewGroupId()); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + AppCache* cache = MakeCacheForGroup(1, 111); + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->AssociateCache(cache); + + // Give cache an existing entry. + cache->AddEntry(http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::EXPLICIT, 222)); + + // Start update with a pending master entry that will fail to give us an + // event to trigger other updates. + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/nosuchfile"); + update->StartUpdate(host2, host2->new_master_entry_url_); + EXPECT_TRUE(update->manifest_url_request_ != NULL); + + // Set up additional updates to be started while update is in progress. + MockFrontend* frontend3 = MakeMockFrontend(); + AppCacheHost* host3 = MakeHost(3, frontend3); + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + + MockFrontend* frontend4 = MakeMockFrontend(); + AppCacheHost* host4 = MakeHost(4, frontend4); // no master entry url + + MockFrontend* frontend5 = MakeMockFrontend(); + AppCacheHost* host5 = MakeHost(5, frontend5); + host5->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); // existing entry + + MockFrontend* frontend6 = MakeMockFrontend(); + AppCacheHost* host6 = MakeHost(6, frontend6); + host6->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + + frontend2->TriggerAdditionalUpdates(ERROR_EVENT, update); + frontend2->AdditionalUpdateHost(host3); + frontend2->AdditionalUpdateHost(NULL); // no host + frontend2->AdditionalUpdateHost(host4); // no master entry url + frontend2->AdditionalUpdateHost(host5); // same as existing cache entry + frontend2->AdditionalUpdateHost(host6); // same as another master entry + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + expect_newest_cache_ = cache; // newest cache unaffected by update + tested_manifest_ = PENDING_MASTER_NO_UPDATE; + MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, NO_UPDATE_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, ERROR_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend3->AddExpectedEvent(ids3, CHECKING_EVENT); + frontend3->AddExpectedEvent(ids3, NO_UPDATE_EVENT); + MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache + frontend4->AddExpectedEvent(ids4, CHECKING_EVENT); + MockFrontend::HostIds ids5(1, host5->host_id()); + frontend5->AddExpectedEvent(ids5, CHECKING_EVENT); + frontend5->AddExpectedEvent(ids5, NO_UPDATE_EVENT); + MockFrontend::HostIds ids6(1, host6->host_id()); + frontend6->AddExpectedEvent(ids6, CHECKING_EVENT); + frontend6->AddExpectedEvent(ids6, NO_UPDATE_EVENT); + + WaitForUpdateToFinish(); + } + + void StartUpdateMidDownloadTest() { + ASSERT_EQ(MessageLoop::TYPE_IO, MessageLoop::current()->type()); + + MakeService(); + group_ = new AppCacheGroup( + service_.get(), http_server_->TestServerPage("files/manifest1"), 111); + AppCacheUpdateJob* update = new AppCacheUpdateJob(service_.get(), group_); + group_->update_job_ = update; + + AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); + MockFrontend* frontend1 = MakeMockFrontend(); + AppCacheHost* host1 = MakeHost(1, frontend1); + host1->AssociateCache(cache); + + update->StartUpdate(NULL, GURL::EmptyGURL()); + + // Set up additional updates to be started while update is in progress. + MockFrontend* frontend2 = MakeMockFrontend(); + AppCacheHost* host2 = MakeHost(2, frontend2); + host2->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit1"); + + MockFrontend* frontend3 = MakeMockFrontend(); + AppCacheHost* host3 = MakeHost(3, frontend3); + host3->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + + MockFrontend* frontend4 = MakeMockFrontend(); + AppCacheHost* host4 = MakeHost(4, frontend4); // no master entry url + + MockFrontend* frontend5 = MakeMockFrontend(); + AppCacheHost* host5 = MakeHost(5, frontend5); + host5->new_master_entry_url_ = + http_server_->TestServerPage("files/explicit2"); + + frontend1->TriggerAdditionalUpdates(PROGRESS_EVENT, update); + frontend1->AdditionalUpdateHost(host2); // same as entry in manifest + frontend1->AdditionalUpdateHost(NULL); // no host + frontend1->AdditionalUpdateHost(host3); // new master entry + frontend1->AdditionalUpdateHost(host4); // no master entry url + frontend1->AdditionalUpdateHost(host5); // same as another master entry + + // Set up checks for when update job finishes. + do_checks_after_update_finished_ = true; + expect_group_obsolete_ = false; + expect_group_has_cache_ = true; + tested_manifest_ = MANIFEST1; + expect_extra_entries_.insert(AppCache::EntryMap::value_type( + http_server_->TestServerPage("files/explicit2"), + AppCacheEntry(AppCacheEntry::MASTER))); + MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host + frontend1->AddExpectedEvent(ids1, CHECKING_EVENT); + frontend1->AddExpectedEvent(ids1, DOWNLOADING_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, PROGRESS_EVENT); + frontend1->AddExpectedEvent(ids1, UPDATE_READY_EVENT); + MockFrontend::HostIds ids2(1, host2->host_id()); + frontend2->AddExpectedEvent(ids2, CHECKING_EVENT); + frontend2->AddExpectedEvent(ids2, DOWNLOADING_EVENT); + frontend2->AddExpectedEvent(ids2, PROGRESS_EVENT); + frontend2->AddExpectedEvent(ids2, UPDATE_READY_EVENT); + MockFrontend::HostIds ids3(1, host3->host_id()); + frontend3->AddExpectedEvent(ids3, CHECKING_EVENT); + frontend3->AddExpectedEvent(ids3, DOWNLOADING_EVENT); + frontend3->AddExpectedEvent(ids3, PROGRESS_EVENT); + frontend3->AddExpectedEvent(ids3, UPDATE_READY_EVENT); + MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache + frontend4->AddExpectedEvent(ids4, CHECKING_EVENT); + frontend4->AddExpectedEvent(ids4, DOWNLOADING_EVENT); + MockFrontend::HostIds ids5(1, host5->host_id()); + frontend5->AddExpectedEvent(ids5, CHECKING_EVENT); + frontend5->AddExpectedEvent(ids5, DOWNLOADING_EVENT); + frontend5->AddExpectedEvent(ids5, PROGRESS_EVENT); + frontend5->AddExpectedEvent(ids5, UPDATE_READY_EVENT); + + WaitForUpdateToFinish(); + } + void WaitForUpdateToFinish() { if (group_->update_status() == AppCacheGroup::IDLE) UpdateFinished(); @@ -1404,30 +2029,36 @@ class AppCacheUpdateJobTest : public testing::Test, // Verify expected cache contents last as some checks are asserts // and will abort the test if they fail. - switch (tested_manifest_) { - case MANIFEST1: - VerifyManifest1(group_->newest_complete_cache()); - break; - case MANIFEST_MERGED_TYPES: - VerifyManifestMergedTypes(group_->newest_complete_cache()); - break; - case EMPTY_MANIFEST: - VerifyEmptyManifest(group_->newest_complete_cache()); - break; - case EMPTY_FILE_MANIFEST: - VerifyEmptyFileManifest(group_->newest_complete_cache()); - break; - case NONE: - default: - break; + if (tested_manifest_) { + AppCache* cache = group_->newest_complete_cache(); + ASSERT_TRUE(cache != NULL); + EXPECT_EQ(group_, cache->owning_group()); + EXPECT_TRUE(cache->is_complete()); + + switch (tested_manifest_) { + case MANIFEST1: + VerifyManifest1(cache); + break; + case MANIFEST_MERGED_TYPES: + VerifyManifestMergedTypes(cache); + break; + case EMPTY_MANIFEST: + VerifyEmptyManifest(cache); + break; + case EMPTY_FILE_MANIFEST: + VerifyEmptyFileManifest(cache); + break; + case PENDING_MASTER_NO_UPDATE: + VerifyMasterEntryNoUpdate(cache); + break; + case NONE: + default: + break; + } } } void VerifyManifest1(AppCache* cache) { - ASSERT_TRUE(cache != NULL); - EXPECT_EQ(group_, cache->owning_group()); - EXPECT_TRUE(cache->is_complete()); - size_t expected = 3 + expect_extra_entries_.size(); EXPECT_EQ(expected, cache->entries().size()); AppCacheEntry* entry = @@ -1436,7 +2067,7 @@ class AppCacheUpdateJobTest : public testing::Test, EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); entry = cache->GetEntry(http_server_->TestServerPage("files/explicit1")); ASSERT_TRUE(entry); - EXPECT_EQ(AppCacheEntry::EXPLICIT, entry->types()); + EXPECT_TRUE(entry->IsExplicit()); entry = cache->GetEntry( http_server_->TestServerPage("files/fallback1a")); ASSERT_TRUE(entry); @@ -1466,10 +2097,6 @@ class AppCacheUpdateJobTest : public testing::Test, } void VerifyManifestMergedTypes(AppCache* cache) { - ASSERT_TRUE(cache != NULL); - EXPECT_EQ(group_, cache->owning_group()); - EXPECT_TRUE(cache->is_complete()); - size_t expected = 2; EXPECT_EQ(expected, cache->entries().size()); AppCacheEntry* entry = cache->GetEntry( @@ -1502,10 +2129,6 @@ class AppCacheUpdateJobTest : public testing::Test, } void VerifyEmptyManifest(AppCache* cache) { - ASSERT_TRUE(cache != NULL); - EXPECT_EQ(group_, cache->owning_group()); - EXPECT_TRUE(cache->is_complete()); - size_t expected = 1; EXPECT_EQ(expected, cache->entries().size()); AppCacheEntry* entry = cache->GetEntry( @@ -1521,10 +2144,6 @@ class AppCacheUpdateJobTest : public testing::Test, } void VerifyEmptyFileManifest(AppCache* cache) { - ASSERT_TRUE(cache != NULL); - EXPECT_EQ(group_, cache->owning_group()); - EXPECT_TRUE(cache->is_complete()); - EXPECT_EQ(size_t(2), cache->entries().size()); AppCacheEntry* entry = cache->GetEntry( http_server_->TestServerPage("files/empty-file-manifest")); @@ -1544,6 +2163,32 @@ class AppCacheUpdateJobTest : public testing::Test, EXPECT_TRUE(cache->update_time_ > base::TimeTicks()); } + void VerifyMasterEntryNoUpdate(AppCache* cache) { + EXPECT_EQ(size_t(3), cache->entries().size()); + AppCacheEntry* entry = cache->GetEntry( + http_server_->TestServerPage("files/notmodified")); + ASSERT_TRUE(entry); + EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); + + entry = cache->GetEntry( + http_server_->TestServerPage("files/explicit1")); + ASSERT_TRUE(entry); + EXPECT_EQ(AppCacheEntry::MASTER, entry->types()); + EXPECT_TRUE(entry->has_response_id()); + + entry = cache->GetEntry( + http_server_->TestServerPage("files/explicit2")); + ASSERT_TRUE(entry); + EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::MASTER, entry->types()); + EXPECT_TRUE(entry->has_response_id()); + + EXPECT_TRUE(cache->fallback_namespaces_.empty()); + EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); + EXPECT_FALSE(cache->online_whitelist_all_); + + EXPECT_TRUE(cache->update_time_ > base::TimeTicks()); + } + private: // Various manifest files used in this test. enum TestedManifest { @@ -1552,6 +2197,7 @@ class AppCacheUpdateJobTest : public testing::Test, MANIFEST_MERGED_TYPES, EMPTY_MANIFEST, EMPTY_FILE_MANIFEST, + PENDING_MASTER_NO_UPDATE, }; static scoped_ptr<base::Thread> io_thread_; @@ -1764,4 +2410,52 @@ TEST_F(AppCacheUpdateJobTest, UpgradeFailMakeGroupObsolete) { RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailMakeGroupObsoleteTest); } +TEST_F(AppCacheUpdateJobTest, MasterEntryFetchManifestFail) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFetchManifestFailTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntryBadManifest) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryBadManifestTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntryManifestNotFound) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryManifestNotFoundTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntryFailUrlFetch) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFailUrlFetchTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntryAllFail) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryAllFailTest); +} + +TEST_F(AppCacheUpdateJobTest, UpgradeMasterEntryAllFail) { + RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntryAllFailTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntrySomeFail) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntrySomeFailTest); +} + +TEST_F(AppCacheUpdateJobTest, UpgradeMasterEntrySomeFail) { + RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntrySomeFailTest); +} + +TEST_F(AppCacheUpdateJobTest, MasterEntryNoUpdate) { + RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryNoUpdateTest); +} + +TEST_F(AppCacheUpdateJobTest, StartUpdateMidCacheAttempt) { + RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidCacheAttemptTest); +} + +TEST_F(AppCacheUpdateJobTest, StartUpdateMidNoUpdate) { + RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidNoUpdateTest); +} + +TEST_F(AppCacheUpdateJobTest, StartUpdateMidDownload) { + RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidDownloadTest); +} + } // namespace appcache |