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