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