1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/run_loop.h"
6 #include "content/browser/appcache/appcache.h"
7 #include "content/browser/appcache/appcache_group.h"
8 #include "content/browser/appcache/appcache_response.h"
9 #include "content/browser/appcache/appcache_storage.h"
10 #include "content/browser/appcache/mock_appcache_service.h"
11 #include "testing/gtest/include/gtest/gtest.h"
15 class MockAppCacheStorageTest
: public testing::Test
{
17 class MockStorageDelegate
: public AppCacheStorage::Delegate
{
19 explicit MockStorageDelegate()
20 : loaded_cache_id_(0), stored_group_success_(false),
21 obsoleted_success_(false), found_cache_id_(kAppCacheNoCacheId
) {
24 virtual void OnCacheLoaded(AppCache
* cache
, int64 cache_id
) OVERRIDE
{
25 loaded_cache_
= cache
;
26 loaded_cache_id_
= cache_id
;
29 virtual void OnGroupLoaded(AppCacheGroup
* group
,
30 const GURL
& manifest_url
) OVERRIDE
{
31 loaded_group_
= group
;
32 loaded_manifest_url_
= manifest_url
;
35 virtual void OnGroupAndNewestCacheStored(
36 AppCacheGroup
* group
, AppCache
* newest_cache
, bool success
,
37 bool would_exceed_quota
) OVERRIDE
{
38 stored_group_
= group
;
39 stored_group_success_
= success
;
42 virtual void OnGroupMadeObsolete(AppCacheGroup
* group
,
44 int response_code
) OVERRIDE
{
45 obsoleted_group_
= group
;
46 obsoleted_success_
= success
;
49 virtual void OnMainResponseFound(const GURL
& url
,
50 const AppCacheEntry
& entry
,
51 const GURL
& fallback_url
,
52 const AppCacheEntry
& fallback_entry
,
55 const GURL
& manifest_url
) OVERRIDE
{
58 found_fallback_url_
= fallback_url
;
59 found_fallback_entry_
= fallback_entry
;
60 found_cache_id_
= cache_id
;
61 found_manifest_url_
= manifest_url
;
64 scoped_refptr
<AppCache
> loaded_cache_
;
65 int64 loaded_cache_id_
;
66 scoped_refptr
<AppCacheGroup
> loaded_group_
;
67 GURL loaded_manifest_url_
;
68 scoped_refptr
<AppCacheGroup
> stored_group_
;
69 bool stored_group_success_
;
70 scoped_refptr
<AppCacheGroup
> obsoleted_group_
;
71 bool obsoleted_success_
;
73 AppCacheEntry found_entry_
;
74 GURL found_fallback_url_
;
75 AppCacheEntry found_fallback_entry_
;
76 int64 found_cache_id_
;
77 GURL found_manifest_url_
;
81 base::MessageLoop message_loop_
;
84 TEST_F(MockAppCacheStorageTest
, LoadCache_Miss
) {
85 // Attempt to load a cache that doesn't exist. Should
87 MockAppCacheService service
;
88 MockStorageDelegate delegate
;
89 service
.storage()->LoadCache(111, &delegate
);
90 EXPECT_NE(111, delegate
.loaded_cache_id_
);
91 base::RunLoop().RunUntilIdle(); // Do async task execution.
92 EXPECT_EQ(111, delegate
.loaded_cache_id_
);
93 EXPECT_FALSE(delegate
.loaded_cache_
.get());
96 TEST_F(MockAppCacheStorageTest
, LoadCache_NearHit
) {
97 // Attempt to load a cache that is currently in use
98 // and does not require loading from disk. This
99 // load should complete syncly.
100 MockAppCacheService service
;
102 // Setup some preconditions. Make an 'unstored' cache for
103 // us to load. The ctor should put it in the working set.
104 int64 cache_id
= service
.storage()->NewCacheId();
105 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
108 MockStorageDelegate delegate
;
109 service
.storage()->LoadCache(cache_id
, &delegate
);
110 EXPECT_EQ(cache_id
, delegate
.loaded_cache_id_
);
111 EXPECT_EQ(cache
.get(), delegate
.loaded_cache_
.get());
114 TEST_F(MockAppCacheStorageTest
, CreateGroup
) {
115 // Attempt to load/create a group that doesn't exist.
116 // Should complete asyncly.
117 MockAppCacheService service
;
118 MockAppCacheStorage
* storage
=
119 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
120 MockStorageDelegate delegate
;
121 GURL
manifest_url("http://blah/");
122 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
123 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
124 EXPECT_FALSE(delegate
.loaded_group_
.get());
125 base::RunLoop().RunUntilIdle(); // Do async task execution.
126 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
127 EXPECT_TRUE(delegate
.loaded_group_
.get());
128 EXPECT_TRUE(delegate
.loaded_group_
->HasOneRef());
129 EXPECT_FALSE(delegate
.loaded_group_
->newest_complete_cache());
130 EXPECT_TRUE(storage
->stored_groups_
.empty());
133 TEST_F(MockAppCacheStorageTest
, LoadGroup_NearHit
) {
134 // Attempt to load a group that is currently in use
135 // and does not require loading from disk. This
136 // load should complete syncly.
137 MockAppCacheService service
;
138 MockStorageDelegate delegate
;
140 // Setup some preconditions. Create a group that appears
141 // to be "unstored" and "currently in use".
142 GURL
manifest_url("http://blah/");
143 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
144 base::RunLoop().RunUntilIdle(); // Do async task execution.
145 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
146 EXPECT_TRUE(delegate
.loaded_group_
.get());
148 // Reset our delegate, and take a reference to the new group.
149 scoped_refptr
<AppCacheGroup
> group
;
150 group
.swap(delegate
.loaded_group_
);
151 delegate
.loaded_manifest_url_
= GURL();
154 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
155 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
156 EXPECT_EQ(group
.get(), delegate
.loaded_group_
.get());
159 TEST_F(MockAppCacheStorageTest
, LoadGroupAndCache_FarHit
) {
160 // Attempt to load a cache that is not currently in use
161 // and does require loading from disk. This
162 // load should complete asyncly.
163 MockAppCacheService service
;
164 MockAppCacheStorage
* storage
=
165 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
167 // Setup some preconditions. Create a group and newest cache that
168 // appears to be "stored" and "not currently in use".
169 GURL
manifest_url("http://blah/");
170 scoped_refptr
<AppCacheGroup
> group(
171 new AppCacheGroup(service
.storage(), manifest_url
, 111));
172 int64 cache_id
= storage
->NewCacheId();
173 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
174 cache
->set_complete(true);
175 group
->AddCache(cache
.get());
176 storage
->AddStoredGroup(group
.get());
177 storage
->AddStoredCache(cache
.get());
179 // Drop the references from above so the only refs to these
180 // objects are from within the storage class. This is to make
181 // these objects appear as "not currently in use".
182 AppCache
* cache_ptr
= cache
.get();
183 AppCacheGroup
* group_ptr
= group
.get();
187 // Setup a delegate to receive completion callbacks.
188 MockStorageDelegate delegate
;
190 // Conduct the cache load test.
191 EXPECT_NE(cache_id
, delegate
.loaded_cache_id_
);
192 EXPECT_NE(cache_ptr
, delegate
.loaded_cache_
.get());
193 storage
->LoadCache(cache_id
, &delegate
);
194 EXPECT_NE(cache_id
, delegate
.loaded_cache_id_
);
195 EXPECT_NE(cache_ptr
, delegate
.loaded_cache_
.get());
196 base::RunLoop().RunUntilIdle(); // Do async task execution.
197 EXPECT_EQ(cache_id
, delegate
.loaded_cache_id_
);
198 EXPECT_EQ(cache_ptr
, delegate
.loaded_cache_
.get());
199 delegate
.loaded_cache_
= NULL
;
201 // Conduct the group load test.
202 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
203 EXPECT_FALSE(delegate
.loaded_group_
.get());
204 storage
->LoadOrCreateGroup(manifest_url
, &delegate
);
205 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
206 EXPECT_FALSE(delegate
.loaded_group_
.get());
207 base::RunLoop().RunUntilIdle(); // Do async task execution.
208 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
209 EXPECT_EQ(group_ptr
, delegate
.loaded_group_
.get());
212 TEST_F(MockAppCacheStorageTest
, StoreNewGroup
) {
213 // Store a group and its newest cache. Should complete asyncly.
214 MockAppCacheService service
;
215 MockAppCacheStorage
* storage
=
216 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
218 // Setup some preconditions. Create a group and newest cache that
219 // appears to be "unstored".
220 GURL
manifest_url("http://blah/");
221 scoped_refptr
<AppCacheGroup
> group(
222 new AppCacheGroup(service
.storage(), manifest_url
, 111));
223 int64 cache_id
= storage
->NewCacheId();
224 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
225 // Hold a ref to the cache simulate the UpdateJob holding that ref,
226 // and hold a ref to the group to simulate the CacheHost holding that ref.
228 // Conduct the store test.
229 MockStorageDelegate delegate
;
230 EXPECT_TRUE(storage
->stored_caches_
.empty());
231 EXPECT_TRUE(storage
->stored_groups_
.empty());
232 storage
->StoreGroupAndNewestCache(group
.get(), cache
.get(), &delegate
);
233 EXPECT_FALSE(delegate
.stored_group_success_
);
234 EXPECT_TRUE(storage
->stored_caches_
.empty());
235 EXPECT_TRUE(storage
->stored_groups_
.empty());
236 base::RunLoop().RunUntilIdle(); // Do async task execution.
237 EXPECT_TRUE(delegate
.stored_group_success_
);
238 EXPECT_FALSE(storage
->stored_caches_
.empty());
239 EXPECT_FALSE(storage
->stored_groups_
.empty());
240 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
241 EXPECT_TRUE(cache
->is_complete());
244 TEST_F(MockAppCacheStorageTest
, StoreExistingGroup
) {
245 // Store a group and its newest cache. Should complete asyncly.
246 MockAppCacheService service
;
247 MockAppCacheStorage
* storage
=
248 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
250 // Setup some preconditions. Create a group and old complete cache
251 // that appear to be "stored", and a newest unstored complete cache.
252 GURL
manifest_url("http://blah/");
253 scoped_refptr
<AppCacheGroup
> group(
254 new AppCacheGroup(service
.storage(), manifest_url
, 111));
255 int64 old_cache_id
= storage
->NewCacheId();
256 scoped_refptr
<AppCache
> old_cache(
257 new AppCache(service
.storage(), old_cache_id
));
258 old_cache
->set_complete(true);
259 group
->AddCache(old_cache
.get());
260 storage
->AddStoredGroup(group
.get());
261 storage
->AddStoredCache(old_cache
.get());
262 int64 new_cache_id
= storage
->NewCacheId();
263 scoped_refptr
<AppCache
> new_cache(
264 new AppCache(service
.storage(), new_cache_id
));
265 // Hold our refs to simulate the UpdateJob holding these refs.
268 MockStorageDelegate delegate
;
269 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
270 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
271 EXPECT_TRUE(storage
->IsCacheStored(old_cache
.get()));
272 EXPECT_FALSE(storage
->IsCacheStored(new_cache
.get()));
273 storage
->StoreGroupAndNewestCache(group
.get(), new_cache
.get(), &delegate
);
274 EXPECT_FALSE(delegate
.stored_group_success_
);
275 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
276 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
277 EXPECT_TRUE(storage
->IsCacheStored(old_cache
.get()));
278 EXPECT_FALSE(storage
->IsCacheStored(new_cache
.get()));
279 base::RunLoop().RunUntilIdle(); // Do async task execution.
280 EXPECT_TRUE(delegate
.stored_group_success_
);
281 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
282 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
283 EXPECT_FALSE(storage
->IsCacheStored(old_cache
.get()));
284 EXPECT_TRUE(storage
->IsCacheStored(new_cache
.get()));
285 EXPECT_EQ(new_cache
.get(), group
->newest_complete_cache());
286 EXPECT_TRUE(new_cache
->is_complete());
289 TEST_F(MockAppCacheStorageTest
, StoreExistingGroupExistingCache
) {
290 // Store a group with updates to its existing newest complete cache.
291 MockAppCacheService service
;
292 MockAppCacheStorage
* storage
=
293 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
295 // Setup some preconditions. Create a group and a complete cache that
296 // appear to be "stored".
297 GURL
manifest_url("http://blah");
298 scoped_refptr
<AppCacheGroup
> group(
299 new AppCacheGroup(service
.storage(), manifest_url
, 111));
300 int64 cache_id
= storage
->NewCacheId();
301 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
302 cache
->set_complete(true);
303 group
->AddCache(cache
.get());
304 storage
->AddStoredGroup(group
.get());
305 storage
->AddStoredCache(cache
.get());
306 // Hold our refs to simulate the UpdateJob holding these refs.
308 // Change the group's newest cache.
309 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
310 GURL
entry_url("http://blah/blah");
311 cache
->AddEntry(entry_url
, AppCacheEntry(AppCacheEntry::MASTER
));
314 MockStorageDelegate delegate
;
315 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
316 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
317 EXPECT_TRUE(storage
->IsCacheStored(cache
.get()));
318 storage
->StoreGroupAndNewestCache(group
.get(), cache
.get(), &delegate
);
319 EXPECT_FALSE(delegate
.stored_group_success_
);
320 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
321 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
322 base::RunLoop().RunUntilIdle(); // Do async task execution.
323 EXPECT_TRUE(delegate
.stored_group_success_
);
324 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
325 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
326 EXPECT_TRUE(storage
->IsCacheStored(cache
.get()));
327 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
328 EXPECT_TRUE(cache
->GetEntry(entry_url
));
331 TEST_F(MockAppCacheStorageTest
, MakeGroupObsolete
) {
332 // Make a group obsolete, should complete asyncly.
333 MockAppCacheService service
;
334 MockAppCacheStorage
* storage
=
335 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
337 // Setup some preconditions. Create a group and newest cache that
338 // appears to be "stored" and "currently in use".
339 GURL
manifest_url("http://blah/");
340 scoped_refptr
<AppCacheGroup
> group(
341 new AppCacheGroup(service
.storage(), manifest_url
, 111));
342 int64 cache_id
= storage
->NewCacheId();
343 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
344 cache
->set_complete(true);
345 group
->AddCache(cache
.get());
346 storage
->AddStoredGroup(group
.get());
347 storage
->AddStoredCache(cache
.get());
348 // Hold our refs to simulate the UpdateJob holding these refs.
351 MockStorageDelegate delegate
;
352 EXPECT_FALSE(group
->is_obsolete());
353 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
354 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
355 EXPECT_FALSE(cache
->HasOneRef());
356 EXPECT_FALSE(group
->HasOneRef());
357 storage
->MakeGroupObsolete(group
.get(), &delegate
, 0);
358 EXPECT_FALSE(group
->is_obsolete());
359 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
360 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
361 EXPECT_FALSE(cache
->HasOneRef());
362 EXPECT_FALSE(group
->HasOneRef());
363 base::RunLoop().RunUntilIdle(); // Do async task execution.
364 EXPECT_TRUE(delegate
.obsoleted_success_
);
365 EXPECT_EQ(group
.get(), delegate
.obsoleted_group_
.get());
366 EXPECT_TRUE(group
->is_obsolete());
367 EXPECT_TRUE(storage
->stored_caches_
.empty());
368 EXPECT_TRUE(storage
->stored_groups_
.empty());
369 EXPECT_TRUE(cache
->HasOneRef());
370 EXPECT_FALSE(group
->HasOneRef());
371 delegate
.obsoleted_group_
= NULL
;
373 EXPECT_TRUE(group
->HasOneRef());
376 TEST_F(MockAppCacheStorageTest
, MarkEntryAsForeign
) {
377 // Should complete syncly.
378 MockAppCacheService service
;
379 MockAppCacheStorage
* storage
=
380 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
382 // Setup some preconditions. Create a cache with an entry.
383 GURL
entry_url("http://blah/entry");
384 int64 cache_id
= storage
->NewCacheId();
385 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
386 cache
->AddEntry(entry_url
, AppCacheEntry(AppCacheEntry::EXPLICIT
));
389 MockStorageDelegate delegate
;
390 EXPECT_FALSE(cache
->GetEntry(entry_url
)->IsForeign());
391 storage
->MarkEntryAsForeign(entry_url
, cache_id
);
392 EXPECT_TRUE(cache
->GetEntry(entry_url
)->IsForeign());
393 EXPECT_TRUE(cache
->GetEntry(entry_url
)->IsExplicit());
396 TEST_F(MockAppCacheStorageTest
, FindNoMainResponse
) {
397 // Should complete asyncly.
398 MockAppCacheService service
;
399 MockAppCacheStorage
* storage
=
400 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
403 MockStorageDelegate delegate
;
404 GURL
url("http://blah/some_url");
405 EXPECT_NE(url
, delegate
.found_url_
);
406 storage
->FindResponseForMainRequest(url
, GURL(), &delegate
);
407 EXPECT_NE(url
, delegate
.found_url_
);
408 base::RunLoop().RunUntilIdle(); // Do async task execution.
409 EXPECT_EQ(url
, delegate
.found_url_
);
410 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
411 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
412 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
413 EXPECT_EQ(kAppCacheNoResponseId
,
414 delegate
.found_fallback_entry_
.response_id());
415 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
416 EXPECT_EQ(0, delegate
.found_entry_
.types());
417 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
420 TEST_F(MockAppCacheStorageTest
, BasicFindMainResponse
) {
421 // Should complete asyncly.
422 MockAppCacheService service
;
423 MockAppCacheStorage
* storage
=
424 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
426 // Setup some preconditions. Create a complete cache with an entry.
427 const int64 kCacheId
= storage
->NewCacheId();
428 const GURL
kEntryUrl("http://blah/entry");
429 const GURL
kManifestUrl("http://blah/manifest");
430 const int64 kResponseId
= 1;
431 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
433 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId
));
434 cache
->set_complete(true);
435 scoped_refptr
<AppCacheGroup
> group(
436 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
437 group
->AddCache(cache
.get());
438 storage
->AddStoredGroup(group
.get());
439 storage
->AddStoredCache(cache
.get());
442 MockStorageDelegate delegate
;
443 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
444 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
445 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
446 base::RunLoop().RunUntilIdle(); // Do async task execution.
447 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
448 EXPECT_EQ(kManifestUrl
, delegate
.found_manifest_url_
);
449 EXPECT_EQ(kCacheId
, delegate
.found_cache_id_
);
450 EXPECT_EQ(kResponseId
, delegate
.found_entry_
.response_id());
451 EXPECT_TRUE(delegate
.found_entry_
.IsExplicit());
452 EXPECT_FALSE(delegate
.found_fallback_entry_
.has_response_id());
455 TEST_F(MockAppCacheStorageTest
, BasicFindMainFallbackResponse
) {
456 // Should complete asyncly.
457 MockAppCacheService service
;
458 MockAppCacheStorage
* storage
=
459 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
461 // Setup some preconditions. Create a complete cache with a
462 // fallback namespace and entry.
463 const int64 kCacheId
= storage
->NewCacheId();
464 const GURL
kFallbackEntryUrl1("http://blah/fallback_entry1");
465 const GURL
kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
466 const GURL
kFallbackEntryUrl2("http://blah/fallback_entry2");
467 const GURL
kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
468 const GURL
kManifestUrl("http://blah/manifest");
469 const int64 kResponseId1
= 1;
470 const int64 kResponseId2
= 2;
473 manifest
.fallback_namespaces
.push_back(
474 AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE
, kFallbackNamespaceUrl1
,
475 kFallbackEntryUrl1
, false));
476 manifest
.fallback_namespaces
.push_back(
477 AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE
, kFallbackNamespaceUrl2
,
478 kFallbackEntryUrl2
, false));
480 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
481 cache
->InitializeWithManifest(&manifest
);
482 cache
->AddEntry(kFallbackEntryUrl1
,
483 AppCacheEntry(AppCacheEntry::FALLBACK
, kResponseId1
));
484 cache
->AddEntry(kFallbackEntryUrl2
,
485 AppCacheEntry(AppCacheEntry::FALLBACK
, kResponseId2
));
486 cache
->set_complete(true);
488 scoped_refptr
<AppCacheGroup
> group(
489 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
490 group
->AddCache(cache
.get());
491 storage
->AddStoredGroup(group
.get());
492 storage
->AddStoredCache(cache
.get());
494 // The test url is in both fallback namespace urls, but should match
495 // the longer of the two.
496 const GURL
kTestUrl("http://blah/fallback_namespace/longer/test");
499 MockStorageDelegate delegate
;
500 EXPECT_NE(kTestUrl
, delegate
.found_url_
);
501 storage
->FindResponseForMainRequest(kTestUrl
, GURL(), &delegate
);
502 EXPECT_NE(kTestUrl
, delegate
.found_url_
);
503 base::RunLoop().RunUntilIdle(); // Do async task execution.
504 EXPECT_EQ(kTestUrl
, delegate
.found_url_
);
505 EXPECT_EQ(kManifestUrl
, delegate
.found_manifest_url_
);
506 EXPECT_EQ(kCacheId
, delegate
.found_cache_id_
);
507 EXPECT_FALSE(delegate
.found_entry_
.has_response_id());
508 EXPECT_EQ(kResponseId2
, delegate
.found_fallback_entry_
.response_id());
509 EXPECT_EQ(kFallbackEntryUrl2
, delegate
.found_fallback_url_
);
510 EXPECT_TRUE(delegate
.found_fallback_entry_
.IsFallback());
513 TEST_F(MockAppCacheStorageTest
, FindMainResponseWithMultipleCandidates
) {
514 // Should complete asyncly.
515 MockAppCacheService service
;
516 MockAppCacheStorage
* storage
=
517 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
519 // Setup some preconditions. Create 2 complete caches with an entry
522 const GURL
kEntryUrl("http://blah/entry");
523 const int64 kCacheId1
= storage
->NewCacheId();
524 const int64 kCacheId2
= storage
->NewCacheId();
525 const GURL
kManifestUrl1("http://blah/manifest1");
526 const GURL
kManifestUrl2("http://blah/manifest2");
527 const int64 kResponseId1
= 1;
528 const int64 kResponseId2
= 2;
531 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId1
));
533 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId1
));
534 cache
->set_complete(true);
535 scoped_refptr
<AppCacheGroup
> group(
536 new AppCacheGroup(service
.storage(), kManifestUrl1
, 111));
537 group
->AddCache(cache
.get());
538 storage
->AddStoredGroup(group
.get());
539 storage
->AddStoredCache(cache
.get());
540 // Drop our references to cache1 so it appears as "not in use".
545 cache
= new AppCache(service
.storage(), kCacheId2
);
547 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId2
));
548 cache
->set_complete(true);
549 group
= new AppCacheGroup(service
.storage(), kManifestUrl2
, 222);
550 group
->AddCache(cache
.get());
551 storage
->AddStoredGroup(group
.get());
552 storage
->AddStoredCache(cache
.get());
554 // Conduct the test, we should find the response from the second cache
555 // since it's "in use".
556 MockStorageDelegate delegate
;
557 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
558 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
559 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
560 base::RunLoop().RunUntilIdle(); // Do async task execution.
561 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
562 EXPECT_EQ(kManifestUrl2
, delegate
.found_manifest_url_
);
563 EXPECT_EQ(kCacheId2
, delegate
.found_cache_id_
);
564 EXPECT_EQ(kResponseId2
, delegate
.found_entry_
.response_id());
565 EXPECT_TRUE(delegate
.found_entry_
.IsExplicit());
566 EXPECT_FALSE(delegate
.found_fallback_entry_
.has_response_id());
569 TEST_F(MockAppCacheStorageTest
, FindMainResponseExclusions
) {
570 // Should complete asyncly.
571 MockAppCacheService service
;
572 MockAppCacheStorage
* storage
=
573 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
575 // Setup some preconditions. Create a complete cache with a
576 // foreign entry and an online namespace.
578 const int64 kCacheId
= storage
->NewCacheId();
579 const GURL
kEntryUrl("http://blah/entry");
580 const GURL
kManifestUrl("http://blah/manifest");
581 const GURL
kOnlineNamespaceUrl("http://blah/online_namespace");
582 const int64 kResponseId
= 1;
585 manifest
.online_whitelist_namespaces
.push_back(
586 AppCacheNamespace(APPCACHE_NETWORK_NAMESPACE
, kOnlineNamespaceUrl
,
588 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
589 cache
->InitializeWithManifest(&manifest
);
592 AppCacheEntry(AppCacheEntry::EXPLICIT
| AppCacheEntry::FOREIGN
,
594 cache
->set_complete(true);
595 scoped_refptr
<AppCacheGroup
> group(
596 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
597 group
->AddCache(cache
.get());
598 storage
->AddStoredGroup(group
.get());
599 storage
->AddStoredCache(cache
.get());
601 MockStorageDelegate delegate
;
603 // We should not find anything for the foreign entry.
604 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
605 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
606 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
607 base::RunLoop().RunUntilIdle(); // Do async task execution.
608 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
609 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
610 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
611 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
612 EXPECT_EQ(kAppCacheNoResponseId
,
613 delegate
.found_fallback_entry_
.response_id());
614 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
615 EXPECT_EQ(0, delegate
.found_entry_
.types());
616 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
618 // We should not find anything for the online namespace.
619 EXPECT_NE(kOnlineNamespaceUrl
, delegate
.found_url_
);
620 storage
->FindResponseForMainRequest(kOnlineNamespaceUrl
, GURL(), &delegate
);
621 EXPECT_NE(kOnlineNamespaceUrl
, delegate
.found_url_
);
622 base::RunLoop().RunUntilIdle(); // Do async task execution.
623 EXPECT_EQ(kOnlineNamespaceUrl
, delegate
.found_url_
);
624 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
625 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
626 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
627 EXPECT_EQ(kAppCacheNoResponseId
,
628 delegate
.found_fallback_entry_
.response_id());
629 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
630 EXPECT_EQ(0, delegate
.found_entry_
.types());
631 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
634 } // namespace content