1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/bind.h" 6#include "base/bind_helpers.h" 7#include "base/stl_util.h" 8#include "base/synchronization/waitable_event.h" 9#include "base/threading/thread.h" 10#include "content/browser/appcache/appcache_group.h" 11#include "content/browser/appcache/appcache_host.h" 12#include "content/browser/appcache/appcache_response.h" 13#include "content/browser/appcache/appcache_update_job.h" 14#include "content/browser/appcache/mock_appcache_service.h" 15#include "net/base/net_errors.h" 16#include "net/http/http_response_headers.h" 17#include "net/url_request/url_request_error_job.h" 18#include "net/url_request/url_request_job_factory_impl.h" 19#include "net/url_request/url_request_test_job.h" 20#include "net/url_request/url_request_test_util.h" 21#include "testing/gtest/include/gtest/gtest.h" 22 23namespace content { 24class AppCacheUpdateJobTest; 25 26namespace { 27 28const char kManifest1Contents[] = 29 "CACHE MANIFEST\n" 30 "explicit1\n" 31 "FALLBACK:\n" 32 "fallback1 fallback1a\n" 33 "NETWORK:\n" 34 "*\n"; 35 36// There are a handful of http accessible resources that we need to conduct 37// these tests. Instead of running a seperate server to host these resources, 38// we mock them up. 39class MockHttpServer { 40 public: 41 static GURL GetMockUrl(const std::string& path) { 42 return GURL("http://mockhost/" + path); 43 } 44 45 static GURL GetMockHttpsUrl(const std::string& path) { 46 return GURL("https://mockhost/" + path); 47 } 48 49 static GURL GetMockCrossOriginHttpsUrl(const std::string& path) { 50 return GURL("https://cross_origin_host/" + path); 51 } 52 53 static net::URLRequestJob* JobFactory( 54 net::URLRequest* request, net::NetworkDelegate* network_delegate) { 55 if (request->url().host() != "mockhost" && 56 request->url().host() != "cross_origin_host") 57 return new net::URLRequestErrorJob(request, network_delegate, -100); 58 59 std::string headers, body; 60 GetMockResponse(request->url().path(), &headers, &body); 61 return new net::URLRequestTestJob( 62 request, network_delegate, headers, body, true); 63 } 64 65 private: 66 static void GetMockResponse(const std::string& path, 67 std::string* headers, 68 std::string* body) { 69 const char ok_headers[] = 70 "HTTP/1.1 200 OK\0" 71 "\0"; 72 const char error_headers[] = 73 "HTTP/1.1 500 BOO HOO\0" 74 "\0"; 75 const char manifest_headers[] = 76 "HTTP/1.1 200 OK\0" 77 "Content-type: text/cache-manifest\0" 78 "\0"; 79 const char not_modified_headers[] = 80 "HTTP/1.1 304 NOT MODIFIED\0" 81 "\0"; 82 const char gone_headers[] = 83 "HTTP/1.1 410 GONE\0" 84 "\0"; 85 const char not_found_headers[] = 86 "HTTP/1.1 404 NOT FOUND\0" 87 "\0"; 88 const char no_store_headers[] = 89 "HTTP/1.1 200 OK\0" 90 "Cache-Control: no-store\0" 91 "\0"; 92 93 if (path == "/files/missing-mime-manifest") { 94 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 95 (*body) = "CACHE MANIFEST\n"; 96 } else if (path == "/files/bad-manifest") { 97 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 98 (*body) = "BAD CACHE MANIFEST"; 99 } else if (path == "/files/empty1") { 100 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 101 (*body) = ""; 102 } else if (path == "/files/empty-file-manifest") { 103 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 104 (*body) = "CACHE MANIFEST\n" 105 "empty1\n"; 106 } else if (path == "/files/empty-manifest") { 107 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 108 (*body) = "CACHE MANIFEST\n"; 109 } else if (path == "/files/explicit1") { 110 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 111 (*body) = "explicit1"; 112 } else if (path == "/files/explicit2") { 113 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 114 (*body) = "explicit2"; 115 } else if (path == "/files/fallback1a") { 116 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 117 (*body) = "fallback1a"; 118 } else if (path == "/files/intercept1a") { 119 (*headers) = std::string(ok_headers, arraysize(ok_headers)); 120 (*body) = "intercept1a"; 121 } else if (path == "/files/gone") { 122 (*headers) = std::string(gone_headers, arraysize(gone_headers)); 123 (*body) = ""; 124 } else if (path == "/files/manifest1") { 125 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 126 (*body) = kManifest1Contents; 127 } else if (path == "/files/manifest1-with-notmodified") { 128 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 129 (*body) = kManifest1Contents; 130 (*body).append("CACHE:\n" 131 "notmodified\n"); 132 } else if (path == "/files/manifest-fb-404") { 133 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 134 (*body) = "CACHE MANIFEST\n" 135 "explicit1\n" 136 "FALLBACK:\n" 137 "fallback1 fallback1a\n" 138 "fallback404 fallback-404\n" 139 "NETWORK:\n" 140 "online1\n"; 141 } else if (path == "/files/manifest-merged-types") { 142 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 143 (*body) = "CACHE MANIFEST\n" 144 "explicit1\n" 145 "# manifest is also an explicit entry\n" 146 "manifest-merged-types\n" 147 "FALLBACK:\n" 148 "# fallback is also explicit entry\n" 149 "fallback1 explicit1\n" 150 "NETWORK:\n" 151 "online1\n"; 152 } else if (path == "/files/manifest-with-404") { 153 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 154 (*body) = "CACHE MANIFEST\n" 155 "explicit-404\n" 156 "explicit1\n" 157 "explicit2\n" 158 "explicit3\n" 159 "FALLBACK:\n" 160 "fallback1 fallback1a\n" 161 "NETWORK:\n" 162 "online1\n"; 163 } else if (path == "/files/manifest-with-intercept") { 164 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 165 (*body) = "CACHE MANIFEST\n" 166 "CHROMIUM-INTERCEPT:\n" 167 "intercept1 return intercept1a\n"; 168 } else if (path == "/files/notmodified") { 169 (*headers) = std::string(not_modified_headers, 170 arraysize(not_modified_headers)); 171 (*body) = ""; 172 } else if (path == "/files/servererror") { 173 (*headers) = std::string(error_headers, 174 arraysize(error_headers)); 175 (*body) = "error"; 176 } else if (path == "/files/valid_cross_origin_https_manifest") { 177 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 178 (*body) = "CACHE MANIFEST\n" 179 "https://cross_origin_host/files/explicit1\n"; 180 } else if (path == "/files/invalid_cross_origin_https_manifest") { 181 (*headers) = std::string(manifest_headers, arraysize(manifest_headers)); 182 (*body) = "CACHE MANIFEST\n" 183 "https://cross_origin_host/files/no-store-headers\n"; 184 } else if (path == "/files/no-store-headers") { 185 (*headers) = std::string(no_store_headers, arraysize(no_store_headers)); 186 (*body) = "no-store"; 187 } else { 188 (*headers) = std::string(not_found_headers, 189 arraysize(not_found_headers)); 190 (*body) = ""; 191 } 192 } 193}; 194 195class MockHttpServerJobFactory 196 : public net::URLRequestJobFactory::ProtocolHandler { 197 public: 198 virtual net::URLRequestJob* MaybeCreateJob( 199 net::URLRequest* request, 200 net::NetworkDelegate* network_delegate) const OVERRIDE { 201 return MockHttpServer::JobFactory(request, network_delegate); 202 } 203}; 204 205inline bool operator==(const AppCacheNamespace& lhs, 206 const AppCacheNamespace& rhs) { 207 return lhs.type == rhs.type && 208 lhs.namespace_url == rhs.namespace_url && 209 lhs.target_url == rhs.target_url; 210} 211 212} // namespace 213 214class MockFrontend : public AppCacheFrontend { 215 public: 216 MockFrontend() 217 : ignore_progress_events_(false), verify_progress_events_(false), 218 last_progress_total_(-1), last_progress_complete_(-1), 219 start_update_trigger_(APPCACHE_CHECKING_EVENT), update_(NULL) { 220 } 221 222 virtual void OnCacheSelected( 223 int host_id, const AppCacheInfo& info) OVERRIDE { 224 } 225 226 virtual void OnStatusChanged(const std::vector<int>& host_ids, 227 AppCacheStatus status) OVERRIDE { 228 } 229 230 virtual void OnEventRaised(const std::vector<int>& host_ids, 231 AppCacheEventID event_id) OVERRIDE { 232 raised_events_.push_back(RaisedEvent(host_ids, event_id)); 233 234 // Trigger additional updates if requested. 235 if (event_id == start_update_trigger_ && update_) { 236 for (std::vector<AppCacheHost*>::iterator it = update_hosts_.begin(); 237 it != update_hosts_.end(); ++it) { 238 AppCacheHost* host = *it; 239 update_->StartUpdate(host, 240 (host ? host->pending_master_entry_url() : GURL())); 241 } 242 update_hosts_.clear(); // only trigger once 243 } 244 } 245 246 virtual void OnErrorEventRaised(const std::vector<int>& host_ids, 247 const AppCacheErrorDetails& details) 248 OVERRIDE { 249 error_message_ = details.message; 250 OnEventRaised(host_ids, APPCACHE_ERROR_EVENT); 251 } 252 253 virtual void OnProgressEventRaised(const std::vector<int>& host_ids, 254 const GURL& url, 255 int num_total, 256 int num_complete) OVERRIDE { 257 if (!ignore_progress_events_) 258 OnEventRaised(host_ids, APPCACHE_PROGRESS_EVENT); 259 260 if (verify_progress_events_) { 261 EXPECT_GE(num_total, num_complete); 262 EXPECT_GE(num_complete, 0); 263 264 if (last_progress_total_ == -1) { 265 // Should start at zero. 266 EXPECT_EQ(0, num_complete); 267 } else { 268 // Total should be stable and complete should bump up by one at a time. 269 EXPECT_EQ(last_progress_total_, num_total); 270 EXPECT_EQ(last_progress_complete_ + 1, num_complete); 271 } 272 273 // Url should be valid for all except the 'final' event. 274 if (num_total == num_complete) 275 EXPECT_TRUE(url.is_empty()); 276 else 277 EXPECT_TRUE(url.is_valid()); 278 279 last_progress_total_ = num_total; 280 last_progress_complete_ = num_complete; 281 } 282 } 283 284 virtual void OnLogMessage(int host_id, 285 AppCacheLogLevel log_level, 286 const std::string& message) OVERRIDE { 287 } 288 289 virtual void OnContentBlocked(int host_id, 290 const GURL& manifest_url) OVERRIDE { 291 } 292 293 void AddExpectedEvent(const std::vector<int>& host_ids, 294 AppCacheEventID event_id) { 295 DCHECK(!ignore_progress_events_ || event_id != APPCACHE_PROGRESS_EVENT); 296 expected_events_.push_back(RaisedEvent(host_ids, event_id)); 297 } 298 299 void SetIgnoreProgressEvents(bool ignore) { 300 // Some tests involve joining new hosts to an already running update job 301 // or intentionally failing. The timing and sequencing of the progress 302 // events generated by an update job are dependent on the behavior of 303 // an external HTTP server. For jobs that do not run fully till completion, 304 // due to either joining late or early exit, we skip monitoring the 305 // progress events to avoid flakiness. 306 ignore_progress_events_ = ignore; 307 } 308 309 void SetVerifyProgressEvents(bool verify) { 310 verify_progress_events_ = verify; 311 } 312 313 void TriggerAdditionalUpdates(AppCacheEventID trigger_event, 314 AppCacheUpdateJob* update) { 315 start_update_trigger_ = trigger_event; 316 update_ = update; 317 } 318 319 void AdditionalUpdateHost(AppCacheHost* host) { 320 update_hosts_.push_back(host); 321 } 322 323 typedef std::vector<int> HostIds; 324 typedef std::pair<HostIds, AppCacheEventID> RaisedEvent; 325 typedef std::vector<RaisedEvent> RaisedEvents; 326 RaisedEvents raised_events_; 327 std::string error_message_; 328 329 // Set the expected events if verification needs to happen asynchronously. 330 RaisedEvents expected_events_; 331 std::string expected_error_message_; 332 333 bool ignore_progress_events_; 334 335 bool verify_progress_events_; 336 int last_progress_total_; 337 int last_progress_complete_; 338 339 // Add ability for frontend to add master entries to an inprogress update. 340 AppCacheEventID start_update_trigger_; 341 AppCacheUpdateJob* update_; 342 std::vector<AppCacheHost*> update_hosts_; 343}; 344 345// Helper factories to simulate redirected URL responses for tests. 346class RedirectFactory : public net::URLRequestJobFactory::ProtocolHandler { 347 public: 348 virtual net::URLRequestJob* MaybeCreateJob( 349 net::URLRequest* request, 350 net::NetworkDelegate* network_delegate) const OVERRIDE { 351 return new net::URLRequestTestJob( 352 request, 353 network_delegate, 354 net::URLRequestTestJob::test_redirect_headers(), 355 net::URLRequestTestJob::test_data_1(), 356 true); 357 } 358}; 359 360// Helper class to simulate a URL that returns retry or success. 361class RetryRequestTestJob : public net::URLRequestTestJob { 362 public: 363 enum RetryHeader { 364 NO_RETRY_AFTER, 365 NONZERO_RETRY_AFTER, 366 RETRY_AFTER_0, 367 }; 368 369 static const GURL kRetryUrl; 370 371 // Call this at the start of each retry test. 372 static void Initialize(int num_retry_responses, RetryHeader header, 373 int expected_requests) { 374 num_requests_ = 0; 375 num_retries_ = num_retry_responses; 376 retry_after_ = header; 377 expected_requests_ = expected_requests; 378 } 379 380 // Verifies results at end of test and resets counters. 381 static void Verify() { 382 EXPECT_EQ(expected_requests_, num_requests_); 383 num_requests_ = 0; 384 expected_requests_ = 0; 385 } 386 387 static net::URLRequestJob* RetryFactory( 388 net::URLRequest* request, net::NetworkDelegate* network_delegate) { 389 ++num_requests_; 390 if (num_retries_ > 0 && request->original_url() == kRetryUrl) { 391 --num_retries_; 392 return new RetryRequestTestJob( 393 request, network_delegate, RetryRequestTestJob::retry_headers(), 503); 394 } else { 395 return new RetryRequestTestJob( 396 request, 397 network_delegate, 398 RetryRequestTestJob::manifest_headers(), 200); 399 } 400 } 401 402 virtual int GetResponseCode() const OVERRIDE { return response_code_; } 403 404 private: 405 virtual ~RetryRequestTestJob() {} 406 407 static std::string retry_headers() { 408 const char no_retry_after[] = 409 "HTTP/1.1 503 BOO HOO\0" 410 "\0"; 411 const char nonzero[] = 412 "HTTP/1.1 503 BOO HOO\0" 413 "Retry-After: 60\0" 414 "\0"; 415 const char retry_after_0[] = 416 "HTTP/1.1 503 BOO HOO\0" 417 "Retry-After: 0\0" 418 "\0"; 419 420 switch (retry_after_) { 421 case NO_RETRY_AFTER: 422 return std::string(no_retry_after, arraysize(no_retry_after)); 423 case NONZERO_RETRY_AFTER: 424 return std::string(nonzero, arraysize(nonzero)); 425 case RETRY_AFTER_0: 426 default: 427 return std::string(retry_after_0, arraysize(retry_after_0)); 428 } 429 } 430 431 static std::string manifest_headers() { 432 const char headers[] = 433 "HTTP/1.1 200 OK\0" 434 "Content-type: text/cache-manifest\0" 435 "\0"; 436 return std::string(headers, arraysize(headers)); 437 } 438 439 static std::string data() { 440 return std::string("CACHE MANIFEST\r" 441 "http://retry\r"); // must be same as kRetryUrl 442 } 443 444 RetryRequestTestJob(net::URLRequest* request, 445 net::NetworkDelegate* network_delegate, 446 const std::string& headers, 447 int response_code) 448 : net::URLRequestTestJob( 449 request, network_delegate, headers, data(), true), 450 response_code_(response_code) { 451 } 452 453 int response_code_; 454 455 static int num_requests_; 456 static int num_retries_; 457 static RetryHeader retry_after_; 458 static int expected_requests_; 459}; 460 461class RetryRequestTestJobFactory 462 : public net::URLRequestJobFactory::ProtocolHandler { 463 public: 464 virtual net::URLRequestJob* MaybeCreateJob( 465 net::URLRequest* request, 466 net::NetworkDelegate* network_delegate) const OVERRIDE { 467 return RetryRequestTestJob::RetryFactory(request, network_delegate); 468 } 469}; 470 471// static 472const GURL RetryRequestTestJob::kRetryUrl("http://retry"); 473int RetryRequestTestJob::num_requests_ = 0; 474int RetryRequestTestJob::num_retries_; 475RetryRequestTestJob::RetryHeader RetryRequestTestJob::retry_after_; 476int RetryRequestTestJob::expected_requests_ = 0; 477 478// Helper class to check for certain HTTP headers. 479class HttpHeadersRequestTestJob : public net::URLRequestTestJob { 480 public: 481 // Call this at the start of each HTTP header-related test. 482 static void Initialize(const std::string& expect_if_modified_since, 483 const std::string& expect_if_none_match) { 484 expect_if_modified_since_ = expect_if_modified_since; 485 expect_if_none_match_ = expect_if_none_match; 486 } 487 488 // Verifies results at end of test and resets class. 489 static void Verify() { 490 if (!expect_if_modified_since_.empty()) 491 EXPECT_TRUE(saw_if_modified_since_); 492 if (!expect_if_none_match_.empty()) 493 EXPECT_TRUE(saw_if_none_match_); 494 495 // Reset. 496 expect_if_modified_since_.clear(); 497 saw_if_modified_since_ = false; 498 expect_if_none_match_.clear(); 499 saw_if_none_match_ = false; 500 already_checked_ = false; 501 } 502 503 static net::URLRequestJob* IfModifiedSinceFactory( 504 net::URLRequest* request, net::NetworkDelegate* network_delegate) { 505 if (!already_checked_) { 506 already_checked_ = true; // only check once for a test 507 const net::HttpRequestHeaders& extra_headers = 508 request->extra_request_headers(); 509 std::string header_value; 510 saw_if_modified_since_ = 511 extra_headers.GetHeader( 512 net::HttpRequestHeaders::kIfModifiedSince, &header_value) && 513 header_value == expect_if_modified_since_; 514 515 saw_if_none_match_ = 516 extra_headers.GetHeader( 517 net::HttpRequestHeaders::kIfNoneMatch, &header_value) && 518 header_value == expect_if_none_match_; 519 } 520 return MockHttpServer::JobFactory(request, network_delegate); 521 } 522 523 protected: 524 virtual ~HttpHeadersRequestTestJob() {} 525 526 private: 527 static std::string expect_if_modified_since_; 528 static bool saw_if_modified_since_; 529 static std::string expect_if_none_match_; 530 static bool saw_if_none_match_; 531 static bool already_checked_; 532}; 533 534// static 535std::string HttpHeadersRequestTestJob::expect_if_modified_since_; 536bool HttpHeadersRequestTestJob::saw_if_modified_since_ = false; 537std::string HttpHeadersRequestTestJob::expect_if_none_match_; 538bool HttpHeadersRequestTestJob::saw_if_none_match_ = false; 539bool HttpHeadersRequestTestJob::already_checked_ = false; 540 541class IfModifiedSinceJobFactory 542 : public net::URLRequestJobFactory::ProtocolHandler { 543 public: 544 virtual net::URLRequestJob* MaybeCreateJob( 545 net::URLRequest* request, 546 net::NetworkDelegate* network_delegate) const OVERRIDE { 547 return HttpHeadersRequestTestJob::IfModifiedSinceFactory( 548 request, network_delegate); 549 } 550}; 551 552class IOThread : public base::Thread { 553 public: 554 explicit IOThread(const char* name) 555 : base::Thread(name) { 556 } 557 558 virtual ~IOThread() { 559 Stop(); 560 } 561 562 net::URLRequestContext* request_context() { 563 return request_context_.get(); 564 } 565 566 void SetNewJobFactory(net::URLRequestJobFactory* job_factory) { 567 DCHECK(job_factory); 568 job_factory_.reset(job_factory); 569 request_context_->set_job_factory(job_factory_.get()); 570 } 571 572 virtual void Init() OVERRIDE { 573 scoped_ptr<net::URLRequestJobFactoryImpl> factory( 574 new net::URLRequestJobFactoryImpl()); 575 factory->SetProtocolHandler("http", new MockHttpServerJobFactory); 576 factory->SetProtocolHandler("https", new MockHttpServerJobFactory); 577 job_factory_ = factory.Pass(); 578 request_context_.reset(new net::TestURLRequestContext()); 579 request_context_->set_job_factory(job_factory_.get()); 580 } 581 582 virtual void CleanUp() OVERRIDE { 583 request_context_.reset(); 584 job_factory_.reset(); 585 } 586 587 private: 588 scoped_ptr<net::URLRequestJobFactory> job_factory_; 589 scoped_ptr<net::URLRequestContext> request_context_; 590}; 591 592class AppCacheUpdateJobTest : public testing::Test, 593 public AppCacheGroup::UpdateObserver { 594 public: 595 AppCacheUpdateJobTest() 596 : do_checks_after_update_finished_(false), 597 expect_group_obsolete_(false), 598 expect_group_has_cache_(false), 599 expect_group_is_being_deleted_(false), 600 expect_old_cache_(NULL), 601 expect_newest_cache_(NULL), 602 expect_non_null_update_time_(false), 603 tested_manifest_(NONE), 604 tested_manifest_path_override_(NULL) { 605 io_thread_.reset(new IOThread("AppCacheUpdateJob IO test thread")); 606 base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); 607 io_thread_->StartWithOptions(options); 608 } 609 610 // Use a separate IO thread to run a test. Thread will be destroyed 611 // when it goes out of scope. 612 template <class Method> 613 void RunTestOnIOThread(Method method) { 614 event_.reset(new base::WaitableEvent(false, false)); 615 io_thread_->message_loop()->PostTask( 616 FROM_HERE, base::Bind(method, base::Unretained(this))); 617 618 // Wait until task is done before exiting the test. 619 event_->Wait(); 620 } 621 622 void StartCacheAttemptTest() { 623 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 624 625 MakeService(); 626 group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 627 service_->storage()->NewGroupId()); 628 629 AppCacheUpdateJob* update = 630 new AppCacheUpdateJob(service_.get(), group_.get()); 631 group_->update_job_ = update; 632 633 MockFrontend mock_frontend; 634 AppCacheHost host(1, &mock_frontend, service_.get()); 635 636 update->StartUpdate(&host, GURL()); 637 638 // Verify state. 639 EXPECT_EQ(AppCacheUpdateJob::CACHE_ATTEMPT, update->update_type_); 640 EXPECT_EQ(AppCacheUpdateJob::FETCH_MANIFEST, update->internal_state_); 641 EXPECT_EQ(AppCacheGroup::CHECKING, group_->update_status()); 642 643 // Verify notifications. 644 MockFrontend::RaisedEvents& events = mock_frontend.raised_events_; 645 size_t expected = 1; 646 EXPECT_EQ(expected, events.size()); 647 EXPECT_EQ(expected, events[0].first.size()); 648 EXPECT_EQ(host.host_id(), events[0].first[0]); 649 EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second); 650 651 // Abort as we're not testing actual URL fetches in this test. 652 delete update; 653 UpdateFinished(); 654 } 655 656 void StartUpgradeAttemptTest() { 657 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 658 659 { 660 MakeService(); 661 group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 662 service_->storage()->NewGroupId()); 663 664 // Give the group some existing caches. 665 AppCache* cache1 = MakeCacheForGroup(1, 111); 666 AppCache* cache2 = MakeCacheForGroup(2, 222); 667 668 // Associate some hosts with caches in the group. 669 MockFrontend mock_frontend1; 670 MockFrontend mock_frontend2; 671 MockFrontend mock_frontend3; 672 673 AppCacheHost host1(1, &mock_frontend1, service_.get()); 674 host1.AssociateCompleteCache(cache1); 675 676 AppCacheHost host2(2, &mock_frontend2, service_.get()); 677 host2.AssociateCompleteCache(cache2); 678 679 AppCacheHost host3(3, &mock_frontend1, service_.get()); 680 host3.AssociateCompleteCache(cache1); 681 682 AppCacheHost host4(4, &mock_frontend3, service_.get()); 683 684 AppCacheUpdateJob* update = 685 new AppCacheUpdateJob(service_.get(), group_.get()); 686 group_->update_job_ = update; 687 update->StartUpdate(&host4, GURL()); 688 689 // Verify state after starting an update. 690 EXPECT_EQ(AppCacheUpdateJob::UPGRADE_ATTEMPT, update->update_type_); 691 EXPECT_EQ(AppCacheUpdateJob::FETCH_MANIFEST, update->internal_state_); 692 EXPECT_EQ(AppCacheGroup::CHECKING, group_->update_status()); 693 694 // Verify notifications. 695 MockFrontend::RaisedEvents& events = mock_frontend1.raised_events_; 696 size_t expected = 1; 697 EXPECT_EQ(expected, events.size()); 698 expected = 2; // 2 hosts using frontend1 699 EXPECT_EQ(expected, events[0].first.size()); 700 MockFrontend::HostIds& host_ids = events[0].first; 701 EXPECT_TRUE(std::find(host_ids.begin(), host_ids.end(), host1.host_id()) 702 != host_ids.end()); 703 EXPECT_TRUE(std::find(host_ids.begin(), host_ids.end(), host3.host_id()) 704 != host_ids.end()); 705 EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second); 706 707 events = mock_frontend2.raised_events_; 708 expected = 1; 709 EXPECT_EQ(expected, events.size()); 710 EXPECT_EQ(expected, events[0].first.size()); // 1 host using frontend2 711 EXPECT_EQ(host2.host_id(), events[0].first[0]); 712 EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second); 713 714 events = mock_frontend3.raised_events_; 715 EXPECT_TRUE(events.empty()); 716 717 // Abort as we're not testing actual URL fetches in this test. 718 delete update; 719 } 720 UpdateFinished(); 721 } 722 723 void CacheAttemptFetchManifestFailTest() { 724 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 725 726 MakeService(); 727 group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 728 service_->storage()->NewGroupId()); 729 AppCacheUpdateJob* update = 730 new AppCacheUpdateJob(service_.get(), group_.get()); 731 group_->update_job_ = update; 732 733 MockFrontend* frontend = MakeMockFrontend(); 734 AppCacheHost* host = MakeHost(1, frontend); 735 update->StartUpdate(host, GURL()); 736 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 737 738 update->manifest_fetcher_->request()->CancelWithError(-100); 739 740 // Set up checks for when update job finishes. 741 do_checks_after_update_finished_ = true; 742 expect_group_obsolete_ = false; 743 expect_group_has_cache_ = false; 744 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 745 APPCACHE_CHECKING_EVENT); 746 747 WaitForUpdateToFinish(); 748 } 749 750 void UpgradeFetchManifestFailTest() { 751 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 752 753 MakeService(); 754 group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 755 service_->storage()->NewGroupId()); 756 AppCacheUpdateJob* update = 757 new AppCacheUpdateJob(service_.get(), group_.get()); 758 group_->update_job_ = update; 759 760 AppCache* cache = MakeCacheForGroup(1, 111); 761 MockFrontend* frontend1 = MakeMockFrontend(); 762 MockFrontend* frontend2 = MakeMockFrontend(); 763 AppCacheHost* host1 = MakeHost(1, frontend1); 764 AppCacheHost* host2 = MakeHost(2, frontend2); 765 host1->AssociateCompleteCache(cache); 766 host2->AssociateCompleteCache(cache); 767 768 update->StartUpdate(NULL, GURL()); 769 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 770 771 update->manifest_fetcher_->request()->CancelWithError(-100); 772 773 // Set up checks for when update job finishes. 774 do_checks_after_update_finished_ = true; 775 expect_group_obsolete_ = false; 776 expect_group_has_cache_ = true; 777 expect_newest_cache_ = cache; // newest cache unaffected by update 778 MockFrontend::HostIds ids1(1, host1->host_id()); 779 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 780 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 781 MockFrontend::HostIds ids2(1, host2->host_id()); 782 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 783 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 784 785 WaitForUpdateToFinish(); 786 } 787 788 void ManifestRedirectTest() { 789 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 790 791 net::URLRequestJobFactoryImpl* new_factory( 792 new net::URLRequestJobFactoryImpl); 793 new_factory->SetProtocolHandler("http", new RedirectFactory); 794 io_thread_->SetNewJobFactory(new_factory); 795 796 MakeService(); 797 group_ = new AppCacheGroup(service_->storage(), GURL("http://testme"), 798 service_->storage()->NewGroupId()); 799 AppCacheUpdateJob* update = 800 new AppCacheUpdateJob(service_.get(), group_.get()); 801 group_->update_job_ = update; 802 803 MockFrontend* frontend = MakeMockFrontend(); 804 AppCacheHost* host = MakeHost(1, frontend); 805 update->StartUpdate(host, GURL()); 806 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 807 808 // Set up checks for when update job finishes. 809 do_checks_after_update_finished_ = true; 810 expect_group_obsolete_ = false; 811 expect_group_has_cache_ = false; // redirect is like a failed request 812 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 813 APPCACHE_CHECKING_EVENT); 814 815 WaitForUpdateToFinish(); 816 } 817 818 void ManifestMissingMimeTypeTest() { 819 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 820 821 MakeService(); 822 group_ = new AppCacheGroup( 823 service_->storage(), 824 MockHttpServer::GetMockUrl("files/missing-mime-manifest"), 825 service_->storage()->NewGroupId()); 826 AppCacheUpdateJob* update = 827 new AppCacheUpdateJob(service_.get(), group_.get()); 828 group_->update_job_ = update; 829 830 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 33); 831 MockFrontend* frontend = MakeMockFrontend(); 832 AppCacheHost* host = MakeHost(1, frontend); 833 host->AssociateCompleteCache(cache); 834 835 frontend->SetVerifyProgressEvents(true); 836 837 update->StartUpdate(NULL, GURL()); 838 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 839 840 // Set up checks for when update job finishes. 841 do_checks_after_update_finished_ = true; 842 expect_group_obsolete_ = false; 843 expect_group_has_cache_ = true; 844 expect_old_cache_ = cache; 845 tested_manifest_ = EMPTY_MANIFEST; 846 tested_manifest_path_override_ = "files/missing-mime-manifest"; 847 MockFrontend::HostIds ids(1, host->host_id()); 848 frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT); 849 frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT); 850 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final 851 frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT); 852 853 WaitForUpdateToFinish(); 854 } 855 856 void ManifestNotFoundTest() { 857 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 858 859 MakeService(); 860 group_ = new AppCacheGroup( 861 service_->storage(), MockHttpServer::GetMockUrl("files/nosuchfile"), 862 service_->storage()->NewGroupId()); 863 AppCacheUpdateJob* update = 864 new AppCacheUpdateJob(service_.get(), group_.get()); 865 group_->update_job_ = update; 866 867 AppCache* cache = MakeCacheForGroup(1, 111); 868 MockFrontend* frontend1 = MakeMockFrontend(); 869 MockFrontend* frontend2 = MakeMockFrontend(); 870 AppCacheHost* host1 = MakeHost(1, frontend1); 871 AppCacheHost* host2 = MakeHost(2, frontend2); 872 host1->AssociateCompleteCache(cache); 873 host2->AssociateCompleteCache(cache); 874 875 update->StartUpdate(NULL, GURL()); 876 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 877 878 // Set up checks for when update job finishes. 879 do_checks_after_update_finished_ = true; 880 expect_group_obsolete_ = true; 881 expect_group_has_cache_ = true; 882 expect_newest_cache_ = cache; // newest cache unaffected by update 883 MockFrontend::HostIds ids1(1, host1->host_id()); 884 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 885 frontend1->AddExpectedEvent(ids1, APPCACHE_OBSOLETE_EVENT); 886 MockFrontend::HostIds ids2(1, host2->host_id()); 887 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 888 frontend2->AddExpectedEvent(ids2, APPCACHE_OBSOLETE_EVENT); 889 890 WaitForUpdateToFinish(); 891 } 892 893 void ManifestGoneTest() { 894 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 895 896 MakeService(); 897 group_ = new AppCacheGroup( 898 service_->storage(), MockHttpServer::GetMockUrl("files/gone"), 899 service_->storage()->NewGroupId()); 900 AppCacheUpdateJob* update = 901 new AppCacheUpdateJob(service_.get(), group_.get()); 902 group_->update_job_ = update; 903 904 MockFrontend* frontend = MakeMockFrontend(); 905 AppCacheHost* host = MakeHost(1, frontend); 906 update->StartUpdate(host, GURL()); 907 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 908 909 // Set up checks for when update job finishes. 910 do_checks_after_update_finished_ = true; 911 expect_group_obsolete_ = false; 912 expect_group_has_cache_ = false; 913 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 914 APPCACHE_CHECKING_EVENT); 915 916 WaitForUpdateToFinish(); 917 } 918 919 void CacheAttemptNotModifiedTest() { 920 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 921 922 MakeService(); 923 group_ = new AppCacheGroup( 924 service_->storage(), MockHttpServer::GetMockUrl("files/notmodified"), 925 service_->storage()->NewGroupId()); 926 AppCacheUpdateJob* update = 927 new AppCacheUpdateJob(service_.get(), group_.get()); 928 group_->update_job_ = update; 929 930 MockFrontend* frontend = MakeMockFrontend(); 931 AppCacheHost* host = MakeHost(1, frontend); 932 update->StartUpdate(host, GURL()); 933 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 934 935 // Set up checks for when update job finishes. 936 do_checks_after_update_finished_ = true; 937 expect_group_obsolete_ = false; 938 expect_group_has_cache_ = false; // treated like cache failure 939 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 940 APPCACHE_CHECKING_EVENT); 941 942 WaitForUpdateToFinish(); 943 } 944 945 void UpgradeNotModifiedTest() { 946 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 947 948 MakeService(); 949 group_ = new AppCacheGroup( 950 service_->storage(), MockHttpServer::GetMockUrl("files/notmodified"), 951 service_->storage()->NewGroupId()); 952 AppCacheUpdateJob* update = 953 new AppCacheUpdateJob(service_.get(), group_.get()); 954 group_->update_job_ = update; 955 956 AppCache* cache = MakeCacheForGroup(1, 111); 957 MockFrontend* frontend1 = MakeMockFrontend(); 958 MockFrontend* frontend2 = MakeMockFrontend(); 959 AppCacheHost* host1 = MakeHost(1, frontend1); 960 AppCacheHost* host2 = MakeHost(2, frontend2); 961 host1->AssociateCompleteCache(cache); 962 host2->AssociateCompleteCache(cache); 963 964 update->StartUpdate(NULL, GURL()); 965 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 966 967 // Set up checks for when update job finishes. 968 do_checks_after_update_finished_ = true; 969 expect_group_obsolete_ = false; 970 expect_group_has_cache_ = true; 971 expect_newest_cache_ = cache; // newest cache unaffected by update 972 MockFrontend::HostIds ids1(1, host1->host_id()); 973 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 974 frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT); 975 MockFrontend::HostIds ids2(1, host2->host_id()); 976 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 977 frontend2->AddExpectedEvent(ids2, APPCACHE_NO_UPDATE_EVENT); 978 979 WaitForUpdateToFinish(); 980 } 981 982 void UpgradeManifestDataUnchangedTest() { 983 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 984 985 MakeService(); 986 group_ = new AppCacheGroup( 987 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 988 service_->storage()->NewGroupId()); 989 AppCacheUpdateJob* update = 990 new AppCacheUpdateJob(service_.get(), group_.get()); 991 group_->update_job_ = update; 992 993 // Create response writer to get a response id. 994 response_writer_.reset( 995 service_->storage()->CreateResponseWriter(group_->manifest_url(), 996 group_->group_id())); 997 998 AppCache* cache = MakeCacheForGroup(1, response_writer_->response_id()); 999 MockFrontend* frontend1 = MakeMockFrontend(); 1000 MockFrontend* frontend2 = MakeMockFrontend(); 1001 AppCacheHost* host1 = MakeHost(1, frontend1); 1002 AppCacheHost* host2 = MakeHost(2, frontend2); 1003 host1->AssociateCompleteCache(cache); 1004 host2->AssociateCompleteCache(cache); 1005 1006 // Set up checks for when update job finishes. 1007 do_checks_after_update_finished_ = true; 1008 expect_group_obsolete_ = false; 1009 expect_group_has_cache_ = true; 1010 expect_newest_cache_ = cache; // newest cache unaffected by update 1011 MockFrontend::HostIds ids1(1, host1->host_id()); 1012 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1013 frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT); 1014 MockFrontend::HostIds ids2(1, host2->host_id()); 1015 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1016 frontend2->AddExpectedEvent(ids2, APPCACHE_NO_UPDATE_EVENT); 1017 1018 // Seed storage with expected manifest data. 1019 const std::string seed_data(kManifest1Contents); 1020 scoped_refptr<net::StringIOBuffer> io_buffer( 1021 new net::StringIOBuffer(seed_data)); 1022 response_writer_->WriteData( 1023 io_buffer.get(), 1024 seed_data.length(), 1025 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 1026 base::Unretained(this))); 1027 1028 // Start update after data write completes asynchronously. 1029 } 1030 1031 // See http://code.google.com/p/chromium/issues/detail?id=95101 1032 void Bug95101Test() { 1033 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1034 1035 MakeService(); 1036 group_ = new AppCacheGroup( 1037 service_->storage(), MockHttpServer::GetMockUrl("files/empty-manifest"), 1038 service_->storage()->NewGroupId()); 1039 AppCacheUpdateJob* update = 1040 new AppCacheUpdateJob(service_.get(), group_.get()); 1041 group_->update_job_ = update; 1042 1043 // Create a malformed cache with a missing manifest entry. 1044 GURL wrong_manifest_url = 1045 MockHttpServer::GetMockUrl("files/missing-mime-manifest"); 1046 AppCache* cache = MakeCacheForGroup(1, wrong_manifest_url, 111); 1047 MockFrontend* frontend = MakeMockFrontend(); 1048 AppCacheHost* host = MakeHost(1, frontend); 1049 host->AssociateCompleteCache(cache); 1050 1051 update->StartUpdate(NULL, GURL()); 1052 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1053 1054 // Set up checks for when update job finishes. 1055 do_checks_after_update_finished_ = true; 1056 expect_group_is_being_deleted_ = true; 1057 expect_group_has_cache_ = true; 1058 expect_newest_cache_ = cache; // newest cache unaffected by update 1059 MockFrontend::HostIds id(1, host->host_id()); 1060 frontend->AddExpectedEvent(id, APPCACHE_CHECKING_EVENT); 1061 frontend->AddExpectedEvent(id, APPCACHE_ERROR_EVENT); 1062 frontend->expected_error_message_ = 1063 "Manifest entry not found in existing cache"; 1064 WaitForUpdateToFinish(); 1065 } 1066 1067 void StartUpdateAfterSeedingStorageData(int result) { 1068 ASSERT_GT(result, 0); 1069 response_writer_.reset(); 1070 1071 AppCacheUpdateJob* update = group_->update_job_; 1072 update->StartUpdate(NULL, GURL()); 1073 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1074 1075 WaitForUpdateToFinish(); 1076 } 1077 1078 void BasicCacheAttemptSuccessTest() { 1079 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1080 1081 GURL manifest_url = MockHttpServer::GetMockUrl("files/manifest1"); 1082 1083 MakeService(); 1084 group_ = new AppCacheGroup( 1085 service_->storage(), manifest_url, 1086 service_->storage()->NewGroupId()); 1087 AppCacheUpdateJob* update = 1088 new AppCacheUpdateJob(service_.get(), group_.get()); 1089 group_->update_job_ = update; 1090 1091 MockFrontend* frontend = MakeMockFrontend(); 1092 AppCacheHost* host = MakeHost(1, frontend); 1093 update->StartUpdate(host, GURL()); 1094 1095 // Set up checks for when update job finishes. 1096 do_checks_after_update_finished_ = true; 1097 expect_group_obsolete_ = false; 1098 expect_group_has_cache_ = true; 1099 tested_manifest_ = MANIFEST1; 1100 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1101 APPCACHE_CHECKING_EVENT); 1102 1103 WaitForUpdateToFinish(); 1104 } 1105 1106 void DownloadInterceptEntriesTest() { 1107 // Ensures we download intercept entries too. 1108 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1109 GURL manifest_url = 1110 MockHttpServer::GetMockUrl("files/manifest-with-intercept"); 1111 MakeService(); 1112 group_ = new AppCacheGroup( 1113 service_->storage(), manifest_url, 1114 service_->storage()->NewGroupId()); 1115 AppCacheUpdateJob* update = 1116 new AppCacheUpdateJob(service_.get(), group_.get()); 1117 group_->update_job_ = update; 1118 1119 MockFrontend* frontend = MakeMockFrontend(); 1120 AppCacheHost* host = MakeHost(1, frontend); 1121 update->StartUpdate(host, GURL()); 1122 1123 // Set up checks for when update job finishes. 1124 do_checks_after_update_finished_ = true; 1125 expect_group_obsolete_ = false; 1126 expect_group_has_cache_ = true; 1127 tested_manifest_ = MANIFEST_WITH_INTERCEPT; 1128 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1129 APPCACHE_CHECKING_EVENT); 1130 1131 WaitForUpdateToFinish(); 1132 } 1133 1134 void BasicUpgradeSuccessTest() { 1135 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1136 1137 MakeService(); 1138 group_ = new AppCacheGroup( 1139 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1140 service_->storage()->NewGroupId()); 1141 AppCacheUpdateJob* update = 1142 new AppCacheUpdateJob(service_.get(), group_.get()); 1143 group_->update_job_ = update; 1144 1145 // Create a response writer to get a response id. 1146 response_writer_.reset( 1147 service_->storage()->CreateResponseWriter(group_->manifest_url(), 1148 group_->group_id())); 1149 1150 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 1151 response_writer_->response_id()); 1152 MockFrontend* frontend1 = MakeMockFrontend(); 1153 MockFrontend* frontend2 = MakeMockFrontend(); 1154 AppCacheHost* host1 = MakeHost(1, frontend1); 1155 AppCacheHost* host2 = MakeHost(2, frontend2); 1156 host1->AssociateCompleteCache(cache); 1157 host2->AssociateCompleteCache(cache); 1158 frontend1->SetVerifyProgressEvents(true); 1159 frontend2->SetVerifyProgressEvents(true); 1160 1161 // Set up checks for when update job finishes. 1162 do_checks_after_update_finished_ = true; 1163 expect_group_obsolete_ = false; 1164 expect_group_has_cache_ = true; 1165 expect_old_cache_ = cache; 1166 tested_manifest_ = MANIFEST1; 1167 MockFrontend::HostIds ids1(1, host1->host_id()); 1168 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1169 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1170 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 1171 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 1172 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 1173 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 1174 MockFrontend::HostIds ids2(1, host2->host_id()); 1175 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1176 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1177 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1178 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1179 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 1180 frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT); 1181 1182 // Seed storage with expected manifest data different from manifest1. 1183 const std::string seed_data("different"); 1184 scoped_refptr<net::StringIOBuffer> io_buffer( 1185 new net::StringIOBuffer(seed_data)); 1186 response_writer_->WriteData( 1187 io_buffer.get(), 1188 seed_data.length(), 1189 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 1190 base::Unretained(this))); 1191 1192 // Start update after data write completes asynchronously. 1193 } 1194 1195 void UpgradeLoadFromNewestCacheTest() { 1196 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1197 1198 MakeService(); 1199 group_ = new AppCacheGroup( 1200 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1201 service_->storage()->NewGroupId()); 1202 AppCacheUpdateJob* update = 1203 new AppCacheUpdateJob(service_.get(), group_.get()); 1204 group_->update_job_ = update; 1205 1206 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 1207 MockFrontend* frontend = MakeMockFrontend(); 1208 AppCacheHost* host = MakeHost(1, frontend); 1209 host->AssociateCompleteCache(cache); 1210 1211 // Give the newest cache an entry that is in storage. 1212 response_writer_.reset( 1213 service_->storage()->CreateResponseWriter(group_->manifest_url(), 1214 group_->group_id())); 1215 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"), 1216 AppCacheEntry(AppCacheEntry::EXPLICIT, 1217 response_writer_->response_id())); 1218 1219 // Set up checks for when update job finishes. 1220 do_checks_after_update_finished_ = true; 1221 expect_group_obsolete_ = false; 1222 expect_group_has_cache_ = true; 1223 expect_old_cache_ = cache; 1224 expect_response_ids_.insert( 1225 std::map<GURL, int64>::value_type( 1226 MockHttpServer::GetMockUrl("files/explicit1"), 1227 response_writer_->response_id())); 1228 tested_manifest_ = MANIFEST1; 1229 MockFrontend::HostIds ids(1, host->host_id()); 1230 frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT); 1231 frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT); 1232 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1233 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1234 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final 1235 frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT); 1236 1237 // Seed storage with expected http response info for entry. Allow reuse. 1238 const char data[] = 1239 "HTTP/1.1 200 OK\0" 1240 "Cache-Control: max-age=8675309\0" 1241 "\0"; 1242 net::HttpResponseHeaders* headers = 1243 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 1244 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 1245 response_info->request_time = base::Time::Now(); 1246 response_info->response_time = base::Time::Now(); 1247 response_info->headers = headers; // adds ref to headers 1248 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( 1249 new HttpResponseInfoIOBuffer(response_info)); // adds ref to info 1250 response_writer_->WriteInfo( 1251 io_buffer.get(), 1252 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 1253 base::Unretained(this))); 1254 1255 // Start update after data write completes asynchronously. 1256 } 1257 1258 void UpgradeNoLoadFromNewestCacheTest() { 1259 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1260 1261 MakeService(); 1262 group_ = new AppCacheGroup( 1263 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1264 service_->storage()->NewGroupId()); 1265 AppCacheUpdateJob* update = 1266 new AppCacheUpdateJob(service_.get(), group_.get()); 1267 group_->update_job_ = update; 1268 1269 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 1270 MockFrontend* frontend = MakeMockFrontend(); 1271 AppCacheHost* host = MakeHost(1, frontend); 1272 host->AssociateCompleteCache(cache); 1273 1274 // Give the newest cache an entry that is in storage. 1275 response_writer_.reset( 1276 service_->storage()->CreateResponseWriter(group_->manifest_url(), 1277 group_->group_id())); 1278 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"), 1279 AppCacheEntry(AppCacheEntry::EXPLICIT, 1280 response_writer_->response_id())); 1281 1282 // Set up checks for when update job finishes. 1283 do_checks_after_update_finished_ = true; 1284 expect_group_obsolete_ = false; 1285 expect_group_has_cache_ = true; 1286 expect_old_cache_ = cache; 1287 tested_manifest_ = MANIFEST1; 1288 MockFrontend::HostIds ids(1, host->host_id()); 1289 frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT); 1290 frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT); 1291 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1292 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1293 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final 1294 frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT); 1295 1296 // Seed storage with expected http response info for entry. Do NOT 1297 // allow reuse by setting an expires header in the past. 1298 const char data[] = 1299 "HTTP/1.1 200 OK\0" 1300 "Expires: Thu, 01 Dec 1994 16:00:00 GMT\0" 1301 "\0"; 1302 net::HttpResponseHeaders* headers = 1303 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 1304 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 1305 response_info->request_time = base::Time::Now(); 1306 response_info->response_time = base::Time::Now(); 1307 response_info->headers = headers; // adds ref to headers 1308 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( 1309 new HttpResponseInfoIOBuffer(response_info)); // adds ref to info 1310 response_writer_->WriteInfo( 1311 io_buffer.get(), 1312 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 1313 base::Unretained(this))); 1314 1315 // Start update after data write completes asynchronously. 1316 } 1317 1318 void UpgradeLoadFromNewestCacheVaryHeaderTest() { 1319 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1320 1321 MakeService(); 1322 group_ = new AppCacheGroup( 1323 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1324 service_->storage()->NewGroupId()); 1325 AppCacheUpdateJob* update = 1326 new AppCacheUpdateJob(service_.get(), group_.get()); 1327 group_->update_job_ = update; 1328 1329 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 1330 MockFrontend* frontend = MakeMockFrontend(); 1331 AppCacheHost* host = MakeHost(1, frontend); 1332 host->AssociateCompleteCache(cache); 1333 1334 // Give the newest cache an entry that is in storage. 1335 response_writer_.reset( 1336 service_->storage()->CreateResponseWriter(group_->manifest_url(), 1337 group_->group_id())); 1338 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"), 1339 AppCacheEntry(AppCacheEntry::EXPLICIT, 1340 response_writer_->response_id())); 1341 1342 // Set up checks for when update job finishes. 1343 do_checks_after_update_finished_ = true; 1344 expect_group_obsolete_ = false; 1345 expect_group_has_cache_ = true; 1346 expect_old_cache_ = cache; 1347 tested_manifest_ = MANIFEST1; 1348 MockFrontend::HostIds ids(1, host->host_id()); 1349 frontend->AddExpectedEvent(ids, APPCACHE_CHECKING_EVENT); 1350 frontend->AddExpectedEvent(ids, APPCACHE_DOWNLOADING_EVENT); 1351 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1352 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); 1353 frontend->AddExpectedEvent(ids, APPCACHE_PROGRESS_EVENT); // final 1354 frontend->AddExpectedEvent(ids, APPCACHE_UPDATE_READY_EVENT); 1355 1356 // Seed storage with expected http response info for entry: a vary header. 1357 const char data[] = 1358 "HTTP/1.1 200 OK\0" 1359 "Cache-Control: max-age=8675309\0" 1360 "Vary: blah\0" 1361 "\0"; 1362 net::HttpResponseHeaders* headers = 1363 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 1364 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 1365 response_info->request_time = base::Time::Now(); 1366 response_info->response_time = base::Time::Now(); 1367 response_info->headers = headers; // adds ref to headers 1368 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( 1369 new HttpResponseInfoIOBuffer(response_info)); // adds ref to info 1370 response_writer_->WriteInfo( 1371 io_buffer.get(), 1372 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 1373 base::Unretained(this))); 1374 1375 // Start update after data write completes asynchronously. 1376 } 1377 1378 void UpgradeSuccessMergedTypesTest() { 1379 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1380 1381 MakeService(); 1382 group_ = new AppCacheGroup(service_->storage(), 1383 MockHttpServer::GetMockUrl("files/manifest-merged-types"), 1384 service_->storage()->NewGroupId()); 1385 AppCacheUpdateJob* update = 1386 new AppCacheUpdateJob(service_.get(), group_.get()); 1387 group_->update_job_ = update; 1388 1389 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 1390 MockFrontend* frontend1 = MakeMockFrontend(); 1391 MockFrontend* frontend2 = MakeMockFrontend(); 1392 AppCacheHost* host1 = MakeHost(1, frontend1); 1393 AppCacheHost* host2 = MakeHost(2, frontend2); 1394 host1->AssociateCompleteCache(cache); 1395 host2->AssociateCompleteCache(cache); 1396 1397 // Give the newest cache a master entry that is also one of the explicit 1398 // entries in the manifest. 1399 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"), 1400 AppCacheEntry(AppCacheEntry::MASTER, 111)); 1401 1402 update->StartUpdate(NULL, GURL()); 1403 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1404 1405 // Set up checks for when update job finishes. 1406 do_checks_after_update_finished_ = true; 1407 expect_group_obsolete_ = false; 1408 expect_group_has_cache_ = true; 1409 expect_old_cache_ = cache; 1410 tested_manifest_ = MANIFEST_MERGED_TYPES; 1411 MockFrontend::HostIds ids1(1, host1->host_id()); 1412 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1413 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1414 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit1 1415 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // manifest 1416 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 1417 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 1418 MockFrontend::HostIds ids2(1, host2->host_id()); 1419 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1420 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1421 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1422 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1423 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 1424 frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT); 1425 1426 WaitForUpdateToFinish(); 1427 } 1428 1429 void CacheAttemptFailUrlFetchTest() { 1430 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1431 1432 MakeService(); 1433 group_ = new AppCacheGroup(service_->storage(), 1434 MockHttpServer::GetMockUrl("files/manifest-with-404"), 1435 service_->storage()->NewGroupId()); 1436 AppCacheUpdateJob* update = 1437 new AppCacheUpdateJob(service_.get(), group_.get()); 1438 group_->update_job_ = update; 1439 1440 MockFrontend* frontend = MakeMockFrontend(); 1441 AppCacheHost* host = MakeHost(1, frontend); 1442 update->StartUpdate(host, GURL()); 1443 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1444 1445 // Set up checks for when update job finishes. 1446 do_checks_after_update_finished_ = true; 1447 expect_group_obsolete_ = false; 1448 expect_group_has_cache_ = false; // 404 explicit url is cache failure 1449 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1450 APPCACHE_CHECKING_EVENT); 1451 1452 WaitForUpdateToFinish(); 1453 } 1454 1455 void UpgradeFailUrlFetchTest() { 1456 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1457 1458 MakeService(); 1459 group_ = new AppCacheGroup(service_->storage(), 1460 MockHttpServer::GetMockUrl("files/manifest-fb-404"), 1461 service_->storage()->NewGroupId()); 1462 AppCacheUpdateJob* update = 1463 new AppCacheUpdateJob(service_.get(), group_.get()); 1464 group_->update_job_ = update; 1465 1466 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 99); 1467 MockFrontend* frontend1 = MakeMockFrontend(); 1468 MockFrontend* frontend2 = MakeMockFrontend(); 1469 frontend1->SetIgnoreProgressEvents(true); 1470 frontend2->SetIgnoreProgressEvents(true); 1471 AppCacheHost* host1 = MakeHost(1, frontend1); 1472 AppCacheHost* host2 = MakeHost(2, frontend2); 1473 host1->AssociateCompleteCache(cache); 1474 host2->AssociateCompleteCache(cache); 1475 1476 update->StartUpdate(NULL, GURL()); 1477 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1478 1479 // Set up checks for when update job finishes. 1480 do_checks_after_update_finished_ = true; 1481 expect_group_obsolete_ = false; 1482 expect_group_has_cache_ = true; 1483 expect_newest_cache_ = cache; // newest cache unaffectd by failed update 1484 MockFrontend::HostIds ids1(1, host1->host_id()); 1485 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1486 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1487 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 1488 MockFrontend::HostIds ids2(1, host2->host_id()); 1489 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1490 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1491 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 1492 1493 WaitForUpdateToFinish(); 1494 } 1495 1496 void UpgradeFailMasterUrlFetchTest() { 1497 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1498 1499 tested_manifest_path_override_ = "files/manifest1-with-notmodified"; 1500 1501 MakeService(); 1502 const GURL kManifestUrl = 1503 MockHttpServer::GetMockUrl(tested_manifest_path_override_); 1504 group_ = new AppCacheGroup( 1505 service_->storage(), kManifestUrl, 1506 service_->storage()->NewGroupId()); 1507 AppCacheUpdateJob* update = 1508 new AppCacheUpdateJob(service_.get(), group_.get()); 1509 group_->update_job_ = update; 1510 1511 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 25); 1512 MockFrontend* frontend1 = MakeMockFrontend(); 1513 MockFrontend* frontend2 = MakeMockFrontend(); 1514 AppCacheHost* host1 = MakeHost(1, frontend1); 1515 AppCacheHost* host2 = MakeHost(2, frontend2); 1516 host1->AssociateCompleteCache(cache); 1517 host2->AssociateCompleteCache(cache); 1518 1519 // Give the newest cache some existing entries; one will fail with a 404. 1520 cache->AddEntry( 1521 MockHttpServer::GetMockUrl("files/notfound"), 1522 AppCacheEntry(AppCacheEntry::MASTER, 222)); 1523 cache->AddEntry( 1524 MockHttpServer::GetMockUrl("files/explicit2"), 1525 AppCacheEntry(AppCacheEntry::MASTER | AppCacheEntry::FOREIGN, 333)); 1526 cache->AddEntry( 1527 MockHttpServer::GetMockUrl("files/servererror"), 1528 AppCacheEntry(AppCacheEntry::MASTER, 444)); 1529 cache->AddEntry( 1530 MockHttpServer::GetMockUrl("files/notmodified"), 1531 AppCacheEntry(AppCacheEntry::EXPLICIT, 555)); 1532 1533 // Seed the response_info working set with canned data for 1534 // files/servererror and for files/notmodified to test that the 1535 // existing entries for those resource are reused by the update job. 1536 const char kData[] = 1537 "HTTP/1.1 200 OK\0" 1538 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0" 1539 "\0"; 1540 const std::string kRawHeaders(kData, arraysize(kData)); 1541 MakeAppCacheResponseInfo(kManifestUrl, 444, kRawHeaders); 1542 MakeAppCacheResponseInfo(kManifestUrl, 555, kRawHeaders); 1543 1544 update->StartUpdate(NULL, GURL()); 1545 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1546 1547 // Set up checks for when update job finishes. 1548 do_checks_after_update_finished_ = true; 1549 expect_group_obsolete_ = false; 1550 expect_group_has_cache_ = true; 1551 expect_old_cache_ = cache; 1552 tested_manifest_ = MANIFEST1; 1553 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 1554 MockHttpServer::GetMockUrl("files/explicit2"), 1555 AppCacheEntry(AppCacheEntry::MASTER))); // foreign flag is dropped 1556 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 1557 MockHttpServer::GetMockUrl("files/servererror"), 1558 AppCacheEntry(AppCacheEntry::MASTER))); 1559 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 1560 MockHttpServer::GetMockUrl("files/notmodified"), 1561 AppCacheEntry(AppCacheEntry::EXPLICIT))); 1562 expect_response_ids_.insert(std::map<GURL, int64>::value_type( 1563 MockHttpServer::GetMockUrl("files/servererror"), 444)); // copied 1564 expect_response_ids_.insert(std::map<GURL, int64>::value_type( 1565 MockHttpServer::GetMockUrl("files/notmodified"), 555)); // copied 1566 MockFrontend::HostIds ids1(1, host1->host_id()); 1567 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1568 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1569 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit1 1570 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // fallback1a 1571 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // notfound 1572 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // explicit2 1573 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // servererror 1574 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // notmodified 1575 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 1576 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 1577 MockFrontend::HostIds ids2(1, host2->host_id()); 1578 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1579 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1580 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // explicit1 1581 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // fallback1a 1582 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // notfound 1583 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // explicit2 1584 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // servererror 1585 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // notmodified 1586 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 1587 frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT); 1588 1589 WaitForUpdateToFinish(); 1590 } 1591 1592 void EmptyManifestTest() { 1593 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1594 1595 MakeService(); 1596 group_ = new AppCacheGroup( 1597 service_->storage(), MockHttpServer::GetMockUrl("files/empty-manifest"), 1598 service_->storage()->NewGroupId()); 1599 AppCacheUpdateJob* update = 1600 new AppCacheUpdateJob(service_.get(), group_.get()); 1601 group_->update_job_ = update; 1602 1603 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 33); 1604 MockFrontend* frontend1 = MakeMockFrontend(); 1605 MockFrontend* frontend2 = MakeMockFrontend(); 1606 AppCacheHost* host1 = MakeHost(1, frontend1); 1607 AppCacheHost* host2 = MakeHost(2, frontend2); 1608 host1->AssociateCompleteCache(cache); 1609 host2->AssociateCompleteCache(cache); 1610 1611 frontend1->SetVerifyProgressEvents(true); 1612 1613 update->StartUpdate(NULL, GURL()); 1614 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1615 1616 // Set up checks for when update job finishes. 1617 do_checks_after_update_finished_ = true; 1618 expect_group_obsolete_ = false; 1619 expect_group_has_cache_ = true; 1620 expect_old_cache_ = cache; 1621 tested_manifest_ = EMPTY_MANIFEST; 1622 MockFrontend::HostIds ids1(1, host1->host_id()); 1623 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1624 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1625 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 1626 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 1627 MockFrontend::HostIds ids2(1, host2->host_id()); 1628 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1629 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1630 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 1631 frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT); 1632 1633 WaitForUpdateToFinish(); 1634 } 1635 1636 void EmptyFileTest() { 1637 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1638 1639 MakeService(); 1640 group_ = new AppCacheGroup(service_->storage(), 1641 MockHttpServer::GetMockUrl("files/empty-file-manifest"), 1642 service_->storage()->NewGroupId()); 1643 AppCacheUpdateJob* update = 1644 new AppCacheUpdateJob(service_.get(), group_.get()); 1645 group_->update_job_ = update; 1646 1647 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 22); 1648 MockFrontend* frontend = MakeMockFrontend(); 1649 AppCacheHost* host = MakeHost(1, frontend); 1650 host->AssociateCompleteCache(cache); 1651 frontend->SetVerifyProgressEvents(true); 1652 1653 update->StartUpdate(host, GURL()); 1654 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1655 1656 // Set up checks for when update job finishes. 1657 do_checks_after_update_finished_ = true; 1658 expect_group_obsolete_ = false; 1659 expect_group_has_cache_ = true; 1660 tested_manifest_ = EMPTY_FILE_MANIFEST; 1661 MockFrontend::HostIds ids1(1, host->host_id()); 1662 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1663 frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1664 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 1665 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 1666 frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 1667 1668 WaitForUpdateToFinish(); 1669 } 1670 1671 void RetryRequestTest() { 1672 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1673 1674 // Set some large number of times to return retry. 1675 // Expect 1 manifest fetch and 3 retries. 1676 RetryRequestTestJob::Initialize(5, RetryRequestTestJob::RETRY_AFTER_0, 4); 1677 net::URLRequestJobFactoryImpl* new_factory( 1678 new net::URLRequestJobFactoryImpl); 1679 new_factory->SetProtocolHandler("http", new RetryRequestTestJobFactory); 1680 io_thread_->SetNewJobFactory(new_factory); 1681 1682 MakeService(); 1683 group_ = new AppCacheGroup(service_->storage(), 1684 RetryRequestTestJob::kRetryUrl, 1685 service_->storage()->NewGroupId()); 1686 AppCacheUpdateJob* update = 1687 new AppCacheUpdateJob(service_.get(), group_.get()); 1688 group_->update_job_ = update; 1689 1690 MockFrontend* frontend = MakeMockFrontend(); 1691 AppCacheHost* host = MakeHost(1, frontend); 1692 update->StartUpdate(host, GURL()); 1693 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1694 1695 // Set up checks for when update job finishes. 1696 do_checks_after_update_finished_ = true; 1697 expect_group_obsolete_ = false; 1698 expect_group_has_cache_ = false; 1699 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1700 APPCACHE_CHECKING_EVENT); 1701 1702 WaitForUpdateToFinish(); 1703 } 1704 1705 void RetryNoRetryAfterTest() { 1706 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1707 1708 // Set some large number of times to return retry. 1709 // Expect 1 manifest fetch and 0 retries. 1710 RetryRequestTestJob::Initialize(5, RetryRequestTestJob::NO_RETRY_AFTER, 1); 1711 net::URLRequestJobFactoryImpl* new_factory( 1712 new net::URLRequestJobFactoryImpl); 1713 new_factory->SetProtocolHandler("http", new RetryRequestTestJobFactory); 1714 io_thread_->SetNewJobFactory(new_factory); 1715 1716 MakeService(); 1717 group_ = new AppCacheGroup(service_->storage(), 1718 RetryRequestTestJob::kRetryUrl, 1719 service_->storage()->NewGroupId()); 1720 AppCacheUpdateJob* update = 1721 new AppCacheUpdateJob(service_.get(), group_.get()); 1722 group_->update_job_ = update; 1723 1724 MockFrontend* frontend = MakeMockFrontend(); 1725 AppCacheHost* host = MakeHost(1, frontend); 1726 update->StartUpdate(host, GURL()); 1727 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1728 1729 // Set up checks for when update job finishes. 1730 do_checks_after_update_finished_ = true; 1731 expect_group_obsolete_ = false; 1732 expect_group_has_cache_ = false; 1733 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1734 APPCACHE_CHECKING_EVENT); 1735 1736 WaitForUpdateToFinish(); 1737 } 1738 1739 void RetryNonzeroRetryAfterTest() { 1740 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1741 1742 // Set some large number of times to return retry. 1743 // Expect 1 request and 0 retry attempts. 1744 RetryRequestTestJob::Initialize( 1745 5, RetryRequestTestJob::NONZERO_RETRY_AFTER, 1); 1746 net::URLRequestJobFactoryImpl* new_factory( 1747 new net::URLRequestJobFactoryImpl); 1748 new_factory->SetProtocolHandler("http", new RetryRequestTestJobFactory); 1749 io_thread_->SetNewJobFactory(new_factory); 1750 1751 MakeService(); 1752 group_ = new AppCacheGroup(service_->storage(), 1753 RetryRequestTestJob::kRetryUrl, 1754 service_->storage()->NewGroupId()); 1755 AppCacheUpdateJob* update = 1756 new AppCacheUpdateJob(service_.get(), group_.get()); 1757 group_->update_job_ = update; 1758 1759 MockFrontend* frontend = MakeMockFrontend(); 1760 AppCacheHost* host = MakeHost(1, frontend); 1761 update->StartUpdate(host, GURL()); 1762 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1763 1764 // Set up checks for when update job finishes. 1765 do_checks_after_update_finished_ = true; 1766 expect_group_obsolete_ = false; 1767 expect_group_has_cache_ = false; 1768 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1769 APPCACHE_CHECKING_EVENT); 1770 1771 WaitForUpdateToFinish(); 1772 } 1773 1774 void RetrySuccessTest() { 1775 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1776 1777 // Set 2 as the retry limit (does not exceed the max). 1778 // Expect 1 manifest fetch, 2 retries, 1 url fetch, 1 manifest refetch. 1779 RetryRequestTestJob::Initialize(2, RetryRequestTestJob::RETRY_AFTER_0, 5); 1780 net::URLRequestJobFactoryImpl* new_factory( 1781 new net::URLRequestJobFactoryImpl); 1782 new_factory->SetProtocolHandler("http", new RetryRequestTestJobFactory); 1783 io_thread_->SetNewJobFactory(new_factory); 1784 1785 MakeService(); 1786 group_ = new AppCacheGroup(service_->storage(), 1787 RetryRequestTestJob::kRetryUrl, 1788 service_->storage()->NewGroupId()); 1789 AppCacheUpdateJob* update = 1790 new AppCacheUpdateJob(service_.get(), group_.get()); 1791 group_->update_job_ = update; 1792 1793 MockFrontend* frontend = MakeMockFrontend(); 1794 AppCacheHost* host = MakeHost(1, frontend); 1795 update->StartUpdate(host, GURL()); 1796 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1797 1798 // Set up checks for when update job finishes. 1799 do_checks_after_update_finished_ = true; 1800 expect_group_obsolete_ = false; 1801 expect_group_has_cache_ = true; 1802 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1803 APPCACHE_CHECKING_EVENT); 1804 1805 WaitForUpdateToFinish(); 1806 } 1807 1808 void RetryUrlTest() { 1809 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1810 1811 // Set 1 as the retry limit (does not exceed the max). 1812 // Expect 1 manifest fetch, 1 url fetch, 1 url retry, 1 manifest refetch. 1813 RetryRequestTestJob::Initialize(1, RetryRequestTestJob::RETRY_AFTER_0, 4); 1814 net::URLRequestJobFactoryImpl* new_factory( 1815 new net::URLRequestJobFactoryImpl); 1816 new_factory->SetProtocolHandler("http", new RetryRequestTestJobFactory); 1817 io_thread_->SetNewJobFactory(new_factory); 1818 1819 MakeService(); 1820 group_ = new AppCacheGroup(service_->storage(), GURL("http://retryurl"), 1821 service_->storage()->NewGroupId()); 1822 AppCacheUpdateJob* update = 1823 new AppCacheUpdateJob(service_.get(), group_.get()); 1824 group_->update_job_ = update; 1825 1826 MockFrontend* frontend = MakeMockFrontend(); 1827 AppCacheHost* host = MakeHost(1, frontend); 1828 update->StartUpdate(host, GURL()); 1829 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1830 1831 // Set up checks for when update job finishes. 1832 do_checks_after_update_finished_ = true; 1833 expect_group_obsolete_ = false; 1834 expect_group_has_cache_ = true; 1835 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1836 APPCACHE_CHECKING_EVENT); 1837 1838 WaitForUpdateToFinish(); 1839 } 1840 1841 void FailStoreNewestCacheTest() { 1842 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1843 1844 MakeService(); 1845 MockAppCacheStorage* storage = 1846 reinterpret_cast<MockAppCacheStorage*>(service_->storage()); 1847 storage->SimulateStoreGroupAndNewestCacheFailure(); 1848 1849 group_ = new AppCacheGroup( 1850 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1851 service_->storage()->NewGroupId()); 1852 AppCacheUpdateJob* update = 1853 new AppCacheUpdateJob(service_.get(), group_.get()); 1854 group_->update_job_ = update; 1855 1856 MockFrontend* frontend = MakeMockFrontend(); 1857 AppCacheHost* host = MakeHost(1, frontend); 1858 update->StartUpdate(host, GURL()); 1859 1860 // Set up checks for when update job finishes. 1861 do_checks_after_update_finished_ = true; 1862 expect_group_obsolete_ = false; 1863 expect_group_has_cache_ = false; // storage failed 1864 frontend->AddExpectedEvent(MockFrontend::HostIds(1, host->host_id()), 1865 APPCACHE_CHECKING_EVENT); 1866 1867 WaitForUpdateToFinish(); 1868 } 1869 1870 void UpgradeFailStoreNewestCacheTest() { 1871 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1872 1873 MakeService(); 1874 MockAppCacheStorage* storage = 1875 reinterpret_cast<MockAppCacheStorage*>(service_->storage()); 1876 storage->SimulateStoreGroupAndNewestCacheFailure(); 1877 1878 group_ = new AppCacheGroup( 1879 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 1880 service_->storage()->NewGroupId()); 1881 AppCacheUpdateJob* update = 1882 new AppCacheUpdateJob(service_.get(), group_.get()); 1883 group_->update_job_ = update; 1884 1885 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 11); 1886 MockFrontend* frontend1 = MakeMockFrontend(); 1887 MockFrontend* frontend2 = MakeMockFrontend(); 1888 AppCacheHost* host1 = MakeHost(1, frontend1); 1889 AppCacheHost* host2 = MakeHost(2, frontend2); 1890 host1->AssociateCompleteCache(cache); 1891 host2->AssociateCompleteCache(cache); 1892 1893 update->StartUpdate(NULL, GURL()); 1894 1895 // Set up checks for when update job finishes. 1896 do_checks_after_update_finished_ = true; 1897 expect_group_obsolete_ = false; 1898 expect_group_has_cache_ = true; 1899 expect_newest_cache_ = cache; // unchanged 1900 MockFrontend::HostIds ids1(1, host1->host_id()); 1901 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1902 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 1903 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 1904 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 1905 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 1906 MockFrontend::HostIds ids2(1, host2->host_id()); 1907 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 1908 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 1909 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1910 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 1911 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 1912 1913 WaitForUpdateToFinish(); 1914 } 1915 1916 void MasterEntryFailStoreNewestCacheTest() { 1917 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1918 1919 MakeService(); 1920 MockAppCacheStorage* storage = 1921 reinterpret_cast<MockAppCacheStorage*>(service_->storage()); 1922 storage->SimulateStoreGroupAndNewestCacheFailure(); 1923 1924 const GURL kManifestUrl = MockHttpServer::GetMockUrl("files/notmodified"); 1925 const int64 kManifestResponseId = 11; 1926 1927 // Seed the response_info working set with canned data for 1928 // files/servererror and for files/notmodified to test that the 1929 // existing entries for those resource are reused by the update job. 1930 const char kData[] = 1931 "HTTP/1.1 200 OK\0" 1932 "Content-type: text/cache-manifest\0" 1933 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0" 1934 "\0"; 1935 const std::string kRawHeaders(kData, arraysize(kData)); 1936 MakeAppCacheResponseInfo(kManifestUrl, kManifestResponseId, kRawHeaders); 1937 1938 group_ = new AppCacheGroup( 1939 service_->storage(), kManifestUrl, 1940 service_->storage()->NewGroupId()); 1941 scoped_refptr<AppCache> cache( 1942 MakeCacheForGroup(service_->storage()->NewCacheId(), 1943 kManifestResponseId)); 1944 1945 MockFrontend* frontend = MakeMockFrontend(); 1946 AppCacheHost* host = MakeHost(1, frontend); 1947 host->first_party_url_ = kManifestUrl; 1948 host->SelectCache(MockHttpServer::GetMockUrl("files/empty1"), 1949 kAppCacheNoCacheId, kManifestUrl); 1950 1951 // Set up checks for when update job finishes. 1952 do_checks_after_update_finished_ = true; 1953 tested_manifest_ = EMPTY_MANIFEST; 1954 tested_manifest_path_override_ = "files/notmodified"; 1955 expect_group_obsolete_ = false; 1956 expect_group_has_cache_ = true; 1957 expect_newest_cache_ = cache.get(); // unchanged 1958 MockFrontend::HostIds ids1(1, host->host_id()); 1959 frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 1960 frontend->expected_error_message_ = 1961 "Failed to commit new cache to storage"; 1962 1963 WaitForUpdateToFinish(); 1964 } 1965 1966 void UpgradeFailMakeGroupObsoleteTest() { 1967 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 1968 1969 MakeService(); 1970 MockAppCacheStorage* storage = 1971 reinterpret_cast<MockAppCacheStorage*>(service_->storage()); 1972 storage->SimulateMakeGroupObsoleteFailure(); 1973 1974 group_ = new AppCacheGroup( 1975 service_->storage(), MockHttpServer::GetMockUrl("files/nosuchfile"), 1976 service_->storage()->NewGroupId()); 1977 AppCacheUpdateJob* update = 1978 new AppCacheUpdateJob(service_.get(), group_.get()); 1979 group_->update_job_ = update; 1980 1981 AppCache* cache = MakeCacheForGroup(1, 111); 1982 MockFrontend* frontend1 = MakeMockFrontend(); 1983 MockFrontend* frontend2 = MakeMockFrontend(); 1984 AppCacheHost* host1 = MakeHost(1, frontend1); 1985 AppCacheHost* host2 = MakeHost(2, frontend2); 1986 host1->AssociateCompleteCache(cache); 1987 host2->AssociateCompleteCache(cache); 1988 1989 update->StartUpdate(NULL, GURL()); 1990 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 1991 1992 // Set up checks for when update job finishes. 1993 do_checks_after_update_finished_ = true; 1994 expect_group_obsolete_ = false; 1995 expect_group_has_cache_ = true; 1996 expect_newest_cache_ = cache; // newest cache unaffected by update 1997 MockFrontend::HostIds ids1(1, host1->host_id()); 1998 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 1999 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2000 MockFrontend::HostIds ids2(1, host2->host_id()); 2001 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 2002 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2003 2004 WaitForUpdateToFinish(); 2005 } 2006 2007 void MasterEntryFetchManifestFailTest() { 2008 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2009 2010 MakeService(); 2011 group_ = new AppCacheGroup(service_->storage(), GURL("http://failme"), 111); 2012 AppCacheUpdateJob* update = 2013 new AppCacheUpdateJob(service_.get(), group_.get()); 2014 group_->update_job_ = update; 2015 2016 MockFrontend* frontend = MakeMockFrontend(); 2017 AppCacheHost* host = MakeHost(1, frontend); 2018 host->new_master_entry_url_ = GURL("http://failme/blah"); 2019 update->StartUpdate(host, host->new_master_entry_url_); 2020 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2021 2022 update->manifest_fetcher_->request()->CancelWithError(-100); 2023 2024 // Set up checks for when update job finishes. 2025 do_checks_after_update_finished_ = true; 2026 expect_group_obsolete_ = false; 2027 expect_group_has_cache_ = false; 2028 MockFrontend::HostIds ids1(1, host->host_id()); 2029 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2030 frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2031 2032 WaitForUpdateToFinish(); 2033 } 2034 2035 void MasterEntryBadManifestTest() { 2036 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2037 2038 MakeService(); 2039 group_ = new AppCacheGroup(service_->storage(), 2040 MockHttpServer::GetMockUrl("files/bad-manifest"), 111); 2041 AppCacheUpdateJob* update = 2042 new AppCacheUpdateJob(service_.get(), group_.get()); 2043 group_->update_job_ = update; 2044 2045 MockFrontend* frontend = MakeMockFrontend(); 2046 AppCacheHost* host = MakeHost(1, frontend); 2047 host->new_master_entry_url_ = MockHttpServer::GetMockUrl("files/blah"); 2048 update->StartUpdate(host, host->new_master_entry_url_); 2049 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2050 2051 // Set up checks for when update job finishes. 2052 do_checks_after_update_finished_ = true; 2053 expect_group_obsolete_ = false; 2054 expect_group_has_cache_ = false; 2055 MockFrontend::HostIds ids1(1, host->host_id()); 2056 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2057 frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2058 2059 WaitForUpdateToFinish(); 2060 } 2061 2062 void MasterEntryManifestNotFoundTest() { 2063 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2064 2065 MakeService(); 2066 group_ = new AppCacheGroup( 2067 service_->storage(), 2068 MockHttpServer::GetMockUrl("files/nosuchfile"), 2069 111); 2070 AppCacheUpdateJob* update = 2071 new AppCacheUpdateJob(service_.get(), group_.get()); 2072 group_->update_job_ = update; 2073 2074 MockFrontend* frontend = MakeMockFrontend(); 2075 AppCacheHost* host = MakeHost(1, frontend); 2076 host->new_master_entry_url_ = MockHttpServer::GetMockUrl("files/blah"); 2077 2078 update->StartUpdate(host, host->new_master_entry_url_); 2079 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2080 2081 // Set up checks for when update job finishes. 2082 do_checks_after_update_finished_ = true; 2083 expect_group_obsolete_ = false; 2084 expect_group_has_cache_ = false; 2085 MockFrontend::HostIds ids1(1, host->host_id()); 2086 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2087 frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2088 2089 WaitForUpdateToFinish(); 2090 } 2091 2092 void MasterEntryFailUrlFetchTest() { 2093 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2094 2095 MakeService(); 2096 group_ = new AppCacheGroup(service_->storage(), 2097 MockHttpServer::GetMockUrl("files/manifest-fb-404"), 111); 2098 AppCacheUpdateJob* update = 2099 new AppCacheUpdateJob(service_.get(), group_.get()); 2100 group_->update_job_ = update; 2101 2102 MockFrontend* frontend = MakeMockFrontend(); 2103 frontend->SetIgnoreProgressEvents(true); 2104 AppCacheHost* host = MakeHost(1, frontend); 2105 host->new_master_entry_url_ = 2106 MockHttpServer::GetMockUrl("files/explicit1"); 2107 2108 update->StartUpdate(host, host->new_master_entry_url_); 2109 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2110 2111 // Set up checks for when update job finishes. 2112 do_checks_after_update_finished_ = true; 2113 expect_group_obsolete_ = false; 2114 expect_group_has_cache_ = false; // 404 fallback url is cache failure 2115 MockFrontend::HostIds ids1(1, host->host_id()); 2116 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2117 frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2118 frontend->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2119 2120 WaitForUpdateToFinish(); 2121 } 2122 2123 void MasterEntryAllFailTest() { 2124 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2125 2126 MakeService(); 2127 group_ = new AppCacheGroup( 2128 service_->storage(), 2129 MockHttpServer::GetMockUrl("files/manifest1"), 2130 111); 2131 AppCacheUpdateJob* update = 2132 new AppCacheUpdateJob(service_.get(), group_.get()); 2133 group_->update_job_ = update; 2134 2135 MockFrontend* frontend1 = MakeMockFrontend(); 2136 frontend1->SetIgnoreProgressEvents(true); 2137 AppCacheHost* host1 = MakeHost(1, frontend1); 2138 host1->new_master_entry_url_ = 2139 MockHttpServer::GetMockUrl("files/nosuchfile"); 2140 update->StartUpdate(host1, host1->new_master_entry_url_); 2141 2142 MockFrontend* frontend2 = MakeMockFrontend(); 2143 frontend2->SetIgnoreProgressEvents(true); 2144 AppCacheHost* host2 = MakeHost(2, frontend2); 2145 host2->new_master_entry_url_ = 2146 MockHttpServer::GetMockUrl("files/servererror"); 2147 update->StartUpdate(host2, host2->new_master_entry_url_); 2148 2149 // Set up checks for when update job finishes. 2150 do_checks_after_update_finished_ = true; 2151 expect_group_obsolete_ = false; 2152 expect_group_has_cache_ = false; // all pending masters failed 2153 MockFrontend::HostIds ids1(1, host1->host_id()); 2154 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2155 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2156 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2157 MockFrontend::HostIds ids2(1, host2->host_id()); 2158 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 2159 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2160 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2161 2162 WaitForUpdateToFinish(); 2163 } 2164 2165 void UpgradeMasterEntryAllFailTest() { 2166 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2167 2168 MakeService(); 2169 group_ = new AppCacheGroup( 2170 service_->storage(), 2171 MockHttpServer::GetMockUrl("files/manifest1"), 2172 111); 2173 AppCacheUpdateJob* update = 2174 new AppCacheUpdateJob(service_.get(), group_.get()); 2175 group_->update_job_ = update; 2176 2177 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 2178 MockFrontend* frontend1 = MakeMockFrontend(); 2179 AppCacheHost* host1 = MakeHost(1, frontend1); 2180 host1->AssociateCompleteCache(cache); 2181 2182 MockFrontend* frontend2 = MakeMockFrontend(); 2183 frontend2->SetIgnoreProgressEvents(true); 2184 AppCacheHost* host2 = MakeHost(2, frontend2); 2185 host2->new_master_entry_url_ = 2186 MockHttpServer::GetMockUrl("files/nosuchfile"); 2187 update->StartUpdate(host2, host2->new_master_entry_url_); 2188 2189 MockFrontend* frontend3 = MakeMockFrontend(); 2190 frontend3->SetIgnoreProgressEvents(true); 2191 AppCacheHost* host3 = MakeHost(3, frontend3); 2192 host3->new_master_entry_url_ = 2193 MockHttpServer::GetMockUrl("files/servererror"); 2194 update->StartUpdate(host3, host3->new_master_entry_url_); 2195 2196 // Set up checks for when update job finishes. 2197 do_checks_after_update_finished_ = true; 2198 expect_group_obsolete_ = false; 2199 expect_group_has_cache_ = true; 2200 expect_old_cache_ = cache; 2201 tested_manifest_ = MANIFEST1; 2202 MockFrontend::HostIds ids1(1, host1->host_id()); 2203 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2204 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2205 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2206 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2207 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2208 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 2209 MockFrontend::HostIds ids2(1, host2->host_id()); 2210 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2211 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2212 MockFrontend::HostIds ids3(1, host3->host_id()); 2213 frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2214 frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT); 2215 frontend3->AddExpectedEvent(ids3, APPCACHE_ERROR_EVENT); 2216 2217 WaitForUpdateToFinish(); 2218 } 2219 2220 void MasterEntrySomeFailTest() { 2221 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2222 2223 MakeService(); 2224 group_ = new AppCacheGroup( 2225 service_->storage(), 2226 MockHttpServer::GetMockUrl("files/manifest1"), 2227 111); 2228 AppCacheUpdateJob* update = 2229 new AppCacheUpdateJob(service_.get(), group_.get()); 2230 group_->update_job_ = update; 2231 2232 MockFrontend* frontend1 = MakeMockFrontend(); 2233 frontend1->SetIgnoreProgressEvents(true); 2234 AppCacheHost* host1 = MakeHost(1, frontend1); 2235 host1->new_master_entry_url_ = 2236 MockHttpServer::GetMockUrl("files/nosuchfile"); 2237 update->StartUpdate(host1, host1->new_master_entry_url_); 2238 2239 MockFrontend* frontend2 = MakeMockFrontend(); 2240 AppCacheHost* host2 = MakeHost(2, frontend2); 2241 host2->new_master_entry_url_ = 2242 MockHttpServer::GetMockUrl("files/explicit2"); 2243 update->StartUpdate(host2, host2->new_master_entry_url_); 2244 2245 // Set up checks for when update job finishes. 2246 do_checks_after_update_finished_ = true; 2247 expect_group_obsolete_ = false; 2248 expect_group_has_cache_ = true; // as long as one pending master succeeds 2249 tested_manifest_ = MANIFEST1; 2250 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 2251 MockHttpServer::GetMockUrl("files/explicit2"), 2252 AppCacheEntry(AppCacheEntry::MASTER))); 2253 MockFrontend::HostIds ids1(1, host1->host_id()); 2254 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2255 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2256 frontend1->AddExpectedEvent(ids1, APPCACHE_ERROR_EVENT); 2257 MockFrontend::HostIds ids2(1, host2->host_id()); 2258 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 2259 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2260 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 2261 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 2262 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 2263 frontend2->AddExpectedEvent(ids2, APPCACHE_CACHED_EVENT); 2264 2265 WaitForUpdateToFinish(); 2266 } 2267 2268 void UpgradeMasterEntrySomeFailTest() { 2269 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2270 2271 MakeService(); 2272 group_ = new AppCacheGroup( 2273 service_->storage(), 2274 MockHttpServer::GetMockUrl("files/manifest1"), 2275 111); 2276 AppCacheUpdateJob* update = 2277 new AppCacheUpdateJob(service_.get(), group_.get()); 2278 group_->update_job_ = update; 2279 2280 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 2281 MockFrontend* frontend1 = MakeMockFrontend(); 2282 AppCacheHost* host1 = MakeHost(1, frontend1); 2283 host1->AssociateCompleteCache(cache); 2284 2285 MockFrontend* frontend2 = MakeMockFrontend(); 2286 frontend2->SetIgnoreProgressEvents(true); 2287 AppCacheHost* host2 = MakeHost(2, frontend2); 2288 host2->new_master_entry_url_ = 2289 MockHttpServer::GetMockUrl("files/nosuchfile"); 2290 update->StartUpdate(host2, host2->new_master_entry_url_); 2291 2292 MockFrontend* frontend3 = MakeMockFrontend(); 2293 AppCacheHost* host3 = MakeHost(3, frontend3); 2294 host3->new_master_entry_url_ = 2295 MockHttpServer::GetMockUrl("files/explicit2"); 2296 update->StartUpdate(host3, host3->new_master_entry_url_); 2297 2298 // Set up checks for when update job finishes. 2299 do_checks_after_update_finished_ = true; 2300 expect_group_obsolete_ = false; 2301 expect_group_has_cache_ = true; 2302 expect_old_cache_ = cache; 2303 tested_manifest_ = MANIFEST1; 2304 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 2305 MockHttpServer::GetMockUrl("files/explicit2"), 2306 AppCacheEntry(AppCacheEntry::MASTER))); 2307 MockFrontend::HostIds ids1(1, host1->host_id()); 2308 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2309 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2310 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2311 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2312 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2313 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 2314 MockFrontend::HostIds ids2(1, host2->host_id()); 2315 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2316 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2317 MockFrontend::HostIds ids3(1, host3->host_id()); 2318 frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2319 frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT); 2320 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); 2321 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); 2322 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final 2323 frontend3->AddExpectedEvent(ids3, APPCACHE_UPDATE_READY_EVENT); 2324 2325 WaitForUpdateToFinish(); 2326 } 2327 2328 void MasterEntryNoUpdateTest() { 2329 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2330 2331 MakeService(); 2332 group_ = new AppCacheGroup(service_->storage(), 2333 MockHttpServer::GetMockUrl("files/notmodified"), 111); 2334 AppCacheUpdateJob* update = 2335 new AppCacheUpdateJob(service_.get(), group_.get()); 2336 group_->update_job_ = update; 2337 2338 AppCache* cache = MakeCacheForGroup(1, 111); 2339 MockFrontend* frontend1 = MakeMockFrontend(); 2340 AppCacheHost* host1 = MakeHost(1, frontend1); 2341 host1->AssociateCompleteCache(cache); 2342 2343 // Give cache an existing entry that can also be fetched. 2344 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit2"), 2345 AppCacheEntry(AppCacheEntry::EXPLICIT, 222)); 2346 2347 // Reset the update time to null so we can verify it gets 2348 // modified in this test case by the UpdateJob. 2349 cache->set_update_time(base::Time()); 2350 2351 MockFrontend* frontend2 = MakeMockFrontend(); 2352 AppCacheHost* host2 = MakeHost(2, frontend2); 2353 host2->new_master_entry_url_ = 2354 MockHttpServer::GetMockUrl("files/explicit1"); 2355 update->StartUpdate(host2, host2->new_master_entry_url_); 2356 2357 AppCacheHost* host3 = MakeHost(3, frontend2); // same frontend as host2 2358 host3->new_master_entry_url_ = 2359 MockHttpServer::GetMockUrl("files/explicit2"); 2360 update->StartUpdate(host3, host3->new_master_entry_url_); 2361 2362 // Set up checks for when update job finishes. 2363 do_checks_after_update_finished_ = true; 2364 expect_group_obsolete_ = false; 2365 expect_group_has_cache_ = true; 2366 expect_newest_cache_ = cache; // newest cache still the same cache 2367 expect_non_null_update_time_ = true; 2368 tested_manifest_ = PENDING_MASTER_NO_UPDATE; 2369 MockFrontend::HostIds ids1(1, host1->host_id()); 2370 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2371 frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT); 2372 MockFrontend::HostIds ids3(1, host3->host_id()); 2373 frontend2->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2374 MockFrontend::HostIds ids2and3; 2375 ids2and3.push_back(host2->host_id()); 2376 ids2and3.push_back(host3->host_id()); 2377 frontend2->AddExpectedEvent(ids2and3, APPCACHE_NO_UPDATE_EVENT); 2378 2379 WaitForUpdateToFinish(); 2380 } 2381 2382 void StartUpdateMidCacheAttemptTest() { 2383 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2384 2385 MakeService(); 2386 group_ = new AppCacheGroup( 2387 service_->storage(), MockHttpServer::GetMockUrl("files/manifest1"), 2388 service_->storage()->NewGroupId()); 2389 AppCacheUpdateJob* update = 2390 new AppCacheUpdateJob(service_.get(), group_.get()); 2391 group_->update_job_ = update; 2392 2393 MockFrontend* frontend1 = MakeMockFrontend(); 2394 AppCacheHost* host1 = MakeHost(1, frontend1); 2395 host1->new_master_entry_url_ = 2396 MockHttpServer::GetMockUrl("files/explicit2"); 2397 update->StartUpdate(host1, host1->new_master_entry_url_); 2398 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2399 2400 // Set up additional updates to be started while update is in progress. 2401 MockFrontend* frontend2 = MakeMockFrontend(); 2402 frontend2->SetIgnoreProgressEvents(true); 2403 AppCacheHost* host2 = MakeHost(2, frontend2); 2404 host2->new_master_entry_url_ = 2405 MockHttpServer::GetMockUrl("files/nosuchfile"); 2406 2407 MockFrontend* frontend3 = MakeMockFrontend(); 2408 AppCacheHost* host3 = MakeHost(3, frontend3); 2409 host3->new_master_entry_url_ = 2410 MockHttpServer::GetMockUrl("files/explicit1"); 2411 2412 MockFrontend* frontend4 = MakeMockFrontend(); 2413 AppCacheHost* host4 = MakeHost(4, frontend4); 2414 host4->new_master_entry_url_ = 2415 MockHttpServer::GetMockUrl("files/explicit2"); 2416 2417 MockFrontend* frontend5 = MakeMockFrontend(); 2418 AppCacheHost* host5 = MakeHost(5, frontend5); // no master entry url 2419 2420 frontend1->TriggerAdditionalUpdates(APPCACHE_DOWNLOADING_EVENT, update); 2421 frontend1->AdditionalUpdateHost(host2); // fetch will fail 2422 frontend1->AdditionalUpdateHost(host3); // same as an explicit entry 2423 frontend1->AdditionalUpdateHost(host4); // same as another master entry 2424 frontend1->AdditionalUpdateHost(NULL); // no host 2425 frontend1->AdditionalUpdateHost(host5); // no master entry url 2426 2427 // Set up checks for when update job finishes. 2428 do_checks_after_update_finished_ = true; 2429 expect_group_obsolete_ = false; 2430 expect_group_has_cache_ = true; 2431 tested_manifest_ = MANIFEST1; 2432 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 2433 MockHttpServer::GetMockUrl("files/explicit2"), 2434 AppCacheEntry(AppCacheEntry::MASTER))); 2435 MockFrontend::HostIds ids1(1, host1->host_id()); 2436 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2437 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2438 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2439 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2440 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2441 frontend1->AddExpectedEvent(ids1, APPCACHE_CACHED_EVENT); 2442 MockFrontend::HostIds ids2(1, host2->host_id()); 2443 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 2444 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2445 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2446 MockFrontend::HostIds ids3(1, host3->host_id()); 2447 frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2448 frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT); 2449 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); 2450 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); 2451 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final 2452 frontend3->AddExpectedEvent(ids3, APPCACHE_CACHED_EVENT); 2453 MockFrontend::HostIds ids4(1, host4->host_id()); 2454 frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT); 2455 frontend4->AddExpectedEvent(ids4, APPCACHE_DOWNLOADING_EVENT); 2456 frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT); 2457 frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT); 2458 frontend4->AddExpectedEvent(ids4, APPCACHE_PROGRESS_EVENT); // final 2459 frontend4->AddExpectedEvent(ids4, APPCACHE_CACHED_EVENT); 2460 2461 // Host 5 is not associated with cache so no progress/cached events. 2462 MockFrontend::HostIds ids5(1, host5->host_id()); 2463 frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT); 2464 frontend5->AddExpectedEvent(ids5, APPCACHE_DOWNLOADING_EVENT); 2465 2466 WaitForUpdateToFinish(); 2467 } 2468 2469 void StartUpdateMidNoUpdateTest() { 2470 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2471 2472 MakeService(); 2473 group_ = new AppCacheGroup( 2474 service_->storage(), MockHttpServer::GetMockUrl("files/notmodified"), 2475 service_->storage()->NewGroupId()); 2476 AppCacheUpdateJob* update = 2477 new AppCacheUpdateJob(service_.get(), group_.get()); 2478 group_->update_job_ = update; 2479 2480 AppCache* cache = MakeCacheForGroup(1, 111); 2481 MockFrontend* frontend1 = MakeMockFrontend(); 2482 AppCacheHost* host1 = MakeHost(1, frontend1); 2483 host1->AssociateCompleteCache(cache); 2484 2485 // Give cache an existing entry. 2486 cache->AddEntry(MockHttpServer::GetMockUrl("files/explicit2"), 2487 AppCacheEntry(AppCacheEntry::EXPLICIT, 222)); 2488 2489 // Start update with a pending master entry that will fail to give us an 2490 // event to trigger other updates. 2491 MockFrontend* frontend2 = MakeMockFrontend(); 2492 AppCacheHost* host2 = MakeHost(2, frontend2); 2493 host2->new_master_entry_url_ = 2494 MockHttpServer::GetMockUrl("files/nosuchfile"); 2495 update->StartUpdate(host2, host2->new_master_entry_url_); 2496 EXPECT_TRUE(update->manifest_fetcher_ != NULL); 2497 2498 // Set up additional updates to be started while update is in progress. 2499 MockFrontend* frontend3 = MakeMockFrontend(); 2500 AppCacheHost* host3 = MakeHost(3, frontend3); 2501 host3->new_master_entry_url_ = 2502 MockHttpServer::GetMockUrl("files/explicit1"); 2503 2504 MockFrontend* frontend4 = MakeMockFrontend(); 2505 AppCacheHost* host4 = MakeHost(4, frontend4); // no master entry url 2506 2507 MockFrontend* frontend5 = MakeMockFrontend(); 2508 AppCacheHost* host5 = MakeHost(5, frontend5); 2509 host5->new_master_entry_url_ = 2510 MockHttpServer::GetMockUrl("files/explicit2"); // existing entry 2511 2512 MockFrontend* frontend6 = MakeMockFrontend(); 2513 AppCacheHost* host6 = MakeHost(6, frontend6); 2514 host6->new_master_entry_url_ = 2515 MockHttpServer::GetMockUrl("files/explicit1"); 2516 2517 frontend2->TriggerAdditionalUpdates(APPCACHE_ERROR_EVENT, update); 2518 frontend2->AdditionalUpdateHost(host3); 2519 frontend2->AdditionalUpdateHost(NULL); // no host 2520 frontend2->AdditionalUpdateHost(host4); // no master entry url 2521 frontend2->AdditionalUpdateHost(host5); // same as existing cache entry 2522 frontend2->AdditionalUpdateHost(host6); // same as another master entry 2523 2524 // Set up checks for when update job finishes. 2525 do_checks_after_update_finished_ = true; 2526 expect_group_obsolete_ = false; 2527 expect_group_has_cache_ = true; 2528 expect_newest_cache_ = cache; // newest cache unaffected by update 2529 tested_manifest_ = PENDING_MASTER_NO_UPDATE; 2530 MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host 2531 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2532 frontend1->AddExpectedEvent(ids1, APPCACHE_NO_UPDATE_EVENT); 2533 MockFrontend::HostIds ids2(1, host2->host_id()); 2534 frontend2->AddExpectedEvent(ids2, APPCACHE_ERROR_EVENT); 2535 MockFrontend::HostIds ids3(1, host3->host_id()); 2536 frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2537 frontend3->AddExpectedEvent(ids3, APPCACHE_NO_UPDATE_EVENT); 2538 MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache 2539 frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT); 2540 MockFrontend::HostIds ids5(1, host5->host_id()); 2541 frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT); 2542 frontend5->AddExpectedEvent(ids5, APPCACHE_NO_UPDATE_EVENT); 2543 MockFrontend::HostIds ids6(1, host6->host_id()); 2544 frontend6->AddExpectedEvent(ids6, APPCACHE_CHECKING_EVENT); 2545 frontend6->AddExpectedEvent(ids6, APPCACHE_NO_UPDATE_EVENT); 2546 2547 WaitForUpdateToFinish(); 2548 } 2549 2550 void StartUpdateMidDownloadTest() { 2551 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2552 2553 MakeService(); 2554 group_ = new AppCacheGroup( 2555 service_->storage(), 2556 MockHttpServer::GetMockUrl("files/manifest1"), 2557 111); 2558 AppCacheUpdateJob* update = 2559 new AppCacheUpdateJob(service_.get(), group_.get()); 2560 group_->update_job_ = update; 2561 2562 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 42); 2563 MockFrontend* frontend1 = MakeMockFrontend(); 2564 AppCacheHost* host1 = MakeHost(1, frontend1); 2565 host1->AssociateCompleteCache(cache); 2566 2567 update->StartUpdate(NULL, GURL()); 2568 2569 // Set up additional updates to be started while update is in progress. 2570 MockFrontend* frontend2 = MakeMockFrontend(); 2571 AppCacheHost* host2 = MakeHost(2, frontend2); 2572 host2->new_master_entry_url_ = 2573 MockHttpServer::GetMockUrl("files/explicit1"); 2574 2575 MockFrontend* frontend3 = MakeMockFrontend(); 2576 AppCacheHost* host3 = MakeHost(3, frontend3); 2577 host3->new_master_entry_url_ = 2578 MockHttpServer::GetMockUrl("files/explicit2"); 2579 2580 MockFrontend* frontend4 = MakeMockFrontend(); 2581 AppCacheHost* host4 = MakeHost(4, frontend4); // no master entry url 2582 2583 MockFrontend* frontend5 = MakeMockFrontend(); 2584 AppCacheHost* host5 = MakeHost(5, frontend5); 2585 host5->new_master_entry_url_ = 2586 MockHttpServer::GetMockUrl("files/explicit2"); 2587 2588 frontend1->TriggerAdditionalUpdates(APPCACHE_PROGRESS_EVENT, update); 2589 frontend1->AdditionalUpdateHost(host2); // same as entry in manifest 2590 frontend1->AdditionalUpdateHost(NULL); // no host 2591 frontend1->AdditionalUpdateHost(host3); // new master entry 2592 frontend1->AdditionalUpdateHost(host4); // no master entry url 2593 frontend1->AdditionalUpdateHost(host5); // same as another master entry 2594 2595 // Set up checks for when update job finishes. 2596 do_checks_after_update_finished_ = true; 2597 expect_group_obsolete_ = false; 2598 expect_group_has_cache_ = true; 2599 tested_manifest_ = MANIFEST1; 2600 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 2601 MockHttpServer::GetMockUrl("files/explicit2"), 2602 AppCacheEntry(AppCacheEntry::MASTER))); 2603 MockFrontend::HostIds ids1(1, host1->host_id()); // prior associated host 2604 frontend1->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2605 frontend1->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2606 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2607 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2608 frontend1->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2609 frontend1->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 2610 MockFrontend::HostIds ids2(1, host2->host_id()); 2611 frontend2->AddExpectedEvent(ids2, APPCACHE_CHECKING_EVENT); 2612 frontend2->AddExpectedEvent(ids2, APPCACHE_DOWNLOADING_EVENT); 2613 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); 2614 frontend2->AddExpectedEvent(ids2, APPCACHE_PROGRESS_EVENT); // final 2615 frontend2->AddExpectedEvent(ids2, APPCACHE_UPDATE_READY_EVENT); 2616 MockFrontend::HostIds ids3(1, host3->host_id()); 2617 frontend3->AddExpectedEvent(ids3, APPCACHE_CHECKING_EVENT); 2618 frontend3->AddExpectedEvent(ids3, APPCACHE_DOWNLOADING_EVENT); 2619 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); 2620 frontend3->AddExpectedEvent(ids3, APPCACHE_PROGRESS_EVENT); // final 2621 frontend3->AddExpectedEvent(ids3, APPCACHE_UPDATE_READY_EVENT); 2622 MockFrontend::HostIds ids4(1, host4->host_id()); // unassociated w/cache 2623 frontend4->AddExpectedEvent(ids4, APPCACHE_CHECKING_EVENT); 2624 frontend4->AddExpectedEvent(ids4, APPCACHE_DOWNLOADING_EVENT); 2625 MockFrontend::HostIds ids5(1, host5->host_id()); 2626 frontend5->AddExpectedEvent(ids5, APPCACHE_CHECKING_EVENT); 2627 frontend5->AddExpectedEvent(ids5, APPCACHE_DOWNLOADING_EVENT); 2628 frontend5->AddExpectedEvent(ids5, APPCACHE_PROGRESS_EVENT); 2629 frontend5->AddExpectedEvent(ids5, APPCACHE_PROGRESS_EVENT); // final 2630 frontend5->AddExpectedEvent(ids5, APPCACHE_UPDATE_READY_EVENT); 2631 2632 WaitForUpdateToFinish(); 2633 } 2634 2635 void QueueMasterEntryTest() { 2636 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2637 2638 MakeService(); 2639 group_ = new AppCacheGroup( 2640 service_->storage(), 2641 MockHttpServer::GetMockUrl("files/manifest1"), 2642 111); 2643 AppCacheUpdateJob* update = 2644 new AppCacheUpdateJob(service_.get(), group_.get()); 2645 group_->update_job_ = update; 2646 2647 // Pretend update job has been running and is about to terminate. 2648 group_->update_status_ = AppCacheGroup::DOWNLOADING; 2649 update->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST; 2650 EXPECT_TRUE(update->IsTerminating()); 2651 2652 // Start an update. Should be queued. 2653 MockFrontend* frontend = MakeMockFrontend(); 2654 AppCacheHost* host = MakeHost(1, frontend); 2655 host->new_master_entry_url_ = 2656 MockHttpServer::GetMockUrl("files/explicit2"); 2657 update->StartUpdate(host, host->new_master_entry_url_); 2658 EXPECT_TRUE(update->pending_master_entries_.empty()); 2659 EXPECT_FALSE(group_->queued_updates_.empty()); 2660 2661 // Delete update, causing it to finish, which should trigger a new update 2662 // for the queued host and master entry after a delay. 2663 delete update; 2664 EXPECT_FALSE(group_->restart_update_task_.IsCancelled()); 2665 2666 // Set up checks for when queued update job finishes. 2667 do_checks_after_update_finished_ = true; 2668 expect_group_obsolete_ = false; 2669 expect_group_has_cache_ = true; 2670 tested_manifest_ = MANIFEST1; 2671 expect_extra_entries_.insert(AppCache::EntryMap::value_type( 2672 host->new_master_entry_url_, AppCacheEntry(AppCacheEntry::MASTER))); 2673 MockFrontend::HostIds ids1(1, host->host_id()); 2674 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2675 frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2676 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2677 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2678 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2679 frontend->AddExpectedEvent(ids1, APPCACHE_CACHED_EVENT); 2680 2681 // Group status will be APPCACHE_STATUS_IDLE so cannot call 2682 // WaitForUpdateToFinish. 2683 group_->AddUpdateObserver(this); 2684 } 2685 2686 void IfModifiedSinceTest() { 2687 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2688 2689 net::URLRequestJobFactoryImpl* new_factory( 2690 new net::URLRequestJobFactoryImpl); 2691 new_factory->SetProtocolHandler("http", new IfModifiedSinceJobFactory); 2692 io_thread_->SetNewJobFactory(new_factory); 2693 2694 MakeService(); 2695 group_ = new AppCacheGroup( 2696 service_->storage(), GURL("http://headertest"), 111); 2697 AppCacheUpdateJob* update = 2698 new AppCacheUpdateJob(service_.get(), group_.get()); 2699 group_->update_job_ = update; 2700 2701 // First test against a cache attempt. Will start manifest fetch 2702 // synchronously. 2703 HttpHeadersRequestTestJob::Initialize(std::string(), std::string()); 2704 MockFrontend mock_frontend; 2705 AppCacheHost host(1, &mock_frontend, service_.get()); 2706 update->StartUpdate(&host, GURL()); 2707 HttpHeadersRequestTestJob::Verify(); 2708 delete update; 2709 2710 // Now simulate a refetch manifest request. Will start fetch request 2711 // synchronously. 2712 const char data[] = 2713 "HTTP/1.1 200 OK\0" 2714 "\0"; 2715 net::HttpResponseHeaders* headers = 2716 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 2717 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 2718 response_info->headers = headers; // adds ref to headers 2719 2720 HttpHeadersRequestTestJob::Initialize(std::string(), std::string()); 2721 update = new AppCacheUpdateJob(service_.get(), group_.get()); 2722 group_->update_job_ = update; 2723 group_->update_status_ = AppCacheGroup::DOWNLOADING; 2724 update->manifest_response_info_.reset(response_info); 2725 update->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST; 2726 update->FetchManifest(false); // not first request 2727 HttpHeadersRequestTestJob::Verify(); 2728 delete update; 2729 2730 // Change the headers to include a Last-Modified header. Manifest refetch 2731 // should include If-Modified-Since header. 2732 const char data2[] = 2733 "HTTP/1.1 200 OK\0" 2734 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0" 2735 "\0"; 2736 net::HttpResponseHeaders* headers2 = 2737 new net::HttpResponseHeaders(std::string(data2, arraysize(data2))); 2738 response_info = new net::HttpResponseInfo(); 2739 response_info->headers = headers2; 2740 2741 HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT", 2742 std::string()); 2743 update = new AppCacheUpdateJob(service_.get(), group_.get()); 2744 group_->update_job_ = update; 2745 group_->update_status_ = AppCacheGroup::DOWNLOADING; 2746 update->manifest_response_info_.reset(response_info); 2747 update->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST; 2748 update->FetchManifest(false); // not first request 2749 HttpHeadersRequestTestJob::Verify(); 2750 delete update; 2751 2752 UpdateFinished(); 2753 } 2754 2755 void IfModifiedSinceUpgradeTest() { 2756 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2757 2758 HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT", 2759 std::string()); 2760 net::URLRequestJobFactoryImpl* new_factory( 2761 new net::URLRequestJobFactoryImpl); 2762 new_factory->SetProtocolHandler("http", new IfModifiedSinceJobFactory); 2763 io_thread_->SetNewJobFactory(new_factory); 2764 2765 MakeService(); 2766 group_ =new AppCacheGroup( 2767 service_->storage(), 2768 MockHttpServer::GetMockUrl("files/manifest1"), 2769 111); 2770 AppCacheUpdateJob* update = 2771 new AppCacheUpdateJob(service_.get(), group_.get()); 2772 group_->update_job_ = update; 2773 2774 // Give the newest cache a manifest enry that is in storage. 2775 response_writer_.reset( 2776 service_->storage()->CreateResponseWriter(group_->manifest_url(), 2777 group_->group_id())); 2778 2779 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 2780 response_writer_->response_id()); 2781 MockFrontend* frontend = MakeMockFrontend(); 2782 AppCacheHost* host = MakeHost(1, frontend); 2783 host->AssociateCompleteCache(cache); 2784 2785 // Set up checks for when update job finishes. 2786 do_checks_after_update_finished_ = true; 2787 expect_group_obsolete_ = false; 2788 expect_group_has_cache_ = true; 2789 expect_old_cache_ = cache; 2790 tested_manifest_ = MANIFEST1; 2791 MockFrontend::HostIds ids1(1, host->host_id()); 2792 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2793 frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2794 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2795 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2796 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2797 frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 2798 2799 // Seed storage with expected manifest response info that will cause 2800 // an If-Modified-Since header to be put in the manifest fetch request. 2801 const char data[] = 2802 "HTTP/1.1 200 OK\0" 2803 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0" 2804 "\0"; 2805 net::HttpResponseHeaders* headers = 2806 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 2807 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 2808 response_info->headers = headers; // adds ref to headers 2809 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( 2810 new HttpResponseInfoIOBuffer(response_info)); // adds ref to info 2811 response_writer_->WriteInfo( 2812 io_buffer.get(), 2813 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 2814 base::Unretained(this))); 2815 2816 // Start update after data write completes asynchronously. 2817 } 2818 2819 void IfNoneMatchUpgradeTest() { 2820 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2821 2822 HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\""); 2823 net::URLRequestJobFactoryImpl* new_factory( 2824 new net::URLRequestJobFactoryImpl); 2825 new_factory->SetProtocolHandler("http", new IfModifiedSinceJobFactory); 2826 io_thread_->SetNewJobFactory(new_factory); 2827 2828 MakeService(); 2829 group_ = new AppCacheGroup( 2830 service_->storage(), 2831 MockHttpServer::GetMockUrl("files/manifest1"), 2832 111); 2833 AppCacheUpdateJob* update = 2834 new AppCacheUpdateJob(service_.get(), group_.get()); 2835 group_->update_job_ = update; 2836 2837 // Give the newest cache a manifest enry that is in storage. 2838 response_writer_.reset( 2839 service_->storage()->CreateResponseWriter(group_->manifest_url(), 2840 group_->group_id())); 2841 2842 AppCache* cache = MakeCacheForGroup(service_->storage()->NewCacheId(), 2843 response_writer_->response_id()); 2844 MockFrontend* frontend = MakeMockFrontend(); 2845 AppCacheHost* host = MakeHost(1, frontend); 2846 host->AssociateCompleteCache(cache); 2847 2848 // Set up checks for when update job finishes. 2849 do_checks_after_update_finished_ = true; 2850 expect_group_obsolete_ = false; 2851 expect_group_has_cache_ = true; 2852 expect_old_cache_ = cache; 2853 tested_manifest_ = MANIFEST1; 2854 MockFrontend::HostIds ids1(1, host->host_id()); 2855 frontend->AddExpectedEvent(ids1, APPCACHE_CHECKING_EVENT); 2856 frontend->AddExpectedEvent(ids1, APPCACHE_DOWNLOADING_EVENT); 2857 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2858 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); 2859 frontend->AddExpectedEvent(ids1, APPCACHE_PROGRESS_EVENT); // final 2860 frontend->AddExpectedEvent(ids1, APPCACHE_UPDATE_READY_EVENT); 2861 2862 // Seed storage with expected manifest response info that will cause 2863 // an If-None-Match header to be put in the manifest fetch request. 2864 const char data[] = 2865 "HTTP/1.1 200 OK\0" 2866 "ETag: \"LadeDade\"\0" 2867 "\0"; 2868 net::HttpResponseHeaders* headers = 2869 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 2870 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 2871 response_info->headers = headers; // adds ref to headers 2872 scoped_refptr<HttpResponseInfoIOBuffer> io_buffer( 2873 new HttpResponseInfoIOBuffer(response_info)); // adds ref to info 2874 response_writer_->WriteInfo( 2875 io_buffer.get(), 2876 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData, 2877 base::Unretained(this))); 2878 2879 // Start update after data write completes asynchronously. 2880 } 2881 2882 void IfNoneMatchRefetchTest() { 2883 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2884 2885 HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\""); 2886 net::URLRequestJobFactoryImpl* new_factory( 2887 new net::URLRequestJobFactoryImpl); 2888 new_factory->SetProtocolHandler("http", new IfModifiedSinceJobFactory); 2889 io_thread_->SetNewJobFactory(new_factory); 2890 2891 MakeService(); 2892 group_ = new AppCacheGroup( 2893 service_->storage(), GURL("http://headertest"), 111); 2894 AppCacheUpdateJob* update = 2895 new AppCacheUpdateJob(service_.get(), group_.get()); 2896 group_->update_job_ = update; 2897 2898 // Simulate a refetch manifest request that uses an ETag header. 2899 const char data[] = 2900 "HTTP/1.1 200 OK\0" 2901 "ETag: \"LadeDade\"\0" 2902 "\0"; 2903 net::HttpResponseHeaders* headers = 2904 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 2905 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 2906 response_info->headers = headers; // adds ref to headers 2907 2908 group_->update_status_ = AppCacheGroup::DOWNLOADING; 2909 update->manifest_response_info_.reset(response_info); 2910 update->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST; 2911 update->FetchManifest(false); // not first request 2912 HttpHeadersRequestTestJob::Verify(); 2913 delete update; 2914 2915 UpdateFinished(); 2916 } 2917 2918 void MultipleHeadersRefetchTest() { 2919 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2920 2921 // Verify that code is correct when building multiple extra headers. 2922 HttpHeadersRequestTestJob::Initialize( 2923 "Sat, 29 Oct 1994 19:43:31 GMT", "\"LadeDade\""); 2924 net::URLRequestJobFactoryImpl* new_factory( 2925 new net::URLRequestJobFactoryImpl); 2926 new_factory->SetProtocolHandler("http", new IfModifiedSinceJobFactory); 2927 io_thread_->SetNewJobFactory(new_factory); 2928 2929 MakeService(); 2930 group_ = new AppCacheGroup( 2931 service_->storage(), GURL("http://headertest"), 111); 2932 AppCacheUpdateJob* update = 2933 new AppCacheUpdateJob(service_.get(), group_.get()); 2934 group_->update_job_ = update; 2935 2936 // Simulate a refetch manifest request that uses an ETag header. 2937 const char data[] = 2938 "HTTP/1.1 200 OK\0" 2939 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0" 2940 "ETag: \"LadeDade\"\0" 2941 "\0"; 2942 net::HttpResponseHeaders* headers = 2943 new net::HttpResponseHeaders(std::string(data, arraysize(data))); 2944 net::HttpResponseInfo* response_info = new net::HttpResponseInfo(); 2945 response_info->headers = headers; // adds ref to headers 2946 2947 group_->update_status_ = AppCacheGroup::DOWNLOADING; 2948 update->manifest_response_info_.reset(response_info); 2949 update->internal_state_ = AppCacheUpdateJob::REFETCH_MANIFEST; 2950 update->FetchManifest(false); // not first request 2951 HttpHeadersRequestTestJob::Verify(); 2952 delete update; 2953 2954 UpdateFinished(); 2955 } 2956 2957 void CrossOriginHttpsSuccessTest() { 2958 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2959 2960 GURL manifest_url = MockHttpServer::GetMockHttpsUrl( 2961 "files/valid_cross_origin_https_manifest"); 2962 2963 MakeService(); 2964 group_ = new AppCacheGroup( 2965 service_->storage(), manifest_url, service_->storage()->NewGroupId()); 2966 AppCacheUpdateJob* update = 2967 new AppCacheUpdateJob(service_.get(), group_.get()); 2968 group_->update_job_ = update; 2969 2970 MockFrontend* frontend = MakeMockFrontend(); 2971 AppCacheHost* host = MakeHost(1, frontend); 2972 update->StartUpdate(host, GURL()); 2973 2974 // Set up checks for when update job finishes. 2975 do_checks_after_update_finished_ = true; 2976 expect_group_obsolete_ = false; 2977 expect_group_has_cache_ = true; 2978 tested_manifest_ = NONE; 2979 MockFrontend::HostIds host_ids(1, host->host_id()); 2980 frontend->AddExpectedEvent(host_ids, APPCACHE_CHECKING_EVENT); 2981 2982 WaitForUpdateToFinish(); 2983 } 2984 2985 void CrossOriginHttpsDeniedTest() { 2986 ASSERT_TRUE(base::MessageLoopForIO::IsCurrent()); 2987 2988 GURL manifest_url = MockHttpServer::GetMockHttpsUrl( 2989 "files/invalid_cross_origin_https_manifest"); 2990 2991 MakeService(); 2992 group_ = new AppCacheGroup( 2993 service_->storage(), manifest_url, service_->storage()->NewGroupId()); 2994 AppCacheUpdateJob* update = 2995 new AppCacheUpdateJob(service_.get(), group_.get()); 2996 group_->update_job_ = update; 2997 2998 MockFrontend* frontend = MakeMockFrontend(); 2999 AppCacheHost* host = MakeHost(1, frontend); 3000 update->StartUpdate(host, GURL()); 3001 3002 // Set up checks for when update job finishes. 3003 do_checks_after_update_finished_ = true; 3004 expect_group_obsolete_ = false; 3005 expect_group_has_cache_ = false; 3006 tested_manifest_ = NONE; 3007 MockFrontend::HostIds host_ids(1, host->host_id()); 3008 frontend->AddExpectedEvent(host_ids, APPCACHE_CHECKING_EVENT); 3009 3010 WaitForUpdateToFinish(); 3011 } 3012 3013 void WaitForUpdateToFinish() { 3014 if (group_->update_status() == AppCacheGroup::IDLE) 3015 UpdateFinished(); 3016 else 3017 group_->AddUpdateObserver(this); 3018 } 3019 3020 virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE { 3021 ASSERT_EQ(group_.get(), group); 3022 protect_newest_cache_ = group->newest_complete_cache(); 3023 UpdateFinished(); 3024 } 3025 3026 void UpdateFinished() { 3027 // We unwind the stack prior to finishing up to let stack-based objects 3028 // get deleted. 3029 base::MessageLoop::current()->PostTask( 3030 FROM_HERE, 3031 base::Bind(&AppCacheUpdateJobTest::UpdateFinishedUnwound, 3032 base::Unretained(this))); 3033 } 3034 3035 void UpdateFinishedUnwound() { 3036 EXPECT_EQ(AppCacheGroup::IDLE, group_->update_status()); 3037 EXPECT_TRUE(group_->update_job() == NULL); 3038 if (do_checks_after_update_finished_) 3039 VerifyExpectations(); 3040 3041 // Clean up everything that was created on the IO thread. 3042 protect_newest_cache_ = NULL; 3043 group_ = NULL; 3044 STLDeleteContainerPointers(hosts_.begin(), hosts_.end()); 3045 STLDeleteContainerPointers(frontends_.begin(), frontends_.end()); 3046 response_infos_.clear(); 3047 service_.reset(NULL); 3048 3049 event_->Signal(); 3050 } 3051 3052 void MakeService() { 3053 service_.reset(new MockAppCacheService()); 3054 service_->set_request_context(io_thread_->request_context()); 3055 } 3056 3057 AppCache* MakeCacheForGroup(int64 cache_id, int64 manifest_response_id) { 3058 return MakeCacheForGroup(cache_id, group_->manifest_url(), 3059 manifest_response_id); 3060 } 3061 3062 AppCache* MakeCacheForGroup(int64 cache_id, const GURL& manifest_entry_url, 3063 int64 manifest_response_id) { 3064 AppCache* cache = new AppCache(service_->storage(), cache_id); 3065 cache->set_complete(true); 3066 cache->set_update_time(base::Time::Now()); 3067 group_->AddCache(cache); 3068 3069 // Add manifest entry to cache. 3070 cache->AddEntry(manifest_entry_url, 3071 AppCacheEntry(AppCacheEntry::MANIFEST, manifest_response_id)); 3072 3073 return cache; 3074 } 3075 3076 AppCacheHost* MakeHost(int host_id, AppCacheFrontend* frontend) { 3077 AppCacheHost* host = new AppCacheHost(host_id, frontend, service_.get()); 3078 hosts_.push_back(host); 3079 return host; 3080 } 3081 3082 AppCacheResponseInfo* MakeAppCacheResponseInfo( 3083 const GURL& manifest_url, int64 response_id, 3084 const std::string& raw_headers) { 3085 net::HttpResponseInfo* http_info = new net::HttpResponseInfo(); 3086 http_info->headers = new net::HttpResponseHeaders(raw_headers); 3087 scoped_refptr<AppCacheResponseInfo> info( 3088 new AppCacheResponseInfo(service_->storage(), manifest_url, 3089 response_id, http_info, 0)); 3090 response_infos_.push_back(info); 3091 return info.get(); 3092 } 3093 3094 MockFrontend* MakeMockFrontend() { 3095 MockFrontend* frontend = new MockFrontend(); 3096 frontends_.push_back(frontend); 3097 return frontend; 3098 } 3099 3100 // Verifies conditions about the group and notifications after an update 3101 // has finished. Cannot verify update job internals as update is deleted. 3102 void VerifyExpectations() { 3103 RetryRequestTestJob::Verify(); 3104 HttpHeadersRequestTestJob::Verify(); 3105 3106 EXPECT_EQ(expect_group_obsolete_, group_->is_obsolete()); 3107 EXPECT_EQ(expect_group_is_being_deleted_, group_->is_being_deleted()); 3108 3109 if (expect_group_has_cache_) { 3110 EXPECT_TRUE(group_->newest_complete_cache() != NULL); 3111 3112 if (expect_non_null_update_time_) 3113 EXPECT_TRUE(!group_->newest_complete_cache()->update_time().is_null()); 3114 3115 if (expect_old_cache_) { 3116 EXPECT_NE(expect_old_cache_, group_->newest_complete_cache()); 3117 EXPECT_TRUE(group_->old_caches().end() != 3118 std::find(group_->old_caches().begin(), 3119 group_->old_caches().end(), expect_old_cache_)); 3120 } 3121 if (expect_newest_cache_) { 3122 EXPECT_EQ(expect_newest_cache_, group_->newest_complete_cache()); 3123 EXPECT_TRUE(group_->old_caches().end() == 3124 std::find(group_->old_caches().begin(), 3125 group_->old_caches().end(), expect_newest_cache_)); 3126 } else { 3127 // Tests that don't know which newest cache to expect contain updates 3128 // that succeed (because the update creates a new cache whose pointer 3129 // is unknown to the test). Check group and newest cache were stored 3130 // when update succeeds. 3131 MockAppCacheStorage* storage = 3132 reinterpret_cast<MockAppCacheStorage*>(service_->storage()); 3133 EXPECT_TRUE(storage->IsGroupStored(group_.get())); 3134 EXPECT_TRUE(storage->IsCacheStored(group_->newest_complete_cache())); 3135 3136 // Check that all entries in the newest cache were stored. 3137 const AppCache::EntryMap& entries = 3138 group_->newest_complete_cache()->entries(); 3139 for (AppCache::EntryMap::const_iterator it = entries.begin(); 3140 it != entries.end(); ++it) { 3141 EXPECT_NE(kAppCacheNoResponseId, it->second.response_id()); 3142 3143 // Check that any copied entries have the expected response id 3144 // and that entries that are not copied have a different response id. 3145 std::map<GURL, int64>::iterator found = 3146 expect_response_ids_.find(it->first); 3147 if (found != expect_response_ids_.end()) { 3148 EXPECT_EQ(found->second, it->second.response_id()); 3149 } else if (expect_old_cache_) { 3150 AppCacheEntry* old_entry = expect_old_cache_->GetEntry(it->first); 3151 if (old_entry) 3152 EXPECT_NE(old_entry->response_id(), it->second.response_id()); 3153 } 3154 } 3155 } 3156 } else { 3157 EXPECT_TRUE(group_->newest_complete_cache() == NULL); 3158 } 3159 3160 // Check expected events. 3161 for (size_t i = 0; i < frontends_.size(); ++i) { 3162 MockFrontend* frontend = frontends_[i]; 3163 3164 MockFrontend::RaisedEvents& expected_events = frontend->expected_events_; 3165 MockFrontend::RaisedEvents& actual_events = frontend->raised_events_; 3166 EXPECT_EQ(expected_events.size(), actual_events.size()); 3167 3168 // Check each expected event. 3169 for (size_t j = 0; 3170 j < expected_events.size() && j < actual_events.size(); ++j) { 3171 EXPECT_EQ(expected_events[j].second, actual_events[j].second); 3172 3173 MockFrontend::HostIds& expected_ids = expected_events[j].first; 3174 MockFrontend::HostIds& actual_ids = actual_events[j].first; 3175 EXPECT_EQ(expected_ids.size(), actual_ids.size()); 3176 3177 for (size_t k = 0; k < expected_ids.size(); ++k) { 3178 int id = expected_ids[k]; 3179 EXPECT_TRUE(std::find(actual_ids.begin(), actual_ids.end(), id) != 3180 actual_ids.end()); 3181 } 3182 } 3183 3184 if (!frontend->expected_error_message_.empty()) { 3185 EXPECT_EQ(frontend->expected_error_message_, 3186 frontend->error_message_); 3187 } 3188 } 3189 3190 // Verify expected cache contents last as some checks are asserts 3191 // and will abort the test if they fail. 3192 if (tested_manifest_) { 3193 AppCache* cache = group_->newest_complete_cache(); 3194 ASSERT_TRUE(cache != NULL); 3195 EXPECT_EQ(group_.get(), cache->owning_group()); 3196 EXPECT_TRUE(cache->is_complete()); 3197 3198 switch (tested_manifest_) { 3199 case MANIFEST1: 3200 VerifyManifest1(cache); 3201 break; 3202 case MANIFEST_MERGED_TYPES: 3203 VerifyManifestMergedTypes(cache); 3204 break; 3205 case EMPTY_MANIFEST: 3206 VerifyEmptyManifest(cache); 3207 break; 3208 case EMPTY_FILE_MANIFEST: 3209 VerifyEmptyFileManifest(cache); 3210 break; 3211 case PENDING_MASTER_NO_UPDATE: 3212 VerifyMasterEntryNoUpdate(cache); 3213 break; 3214 case MANIFEST_WITH_INTERCEPT: 3215 VerifyManifestWithIntercept(cache); 3216 break; 3217 case NONE: 3218 default: 3219 break; 3220 } 3221 } 3222 } 3223 3224 void VerifyManifest1(AppCache* cache) { 3225 size_t expected = 3 + expect_extra_entries_.size(); 3226 EXPECT_EQ(expected, cache->entries().size()); 3227 const char* kManifestPath = tested_manifest_path_override_ ? 3228 tested_manifest_path_override_ : 3229 "files/manifest1"; 3230 AppCacheEntry* entry = 3231 cache->GetEntry(MockHttpServer::GetMockUrl(kManifestPath)); 3232 ASSERT_TRUE(entry); 3233 EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); 3234 entry = cache->GetEntry(MockHttpServer::GetMockUrl("files/explicit1")); 3235 ASSERT_TRUE(entry); 3236 EXPECT_TRUE(entry->IsExplicit()); 3237 entry = cache->GetEntry( 3238 MockHttpServer::GetMockUrl("files/fallback1a")); 3239 ASSERT_TRUE(entry); 3240 EXPECT_EQ(AppCacheEntry::FALLBACK, entry->types()); 3241 3242 for (AppCache::EntryMap::iterator i = expect_extra_entries_.begin(); 3243 i != expect_extra_entries_.end(); ++i) { 3244 entry = cache->GetEntry(i->first); 3245 ASSERT_TRUE(entry); 3246 EXPECT_EQ(i->second.types(), entry->types()); 3247 } 3248 3249 expected = 1; 3250 ASSERT_EQ(expected, cache->fallback_namespaces_.size()); 3251 EXPECT_TRUE(cache->fallback_namespaces_[0] == 3252 AppCacheNamespace( 3253 APPCACHE_FALLBACK_NAMESPACE, 3254 MockHttpServer::GetMockUrl("files/fallback1"), 3255 MockHttpServer::GetMockUrl("files/fallback1a"), 3256 false)); 3257 3258 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 3259 EXPECT_TRUE(cache->online_whitelist_all_); 3260 3261 EXPECT_TRUE(cache->update_time_ > base::Time()); 3262 } 3263 3264 void VerifyManifestMergedTypes(AppCache* cache) { 3265 size_t expected = 2; 3266 EXPECT_EQ(expected, cache->entries().size()); 3267 AppCacheEntry* entry = cache->GetEntry( 3268 MockHttpServer::GetMockUrl("files/manifest-merged-types")); 3269 ASSERT_TRUE(entry); 3270 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::MANIFEST, 3271 entry->types()); 3272 entry = cache->GetEntry(MockHttpServer::GetMockUrl("files/explicit1")); 3273 ASSERT_TRUE(entry); 3274 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FALLBACK | 3275 AppCacheEntry::MASTER, entry->types()); 3276 3277 expected = 1; 3278 ASSERT_EQ(expected, cache->fallback_namespaces_.size()); 3279 EXPECT_TRUE(cache->fallback_namespaces_[0] == 3280 AppCacheNamespace( 3281 APPCACHE_FALLBACK_NAMESPACE, 3282 MockHttpServer::GetMockUrl("files/fallback1"), 3283 MockHttpServer::GetMockUrl("files/explicit1"), 3284 false)); 3285 3286 EXPECT_EQ(expected, cache->online_whitelist_namespaces_.size()); 3287 EXPECT_TRUE(cache->online_whitelist_namespaces_[0] == 3288 AppCacheNamespace( 3289 APPCACHE_NETWORK_NAMESPACE, 3290 MockHttpServer::GetMockUrl("files/online1"), 3291 GURL(), false)); 3292 EXPECT_FALSE(cache->online_whitelist_all_); 3293 3294 EXPECT_TRUE(cache->update_time_ > base::Time()); 3295 } 3296 3297 void VerifyEmptyManifest(AppCache* cache) { 3298 const char* kManifestPath = tested_manifest_path_override_ ? 3299 tested_manifest_path_override_ : 3300 "files/empty-manifest"; 3301 size_t expected = 1; 3302 EXPECT_EQ(expected, cache->entries().size()); 3303 AppCacheEntry* entry = cache->GetEntry( 3304 MockHttpServer::GetMockUrl(kManifestPath)); 3305 ASSERT_TRUE(entry); 3306 EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); 3307 3308 EXPECT_TRUE(cache->fallback_namespaces_.empty()); 3309 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 3310 EXPECT_FALSE(cache->online_whitelist_all_); 3311 3312 EXPECT_TRUE(cache->update_time_ > base::Time()); 3313 } 3314 3315 void VerifyEmptyFileManifest(AppCache* cache) { 3316 EXPECT_EQ(size_t(2), cache->entries().size()); 3317 AppCacheEntry* entry = cache->GetEntry( 3318 MockHttpServer::GetMockUrl("files/empty-file-manifest")); 3319 ASSERT_TRUE(entry); 3320 EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); 3321 3322 entry = cache->GetEntry( 3323 MockHttpServer::GetMockUrl("files/empty1")); 3324 ASSERT_TRUE(entry); 3325 EXPECT_EQ(AppCacheEntry::EXPLICIT, entry->types()); 3326 EXPECT_TRUE(entry->has_response_id()); 3327 3328 EXPECT_TRUE(cache->fallback_namespaces_.empty()); 3329 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 3330 EXPECT_FALSE(cache->online_whitelist_all_); 3331 3332 EXPECT_TRUE(cache->update_time_ > base::Time()); 3333 } 3334 3335 void VerifyMasterEntryNoUpdate(AppCache* cache) { 3336 EXPECT_EQ(size_t(3), cache->entries().size()); 3337 AppCacheEntry* entry = cache->GetEntry( 3338 MockHttpServer::GetMockUrl("files/notmodified")); 3339 ASSERT_TRUE(entry); 3340 EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); 3341 3342 entry = cache->GetEntry( 3343 MockHttpServer::GetMockUrl("files/explicit1")); 3344 ASSERT_TRUE(entry); 3345 EXPECT_EQ(AppCacheEntry::MASTER, entry->types()); 3346 EXPECT_TRUE(entry->has_response_id()); 3347 3348 entry = cache->GetEntry( 3349 MockHttpServer::GetMockUrl("files/explicit2")); 3350 ASSERT_TRUE(entry); 3351 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::MASTER, entry->types()); 3352 EXPECT_TRUE(entry->has_response_id()); 3353 3354 EXPECT_TRUE(cache->fallback_namespaces_.empty()); 3355 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 3356 EXPECT_FALSE(cache->online_whitelist_all_); 3357 3358 EXPECT_TRUE(cache->update_time_ > base::Time()); 3359 } 3360 3361 void VerifyManifestWithIntercept(AppCache* cache) { 3362 EXPECT_EQ(2u, cache->entries().size()); 3363 const char* kManifestPath = "files/manifest-with-intercept"; 3364 AppCacheEntry* entry = 3365 cache->GetEntry(MockHttpServer::GetMockUrl(kManifestPath)); 3366 ASSERT_TRUE(entry); 3367 EXPECT_EQ(AppCacheEntry::MANIFEST, entry->types()); 3368 entry = cache->GetEntry(MockHttpServer::GetMockUrl("files/intercept1a")); 3369 ASSERT_TRUE(entry); 3370 EXPECT_TRUE(entry->IsIntercept()); 3371 EXPECT_TRUE(cache->online_whitelist_namespaces_.empty()); 3372 EXPECT_FALSE(cache->online_whitelist_all_); 3373 EXPECT_TRUE(cache->update_time_ > base::Time()); 3374 } 3375 3376 private: 3377 // Various manifest files used in this test. 3378 enum TestedManifest { 3379 NONE, 3380 MANIFEST1, 3381 MANIFEST_MERGED_TYPES, 3382 EMPTY_MANIFEST, 3383 EMPTY_FILE_MANIFEST, 3384 PENDING_MASTER_NO_UPDATE, 3385 MANIFEST_WITH_INTERCEPT 3386 }; 3387 3388 scoped_ptr<IOThread> io_thread_; 3389 3390 scoped_ptr<MockAppCacheService> service_; 3391 scoped_refptr<AppCacheGroup> group_; 3392 scoped_refptr<AppCache> protect_newest_cache_; 3393 scoped_ptr<base::WaitableEvent> event_; 3394 3395 scoped_ptr<AppCacheResponseWriter> response_writer_; 3396 3397 // Hosts used by an async test that need to live until update job finishes. 3398 // Otherwise, test can put host on the stack instead of here. 3399 std::vector<AppCacheHost*> hosts_; 3400 3401 // Response infos used by an async test that need to live until update job 3402 // finishes. 3403 std::vector<scoped_refptr<AppCacheResponseInfo> > response_infos_; 3404 3405 // Flag indicating if test cares to verify the update after update finishes. 3406 bool do_checks_after_update_finished_; 3407 bool expect_group_obsolete_; 3408 bool expect_group_has_cache_; 3409 bool expect_group_is_being_deleted_; 3410 AppCache* expect_old_cache_; 3411 AppCache* expect_newest_cache_; 3412 bool expect_non_null_update_time_; 3413 std::vector<MockFrontend*> frontends_; // to check expected events 3414 TestedManifest tested_manifest_; 3415 const char* tested_manifest_path_override_; 3416 AppCache::EntryMap expect_extra_entries_; 3417 std::map<GURL, int64> expect_response_ids_; 3418}; 3419 3420TEST_F(AppCacheUpdateJobTest, AlreadyChecking) { 3421 MockAppCacheService service; 3422 scoped_refptr<AppCacheGroup> group( 3423 new AppCacheGroup(service.storage(), GURL("http://manifesturl.com"), 3424 service.storage()->NewGroupId())); 3425 3426 AppCacheUpdateJob update(&service, group.get()); 3427 3428 // Pretend group is in checking state. 3429 group->update_job_ = &update; 3430 group->update_status_ = AppCacheGroup::CHECKING; 3431 3432 update.StartUpdate(NULL, GURL()); 3433 EXPECT_EQ(AppCacheGroup::CHECKING, group->update_status()); 3434 3435 MockFrontend mock_frontend; 3436 AppCacheHost host(1, &mock_frontend, &service); 3437 update.StartUpdate(&host, GURL()); 3438 3439 MockFrontend::RaisedEvents events = mock_frontend.raised_events_; 3440 size_t expected = 1; 3441 EXPECT_EQ(expected, events.size()); 3442 EXPECT_EQ(expected, events[0].first.size()); 3443 EXPECT_EQ(host.host_id(), events[0].first[0]); 3444 EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second); 3445 EXPECT_EQ(AppCacheGroup::CHECKING, group->update_status()); 3446} 3447 3448TEST_F(AppCacheUpdateJobTest, AlreadyDownloading) { 3449 MockAppCacheService service; 3450 scoped_refptr<AppCacheGroup> group( 3451 new AppCacheGroup(service.storage(), GURL("http://manifesturl.com"), 3452 service.storage()->NewGroupId())); 3453 3454 AppCacheUpdateJob update(&service, group.get()); 3455 3456 // Pretend group is in downloading state. 3457 group->update_job_ = &update; 3458 group->update_status_ = AppCacheGroup::DOWNLOADING; 3459 3460 update.StartUpdate(NULL, GURL()); 3461 EXPECT_EQ(AppCacheGroup::DOWNLOADING, group->update_status()); 3462 3463 MockFrontend mock_frontend; 3464 AppCacheHost host(1, &mock_frontend, &service); 3465 update.StartUpdate(&host, GURL()); 3466 3467 MockFrontend::RaisedEvents events = mock_frontend.raised_events_; 3468 size_t expected = 2; 3469 EXPECT_EQ(expected, events.size()); 3470 expected = 1; 3471 EXPECT_EQ(expected, events[0].first.size()); 3472 EXPECT_EQ(host.host_id(), events[0].first[0]); 3473 EXPECT_EQ(APPCACHE_CHECKING_EVENT, events[0].second); 3474 3475 EXPECT_EQ(expected, events[1].first.size()); 3476 EXPECT_EQ(host.host_id(), events[1].first[0]); 3477 EXPECT_EQ(APPCACHE_DOWNLOADING_EVENT, events[1].second); 3478 3479 EXPECT_EQ(AppCacheGroup::DOWNLOADING, group->update_status()); 3480} 3481 3482TEST_F(AppCacheUpdateJobTest, StartCacheAttempt) { 3483 RunTestOnIOThread(&AppCacheUpdateJobTest::StartCacheAttemptTest); 3484} 3485 3486TEST_F(AppCacheUpdateJobTest, StartUpgradeAttempt) { 3487 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpgradeAttemptTest); 3488} 3489 3490TEST_F(AppCacheUpdateJobTest, CacheAttemptFetchManifestFail) { 3491 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptFetchManifestFailTest); 3492} 3493 3494TEST_F(AppCacheUpdateJobTest, UpgradeFetchManifestFail) { 3495 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFetchManifestFailTest); 3496} 3497 3498TEST_F(AppCacheUpdateJobTest, ManifestRedirect) { 3499 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestRedirectTest); 3500} 3501 3502TEST_F(AppCacheUpdateJobTest, ManifestMissingMimeTypeTest) { 3503 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestMissingMimeTypeTest); 3504} 3505 3506TEST_F(AppCacheUpdateJobTest, ManifestNotFound) { 3507 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestNotFoundTest); 3508} 3509 3510TEST_F(AppCacheUpdateJobTest, ManifestGone) { 3511 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestGoneTest); 3512} 3513 3514TEST_F(AppCacheUpdateJobTest, CacheAttemptNotModified) { 3515 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptNotModifiedTest); 3516} 3517 3518TEST_F(AppCacheUpdateJobTest, UpgradeNotModified) { 3519 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeNotModifiedTest); 3520} 3521 3522TEST_F(AppCacheUpdateJobTest, UpgradeManifestDataUnchanged) { 3523 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeManifestDataUnchangedTest); 3524} 3525 3526TEST_F(AppCacheUpdateJobTest, Bug95101Test) { 3527 RunTestOnIOThread(&AppCacheUpdateJobTest::Bug95101Test); 3528} 3529 3530TEST_F(AppCacheUpdateJobTest, BasicCacheAttemptSuccess) { 3531 RunTestOnIOThread(&AppCacheUpdateJobTest::BasicCacheAttemptSuccessTest); 3532} 3533 3534TEST_F(AppCacheUpdateJobTest, DownloadInterceptEntriesTest) { 3535 RunTestOnIOThread(&AppCacheUpdateJobTest::DownloadInterceptEntriesTest); 3536} 3537 3538TEST_F(AppCacheUpdateJobTest, BasicUpgradeSuccess) { 3539 RunTestOnIOThread(&AppCacheUpdateJobTest::BasicUpgradeSuccessTest); 3540} 3541 3542TEST_F(AppCacheUpdateJobTest, UpgradeLoadFromNewestCache) { 3543 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeLoadFromNewestCacheTest); 3544} 3545 3546TEST_F(AppCacheUpdateJobTest, UpgradeNoLoadFromNewestCache) { 3547 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeNoLoadFromNewestCacheTest); 3548} 3549 3550TEST_F(AppCacheUpdateJobTest, UpgradeLoadFromNewestCacheVaryHeader) { 3551 RunTestOnIOThread( 3552 &AppCacheUpdateJobTest::UpgradeLoadFromNewestCacheVaryHeaderTest); 3553} 3554 3555TEST_F(AppCacheUpdateJobTest, UpgradeSuccessMergedTypes) { 3556 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeSuccessMergedTypesTest); 3557} 3558 3559TEST_F(AppCacheUpdateJobTest, CacheAttemptFailUrlFetch) { 3560 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptFailUrlFetchTest); 3561} 3562 3563TEST_F(AppCacheUpdateJobTest, UpgradeFailUrlFetch) { 3564 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailUrlFetchTest); 3565} 3566 3567TEST_F(AppCacheUpdateJobTest, UpgradeFailMasterUrlFetch) { 3568 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailMasterUrlFetchTest); 3569} 3570 3571TEST_F(AppCacheUpdateJobTest, EmptyManifest) { 3572 RunTestOnIOThread(&AppCacheUpdateJobTest::EmptyManifestTest); 3573} 3574 3575TEST_F(AppCacheUpdateJobTest, EmptyFile) { 3576 RunTestOnIOThread(&AppCacheUpdateJobTest::EmptyFileTest); 3577} 3578 3579TEST_F(AppCacheUpdateJobTest, RetryRequest) { 3580 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryRequestTest); 3581} 3582 3583TEST_F(AppCacheUpdateJobTest, RetryNoRetryAfter) { 3584 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryNoRetryAfterTest); 3585} 3586 3587TEST_F(AppCacheUpdateJobTest, RetryNonzeroRetryAfter) { 3588 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryNonzeroRetryAfterTest); 3589} 3590 3591TEST_F(AppCacheUpdateJobTest, RetrySuccess) { 3592 RunTestOnIOThread(&AppCacheUpdateJobTest::RetrySuccessTest); 3593} 3594 3595TEST_F(AppCacheUpdateJobTest, RetryUrl) { 3596 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryUrlTest); 3597} 3598 3599TEST_F(AppCacheUpdateJobTest, FailStoreNewestCache) { 3600 RunTestOnIOThread(&AppCacheUpdateJobTest::FailStoreNewestCacheTest); 3601} 3602 3603TEST_F(AppCacheUpdateJobTest, MasterEntryFailStoreNewestCacheTest) { 3604 RunTestOnIOThread( 3605 &AppCacheUpdateJobTest::MasterEntryFailStoreNewestCacheTest); 3606} 3607 3608TEST_F(AppCacheUpdateJobTest, UpgradeFailStoreNewestCache) { 3609 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailStoreNewestCacheTest); 3610} 3611 3612TEST_F(AppCacheUpdateJobTest, UpgradeFailMakeGroupObsolete) { 3613 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailMakeGroupObsoleteTest); 3614} 3615 3616TEST_F(AppCacheUpdateJobTest, MasterEntryFetchManifestFail) { 3617 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFetchManifestFailTest); 3618} 3619 3620TEST_F(AppCacheUpdateJobTest, MasterEntryBadManifest) { 3621 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryBadManifestTest); 3622} 3623 3624TEST_F(AppCacheUpdateJobTest, MasterEntryManifestNotFound) { 3625 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryManifestNotFoundTest); 3626} 3627 3628TEST_F(AppCacheUpdateJobTest, MasterEntryFailUrlFetch) { 3629 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFailUrlFetchTest); 3630} 3631 3632TEST_F(AppCacheUpdateJobTest, MasterEntryAllFail) { 3633 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryAllFailTest); 3634} 3635 3636TEST_F(AppCacheUpdateJobTest, UpgradeMasterEntryAllFail) { 3637 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntryAllFailTest); 3638} 3639 3640TEST_F(AppCacheUpdateJobTest, MasterEntrySomeFail) { 3641 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntrySomeFailTest); 3642} 3643 3644TEST_F(AppCacheUpdateJobTest, UpgradeMasterEntrySomeFail) { 3645 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntrySomeFailTest); 3646} 3647 3648TEST_F(AppCacheUpdateJobTest, MasterEntryNoUpdate) { 3649 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryNoUpdateTest); 3650} 3651 3652TEST_F(AppCacheUpdateJobTest, StartUpdateMidCacheAttempt) { 3653 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidCacheAttemptTest); 3654} 3655 3656TEST_F(AppCacheUpdateJobTest, StartUpdateMidNoUpdate) { 3657 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidNoUpdateTest); 3658} 3659 3660TEST_F(AppCacheUpdateJobTest, StartUpdateMidDownload) { 3661 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidDownloadTest); 3662} 3663 3664TEST_F(AppCacheUpdateJobTest, QueueMasterEntry) { 3665 RunTestOnIOThread(&AppCacheUpdateJobTest::QueueMasterEntryTest); 3666} 3667 3668TEST_F(AppCacheUpdateJobTest, IfModifiedSince) { 3669 RunTestOnIOThread(&AppCacheUpdateJobTest::IfModifiedSinceTest); 3670} 3671 3672TEST_F(AppCacheUpdateJobTest, IfModifiedSinceUpgrade) { 3673 RunTestOnIOThread(&AppCacheUpdateJobTest::IfModifiedSinceUpgradeTest); 3674} 3675 3676TEST_F(AppCacheUpdateJobTest, IfNoneMatchUpgrade) { 3677 RunTestOnIOThread(&AppCacheUpdateJobTest::IfNoneMatchUpgradeTest); 3678} 3679 3680TEST_F(AppCacheUpdateJobTest, IfNoneMatchRefetch) { 3681 RunTestOnIOThread(&AppCacheUpdateJobTest::IfNoneMatchRefetchTest); 3682} 3683 3684TEST_F(AppCacheUpdateJobTest, MultipleHeadersRefetch) { 3685 RunTestOnIOThread(&AppCacheUpdateJobTest::MultipleHeadersRefetchTest); 3686} 3687 3688TEST_F(AppCacheUpdateJobTest, CrossOriginHttpsSuccess) { 3689 RunTestOnIOThread(&AppCacheUpdateJobTest::CrossOriginHttpsSuccessTest); 3690} 3691 3692TEST_F(AppCacheUpdateJobTest, CrossOriginHttpsDenied) { 3693 RunTestOnIOThread(&AppCacheUpdateJobTest::CrossOriginHttpsDeniedTest); 3694} 3695 3696} // namespace content 3697