OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authos. 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. |
| 4 |
| 5 #include "base/message_loop.h" |
| 6 #include "testing/gtest/include/gtest/gtest.h" |
| 7 #include "webkit/appcache/appcache.h" |
| 8 #include "webkit/appcache/appcache_group.h" |
| 9 #include "webkit/appcache/appcache_response.h" |
| 10 #include "webkit/appcache/appcache_storage.h" |
| 11 #include "webkit/appcache/mock_appcache_service.h" |
| 12 |
| 13 namespace appcache { |
| 14 |
| 15 class MockAppCacheStorageTest : public testing::Test { |
| 16 public: |
| 17 class MockStorageDelegate : public AppCacheStorage::Delegate { |
| 18 public: |
| 19 explicit MockStorageDelegate() |
| 20 : loaded_cache_id_(0), stored_group_success_(false), |
| 21 obsoleted_success_(false), found_cache_id_(kNoCacheId) { |
| 22 } |
| 23 |
| 24 void OnCacheLoaded(AppCache* cache, int64 cache_id) { |
| 25 loaded_cache_ = cache; |
| 26 loaded_cache_id_ = cache_id; |
| 27 } |
| 28 |
| 29 void OnGroupLoaded(AppCacheGroup* group, const GURL& manifest_url) { |
| 30 loaded_group_ = group; |
| 31 loaded_manifest_url_ = manifest_url; |
| 32 } |
| 33 |
| 34 void OnGroupAndNewestCacheStored(AppCacheGroup* group, bool success) { |
| 35 stored_group_ = group; |
| 36 stored_group_success_ = success; |
| 37 } |
| 38 |
| 39 void OnGroupMadeObsolete(AppCacheGroup* group, bool success) { |
| 40 obsoleted_group_ = group; |
| 41 obsoleted_success_ = success; |
| 42 } |
| 43 |
| 44 void OnMainResponseFound(const GURL& url, const AppCacheEntry& entry, |
| 45 int64 cache_id, const GURL& manifest_url) { |
| 46 found_url_ = url; |
| 47 found_entry_ = entry; |
| 48 found_cache_id_ = cache_id; |
| 49 found_manifest_url_ = manifest_url; |
| 50 } |
| 51 |
| 52 scoped_refptr<AppCache> loaded_cache_; |
| 53 int64 loaded_cache_id_; |
| 54 scoped_refptr<AppCacheGroup> loaded_group_; |
| 55 GURL loaded_manifest_url_; |
| 56 scoped_refptr<AppCacheGroup> stored_group_; |
| 57 bool stored_group_success_; |
| 58 scoped_refptr<AppCacheGroup> obsoleted_group_; |
| 59 bool obsoleted_success_; |
| 60 GURL found_url_; |
| 61 AppCacheEntry found_entry_; |
| 62 int64 found_cache_id_; |
| 63 GURL found_manifest_url_; |
| 64 }; |
| 65 }; |
| 66 |
| 67 |
| 68 TEST_F(MockAppCacheStorageTest, LoadCache_Miss) { |
| 69 // Attempt to load a cache that doesn't exist. Should |
| 70 // complete asyncly. |
| 71 MockAppCacheService service; |
| 72 MockStorageDelegate delegate; |
| 73 service.storage()->LoadCache(111, &delegate); |
| 74 EXPECT_NE(111, delegate.loaded_cache_id_); |
| 75 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 76 EXPECT_EQ(111, delegate.loaded_cache_id_); |
| 77 EXPECT_FALSE(delegate.loaded_cache_); |
| 78 } |
| 79 |
| 80 TEST_F(MockAppCacheStorageTest, LoadCache_NearHit) { |
| 81 // Attempt to load a cache that is currently in use |
| 82 // and does not require loading from disk. This |
| 83 // load should complete syncly. |
| 84 MockAppCacheService service; |
| 85 |
| 86 // Setup some preconditions. Make an 'unstored' cache for |
| 87 // us to load. The ctor should put it in the working set. |
| 88 int64 cache_id = service.storage()->NewCacheId(); |
| 89 scoped_refptr<AppCache> cache = new AppCache(&service, cache_id); |
| 90 |
| 91 // Conduct the test. |
| 92 MockStorageDelegate delegate; |
| 93 service.storage()->LoadCache(cache_id, &delegate); |
| 94 EXPECT_EQ(cache_id, delegate.loaded_cache_id_); |
| 95 EXPECT_EQ(cache.get(), delegate.loaded_cache_.get()); |
| 96 } |
| 97 |
| 98 TEST_F(MockAppCacheStorageTest, CreateGroup) { |
| 99 // Attempt to load/create a group that doesn't exist. |
| 100 // Should complete asyncly. |
| 101 MockAppCacheService service; |
| 102 MockAppCacheStorage* storage = |
| 103 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 104 MockStorageDelegate delegate; |
| 105 GURL manifest_url("http://blah/"); |
| 106 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); |
| 107 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); |
| 108 EXPECT_FALSE(delegate.loaded_group_.get()); |
| 109 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 110 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); |
| 111 EXPECT_TRUE(delegate.loaded_group_.get()); |
| 112 EXPECT_TRUE(delegate.loaded_group_->HasOneRef()); |
| 113 EXPECT_FALSE(delegate.loaded_group_->newest_complete_cache()); |
| 114 EXPECT_TRUE(storage->stored_groups_.empty()); |
| 115 } |
| 116 |
| 117 TEST_F(MockAppCacheStorageTest, LoadGroup_NearHit) { |
| 118 // Attempt to load a group that is currently in use |
| 119 // and does not require loading from disk. This |
| 120 // load should complete syncly. |
| 121 MockAppCacheService service; |
| 122 MockStorageDelegate delegate; |
| 123 |
| 124 // Setup some preconditions. Create a group that appears |
| 125 // to be "unstored" and "currently in use". |
| 126 GURL manifest_url("http://blah/"); |
| 127 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); |
| 128 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 129 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); |
| 130 EXPECT_TRUE(delegate.loaded_group_.get()); |
| 131 |
| 132 // Reset our delegate, and take a reference to the new group. |
| 133 scoped_refptr<AppCacheGroup> group; |
| 134 group.swap(delegate.loaded_group_); |
| 135 delegate.loaded_manifest_url_ = GURL(); |
| 136 |
| 137 // Conduct the test. |
| 138 service.storage()->LoadOrCreateGroup(manifest_url, &delegate); |
| 139 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); |
| 140 EXPECT_EQ(group.get(), delegate.loaded_group_.get()); |
| 141 } |
| 142 |
| 143 TEST_F(MockAppCacheStorageTest, LoadGroupAndCache_FarHit) { |
| 144 // Attempt to load a cache that is not currently in use |
| 145 // and does require loading from disk. This |
| 146 // load should complete asyncly. |
| 147 MockAppCacheService service; |
| 148 MockAppCacheStorage* storage = |
| 149 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 150 |
| 151 // Setup some preconditions. Create a group and newest cache that |
| 152 // appears to be "stored" and "not currently in use". |
| 153 GURL manifest_url("http://blah/"); |
| 154 scoped_refptr<AppCacheGroup> group = |
| 155 new AppCacheGroup(&service, manifest_url); |
| 156 int64 cache_id = storage->NewCacheId(); |
| 157 scoped_refptr<AppCache> cache = new AppCache(&service, cache_id); |
| 158 cache->set_complete(true); |
| 159 group->AddCache(cache); |
| 160 storage->AddStoredGroup(group); |
| 161 storage->AddStoredCache(cache); |
| 162 |
| 163 // Drop the references from above so the only refs to these |
| 164 // objects are from within the storage class. This is to make |
| 165 // these objects appear as "not currently in use". |
| 166 AppCache* cache_ptr = cache.get(); |
| 167 AppCacheGroup* group_ptr = group.get(); |
| 168 cache = NULL; |
| 169 group = NULL; |
| 170 |
| 171 // Setup a delegate to receive completion callbacks. |
| 172 MockStorageDelegate delegate; |
| 173 |
| 174 // Conduct the cache load test. |
| 175 EXPECT_NE(cache_id, delegate.loaded_cache_id_); |
| 176 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get()); |
| 177 storage->LoadCache(cache_id, &delegate); |
| 178 EXPECT_NE(cache_id, delegate.loaded_cache_id_); |
| 179 EXPECT_NE(cache_ptr, delegate.loaded_cache_.get()); |
| 180 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 181 EXPECT_EQ(cache_id, delegate.loaded_cache_id_); |
| 182 EXPECT_EQ(cache_ptr, delegate.loaded_cache_.get()); |
| 183 delegate.loaded_cache_ = NULL; |
| 184 |
| 185 // Conduct the group load test. |
| 186 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); |
| 187 EXPECT_FALSE(delegate.loaded_group_.get()); |
| 188 storage->LoadOrCreateGroup(manifest_url, &delegate); |
| 189 EXPECT_NE(manifest_url, delegate.loaded_manifest_url_); |
| 190 EXPECT_FALSE(delegate.loaded_group_.get()); |
| 191 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 192 EXPECT_EQ(manifest_url, delegate.loaded_manifest_url_); |
| 193 EXPECT_EQ(group_ptr, delegate.loaded_group_.get()); |
| 194 } |
| 195 |
| 196 TEST_F(MockAppCacheStorageTest, StoreNewGroup) { |
| 197 // Store a group and its newest cache. Should complete asyncly. |
| 198 MockAppCacheService service; |
| 199 MockAppCacheStorage* storage = |
| 200 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 201 |
| 202 // Setup some preconditions. Create a group and newest cache that |
| 203 // appears to be "unstored". |
| 204 GURL manifest_url("http://blah/"); |
| 205 scoped_refptr<AppCacheGroup> group = |
| 206 new AppCacheGroup(&service, manifest_url); |
| 207 int64 cache_id = storage->NewCacheId(); |
| 208 scoped_refptr<AppCache> cache = new AppCache(&service, cache_id); |
| 209 cache->set_complete(true); |
| 210 group->AddCache(cache); |
| 211 // Hold a ref to the cache simulate the UpdateJob holding that ref, |
| 212 // and hold a ref to the group to simulate the CacheHost holding that ref. |
| 213 |
| 214 // Conduct the store test. |
| 215 MockStorageDelegate delegate; |
| 216 EXPECT_TRUE(storage->stored_caches_.empty()); |
| 217 EXPECT_TRUE(storage->stored_groups_.empty()); |
| 218 storage->StoreGroupAndNewestCache(group, &delegate); |
| 219 EXPECT_FALSE(delegate.stored_group_success_); |
| 220 EXPECT_TRUE(storage->stored_caches_.empty()); |
| 221 EXPECT_TRUE(storage->stored_groups_.empty()); |
| 222 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 223 EXPECT_TRUE(delegate.stored_group_success_); |
| 224 EXPECT_FALSE(storage->stored_caches_.empty()); |
| 225 EXPECT_FALSE(storage->stored_groups_.empty()); |
| 226 } |
| 227 |
| 228 TEST_F(MockAppCacheStorageTest, StoreExistingGroup) { |
| 229 // Store a group and its newest cache. Should complete asyncly. |
| 230 MockAppCacheService service; |
| 231 MockAppCacheStorage* storage = |
| 232 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 233 |
| 234 // Setup some preconditions. Create a group and old complete cache |
| 235 // that appear to be "stored", and a newest unstored complete cache. |
| 236 GURL manifest_url("http://blah/"); |
| 237 scoped_refptr<AppCacheGroup> group = |
| 238 new AppCacheGroup(&service, manifest_url); |
| 239 int64 old_cache_id = storage->NewCacheId(); |
| 240 scoped_refptr<AppCache> old_cache = new AppCache(&service, old_cache_id); |
| 241 old_cache->set_complete(true); |
| 242 group->AddCache(old_cache); |
| 243 storage->AddStoredGroup(group); |
| 244 storage->AddStoredCache(old_cache); |
| 245 int64 new_cache_id = storage->NewCacheId(); |
| 246 scoped_refptr<AppCache> new_cache = new AppCache(&service, new_cache_id); |
| 247 new_cache->set_complete(true); |
| 248 group->AddCache(new_cache); |
| 249 EXPECT_EQ(new_cache.get(), group->newest_complete_cache()); |
| 250 // Hold our refs to simulate the UpdateJob holding these refs. |
| 251 |
| 252 // Conduct the test. |
| 253 MockStorageDelegate delegate; |
| 254 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); |
| 255 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); |
| 256 EXPECT_TRUE(storage->IsCacheStored(old_cache)); |
| 257 EXPECT_FALSE(storage->IsCacheStored(new_cache)); |
| 258 storage->StoreGroupAndNewestCache(group, &delegate); |
| 259 EXPECT_FALSE(delegate.stored_group_success_); |
| 260 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); |
| 261 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); |
| 262 EXPECT_TRUE(storage->IsCacheStored(old_cache)); |
| 263 EXPECT_FALSE(storage->IsCacheStored(new_cache)); |
| 264 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 265 EXPECT_TRUE(delegate.stored_group_success_); |
| 266 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); |
| 267 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); |
| 268 EXPECT_FALSE(storage->IsCacheStored(old_cache)); |
| 269 EXPECT_TRUE(storage->IsCacheStored(new_cache)); |
| 270 } |
| 271 |
| 272 TEST_F(MockAppCacheStorageTest, MakeGroupObsolete) { |
| 273 // Make a group obsolete, should complete asyncly. |
| 274 MockAppCacheService service; |
| 275 MockAppCacheStorage* storage = |
| 276 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 277 |
| 278 // Setup some preconditions. Create a group and newest cache that |
| 279 // appears to be "stored" and "currently in use". |
| 280 GURL manifest_url("http://blah/"); |
| 281 scoped_refptr<AppCacheGroup> group = |
| 282 new AppCacheGroup(&service, manifest_url); |
| 283 int64 cache_id = storage->NewCacheId(); |
| 284 scoped_refptr<AppCache> cache = new AppCache(&service, cache_id); |
| 285 cache->set_complete(true); |
| 286 group->AddCache(cache); |
| 287 storage->AddStoredGroup(group); |
| 288 storage->AddStoredCache(cache); |
| 289 // Hold our refs to simulate the UpdateJob holding these refs. |
| 290 |
| 291 // Conduct the test. |
| 292 MockStorageDelegate delegate; |
| 293 EXPECT_FALSE(group->is_obsolete()); |
| 294 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); |
| 295 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); |
| 296 EXPECT_FALSE(cache->HasOneRef()); |
| 297 EXPECT_FALSE(group->HasOneRef()); |
| 298 storage->MakeGroupObsolete(group, &delegate); |
| 299 EXPECT_FALSE(group->is_obsolete()); |
| 300 EXPECT_EQ(size_t(1), storage->stored_caches_.size()); |
| 301 EXPECT_EQ(size_t(1), storage->stored_groups_.size()); |
| 302 EXPECT_FALSE(cache->HasOneRef()); |
| 303 EXPECT_FALSE(group->HasOneRef()); |
| 304 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 305 EXPECT_TRUE(delegate.obsoleted_success_); |
| 306 EXPECT_EQ(group.get(), delegate.obsoleted_group_.get()); |
| 307 EXPECT_TRUE(group->is_obsolete()); |
| 308 EXPECT_TRUE(storage->stored_caches_.empty()); |
| 309 EXPECT_TRUE(storage->stored_groups_.empty()); |
| 310 EXPECT_TRUE(cache->HasOneRef()); |
| 311 EXPECT_FALSE(group->HasOneRef()); |
| 312 delegate.obsoleted_group_ = NULL; |
| 313 cache = NULL; |
| 314 EXPECT_TRUE(group->HasOneRef()); |
| 315 } |
| 316 |
| 317 TEST_F(MockAppCacheStorageTest, MarkEntryAsForeign) { |
| 318 // Should complete syncly. |
| 319 MockAppCacheService service; |
| 320 MockAppCacheStorage* storage = |
| 321 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 322 |
| 323 // Setup some preconditions. Create a cache with an entry. |
| 324 GURL entry_url("http://blan/entry"); |
| 325 int64 cache_id = storage->NewCacheId(); |
| 326 scoped_refptr<AppCache> cache = new AppCache(&service, cache_id); |
| 327 cache->AddEntry(entry_url, AppCacheEntry(AppCacheEntry::EXPLICIT)); |
| 328 |
| 329 // Conduct the test. |
| 330 MockStorageDelegate delegate; |
| 331 EXPECT_FALSE(cache->GetEntry(entry_url)->IsForeign()); |
| 332 storage->MarkEntryAsForeign(entry_url, cache_id); |
| 333 EXPECT_TRUE(cache->GetEntry(entry_url)->IsForeign()); |
| 334 EXPECT_TRUE(cache->GetEntry(entry_url)->IsExplicit()); |
| 335 } |
| 336 |
| 337 TEST_F(MockAppCacheStorageTest, FindNoMainResponse) { |
| 338 // Should complete asyncly. |
| 339 MockAppCacheService service; |
| 340 MockAppCacheStorage* storage = |
| 341 reinterpret_cast<MockAppCacheStorage*>(service.storage()); |
| 342 |
| 343 // Conduct the test. |
| 344 MockStorageDelegate delegate; |
| 345 GURL url("http://blah/some_url"); |
| 346 EXPECT_NE(url, delegate.found_url_); |
| 347 storage->FindResponseForMainRequest(url, &delegate); |
| 348 EXPECT_NE(url, delegate.found_url_); |
| 349 MessageLoop::current()->RunAllPending(); // Do async task execution. |
| 350 EXPECT_EQ(url, delegate.found_url_); |
| 351 EXPECT_TRUE(delegate.found_manifest_url_.is_empty()); |
| 352 EXPECT_EQ(kNoCacheId, delegate.found_cache_id_); |
| 353 EXPECT_EQ(kNoResponseId, delegate.found_entry_.response_id()); |
| 354 EXPECT_EQ(0, delegate.found_entry_.types()); |
| 355 } |
| 356 |
| 357 } // namespace appcache |
| 358 |
OLD | NEW |