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