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