1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/bind_helpers.h"
7 #include "base/stl_util.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/thread.h"
10 #include "net/base/net_errors.h"
11 #include "net/http/http_response_headers.h"
12 #include "net/url_request/url_request_error_job.h"
13 #include "net/url_request/url_request_job_factory_impl.h"
14 #include "net/url_request/url_request_test_job.h"
15 #include "net/url_request/url_request_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "webkit/browser/appcache/appcache_group.h"
18 #include "webkit/browser/appcache/appcache_host.h"
19 #include "webkit/browser/appcache/appcache_response.h"
20 #include "webkit/browser/appcache/appcache_update_job.h"
21 #include "webkit/browser/appcache/mock_appcache_service.h"
24 class AppCacheUpdateJobTest
;
28 const char kManifest1Contents
[] =
32 "fallback1 fallback1a\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,
39 class MockHttpServer
{
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);
66 static void GetMockResponse(const std::string
& path
,
69 const char ok_headers
[] =
72 const char error_headers
[] =
73 "HTTP/1.1 500 BOO HOO\0"
75 const char manifest_headers
[] =
77 "Content-type: text/cache-manifest\0"
79 const char not_modified_headers
[] =
80 "HTTP/1.1 304 NOT MODIFIED\0"
82 const char gone_headers
[] =
85 const char not_found_headers
[] =
86 "HTTP/1.1 404 NOT FOUND\0"
88 const char no_store_headers
[] =
90 "Cache-Control: no-store\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
));
102 } else if (path
== "/files/empty-file-manifest") {
103 (*headers
) = std::string(manifest_headers
, arraysize(manifest_headers
));
104 (*body
) = "CACHE MANIFEST\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
));
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"
132 } else if (path
== "/files/manifest-fb-404") {
133 (*headers
) = std::string(manifest_headers
, arraysize(manifest_headers
));
134 (*body
) = "CACHE MANIFEST\n"
137 "fallback1 fallback1a\n"
138 "fallback404 fallback-404\n"
141 } else if (path
== "/files/manifest-merged-types") {
142 (*headers
) = std::string(manifest_headers
, arraysize(manifest_headers
));
143 (*body
) = "CACHE MANIFEST\n"
145 "# manifest is also an explicit entry\n"
146 "manifest-merged-types\n"
148 "# fallback is also explicit entry\n"
149 "fallback1 explicit1\n"
152 } else if (path
== "/files/manifest-with-404") {
153 (*headers
) = std::string(manifest_headers
, arraysize(manifest_headers
));
154 (*body
) = "CACHE MANIFEST\n"
160 "fallback1 fallback1a\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
));
172 } else if (path
== "/files/servererror") {
173 (*headers
) = std::string(error_headers
,
174 arraysize(error_headers
));
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";
188 (*headers
) = std::string(not_found_headers
,
189 arraysize(not_found_headers
));
195 class MockHttpServerJobFactory
196 : public net::URLRequestJobFactory::ProtocolHandler
{
198 virtual 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 Namespace
& lhs
, const Namespace
& rhs
) {
206 return lhs
.type
== rhs
.type
&&
207 lhs
.namespace_url
== rhs
.namespace_url
&&
208 lhs
.target_url
== rhs
.target_url
;
213 class MockFrontend
: public AppCacheFrontend
{
216 : ignore_progress_events_(false), verify_progress_events_(false),
217 last_progress_total_(-1), last_progress_complete_(-1),
218 start_update_trigger_(CHECKING_EVENT
), update_(NULL
) {
221 virtual void OnCacheSelected(
222 int host_id
, const appcache::AppCacheInfo
& info
) OVERRIDE
{
225 virtual void OnStatusChanged(const std::vector
<int>& host_ids
,
226 Status status
) OVERRIDE
{
229 virtual void OnEventRaised(const std::vector
<int>& host_ids
,
230 EventID event_id
) OVERRIDE
{
231 raised_events_
.push_back(RaisedEvent(host_ids
, event_id
));
233 // Trigger additional updates if requested.
234 if (event_id
== start_update_trigger_
&& update_
) {
235 for (std::vector
<AppCacheHost
*>::iterator it
= update_hosts_
.begin();
236 it
!= update_hosts_
.end(); ++it
) {
237 AppCacheHost
* host
= *it
;
238 update_
->StartUpdate(host
,
239 (host
? host
->pending_master_entry_url() : GURL()));
241 update_hosts_
.clear(); // only trigger once
245 virtual void OnErrorEventRaised(const std::vector
<int>& host_ids
,
246 const std::string
& message
) OVERRIDE
{
247 error_message_
= message
;
248 OnEventRaised(host_ids
, ERROR_EVENT
);
251 virtual void OnProgressEventRaised(const std::vector
<int>& host_ids
,
254 int num_complete
) OVERRIDE
{
255 if (!ignore_progress_events_
)
256 OnEventRaised(host_ids
, PROGRESS_EVENT
);
258 if (verify_progress_events_
) {
259 EXPECT_GE(num_total
, num_complete
);
260 EXPECT_GE(num_complete
, 0);
262 if (last_progress_total_
== -1) {
263 // Should start at zero.
264 EXPECT_EQ(0, num_complete
);
266 // Total should be stable and complete should bump up by one at a time.
267 EXPECT_EQ(last_progress_total_
, num_total
);
268 EXPECT_EQ(last_progress_complete_
+ 1, num_complete
);
271 // Url should be valid for all except the 'final' event.
272 if (num_total
== num_complete
)
273 EXPECT_TRUE(url
.is_empty());
275 EXPECT_TRUE(url
.is_valid());
277 last_progress_total_
= num_total
;
278 last_progress_complete_
= num_complete
;
282 virtual void OnLogMessage(int host_id
,
283 appcache::LogLevel log_level
,
284 const std::string
& message
) OVERRIDE
{
287 virtual void OnContentBlocked(int host_id
,
288 const GURL
& manifest_url
) OVERRIDE
{
291 void AddExpectedEvent(const std::vector
<int>& host_ids
, EventID event_id
) {
292 DCHECK(!ignore_progress_events_
|| event_id
!= PROGRESS_EVENT
);
293 expected_events_
.push_back(RaisedEvent(host_ids
, event_id
));
296 void SetIgnoreProgressEvents(bool ignore
) {
297 // Some tests involve joining new hosts to an already running update job
298 // or intentionally failing. The timing and sequencing of the progress
299 // events generated by an update job are dependent on the behavior of
300 // an external HTTP server. For jobs that do not run fully till completion,
301 // due to either joining late or early exit, we skip monitoring the
302 // progress events to avoid flakiness.
303 ignore_progress_events_
= ignore
;
306 void SetVerifyProgressEvents(bool verify
) {
307 verify_progress_events_
= verify
;
310 void TriggerAdditionalUpdates(EventID trigger_event
,
311 AppCacheUpdateJob
* update
) {
312 start_update_trigger_
= trigger_event
;
316 void AdditionalUpdateHost(AppCacheHost
* host
) {
317 update_hosts_
.push_back(host
);
320 typedef std::vector
<int> HostIds
;
321 typedef std::pair
<HostIds
, EventID
> RaisedEvent
;
322 typedef std::vector
<RaisedEvent
> RaisedEvents
;
323 RaisedEvents raised_events_
;
324 std::string error_message_
;
326 // Set the expected events if verification needs to happen asynchronously.
327 RaisedEvents expected_events_
;
328 std::string expected_error_message_
;
330 bool ignore_progress_events_
;
332 bool verify_progress_events_
;
333 int last_progress_total_
;
334 int last_progress_complete_
;
336 // Add ability for frontend to add master entries to an inprogress update.
337 EventID start_update_trigger_
;
338 AppCacheUpdateJob
* update_
;
339 std::vector
<AppCacheHost
*> update_hosts_
;
342 // Helper factories to simulate redirected URL responses for tests.
343 class RedirectFactory
: public net::URLRequestJobFactory::ProtocolHandler
{
345 virtual net::URLRequestJob
* MaybeCreateJob(
346 net::URLRequest
* request
,
347 net::NetworkDelegate
* network_delegate
) const OVERRIDE
{
348 return new net::URLRequestTestJob(
351 net::URLRequestTestJob::test_redirect_headers(),
352 net::URLRequestTestJob::test_data_1(),
357 // Helper class to simulate a URL that returns retry or success.
358 class RetryRequestTestJob
: public net::URLRequestTestJob
{
366 static const GURL kRetryUrl
;
368 // Call this at the start of each retry test.
369 static void Initialize(int num_retry_responses
, RetryHeader header
,
370 int expected_requests
) {
372 num_retries_
= num_retry_responses
;
373 retry_after_
= header
;
374 expected_requests_
= expected_requests
;
377 // Verifies results at end of test and resets counters.
378 static void Verify() {
379 EXPECT_EQ(expected_requests_
, num_requests_
);
381 expected_requests_
= 0;
384 static net::URLRequestJob
* RetryFactory(
385 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
) {
387 if (num_retries_
> 0 && request
->original_url() == kRetryUrl
) {
389 return new RetryRequestTestJob(
390 request
, network_delegate
, RetryRequestTestJob::retry_headers(), 503);
392 return new RetryRequestTestJob(
395 RetryRequestTestJob::manifest_headers(), 200);
399 virtual int GetResponseCode() const OVERRIDE
{ return response_code_
; }
402 virtual ~RetryRequestTestJob() {}
404 static std::string
retry_headers() {
405 const char no_retry_after
[] =
406 "HTTP/1.1 503 BOO HOO\0"
408 const char nonzero
[] =
409 "HTTP/1.1 503 BOO HOO\0"
412 const char retry_after_0
[] =
413 "HTTP/1.1 503 BOO HOO\0"
417 switch (retry_after_
) {
419 return std::string(no_retry_after
, arraysize(no_retry_after
));
420 case NONZERO_RETRY_AFTER
:
421 return std::string(nonzero
, arraysize(nonzero
));
424 return std::string(retry_after_0
, arraysize(retry_after_0
));
428 static std::string
manifest_headers() {
429 const char headers
[] =
431 "Content-type: text/cache-manifest\0"
433 return std::string(headers
, arraysize(headers
));
436 static std::string
data() {
437 return std::string("CACHE MANIFEST\r"
438 "http://retry\r"); // must be same as kRetryUrl
441 RetryRequestTestJob(net::URLRequest
* request
,
442 net::NetworkDelegate
* network_delegate
,
443 const std::string
& headers
,
445 : net::URLRequestTestJob(
446 request
, network_delegate
, headers
, data(), true),
447 response_code_(response_code
) {
452 static int num_requests_
;
453 static int num_retries_
;
454 static RetryHeader retry_after_
;
455 static int expected_requests_
;
458 class RetryRequestTestJobFactory
459 : public net::URLRequestJobFactory::ProtocolHandler
{
461 virtual net::URLRequestJob
* MaybeCreateJob(
462 net::URLRequest
* request
,
463 net::NetworkDelegate
* network_delegate
) const OVERRIDE
{
464 return RetryRequestTestJob::RetryFactory(request
, network_delegate
);
469 const GURL
RetryRequestTestJob::kRetryUrl("http://retry");
470 int RetryRequestTestJob::num_requests_
= 0;
471 int RetryRequestTestJob::num_retries_
;
472 RetryRequestTestJob::RetryHeader
RetryRequestTestJob::retry_after_
;
473 int RetryRequestTestJob::expected_requests_
= 0;
475 // Helper class to check for certain HTTP headers.
476 class HttpHeadersRequestTestJob
: public net::URLRequestTestJob
{
478 // Call this at the start of each HTTP header-related test.
479 static void Initialize(const std::string
& expect_if_modified_since
,
480 const std::string
& expect_if_none_match
) {
481 expect_if_modified_since_
= expect_if_modified_since
;
482 expect_if_none_match_
= expect_if_none_match
;
485 // Verifies results at end of test and resets class.
486 static void Verify() {
487 if (!expect_if_modified_since_
.empty())
488 EXPECT_TRUE(saw_if_modified_since_
);
489 if (!expect_if_none_match_
.empty())
490 EXPECT_TRUE(saw_if_none_match_
);
493 expect_if_modified_since_
.clear();
494 saw_if_modified_since_
= false;
495 expect_if_none_match_
.clear();
496 saw_if_none_match_
= false;
497 already_checked_
= false;
500 static net::URLRequestJob
* IfModifiedSinceFactory(
501 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
) {
502 if (!already_checked_
) {
503 already_checked_
= true; // only check once for a test
504 const net::HttpRequestHeaders
& extra_headers
=
505 request
->extra_request_headers();
506 std::string header_value
;
507 saw_if_modified_since_
=
508 extra_headers
.GetHeader(
509 net::HttpRequestHeaders::kIfModifiedSince
, &header_value
) &&
510 header_value
== expect_if_modified_since_
;
513 extra_headers
.GetHeader(
514 net::HttpRequestHeaders::kIfNoneMatch
, &header_value
) &&
515 header_value
== expect_if_none_match_
;
517 return MockHttpServer::JobFactory(request
, network_delegate
);
521 virtual ~HttpHeadersRequestTestJob() {}
524 static std::string expect_if_modified_since_
;
525 static bool saw_if_modified_since_
;
526 static std::string expect_if_none_match_
;
527 static bool saw_if_none_match_
;
528 static bool already_checked_
;
532 std::string
HttpHeadersRequestTestJob::expect_if_modified_since_
;
533 bool HttpHeadersRequestTestJob::saw_if_modified_since_
= false;
534 std::string
HttpHeadersRequestTestJob::expect_if_none_match_
;
535 bool HttpHeadersRequestTestJob::saw_if_none_match_
= false;
536 bool HttpHeadersRequestTestJob::already_checked_
= false;
538 class IfModifiedSinceJobFactory
539 : public net::URLRequestJobFactory::ProtocolHandler
{
541 virtual net::URLRequestJob
* MaybeCreateJob(
542 net::URLRequest
* request
,
543 net::NetworkDelegate
* network_delegate
) const OVERRIDE
{
544 return HttpHeadersRequestTestJob::IfModifiedSinceFactory(
545 request
, network_delegate
);
549 class IOThread
: public base::Thread
{
551 explicit IOThread(const char* name
)
552 : base::Thread(name
) {
555 virtual ~IOThread() {
559 net::URLRequestContext
* request_context() {
560 return request_context_
.get();
563 void SetNewJobFactory(net::URLRequestJobFactory
* job_factory
) {
565 job_factory_
.reset(job_factory
);
566 request_context_
->set_job_factory(job_factory_
.get());
569 virtual void Init() OVERRIDE
{
570 scoped_ptr
<net::URLRequestJobFactoryImpl
> factory(
571 new net::URLRequestJobFactoryImpl());
572 factory
->SetProtocolHandler("http", new MockHttpServerJobFactory
);
573 factory
->SetProtocolHandler("https", new MockHttpServerJobFactory
);
574 job_factory_
= factory
.Pass();
575 request_context_
.reset(new net::TestURLRequestContext());
576 request_context_
->set_job_factory(job_factory_
.get());
579 virtual void CleanUp() OVERRIDE
{
580 request_context_
.reset();
581 job_factory_
.reset();
585 scoped_ptr
<net::URLRequestJobFactory
> job_factory_
;
586 scoped_ptr
<net::URLRequestContext
> request_context_
;
589 class AppCacheUpdateJobTest
: public testing::Test
,
590 public AppCacheGroup::UpdateObserver
{
592 AppCacheUpdateJobTest()
593 : do_checks_after_update_finished_(false),
594 expect_group_obsolete_(false),
595 expect_group_has_cache_(false),
596 expect_group_is_being_deleted_(false),
597 expect_old_cache_(NULL
),
598 expect_newest_cache_(NULL
),
599 expect_non_null_update_time_(false),
600 tested_manifest_(NONE
),
601 tested_manifest_path_override_(NULL
) {
602 io_thread_
.reset(new IOThread("AppCacheUpdateJob IO test thread"));
603 base::Thread::Options
options(base::MessageLoop::TYPE_IO
, 0);
604 io_thread_
->StartWithOptions(options
);
607 // Use a separate IO thread to run a test. Thread will be destroyed
608 // when it goes out of scope.
609 template <class Method
>
610 void RunTestOnIOThread(Method method
) {
611 event_
.reset(new base::WaitableEvent(false, false));
612 io_thread_
->message_loop()->PostTask(
613 FROM_HERE
, base::Bind(method
, base::Unretained(this)));
615 // Wait until task is done before exiting the test.
619 void StartCacheAttemptTest() {
620 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
623 group_
= new AppCacheGroup(service_
->storage(), GURL("http://failme"),
624 service_
->storage()->NewGroupId());
626 AppCacheUpdateJob
* update
=
627 new AppCacheUpdateJob(service_
.get(), group_
.get());
628 group_
->update_job_
= update
;
630 MockFrontend mock_frontend
;
631 AppCacheHost
host(1, &mock_frontend
, service_
.get());
633 update
->StartUpdate(&host
, GURL());
636 EXPECT_EQ(AppCacheUpdateJob::CACHE_ATTEMPT
, update
->update_type_
);
637 EXPECT_EQ(AppCacheUpdateJob::FETCH_MANIFEST
, update
->internal_state_
);
638 EXPECT_EQ(AppCacheGroup::CHECKING
, group_
->update_status());
640 // Verify notifications.
641 MockFrontend::RaisedEvents
& events
= mock_frontend
.raised_events_
;
643 EXPECT_EQ(expected
, events
.size());
644 EXPECT_EQ(expected
, events
[0].first
.size());
645 EXPECT_EQ(host
.host_id(), events
[0].first
[0]);
646 EXPECT_EQ(CHECKING_EVENT
, events
[0].second
);
648 // Abort as we're not testing actual URL fetches in this test.
653 void StartUpgradeAttemptTest() {
654 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
658 group_
= new AppCacheGroup(service_
->storage(), GURL("http://failme"),
659 service_
->storage()->NewGroupId());
661 // Give the group some existing caches.
662 AppCache
* cache1
= MakeCacheForGroup(1, 111);
663 AppCache
* cache2
= MakeCacheForGroup(2, 222);
665 // Associate some hosts with caches in the group.
666 MockFrontend mock_frontend1
;
667 MockFrontend mock_frontend2
;
668 MockFrontend mock_frontend3
;
670 AppCacheHost
host1(1, &mock_frontend1
, service_
.get());
671 host1
.AssociateCompleteCache(cache1
);
673 AppCacheHost
host2(2, &mock_frontend2
, service_
.get());
674 host2
.AssociateCompleteCache(cache2
);
676 AppCacheHost
host3(3, &mock_frontend1
, service_
.get());
677 host3
.AssociateCompleteCache(cache1
);
679 AppCacheHost
host4(4, &mock_frontend3
, service_
.get());
681 AppCacheUpdateJob
* update
=
682 new AppCacheUpdateJob(service_
.get(), group_
.get());
683 group_
->update_job_
= update
;
684 update
->StartUpdate(&host4
, GURL());
686 // Verify state after starting an update.
687 EXPECT_EQ(AppCacheUpdateJob::UPGRADE_ATTEMPT
, update
->update_type_
);
688 EXPECT_EQ(AppCacheUpdateJob::FETCH_MANIFEST
, update
->internal_state_
);
689 EXPECT_EQ(AppCacheGroup::CHECKING
, group_
->update_status());
691 // Verify notifications.
692 MockFrontend::RaisedEvents
& events
= mock_frontend1
.raised_events_
;
694 EXPECT_EQ(expected
, events
.size());
695 expected
= 2; // 2 hosts using frontend1
696 EXPECT_EQ(expected
, events
[0].first
.size());
697 MockFrontend::HostIds
& host_ids
= events
[0].first
;
698 EXPECT_TRUE(std::find(host_ids
.begin(), host_ids
.end(), host1
.host_id())
700 EXPECT_TRUE(std::find(host_ids
.begin(), host_ids
.end(), host3
.host_id())
702 EXPECT_EQ(CHECKING_EVENT
, events
[0].second
);
704 events
= mock_frontend2
.raised_events_
;
706 EXPECT_EQ(expected
, events
.size());
707 EXPECT_EQ(expected
, events
[0].first
.size()); // 1 host using frontend2
708 EXPECT_EQ(host2
.host_id(), events
[0].first
[0]);
709 EXPECT_EQ(CHECKING_EVENT
, events
[0].second
);
711 events
= mock_frontend3
.raised_events_
;
712 EXPECT_TRUE(events
.empty());
714 // Abort as we're not testing actual URL fetches in this test.
720 void CacheAttemptFetchManifestFailTest() {
721 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
724 group_
= new AppCacheGroup(service_
->storage(), GURL("http://failme"),
725 service_
->storage()->NewGroupId());
726 AppCacheUpdateJob
* update
=
727 new AppCacheUpdateJob(service_
.get(), group_
.get());
728 group_
->update_job_
= update
;
730 MockFrontend
* frontend
= MakeMockFrontend();
731 AppCacheHost
* host
= MakeHost(1, frontend
);
732 update
->StartUpdate(host
, GURL());
733 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
735 update
->manifest_fetcher_
->request()->CancelWithError(-100);
737 // Set up checks for when update job finishes.
738 do_checks_after_update_finished_
= true;
739 expect_group_obsolete_
= false;
740 expect_group_has_cache_
= false;
741 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
744 WaitForUpdateToFinish();
747 void UpgradeFetchManifestFailTest() {
748 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
751 group_
= new AppCacheGroup(service_
->storage(), GURL("http://failme"),
752 service_
->storage()->NewGroupId());
753 AppCacheUpdateJob
* update
=
754 new AppCacheUpdateJob(service_
.get(), group_
.get());
755 group_
->update_job_
= update
;
757 AppCache
* cache
= MakeCacheForGroup(1, 111);
758 MockFrontend
* frontend1
= MakeMockFrontend();
759 MockFrontend
* frontend2
= MakeMockFrontend();
760 AppCacheHost
* host1
= MakeHost(1, frontend1
);
761 AppCacheHost
* host2
= MakeHost(2, frontend2
);
762 host1
->AssociateCompleteCache(cache
);
763 host2
->AssociateCompleteCache(cache
);
765 update
->StartUpdate(NULL
, GURL());
766 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
768 update
->manifest_fetcher_
->request()->CancelWithError(-100);
770 // Set up checks for when update job finishes.
771 do_checks_after_update_finished_
= true;
772 expect_group_obsolete_
= false;
773 expect_group_has_cache_
= true;
774 expect_newest_cache_
= cache
; // newest cache unaffected by update
775 MockFrontend::HostIds
ids1(1, host1
->host_id());
776 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
777 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
778 MockFrontend::HostIds
ids2(1, host2
->host_id());
779 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
780 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
782 WaitForUpdateToFinish();
785 void ManifestRedirectTest() {
786 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
788 net::URLRequestJobFactoryImpl
* new_factory(
789 new net::URLRequestJobFactoryImpl
);
790 new_factory
->SetProtocolHandler("http", new RedirectFactory
);
791 io_thread_
->SetNewJobFactory(new_factory
);
794 group_
= new AppCacheGroup(service_
->storage(), GURL("http://testme"),
795 service_
->storage()->NewGroupId());
796 AppCacheUpdateJob
* update
=
797 new AppCacheUpdateJob(service_
.get(), group_
.get());
798 group_
->update_job_
= update
;
800 MockFrontend
* frontend
= MakeMockFrontend();
801 AppCacheHost
* host
= MakeHost(1, frontend
);
802 update
->StartUpdate(host
, GURL());
803 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
805 // Set up checks for when update job finishes.
806 do_checks_after_update_finished_
= true;
807 expect_group_obsolete_
= false;
808 expect_group_has_cache_
= false; // redirect is like a failed request
809 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
812 WaitForUpdateToFinish();
815 void ManifestMissingMimeTypeTest() {
816 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
819 group_
= new AppCacheGroup(
821 MockHttpServer::GetMockUrl("files/missing-mime-manifest"),
822 service_
->storage()->NewGroupId());
823 AppCacheUpdateJob
* update
=
824 new AppCacheUpdateJob(service_
.get(), group_
.get());
825 group_
->update_job_
= update
;
827 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 33);
828 MockFrontend
* frontend
= MakeMockFrontend();
829 AppCacheHost
* host
= MakeHost(1, frontend
);
830 host
->AssociateCompleteCache(cache
);
832 frontend
->SetVerifyProgressEvents(true);
834 update
->StartUpdate(NULL
, GURL());
835 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
837 // Set up checks for when update job finishes.
838 do_checks_after_update_finished_
= true;
839 expect_group_obsolete_
= false;
840 expect_group_has_cache_
= true;
841 expect_old_cache_
= cache
;
842 tested_manifest_
= EMPTY_MANIFEST
;
843 tested_manifest_path_override_
= "files/missing-mime-manifest";
844 MockFrontend::HostIds
ids(1, host
->host_id());
845 frontend
->AddExpectedEvent(ids
, CHECKING_EVENT
);
846 frontend
->AddExpectedEvent(ids
, DOWNLOADING_EVENT
);
847 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
); // final
848 frontend
->AddExpectedEvent(ids
, UPDATE_READY_EVENT
);
850 WaitForUpdateToFinish();
853 void ManifestNotFoundTest() {
854 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
857 group_
= new AppCacheGroup(
858 service_
->storage(), MockHttpServer::GetMockUrl("files/nosuchfile"),
859 service_
->storage()->NewGroupId());
860 AppCacheUpdateJob
* update
=
861 new AppCacheUpdateJob(service_
.get(), group_
.get());
862 group_
->update_job_
= update
;
864 AppCache
* cache
= MakeCacheForGroup(1, 111);
865 MockFrontend
* frontend1
= MakeMockFrontend();
866 MockFrontend
* frontend2
= MakeMockFrontend();
867 AppCacheHost
* host1
= MakeHost(1, frontend1
);
868 AppCacheHost
* host2
= MakeHost(2, frontend2
);
869 host1
->AssociateCompleteCache(cache
);
870 host2
->AssociateCompleteCache(cache
);
872 update
->StartUpdate(NULL
, GURL());
873 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
875 // Set up checks for when update job finishes.
876 do_checks_after_update_finished_
= true;
877 expect_group_obsolete_
= true;
878 expect_group_has_cache_
= true;
879 expect_newest_cache_
= cache
; // newest cache unaffected by update
880 MockFrontend::HostIds
ids1(1, host1
->host_id());
881 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
882 frontend1
->AddExpectedEvent(ids1
, OBSOLETE_EVENT
);
883 MockFrontend::HostIds
ids2(1, host2
->host_id());
884 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
885 frontend2
->AddExpectedEvent(ids2
, OBSOLETE_EVENT
);
887 WaitForUpdateToFinish();
890 void ManifestGoneTest() {
891 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
894 group_
= new AppCacheGroup(
895 service_
->storage(), MockHttpServer::GetMockUrl("files/gone"),
896 service_
->storage()->NewGroupId());
897 AppCacheUpdateJob
* update
=
898 new AppCacheUpdateJob(service_
.get(), group_
.get());
899 group_
->update_job_
= update
;
901 MockFrontend
* frontend
= MakeMockFrontend();
902 AppCacheHost
* host
= MakeHost(1, frontend
);
903 update
->StartUpdate(host
, GURL());
904 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
906 // Set up checks for when update job finishes.
907 do_checks_after_update_finished_
= true;
908 expect_group_obsolete_
= false;
909 expect_group_has_cache_
= false;
910 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
913 WaitForUpdateToFinish();
916 void CacheAttemptNotModifiedTest() {
917 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
920 group_
= new AppCacheGroup(
921 service_
->storage(), MockHttpServer::GetMockUrl("files/notmodified"),
922 service_
->storage()->NewGroupId());
923 AppCacheUpdateJob
* update
=
924 new AppCacheUpdateJob(service_
.get(), group_
.get());
925 group_
->update_job_
= update
;
927 MockFrontend
* frontend
= MakeMockFrontend();
928 AppCacheHost
* host
= MakeHost(1, frontend
);
929 update
->StartUpdate(host
, GURL());
930 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
932 // Set up checks for when update job finishes.
933 do_checks_after_update_finished_
= true;
934 expect_group_obsolete_
= false;
935 expect_group_has_cache_
= false; // treated like cache failure
936 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
939 WaitForUpdateToFinish();
942 void UpgradeNotModifiedTest() {
943 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
946 group_
= new AppCacheGroup(
947 service_
->storage(), MockHttpServer::GetMockUrl("files/notmodified"),
948 service_
->storage()->NewGroupId());
949 AppCacheUpdateJob
* update
=
950 new AppCacheUpdateJob(service_
.get(), group_
.get());
951 group_
->update_job_
= update
;
953 AppCache
* cache
= MakeCacheForGroup(1, 111);
954 MockFrontend
* frontend1
= MakeMockFrontend();
955 MockFrontend
* frontend2
= MakeMockFrontend();
956 AppCacheHost
* host1
= MakeHost(1, frontend1
);
957 AppCacheHost
* host2
= MakeHost(2, frontend2
);
958 host1
->AssociateCompleteCache(cache
);
959 host2
->AssociateCompleteCache(cache
);
961 update
->StartUpdate(NULL
, GURL());
962 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
964 // Set up checks for when update job finishes.
965 do_checks_after_update_finished_
= true;
966 expect_group_obsolete_
= false;
967 expect_group_has_cache_
= true;
968 expect_newest_cache_
= cache
; // newest cache unaffected by update
969 MockFrontend::HostIds
ids1(1, host1
->host_id());
970 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
971 frontend1
->AddExpectedEvent(ids1
, NO_UPDATE_EVENT
);
972 MockFrontend::HostIds
ids2(1, host2
->host_id());
973 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
974 frontend2
->AddExpectedEvent(ids2
, NO_UPDATE_EVENT
);
976 WaitForUpdateToFinish();
979 void UpgradeManifestDataUnchangedTest() {
980 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
983 group_
= new AppCacheGroup(
984 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
985 service_
->storage()->NewGroupId());
986 AppCacheUpdateJob
* update
=
987 new AppCacheUpdateJob(service_
.get(), group_
.get());
988 group_
->update_job_
= update
;
990 // Create response writer to get a response id.
991 response_writer_
.reset(
992 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
993 group_
->group_id()));
995 AppCache
* cache
= MakeCacheForGroup(1, response_writer_
->response_id());
996 MockFrontend
* frontend1
= MakeMockFrontend();
997 MockFrontend
* frontend2
= MakeMockFrontend();
998 AppCacheHost
* host1
= MakeHost(1, frontend1
);
999 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1000 host1
->AssociateCompleteCache(cache
);
1001 host2
->AssociateCompleteCache(cache
);
1003 // Set up checks for when update job finishes.
1004 do_checks_after_update_finished_
= true;
1005 expect_group_obsolete_
= false;
1006 expect_group_has_cache_
= true;
1007 expect_newest_cache_
= cache
; // newest cache unaffected by update
1008 MockFrontend::HostIds
ids1(1, host1
->host_id());
1009 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1010 frontend1
->AddExpectedEvent(ids1
, NO_UPDATE_EVENT
);
1011 MockFrontend::HostIds
ids2(1, host2
->host_id());
1012 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1013 frontend2
->AddExpectedEvent(ids2
, NO_UPDATE_EVENT
);
1015 // Seed storage with expected manifest data.
1016 const std::string
seed_data(kManifest1Contents
);
1017 scoped_refptr
<net::StringIOBuffer
> io_buffer(
1018 new net::StringIOBuffer(seed_data
));
1019 response_writer_
->WriteData(
1022 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
1023 base::Unretained(this)));
1025 // Start update after data write completes asynchronously.
1028 // See http://code.google.com/p/chromium/issues/detail?id=95101
1029 void Bug95101Test() {
1030 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1033 group_
= new AppCacheGroup(
1034 service_
->storage(), MockHttpServer::GetMockUrl("files/empty-manifest"),
1035 service_
->storage()->NewGroupId());
1036 AppCacheUpdateJob
* update
=
1037 new AppCacheUpdateJob(service_
.get(), group_
.get());
1038 group_
->update_job_
= update
;
1040 // Create a malformed cache with a missing manifest entry.
1041 GURL wrong_manifest_url
=
1042 MockHttpServer::GetMockUrl("files/missing-mime-manifest");
1043 AppCache
* cache
= MakeCacheForGroup(1, wrong_manifest_url
, 111);
1044 MockFrontend
* frontend
= MakeMockFrontend();
1045 AppCacheHost
* host
= MakeHost(1, frontend
);
1046 host
->AssociateCompleteCache(cache
);
1048 update
->StartUpdate(NULL
, GURL());
1049 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1051 // Set up checks for when update job finishes.
1052 do_checks_after_update_finished_
= true;
1053 expect_group_is_being_deleted_
= true;
1054 expect_group_has_cache_
= true;
1055 expect_newest_cache_
= cache
; // newest cache unaffected by update
1056 MockFrontend::HostIds
id(1, host
->host_id());
1057 frontend
->AddExpectedEvent(id
, CHECKING_EVENT
);
1058 frontend
->AddExpectedEvent(id
, ERROR_EVENT
);
1059 frontend
->expected_error_message_
=
1060 "Manifest entry not found in existing cache";
1061 WaitForUpdateToFinish();
1064 void StartUpdateAfterSeedingStorageData(int result
) {
1065 ASSERT_GT(result
, 0);
1066 response_writer_
.reset();
1068 AppCacheUpdateJob
* update
= group_
->update_job_
;
1069 update
->StartUpdate(NULL
, GURL());
1070 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1072 WaitForUpdateToFinish();
1075 void BasicCacheAttemptSuccessTest() {
1076 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1078 GURL manifest_url
= MockHttpServer::GetMockUrl("files/manifest1");
1081 group_
= new AppCacheGroup(
1082 service_
->storage(), manifest_url
,
1083 service_
->storage()->NewGroupId());
1084 AppCacheUpdateJob
* update
=
1085 new AppCacheUpdateJob(service_
.get(), group_
.get());
1086 group_
->update_job_
= update
;
1088 MockFrontend
* frontend
= MakeMockFrontend();
1089 AppCacheHost
* host
= MakeHost(1, frontend
);
1090 update
->StartUpdate(host
, GURL());
1092 // Set up checks for when update job finishes.
1093 do_checks_after_update_finished_
= true;
1094 expect_group_obsolete_
= false;
1095 expect_group_has_cache_
= true;
1096 tested_manifest_
= MANIFEST1
;
1097 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1100 WaitForUpdateToFinish();
1103 void DownloadInterceptEntriesTest() {
1104 // Ensures we download intercept entries too.
1105 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1107 MockHttpServer::GetMockUrl("files/manifest-with-intercept");
1109 group_
= new AppCacheGroup(
1110 service_
->storage(), manifest_url
,
1111 service_
->storage()->NewGroupId());
1112 AppCacheUpdateJob
* update
=
1113 new AppCacheUpdateJob(service_
.get(), group_
.get());
1114 group_
->update_job_
= update
;
1116 MockFrontend
* frontend
= MakeMockFrontend();
1117 AppCacheHost
* host
= MakeHost(1, frontend
);
1118 update
->StartUpdate(host
, GURL());
1120 // Set up checks for when update job finishes.
1121 do_checks_after_update_finished_
= true;
1122 expect_group_obsolete_
= false;
1123 expect_group_has_cache_
= true;
1124 tested_manifest_
= MANIFEST_WITH_INTERCEPT
;
1125 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1128 WaitForUpdateToFinish();
1131 void BasicUpgradeSuccessTest() {
1132 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1135 group_
= new AppCacheGroup(
1136 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1137 service_
->storage()->NewGroupId());
1138 AppCacheUpdateJob
* update
=
1139 new AppCacheUpdateJob(service_
.get(), group_
.get());
1140 group_
->update_job_
= update
;
1142 // Create a response writer to get a response id.
1143 response_writer_
.reset(
1144 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
1145 group_
->group_id()));
1147 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(),
1148 response_writer_
->response_id());
1149 MockFrontend
* frontend1
= MakeMockFrontend();
1150 MockFrontend
* frontend2
= MakeMockFrontend();
1151 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1152 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1153 host1
->AssociateCompleteCache(cache
);
1154 host2
->AssociateCompleteCache(cache
);
1155 frontend1
->SetVerifyProgressEvents(true);
1156 frontend2
->SetVerifyProgressEvents(true);
1158 // Set up checks for when update job finishes.
1159 do_checks_after_update_finished_
= true;
1160 expect_group_obsolete_
= false;
1161 expect_group_has_cache_
= true;
1162 expect_old_cache_
= cache
;
1163 tested_manifest_
= MANIFEST1
;
1164 MockFrontend::HostIds
ids1(1, host1
->host_id());
1165 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1166 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1167 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
1168 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
1169 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
1170 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
1171 MockFrontend::HostIds
ids2(1, host2
->host_id());
1172 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1173 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1174 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1175 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1176 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
1177 frontend2
->AddExpectedEvent(ids2
, UPDATE_READY_EVENT
);
1179 // Seed storage with expected manifest data different from manifest1.
1180 const std::string
seed_data("different");
1181 scoped_refptr
<net::StringIOBuffer
> io_buffer(
1182 new net::StringIOBuffer(seed_data
));
1183 response_writer_
->WriteData(
1186 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
1187 base::Unretained(this)));
1189 // Start update after data write completes asynchronously.
1192 void UpgradeLoadFromNewestCacheTest() {
1193 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1196 group_
= new AppCacheGroup(
1197 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1198 service_
->storage()->NewGroupId());
1199 AppCacheUpdateJob
* update
=
1200 new AppCacheUpdateJob(service_
.get(), group_
.get());
1201 group_
->update_job_
= update
;
1203 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
1204 MockFrontend
* frontend
= MakeMockFrontend();
1205 AppCacheHost
* host
= MakeHost(1, frontend
);
1206 host
->AssociateCompleteCache(cache
);
1208 // Give the newest cache an entry that is in storage.
1209 response_writer_
.reset(
1210 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
1211 group_
->group_id()));
1212 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
1213 AppCacheEntry(AppCacheEntry::EXPLICIT
,
1214 response_writer_
->response_id()));
1216 // Set up checks for when update job finishes.
1217 do_checks_after_update_finished_
= true;
1218 expect_group_obsolete_
= false;
1219 expect_group_has_cache_
= true;
1220 expect_old_cache_
= cache
;
1221 expect_response_ids_
.insert(
1222 std::map
<GURL
, int64
>::value_type(
1223 MockHttpServer::GetMockUrl("files/explicit1"),
1224 response_writer_
->response_id()));
1225 tested_manifest_
= MANIFEST1
;
1226 MockFrontend::HostIds
ids(1, host
->host_id());
1227 frontend
->AddExpectedEvent(ids
, CHECKING_EVENT
);
1228 frontend
->AddExpectedEvent(ids
, DOWNLOADING_EVENT
);
1229 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1230 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1231 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
); // final
1232 frontend
->AddExpectedEvent(ids
, UPDATE_READY_EVENT
);
1234 // Seed storage with expected http response info for entry. Allow reuse.
1237 "Cache-Control: max-age=8675309\0"
1239 net::HttpResponseHeaders
* headers
=
1240 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
1241 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
1242 response_info
->request_time
= base::Time::Now();
1243 response_info
->response_time
= base::Time::Now();
1244 response_info
->headers
= headers
; // adds ref to headers
1245 scoped_refptr
<HttpResponseInfoIOBuffer
> io_buffer(
1246 new HttpResponseInfoIOBuffer(response_info
)); // adds ref to info
1247 response_writer_
->WriteInfo(
1249 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
1250 base::Unretained(this)));
1252 // Start update after data write completes asynchronously.
1255 void UpgradeNoLoadFromNewestCacheTest() {
1256 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1259 group_
= new AppCacheGroup(
1260 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1261 service_
->storage()->NewGroupId());
1262 AppCacheUpdateJob
* update
=
1263 new AppCacheUpdateJob(service_
.get(), group_
.get());
1264 group_
->update_job_
= update
;
1266 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
1267 MockFrontend
* frontend
= MakeMockFrontend();
1268 AppCacheHost
* host
= MakeHost(1, frontend
);
1269 host
->AssociateCompleteCache(cache
);
1271 // Give the newest cache an entry that is in storage.
1272 response_writer_
.reset(
1273 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
1274 group_
->group_id()));
1275 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
1276 AppCacheEntry(AppCacheEntry::EXPLICIT
,
1277 response_writer_
->response_id()));
1279 // Set up checks for when update job finishes.
1280 do_checks_after_update_finished_
= true;
1281 expect_group_obsolete_
= false;
1282 expect_group_has_cache_
= true;
1283 expect_old_cache_
= cache
;
1284 tested_manifest_
= MANIFEST1
;
1285 MockFrontend::HostIds
ids(1, host
->host_id());
1286 frontend
->AddExpectedEvent(ids
, CHECKING_EVENT
);
1287 frontend
->AddExpectedEvent(ids
, DOWNLOADING_EVENT
);
1288 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1289 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1290 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
); // final
1291 frontend
->AddExpectedEvent(ids
, UPDATE_READY_EVENT
);
1293 // Seed storage with expected http response info for entry. Do NOT
1294 // allow reuse by setting an expires header in the past.
1297 "Expires: Thu, 01 Dec 1994 16:00:00 GMT\0"
1299 net::HttpResponseHeaders
* headers
=
1300 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
1301 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
1302 response_info
->request_time
= base::Time::Now();
1303 response_info
->response_time
= base::Time::Now();
1304 response_info
->headers
= headers
; // adds ref to headers
1305 scoped_refptr
<HttpResponseInfoIOBuffer
> io_buffer(
1306 new HttpResponseInfoIOBuffer(response_info
)); // adds ref to info
1307 response_writer_
->WriteInfo(
1309 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
1310 base::Unretained(this)));
1312 // Start update after data write completes asynchronously.
1315 void UpgradeLoadFromNewestCacheVaryHeaderTest() {
1316 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1319 group_
= new AppCacheGroup(
1320 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1321 service_
->storage()->NewGroupId());
1322 AppCacheUpdateJob
* update
=
1323 new AppCacheUpdateJob(service_
.get(), group_
.get());
1324 group_
->update_job_
= update
;
1326 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
1327 MockFrontend
* frontend
= MakeMockFrontend();
1328 AppCacheHost
* host
= MakeHost(1, frontend
);
1329 host
->AssociateCompleteCache(cache
);
1331 // Give the newest cache an entry that is in storage.
1332 response_writer_
.reset(
1333 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
1334 group_
->group_id()));
1335 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
1336 AppCacheEntry(AppCacheEntry::EXPLICIT
,
1337 response_writer_
->response_id()));
1339 // Set up checks for when update job finishes.
1340 do_checks_after_update_finished_
= true;
1341 expect_group_obsolete_
= false;
1342 expect_group_has_cache_
= true;
1343 expect_old_cache_
= cache
;
1344 tested_manifest_
= MANIFEST1
;
1345 MockFrontend::HostIds
ids(1, host
->host_id());
1346 frontend
->AddExpectedEvent(ids
, CHECKING_EVENT
);
1347 frontend
->AddExpectedEvent(ids
, DOWNLOADING_EVENT
);
1348 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1349 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
);
1350 frontend
->AddExpectedEvent(ids
, PROGRESS_EVENT
); // final
1351 frontend
->AddExpectedEvent(ids
, UPDATE_READY_EVENT
);
1353 // Seed storage with expected http response info for entry: a vary header.
1356 "Cache-Control: max-age=8675309\0"
1359 net::HttpResponseHeaders
* headers
=
1360 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
1361 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
1362 response_info
->request_time
= base::Time::Now();
1363 response_info
->response_time
= base::Time::Now();
1364 response_info
->headers
= headers
; // adds ref to headers
1365 scoped_refptr
<HttpResponseInfoIOBuffer
> io_buffer(
1366 new HttpResponseInfoIOBuffer(response_info
)); // adds ref to info
1367 response_writer_
->WriteInfo(
1369 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
1370 base::Unretained(this)));
1372 // Start update after data write completes asynchronously.
1375 void UpgradeSuccessMergedTypesTest() {
1376 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1379 group_
= new AppCacheGroup(service_
->storage(),
1380 MockHttpServer::GetMockUrl("files/manifest-merged-types"),
1381 service_
->storage()->NewGroupId());
1382 AppCacheUpdateJob
* update
=
1383 new AppCacheUpdateJob(service_
.get(), group_
.get());
1384 group_
->update_job_
= update
;
1386 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
1387 MockFrontend
* frontend1
= MakeMockFrontend();
1388 MockFrontend
* frontend2
= MakeMockFrontend();
1389 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1390 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1391 host1
->AssociateCompleteCache(cache
);
1392 host2
->AssociateCompleteCache(cache
);
1394 // Give the newest cache a master entry that is also one of the explicit
1395 // entries in the manifest.
1396 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit1"),
1397 AppCacheEntry(AppCacheEntry::MASTER
, 111));
1399 update
->StartUpdate(NULL
, GURL());
1400 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1402 // Set up checks for when update job finishes.
1403 do_checks_after_update_finished_
= true;
1404 expect_group_obsolete_
= false;
1405 expect_group_has_cache_
= true;
1406 expect_old_cache_
= cache
;
1407 tested_manifest_
= MANIFEST_MERGED_TYPES
;
1408 MockFrontend::HostIds
ids1(1, host1
->host_id());
1409 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1410 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1411 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // explicit1
1412 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // manifest
1413 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
1414 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
1415 MockFrontend::HostIds
ids2(1, host2
->host_id());
1416 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1417 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1418 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1419 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1420 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
1421 frontend2
->AddExpectedEvent(ids2
, UPDATE_READY_EVENT
);
1423 WaitForUpdateToFinish();
1426 void CacheAttemptFailUrlFetchTest() {
1427 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1430 group_
= new AppCacheGroup(service_
->storage(),
1431 MockHttpServer::GetMockUrl("files/manifest-with-404"),
1432 service_
->storage()->NewGroupId());
1433 AppCacheUpdateJob
* update
=
1434 new AppCacheUpdateJob(service_
.get(), group_
.get());
1435 group_
->update_job_
= update
;
1437 MockFrontend
* frontend
= MakeMockFrontend();
1438 AppCacheHost
* host
= MakeHost(1, frontend
);
1439 update
->StartUpdate(host
, GURL());
1440 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1442 // Set up checks for when update job finishes.
1443 do_checks_after_update_finished_
= true;
1444 expect_group_obsolete_
= false;
1445 expect_group_has_cache_
= false; // 404 explicit url is cache failure
1446 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1449 WaitForUpdateToFinish();
1452 void UpgradeFailUrlFetchTest() {
1453 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1456 group_
= new AppCacheGroup(service_
->storage(),
1457 MockHttpServer::GetMockUrl("files/manifest-fb-404"),
1458 service_
->storage()->NewGroupId());
1459 AppCacheUpdateJob
* update
=
1460 new AppCacheUpdateJob(service_
.get(), group_
.get());
1461 group_
->update_job_
= update
;
1463 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 99);
1464 MockFrontend
* frontend1
= MakeMockFrontend();
1465 MockFrontend
* frontend2
= MakeMockFrontend();
1466 frontend1
->SetIgnoreProgressEvents(true);
1467 frontend2
->SetIgnoreProgressEvents(true);
1468 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1469 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1470 host1
->AssociateCompleteCache(cache
);
1471 host2
->AssociateCompleteCache(cache
);
1473 update
->StartUpdate(NULL
, GURL());
1474 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1476 // Set up checks for when update job finishes.
1477 do_checks_after_update_finished_
= true;
1478 expect_group_obsolete_
= false;
1479 expect_group_has_cache_
= true;
1480 expect_newest_cache_
= cache
; // newest cache unaffectd by failed update
1481 MockFrontend::HostIds
ids1(1, host1
->host_id());
1482 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1483 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1484 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
1485 MockFrontend::HostIds
ids2(1, host2
->host_id());
1486 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1487 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1488 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
1490 WaitForUpdateToFinish();
1493 void UpgradeFailMasterUrlFetchTest() {
1494 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1496 tested_manifest_path_override_
= "files/manifest1-with-notmodified";
1499 const GURL kManifestUrl
=
1500 MockHttpServer::GetMockUrl(tested_manifest_path_override_
);
1501 group_
= new AppCacheGroup(
1502 service_
->storage(), kManifestUrl
,
1503 service_
->storage()->NewGroupId());
1504 AppCacheUpdateJob
* update
=
1505 new AppCacheUpdateJob(service_
.get(), group_
.get());
1506 group_
->update_job_
= update
;
1508 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 25);
1509 MockFrontend
* frontend1
= MakeMockFrontend();
1510 MockFrontend
* frontend2
= MakeMockFrontend();
1511 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1512 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1513 host1
->AssociateCompleteCache(cache
);
1514 host2
->AssociateCompleteCache(cache
);
1516 // Give the newest cache some existing entries; one will fail with a 404.
1518 MockHttpServer::GetMockUrl("files/notfound"),
1519 AppCacheEntry(AppCacheEntry::MASTER
, 222));
1521 MockHttpServer::GetMockUrl("files/explicit2"),
1522 AppCacheEntry(AppCacheEntry::MASTER
| AppCacheEntry::FOREIGN
, 333));
1524 MockHttpServer::GetMockUrl("files/servererror"),
1525 AppCacheEntry(AppCacheEntry::MASTER
, 444));
1527 MockHttpServer::GetMockUrl("files/notmodified"),
1528 AppCacheEntry(AppCacheEntry::EXPLICIT
, 555));
1530 // Seed the response_info working set with canned data for
1531 // files/servererror and for files/notmodified to test that the
1532 // existing entries for those resource are reused by the update job.
1533 const char kData
[] =
1535 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0"
1537 const std::string
kRawHeaders(kData
, arraysize(kData
));
1538 MakeAppCacheResponseInfo(kManifestUrl
, 444, kRawHeaders
);
1539 MakeAppCacheResponseInfo(kManifestUrl
, 555, kRawHeaders
);
1541 update
->StartUpdate(NULL
, GURL());
1542 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1544 // Set up checks for when update job finishes.
1545 do_checks_after_update_finished_
= true;
1546 expect_group_obsolete_
= false;
1547 expect_group_has_cache_
= true;
1548 expect_old_cache_
= cache
;
1549 tested_manifest_
= MANIFEST1
;
1550 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
1551 MockHttpServer::GetMockUrl("files/explicit2"),
1552 AppCacheEntry(AppCacheEntry::MASTER
))); // foreign flag is dropped
1553 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
1554 MockHttpServer::GetMockUrl("files/servererror"),
1555 AppCacheEntry(AppCacheEntry::MASTER
)));
1556 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
1557 MockHttpServer::GetMockUrl("files/notmodified"),
1558 AppCacheEntry(AppCacheEntry::EXPLICIT
)));
1559 expect_response_ids_
.insert(std::map
<GURL
, int64
>::value_type(
1560 MockHttpServer::GetMockUrl("files/servererror"), 444)); // copied
1561 expect_response_ids_
.insert(std::map
<GURL
, int64
>::value_type(
1562 MockHttpServer::GetMockUrl("files/notmodified"), 555)); // copied
1563 MockFrontend::HostIds
ids1(1, host1
->host_id());
1564 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1565 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1566 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // explicit1
1567 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // fallback1a
1568 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // notfound
1569 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // explicit2
1570 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // servererror
1571 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // notmodified
1572 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
1573 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
1574 MockFrontend::HostIds
ids2(1, host2
->host_id());
1575 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1576 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1577 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // explicit1
1578 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // fallback1a
1579 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // notfound
1580 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // explicit2
1581 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // servererror
1582 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // notmodified
1583 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
1584 frontend2
->AddExpectedEvent(ids2
, UPDATE_READY_EVENT
);
1586 WaitForUpdateToFinish();
1589 void EmptyManifestTest() {
1590 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1593 group_
= new AppCacheGroup(
1594 service_
->storage(), MockHttpServer::GetMockUrl("files/empty-manifest"),
1595 service_
->storage()->NewGroupId());
1596 AppCacheUpdateJob
* update
=
1597 new AppCacheUpdateJob(service_
.get(), group_
.get());
1598 group_
->update_job_
= update
;
1600 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 33);
1601 MockFrontend
* frontend1
= MakeMockFrontend();
1602 MockFrontend
* frontend2
= MakeMockFrontend();
1603 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1604 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1605 host1
->AssociateCompleteCache(cache
);
1606 host2
->AssociateCompleteCache(cache
);
1608 frontend1
->SetVerifyProgressEvents(true);
1610 update
->StartUpdate(NULL
, GURL());
1611 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1613 // Set up checks for when update job finishes.
1614 do_checks_after_update_finished_
= true;
1615 expect_group_obsolete_
= false;
1616 expect_group_has_cache_
= true;
1617 expect_old_cache_
= cache
;
1618 tested_manifest_
= EMPTY_MANIFEST
;
1619 MockFrontend::HostIds
ids1(1, host1
->host_id());
1620 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1621 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1622 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
1623 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
1624 MockFrontend::HostIds
ids2(1, host2
->host_id());
1625 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1626 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1627 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
1628 frontend2
->AddExpectedEvent(ids2
, UPDATE_READY_EVENT
);
1630 WaitForUpdateToFinish();
1633 void EmptyFileTest() {
1634 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1637 group_
= new AppCacheGroup(service_
->storage(),
1638 MockHttpServer::GetMockUrl("files/empty-file-manifest"),
1639 service_
->storage()->NewGroupId());
1640 AppCacheUpdateJob
* update
=
1641 new AppCacheUpdateJob(service_
.get(), group_
.get());
1642 group_
->update_job_
= update
;
1644 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 22);
1645 MockFrontend
* frontend
= MakeMockFrontend();
1646 AppCacheHost
* host
= MakeHost(1, frontend
);
1647 host
->AssociateCompleteCache(cache
);
1648 frontend
->SetVerifyProgressEvents(true);
1650 update
->StartUpdate(host
, GURL());
1651 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1653 // Set up checks for when update job finishes.
1654 do_checks_after_update_finished_
= true;
1655 expect_group_obsolete_
= false;
1656 expect_group_has_cache_
= true;
1657 tested_manifest_
= EMPTY_FILE_MANIFEST
;
1658 MockFrontend::HostIds
ids1(1, host
->host_id());
1659 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1660 frontend
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1661 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
1662 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
1663 frontend
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
1665 WaitForUpdateToFinish();
1668 void RetryRequestTest() {
1669 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1671 // Set some large number of times to return retry.
1672 // Expect 1 manifest fetch and 3 retries.
1673 RetryRequestTestJob::Initialize(5, RetryRequestTestJob::RETRY_AFTER_0
, 4);
1674 net::URLRequestJobFactoryImpl
* new_factory(
1675 new net::URLRequestJobFactoryImpl
);
1676 new_factory
->SetProtocolHandler("http", new RetryRequestTestJobFactory
);
1677 io_thread_
->SetNewJobFactory(new_factory
);
1680 group_
= new AppCacheGroup(service_
->storage(),
1681 RetryRequestTestJob::kRetryUrl
,
1682 service_
->storage()->NewGroupId());
1683 AppCacheUpdateJob
* update
=
1684 new AppCacheUpdateJob(service_
.get(), group_
.get());
1685 group_
->update_job_
= update
;
1687 MockFrontend
* frontend
= MakeMockFrontend();
1688 AppCacheHost
* host
= MakeHost(1, frontend
);
1689 update
->StartUpdate(host
, GURL());
1690 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1692 // Set up checks for when update job finishes.
1693 do_checks_after_update_finished_
= true;
1694 expect_group_obsolete_
= false;
1695 expect_group_has_cache_
= false;
1696 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1699 WaitForUpdateToFinish();
1702 void RetryNoRetryAfterTest() {
1703 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1705 // Set some large number of times to return retry.
1706 // Expect 1 manifest fetch and 0 retries.
1707 RetryRequestTestJob::Initialize(5, RetryRequestTestJob::NO_RETRY_AFTER
, 1);
1708 net::URLRequestJobFactoryImpl
* new_factory(
1709 new net::URLRequestJobFactoryImpl
);
1710 new_factory
->SetProtocolHandler("http", new RetryRequestTestJobFactory
);
1711 io_thread_
->SetNewJobFactory(new_factory
);
1714 group_
= new AppCacheGroup(service_
->storage(),
1715 RetryRequestTestJob::kRetryUrl
,
1716 service_
->storage()->NewGroupId());
1717 AppCacheUpdateJob
* update
=
1718 new AppCacheUpdateJob(service_
.get(), group_
.get());
1719 group_
->update_job_
= update
;
1721 MockFrontend
* frontend
= MakeMockFrontend();
1722 AppCacheHost
* host
= MakeHost(1, frontend
);
1723 update
->StartUpdate(host
, GURL());
1724 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1726 // Set up checks for when update job finishes.
1727 do_checks_after_update_finished_
= true;
1728 expect_group_obsolete_
= false;
1729 expect_group_has_cache_
= false;
1730 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1733 WaitForUpdateToFinish();
1736 void RetryNonzeroRetryAfterTest() {
1737 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1739 // Set some large number of times to return retry.
1740 // Expect 1 request and 0 retry attempts.
1741 RetryRequestTestJob::Initialize(
1742 5, RetryRequestTestJob::NONZERO_RETRY_AFTER
, 1);
1743 net::URLRequestJobFactoryImpl
* new_factory(
1744 new net::URLRequestJobFactoryImpl
);
1745 new_factory
->SetProtocolHandler("http", new RetryRequestTestJobFactory
);
1746 io_thread_
->SetNewJobFactory(new_factory
);
1749 group_
= new AppCacheGroup(service_
->storage(),
1750 RetryRequestTestJob::kRetryUrl
,
1751 service_
->storage()->NewGroupId());
1752 AppCacheUpdateJob
* update
=
1753 new AppCacheUpdateJob(service_
.get(), group_
.get());
1754 group_
->update_job_
= update
;
1756 MockFrontend
* frontend
= MakeMockFrontend();
1757 AppCacheHost
* host
= MakeHost(1, frontend
);
1758 update
->StartUpdate(host
, GURL());
1759 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1761 // Set up checks for when update job finishes.
1762 do_checks_after_update_finished_
= true;
1763 expect_group_obsolete_
= false;
1764 expect_group_has_cache_
= false;
1765 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1768 WaitForUpdateToFinish();
1771 void RetrySuccessTest() {
1772 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1774 // Set 2 as the retry limit (does not exceed the max).
1775 // Expect 1 manifest fetch, 2 retries, 1 url fetch, 1 manifest refetch.
1776 RetryRequestTestJob::Initialize(2, RetryRequestTestJob::RETRY_AFTER_0
, 5);
1777 net::URLRequestJobFactoryImpl
* new_factory(
1778 new net::URLRequestJobFactoryImpl
);
1779 new_factory
->SetProtocolHandler("http", new RetryRequestTestJobFactory
);
1780 io_thread_
->SetNewJobFactory(new_factory
);
1783 group_
= new AppCacheGroup(service_
->storage(),
1784 RetryRequestTestJob::kRetryUrl
,
1785 service_
->storage()->NewGroupId());
1786 AppCacheUpdateJob
* update
=
1787 new AppCacheUpdateJob(service_
.get(), group_
.get());
1788 group_
->update_job_
= update
;
1790 MockFrontend
* frontend
= MakeMockFrontend();
1791 AppCacheHost
* host
= MakeHost(1, frontend
);
1792 update
->StartUpdate(host
, GURL());
1793 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1795 // Set up checks for when update job finishes.
1796 do_checks_after_update_finished_
= true;
1797 expect_group_obsolete_
= false;
1798 expect_group_has_cache_
= true;
1799 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1802 WaitForUpdateToFinish();
1805 void RetryUrlTest() {
1806 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1808 // Set 1 as the retry limit (does not exceed the max).
1809 // Expect 1 manifest fetch, 1 url fetch, 1 url retry, 1 manifest refetch.
1810 RetryRequestTestJob::Initialize(1, RetryRequestTestJob::RETRY_AFTER_0
, 4);
1811 net::URLRequestJobFactoryImpl
* new_factory(
1812 new net::URLRequestJobFactoryImpl
);
1813 new_factory
->SetProtocolHandler("http", new RetryRequestTestJobFactory
);
1814 io_thread_
->SetNewJobFactory(new_factory
);
1817 group_
= new AppCacheGroup(service_
->storage(), GURL("http://retryurl"),
1818 service_
->storage()->NewGroupId());
1819 AppCacheUpdateJob
* update
=
1820 new AppCacheUpdateJob(service_
.get(), group_
.get());
1821 group_
->update_job_
= update
;
1823 MockFrontend
* frontend
= MakeMockFrontend();
1824 AppCacheHost
* host
= MakeHost(1, frontend
);
1825 update
->StartUpdate(host
, GURL());
1826 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1828 // Set up checks for when update job finishes.
1829 do_checks_after_update_finished_
= true;
1830 expect_group_obsolete_
= false;
1831 expect_group_has_cache_
= true;
1832 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1835 WaitForUpdateToFinish();
1838 void FailStoreNewestCacheTest() {
1839 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1842 MockAppCacheStorage
* storage
=
1843 reinterpret_cast<MockAppCacheStorage
*>(service_
->storage());
1844 storage
->SimulateStoreGroupAndNewestCacheFailure();
1846 group_
= new AppCacheGroup(
1847 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1848 service_
->storage()->NewGroupId());
1849 AppCacheUpdateJob
* update
=
1850 new AppCacheUpdateJob(service_
.get(), group_
.get());
1851 group_
->update_job_
= update
;
1853 MockFrontend
* frontend
= MakeMockFrontend();
1854 AppCacheHost
* host
= MakeHost(1, frontend
);
1855 update
->StartUpdate(host
, GURL());
1857 // Set up checks for when update job finishes.
1858 do_checks_after_update_finished_
= true;
1859 expect_group_obsolete_
= false;
1860 expect_group_has_cache_
= false; // storage failed
1861 frontend
->AddExpectedEvent(MockFrontend::HostIds(1, host
->host_id()),
1864 WaitForUpdateToFinish();
1867 void UpgradeFailStoreNewestCacheTest() {
1868 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1871 MockAppCacheStorage
* storage
=
1872 reinterpret_cast<MockAppCacheStorage
*>(service_
->storage());
1873 storage
->SimulateStoreGroupAndNewestCacheFailure();
1875 group_
= new AppCacheGroup(
1876 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
1877 service_
->storage()->NewGroupId());
1878 AppCacheUpdateJob
* update
=
1879 new AppCacheUpdateJob(service_
.get(), group_
.get());
1880 group_
->update_job_
= update
;
1882 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 11);
1883 MockFrontend
* frontend1
= MakeMockFrontend();
1884 MockFrontend
* frontend2
= MakeMockFrontend();
1885 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1886 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1887 host1
->AssociateCompleteCache(cache
);
1888 host2
->AssociateCompleteCache(cache
);
1890 update
->StartUpdate(NULL
, GURL());
1892 // Set up checks for when update job finishes.
1893 do_checks_after_update_finished_
= true;
1894 expect_group_obsolete_
= false;
1895 expect_group_has_cache_
= true;
1896 expect_newest_cache_
= cache
; // unchanged
1897 MockFrontend::HostIds
ids1(1, host1
->host_id());
1898 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1899 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
1900 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
1901 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
1902 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
1903 MockFrontend::HostIds
ids2(1, host2
->host_id());
1904 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1905 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
1906 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1907 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
1908 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
1910 WaitForUpdateToFinish();
1913 void MasterEntryFailStoreNewestCacheTest() {
1914 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1917 MockAppCacheStorage
* storage
=
1918 reinterpret_cast<MockAppCacheStorage
*>(service_
->storage());
1919 storage
->SimulateStoreGroupAndNewestCacheFailure();
1921 const GURL kManifestUrl
= MockHttpServer::GetMockUrl("files/notmodified");
1922 const int64 kManifestResponseId
= 11;
1924 // Seed the response_info working set with canned data for
1925 // files/servererror and for files/notmodified to test that the
1926 // existing entries for those resource are reused by the update job.
1927 const char kData
[] =
1929 "Content-type: text/cache-manifest\0"
1930 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0"
1932 const std::string
kRawHeaders(kData
, arraysize(kData
));
1933 MakeAppCacheResponseInfo(kManifestUrl
, kManifestResponseId
, kRawHeaders
);
1935 group_
= new AppCacheGroup(
1936 service_
->storage(), kManifestUrl
,
1937 service_
->storage()->NewGroupId());
1938 scoped_refptr
<AppCache
> cache(
1939 MakeCacheForGroup(service_
->storage()->NewCacheId(),
1940 kManifestResponseId
));
1942 MockFrontend
* frontend
= MakeMockFrontend();
1943 AppCacheHost
* host
= MakeHost(1, frontend
);
1944 host
->first_party_url_
= kManifestUrl
;
1945 host
->SelectCache(MockHttpServer::GetMockUrl("files/empty1"),
1946 kNoCacheId
, kManifestUrl
);
1948 // Set up checks for when update job finishes.
1949 do_checks_after_update_finished_
= true;
1950 tested_manifest_
= EMPTY_MANIFEST
;
1951 tested_manifest_path_override_
= "files/notmodified";
1952 expect_group_obsolete_
= false;
1953 expect_group_has_cache_
= true;
1954 expect_newest_cache_
= cache
.get(); // unchanged
1955 MockFrontend::HostIds
ids1(1, host
->host_id());
1956 frontend
->AddExpectedEvent(ids1
, ERROR_EVENT
);
1957 frontend
->expected_error_message_
=
1958 "Failed to commit new cache to storage";
1960 WaitForUpdateToFinish();
1963 void UpgradeFailMakeGroupObsoleteTest() {
1964 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
1967 MockAppCacheStorage
* storage
=
1968 reinterpret_cast<MockAppCacheStorage
*>(service_
->storage());
1969 storage
->SimulateMakeGroupObsoleteFailure();
1971 group_
= new AppCacheGroup(
1972 service_
->storage(), MockHttpServer::GetMockUrl("files/nosuchfile"),
1973 service_
->storage()->NewGroupId());
1974 AppCacheUpdateJob
* update
=
1975 new AppCacheUpdateJob(service_
.get(), group_
.get());
1976 group_
->update_job_
= update
;
1978 AppCache
* cache
= MakeCacheForGroup(1, 111);
1979 MockFrontend
* frontend1
= MakeMockFrontend();
1980 MockFrontend
* frontend2
= MakeMockFrontend();
1981 AppCacheHost
* host1
= MakeHost(1, frontend1
);
1982 AppCacheHost
* host2
= MakeHost(2, frontend2
);
1983 host1
->AssociateCompleteCache(cache
);
1984 host2
->AssociateCompleteCache(cache
);
1986 update
->StartUpdate(NULL
, GURL());
1987 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
1989 // Set up checks for when update job finishes.
1990 do_checks_after_update_finished_
= true;
1991 expect_group_obsolete_
= false;
1992 expect_group_has_cache_
= true;
1993 expect_newest_cache_
= cache
; // newest cache unaffected by update
1994 MockFrontend::HostIds
ids1(1, host1
->host_id());
1995 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
1996 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
1997 MockFrontend::HostIds
ids2(1, host2
->host_id());
1998 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
1999 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2001 WaitForUpdateToFinish();
2004 void MasterEntryFetchManifestFailTest() {
2005 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2008 group_
= new AppCacheGroup(service_
->storage(), GURL("http://failme"), 111);
2009 AppCacheUpdateJob
* update
=
2010 new AppCacheUpdateJob(service_
.get(), group_
.get());
2011 group_
->update_job_
= update
;
2013 MockFrontend
* frontend
= MakeMockFrontend();
2014 AppCacheHost
* host
= MakeHost(1, frontend
);
2015 host
->new_master_entry_url_
= GURL("http://failme/blah");
2016 update
->StartUpdate(host
, host
->new_master_entry_url_
);
2017 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2019 update
->manifest_fetcher_
->request()->CancelWithError(-100);
2021 // Set up checks for when update job finishes.
2022 do_checks_after_update_finished_
= true;
2023 expect_group_obsolete_
= false;
2024 expect_group_has_cache_
= false;
2025 MockFrontend::HostIds
ids1(1, host
->host_id());
2026 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2027 frontend
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2029 WaitForUpdateToFinish();
2032 void MasterEntryBadManifestTest() {
2033 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2036 group_
= new AppCacheGroup(service_
->storage(),
2037 MockHttpServer::GetMockUrl("files/bad-manifest"), 111);
2038 AppCacheUpdateJob
* update
=
2039 new AppCacheUpdateJob(service_
.get(), group_
.get());
2040 group_
->update_job_
= update
;
2042 MockFrontend
* frontend
= MakeMockFrontend();
2043 AppCacheHost
* host
= MakeHost(1, frontend
);
2044 host
->new_master_entry_url_
= MockHttpServer::GetMockUrl("files/blah");
2045 update
->StartUpdate(host
, host
->new_master_entry_url_
);
2046 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2048 // Set up checks for when update job finishes.
2049 do_checks_after_update_finished_
= true;
2050 expect_group_obsolete_
= false;
2051 expect_group_has_cache_
= false;
2052 MockFrontend::HostIds
ids1(1, host
->host_id());
2053 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2054 frontend
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2056 WaitForUpdateToFinish();
2059 void MasterEntryManifestNotFoundTest() {
2060 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2063 group_
= new AppCacheGroup(
2064 service_
->storage(),
2065 MockHttpServer::GetMockUrl("files/nosuchfile"),
2067 AppCacheUpdateJob
* update
=
2068 new AppCacheUpdateJob(service_
.get(), group_
.get());
2069 group_
->update_job_
= update
;
2071 MockFrontend
* frontend
= MakeMockFrontend();
2072 AppCacheHost
* host
= MakeHost(1, frontend
);
2073 host
->new_master_entry_url_
= MockHttpServer::GetMockUrl("files/blah");
2075 update
->StartUpdate(host
, host
->new_master_entry_url_
);
2076 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2078 // Set up checks for when update job finishes.
2079 do_checks_after_update_finished_
= true;
2080 expect_group_obsolete_
= false;
2081 expect_group_has_cache_
= false;
2082 MockFrontend::HostIds
ids1(1, host
->host_id());
2083 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2084 frontend
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2086 WaitForUpdateToFinish();
2089 void MasterEntryFailUrlFetchTest() {
2090 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2093 group_
= new AppCacheGroup(service_
->storage(),
2094 MockHttpServer::GetMockUrl("files/manifest-fb-404"), 111);
2095 AppCacheUpdateJob
* update
=
2096 new AppCacheUpdateJob(service_
.get(), group_
.get());
2097 group_
->update_job_
= update
;
2099 MockFrontend
* frontend
= MakeMockFrontend();
2100 frontend
->SetIgnoreProgressEvents(true);
2101 AppCacheHost
* host
= MakeHost(1, frontend
);
2102 host
->new_master_entry_url_
=
2103 MockHttpServer::GetMockUrl("files/explicit1");
2105 update
->StartUpdate(host
, host
->new_master_entry_url_
);
2106 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2108 // Set up checks for when update job finishes.
2109 do_checks_after_update_finished_
= true;
2110 expect_group_obsolete_
= false;
2111 expect_group_has_cache_
= false; // 404 fallback url is cache failure
2112 MockFrontend::HostIds
ids1(1, host
->host_id());
2113 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2114 frontend
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2115 frontend
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2117 WaitForUpdateToFinish();
2120 void MasterEntryAllFailTest() {
2121 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2124 group_
= new AppCacheGroup(
2125 service_
->storage(),
2126 MockHttpServer::GetMockUrl("files/manifest1"),
2128 AppCacheUpdateJob
* update
=
2129 new AppCacheUpdateJob(service_
.get(), group_
.get());
2130 group_
->update_job_
= update
;
2132 MockFrontend
* frontend1
= MakeMockFrontend();
2133 frontend1
->SetIgnoreProgressEvents(true);
2134 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2135 host1
->new_master_entry_url_
=
2136 MockHttpServer::GetMockUrl("files/nosuchfile");
2137 update
->StartUpdate(host1
, host1
->new_master_entry_url_
);
2139 MockFrontend
* frontend2
= MakeMockFrontend();
2140 frontend2
->SetIgnoreProgressEvents(true);
2141 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2142 host2
->new_master_entry_url_
=
2143 MockHttpServer::GetMockUrl("files/servererror");
2144 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2146 // Set up checks for when update job finishes.
2147 do_checks_after_update_finished_
= true;
2148 expect_group_obsolete_
= false;
2149 expect_group_has_cache_
= false; // all pending masters failed
2150 MockFrontend::HostIds
ids1(1, host1
->host_id());
2151 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2152 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2153 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2154 MockFrontend::HostIds
ids2(1, host2
->host_id());
2155 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
2156 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2157 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2159 WaitForUpdateToFinish();
2162 void UpgradeMasterEntryAllFailTest() {
2163 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2166 group_
= new AppCacheGroup(
2167 service_
->storage(),
2168 MockHttpServer::GetMockUrl("files/manifest1"),
2170 AppCacheUpdateJob
* update
=
2171 new AppCacheUpdateJob(service_
.get(), group_
.get());
2172 group_
->update_job_
= update
;
2174 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
2175 MockFrontend
* frontend1
= MakeMockFrontend();
2176 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2177 host1
->AssociateCompleteCache(cache
);
2179 MockFrontend
* frontend2
= MakeMockFrontend();
2180 frontend2
->SetIgnoreProgressEvents(true);
2181 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2182 host2
->new_master_entry_url_
=
2183 MockHttpServer::GetMockUrl("files/nosuchfile");
2184 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2186 MockFrontend
* frontend3
= MakeMockFrontend();
2187 frontend3
->SetIgnoreProgressEvents(true);
2188 AppCacheHost
* host3
= MakeHost(3, frontend3
);
2189 host3
->new_master_entry_url_
=
2190 MockHttpServer::GetMockUrl("files/servererror");
2191 update
->StartUpdate(host3
, host3
->new_master_entry_url_
);
2193 // Set up checks for when update job finishes.
2194 do_checks_after_update_finished_
= true;
2195 expect_group_obsolete_
= false;
2196 expect_group_has_cache_
= true;
2197 expect_old_cache_
= cache
;
2198 tested_manifest_
= MANIFEST1
;
2199 MockFrontend::HostIds
ids1(1, host1
->host_id());
2200 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2201 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2202 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2203 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2204 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2205 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
2206 MockFrontend::HostIds
ids2(1, host2
->host_id());
2207 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2208 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2209 MockFrontend::HostIds
ids3(1, host3
->host_id());
2210 frontend3
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2211 frontend3
->AddExpectedEvent(ids3
, DOWNLOADING_EVENT
);
2212 frontend3
->AddExpectedEvent(ids3
, ERROR_EVENT
);
2214 WaitForUpdateToFinish();
2217 void MasterEntrySomeFailTest() {
2218 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2221 group_
= new AppCacheGroup(
2222 service_
->storage(),
2223 MockHttpServer::GetMockUrl("files/manifest1"),
2225 AppCacheUpdateJob
* update
=
2226 new AppCacheUpdateJob(service_
.get(), group_
.get());
2227 group_
->update_job_
= update
;
2229 MockFrontend
* frontend1
= MakeMockFrontend();
2230 frontend1
->SetIgnoreProgressEvents(true);
2231 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2232 host1
->new_master_entry_url_
=
2233 MockHttpServer::GetMockUrl("files/nosuchfile");
2234 update
->StartUpdate(host1
, host1
->new_master_entry_url_
);
2236 MockFrontend
* frontend2
= MakeMockFrontend();
2237 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2238 host2
->new_master_entry_url_
=
2239 MockHttpServer::GetMockUrl("files/explicit2");
2240 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2242 // Set up checks for when update job finishes.
2243 do_checks_after_update_finished_
= true;
2244 expect_group_obsolete_
= false;
2245 expect_group_has_cache_
= true; // as long as one pending master succeeds
2246 tested_manifest_
= MANIFEST1
;
2247 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
2248 MockHttpServer::GetMockUrl("files/explicit2"),
2249 AppCacheEntry(AppCacheEntry::MASTER
)));
2250 MockFrontend::HostIds
ids1(1, host1
->host_id());
2251 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2252 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2253 frontend1
->AddExpectedEvent(ids1
, ERROR_EVENT
);
2254 MockFrontend::HostIds
ids2(1, host2
->host_id());
2255 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
2256 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2257 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
2258 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
2259 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
2260 frontend2
->AddExpectedEvent(ids2
, CACHED_EVENT
);
2262 WaitForUpdateToFinish();
2265 void UpgradeMasterEntrySomeFailTest() {
2266 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2269 group_
= new AppCacheGroup(
2270 service_
->storage(),
2271 MockHttpServer::GetMockUrl("files/manifest1"),
2273 AppCacheUpdateJob
* update
=
2274 new AppCacheUpdateJob(service_
.get(), group_
.get());
2275 group_
->update_job_
= update
;
2277 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
2278 MockFrontend
* frontend1
= MakeMockFrontend();
2279 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2280 host1
->AssociateCompleteCache(cache
);
2282 MockFrontend
* frontend2
= MakeMockFrontend();
2283 frontend2
->SetIgnoreProgressEvents(true);
2284 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2285 host2
->new_master_entry_url_
=
2286 MockHttpServer::GetMockUrl("files/nosuchfile");
2287 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2289 MockFrontend
* frontend3
= MakeMockFrontend();
2290 AppCacheHost
* host3
= MakeHost(3, frontend3
);
2291 host3
->new_master_entry_url_
=
2292 MockHttpServer::GetMockUrl("files/explicit2");
2293 update
->StartUpdate(host3
, host3
->new_master_entry_url_
);
2295 // Set up checks for when update job finishes.
2296 do_checks_after_update_finished_
= true;
2297 expect_group_obsolete_
= false;
2298 expect_group_has_cache_
= true;
2299 expect_old_cache_
= cache
;
2300 tested_manifest_
= MANIFEST1
;
2301 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
2302 MockHttpServer::GetMockUrl("files/explicit2"),
2303 AppCacheEntry(AppCacheEntry::MASTER
)));
2304 MockFrontend::HostIds
ids1(1, host1
->host_id());
2305 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2306 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2307 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2308 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2309 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2310 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
2311 MockFrontend::HostIds
ids2(1, host2
->host_id());
2312 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2313 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2314 MockFrontend::HostIds
ids3(1, host3
->host_id());
2315 frontend3
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2316 frontend3
->AddExpectedEvent(ids3
, DOWNLOADING_EVENT
);
2317 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
);
2318 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
);
2319 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
); // final
2320 frontend3
->AddExpectedEvent(ids3
, UPDATE_READY_EVENT
);
2322 WaitForUpdateToFinish();
2325 void MasterEntryNoUpdateTest() {
2326 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2329 group_
= new AppCacheGroup(service_
->storage(),
2330 MockHttpServer::GetMockUrl("files/notmodified"), 111);
2331 AppCacheUpdateJob
* update
=
2332 new AppCacheUpdateJob(service_
.get(), group_
.get());
2333 group_
->update_job_
= update
;
2335 AppCache
* cache
= MakeCacheForGroup(1, 111);
2336 MockFrontend
* frontend1
= MakeMockFrontend();
2337 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2338 host1
->AssociateCompleteCache(cache
);
2340 // Give cache an existing entry that can also be fetched.
2341 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit2"),
2342 AppCacheEntry(AppCacheEntry::EXPLICIT
, 222));
2344 // Reset the update time to null so we can verify it gets
2345 // modified in this test case by the UpdateJob.
2346 cache
->set_update_time(base::Time());
2348 MockFrontend
* frontend2
= MakeMockFrontend();
2349 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2350 host2
->new_master_entry_url_
=
2351 MockHttpServer::GetMockUrl("files/explicit1");
2352 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2354 AppCacheHost
* host3
= MakeHost(3, frontend2
); // same frontend as host2
2355 host3
->new_master_entry_url_
=
2356 MockHttpServer::GetMockUrl("files/explicit2");
2357 update
->StartUpdate(host3
, host3
->new_master_entry_url_
);
2359 // Set up checks for when update job finishes.
2360 do_checks_after_update_finished_
= true;
2361 expect_group_obsolete_
= false;
2362 expect_group_has_cache_
= true;
2363 expect_newest_cache_
= cache
; // newest cache still the same cache
2364 expect_non_null_update_time_
= true;
2365 tested_manifest_
= PENDING_MASTER_NO_UPDATE
;
2366 MockFrontend::HostIds
ids1(1, host1
->host_id());
2367 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2368 frontend1
->AddExpectedEvent(ids1
, NO_UPDATE_EVENT
);
2369 MockFrontend::HostIds
ids3(1, host3
->host_id());
2370 frontend2
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2371 MockFrontend::HostIds ids2and3
;
2372 ids2and3
.push_back(host2
->host_id());
2373 ids2and3
.push_back(host3
->host_id());
2374 frontend2
->AddExpectedEvent(ids2and3
, NO_UPDATE_EVENT
);
2376 WaitForUpdateToFinish();
2379 void StartUpdateMidCacheAttemptTest() {
2380 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2383 group_
= new AppCacheGroup(
2384 service_
->storage(), MockHttpServer::GetMockUrl("files/manifest1"),
2385 service_
->storage()->NewGroupId());
2386 AppCacheUpdateJob
* update
=
2387 new AppCacheUpdateJob(service_
.get(), group_
.get());
2388 group_
->update_job_
= update
;
2390 MockFrontend
* frontend1
= MakeMockFrontend();
2391 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2392 host1
->new_master_entry_url_
=
2393 MockHttpServer::GetMockUrl("files/explicit2");
2394 update
->StartUpdate(host1
, host1
->new_master_entry_url_
);
2395 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2397 // Set up additional updates to be started while update is in progress.
2398 MockFrontend
* frontend2
= MakeMockFrontend();
2399 frontend2
->SetIgnoreProgressEvents(true);
2400 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2401 host2
->new_master_entry_url_
=
2402 MockHttpServer::GetMockUrl("files/nosuchfile");
2404 MockFrontend
* frontend3
= MakeMockFrontend();
2405 AppCacheHost
* host3
= MakeHost(3, frontend3
);
2406 host3
->new_master_entry_url_
=
2407 MockHttpServer::GetMockUrl("files/explicit1");
2409 MockFrontend
* frontend4
= MakeMockFrontend();
2410 AppCacheHost
* host4
= MakeHost(4, frontend4
);
2411 host4
->new_master_entry_url_
=
2412 MockHttpServer::GetMockUrl("files/explicit2");
2414 MockFrontend
* frontend5
= MakeMockFrontend();
2415 AppCacheHost
* host5
= MakeHost(5, frontend5
); // no master entry url
2417 frontend1
->TriggerAdditionalUpdates(DOWNLOADING_EVENT
, update
);
2418 frontend1
->AdditionalUpdateHost(host2
); // fetch will fail
2419 frontend1
->AdditionalUpdateHost(host3
); // same as an explicit entry
2420 frontend1
->AdditionalUpdateHost(host4
); // same as another master entry
2421 frontend1
->AdditionalUpdateHost(NULL
); // no host
2422 frontend1
->AdditionalUpdateHost(host5
); // no master entry url
2424 // Set up checks for when update job finishes.
2425 do_checks_after_update_finished_
= true;
2426 expect_group_obsolete_
= false;
2427 expect_group_has_cache_
= true;
2428 tested_manifest_
= MANIFEST1
;
2429 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
2430 MockHttpServer::GetMockUrl("files/explicit2"),
2431 AppCacheEntry(AppCacheEntry::MASTER
)));
2432 MockFrontend::HostIds
ids1(1, host1
->host_id());
2433 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2434 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2435 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2436 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2437 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2438 frontend1
->AddExpectedEvent(ids1
, CACHED_EVENT
);
2439 MockFrontend::HostIds
ids2(1, host2
->host_id());
2440 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
2441 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2442 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2443 MockFrontend::HostIds
ids3(1, host3
->host_id());
2444 frontend3
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2445 frontend3
->AddExpectedEvent(ids3
, DOWNLOADING_EVENT
);
2446 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
);
2447 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
);
2448 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
); // final
2449 frontend3
->AddExpectedEvent(ids3
, CACHED_EVENT
);
2450 MockFrontend::HostIds
ids4(1, host4
->host_id());
2451 frontend4
->AddExpectedEvent(ids4
, CHECKING_EVENT
);
2452 frontend4
->AddExpectedEvent(ids4
, DOWNLOADING_EVENT
);
2453 frontend4
->AddExpectedEvent(ids4
, PROGRESS_EVENT
);
2454 frontend4
->AddExpectedEvent(ids4
, PROGRESS_EVENT
);
2455 frontend4
->AddExpectedEvent(ids4
, PROGRESS_EVENT
); // final
2456 frontend4
->AddExpectedEvent(ids4
, CACHED_EVENT
);
2458 // Host 5 is not associated with cache so no progress/cached events.
2459 MockFrontend::HostIds
ids5(1, host5
->host_id());
2460 frontend5
->AddExpectedEvent(ids5
, CHECKING_EVENT
);
2461 frontend5
->AddExpectedEvent(ids5
, DOWNLOADING_EVENT
);
2463 WaitForUpdateToFinish();
2466 void StartUpdateMidNoUpdateTest() {
2467 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2470 group_
= new AppCacheGroup(
2471 service_
->storage(), MockHttpServer::GetMockUrl("files/notmodified"),
2472 service_
->storage()->NewGroupId());
2473 AppCacheUpdateJob
* update
=
2474 new AppCacheUpdateJob(service_
.get(), group_
.get());
2475 group_
->update_job_
= update
;
2477 AppCache
* cache
= MakeCacheForGroup(1, 111);
2478 MockFrontend
* frontend1
= MakeMockFrontend();
2479 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2480 host1
->AssociateCompleteCache(cache
);
2482 // Give cache an existing entry.
2483 cache
->AddEntry(MockHttpServer::GetMockUrl("files/explicit2"),
2484 AppCacheEntry(AppCacheEntry::EXPLICIT
, 222));
2486 // Start update with a pending master entry that will fail to give us an
2487 // event to trigger other updates.
2488 MockFrontend
* frontend2
= MakeMockFrontend();
2489 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2490 host2
->new_master_entry_url_
=
2491 MockHttpServer::GetMockUrl("files/nosuchfile");
2492 update
->StartUpdate(host2
, host2
->new_master_entry_url_
);
2493 EXPECT_TRUE(update
->manifest_fetcher_
!= NULL
);
2495 // Set up additional updates to be started while update is in progress.
2496 MockFrontend
* frontend3
= MakeMockFrontend();
2497 AppCacheHost
* host3
= MakeHost(3, frontend3
);
2498 host3
->new_master_entry_url_
=
2499 MockHttpServer::GetMockUrl("files/explicit1");
2501 MockFrontend
* frontend4
= MakeMockFrontend();
2502 AppCacheHost
* host4
= MakeHost(4, frontend4
); // no master entry url
2504 MockFrontend
* frontend5
= MakeMockFrontend();
2505 AppCacheHost
* host5
= MakeHost(5, frontend5
);
2506 host5
->new_master_entry_url_
=
2507 MockHttpServer::GetMockUrl("files/explicit2"); // existing entry
2509 MockFrontend
* frontend6
= MakeMockFrontend();
2510 AppCacheHost
* host6
= MakeHost(6, frontend6
);
2511 host6
->new_master_entry_url_
=
2512 MockHttpServer::GetMockUrl("files/explicit1");
2514 frontend2
->TriggerAdditionalUpdates(ERROR_EVENT
, update
);
2515 frontend2
->AdditionalUpdateHost(host3
);
2516 frontend2
->AdditionalUpdateHost(NULL
); // no host
2517 frontend2
->AdditionalUpdateHost(host4
); // no master entry url
2518 frontend2
->AdditionalUpdateHost(host5
); // same as existing cache entry
2519 frontend2
->AdditionalUpdateHost(host6
); // same as another master entry
2521 // Set up checks for when update job finishes.
2522 do_checks_after_update_finished_
= true;
2523 expect_group_obsolete_
= false;
2524 expect_group_has_cache_
= true;
2525 expect_newest_cache_
= cache
; // newest cache unaffected by update
2526 tested_manifest_
= PENDING_MASTER_NO_UPDATE
;
2527 MockFrontend::HostIds
ids1(1, host1
->host_id()); // prior associated host
2528 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2529 frontend1
->AddExpectedEvent(ids1
, NO_UPDATE_EVENT
);
2530 MockFrontend::HostIds
ids2(1, host2
->host_id());
2531 frontend2
->AddExpectedEvent(ids2
, ERROR_EVENT
);
2532 MockFrontend::HostIds
ids3(1, host3
->host_id());
2533 frontend3
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2534 frontend3
->AddExpectedEvent(ids3
, NO_UPDATE_EVENT
);
2535 MockFrontend::HostIds
ids4(1, host4
->host_id()); // unassociated w/cache
2536 frontend4
->AddExpectedEvent(ids4
, CHECKING_EVENT
);
2537 MockFrontend::HostIds
ids5(1, host5
->host_id());
2538 frontend5
->AddExpectedEvent(ids5
, CHECKING_EVENT
);
2539 frontend5
->AddExpectedEvent(ids5
, NO_UPDATE_EVENT
);
2540 MockFrontend::HostIds
ids6(1, host6
->host_id());
2541 frontend6
->AddExpectedEvent(ids6
, CHECKING_EVENT
);
2542 frontend6
->AddExpectedEvent(ids6
, NO_UPDATE_EVENT
);
2544 WaitForUpdateToFinish();
2547 void StartUpdateMidDownloadTest() {
2548 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2551 group_
= new AppCacheGroup(
2552 service_
->storage(),
2553 MockHttpServer::GetMockUrl("files/manifest1"),
2555 AppCacheUpdateJob
* update
=
2556 new AppCacheUpdateJob(service_
.get(), group_
.get());
2557 group_
->update_job_
= update
;
2559 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(), 42);
2560 MockFrontend
* frontend1
= MakeMockFrontend();
2561 AppCacheHost
* host1
= MakeHost(1, frontend1
);
2562 host1
->AssociateCompleteCache(cache
);
2564 update
->StartUpdate(NULL
, GURL());
2566 // Set up additional updates to be started while update is in progress.
2567 MockFrontend
* frontend2
= MakeMockFrontend();
2568 AppCacheHost
* host2
= MakeHost(2, frontend2
);
2569 host2
->new_master_entry_url_
=
2570 MockHttpServer::GetMockUrl("files/explicit1");
2572 MockFrontend
* frontend3
= MakeMockFrontend();
2573 AppCacheHost
* host3
= MakeHost(3, frontend3
);
2574 host3
->new_master_entry_url_
=
2575 MockHttpServer::GetMockUrl("files/explicit2");
2577 MockFrontend
* frontend4
= MakeMockFrontend();
2578 AppCacheHost
* host4
= MakeHost(4, frontend4
); // no master entry url
2580 MockFrontend
* frontend5
= MakeMockFrontend();
2581 AppCacheHost
* host5
= MakeHost(5, frontend5
);
2582 host5
->new_master_entry_url_
=
2583 MockHttpServer::GetMockUrl("files/explicit2");
2585 frontend1
->TriggerAdditionalUpdates(PROGRESS_EVENT
, update
);
2586 frontend1
->AdditionalUpdateHost(host2
); // same as entry in manifest
2587 frontend1
->AdditionalUpdateHost(NULL
); // no host
2588 frontend1
->AdditionalUpdateHost(host3
); // new master entry
2589 frontend1
->AdditionalUpdateHost(host4
); // no master entry url
2590 frontend1
->AdditionalUpdateHost(host5
); // same as another master entry
2592 // Set up checks for when update job finishes.
2593 do_checks_after_update_finished_
= true;
2594 expect_group_obsolete_
= false;
2595 expect_group_has_cache_
= true;
2596 tested_manifest_
= MANIFEST1
;
2597 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
2598 MockHttpServer::GetMockUrl("files/explicit2"),
2599 AppCacheEntry(AppCacheEntry::MASTER
)));
2600 MockFrontend::HostIds
ids1(1, host1
->host_id()); // prior associated host
2601 frontend1
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2602 frontend1
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2603 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2604 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2605 frontend1
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2606 frontend1
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
2607 MockFrontend::HostIds
ids2(1, host2
->host_id());
2608 frontend2
->AddExpectedEvent(ids2
, CHECKING_EVENT
);
2609 frontend2
->AddExpectedEvent(ids2
, DOWNLOADING_EVENT
);
2610 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
);
2611 frontend2
->AddExpectedEvent(ids2
, PROGRESS_EVENT
); // final
2612 frontend2
->AddExpectedEvent(ids2
, UPDATE_READY_EVENT
);
2613 MockFrontend::HostIds
ids3(1, host3
->host_id());
2614 frontend3
->AddExpectedEvent(ids3
, CHECKING_EVENT
);
2615 frontend3
->AddExpectedEvent(ids3
, DOWNLOADING_EVENT
);
2616 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
);
2617 frontend3
->AddExpectedEvent(ids3
, PROGRESS_EVENT
); // final
2618 frontend3
->AddExpectedEvent(ids3
, UPDATE_READY_EVENT
);
2619 MockFrontend::HostIds
ids4(1, host4
->host_id()); // unassociated w/cache
2620 frontend4
->AddExpectedEvent(ids4
, CHECKING_EVENT
);
2621 frontend4
->AddExpectedEvent(ids4
, DOWNLOADING_EVENT
);
2622 MockFrontend::HostIds
ids5(1, host5
->host_id());
2623 frontend5
->AddExpectedEvent(ids5
, CHECKING_EVENT
);
2624 frontend5
->AddExpectedEvent(ids5
, DOWNLOADING_EVENT
);
2625 frontend5
->AddExpectedEvent(ids5
, PROGRESS_EVENT
);
2626 frontend5
->AddExpectedEvent(ids5
, PROGRESS_EVENT
); // final
2627 frontend5
->AddExpectedEvent(ids5
, UPDATE_READY_EVENT
);
2629 WaitForUpdateToFinish();
2632 void QueueMasterEntryTest() {
2633 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2636 group_
= new AppCacheGroup(
2637 service_
->storage(),
2638 MockHttpServer::GetMockUrl("files/manifest1"),
2640 AppCacheUpdateJob
* update
=
2641 new AppCacheUpdateJob(service_
.get(), group_
.get());
2642 group_
->update_job_
= update
;
2644 // Pretend update job has been running and is about to terminate.
2645 group_
->update_status_
= AppCacheGroup::DOWNLOADING
;
2646 update
->internal_state_
= AppCacheUpdateJob::REFETCH_MANIFEST
;
2647 EXPECT_TRUE(update
->IsTerminating());
2649 // Start an update. Should be queued.
2650 MockFrontend
* frontend
= MakeMockFrontend();
2651 AppCacheHost
* host
= MakeHost(1, frontend
);
2652 host
->new_master_entry_url_
=
2653 MockHttpServer::GetMockUrl("files/explicit2");
2654 update
->StartUpdate(host
, host
->new_master_entry_url_
);
2655 EXPECT_TRUE(update
->pending_master_entries_
.empty());
2656 EXPECT_FALSE(group_
->queued_updates_
.empty());
2658 // Delete update, causing it to finish, which should trigger a new update
2659 // for the queued host and master entry after a delay.
2661 EXPECT_FALSE(group_
->restart_update_task_
.IsCancelled());
2663 // Set up checks for when queued update job finishes.
2664 do_checks_after_update_finished_
= true;
2665 expect_group_obsolete_
= false;
2666 expect_group_has_cache_
= true;
2667 tested_manifest_
= MANIFEST1
;
2668 expect_extra_entries_
.insert(AppCache::EntryMap::value_type(
2669 host
->new_master_entry_url_
, AppCacheEntry(AppCacheEntry::MASTER
)));
2670 MockFrontend::HostIds
ids1(1, host
->host_id());
2671 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2672 frontend
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2673 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2674 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2675 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2676 frontend
->AddExpectedEvent(ids1
, CACHED_EVENT
);
2678 // Group status will be IDLE so cannot call WaitForUpdateToFinish.
2679 group_
->AddUpdateObserver(this);
2682 void IfModifiedSinceTest() {
2683 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2685 net::URLRequestJobFactoryImpl
* new_factory(
2686 new net::URLRequestJobFactoryImpl
);
2687 new_factory
->SetProtocolHandler("http", new IfModifiedSinceJobFactory
);
2688 io_thread_
->SetNewJobFactory(new_factory
);
2691 group_
= new AppCacheGroup(
2692 service_
->storage(), GURL("http://headertest"), 111);
2693 AppCacheUpdateJob
* update
=
2694 new AppCacheUpdateJob(service_
.get(), group_
.get());
2695 group_
->update_job_
= update
;
2697 // First test against a cache attempt. Will start manifest fetch
2699 HttpHeadersRequestTestJob::Initialize(std::string(), std::string());
2700 MockFrontend mock_frontend
;
2701 AppCacheHost
host(1, &mock_frontend
, service_
.get());
2702 update
->StartUpdate(&host
, GURL());
2703 HttpHeadersRequestTestJob::Verify();
2706 // Now simulate a refetch manifest request. Will start fetch request
2711 net::HttpResponseHeaders
* headers
=
2712 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
2713 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
2714 response_info
->headers
= headers
; // adds ref to headers
2716 HttpHeadersRequestTestJob::Initialize(std::string(), std::string());
2717 update
= new AppCacheUpdateJob(service_
.get(), group_
.get());
2718 group_
->update_job_
= update
;
2719 group_
->update_status_
= AppCacheGroup::DOWNLOADING
;
2720 update
->manifest_response_info_
.reset(response_info
);
2721 update
->internal_state_
= AppCacheUpdateJob::REFETCH_MANIFEST
;
2722 update
->FetchManifest(false); // not first request
2723 HttpHeadersRequestTestJob::Verify();
2726 // Change the headers to include a Last-Modified header. Manifest refetch
2727 // should include If-Modified-Since header.
2728 const char data2
[] =
2730 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0"
2732 net::HttpResponseHeaders
* headers2
=
2733 new net::HttpResponseHeaders(std::string(data2
, arraysize(data2
)));
2734 response_info
= new net::HttpResponseInfo();
2735 response_info
->headers
= headers2
;
2737 HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT",
2739 update
= new AppCacheUpdateJob(service_
.get(), group_
.get());
2740 group_
->update_job_
= update
;
2741 group_
->update_status_
= AppCacheGroup::DOWNLOADING
;
2742 update
->manifest_response_info_
.reset(response_info
);
2743 update
->internal_state_
= AppCacheUpdateJob::REFETCH_MANIFEST
;
2744 update
->FetchManifest(false); // not first request
2745 HttpHeadersRequestTestJob::Verify();
2751 void IfModifiedSinceUpgradeTest() {
2752 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2754 HttpHeadersRequestTestJob::Initialize("Sat, 29 Oct 1994 19:43:31 GMT",
2756 net::URLRequestJobFactoryImpl
* new_factory(
2757 new net::URLRequestJobFactoryImpl
);
2758 new_factory
->SetProtocolHandler("http", new IfModifiedSinceJobFactory
);
2759 io_thread_
->SetNewJobFactory(new_factory
);
2762 group_
=new AppCacheGroup(
2763 service_
->storage(),
2764 MockHttpServer::GetMockUrl("files/manifest1"),
2766 AppCacheUpdateJob
* update
=
2767 new AppCacheUpdateJob(service_
.get(), group_
.get());
2768 group_
->update_job_
= update
;
2770 // Give the newest cache a manifest enry that is in storage.
2771 response_writer_
.reset(
2772 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
2773 group_
->group_id()));
2775 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(),
2776 response_writer_
->response_id());
2777 MockFrontend
* frontend
= MakeMockFrontend();
2778 AppCacheHost
* host
= MakeHost(1, frontend
);
2779 host
->AssociateCompleteCache(cache
);
2781 // Set up checks for when update job finishes.
2782 do_checks_after_update_finished_
= true;
2783 expect_group_obsolete_
= false;
2784 expect_group_has_cache_
= true;
2785 expect_old_cache_
= cache
;
2786 tested_manifest_
= MANIFEST1
;
2787 MockFrontend::HostIds
ids1(1, host
->host_id());
2788 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2789 frontend
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2790 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2791 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2792 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2793 frontend
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
2795 // Seed storage with expected manifest response info that will cause
2796 // an If-Modified-Since header to be put in the manifest fetch request.
2799 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0"
2801 net::HttpResponseHeaders
* headers
=
2802 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
2803 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
2804 response_info
->headers
= headers
; // adds ref to headers
2805 scoped_refptr
<HttpResponseInfoIOBuffer
> io_buffer(
2806 new HttpResponseInfoIOBuffer(response_info
)); // adds ref to info
2807 response_writer_
->WriteInfo(
2809 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
2810 base::Unretained(this)));
2812 // Start update after data write completes asynchronously.
2815 void IfNoneMatchUpgradeTest() {
2816 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2818 HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\"");
2819 net::URLRequestJobFactoryImpl
* new_factory(
2820 new net::URLRequestJobFactoryImpl
);
2821 new_factory
->SetProtocolHandler("http", new IfModifiedSinceJobFactory
);
2822 io_thread_
->SetNewJobFactory(new_factory
);
2825 group_
= new AppCacheGroup(
2826 service_
->storage(),
2827 MockHttpServer::GetMockUrl("files/manifest1"),
2829 AppCacheUpdateJob
* update
=
2830 new AppCacheUpdateJob(service_
.get(), group_
.get());
2831 group_
->update_job_
= update
;
2833 // Give the newest cache a manifest enry that is in storage.
2834 response_writer_
.reset(
2835 service_
->storage()->CreateResponseWriter(group_
->manifest_url(),
2836 group_
->group_id()));
2838 AppCache
* cache
= MakeCacheForGroup(service_
->storage()->NewCacheId(),
2839 response_writer_
->response_id());
2840 MockFrontend
* frontend
= MakeMockFrontend();
2841 AppCacheHost
* host
= MakeHost(1, frontend
);
2842 host
->AssociateCompleteCache(cache
);
2844 // Set up checks for when update job finishes.
2845 do_checks_after_update_finished_
= true;
2846 expect_group_obsolete_
= false;
2847 expect_group_has_cache_
= true;
2848 expect_old_cache_
= cache
;
2849 tested_manifest_
= MANIFEST1
;
2850 MockFrontend::HostIds
ids1(1, host
->host_id());
2851 frontend
->AddExpectedEvent(ids1
, CHECKING_EVENT
);
2852 frontend
->AddExpectedEvent(ids1
, DOWNLOADING_EVENT
);
2853 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2854 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
);
2855 frontend
->AddExpectedEvent(ids1
, PROGRESS_EVENT
); // final
2856 frontend
->AddExpectedEvent(ids1
, UPDATE_READY_EVENT
);
2858 // Seed storage with expected manifest response info that will cause
2859 // an If-None-Match header to be put in the manifest fetch request.
2862 "ETag: \"LadeDade\"\0"
2864 net::HttpResponseHeaders
* headers
=
2865 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
2866 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
2867 response_info
->headers
= headers
; // adds ref to headers
2868 scoped_refptr
<HttpResponseInfoIOBuffer
> io_buffer(
2869 new HttpResponseInfoIOBuffer(response_info
)); // adds ref to info
2870 response_writer_
->WriteInfo(
2872 base::Bind(&AppCacheUpdateJobTest::StartUpdateAfterSeedingStorageData
,
2873 base::Unretained(this)));
2875 // Start update after data write completes asynchronously.
2878 void IfNoneMatchRefetchTest() {
2879 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2881 HttpHeadersRequestTestJob::Initialize(std::string(), "\"LadeDade\"");
2882 net::URLRequestJobFactoryImpl
* new_factory(
2883 new net::URLRequestJobFactoryImpl
);
2884 new_factory
->SetProtocolHandler("http", new IfModifiedSinceJobFactory
);
2885 io_thread_
->SetNewJobFactory(new_factory
);
2888 group_
= new AppCacheGroup(
2889 service_
->storage(), GURL("http://headertest"), 111);
2890 AppCacheUpdateJob
* update
=
2891 new AppCacheUpdateJob(service_
.get(), group_
.get());
2892 group_
->update_job_
= update
;
2894 // Simulate a refetch manifest request that uses an ETag header.
2897 "ETag: \"LadeDade\"\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();
2914 void MultipleHeadersRefetchTest() {
2915 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2917 // Verify that code is correct when building multiple extra headers.
2918 HttpHeadersRequestTestJob::Initialize(
2919 "Sat, 29 Oct 1994 19:43:31 GMT", "\"LadeDade\"");
2920 net::URLRequestJobFactoryImpl
* new_factory(
2921 new net::URLRequestJobFactoryImpl
);
2922 new_factory
->SetProtocolHandler("http", new IfModifiedSinceJobFactory
);
2923 io_thread_
->SetNewJobFactory(new_factory
);
2926 group_
= new AppCacheGroup(
2927 service_
->storage(), GURL("http://headertest"), 111);
2928 AppCacheUpdateJob
* update
=
2929 new AppCacheUpdateJob(service_
.get(), group_
.get());
2930 group_
->update_job_
= update
;
2932 // Simulate a refetch manifest request that uses an ETag header.
2935 "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\0"
2936 "ETag: \"LadeDade\"\0"
2938 net::HttpResponseHeaders
* headers
=
2939 new net::HttpResponseHeaders(std::string(data
, arraysize(data
)));
2940 net::HttpResponseInfo
* response_info
= new net::HttpResponseInfo();
2941 response_info
->headers
= headers
; // adds ref to headers
2943 group_
->update_status_
= AppCacheGroup::DOWNLOADING
;
2944 update
->manifest_response_info_
.reset(response_info
);
2945 update
->internal_state_
= AppCacheUpdateJob::REFETCH_MANIFEST
;
2946 update
->FetchManifest(false); // not first request
2947 HttpHeadersRequestTestJob::Verify();
2953 void CrossOriginHttpsSuccessTest() {
2954 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2956 GURL manifest_url
= MockHttpServer::GetMockHttpsUrl(
2957 "files/valid_cross_origin_https_manifest");
2960 group_
= new AppCacheGroup(
2961 service_
->storage(), manifest_url
, service_
->storage()->NewGroupId());
2962 AppCacheUpdateJob
* update
=
2963 new AppCacheUpdateJob(service_
.get(), group_
.get());
2964 group_
->update_job_
= update
;
2966 MockFrontend
* frontend
= MakeMockFrontend();
2967 AppCacheHost
* host
= MakeHost(1, frontend
);
2968 update
->StartUpdate(host
, GURL());
2970 // Set up checks for when update job finishes.
2971 do_checks_after_update_finished_
= true;
2972 expect_group_obsolete_
= false;
2973 expect_group_has_cache_
= true;
2974 tested_manifest_
= NONE
;
2975 MockFrontend::HostIds
host_ids(1, host
->host_id());
2976 frontend
->AddExpectedEvent(host_ids
, CHECKING_EVENT
);
2978 WaitForUpdateToFinish();
2981 void CrossOriginHttpsDeniedTest() {
2982 ASSERT_EQ(base::MessageLoop::TYPE_IO
, base::MessageLoop::current()->type());
2984 GURL manifest_url
= MockHttpServer::GetMockHttpsUrl(
2985 "files/invalid_cross_origin_https_manifest");
2988 group_
= new AppCacheGroup(
2989 service_
->storage(), manifest_url
, service_
->storage()->NewGroupId());
2990 AppCacheUpdateJob
* update
=
2991 new AppCacheUpdateJob(service_
.get(), group_
.get());
2992 group_
->update_job_
= update
;
2994 MockFrontend
* frontend
= MakeMockFrontend();
2995 AppCacheHost
* host
= MakeHost(1, frontend
);
2996 update
->StartUpdate(host
, GURL());
2998 // Set up checks for when update job finishes.
2999 do_checks_after_update_finished_
= true;
3000 expect_group_obsolete_
= false;
3001 expect_group_has_cache_
= false;
3002 tested_manifest_
= NONE
;
3003 MockFrontend::HostIds
host_ids(1, host
->host_id());
3004 frontend
->AddExpectedEvent(host_ids
, CHECKING_EVENT
);
3006 WaitForUpdateToFinish();
3009 void WaitForUpdateToFinish() {
3010 if (group_
->update_status() == AppCacheGroup::IDLE
)
3013 group_
->AddUpdateObserver(this);
3016 virtual void OnUpdateComplete(AppCacheGroup
* group
) OVERRIDE
{
3017 ASSERT_EQ(group_
, group
);
3018 protect_newest_cache_
= group
->newest_complete_cache();
3022 void UpdateFinished() {
3023 // We unwind the stack prior to finishing up to let stack-based objects
3025 base::MessageLoop::current()->PostTask(
3027 base::Bind(&AppCacheUpdateJobTest::UpdateFinishedUnwound
,
3028 base::Unretained(this)));
3031 void UpdateFinishedUnwound() {
3032 EXPECT_EQ(AppCacheGroup::IDLE
, group_
->update_status());
3033 EXPECT_TRUE(group_
->update_job() == NULL
);
3034 if (do_checks_after_update_finished_
)
3035 VerifyExpectations();
3037 // Clean up everything that was created on the IO thread.
3038 protect_newest_cache_
= NULL
;
3040 STLDeleteContainerPointers(hosts_
.begin(), hosts_
.end());
3041 STLDeleteContainerPointers(frontends_
.begin(), frontends_
.end());
3042 response_infos_
.clear();
3043 service_
.reset(NULL
);
3048 void MakeService() {
3049 service_
.reset(new MockAppCacheService());
3050 service_
->set_request_context(io_thread_
->request_context());
3053 AppCache
* MakeCacheForGroup(int64 cache_id
, int64 manifest_response_id
) {
3054 return MakeCacheForGroup(cache_id
, group_
->manifest_url(),
3055 manifest_response_id
);
3058 AppCache
* MakeCacheForGroup(int64 cache_id
, const GURL
& manifest_entry_url
,
3059 int64 manifest_response_id
) {
3060 AppCache
* cache
= new AppCache(service_
->storage(), cache_id
);
3061 cache
->set_complete(true);
3062 cache
->set_update_time(base::Time::Now());
3063 group_
->AddCache(cache
);
3065 // Add manifest entry to cache.
3066 cache
->AddEntry(manifest_entry_url
,
3067 AppCacheEntry(AppCacheEntry::MANIFEST
, manifest_response_id
));
3072 AppCacheHost
* MakeHost(int host_id
, AppCacheFrontend
* frontend
) {
3073 AppCacheHost
* host
= new AppCacheHost(host_id
, frontend
, service_
.get());
3074 hosts_
.push_back(host
);
3078 AppCacheResponseInfo
* MakeAppCacheResponseInfo(
3079 const GURL
& manifest_url
, int64 response_id
,
3080 const std::string
& raw_headers
) {
3081 net::HttpResponseInfo
* http_info
= new net::HttpResponseInfo();
3082 http_info
->headers
= new net::HttpResponseHeaders(raw_headers
);
3083 scoped_refptr
<AppCacheResponseInfo
> info(
3084 new AppCacheResponseInfo(service_
.get(), manifest_url
,
3085 response_id
, http_info
, 0));
3086 response_infos_
.push_back(info
);
3090 MockFrontend
* MakeMockFrontend() {
3091 MockFrontend
* frontend
= new MockFrontend();
3092 frontends_
.push_back(frontend
);
3096 // Verifies conditions about the group and notifications after an update
3097 // has finished. Cannot verify update job internals as update is deleted.
3098 void VerifyExpectations() {
3099 RetryRequestTestJob::Verify();
3100 HttpHeadersRequestTestJob::Verify();
3102 EXPECT_EQ(expect_group_obsolete_
, group_
->is_obsolete());
3103 EXPECT_EQ(expect_group_is_being_deleted_
, group_
->is_being_deleted());
3105 if (expect_group_has_cache_
) {
3106 EXPECT_TRUE(group_
->newest_complete_cache() != NULL
);
3108 if (expect_non_null_update_time_
)
3109 EXPECT_TRUE(!group_
->newest_complete_cache()->update_time().is_null());
3111 if (expect_old_cache_
) {
3112 EXPECT_NE(expect_old_cache_
, group_
->newest_complete_cache());
3113 EXPECT_TRUE(group_
->old_caches().end() !=
3114 std::find(group_
->old_caches().begin(),
3115 group_
->old_caches().end(), expect_old_cache_
));
3117 if (expect_newest_cache_
) {
3118 EXPECT_EQ(expect_newest_cache_
, group_
->newest_complete_cache());
3119 EXPECT_TRUE(group_
->old_caches().end() ==
3120 std::find(group_
->old_caches().begin(),
3121 group_
->old_caches().end(), expect_newest_cache_
));
3123 // Tests that don't know which newest cache to expect contain updates
3124 // that succeed (because the update creates a new cache whose pointer
3125 // is unknown to the test). Check group and newest cache were stored
3126 // when update succeeds.
3127 MockAppCacheStorage
* storage
=
3128 reinterpret_cast<MockAppCacheStorage
*>(service_
->storage());
3129 EXPECT_TRUE(storage
->IsGroupStored(group_
.get()));
3130 EXPECT_TRUE(storage
->IsCacheStored(group_
->newest_complete_cache()));
3132 // Check that all entries in the newest cache were stored.
3133 const AppCache::EntryMap
& entries
=
3134 group_
->newest_complete_cache()->entries();
3135 for (AppCache::EntryMap::const_iterator it
= entries
.begin();
3136 it
!= entries
.end(); ++it
) {
3137 EXPECT_NE(kNoResponseId
, it
->second
.response_id());
3139 // Check that any copied entries have the expected response id
3140 // and that entries that are not copied have a different response id.
3141 std::map
<GURL
, int64
>::iterator found
=
3142 expect_response_ids_
.find(it
->first
);
3143 if (found
!= expect_response_ids_
.end()) {
3144 EXPECT_EQ(found
->second
, it
->second
.response_id());
3145 } else if (expect_old_cache_
) {
3146 AppCacheEntry
* old_entry
= expect_old_cache_
->GetEntry(it
->first
);
3148 EXPECT_NE(old_entry
->response_id(), it
->second
.response_id());
3153 EXPECT_TRUE(group_
->newest_complete_cache() == NULL
);
3156 // Check expected events.
3157 for (size_t i
= 0; i
< frontends_
.size(); ++i
) {
3158 MockFrontend
* frontend
= frontends_
[i
];
3160 MockFrontend::RaisedEvents
& expected_events
= frontend
->expected_events_
;
3161 MockFrontend::RaisedEvents
& actual_events
= frontend
->raised_events_
;
3162 EXPECT_EQ(expected_events
.size(), actual_events
.size());
3164 // Check each expected event.
3166 j
< expected_events
.size() && j
< actual_events
.size(); ++j
) {
3167 EXPECT_EQ(expected_events
[j
].second
, actual_events
[j
].second
);
3169 MockFrontend::HostIds
& expected_ids
= expected_events
[j
].first
;
3170 MockFrontend::HostIds
& actual_ids
= actual_events
[j
].first
;
3171 EXPECT_EQ(expected_ids
.size(), actual_ids
.size());
3173 for (size_t k
= 0; k
< expected_ids
.size(); ++k
) {
3174 int id
= expected_ids
[k
];
3175 EXPECT_TRUE(std::find(actual_ids
.begin(), actual_ids
.end(), id
) !=
3180 if (!frontend
->expected_error_message_
.empty()) {
3181 EXPECT_EQ(frontend
->expected_error_message_
,
3182 frontend
->error_message_
);
3186 // Verify expected cache contents last as some checks are asserts
3187 // and will abort the test if they fail.
3188 if (tested_manifest_
) {
3189 AppCache
* cache
= group_
->newest_complete_cache();
3190 ASSERT_TRUE(cache
!= NULL
);
3191 EXPECT_EQ(group_
, cache
->owning_group());
3192 EXPECT_TRUE(cache
->is_complete());
3194 switch (tested_manifest_
) {
3196 VerifyManifest1(cache
);
3198 case MANIFEST_MERGED_TYPES
:
3199 VerifyManifestMergedTypes(cache
);
3201 case EMPTY_MANIFEST
:
3202 VerifyEmptyManifest(cache
);
3204 case EMPTY_FILE_MANIFEST
:
3205 VerifyEmptyFileManifest(cache
);
3207 case PENDING_MASTER_NO_UPDATE
:
3208 VerifyMasterEntryNoUpdate(cache
);
3210 case MANIFEST_WITH_INTERCEPT
:
3211 VerifyManifestWithIntercept(cache
);
3220 void VerifyManifest1(AppCache
* cache
) {
3221 size_t expected
= 3 + expect_extra_entries_
.size();
3222 EXPECT_EQ(expected
, cache
->entries().size());
3223 const char* kManifestPath
= tested_manifest_path_override_
?
3224 tested_manifest_path_override_
:
3226 AppCacheEntry
* entry
=
3227 cache
->GetEntry(MockHttpServer::GetMockUrl(kManifestPath
));
3229 EXPECT_EQ(AppCacheEntry::MANIFEST
, entry
->types());
3230 entry
= cache
->GetEntry(MockHttpServer::GetMockUrl("files/explicit1"));
3232 EXPECT_TRUE(entry
->IsExplicit());
3233 entry
= cache
->GetEntry(
3234 MockHttpServer::GetMockUrl("files/fallback1a"));
3236 EXPECT_EQ(AppCacheEntry::FALLBACK
, entry
->types());
3238 for (AppCache::EntryMap::iterator i
= expect_extra_entries_
.begin();
3239 i
!= expect_extra_entries_
.end(); ++i
) {
3240 entry
= cache
->GetEntry(i
->first
);
3242 EXPECT_EQ(i
->second
.types(), entry
->types());
3246 ASSERT_EQ(expected
, cache
->fallback_namespaces_
.size());
3247 EXPECT_TRUE(cache
->fallback_namespaces_
[0] ==
3250 MockHttpServer::GetMockUrl("files/fallback1"),
3251 MockHttpServer::GetMockUrl("files/fallback1a"),
3254 EXPECT_TRUE(cache
->online_whitelist_namespaces_
.empty());
3255 EXPECT_TRUE(cache
->online_whitelist_all_
);
3257 EXPECT_TRUE(cache
->update_time_
> base::Time());
3260 void VerifyManifestMergedTypes(AppCache
* cache
) {
3261 size_t expected
= 2;
3262 EXPECT_EQ(expected
, cache
->entries().size());
3263 AppCacheEntry
* entry
= cache
->GetEntry(
3264 MockHttpServer::GetMockUrl("files/manifest-merged-types"));
3266 EXPECT_EQ(AppCacheEntry::EXPLICIT
| AppCacheEntry::MANIFEST
,
3268 entry
= cache
->GetEntry(MockHttpServer::GetMockUrl("files/explicit1"));
3270 EXPECT_EQ(AppCacheEntry::EXPLICIT
| AppCacheEntry::FALLBACK
|
3271 AppCacheEntry::MASTER
, entry
->types());
3274 ASSERT_EQ(expected
, cache
->fallback_namespaces_
.size());
3275 EXPECT_TRUE(cache
->fallback_namespaces_
[0] ==
3278 MockHttpServer::GetMockUrl("files/fallback1"),
3279 MockHttpServer::GetMockUrl("files/explicit1"),
3282 EXPECT_EQ(expected
, cache
->online_whitelist_namespaces_
.size());
3283 EXPECT_TRUE(cache
->online_whitelist_namespaces_
[0] ==
3286 MockHttpServer::GetMockUrl("files/online1"),
3288 EXPECT_FALSE(cache
->online_whitelist_all_
);
3290 EXPECT_TRUE(cache
->update_time_
> base::Time());
3293 void VerifyEmptyManifest(AppCache
* cache
) {
3294 const char* kManifestPath
= tested_manifest_path_override_
?
3295 tested_manifest_path_override_
:
3296 "files/empty-manifest";
3297 size_t expected
= 1;
3298 EXPECT_EQ(expected
, cache
->entries().size());
3299 AppCacheEntry
* entry
= cache
->GetEntry(
3300 MockHttpServer::GetMockUrl(kManifestPath
));
3302 EXPECT_EQ(AppCacheEntry::MANIFEST
, entry
->types());
3304 EXPECT_TRUE(cache
->fallback_namespaces_
.empty());
3305 EXPECT_TRUE(cache
->online_whitelist_namespaces_
.empty());
3306 EXPECT_FALSE(cache
->online_whitelist_all_
);
3308 EXPECT_TRUE(cache
->update_time_
> base::Time());
3311 void VerifyEmptyFileManifest(AppCache
* cache
) {
3312 EXPECT_EQ(size_t(2), cache
->entries().size());
3313 AppCacheEntry
* entry
= cache
->GetEntry(
3314 MockHttpServer::GetMockUrl("files/empty-file-manifest"));
3316 EXPECT_EQ(AppCacheEntry::MANIFEST
, entry
->types());
3318 entry
= cache
->GetEntry(
3319 MockHttpServer::GetMockUrl("files/empty1"));
3321 EXPECT_EQ(AppCacheEntry::EXPLICIT
, entry
->types());
3322 EXPECT_TRUE(entry
->has_response_id());
3324 EXPECT_TRUE(cache
->fallback_namespaces_
.empty());
3325 EXPECT_TRUE(cache
->online_whitelist_namespaces_
.empty());
3326 EXPECT_FALSE(cache
->online_whitelist_all_
);
3328 EXPECT_TRUE(cache
->update_time_
> base::Time());
3331 void VerifyMasterEntryNoUpdate(AppCache
* cache
) {
3332 EXPECT_EQ(size_t(3), cache
->entries().size());
3333 AppCacheEntry
* entry
= cache
->GetEntry(
3334 MockHttpServer::GetMockUrl("files/notmodified"));
3336 EXPECT_EQ(AppCacheEntry::MANIFEST
, entry
->types());
3338 entry
= cache
->GetEntry(
3339 MockHttpServer::GetMockUrl("files/explicit1"));
3341 EXPECT_EQ(AppCacheEntry::MASTER
, entry
->types());
3342 EXPECT_TRUE(entry
->has_response_id());
3344 entry
= cache
->GetEntry(
3345 MockHttpServer::GetMockUrl("files/explicit2"));
3347 EXPECT_EQ(AppCacheEntry::EXPLICIT
| AppCacheEntry::MASTER
, entry
->types());
3348 EXPECT_TRUE(entry
->has_response_id());
3350 EXPECT_TRUE(cache
->fallback_namespaces_
.empty());
3351 EXPECT_TRUE(cache
->online_whitelist_namespaces_
.empty());
3352 EXPECT_FALSE(cache
->online_whitelist_all_
);
3354 EXPECT_TRUE(cache
->update_time_
> base::Time());
3357 void VerifyManifestWithIntercept(AppCache
* cache
) {
3358 EXPECT_EQ(2u, cache
->entries().size());
3359 const char* kManifestPath
= "files/manifest-with-intercept";
3360 AppCacheEntry
* entry
=
3361 cache
->GetEntry(MockHttpServer::GetMockUrl(kManifestPath
));
3363 EXPECT_EQ(AppCacheEntry::MANIFEST
, entry
->types());
3364 entry
= cache
->GetEntry(MockHttpServer::GetMockUrl("files/intercept1a"));
3366 EXPECT_TRUE(entry
->IsIntercept());
3367 EXPECT_TRUE(cache
->online_whitelist_namespaces_
.empty());
3368 EXPECT_FALSE(cache
->online_whitelist_all_
);
3369 EXPECT_TRUE(cache
->update_time_
> base::Time());
3373 // Various manifest files used in this test.
3374 enum TestedManifest
{
3377 MANIFEST_MERGED_TYPES
,
3379 EMPTY_FILE_MANIFEST
,
3380 PENDING_MASTER_NO_UPDATE
,
3381 MANIFEST_WITH_INTERCEPT
3384 scoped_ptr
<IOThread
> io_thread_
;
3386 scoped_ptr
<MockAppCacheService
> service_
;
3387 scoped_refptr
<AppCacheGroup
> group_
;
3388 scoped_refptr
<AppCache
> protect_newest_cache_
;
3389 scoped_ptr
<base::WaitableEvent
> event_
;
3391 scoped_ptr
<AppCacheResponseWriter
> response_writer_
;
3393 // Hosts used by an async test that need to live until update job finishes.
3394 // Otherwise, test can put host on the stack instead of here.
3395 std::vector
<AppCacheHost
*> hosts_
;
3397 // Response infos used by an async test that need to live until update job
3399 std::vector
<scoped_refptr
<AppCacheResponseInfo
> > response_infos_
;
3401 // Flag indicating if test cares to verify the update after update finishes.
3402 bool do_checks_after_update_finished_
;
3403 bool expect_group_obsolete_
;
3404 bool expect_group_has_cache_
;
3405 bool expect_group_is_being_deleted_
;
3406 AppCache
* expect_old_cache_
;
3407 AppCache
* expect_newest_cache_
;
3408 bool expect_non_null_update_time_
;
3409 std::vector
<MockFrontend
*> frontends_
; // to check expected events
3410 TestedManifest tested_manifest_
;
3411 const char* tested_manifest_path_override_
;
3412 AppCache::EntryMap expect_extra_entries_
;
3413 std::map
<GURL
, int64
> expect_response_ids_
;
3416 TEST_F(AppCacheUpdateJobTest
, AlreadyChecking
) {
3417 MockAppCacheService service
;
3418 scoped_refptr
<AppCacheGroup
> group(
3419 new AppCacheGroup(service
.storage(), GURL("http://manifesturl.com"),
3420 service
.storage()->NewGroupId()));
3422 AppCacheUpdateJob
update(&service
, group
.get());
3424 // Pretend group is in checking state.
3425 group
->update_job_
= &update
;
3426 group
->update_status_
= AppCacheGroup::CHECKING
;
3428 update
.StartUpdate(NULL
, GURL());
3429 EXPECT_EQ(AppCacheGroup::CHECKING
, group
->update_status());
3431 MockFrontend mock_frontend
;
3432 AppCacheHost
host(1, &mock_frontend
, &service
);
3433 update
.StartUpdate(&host
, GURL());
3435 MockFrontend::RaisedEvents events
= mock_frontend
.raised_events_
;
3436 size_t expected
= 1;
3437 EXPECT_EQ(expected
, events
.size());
3438 EXPECT_EQ(expected
, events
[0].first
.size());
3439 EXPECT_EQ(host
.host_id(), events
[0].first
[0]);
3440 EXPECT_EQ(CHECKING_EVENT
, events
[0].second
);
3441 EXPECT_EQ(AppCacheGroup::CHECKING
, group
->update_status());
3444 TEST_F(AppCacheUpdateJobTest
, AlreadyDownloading
) {
3445 MockAppCacheService service
;
3446 scoped_refptr
<AppCacheGroup
> group(
3447 new AppCacheGroup(service
.storage(), GURL("http://manifesturl.com"),
3448 service
.storage()->NewGroupId()));
3450 AppCacheUpdateJob
update(&service
, group
.get());
3452 // Pretend group is in downloading state.
3453 group
->update_job_
= &update
;
3454 group
->update_status_
= AppCacheGroup::DOWNLOADING
;
3456 update
.StartUpdate(NULL
, GURL());
3457 EXPECT_EQ(AppCacheGroup::DOWNLOADING
, group
->update_status());
3459 MockFrontend mock_frontend
;
3460 AppCacheHost
host(1, &mock_frontend
, &service
);
3461 update
.StartUpdate(&host
, GURL());
3463 MockFrontend::RaisedEvents events
= mock_frontend
.raised_events_
;
3464 size_t expected
= 2;
3465 EXPECT_EQ(expected
, events
.size());
3467 EXPECT_EQ(expected
, events
[0].first
.size());
3468 EXPECT_EQ(host
.host_id(), events
[0].first
[0]);
3469 EXPECT_EQ(CHECKING_EVENT
, events
[0].second
);
3471 EXPECT_EQ(expected
, events
[1].first
.size());
3472 EXPECT_EQ(host
.host_id(), events
[1].first
[0]);
3473 EXPECT_EQ(appcache::DOWNLOADING_EVENT
, events
[1].second
);
3475 EXPECT_EQ(AppCacheGroup::DOWNLOADING
, group
->update_status());
3478 TEST_F(AppCacheUpdateJobTest
, StartCacheAttempt
) {
3479 RunTestOnIOThread(&AppCacheUpdateJobTest::StartCacheAttemptTest
);
3482 TEST_F(AppCacheUpdateJobTest
, StartUpgradeAttempt
) {
3483 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpgradeAttemptTest
);
3486 TEST_F(AppCacheUpdateJobTest
, CacheAttemptFetchManifestFail
) {
3487 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptFetchManifestFailTest
);
3490 TEST_F(AppCacheUpdateJobTest
, UpgradeFetchManifestFail
) {
3491 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFetchManifestFailTest
);
3494 TEST_F(AppCacheUpdateJobTest
, ManifestRedirect
) {
3495 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestRedirectTest
);
3498 TEST_F(AppCacheUpdateJobTest
, ManifestMissingMimeTypeTest
) {
3499 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestMissingMimeTypeTest
);
3502 TEST_F(AppCacheUpdateJobTest
, ManifestNotFound
) {
3503 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestNotFoundTest
);
3506 TEST_F(AppCacheUpdateJobTest
, ManifestGone
) {
3507 RunTestOnIOThread(&AppCacheUpdateJobTest::ManifestGoneTest
);
3510 TEST_F(AppCacheUpdateJobTest
, CacheAttemptNotModified
) {
3511 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptNotModifiedTest
);
3514 TEST_F(AppCacheUpdateJobTest
, UpgradeNotModified
) {
3515 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeNotModifiedTest
);
3518 TEST_F(AppCacheUpdateJobTest
, UpgradeManifestDataUnchanged
) {
3519 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeManifestDataUnchangedTest
);
3522 TEST_F(AppCacheUpdateJobTest
, Bug95101Test
) {
3523 RunTestOnIOThread(&AppCacheUpdateJobTest::Bug95101Test
);
3526 TEST_F(AppCacheUpdateJobTest
, BasicCacheAttemptSuccess
) {
3527 RunTestOnIOThread(&AppCacheUpdateJobTest::BasicCacheAttemptSuccessTest
);
3530 TEST_F(AppCacheUpdateJobTest
, DownloadInterceptEntriesTest
) {
3531 RunTestOnIOThread(&AppCacheUpdateJobTest::DownloadInterceptEntriesTest
);
3534 TEST_F(AppCacheUpdateJobTest
, BasicUpgradeSuccess
) {
3535 RunTestOnIOThread(&AppCacheUpdateJobTest::BasicUpgradeSuccessTest
);
3538 TEST_F(AppCacheUpdateJobTest
, UpgradeLoadFromNewestCache
) {
3539 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeLoadFromNewestCacheTest
);
3542 TEST_F(AppCacheUpdateJobTest
, UpgradeNoLoadFromNewestCache
) {
3543 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeNoLoadFromNewestCacheTest
);
3546 TEST_F(AppCacheUpdateJobTest
, UpgradeLoadFromNewestCacheVaryHeader
) {
3548 &AppCacheUpdateJobTest::UpgradeLoadFromNewestCacheVaryHeaderTest
);
3551 TEST_F(AppCacheUpdateJobTest
, UpgradeSuccessMergedTypes
) {
3552 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeSuccessMergedTypesTest
);
3555 TEST_F(AppCacheUpdateJobTest
, CacheAttemptFailUrlFetch
) {
3556 RunTestOnIOThread(&AppCacheUpdateJobTest::CacheAttemptFailUrlFetchTest
);
3559 TEST_F(AppCacheUpdateJobTest
, UpgradeFailUrlFetch
) {
3560 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailUrlFetchTest
);
3563 TEST_F(AppCacheUpdateJobTest
, UpgradeFailMasterUrlFetch
) {
3564 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailMasterUrlFetchTest
);
3567 TEST_F(AppCacheUpdateJobTest
, EmptyManifest
) {
3568 RunTestOnIOThread(&AppCacheUpdateJobTest::EmptyManifestTest
);
3571 TEST_F(AppCacheUpdateJobTest
, EmptyFile
) {
3572 RunTestOnIOThread(&AppCacheUpdateJobTest::EmptyFileTest
);
3575 TEST_F(AppCacheUpdateJobTest
, RetryRequest
) {
3576 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryRequestTest
);
3579 TEST_F(AppCacheUpdateJobTest
, RetryNoRetryAfter
) {
3580 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryNoRetryAfterTest
);
3583 TEST_F(AppCacheUpdateJobTest
, RetryNonzeroRetryAfter
) {
3584 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryNonzeroRetryAfterTest
);
3587 TEST_F(AppCacheUpdateJobTest
, RetrySuccess
) {
3588 RunTestOnIOThread(&AppCacheUpdateJobTest::RetrySuccessTest
);
3591 TEST_F(AppCacheUpdateJobTest
, RetryUrl
) {
3592 RunTestOnIOThread(&AppCacheUpdateJobTest::RetryUrlTest
);
3595 TEST_F(AppCacheUpdateJobTest
, FailStoreNewestCache
) {
3596 RunTestOnIOThread(&AppCacheUpdateJobTest::FailStoreNewestCacheTest
);
3599 TEST_F(AppCacheUpdateJobTest
, MasterEntryFailStoreNewestCacheTest
) {
3601 &AppCacheUpdateJobTest::MasterEntryFailStoreNewestCacheTest
);
3604 TEST_F(AppCacheUpdateJobTest
, UpgradeFailStoreNewestCache
) {
3605 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailStoreNewestCacheTest
);
3608 TEST_F(AppCacheUpdateJobTest
, UpgradeFailMakeGroupObsolete
) {
3609 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeFailMakeGroupObsoleteTest
);
3612 TEST_F(AppCacheUpdateJobTest
, MasterEntryFetchManifestFail
) {
3613 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFetchManifestFailTest
);
3616 TEST_F(AppCacheUpdateJobTest
, MasterEntryBadManifest
) {
3617 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryBadManifestTest
);
3620 TEST_F(AppCacheUpdateJobTest
, MasterEntryManifestNotFound
) {
3621 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryManifestNotFoundTest
);
3624 TEST_F(AppCacheUpdateJobTest
, MasterEntryFailUrlFetch
) {
3625 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryFailUrlFetchTest
);
3628 TEST_F(AppCacheUpdateJobTest
, MasterEntryAllFail
) {
3629 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryAllFailTest
);
3632 TEST_F(AppCacheUpdateJobTest
, UpgradeMasterEntryAllFail
) {
3633 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntryAllFailTest
);
3636 TEST_F(AppCacheUpdateJobTest
, MasterEntrySomeFail
) {
3637 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntrySomeFailTest
);
3640 TEST_F(AppCacheUpdateJobTest
, UpgradeMasterEntrySomeFail
) {
3641 RunTestOnIOThread(&AppCacheUpdateJobTest::UpgradeMasterEntrySomeFailTest
);
3644 TEST_F(AppCacheUpdateJobTest
, MasterEntryNoUpdate
) {
3645 RunTestOnIOThread(&AppCacheUpdateJobTest::MasterEntryNoUpdateTest
);
3648 TEST_F(AppCacheUpdateJobTest
, StartUpdateMidCacheAttempt
) {
3649 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidCacheAttemptTest
);
3652 TEST_F(AppCacheUpdateJobTest
, StartUpdateMidNoUpdate
) {
3653 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidNoUpdateTest
);
3656 TEST_F(AppCacheUpdateJobTest
, StartUpdateMidDownload
) {
3657 RunTestOnIOThread(&AppCacheUpdateJobTest::StartUpdateMidDownloadTest
);
3660 TEST_F(AppCacheUpdateJobTest
, QueueMasterEntry
) {
3661 RunTestOnIOThread(&AppCacheUpdateJobTest::QueueMasterEntryTest
);
3664 TEST_F(AppCacheUpdateJobTest
, IfModifiedSince
) {
3665 RunTestOnIOThread(&AppCacheUpdateJobTest::IfModifiedSinceTest
);
3668 TEST_F(AppCacheUpdateJobTest
, IfModifiedSinceUpgrade
) {
3669 RunTestOnIOThread(&AppCacheUpdateJobTest::IfModifiedSinceUpgradeTest
);
3672 TEST_F(AppCacheUpdateJobTest
, IfNoneMatchUpgrade
) {
3673 RunTestOnIOThread(&AppCacheUpdateJobTest::IfNoneMatchUpgradeTest
);
3676 TEST_F(AppCacheUpdateJobTest
, IfNoneMatchRefetch
) {
3677 RunTestOnIOThread(&AppCacheUpdateJobTest::IfNoneMatchRefetchTest
);
3680 TEST_F(AppCacheUpdateJobTest
, MultipleHeadersRefetch
) {
3681 RunTestOnIOThread(&AppCacheUpdateJobTest::MultipleHeadersRefetchTest
);
3684 TEST_F(AppCacheUpdateJobTest
, CrossOriginHttpsSuccess
) {
3685 RunTestOnIOThread(&AppCacheUpdateJobTest::CrossOriginHttpsSuccessTest
);
3688 TEST_F(AppCacheUpdateJobTest
, CrossOriginHttpsDenied
) {
3689 RunTestOnIOThread(&AppCacheUpdateJobTest::CrossOriginHttpsDeniedTest
);
3692 } // namespace appcache