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/mock_appcache_service.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "webkit/browser/appcache/appcache.h"
9 #include "webkit/browser/appcache/appcache_group.h"
10 #include "webkit/browser/appcache/appcache_response.h"
11 #include "webkit/browser/appcache/appcache_storage.h"
13 using appcache::AppCache;
14 using appcache::AppCacheEntry;
15 using appcache::AppCacheGroup;
16 using appcache::AppCacheStorage;
17 using appcache::FALLBACK_NAMESPACE;
18 using appcache::INTERCEPT_NAMESPACE;
19 using appcache::kNoCacheId;
20 using appcache::kNoResponseId;
21 using appcache::Manifest;
22 using appcache::Namespace;
23 using appcache::NETWORK_NAMESPACE;
27 class MockAppCacheStorageTest : public testing::Test {
29 class MockStorageDelegate : public AppCacheStorage::Delegate {
31 explicit MockStorageDelegate()
32 : loaded_cache_id_(0), stored_group_success_(false),
33 obsoleted_success_(false), found_cache_id_(kNoCacheId) {
36 virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE {
37 loaded_cache_ = cache;
38 loaded_cache_id_ = cache_id;
41 virtual void OnGroupLoaded(AppCacheGroup* group,
42 const GURL& manifest_url) OVERRIDE {
43 loaded_group_ = group;
44 loaded_manifest_url_ = manifest_url;
47 virtual void OnGroupAndNewestCacheStored(
48 AppCacheGroup* group, AppCache* newest_cache, bool success,
49 bool would_exceed_quota) OVERRIDE {
50 stored_group_ = group;
51 stored_group_success_ = success;
54 virtual void OnGroupMadeObsolete(AppCacheGroup* group,
56 int response_code) OVERRIDE {
57 obsoleted_group_ = group;
58 obsoleted_success_ = success;
61 virtual void OnMainResponseFound(const GURL& url,
62 const AppCacheEntry& entry,
63 const GURL& fallback_url,
64 const AppCacheEntry& fallback_entry,
67 const GURL& manifest_url) OVERRIDE {
70 found_fallback_url_ = fallback_url;
71 found_fallback_entry_ = fallback_entry;
72 found_cache_id_ = cache_id;
73 found_manifest_url_ = manifest_url;
76 scoped_refptr<AppCache> loaded_cache_;
77 int64 loaded_cache_id_;
78 scoped_refptr<AppCacheGroup> loaded_group_;
79 GURL loaded_manifest_url_;
80 scoped_refptr<AppCacheGroup> stored_group_;
81 bool stored_group_success_;
82 scoped_refptr<AppCacheGroup> obsoleted_group_;
83 bool obsoleted_success_;
85 AppCacheEntry found_entry_;
86 GURL found_fallback_url_;
87 AppCacheEntry found_fallback_entry_;
88 int64 found_cache_id_;
89 GURL found_manifest_url_;
93 base::MessageLoop message_loop_;
96 TEST_F(MockAppCacheStorageTest, LoadCache_Miss) {
97 // Attempt to load a cache that doesn't exist. Should
99 MockAppCacheService service;
100 MockStorageDelegate delegate;
101 service.storage()->LoadCache(111, &delegate);
102 EXPECT_NE(111, delegate.loaded_cache_id_);
103 base::RunLoop().RunUntilIdle(); // Do async task execution.
104 EXPECT_EQ(111, delegate.loaded_cache_id_);
105 EXPECT_FALSE(delegate.loaded_cache_.get());
108 TEST_F(MockAppCacheStorageTest, LoadCache_NearHit) {
109 // Attempt to load a cache that is currently in use
110 // and does not require loading from disk. This
111 // load should complete syncly.
112 MockAppCacheService service;
114 // Setup some preconditions. Make an 'unstored' cache for
115 // us to load. The ctor should put it in the working set.
116 int64 cache_id = service.storage()->NewCacheId();
117 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
120 MockStorageDelegate delegate;
121 service.storage()->LoadCache(cache_id, &delegate);
122 EXPECT_EQ(cache_id, delegate.loaded_cache_id_);
123 EXPECT_EQ(cache.get(), delegate.loaded_cache_.get());
126 TEST_F(MockAppCacheStorageTest, CreateGroup) {
127 // Attempt to load/create a group that doesn't exist.
128 // Should complete asyncly.
129 MockAppCacheService service;
130 MockAppCacheStorage* storage =
131 reinterpret_cast<MockAppCacheStorage*>(service.storage());
132 MockStorageDelegate delegate;
133 GURL manifest_url("http://blah/");
134 service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
135 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
136 EXPECT_FALSE(delegate.loaded_group_.get());
137 base::RunLoop().RunUntilIdle(); // Do async task execution.
138 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
139 EXPECT_TRUE(delegate.loaded_group_.get());
140 EXPECT_TRUE(delegate.loaded_group_->HasOneRef());
141 EXPECT_FALSE(delegate.loaded_group_->newest_complete_cache());
142 EXPECT_TRUE(storage->stored_groups_.empty());
145 TEST_F(MockAppCacheStorageTest, LoadGroup_NearHit) {
146 // Attempt to load a group that is currently in use
147 // and does not require loading from disk. This
148 // load should complete syncly.
149 MockAppCacheService service;
150 MockStorageDelegate delegate;
152 // Setup some preconditions. Create a group that appears
153 // to be "unstored" and "currently in use".
154 GURL manifest_url("http://blah/");
155 service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
156 base::RunLoop().RunUntilIdle(); // Do async task execution.
157 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
158 EXPECT_TRUE(delegate.loaded_group_.get());
160 // Reset our delegate, and take a reference to the new group.
161 scoped_refptr<AppCacheGroup> group;
162 group.swap(delegate.loaded_group_);
163 delegate.loaded_manifest_url_ = GURL();
166 service.storage()->LoadOrCreateGroup(manifest_url, &delegate);
167 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
168 EXPECT_EQ(group.get(), delegate.loaded_group_.get());
171 TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) {
172 // Attempt to load a cache that is not currently in use
173 // and does require loading from disk. This
174 // load should complete asyncly.
175 MockAppCacheService service;
176 MockAppCacheStorage* storage =
177 reinterpret_cast<MockAppCacheStorage*>(service.storage());
179 // Setup some preconditions. Create a group and newest cache that
180 // appears to be "stored" and "not currently in use".
181 GURL manifest_url("http://blah/");
182 scoped_refptr<AppCacheGroup> group(
183 new AppCacheGroup(service.storage(), manifest_url, 111));
184 int64 cache_id = storage->NewCacheId();
185 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
186 cache->set_complete(true);
187 group->AddCache(cache.get());
188 storage->AddStoredGroup(group.get());
189 storage->AddStoredCache(cache.get());
191 // Drop the references from above so the only refs to these
192 // objects are from within the storage class. This is to make
193 // these objects appear as "not currently in use".
194 AppCache* cache_ptr = cache.get();
195 AppCacheGroup* group_ptr = group.get();
199 // Setup a delegate to receive completion callbacks.
200 MockStorageDelegate delegate;
202 // Conduct the cache load test.
203 EXPECT_NE(cache_id, delegate.loaded_cache_id_);
204 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get());
205 storage->LoadCache(cache_id, &delegate);
206 EXPECT_NE(cache_id, delegate.loaded_cache_id_);
207 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get());
208 base::RunLoop().RunUntilIdle(); // Do async task execution.
209 EXPECT_EQ(cache_id, delegate.loaded_cache_id_);
210 EXPECT_EQ(cache_ptr, delegate.loaded_cache_.get());
211 delegate.loaded_cache_ = NULL;
213 // Conduct the group load test.
214 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
215 EXPECT_FALSE(delegate.loaded_group_.get());
216 storage->LoadOrCreateGroup(manifest_url, &delegate);
217 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_);
218 EXPECT_FALSE(delegate.loaded_group_.get());
219 base::RunLoop().RunUntilIdle(); // Do async task execution.
220 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_);
221 EXPECT_EQ(group_ptr, delegate.loaded_group_.get());
224 TEST_F(MockAppCacheStorageTest, StoreNewGroup) {
225 // Store a group and its newest cache. Should complete asyncly.
226 MockAppCacheService service;
227 MockAppCacheStorage* storage =
228 reinterpret_cast<MockAppCacheStorage*>(service.storage());
230 // Setup some preconditions. Create a group and newest cache that
231 // appears to be "unstored".
232 GURL manifest_url("http://blah/");
233 scoped_refptr<AppCacheGroup> group(
234 new AppCacheGroup(service.storage(), manifest_url, 111));
235 int64 cache_id = storage->NewCacheId();
236 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
237 // Hold a ref to the cache simulate the UpdateJob holding that ref,
238 // and hold a ref to the group to simulate the CacheHost holding that ref.
240 // Conduct the store test.
241 MockStorageDelegate delegate;
242 EXPECT_TRUE(storage->stored_caches_.empty());
243 EXPECT_TRUE(storage->stored_groups_.empty());
244 storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate);
245 EXPECT_FALSE(delegate.stored_group_success_);
246 EXPECT_TRUE(storage->stored_caches_.empty());
247 EXPECT_TRUE(storage->stored_groups_.empty());
248 base::RunLoop().RunUntilIdle(); // Do async task execution.
249 EXPECT_TRUE(delegate.stored_group_success_);
250 EXPECT_FALSE(storage->stored_caches_.empty());
251 EXPECT_FALSE(storage->stored_groups_.empty());
252 EXPECT_EQ(cache, group->newest_complete_cache());
253 EXPECT_TRUE(cache->is_complete());
256 TEST_F(MockAppCacheStorageTest, StoreExistingGroup) {
257 // Store a group and its newest cache. Should complete asyncly.
258 MockAppCacheService service;
259 MockAppCacheStorage* storage =
260 reinterpret_cast<MockAppCacheStorage*>(service.storage());
262 // Setup some preconditions. Create a group and old complete cache
263 // that appear to be "stored", and a newest unstored complete cache.
264 GURL manifest_url("http://blah/");
265 scoped_refptr<AppCacheGroup> group(
266 new AppCacheGroup(service.storage(), manifest_url, 111));
267 int64 old_cache_id = storage->NewCacheId();
268 scoped_refptr<AppCache> old_cache(
269 new AppCache(service.storage(), old_cache_id));
270 old_cache->set_complete(true);
271 group->AddCache(old_cache.get());
272 storage->AddStoredGroup(group.get());
273 storage->AddStoredCache(old_cache.get());
274 int64 new_cache_id = storage->NewCacheId();
275 scoped_refptr<AppCache> new_cache(
276 new AppCache(service.storage(), new_cache_id));
277 // Hold our refs to simulate the UpdateJob holding these refs.
280 MockStorageDelegate delegate;
281 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
282 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
283 EXPECT_TRUE(storage->IsCacheStored(old_cache.get()));
284 EXPECT_FALSE(storage->IsCacheStored(new_cache.get()));
285 storage->StoreGroupAndNewestCache(group.get(), new_cache.get(), &delegate);
286 EXPECT_FALSE(delegate.stored_group_success_);
287 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
288 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
289 EXPECT_TRUE(storage->IsCacheStored(old_cache.get()));
290 EXPECT_FALSE(storage->IsCacheStored(new_cache.get()));
291 base::RunLoop().RunUntilIdle(); // Do async task execution.
292 EXPECT_TRUE(delegate.stored_group_success_);
293 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
294 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
295 EXPECT_FALSE(storage->IsCacheStored(old_cache.get()));
296 EXPECT_TRUE(storage->IsCacheStored(new_cache.get()));
297 EXPECT_EQ(new_cache.get(), group->newest_complete_cache());
298 EXPECT_TRUE(new_cache->is_complete());
301 TEST_F(MockAppCacheStorageTest, StoreExistingGroupExistingCache) {
302 // Store a group with updates to its existing newest complete cache.
303 MockAppCacheService service;
304 MockAppCacheStorage* storage =
305 reinterpret_cast<MockAppCacheStorage*>(service.storage());
307 // Setup some preconditions. Create a group and a complete cache that
308 // appear to be "stored".
309 GURL manifest_url("http://blah");
310 scoped_refptr<AppCacheGroup> group(
311 new AppCacheGroup(service.storage(), manifest_url, 111));
312 int64 cache_id = storage->NewCacheId();
313 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
314 cache->set_complete(true);
315 group->AddCache(cache.get());
316 storage->AddStoredGroup(group.get());
317 storage->AddStoredCache(cache.get());
318 // Hold our refs to simulate the UpdateJob holding these refs.
320 // Change the group's newest cache.
321 EXPECT_EQ(cache, group->newest_complete_cache());
322 GURL entry_url("http://blah/blah");
323 cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::MASTER));
326 MockStorageDelegate delegate;
327 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
328 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
329 EXPECT_TRUE(storage->IsCacheStored(cache.get()));
330 storage->StoreGroupAndNewestCache(group.get(), cache.get(), &delegate);
331 EXPECT_FALSE(delegate.stored_group_success_);
332 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
333 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
334 base::RunLoop().RunUntilIdle(); // Do async task execution.
335 EXPECT_TRUE(delegate.stored_group_success_);
336 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
337 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
338 EXPECT_TRUE(storage->IsCacheStored(cache.get()));
339 EXPECT_EQ(cache, group->newest_complete_cache());
340 EXPECT_TRUE(cache->GetEntry(entry_url));
343 TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) {
344 // Make a group obsolete, should complete asyncly.
345 MockAppCacheService service;
346 MockAppCacheStorage* storage =
347 reinterpret_cast<MockAppCacheStorage*>(service.storage());
349 // Setup some preconditions. Create a group and newest cache that
350 // appears to be "stored" and "currently in use".
351 GURL manifest_url("http://blah/");
352 scoped_refptr<AppCacheGroup> group(
353 new AppCacheGroup(service.storage(), manifest_url, 111));
354 int64 cache_id = storage->NewCacheId();
355 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
356 cache->set_complete(true);
357 group->AddCache(cache.get());
358 storage->AddStoredGroup(group.get());
359 storage->AddStoredCache(cache.get());
360 // Hold our refs to simulate the UpdateJob holding these refs.
363 MockStorageDelegate delegate;
364 EXPECT_FALSE(group->is_obsolete());
365 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
366 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
367 EXPECT_FALSE(cache->HasOneRef());
368 EXPECT_FALSE(group->HasOneRef());
369 storage->MakeGroupObsolete(group.get(), &delegate, 0);
370 EXPECT_FALSE(group->is_obsolete());
371 EXPECT_EQ(size_t(1), storage->stored_caches_.size());
372 EXPECT_EQ(size_t(1), storage->stored_groups_.size());
373 EXPECT_FALSE(cache->HasOneRef());
374 EXPECT_FALSE(group->HasOneRef());
375 base::RunLoop().RunUntilIdle(); // Do async task execution.
376 EXPECT_TRUE(delegate.obsoleted_success_);
377 EXPECT_EQ(group.get(), delegate.obsoleted_group_.get());
378 EXPECT_TRUE(group->is_obsolete());
379 EXPECT_TRUE(storage->stored_caches_.empty());
380 EXPECT_TRUE(storage->stored_groups_.empty());
381 EXPECT_TRUE(cache->HasOneRef());
382 EXPECT_FALSE(group->HasOneRef());
383 delegate.obsoleted_group_ = NULL;
385 EXPECT_TRUE(group->HasOneRef());
388 TEST_F(MockAppCacheStorageTest, MarkEntryAsForeign) {
389 // Should complete syncly.
390 MockAppCacheService service;
391 MockAppCacheStorage* storage =
392 reinterpret_cast<MockAppCacheStorage*>(service.storage());
394 // Setup some preconditions. Create a cache with an entry.
395 GURL entry_url("http://blah/entry");
396 int64 cache_id = storage->NewCacheId();
397 scoped_refptr<AppCache> cache(new AppCache(service.storage(), cache_id));
398 cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::EXPLICIT));
401 MockStorageDelegate delegate;
402 EXPECT_FALSE(cache->GetEntry(entry_url)->IsForeign());
403 storage->MarkEntryAsForeign(entry_url, cache_id);
404 EXPECT_TRUE(cache->GetEntry(entry_url)->IsForeign());
405 EXPECT_TRUE(cache->GetEntry(entry_url)->IsExplicit());
408 TEST_F(MockAppCacheStorageTest, FindNoMainResponse) {
409 // Should complete asyncly.
410 MockAppCacheService service;
411 MockAppCacheStorage* storage =
412 reinterpret_cast<MockAppCacheStorage*>(service.storage());
415 MockStorageDelegate delegate;
416 GURL url("http://blah/some_url");
417 EXPECT_NE(url, delegate.found_url_);
418 storage->FindResponseForMainRequest(url, GURL(), &delegate);
419 EXPECT_NE(url, delegate.found_url_);
420 base::RunLoop().RunUntilIdle(); // Do async task execution.
421 EXPECT_EQ(url, delegate.found_url_);
422 EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
423 EXPECT_EQ(kNoCacheId, delegate.found_cache_id_);
424 EXPECT_EQ(kNoResponseId, delegate.found_entry_.response_id());
425 EXPECT_EQ(kNoResponseId, delegate.found_fallback_entry_.response_id());
426 EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
427 EXPECT_EQ(0, delegate.found_entry_.types());
428 EXPECT_EQ(0, delegate.found_fallback_entry_.types());
431 TEST_F(MockAppCacheStorageTest, BasicFindMainResponse) {
432 // Should complete asyncly.
433 MockAppCacheService service;
434 MockAppCacheStorage* storage =
435 reinterpret_cast<MockAppCacheStorage*>(service.storage());
437 // Setup some preconditions. Create a complete cache with an entry.
438 const int64 kCacheId = storage->NewCacheId();
439 const GURL kEntryUrl("http://blah/entry");
440 const GURL kManifestUrl("http://blah/manifest");
441 const int64 kResponseId = 1;
442 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
444 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId));
445 cache->set_complete(true);
446 scoped_refptr<AppCacheGroup> group(
447 new AppCacheGroup(service.storage(), kManifestUrl, 111));
448 group->AddCache(cache.get());
449 storage->AddStoredGroup(group.get());
450 storage->AddStoredCache(cache.get());
453 MockStorageDelegate delegate;
454 EXPECT_NE(kEntryUrl, delegate.found_url_);
455 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
456 EXPECT_NE(kEntryUrl, delegate.found_url_);
457 base::RunLoop().RunUntilIdle(); // Do async task execution.
458 EXPECT_EQ(kEntryUrl, delegate.found_url_);
459 EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_);
460 EXPECT_EQ(kCacheId, delegate.found_cache_id_);
461 EXPECT_EQ(kResponseId, delegate.found_entry_.response_id());
462 EXPECT_TRUE(delegate.found_entry_.IsExplicit());
463 EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id());
466 TEST_F(MockAppCacheStorageTest, BasicFindMainFallbackResponse) {
467 // Should complete asyncly.
468 MockAppCacheService service;
469 MockAppCacheStorage* storage =
470 reinterpret_cast<MockAppCacheStorage*>(service.storage());
472 // Setup some preconditions. Create a complete cache with a
473 // fallback namespace and entry.
474 const int64 kCacheId = storage->NewCacheId();
475 const GURL kFallbackEntryUrl1("http://blah/fallback_entry1");
476 const GURL kFallbackNamespaceUrl1("http://blah/fallback_namespace/");
477 const GURL kFallbackEntryUrl2("http://blah/fallback_entry2");
478 const GURL kFallbackNamespaceUrl2("http://blah/fallback_namespace/longer");
479 const GURL kManifestUrl("http://blah/manifest");
480 const int64 kResponseId1 = 1;
481 const int64 kResponseId2 = 2;
484 manifest.fallback_namespaces.push_back(
485 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl1,
486 kFallbackEntryUrl1, false));
487 manifest.fallback_namespaces.push_back(
488 Namespace(FALLBACK_NAMESPACE, kFallbackNamespaceUrl2,
489 kFallbackEntryUrl2, false));
491 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
492 cache->InitializeWithManifest(&manifest);
493 cache->AddEntry(kFallbackEntryUrl1,
494 AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId1));
495 cache->AddEntry(kFallbackEntryUrl2,
496 AppCacheEntry(AppCacheEntry::FALLBACK, kResponseId2));
497 cache->set_complete(true);
499 scoped_refptr<AppCacheGroup> group(
500 new AppCacheGroup(service.storage(), kManifestUrl, 111));
501 group->AddCache(cache.get());
502 storage->AddStoredGroup(group.get());
503 storage->AddStoredCache(cache.get());
505 // The test url is in both fallback namespace urls, but should match
506 // the longer of the two.
507 const GURL kTestUrl("http://blah/fallback_namespace/longer/test");
510 MockStorageDelegate delegate;
511 EXPECT_NE(kTestUrl, delegate.found_url_);
512 storage->FindResponseForMainRequest(kTestUrl, GURL(), &delegate);
513 EXPECT_NE(kTestUrl, delegate.found_url_);
514 base::RunLoop().RunUntilIdle(); // Do async task execution.
515 EXPECT_EQ(kTestUrl, delegate.found_url_);
516 EXPECT_EQ(kManifestUrl, delegate.found_manifest_url_);
517 EXPECT_EQ(kCacheId, delegate.found_cache_id_);
518 EXPECT_FALSE(delegate.found_entry_.has_response_id());
519 EXPECT_EQ(kResponseId2, delegate.found_fallback_entry_.response_id());
520 EXPECT_EQ(kFallbackEntryUrl2, delegate.found_fallback_url_);
521 EXPECT_TRUE(delegate.found_fallback_entry_.IsFallback());
524 TEST_F(MockAppCacheStorageTest, FindMainResponseWithMultipleCandidates) {
525 // Should complete asyncly.
526 MockAppCacheService service;
527 MockAppCacheStorage* storage =
528 reinterpret_cast<MockAppCacheStorage*>(service.storage());
530 // Setup some preconditions. Create 2 complete caches with an entry
533 const GURL kEntryUrl("http://blah/entry");
534 const int64 kCacheId1 = storage->NewCacheId();
535 const int64 kCacheId2 = storage->NewCacheId();
536 const GURL kManifestUrl1("http://blah/manifest1");
537 const GURL kManifestUrl2("http://blah/manifest2");
538 const int64 kResponseId1 = 1;
539 const int64 kResponseId2 = 2;
542 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId1));
544 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId1));
545 cache->set_complete(true);
546 scoped_refptr<AppCacheGroup> group(
547 new AppCacheGroup(service.storage(), kManifestUrl1, 111));
548 group->AddCache(cache.get());
549 storage->AddStoredGroup(group.get());
550 storage->AddStoredCache(cache.get());
551 // Drop our references to cache1 so it appears as "not in use".
556 cache = new AppCache(service.storage(), kCacheId2);
558 kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, kResponseId2));
559 cache->set_complete(true);
560 group = new AppCacheGroup(service.storage(), kManifestUrl2, 222);
561 group->AddCache(cache.get());
562 storage->AddStoredGroup(group.get());
563 storage->AddStoredCache(cache.get());
565 // Conduct the test, we should find the response from the second cache
566 // since it's "in use".
567 MockStorageDelegate delegate;
568 EXPECT_NE(kEntryUrl, delegate.found_url_);
569 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
570 EXPECT_NE(kEntryUrl, delegate.found_url_);
571 base::RunLoop().RunUntilIdle(); // Do async task execution.
572 EXPECT_EQ(kEntryUrl, delegate.found_url_);
573 EXPECT_EQ(kManifestUrl2, delegate.found_manifest_url_);
574 EXPECT_EQ(kCacheId2, delegate.found_cache_id_);
575 EXPECT_EQ(kResponseId2, delegate.found_entry_.response_id());
576 EXPECT_TRUE(delegate.found_entry_.IsExplicit());
577 EXPECT_FALSE(delegate.found_fallback_entry_.has_response_id());
580 TEST_F(MockAppCacheStorageTest, FindMainResponseExclusions) {
581 // Should complete asyncly.
582 MockAppCacheService service;
583 MockAppCacheStorage* storage =
584 reinterpret_cast<MockAppCacheStorage*>(service.storage());
586 // Setup some preconditions. Create a complete cache with a
587 // foreign entry and an online namespace.
589 const int64 kCacheId = storage->NewCacheId();
590 const GURL kEntryUrl("http://blah/entry");
591 const GURL kManifestUrl("http://blah/manifest");
592 const GURL kOnlineNamespaceUrl("http://blah/online_namespace");
593 const int64 kResponseId = 1;
596 manifest.online_whitelist_namespaces.push_back(
597 Namespace(NETWORK_NAMESPACE, kOnlineNamespaceUrl,
599 scoped_refptr<AppCache> cache(new AppCache(service.storage(), kCacheId));
600 cache->InitializeWithManifest(&manifest);
603 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
605 cache->set_complete(true);
606 scoped_refptr<AppCacheGroup> group(
607 new AppCacheGroup(service.storage(), kManifestUrl, 111));
608 group->AddCache(cache.get());
609 storage->AddStoredGroup(group.get());
610 storage->AddStoredCache(cache.get());
612 MockStorageDelegate delegate;
614 // We should not find anything for the foreign entry.
615 EXPECT_NE(kEntryUrl, delegate.found_url_);
616 storage->FindResponseForMainRequest(kEntryUrl, GURL(), &delegate);
617 EXPECT_NE(kEntryUrl, delegate.found_url_);
618 base::RunLoop().RunUntilIdle(); // Do async task execution.
619 EXPECT_EQ(kEntryUrl, delegate.found_url_);
620 EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
621 EXPECT_EQ(kNoCacheId, delegate.found_cache_id_);
622 EXPECT_EQ(kNoResponseId, delegate.found_entry_.response_id());
623 EXPECT_EQ(kNoResponseId, delegate.found_fallback_entry_.response_id());
624 EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
625 EXPECT_EQ(0, delegate.found_entry_.types());
626 EXPECT_EQ(0, delegate.found_fallback_entry_.types());
628 // We should not find anything for the online namespace.
629 EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_);
630 storage->FindResponseForMainRequest(kOnlineNamespaceUrl, GURL(), &delegate);
631 EXPECT_NE(kOnlineNamespaceUrl, delegate.found_url_);
632 base::RunLoop().RunUntilIdle(); // Do async task execution.
633 EXPECT_EQ(kOnlineNamespaceUrl, delegate.found_url_);
634 EXPECT_TRUE(delegate.found_manifest_url_.is_empty());
635 EXPECT_EQ(kNoCacheId, delegate.found_cache_id_);
636 EXPECT_EQ(kNoResponseId, delegate.found_entry_.response_id());
637 EXPECT_EQ(kNoResponseId, delegate.found_fallback_entry_.response_id());
638 EXPECT_TRUE(delegate.found_fallback_url_.is_empty());
639 EXPECT_EQ(0, delegate.found_entry_.types());
640 EXPECT_EQ(0, delegate.found_fallback_entry_.types());
643 } // namespace content