blob: 1d874bc4ae8a76eabf013fe53ab898649c9424e1 [file] [log] [blame]
[email protected]035545f2010-04-09 13:10:211// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]35f2094c2009-12-29 22:46:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]80d42812010-02-09 10:30:255#include <stack>
6
[email protected]35f2094c2009-12-29 22:46:557#include "base/message_loop.h"
[email protected]34b99632011-01-01 01:01:068#include "base/threading/thread.h"
[email protected]44f9c952011-01-02 06:05:399#include "base/synchronization/waitable_event.h"
[email protected]ea776d022010-02-17 22:20:3610#include "net/base/net_errors.h"
[email protected]35f2094c2009-12-29 22:46:5511#include "testing/gtest/include/gtest/gtest.h"
12#include "webkit/appcache/appcache.h"
13#include "webkit/appcache/appcache_database.h"
14#include "webkit/appcache/appcache_entry.h"
15#include "webkit/appcache/appcache_group.h"
[email protected]ea776d022010-02-17 22:20:3616#include "webkit/appcache/appcache_policy.h"
[email protected]35f2094c2009-12-29 22:46:5517#include "webkit/appcache/appcache_service.h"
18#include "webkit/appcache/appcache_storage_impl.h"
19#include "webkit/tools/test_shell/simple_appcache_system.h"
20
21namespace appcache {
22
23namespace {
24
[email protected]ca25209a2010-02-23 20:39:0125const base::Time kZeroTime;
[email protected]35f2094c2009-12-29 22:46:5526const GURL kManifestUrl("http://blah/manifest");
27const GURL kManifestUrl2("http://blah/manifest2");
28const GURL kEntryUrl("http://blah/entry");
29const GURL kEntryUrl2("http://blah/entry2");
30const GURL kFallbackNamespace("http://blah/fallback_namespace/");
31const GURL kFallbackNamespace2("http://blah/fallback_namespace/longer");
32const GURL kFallbackTestUrl("http://blah/fallback_namespace/longer/test");
33const GURL kOnlineNamespace("http://blah/online_namespace");
[email protected]0b52f1c2010-11-19 03:12:1234const GURL kOnlineNamespaceWithinFallback(
35 "http://blah/fallback_namespace/online/");
[email protected]35f2094c2009-12-29 22:46:5536
37// For the duration of this test case, we hijack the AppCacheThread API
38// calls and implement them in terms of the io and db threads created here.
39
40scoped_ptr<base::Thread> io_thread;
41scoped_ptr<base::Thread> db_thread;
42
43class TestThreadProvider : public SimpleAppCacheSystem::ThreadProvider {
44 public:
45 virtual bool PostTask(
46 int id,
47 const tracked_objects::Location& from_here,
48 Task* task) {
49 GetMessageLoop(id)->PostTask(from_here, task);
50 return true;
51 }
52
53 virtual bool CurrentlyOn(int id) {
54 return MessageLoop::current() == GetMessageLoop(id);
55 }
56
57 MessageLoop* GetMessageLoop(int id) {
58 DCHECK(io_thread.get() && db_thread.get());
59 if (id == SimpleAppCacheSystem::IO_THREAD_ID)
60 return io_thread->message_loop();
61 if (id == SimpleAppCacheSystem::DB_THREAD_ID)
62 return db_thread->message_loop();
63 NOTREACHED() << "Invalid AppCacheThreadID value";
64 return NULL;
65 }
66};
67
68TestThreadProvider thread_provider;
69
70} // namespace
71
72class AppCacheStorageImplTest : public testing::Test {
73 public:
74 class MockStorageDelegate : public AppCacheStorage::Delegate {
75 public:
76 explicit MockStorageDelegate(AppCacheStorageImplTest* test)
77 : loaded_cache_id_(0), stored_group_success_(false),
[email protected]bae30692010-08-04 20:01:3778 would_exceed_quota_(false), obsoleted_success_(false),
79 found_cache_id_(kNoCacheId), found_blocked_by_policy_(false),
80 test_(test) {
[email protected]35f2094c2009-12-29 22:46:5581 }
82
83 void OnCacheLoaded(AppCache* cache, int64 cache_id) {
84 loaded_cache_ = cache;
85 loaded_cache_id_ = cache_id;
86 test_->ScheduleNextTask();
87 }
88
89 void OnGroupLoaded(AppCacheGroup* group, const GURL& manifest_url) {
90 loaded_group_ = group;
91 loaded_manifest_url_ = manifest_url;
92 loaded_groups_newest_cache_ = group ? group->newest_complete_cache()
93 : NULL;
94 test_->ScheduleNextTask();
95 }
96
[email protected]dcd3de722010-01-24 01:38:3697 void OnGroupAndNewestCacheStored(
[email protected]4f323032010-08-03 01:26:1098 AppCacheGroup* group, AppCache* newest_cache, bool success,
99 bool would_exceed_quota) {
[email protected]35f2094c2009-12-29 22:46:55100 stored_group_ = group;
101 stored_group_success_ = success;
[email protected]bae30692010-08-04 20:01:37102 would_exceed_quota_ = would_exceed_quota;
[email protected]35f2094c2009-12-29 22:46:55103 test_->ScheduleNextTask();
104 }
105
106 void OnGroupMadeObsolete(AppCacheGroup* group, bool success) {
107 obsoleted_group_ = group;
108 obsoleted_success_ = success;
109 test_->ScheduleNextTask();
110 }
111
112 void OnMainResponseFound(const GURL& url, const AppCacheEntry& entry,
[email protected]6ed2a5a52010-11-03 02:29:14113 const GURL& fallback_url,
[email protected]35f2094c2009-12-29 22:46:55114 const AppCacheEntry& fallback_entry,
[email protected]035545f2010-04-09 13:10:21115 int64 cache_id, const GURL& manifest_url,
116 bool was_blocked_by_policy) {
[email protected]35f2094c2009-12-29 22:46:55117 found_url_ = url;
118 found_entry_ = entry;
[email protected]6ed2a5a52010-11-03 02:29:14119 found_fallback_url_ = fallback_url;
[email protected]35f2094c2009-12-29 22:46:55120 found_fallback_entry_ = fallback_entry;
121 found_cache_id_ = cache_id;
122 found_manifest_url_ = manifest_url;
[email protected]5c7d5982010-07-12 09:12:59123 found_blocked_by_policy_ = was_blocked_by_policy;
[email protected]35f2094c2009-12-29 22:46:55124 test_->ScheduleNextTask();
125 }
126
127 scoped_refptr<AppCache> loaded_cache_;
128 int64 loaded_cache_id_;
129 scoped_refptr<AppCacheGroup> loaded_group_;
130 GURL loaded_manifest_url_;
131 scoped_refptr<AppCache> loaded_groups_newest_cache_;
132 scoped_refptr<AppCacheGroup> stored_group_;
133 bool stored_group_success_;
[email protected]bae30692010-08-04 20:01:37134 bool would_exceed_quota_;
[email protected]35f2094c2009-12-29 22:46:55135 scoped_refptr<AppCacheGroup> obsoleted_group_;
136 bool obsoleted_success_;
137 GURL found_url_;
138 AppCacheEntry found_entry_;
[email protected]6ed2a5a52010-11-03 02:29:14139 GURL found_fallback_url_;
[email protected]35f2094c2009-12-29 22:46:55140 AppCacheEntry found_fallback_entry_;
141 int64 found_cache_id_;
142 GURL found_manifest_url_;
[email protected]5c7d5982010-07-12 09:12:59143 bool found_blocked_by_policy_;
[email protected]35f2094c2009-12-29 22:46:55144 AppCacheStorageImplTest* test_;
145 };
146
[email protected]ea776d022010-02-17 22:20:36147 class MockAppCachePolicy : public AppCachePolicy {
148 public:
149 explicit MockAppCachePolicy(AppCacheStorageImplTest* test)
150 : can_load_return_value_(true), can_create_return_value_(0),
151 callback_(NULL), test_(test) {
152 }
153
154 virtual bool CanLoadAppCache(const GURL& manifest_url) {
155 requested_manifest_url_ = manifest_url;
156 return can_load_return_value_;
157 }
158
159 virtual int CanCreateAppCache(const GURL& manifest_url,
160 net::CompletionCallback* callback) {
161 requested_manifest_url_ = manifest_url;
162 callback_ = callback;
163 if (can_create_return_value_ == net::ERR_IO_PENDING)
164 test_->ScheduleNextTask();
165 return can_create_return_value_;
166 }
167
168 bool can_load_return_value_;
169 int can_create_return_value_;
170 GURL requested_manifest_url_;
171 net::CompletionCallback* callback_;
172 AppCacheStorageImplTest* test_;
173 };
174
[email protected]35f2094c2009-12-29 22:46:55175 // Helper class run a test on our io_thread. The io_thread
176 // is spun up once and reused for all tests.
177 template <class Method>
178 class WrapperTask : public Task {
179 public:
180 WrapperTask(AppCacheStorageImplTest* test, Method method)
181 : test_(test), method_(method) {
182 }
183
184 virtual void Run() {
185 test_->SetUpTest();
186
187 // Ensure InitTask execution prior to conducting a test.
188 test_->FlushDbThreadTasks();
189
190 // We also have to wait for InitTask completion call to be performed
191 // on the IO thread prior to running the test. Its guaranteed to be
192 // queued by this time.
193 MessageLoop::current()->PostTask(FROM_HERE,
194 NewRunnableFunction(&RunMethod, test_, method_));
195 }
196
197 static void RunMethod(AppCacheStorageImplTest* test, Method method) {
198 (test->*method)();
199 }
200
201 private:
202 AppCacheStorageImplTest* test_;
203 Method method_;
204 };
205
206
207 static void SetUpTestCase() {
208 io_thread.reset(new base::Thread("AppCacheTest.IOThread"));
209 base::Thread::Options options(MessageLoop::TYPE_IO, 0);
210 ASSERT_TRUE(io_thread->StartWithOptions(options));
211
212 db_thread.reset(new base::Thread("AppCacheTest::DBThread"));
213 ASSERT_TRUE(db_thread->Start());
214
215 SimpleAppCacheSystem::set_thread_provider(&thread_provider);
216 }
217
218 static void TearDownTestCase() {
219 SimpleAppCacheSystem::set_thread_provider(NULL);
220 io_thread.reset(NULL);
221 db_thread.reset(NULL);
222 }
223
224 // Test harness --------------------------------------------------
225
226 AppCacheStorageImplTest()
[email protected]79b15b22010-05-19 00:38:56227 : ALLOW_THIS_IN_INITIALIZER_LIST(policy_(this)) {
[email protected]35f2094c2009-12-29 22:46:55228 }
229
230 template <class Method>
231 void RunTestOnIOThread(Method method) {
232 test_finished_event_ .reset(new base::WaitableEvent(false, false));
233 io_thread->message_loop()->PostTask(
234 FROM_HERE, new WrapperTask<Method>(this, method));
235 test_finished_event_->Wait();
236 }
237
238 void SetUpTest() {
239 DCHECK(MessageLoop::current() == io_thread->message_loop());
240 service_.reset(new AppCacheService);
[email protected]f5ad47a12010-06-07 22:42:01241 service_->Initialize(FilePath(), NULL);
[email protected]35f2094c2009-12-29 22:46:55242 delegate_.reset(new MockStorageDelegate(this));
243 }
244
245 void TearDownTest() {
246 DCHECK(MessageLoop::current() == io_thread->message_loop());
247 storage()->CancelDelegateCallbacks(delegate());
248 group_ = NULL;
249 cache_ = NULL;
250 cache2_ = NULL;
251 delegate_.reset();
252 service_.reset();
253 FlushDbThreadTasks();
254 }
255
256 void TestFinished() {
257 // We unwind the stack prior to finishing up to let stack
258 // based objects get deleted.
259 DCHECK(MessageLoop::current() == io_thread->message_loop());
260 MessageLoop::current()->PostTask(FROM_HERE,
[email protected]79b15b22010-05-19 00:38:56261 NewRunnableMethod(this, &AppCacheStorageImplTest::TestFinishedUnwound));
[email protected]35f2094c2009-12-29 22:46:55262 }
263
264 void TestFinishedUnwound() {
265 TearDownTest();
266 test_finished_event_->Signal();
267 }
268
269 void PushNextTask(Task* task) {
270 task_stack_.push(task);
271 }
272
273 void ScheduleNextTask() {
274 DCHECK(MessageLoop::current() == io_thread->message_loop());
275 if (task_stack_.empty()) {
276 return;
277 }
278 MessageLoop::current()->PostTask(FROM_HERE, task_stack_.top());
279 task_stack_.pop();
280 }
281
282 static void SignalEvent(base::WaitableEvent* event) {
283 event->Signal();
284 }
285
286 void FlushDbThreadTasks() {
287 // We pump a task thru the db thread to ensure any tasks previously
288 // scheduled on that thread have been performed prior to return.
289 base::WaitableEvent event(false, false);
290 db_thread->message_loop()->PostTask(FROM_HERE,
291 NewRunnableFunction(&AppCacheStorageImplTest::SignalEvent,
292 &event));
293 event.Wait();
294 }
295
296 // LoadCache_Miss ----------------------------------------------------
297
298 void LoadCache_Miss() {
299 // Attempt to load a cache that doesn't exist. Should
300 // complete asyncly.
[email protected]79b15b22010-05-19 00:38:56301 PushNextTask(NewRunnableMethod(
302 this, &AppCacheStorageImplTest::Verify_LoadCache_Miss));
[email protected]35f2094c2009-12-29 22:46:55303
304 storage()->LoadCache(111, delegate());
305 EXPECT_NE(111, delegate()->loaded_cache_id_);
306 }
307
308 void Verify_LoadCache_Miss() {
309 EXPECT_EQ(111, delegate()->loaded_cache_id_);
310 EXPECT_FALSE(delegate()->loaded_cache_);
311 TestFinished();
312 }
313
314 // LoadCache_NearHit -------------------------------------------------
315
316 void LoadCache_NearHit() {
317 // Attempt to load a cache that is currently in use
318 // and does not require loading from storage. This
319 // load should complete syncly.
320
321 // Setup some preconditions. Make an 'unstored' cache for
322 // us to load. The ctor should put it in the working set.
323 int64 cache_id = storage()->NewCacheId();
[email protected]ad8e04a2010-11-01 04:16:27324 scoped_refptr<AppCache> cache(new AppCache(service(), cache_id));
[email protected]35f2094c2009-12-29 22:46:55325
326 // Conduct the test.
327 storage()->LoadCache(cache_id, delegate());
328 EXPECT_EQ(cache_id, delegate()->loaded_cache_id_);
329 EXPECT_EQ(cache.get(), delegate()->loaded_cache_.get());
330 TestFinished();
331 }
332
333 // CreateGroup --------------------------------------------
334
335 void CreateGroupInEmptyOrigin() {
336 // Attempt to load a group that doesn't exist, one should
337 // be created for us, but not stored.
338
339 // Since the origin has no groups, the storage class will respond
340 // syncly.
341 storage()->LoadOrCreateGroup(kManifestUrl, delegate());
342 Verify_CreateGroup();
343 }
344
345 void CreateGroupInPopulatedOrigin() {
346 // Attempt to load a group that doesn't exist, one should
347 // be created for us, but not stored.
[email protected]79b15b22010-05-19 00:38:56348 PushNextTask(NewRunnableMethod(
349 this, &AppCacheStorageImplTest::Verify_CreateGroup));
[email protected]35f2094c2009-12-29 22:46:55350
351 // Since the origin has groups, storage class will have to
352 // consult the database and completion will be async.
353 storage()->origins_with_groups_.insert(kManifestUrl.GetOrigin());
354
355 storage()->LoadOrCreateGroup(kManifestUrl, delegate());
356 EXPECT_FALSE(delegate()->loaded_group_.get());
357 }
358
359 void Verify_CreateGroup() {
360 EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_);
361 EXPECT_TRUE(delegate()->loaded_group_.get());
362 EXPECT_TRUE(delegate()->loaded_group_->HasOneRef());
363 EXPECT_FALSE(delegate()->loaded_group_->newest_complete_cache());
364
365 // Should not have been stored in the database.
366 AppCacheDatabase::GroupRecord record;
367 EXPECT_FALSE(database()->FindGroup(
368 delegate()->loaded_group_->group_id(), &record));
369
370 TestFinished();
371 }
372
373 // LoadGroupAndCache_FarHit --------------------------------------
374
375 void LoadGroupAndCache_FarHit() {
376 // Attempt to load a cache that is not currently in use
377 // and does require loading from disk. This
378 // load should complete asyncly.
[email protected]79b15b22010-05-19 00:38:56379 PushNextTask(NewRunnableMethod(
380 this, &AppCacheStorageImplTest::Verify_LoadCache_Far_Hit));
[email protected]35f2094c2009-12-29 22:46:55381
382 // Setup some preconditions. Create a group and newest cache that
383 // appear to be "stored" and "not currently in use".
384 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
385 group_ = NULL;
386 cache_ = NULL;
387
388 // Conduct the cache load test, completes async
389 storage()->LoadCache(1, delegate());
390 }
391
392 void Verify_LoadCache_Far_Hit() {
393 EXPECT_TRUE(delegate()->loaded_cache_);
394 EXPECT_TRUE(delegate()->loaded_cache_->HasOneRef());
395 EXPECT_EQ(1, delegate()->loaded_cache_id_);
396
397 // The group should also have been loaded.
398 EXPECT_TRUE(delegate()->loaded_cache_->owning_group());
399 EXPECT_TRUE(delegate()->loaded_cache_->owning_group()->HasOneRef());
400 EXPECT_EQ(1, delegate()->loaded_cache_->owning_group()->group_id());
401
402 // Drop things from the working set.
403 delegate()->loaded_cache_ = NULL;
404 EXPECT_FALSE(delegate()->loaded_group_);
405
406 // Conduct the group load test, also complete asyncly.
[email protected]79b15b22010-05-19 00:38:56407 PushNextTask(NewRunnableMethod(
408 this, &AppCacheStorageImplTest::Verify_LoadGroup_Far_Hit));
[email protected]35f2094c2009-12-29 22:46:55409
410 storage()->LoadOrCreateGroup(kManifestUrl, delegate());
411 }
412
413 void Verify_LoadGroup_Far_Hit() {
414 EXPECT_TRUE(delegate()->loaded_group_);
415 EXPECT_EQ(kManifestUrl, delegate()->loaded_manifest_url_);
416 EXPECT_TRUE(delegate()->loaded_group_->newest_complete_cache());
417 delegate()->loaded_groups_newest_cache_ = NULL;
418 EXPECT_TRUE(delegate()->loaded_group_->HasOneRef());
419 TestFinished();
420 }
421
422 // StoreNewGroup --------------------------------------
423
424 void StoreNewGroup() {
425 // Store a group and its newest cache. Should complete asyncly.
[email protected]79b15b22010-05-19 00:38:56426 PushNextTask(NewRunnableMethod(
427 this, &AppCacheStorageImplTest::Verify_StoreNewGroup));
[email protected]35f2094c2009-12-29 22:46:55428
429 // Setup some preconditions. Create a group and newest cache that
430 // appear to be "unstored".
431 group_ = new AppCacheGroup(
432 service(), kManifestUrl, storage()->NewGroupId());
433 cache_ = new AppCache(service(), storage()->NewCacheId());
[email protected]35f2094c2009-12-29 22:46:55434 // Hold a ref to the cache simulate the UpdateJob holding that ref,
435 // and hold a ref to the group to simulate the CacheHost holding that ref.
436
437 // Conduct the store test.
438 storage()->StoreGroupAndNewestCache(group_, cache_, delegate());
439 EXPECT_FALSE(delegate()->stored_group_success_);
440 }
441
442 void Verify_StoreNewGroup() {
443 EXPECT_TRUE(delegate()->stored_group_success_);
444 EXPECT_EQ(group_.get(), delegate()->stored_group_.get());
445 EXPECT_EQ(cache_.get(), group_->newest_complete_cache());
[email protected]9b7a0c52010-01-21 02:39:40446 EXPECT_TRUE(cache_->is_complete());
[email protected]35f2094c2009-12-29 22:46:55447
448 // Should have been stored in the database.
449 AppCacheDatabase::GroupRecord group_record;
450 AppCacheDatabase::CacheRecord cache_record;
451 EXPECT_TRUE(database()->FindGroup(group_->group_id(), &group_record));
452 EXPECT_TRUE(database()->FindCache(cache_->cache_id(), &cache_record));
453 TestFinished();
454 }
455
456 // StoreExistingGroup --------------------------------------
457
458 void StoreExistingGroup() {
459 // Store a group and its newest cache. Should complete asyncly.
[email protected]79b15b22010-05-19 00:38:56460 PushNextTask(NewRunnableMethod(
461 this, &AppCacheStorageImplTest::Verify_StoreExistingGroup));
[email protected]35f2094c2009-12-29 22:46:55462
463 // Setup some preconditions. Create a group and old complete cache
464 // that appear to be "stored"
465 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
466
467 // And a newest unstored complete cache.
468 cache2_ = new AppCache(service(), 2);
[email protected]35f2094c2009-12-29 22:46:55469
470 // Conduct the test.
471 storage()->StoreGroupAndNewestCache(group_, cache2_, delegate());
472 EXPECT_FALSE(delegate()->stored_group_success_);
473 }
474
475 void Verify_StoreExistingGroup() {
476 EXPECT_TRUE(delegate()->stored_group_success_);
477 EXPECT_EQ(group_.get(), delegate()->stored_group_.get());
478 EXPECT_EQ(cache2_.get(), group_->newest_complete_cache());
[email protected]9b7a0c52010-01-21 02:39:40479 EXPECT_TRUE(cache2_->is_complete());
[email protected]35f2094c2009-12-29 22:46:55480
481 // The new cache should have been stored in the database.
482 AppCacheDatabase::GroupRecord group_record;
483 AppCacheDatabase::CacheRecord cache_record;
484 EXPECT_TRUE(database()->FindGroup(1, &group_record));
485 EXPECT_TRUE(database()->FindCache(2, &cache_record));
486
487 // The old cache should have been deleted
488 EXPECT_FALSE(database()->FindCache(1, &cache_record));
489 TestFinished();
490 }
491
492 // StoreExistingGroupExistingCache -------------------------------
493
494 void StoreExistingGroupExistingCache() {
495 // Store a group with updates to its existing newest complete cache.
496 // Setup some preconditions. Create a group and a complete cache that
497 // appear to be "stored".
498
499 // Setup some preconditions. Create a group and old complete cache
500 // that appear to be "stored"
501 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
502
503 // Change the cache.
[email protected]ca25209a2010-02-23 20:39:01504 base::Time now = base::Time::Now();
[email protected]0dfeec32010-01-06 22:25:33505 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::MASTER, 1, 100));
[email protected]35f2094c2009-12-29 22:46:55506 cache_->set_update_time(now);
507
[email protected]79b15b22010-05-19 00:38:56508 PushNextTask(NewRunnableMethod(
509 this, &AppCacheStorageImplTest::Verify_StoreExistingGroupExistingCache,
[email protected]35f2094c2009-12-29 22:46:55510 now));
511
512 // Conduct the test.
513 EXPECT_EQ(cache_, group_->newest_complete_cache());
514 storage()->StoreGroupAndNewestCache(group_, cache_, delegate());
515 EXPECT_FALSE(delegate()->stored_group_success_);
516 }
517
518 void Verify_StoreExistingGroupExistingCache(
[email protected]ca25209a2010-02-23 20:39:01519 base::Time expected_update_time) {
[email protected]35f2094c2009-12-29 22:46:55520 EXPECT_TRUE(delegate()->stored_group_success_);
521 EXPECT_EQ(cache_, group_->newest_complete_cache());
522
523 AppCacheDatabase::CacheRecord cache_record;
524 EXPECT_TRUE(database()->FindCache(1, &cache_record));
525 EXPECT_EQ(1, cache_record.cache_id);
526 EXPECT_EQ(1, cache_record.group_id);
527 EXPECT_FALSE(cache_record.online_wildcard);
528 EXPECT_TRUE(expected_update_time == cache_record.update_time);
[email protected]0dfeec32010-01-06 22:25:33529 EXPECT_EQ(100, cache_record.cache_size);
[email protected]35f2094c2009-12-29 22:46:55530
531 std::vector<AppCacheDatabase::EntryRecord> entry_records;
532 EXPECT_TRUE(database()->FindEntriesForCache(1, &entry_records));
533 EXPECT_EQ(1U, entry_records.size());
534 EXPECT_EQ(1 , entry_records[0].cache_id);
535 EXPECT_EQ(kEntryUrl, entry_records[0].url);
536 EXPECT_EQ(AppCacheEntry::MASTER, entry_records[0].flags);
[email protected]0dfeec32010-01-06 22:25:33537 EXPECT_EQ(1, entry_records[0].response_id);
538 EXPECT_EQ(100, entry_records[0].response_size);
[email protected]35f2094c2009-12-29 22:46:55539
540 TestFinished();
541 }
542
[email protected]bae30692010-08-04 20:01:37543 // FailStoreGroup --------------------------------------
544
545 void FailStoreGroup() {
546 // Store a group and its newest cache. Should complete asyncly.
547 PushNextTask(NewRunnableMethod(
548 this, &AppCacheStorageImplTest::Verify_FailStoreGroup));
549
[email protected]bae30692010-08-04 20:01:37550 // Setup some preconditions. Create a group and newest cache that
[email protected]19eb80152011-02-26 00:28:43551 // appear to be "unstored" and big enough to exceed the 5M limit.
552 const int64 kTooBig = 10 * 1024 * 1024; // 10M
[email protected]bae30692010-08-04 20:01:37553 group_ = new AppCacheGroup(
554 service(), kManifestUrl, storage()->NewGroupId());
555 cache_ = new AppCache(service(), storage()->NewCacheId());
556 cache_->AddEntry(kManifestUrl,
[email protected]19eb80152011-02-26 00:28:43557 AppCacheEntry(AppCacheEntry::MANIFEST, 1, kTooBig));
[email protected]bae30692010-08-04 20:01:37558 // Hold a ref to the cache simulate the UpdateJob holding that ref,
559 // and hold a ref to the group to simulate the CacheHost holding that ref.
560
561 // Conduct the store test.
562 storage()->StoreGroupAndNewestCache(group_, cache_, delegate());
563 EXPECT_FALSE(delegate()->stored_group_success_); // Expected to be async.
564 }
565
566 void Verify_FailStoreGroup() {
567 EXPECT_FALSE(delegate()->stored_group_success_);
568 EXPECT_TRUE(delegate()->would_exceed_quota_);
569
570 // Should not have been stored in the database.
571 AppCacheDatabase::GroupRecord group_record;
572 AppCacheDatabase::CacheRecord cache_record;
573 EXPECT_FALSE(database()->FindGroup(group_->group_id(), &group_record));
574 EXPECT_FALSE(database()->FindCache(cache_->cache_id(), &cache_record));
575
[email protected]bae30692010-08-04 20:01:37576 TestFinished();
577 }
578
[email protected]35f2094c2009-12-29 22:46:55579 // MakeGroupObsolete -------------------------------
580
581 void MakeGroupObsolete() {
582 // Make a group obsolete, should complete asyncly.
[email protected]79b15b22010-05-19 00:38:56583 PushNextTask(NewRunnableMethod(
584 this, &AppCacheStorageImplTest::Verify_MakeGroupObsolete));
[email protected]35f2094c2009-12-29 22:46:55585
586 // Setup some preconditions. Create a group and newest cache that
587 // appears to be "stored" and "currently in use".
588 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
589 EXPECT_FALSE(storage()->origins_with_groups_.empty());
590
591 // Also insert some related records.
592 AppCacheDatabase::EntryRecord entry_record;
593 entry_record.cache_id = 1;
594 entry_record.flags = AppCacheEntry::FALLBACK;
595 entry_record.response_id = 1;
596 entry_record.url = kEntryUrl;
597 EXPECT_TRUE(database()->InsertEntry(&entry_record));
598
599 AppCacheDatabase::FallbackNameSpaceRecord fallback_namespace_record;
600 fallback_namespace_record.cache_id = 1;
601 fallback_namespace_record.fallback_entry_url = kEntryUrl;
602 fallback_namespace_record.namespace_url = kFallbackNamespace;
603 fallback_namespace_record.origin = kManifestUrl.GetOrigin();
604 EXPECT_TRUE(
605 database()->InsertFallbackNameSpace(&fallback_namespace_record));
606
607 AppCacheDatabase::OnlineWhiteListRecord online_whitelist_record;
608 online_whitelist_record.cache_id = 1;
609 online_whitelist_record.namespace_url = kOnlineNamespace;
610 EXPECT_TRUE(database()->InsertOnlineWhiteList(&online_whitelist_record));
611
612 // Conduct the test.
613 storage()->MakeGroupObsolete(group_, delegate());
614 EXPECT_FALSE(group_->is_obsolete());
615 }
616
617 void Verify_MakeGroupObsolete() {
618 EXPECT_TRUE(delegate()->obsoleted_success_);
619 EXPECT_EQ(group_.get(), delegate()->obsoleted_group_.get());
620 EXPECT_TRUE(group_->is_obsolete());
621 EXPECT_TRUE(storage()->origins_with_groups_.empty());
622
623 // The cache and group have been deleted from the database.
624 AppCacheDatabase::GroupRecord group_record;
625 AppCacheDatabase::CacheRecord cache_record;
626 EXPECT_FALSE(database()->FindGroup(1, &group_record));
627 EXPECT_FALSE(database()->FindCache(1, &cache_record));
628
629 // The related records should have been deleted too.
630 std::vector<AppCacheDatabase::EntryRecord> entry_records;
631 database()->FindEntriesForCache(1, &entry_records);
632 EXPECT_TRUE(entry_records.empty());
633 std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallback_records;
634 database()->FindFallbackNameSpacesForCache(1, &fallback_records);
635 EXPECT_TRUE(fallback_records.empty());
636 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelist_records;
637 database()->FindOnlineWhiteListForCache(1, &whitelist_records);
638 EXPECT_TRUE(whitelist_records.empty());
639
640 TestFinished();
641 }
642
643 // MarkEntryAsForeign -------------------------------
644
645 void MarkEntryAsForeign() {
646 // Setup some preconditions. Create a cache with an entry
647 // in storage and in the working set.
648 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
649 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT));
650 AppCacheDatabase::EntryRecord entry_record;
651 entry_record.cache_id = 1;
652 entry_record.url = kEntryUrl;
653 entry_record.flags = AppCacheEntry::EXPLICIT;
654 entry_record.response_id = 0;
655 EXPECT_TRUE(database()->InsertEntry(&entry_record));
656 EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign());
657
658 // Conduct the test.
659 storage()->MarkEntryAsForeign(kEntryUrl, 1);
660
661 // The entry in the working set should have been updated syncly.
662 EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsForeign());
663 EXPECT_TRUE(cache_->GetEntry(kEntryUrl)->IsExplicit());
664
665 // And the entry in storage should also be updated, but that
666 // happens asyncly on the db thread.
667 FlushDbThreadTasks();
668 AppCacheDatabase::EntryRecord entry_record2;
669 EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record2));
670 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
671 entry_record2.flags);
672 TestFinished();
673 }
674
675 // MarkEntryAsForeignWithLoadInProgress -------------------------------
676
677 void MarkEntryAsForeignWithLoadInProgress() {
[email protected]79b15b22010-05-19 00:38:56678 PushNextTask(NewRunnableMethod(this,
[email protected]35f2094c2009-12-29 22:46:55679 &AppCacheStorageImplTest::Verify_MarkEntryAsForeignWithLoadInProgress));
680
681 // Setup some preconditions. Create a cache with an entry
682 // in storage, but not in the working set.
683 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
684 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT));
685 AppCacheDatabase::EntryRecord entry_record;
686 entry_record.cache_id = 1;
687 entry_record.url = kEntryUrl;
688 entry_record.flags = AppCacheEntry::EXPLICIT;
689 entry_record.response_id = 0;
690 EXPECT_TRUE(database()->InsertEntry(&entry_record));
691 EXPECT_FALSE(cache_->GetEntry(kEntryUrl)->IsForeign());
692 EXPECT_TRUE(cache_->HasOneRef());
693 cache_ = NULL;
694 group_ = NULL;
695
696 // Conduct the test, start a cache load, and prior to completion
697 // of that load, mark the entry as foreign.
698 storage()->LoadCache(1, delegate());
699 storage()->MarkEntryAsForeign(kEntryUrl, 1);
700 }
701
702 void Verify_MarkEntryAsForeignWithLoadInProgress() {
703 EXPECT_EQ(1, delegate()->loaded_cache_id_);
704 EXPECT_TRUE(delegate()->loaded_cache_.get());
705
706 // The entry in the working set should have been updated upon load.
707 EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsForeign());
708 EXPECT_TRUE(delegate()->loaded_cache_->GetEntry(kEntryUrl)->IsExplicit());
709
710 // And the entry in storage should also be updated.
711 FlushDbThreadTasks();
712 AppCacheDatabase::EntryRecord entry_record;
713 EXPECT_TRUE(database()->FindEntry(1, kEntryUrl, &entry_record));
714 EXPECT_EQ(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN,
715 entry_record.flags);
716 TestFinished();
717 }
718
719 // FindNoMainResponse -------------------------------
720
721 void FindNoMainResponse() {
[email protected]79b15b22010-05-19 00:38:56722 PushNextTask(NewRunnableMethod(
723 this, &AppCacheStorageImplTest::Verify_FindNoMainResponse));
[email protected]35f2094c2009-12-29 22:46:55724
725 // Conduct the test.
726 storage()->FindResponseForMainRequest(kEntryUrl, delegate());
727 EXPECT_NE(kEntryUrl, delegate()->found_url_);
728 }
729
730 void Verify_FindNoMainResponse() {
731 EXPECT_EQ(kEntryUrl, delegate()->found_url_);
[email protected]5c7d5982010-07-12 09:12:59732 // If the request was blocked by a policy, the manifest url is still valid.
733 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty() ||
734 delegate()->found_blocked_by_policy_);
[email protected]35f2094c2009-12-29 22:46:55735 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_);
736 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id());
737 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id());
[email protected]6ed2a5a52010-11-03 02:29:14738 EXPECT_TRUE(delegate()->found_fallback_url_.is_empty());
[email protected]35f2094c2009-12-29 22:46:55739 EXPECT_EQ(0, delegate()->found_entry_.types());
740 EXPECT_EQ(0, delegate()->found_fallback_entry_.types());
741 TestFinished();
742 }
743
744 // BasicFindMainResponse -------------------------------
745
746 void BasicFindMainResponseInDatabase() {
[email protected]ea776d022010-02-17 22:20:36747 BasicFindMainResponse(true, false);
[email protected]35f2094c2009-12-29 22:46:55748 }
749
750 void BasicFindMainResponseInWorkingSet() {
[email protected]ea776d022010-02-17 22:20:36751 BasicFindMainResponse(false, false);
[email protected]35f2094c2009-12-29 22:46:55752 }
753
[email protected]ea776d022010-02-17 22:20:36754 void BlockFindMainResponseWithPolicyCheck() {
755 BasicFindMainResponse(true, true);
756 }
757
758 void BasicFindMainResponse(bool drop_from_working_set,
759 bool block_with_policy_check) {
[email protected]79b15b22010-05-19 00:38:56760 PushNextTask(NewRunnableMethod(
761 this, &AppCacheStorageImplTest::Verify_BasicFindMainResponse));
[email protected]35f2094c2009-12-29 22:46:55762
[email protected]ea776d022010-02-17 22:20:36763 policy_.can_load_return_value_ = !block_with_policy_check;
764 service()->set_appcache_policy(&policy_);
765
[email protected]35f2094c2009-12-29 22:46:55766 // Setup some preconditions. Create a complete cache with an entry
767 // in storage.
768 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
769 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1));
770 AppCacheDatabase::EntryRecord entry_record;
771 entry_record.cache_id = 1;
772 entry_record.url = kEntryUrl;
773 entry_record.flags = AppCacheEntry::EXPLICIT;
774 entry_record.response_id = 1;
775 EXPECT_TRUE(database()->InsertEntry(&entry_record));
776
777 // Optionally drop the cache/group pair from the working set.
778 if (drop_from_working_set) {
779 EXPECT_TRUE(cache_->HasOneRef());
780 cache_ = NULL;
781 EXPECT_TRUE(group_->HasOneRef());
782 group_ = NULL;
783 }
784
785 // Conduct the test.
786 storage()->FindResponseForMainRequest(kEntryUrl, delegate());
787 EXPECT_NE(kEntryUrl, delegate()->found_url_);
788 }
789
790 void Verify_BasicFindMainResponse() {
[email protected]ea776d022010-02-17 22:20:36791 EXPECT_EQ(kManifestUrl, policy_.requested_manifest_url_);
792 if (policy_.can_load_return_value_) {
793 EXPECT_EQ(kEntryUrl, delegate()->found_url_);
794 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
[email protected]5c7d5982010-07-12 09:12:59795 EXPECT_FALSE(delegate()->found_blocked_by_policy_);
[email protected]ea776d022010-02-17 22:20:36796 EXPECT_EQ(1, delegate()->found_cache_id_);
797 EXPECT_EQ(1, delegate()->found_entry_.response_id());
798 EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
799 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
800 TestFinished();
801 } else {
802 Verify_FindNoMainResponse();
803 }
[email protected]35f2094c2009-12-29 22:46:55804 }
805
806 // BasicFindMainFallbackResponse -------------------------------
807
808 void BasicFindMainFallbackResponseInDatabase() {
809 BasicFindMainFallbackResponse(true);
810 }
811
812 void BasicFindMainFallbackResponseInWorkingSet() {
813 BasicFindMainFallbackResponse(false);
814 }
815
816 void BasicFindMainFallbackResponse(bool drop_from_working_set) {
[email protected]79b15b22010-05-19 00:38:56817 PushNextTask(NewRunnableMethod(
818 this, &AppCacheStorageImplTest::Verify_BasicFindMainFallbackResponse));
[email protected]35f2094c2009-12-29 22:46:55819
820 // Setup some preconditions. Create a complete cache with a
821 // fallback namespace and entry.
822 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
823 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::FALLBACK, 1));
824 cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2));
825 cache_->fallback_namespaces_.push_back(
826 FallbackNamespace(kFallbackNamespace2, kEntryUrl2));
827 cache_->fallback_namespaces_.push_back(
828 FallbackNamespace(kFallbackNamespace, kEntryUrl));
829 AppCacheDatabase::CacheRecord cache_record;
830 std::vector<AppCacheDatabase::EntryRecord> entries;
831 std::vector<AppCacheDatabase::FallbackNameSpaceRecord> fallbacks;
832 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists;
833 cache_->ToDatabaseRecords(group_,
834 &cache_record, &entries, &fallbacks, &whitelists);
835 EXPECT_TRUE(database()->InsertEntryRecords(entries));
836 EXPECT_TRUE(database()->InsertFallbackNameSpaceRecords(fallbacks));
837 EXPECT_TRUE(database()->InsertOnlineWhiteListRecords(whitelists));
838 if (drop_from_working_set) {
839 EXPECT_TRUE(cache_->HasOneRef());
840 cache_ = NULL;
841 EXPECT_TRUE(group_->HasOneRef());
842 group_ = NULL;
843 }
844
845 // Conduct the test. The test url is in both fallback namespace urls,
846 // but should match the longer of the two.
847 storage()->FindResponseForMainRequest(kFallbackTestUrl, delegate());
848 EXPECT_NE(kFallbackTestUrl, delegate()->found_url_);
849 }
850
851 void Verify_BasicFindMainFallbackResponse() {
852 EXPECT_EQ(kFallbackTestUrl, delegate()->found_url_);
853 EXPECT_EQ(kManifestUrl, delegate()->found_manifest_url_);
[email protected]5c7d5982010-07-12 09:12:59854 EXPECT_FALSE(delegate()->found_blocked_by_policy_);
[email protected]35f2094c2009-12-29 22:46:55855 EXPECT_EQ(1, delegate()->found_cache_id_);
856 EXPECT_FALSE(delegate()->found_entry_.has_response_id());
857 EXPECT_EQ(2, delegate()->found_fallback_entry_.response_id());
[email protected]6ed2a5a52010-11-03 02:29:14858 EXPECT_EQ(kEntryUrl2, delegate()->found_fallback_url_);
[email protected]35f2094c2009-12-29 22:46:55859 EXPECT_TRUE(delegate()->found_fallback_entry_.IsFallback());
860 TestFinished();
861 }
862
863 // FindMainResponseWithMultipleHits -------------------------------
864
865 void FindMainResponseWithMultipleHits() {
[email protected]79b15b22010-05-19 00:38:56866 PushNextTask(NewRunnableMethod(this,
[email protected]35f2094c2009-12-29 22:46:55867 &AppCacheStorageImplTest::Verify_FindMainResponseWithMultipleHits));
868
869 // Setup some preconditions. Create 2 complete caches with an entry
870 // for the same url.
871
872 // The first cache, in the database but not in the working set.
873 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
874 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 1));
875 AppCacheDatabase::EntryRecord entry_record;
876 entry_record.cache_id = 1;
877 entry_record.url = kEntryUrl;
878 entry_record.flags = AppCacheEntry::EXPLICIT;
879 entry_record.response_id = 1;
880 EXPECT_TRUE(database()->InsertEntry(&entry_record));
881 cache_ = NULL;
882 group_ = NULL;
883
884 // The second cache, in the database and working set.
885 MakeCacheAndGroup(kManifestUrl2, 2, 2, true);
886 cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT, 2));
887 entry_record.cache_id = 2;
888 entry_record.url = kEntryUrl;
889 entry_record.flags = AppCacheEntry::EXPLICIT;
890 entry_record.response_id = 2;
891 EXPECT_TRUE(database()->InsertEntry(&entry_record));
892
893 // Conduct the test, we should find the response from the second cache
894 // since it's "in use".
895 storage()->FindResponseForMainRequest(kEntryUrl, delegate());
896 EXPECT_NE(kEntryUrl, delegate()->found_url_);
897 }
898
899 void Verify_FindMainResponseWithMultipleHits() {
900 EXPECT_EQ(kEntryUrl, delegate()->found_url_);
901 EXPECT_EQ(kManifestUrl2, delegate()->found_manifest_url_);
[email protected]5c7d5982010-07-12 09:12:59902 EXPECT_FALSE(delegate()->found_blocked_by_policy_);
[email protected]35f2094c2009-12-29 22:46:55903 EXPECT_EQ(2, delegate()->found_cache_id_);
904 EXPECT_EQ(2, delegate()->found_entry_.response_id());
905 EXPECT_TRUE(delegate()->found_entry_.IsExplicit());
906 EXPECT_FALSE(delegate()->found_fallback_entry_.has_response_id());
907 TestFinished();
908 }
909
910 // FindMainResponseExclusions -------------------------------
911
912 void FindMainResponseExclusionsInDatabase() {
913 FindMainResponseExclusions(true);
914 }
915
916 void FindMainResponseExclusionsInWorkingSet() {
917 FindMainResponseExclusions(false);
918 }
919
920 void FindMainResponseExclusions(bool drop_from_working_set) {
921 // Setup some preconditions. Create a complete cache with a
[email protected]0b52f1c2010-11-19 03:12:12922 // foreign entry, an online namespace, and a second online
923 // namespace nested within a fallback namespace.
[email protected]35f2094c2009-12-29 22:46:55924 MakeCacheAndGroup(kManifestUrl, 1, 1, true);
925 cache_->AddEntry(kEntryUrl,
926 AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 1));
927 cache_->online_whitelist_namespaces_.push_back(kOnlineNamespace);
[email protected]0b52f1c2010-11-19 03:12:12928 cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2));
929 cache_->fallback_namespaces_.push_back(
930 FallbackNamespace(kFallbackNamespace, kEntryUrl2));
931 cache_->online_whitelist_namespaces_.push_back(kOnlineNamespace);
932 cache_->online_whitelist_namespaces_.push_back(
933 kOnlineNamespaceWithinFallback);
934
[email protected]35f2094c2009-12-29 22:46:55935 AppCacheDatabase::EntryRecord entry_record;
936 entry_record.cache_id = 1;
937 entry_record.url = kEntryUrl;
938 entry_record.flags = AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN;
939 entry_record.response_id = 1;
940 EXPECT_TRUE(database()->InsertEntry(&entry_record));
941 AppCacheDatabase::OnlineWhiteListRecord whitelist_record;
942 whitelist_record.cache_id = 1;
943 whitelist_record.namespace_url = kOnlineNamespace;
944 EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record));
[email protected]0b52f1c2010-11-19 03:12:12945 AppCacheDatabase::FallbackNameSpaceRecord fallback_namespace_record;
946 fallback_namespace_record.cache_id = 1;
947 fallback_namespace_record.fallback_entry_url = kEntryUrl2;
948 fallback_namespace_record.namespace_url = kFallbackNamespace;
949 fallback_namespace_record.origin = kManifestUrl.GetOrigin();
950 EXPECT_TRUE(
951 database()->InsertFallbackNameSpace(&fallback_namespace_record));
952 whitelist_record.cache_id = 1;
953 whitelist_record.namespace_url = kOnlineNamespaceWithinFallback;
954 EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record));
[email protected]35f2094c2009-12-29 22:46:55955 if (drop_from_working_set) {
956 cache_ = NULL;
957 group_ = NULL;
958 }
959
960 // We should not find anything for the foreign entry.
[email protected]79b15b22010-05-19 00:38:56961 PushNextTask(NewRunnableMethod(
[email protected]0b52f1c2010-11-19 03:12:12962 this, &AppCacheStorageImplTest::Verify_ExclusionNotFound,
963 kEntryUrl, 1));
[email protected]35f2094c2009-12-29 22:46:55964 storage()->FindResponseForMainRequest(kEntryUrl, delegate());
965 }
966
[email protected]0b52f1c2010-11-19 03:12:12967 void Verify_ExclusionNotFound(GURL expected_url, int phase) {
[email protected]35f2094c2009-12-29 22:46:55968 EXPECT_EQ(expected_url, delegate()->found_url_);
969 EXPECT_TRUE(delegate()->found_manifest_url_.is_empty());
[email protected]5c7d5982010-07-12 09:12:59970 EXPECT_FALSE(delegate()->found_blocked_by_policy_);
[email protected]35f2094c2009-12-29 22:46:55971 EXPECT_EQ(kNoCacheId, delegate()->found_cache_id_);
972 EXPECT_EQ(kNoResponseId, delegate()->found_entry_.response_id());
973 EXPECT_EQ(kNoResponseId, delegate()->found_fallback_entry_.response_id());
[email protected]6ed2a5a52010-11-03 02:29:14974 EXPECT_TRUE(delegate()->found_fallback_url_.is_empty());
[email protected]35f2094c2009-12-29 22:46:55975 EXPECT_EQ(0, delegate()->found_entry_.types());
976 EXPECT_EQ(0, delegate()->found_fallback_entry_.types());
977
[email protected]0b52f1c2010-11-19 03:12:12978 if (phase == 1) {
[email protected]35f2094c2009-12-29 22:46:55979 // We should not find anything for the online namespace.
[email protected]79b15b22010-05-19 00:38:56980 PushNextTask(NewRunnableMethod(this,
[email protected]0b52f1c2010-11-19 03:12:12981 &AppCacheStorageImplTest::Verify_ExclusionNotFound,
982 kOnlineNamespace, 2));
[email protected]35f2094c2009-12-29 22:46:55983 storage()->FindResponseForMainRequest(kOnlineNamespace, delegate());
984 return;
985 }
[email protected]0b52f1c2010-11-19 03:12:12986 if (phase == 2) {
987 // We should not find anything for the online namespace nested within
988 // the fallback namespace.
989 PushNextTask(NewRunnableMethod(this,
990 &AppCacheStorageImplTest::Verify_ExclusionNotFound,
991 kOnlineNamespaceWithinFallback, 3));
992 storage()->FindResponseForMainRequest(
993 kOnlineNamespaceWithinFallback, delegate());
994 return;
995 }
[email protected]35f2094c2009-12-29 22:46:55996
997 TestFinished();
998 }
999
1000 // Test case helpers --------------------------------------------------
1001
1002 AppCacheService* service() {
1003 return service_.get();
1004 }
1005
1006 AppCacheStorageImpl* storage() {
1007 return static_cast<AppCacheStorageImpl*>(service()->storage());
1008 }
1009
1010 AppCacheDatabase* database() {
1011 return storage()->database_;
1012 }
1013
1014 MockStorageDelegate* delegate() {
1015 return delegate_.get();
1016 }
1017
1018 void MakeCacheAndGroup(
1019 const GURL& manifest_url, int64 group_id, int64 cache_id,
1020 bool add_to_database) {
1021 group_ = new AppCacheGroup(service(), manifest_url, group_id);
1022 cache_ = new AppCache(service(), cache_id);
1023 cache_->set_complete(true);
1024 group_->AddCache(cache_);
1025 if (add_to_database) {
1026 AppCacheDatabase::GroupRecord group_record;
1027 group_record.group_id = group_id;
1028 group_record.manifest_url = manifest_url;
1029 group_record.origin = manifest_url.GetOrigin();
1030 EXPECT_TRUE(database()->InsertGroup(&group_record));
1031 AppCacheDatabase::CacheRecord cache_record;
1032 cache_record.cache_id = cache_id;
1033 cache_record.group_id = group_id;
1034 cache_record.online_wildcard = false;
[email protected]ca25209a2010-02-23 20:39:011035 cache_record.update_time = kZeroTime;
[email protected]35f2094c2009-12-29 22:46:551036 EXPECT_TRUE(database()->InsertCache(&cache_record));
1037 storage()->origins_with_groups_.insert(manifest_url.GetOrigin());
1038 }
1039 }
1040
1041 // Data members --------------------------------------------------
1042
[email protected]35f2094c2009-12-29 22:46:551043 scoped_ptr<base::WaitableEvent> test_finished_event_;
1044 std::stack<Task*> task_stack_;
[email protected]ea776d022010-02-17 22:20:361045 MockAppCachePolicy policy_;
[email protected]35f2094c2009-12-29 22:46:551046 scoped_ptr<AppCacheService> service_;
1047 scoped_ptr<MockStorageDelegate> delegate_;
1048 scoped_refptr<AppCacheGroup> group_;
1049 scoped_refptr<AppCache> cache_;
1050 scoped_refptr<AppCache> cache2_;
1051};
1052
1053
1054TEST_F(AppCacheStorageImplTest, LoadCache_Miss) {
1055 RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_Miss);
1056}
1057
1058TEST_F(AppCacheStorageImplTest, LoadCache_NearHit) {
1059 RunTestOnIOThread(&AppCacheStorageImplTest::LoadCache_NearHit);
1060}
1061
1062TEST_F(AppCacheStorageImplTest, CreateGroupInEmptyOrigin) {
1063 RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInEmptyOrigin);
1064}
1065
1066TEST_F(AppCacheStorageImplTest, CreateGroupInPopulatedOrigin) {
1067 RunTestOnIOThread(&AppCacheStorageImplTest::CreateGroupInPopulatedOrigin);
1068}
1069
1070TEST_F(AppCacheStorageImplTest, LoadGroupAndCache_FarHit) {
1071 RunTestOnIOThread(&AppCacheStorageImplTest::LoadGroupAndCache_FarHit);
1072}
1073
1074TEST_F(AppCacheStorageImplTest, StoreNewGroup) {
1075 RunTestOnIOThread(&AppCacheStorageImplTest::StoreNewGroup);
1076}
1077
1078TEST_F(AppCacheStorageImplTest, StoreExistingGroup) {
1079 RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroup);
1080}
1081
1082TEST_F(AppCacheStorageImplTest, StoreExistingGroupExistingCache) {
1083 RunTestOnIOThread(&AppCacheStorageImplTest::StoreExistingGroupExistingCache);
1084}
1085
[email protected]bae30692010-08-04 20:01:371086TEST_F(AppCacheStorageImplTest, FailStoreGroup) {
1087 RunTestOnIOThread(&AppCacheStorageImplTest::FailStoreGroup);
1088}
1089
[email protected]35f2094c2009-12-29 22:46:551090TEST_F(AppCacheStorageImplTest, MakeGroupObsolete) {
1091 RunTestOnIOThread(&AppCacheStorageImplTest::MakeGroupObsolete);
1092}
1093
1094TEST_F(AppCacheStorageImplTest, MarkEntryAsForeign) {
1095 RunTestOnIOThread(&AppCacheStorageImplTest::MarkEntryAsForeign);
1096}
1097
1098TEST_F(AppCacheStorageImplTest, MarkEntryAsForeignWithLoadInProgress) {
1099 RunTestOnIOThread(
1100 &AppCacheStorageImplTest::MarkEntryAsForeignWithLoadInProgress);
1101}
1102
1103TEST_F(AppCacheStorageImplTest, FindNoMainResponse) {
1104 RunTestOnIOThread(&AppCacheStorageImplTest::FindNoMainResponse);
1105}
1106
[email protected]56566932010-06-15 22:58:021107TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInDatabase) {
[email protected]35f2094c2009-12-29 22:46:551108 RunTestOnIOThread(
1109 &AppCacheStorageImplTest::BasicFindMainResponseInDatabase);
1110}
1111
1112TEST_F(AppCacheStorageImplTest, BasicFindMainResponseInWorkingSet) {
1113 RunTestOnIOThread(
1114 &AppCacheStorageImplTest::BasicFindMainResponseInWorkingSet);
1115}
1116
[email protected]ea776d022010-02-17 22:20:361117TEST_F(AppCacheStorageImplTest, BlockFindMainResponseWithPolicyCheck) {
1118 RunTestOnIOThread(
1119 &AppCacheStorageImplTest::BlockFindMainResponseWithPolicyCheck);
1120}
1121
[email protected]84a6a3b2010-02-09 18:59:181122TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInDatabase) {
[email protected]35f2094c2009-12-29 22:46:551123 RunTestOnIOThread(
1124 &AppCacheStorageImplTest::BasicFindMainFallbackResponseInDatabase);
1125}
1126
1127TEST_F(AppCacheStorageImplTest, BasicFindMainFallbackResponseInWorkingSet) {
1128 RunTestOnIOThread(
1129 &AppCacheStorageImplTest::BasicFindMainFallbackResponseInWorkingSet);
1130}
1131
1132TEST_F(AppCacheStorageImplTest, FindMainResponseWithMultipleHits) {
1133 RunTestOnIOThread(
1134 &AppCacheStorageImplTest::FindMainResponseWithMultipleHits);
1135}
1136
1137TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInDatabase) {
1138 RunTestOnIOThread(
1139 &AppCacheStorageImplTest::FindMainResponseExclusionsInDatabase);
1140}
1141
1142TEST_F(AppCacheStorageImplTest, FindMainResponseExclusionsInWorkingSet) {
1143 RunTestOnIOThread(
1144 &AppCacheStorageImplTest::FindMainResponseExclusionsInWorkingSet);
1145}
1146
1147// That's all folks!
1148
1149} // namespace appcache
1150
[email protected]79b15b22010-05-19 00:38:561151// AppCacheStorageImplTest is expected to always live longer than the
1152// runnable methods. This lets us call NewRunnableMethod on its instances.
[email protected]c56428f22010-06-16 02:17:231153DISABLE_RUNNABLE_METHOD_REFCOUNT(appcache::AppCacheStorageImplTest);