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 void OnCacheLoaded(AppCache
* cache
, int64 cache_id
) override
{
25 loaded_cache_
= cache
;
26 loaded_cache_id_
= cache_id
;
29 void OnGroupLoaded(AppCacheGroup
* group
,
30 const GURL
& manifest_url
) override
{
31 loaded_group_
= group
;
32 loaded_manifest_url_
= manifest_url
;
35 void OnGroupAndNewestCacheStored(AppCacheGroup
* group
,
36 AppCache
* newest_cache
,
38 bool would_exceed_quota
) override
{
39 stored_group_
= group
;
40 stored_group_success_
= success
;
43 void OnGroupMadeObsolete(AppCacheGroup
* group
,
45 int response_code
) override
{
46 obsoleted_group_
= group
;
47 obsoleted_success_
= success
;
50 void OnMainResponseFound(const GURL
& url
,
51 const AppCacheEntry
& entry
,
52 const GURL
& fallback_url
,
53 const AppCacheEntry
& fallback_entry
,
56 const GURL
& manifest_url
) override
{
59 found_fallback_url_
= fallback_url
;
60 found_fallback_entry_
= fallback_entry
;
61 found_cache_id_
= cache_id
;
62 found_manifest_url_
= manifest_url
;
65 scoped_refptr
<AppCache
> loaded_cache_
;
66 int64 loaded_cache_id_
;
67 scoped_refptr
<AppCacheGroup
> loaded_group_
;
68 GURL loaded_manifest_url_
;
69 scoped_refptr
<AppCacheGroup
> stored_group_
;
70 bool stored_group_success_
;
71 scoped_refptr
<AppCacheGroup
> obsoleted_group_
;
72 bool obsoleted_success_
;
74 AppCacheEntry found_entry_
;
75 GURL found_fallback_url_
;
76 AppCacheEntry found_fallback_entry_
;
77 int64 found_cache_id_
;
78 GURL found_manifest_url_
;
82 base::MessageLoop message_loop_
;
85 TEST_F(MockAppCacheStorageTest
, LoadCache_Miss
) {
86 // Attempt to load a cache that doesn't exist. Should
88 MockAppCacheService service
;
89 MockStorageDelegate delegate
;
90 service
.storage()->LoadCache(111, &delegate
);
91 EXPECT_NE(111, delegate
.loaded_cache_id_
);
92 base::RunLoop().RunUntilIdle(); // Do async task execution.
93 EXPECT_EQ(111, delegate
.loaded_cache_id_
);
94 EXPECT_FALSE(delegate
.loaded_cache_
.get());
97 TEST_F(MockAppCacheStorageTest
, LoadCache_NearHit
) {
98 // Attempt to load a cache that is currently in use
99 // and does not require loading from disk. This
100 // load should complete syncly.
101 MockAppCacheService service
;
103 // Setup some preconditions. Make an 'unstored' cache for
104 // us to load. The ctor should put it in the working set.
105 int64 cache_id
= service
.storage()->NewCacheId();
106 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
109 MockStorageDelegate delegate
;
110 service
.storage()->LoadCache(cache_id
, &delegate
);
111 EXPECT_EQ(cache_id
, delegate
.loaded_cache_id_
);
112 EXPECT_EQ(cache
.get(), delegate
.loaded_cache_
.get());
115 TEST_F(MockAppCacheStorageTest
, CreateGroup
) {
116 // Attempt to load/create a group that doesn't exist.
117 // Should complete asyncly.
118 MockAppCacheService service
;
119 MockAppCacheStorage
* storage
=
120 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
121 MockStorageDelegate delegate
;
122 GURL
manifest_url("http://blah/");
123 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
124 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
125 EXPECT_FALSE(delegate
.loaded_group_
.get());
126 base::RunLoop().RunUntilIdle(); // Do async task execution.
127 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
128 EXPECT_TRUE(delegate
.loaded_group_
.get());
129 EXPECT_TRUE(delegate
.loaded_group_
->HasOneRef());
130 EXPECT_FALSE(delegate
.loaded_group_
->newest_complete_cache());
131 EXPECT_TRUE(storage
->stored_groups_
.empty());
134 TEST_F(MockAppCacheStorageTest
, LoadGroup_NearHit
) {
135 // Attempt to load a group that is currently in use
136 // and does not require loading from disk. This
137 // load should complete syncly.
138 MockAppCacheService service
;
139 MockStorageDelegate delegate
;
141 // Setup some preconditions. Create a group that appears
142 // to be "unstored" and "currently in use".
143 GURL
manifest_url("http://blah/");
144 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
145 base::RunLoop().RunUntilIdle(); // Do async task execution.
146 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
147 EXPECT_TRUE(delegate
.loaded_group_
.get());
149 // Reset our delegate, and take a reference to the new group.
150 scoped_refptr
<AppCacheGroup
> group
;
151 group
.swap(delegate
.loaded_group_
);
152 delegate
.loaded_manifest_url_
= GURL();
155 service
.storage()->LoadOrCreateGroup(manifest_url
, &delegate
);
156 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
157 EXPECT_EQ(group
.get(), delegate
.loaded_group_
.get());
160 TEST_F(MockAppCacheStorageTest
, LoadGroupAndCache_FarHit
) {
161 // Attempt to load a cache that is not currently in use
162 // and does require loading from disk. This
163 // load should complete asyncly.
164 MockAppCacheService service
;
165 MockAppCacheStorage
* storage
=
166 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
168 // Setup some preconditions. Create a group and newest cache that
169 // appears to be "stored" and "not currently in use".
170 GURL
manifest_url("http://blah/");
171 scoped_refptr
<AppCacheGroup
> group(
172 new AppCacheGroup(service
.storage(), manifest_url
, 111));
173 int64 cache_id
= storage
->NewCacheId();
174 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
175 cache
->set_complete(true);
176 group
->AddCache(cache
.get());
177 storage
->AddStoredGroup(group
.get());
178 storage
->AddStoredCache(cache
.get());
180 // Drop the references from above so the only refs to these
181 // objects are from within the storage class. This is to make
182 // these objects appear as "not currently in use".
183 AppCache
* cache_ptr
= cache
.get();
184 AppCacheGroup
* group_ptr
= group
.get();
188 // Setup a delegate to receive completion callbacks.
189 MockStorageDelegate delegate
;
191 // Conduct the cache load test.
192 EXPECT_NE(cache_id
, delegate
.loaded_cache_id_
);
193 EXPECT_NE(cache_ptr
, delegate
.loaded_cache_
.get());
194 storage
->LoadCache(cache_id
, &delegate
);
195 EXPECT_NE(cache_id
, delegate
.loaded_cache_id_
);
196 EXPECT_NE(cache_ptr
, delegate
.loaded_cache_
.get());
197 base::RunLoop().RunUntilIdle(); // Do async task execution.
198 EXPECT_EQ(cache_id
, delegate
.loaded_cache_id_
);
199 EXPECT_EQ(cache_ptr
, delegate
.loaded_cache_
.get());
200 delegate
.loaded_cache_
= NULL
;
202 // Conduct the group load test.
203 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
204 EXPECT_FALSE(delegate
.loaded_group_
.get());
205 storage
->LoadOrCreateGroup(manifest_url
, &delegate
);
206 EXPECT_NE(manifest_url
, delegate
.loaded_manifest_url_
);
207 EXPECT_FALSE(delegate
.loaded_group_
.get());
208 base::RunLoop().RunUntilIdle(); // Do async task execution.
209 EXPECT_EQ(manifest_url
, delegate
.loaded_manifest_url_
);
210 EXPECT_EQ(group_ptr
, delegate
.loaded_group_
.get());
213 TEST_F(MockAppCacheStorageTest
, StoreNewGroup
) {
214 // Store a group and its newest cache. Should complete asyncly.
215 MockAppCacheService service
;
216 MockAppCacheStorage
* storage
=
217 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
219 // Setup some preconditions. Create a group and newest cache that
220 // appears to be "unstored".
221 GURL
manifest_url("http://blah/");
222 scoped_refptr
<AppCacheGroup
> group(
223 new AppCacheGroup(service
.storage(), manifest_url
, 111));
224 int64 cache_id
= storage
->NewCacheId();
225 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
226 // Hold a ref to the cache simulate the UpdateJob holding that ref,
227 // and hold a ref to the group to simulate the CacheHost holding that ref.
229 // Conduct the store test.
230 MockStorageDelegate delegate
;
231 EXPECT_TRUE(storage
->stored_caches_
.empty());
232 EXPECT_TRUE(storage
->stored_groups_
.empty());
233 storage
->StoreGroupAndNewestCache(group
.get(), cache
.get(), &delegate
);
234 EXPECT_FALSE(delegate
.stored_group_success_
);
235 EXPECT_TRUE(storage
->stored_caches_
.empty());
236 EXPECT_TRUE(storage
->stored_groups_
.empty());
237 base::RunLoop().RunUntilIdle(); // Do async task execution.
238 EXPECT_TRUE(delegate
.stored_group_success_
);
239 EXPECT_FALSE(storage
->stored_caches_
.empty());
240 EXPECT_FALSE(storage
->stored_groups_
.empty());
241 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
242 EXPECT_TRUE(cache
->is_complete());
245 TEST_F(MockAppCacheStorageTest
, StoreExistingGroup
) {
246 // Store a group and its newest cache. Should complete asyncly.
247 MockAppCacheService service
;
248 MockAppCacheStorage
* storage
=
249 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
251 // Setup some preconditions. Create a group and old complete cache
252 // that appear to be "stored", and a newest unstored complete cache.
253 GURL
manifest_url("http://blah/");
254 scoped_refptr
<AppCacheGroup
> group(
255 new AppCacheGroup(service
.storage(), manifest_url
, 111));
256 int64 old_cache_id
= storage
->NewCacheId();
257 scoped_refptr
<AppCache
> old_cache(
258 new AppCache(service
.storage(), old_cache_id
));
259 old_cache
->set_complete(true);
260 group
->AddCache(old_cache
.get());
261 storage
->AddStoredGroup(group
.get());
262 storage
->AddStoredCache(old_cache
.get());
263 int64 new_cache_id
= storage
->NewCacheId();
264 scoped_refptr
<AppCache
> new_cache(
265 new AppCache(service
.storage(), new_cache_id
));
266 // Hold our refs to simulate the UpdateJob holding these refs.
269 MockStorageDelegate delegate
;
270 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
271 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
272 EXPECT_TRUE(storage
->IsCacheStored(old_cache
.get()));
273 EXPECT_FALSE(storage
->IsCacheStored(new_cache
.get()));
274 storage
->StoreGroupAndNewestCache(group
.get(), new_cache
.get(), &delegate
);
275 EXPECT_FALSE(delegate
.stored_group_success_
);
276 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
277 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
278 EXPECT_TRUE(storage
->IsCacheStored(old_cache
.get()));
279 EXPECT_FALSE(storage
->IsCacheStored(new_cache
.get()));
280 base::RunLoop().RunUntilIdle(); // Do async task execution.
281 EXPECT_TRUE(delegate
.stored_group_success_
);
282 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
283 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
284 EXPECT_FALSE(storage
->IsCacheStored(old_cache
.get()));
285 EXPECT_TRUE(storage
->IsCacheStored(new_cache
.get()));
286 EXPECT_EQ(new_cache
.get(), group
->newest_complete_cache());
287 EXPECT_TRUE(new_cache
->is_complete());
290 TEST_F(MockAppCacheStorageTest
, StoreExistingGroupExistingCache
) {
291 // Store a group with updates to its existing newest complete cache.
292 MockAppCacheService service
;
293 MockAppCacheStorage
* storage
=
294 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
296 // Setup some preconditions. Create a group and a complete cache that
297 // appear to be "stored".
298 GURL
manifest_url("http://blah");
299 scoped_refptr
<AppCacheGroup
> group(
300 new AppCacheGroup(service
.storage(), manifest_url
, 111));
301 int64 cache_id
= storage
->NewCacheId();
302 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
303 cache
->set_complete(true);
304 group
->AddCache(cache
.get());
305 storage
->AddStoredGroup(group
.get());
306 storage
->AddStoredCache(cache
.get());
307 // Hold our refs to simulate the UpdateJob holding these refs.
309 // Change the group's newest cache.
310 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
311 GURL
entry_url("http://blah/blah");
312 cache
->AddEntry(entry_url
, AppCacheEntry(AppCacheEntry::MASTER
));
315 MockStorageDelegate delegate
;
316 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
317 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
318 EXPECT_TRUE(storage
->IsCacheStored(cache
.get()));
319 storage
->StoreGroupAndNewestCache(group
.get(), cache
.get(), &delegate
);
320 EXPECT_FALSE(delegate
.stored_group_success_
);
321 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
322 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
323 base::RunLoop().RunUntilIdle(); // Do async task execution.
324 EXPECT_TRUE(delegate
.stored_group_success_
);
325 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
326 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
327 EXPECT_TRUE(storage
->IsCacheStored(cache
.get()));
328 EXPECT_EQ(cache
.get(), group
->newest_complete_cache());
329 EXPECT_TRUE(cache
->GetEntry(entry_url
));
332 TEST_F(MockAppCacheStorageTest
, MakeGroupObsolete
) {
333 // Make a group obsolete, should complete asyncly.
334 MockAppCacheService service
;
335 MockAppCacheStorage
* storage
=
336 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
338 // Setup some preconditions. Create a group and newest cache that
339 // appears to be "stored" and "currently in use".
340 GURL
manifest_url("http://blah/");
341 scoped_refptr
<AppCacheGroup
> group(
342 new AppCacheGroup(service
.storage(), manifest_url
, 111));
343 int64 cache_id
= storage
->NewCacheId();
344 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
345 cache
->set_complete(true);
346 group
->AddCache(cache
.get());
347 storage
->AddStoredGroup(group
.get());
348 storage
->AddStoredCache(cache
.get());
349 // Hold our refs to simulate the UpdateJob holding these refs.
352 MockStorageDelegate delegate
;
353 EXPECT_FALSE(group
->is_obsolete());
354 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
355 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
356 EXPECT_FALSE(cache
->HasOneRef());
357 EXPECT_FALSE(group
->HasOneRef());
358 storage
->MakeGroupObsolete(group
.get(), &delegate
, 0);
359 EXPECT_FALSE(group
->is_obsolete());
360 EXPECT_EQ(size_t(1), storage
->stored_caches_
.size());
361 EXPECT_EQ(size_t(1), storage
->stored_groups_
.size());
362 EXPECT_FALSE(cache
->HasOneRef());
363 EXPECT_FALSE(group
->HasOneRef());
364 base::RunLoop().RunUntilIdle(); // Do async task execution.
365 EXPECT_TRUE(delegate
.obsoleted_success_
);
366 EXPECT_EQ(group
.get(), delegate
.obsoleted_group_
.get());
367 EXPECT_TRUE(group
->is_obsolete());
368 EXPECT_TRUE(storage
->stored_caches_
.empty());
369 EXPECT_TRUE(storage
->stored_groups_
.empty());
370 EXPECT_TRUE(cache
->HasOneRef());
371 EXPECT_FALSE(group
->HasOneRef());
372 delegate
.obsoleted_group_
= NULL
;
374 EXPECT_TRUE(group
->HasOneRef());
377 TEST_F(MockAppCacheStorageTest
, MarkEntryAsForeign
) {
378 // Should complete syncly.
379 MockAppCacheService service
;
380 MockAppCacheStorage
* storage
=
381 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
383 // Setup some preconditions. Create a cache with an entry.
384 GURL
entry_url("http://blah/entry");
385 int64 cache_id
= storage
->NewCacheId();
386 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), cache_id
));
387 cache
->AddEntry(entry_url
, AppCacheEntry(AppCacheEntry::EXPLICIT
));
390 MockStorageDelegate delegate
;
391 EXPECT_FALSE(cache
->GetEntry(entry_url
)->IsForeign());
392 storage
->MarkEntryAsForeign(entry_url
, cache_id
);
393 EXPECT_TRUE(cache
->GetEntry(entry_url
)->IsForeign());
394 EXPECT_TRUE(cache
->GetEntry(entry_url
)->IsExplicit());
397 TEST_F(MockAppCacheStorageTest
, FindNoMainResponse
) {
398 // Should complete asyncly.
399 MockAppCacheService service
;
400 MockAppCacheStorage
* storage
=
401 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
404 MockStorageDelegate delegate
;
405 GURL
url("http://blah/some_url");
406 EXPECT_NE(url
, delegate
.found_url_
);
407 storage
->FindResponseForMainRequest(url
, GURL(), &delegate
);
408 EXPECT_NE(url
, delegate
.found_url_
);
409 base::RunLoop().RunUntilIdle(); // Do async task execution.
410 EXPECT_EQ(url
, delegate
.found_url_
);
411 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
412 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
413 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
414 EXPECT_EQ(kAppCacheNoResponseId
,
415 delegate
.found_fallback_entry_
.response_id());
416 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
417 EXPECT_EQ(0, delegate
.found_entry_
.types());
418 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
421 TEST_F(MockAppCacheStorageTest
, BasicFindMainResponse
) {
422 // Should complete asyncly.
423 MockAppCacheService service
;
424 MockAppCacheStorage
* storage
=
425 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
427 // Setup some preconditions. Create a complete cache with an entry.
428 const int64 kCacheId
= storage
->NewCacheId();
429 const GURL
kEntryUrl("http://blah/entry");
430 const GURL
kManifestUrl("http://blah/manifest");
431 const int64 kResponseId
= 1;
432 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
434 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId
));
435 cache
->set_complete(true);
436 scoped_refptr
<AppCacheGroup
> group(
437 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
438 group
->AddCache(cache
.get());
439 storage
->AddStoredGroup(group
.get());
440 storage
->AddStoredCache(cache
.get());
443 MockStorageDelegate delegate
;
444 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
445 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
446 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
447 base::RunLoop().RunUntilIdle(); // Do async task execution.
448 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
449 EXPECT_EQ(kManifestUrl
, delegate
.found_manifest_url_
);
450 EXPECT_EQ(kCacheId
, delegate
.found_cache_id_
);
451 EXPECT_EQ(kResponseId
, delegate
.found_entry_
.response_id());
452 EXPECT_TRUE(delegate
.found_entry_
.IsExplicit());
453 EXPECT_FALSE(delegate
.found_fallback_entry_
.has_response_id());
456 TEST_F(MockAppCacheStorageTest
, BasicFindMainFallbackResponse
) {
457 // Should complete asyncly.
458 MockAppCacheService service
;
459 MockAppCacheStorage
* storage
=
460 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
462 // Setup some preconditions. Create a complete cache with a
463 // fallback namespace and entry.
464 const int64 kCacheId
= storage
->NewCacheId();
465 const GURL
kFallbackEntryUrl1("http://blah/fallback_entry1");
466 const GURL
kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
467 const GURL
kFallbackEntryUrl2("http://blah/fallback_entry2");
468 const GURL
kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
469 const GURL
kManifestUrl("http://blah/manifest");
470 const int64 kResponseId1
= 1;
471 const int64 kResponseId2
= 2;
473 AppCacheManifest manifest
;
474 manifest
.fallback_namespaces
.push_back(
475 AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE
, kFallbackNamespaceUrl1
,
476 kFallbackEntryUrl1
, false));
477 manifest
.fallback_namespaces
.push_back(
478 AppCacheNamespace(APPCACHE_FALLBACK_NAMESPACE
, kFallbackNamespaceUrl2
,
479 kFallbackEntryUrl2
, false));
481 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
482 cache
->InitializeWithManifest(&manifest
);
483 cache
->AddEntry(kFallbackEntryUrl1
,
484 AppCacheEntry(AppCacheEntry::FALLBACK
, kResponseId1
));
485 cache
->AddEntry(kFallbackEntryUrl2
,
486 AppCacheEntry(AppCacheEntry::FALLBACK
, kResponseId2
));
487 cache
->set_complete(true);
489 scoped_refptr
<AppCacheGroup
> group(
490 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
491 group
->AddCache(cache
.get());
492 storage
->AddStoredGroup(group
.get());
493 storage
->AddStoredCache(cache
.get());
495 // The test url is in both fallback namespace urls, but should match
496 // the longer of the two.
497 const GURL
kTestUrl("http://blah/fallback_namespace/longer/test");
500 MockStorageDelegate delegate
;
501 EXPECT_NE(kTestUrl
, delegate
.found_url_
);
502 storage
->FindResponseForMainRequest(kTestUrl
, GURL(), &delegate
);
503 EXPECT_NE(kTestUrl
, delegate
.found_url_
);
504 base::RunLoop().RunUntilIdle(); // Do async task execution.
505 EXPECT_EQ(kTestUrl
, delegate
.found_url_
);
506 EXPECT_EQ(kManifestUrl
, delegate
.found_manifest_url_
);
507 EXPECT_EQ(kCacheId
, delegate
.found_cache_id_
);
508 EXPECT_FALSE(delegate
.found_entry_
.has_response_id());
509 EXPECT_EQ(kResponseId2
, delegate
.found_fallback_entry_
.response_id());
510 EXPECT_EQ(kFallbackEntryUrl2
, delegate
.found_fallback_url_
);
511 EXPECT_TRUE(delegate
.found_fallback_entry_
.IsFallback());
514 TEST_F(MockAppCacheStorageTest
, FindMainResponseWithMultipleCandidates
) {
515 // Should complete asyncly.
516 MockAppCacheService service
;
517 MockAppCacheStorage
* storage
=
518 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
520 // Setup some preconditions. Create 2 complete caches with an entry
523 const GURL
kEntryUrl("http://blah/entry");
524 const int64 kCacheId1
= storage
->NewCacheId();
525 const int64 kCacheId2
= storage
->NewCacheId();
526 const GURL
kManifestUrl1("http://blah/manifest1");
527 const GURL
kManifestUrl2("http://blah/manifest2");
528 const int64 kResponseId1
= 1;
529 const int64 kResponseId2
= 2;
532 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId1
));
534 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId1
));
535 cache
->set_complete(true);
536 scoped_refptr
<AppCacheGroup
> group(
537 new AppCacheGroup(service
.storage(), kManifestUrl1
, 111));
538 group
->AddCache(cache
.get());
539 storage
->AddStoredGroup(group
.get());
540 storage
->AddStoredCache(cache
.get());
541 // Drop our references to cache1 so it appears as "not in use".
546 cache
= new AppCache(service
.storage(), kCacheId2
);
548 kEntryUrl
, AppCacheEntry(AppCacheEntry::EXPLICIT
, kResponseId2
));
549 cache
->set_complete(true);
550 group
= new AppCacheGroup(service
.storage(), kManifestUrl2
, 222);
551 group
->AddCache(cache
.get());
552 storage
->AddStoredGroup(group
.get());
553 storage
->AddStoredCache(cache
.get());
555 // Conduct the test, we should find the response from the second cache
556 // since it's "in use".
557 MockStorageDelegate delegate
;
558 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
559 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
560 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
561 base::RunLoop().RunUntilIdle(); // Do async task execution.
562 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
563 EXPECT_EQ(kManifestUrl2
, delegate
.found_manifest_url_
);
564 EXPECT_EQ(kCacheId2
, delegate
.found_cache_id_
);
565 EXPECT_EQ(kResponseId2
, delegate
.found_entry_
.response_id());
566 EXPECT_TRUE(delegate
.found_entry_
.IsExplicit());
567 EXPECT_FALSE(delegate
.found_fallback_entry_
.has_response_id());
570 TEST_F(MockAppCacheStorageTest
, FindMainResponseExclusions
) {
571 // Should complete asyncly.
572 MockAppCacheService service
;
573 MockAppCacheStorage
* storage
=
574 reinterpret_cast<MockAppCacheStorage
*>(service
.storage());
576 // Setup some preconditions. Create a complete cache with a
577 // foreign entry and an online namespace.
579 const int64 kCacheId
= storage
->NewCacheId();
580 const GURL
kEntryUrl("http://blah/entry");
581 const GURL
kManifestUrl("http://blah/manifest");
582 const GURL
kOnlineNamespaceUrl("http://blah/online_namespace");
583 const int64 kResponseId
= 1;
585 AppCacheManifest manifest
;
586 manifest
.online_whitelist_namespaces
.push_back(
587 AppCacheNamespace(APPCACHE_NETWORK_NAMESPACE
, kOnlineNamespaceUrl
,
589 scoped_refptr
<AppCache
> cache(new AppCache(service
.storage(), kCacheId
));
590 cache
->InitializeWithManifest(&manifest
);
593 AppCacheEntry(AppCacheEntry::EXPLICIT
| AppCacheEntry::FOREIGN
,
595 cache
->set_complete(true);
596 scoped_refptr
<AppCacheGroup
> group(
597 new AppCacheGroup(service
.storage(), kManifestUrl
, 111));
598 group
->AddCache(cache
.get());
599 storage
->AddStoredGroup(group
.get());
600 storage
->AddStoredCache(cache
.get());
602 MockStorageDelegate delegate
;
604 // We should not find anything for the foreign entry.
605 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
606 storage
->FindResponseForMainRequest(kEntryUrl
, GURL(), &delegate
);
607 EXPECT_NE(kEntryUrl
, delegate
.found_url_
);
608 base::RunLoop().RunUntilIdle(); // Do async task execution.
609 EXPECT_EQ(kEntryUrl
, delegate
.found_url_
);
610 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
611 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
612 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
613 EXPECT_EQ(kAppCacheNoResponseId
,
614 delegate
.found_fallback_entry_
.response_id());
615 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
616 EXPECT_EQ(0, delegate
.found_entry_
.types());
617 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
619 // We should not find anything for the online namespace.
620 EXPECT_NE(kOnlineNamespaceUrl
, delegate
.found_url_
);
621 storage
->FindResponseForMainRequest(kOnlineNamespaceUrl
, GURL(), &delegate
);
622 EXPECT_NE(kOnlineNamespaceUrl
, delegate
.found_url_
);
623 base::RunLoop().RunUntilIdle(); // Do async task execution.
624 EXPECT_EQ(kOnlineNamespaceUrl
, delegate
.found_url_
);
625 EXPECT_TRUE(delegate
.found_manifest_url_
.is_empty());
626 EXPECT_EQ(kAppCacheNoCacheId
, delegate
.found_cache_id_
);
627 EXPECT_EQ(kAppCacheNoResponseId
, delegate
.found_entry_
.response_id());
628 EXPECT_EQ(kAppCacheNoResponseId
,
629 delegate
.found_fallback_entry_
.response_id());
630 EXPECT_TRUE(delegate
.found_fallback_url_
.is_empty());
631 EXPECT_EQ(0, delegate
.found_entry_
.types());
632 EXPECT_EQ(0, delegate
.found_fallback_entry_
.types());
635 } // namespace content