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. 4 5 #ifndef CONTENT_BROWSER_APPCACHE_MOCK_APPCACHE_STORAGE_H_ 6 #define CONTENT_BROWSER_APPCACHE_MOCK_APPCACHE_STORAGE_H_ 7 8 #include <deque> 9 #include <map> 10 #include <vector> 11 12 #include "base/callback.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "webkit/browser/appcache/appcache.h" 18 #include "webkit/browser/appcache/appcache_disk_cache.h" 19 #include "webkit/browser/appcache/appcache_group.h" 20 #include "webkit/browser/appcache/appcache_response.h" 21 #include "webkit/browser/appcache/appcache_storage.h" 22 23 using appcache::AppCache; 24 using appcache::AppCacheDiskCache; 25 using appcache::AppCacheEntry; 26 using appcache::AppCacheGroup; 27 using appcache::AppCacheInfoCollection; 28 using appcache::AppCacheResponseReader; 29 using appcache::AppCacheResponseWriter; 30 using appcache::AppCacheServiceImpl; 31 using appcache::AppCacheStorage; 32 using appcache::kAppCacheNoCacheId; 33 34 namespace content { 35 FORWARD_DECLARE_TEST(AppCacheServiceImplTest, DeleteAppCachesForOrigin); 36 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, BasicFindMainResponse); 37 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, 38 BasicFindMainFallbackResponse); 39 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, CreateGroup); 40 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, FindMainResponseExclusions); 41 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, 42 FindMainResponseWithMultipleCandidates); 43 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, LoadCache_FarHit); 44 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, LoadGroupAndCache_FarHit); 45 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, MakeGroupObsolete); 46 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, StoreNewGroup); 47 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, StoreExistingGroup); 48 FORWARD_DECLARE_TEST(MockAppCacheStorageTest, 49 StoreExistingGroupExistingCache); 50 class AppCacheRequestHandlerTest; 51 class AppCacheServiceImplTest; 52 class MockAppCacheStorageTest; 53 54 // For use in unit tests. 55 // Note: This class is also being used to bootstrap our development efforts. 56 // We can get layout tests up and running, and back fill with real storage 57 // somewhat in parallel. 58 class MockAppCacheStorage : public AppCacheStorage { 59 public: 60 explicit MockAppCacheStorage(AppCacheServiceImpl* service); 61 virtual ~MockAppCacheStorage(); 62 63 virtual void GetAllInfo(Delegate* delegate) OVERRIDE; 64 virtual void LoadCache(int64 id, Delegate* delegate) OVERRIDE; 65 virtual void LoadOrCreateGroup(const GURL& manifest_url, 66 Delegate* delegate) OVERRIDE; 67 virtual void StoreGroupAndNewestCache(AppCacheGroup* group, 68 AppCache* newest_cache, 69 Delegate* delegate) OVERRIDE; 70 virtual void FindResponseForMainRequest(const GURL& url, 71 const GURL& preferred_manifest_url, 72 Delegate* delegate) OVERRIDE; 73 virtual void FindResponseForSubRequest( 74 AppCache* cache, const GURL& url, 75 AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry, 76 bool * found_network_namespace) OVERRIDE; 77 virtual void MarkEntryAsForeign(const GURL& entry_url, 78 int64 cache_id) OVERRIDE; 79 virtual void MakeGroupObsolete(AppCacheGroup* group, 80 Delegate* delegate, 81 int response_code) OVERRIDE; 82 virtual AppCacheResponseReader* CreateResponseReader( 83 const GURL& manifest_url, int64 group_id, int64 response_id) OVERRIDE; 84 virtual AppCacheResponseWriter* CreateResponseWriter( 85 const GURL& manifest_url, int64 group_id) OVERRIDE; 86 virtual void DoomResponses( 87 const GURL& manifest_url, 88 const std::vector<int64>& response_ids) OVERRIDE; 89 virtual void DeleteResponses( 90 const GURL& manifest_url, 91 const std::vector<int64>& response_ids) OVERRIDE; 92 93 private: 94 friend class AppCacheRequestHandlerTest; 95 friend class AppCacheServiceImplTest; 96 friend class AppCacheUpdateJobTest; 97 friend class MockAppCacheStorageTest; 98 99 typedef base::hash_map<int64, scoped_refptr<AppCache> > StoredCacheMap; 100 typedef std::map<GURL, scoped_refptr<AppCacheGroup> > StoredGroupMap; 101 typedef std::set<int64> DoomedResponseIds; 102 103 void ProcessGetAllInfo(scoped_refptr<DelegateReference> delegate_ref); 104 void ProcessLoadCache( 105 int64 id, scoped_refptr<DelegateReference> delegate_ref); 106 void ProcessLoadOrCreateGroup( 107 const GURL& manifest_url, scoped_refptr<DelegateReference> delegate_ref); 108 void ProcessStoreGroupAndNewestCache( 109 scoped_refptr<AppCacheGroup> group, scoped_refptr<AppCache> newest_cache, 110 scoped_refptr<DelegateReference> delegate_ref); 111 void ProcessMakeGroupObsolete(scoped_refptr<AppCacheGroup> group, 112 scoped_refptr<DelegateReference> delegate_ref, 113 int response_code); 114 void ProcessFindResponseForMainRequest( 115 const GURL& url, scoped_refptr<DelegateReference> delegate_ref); 116 117 void ScheduleTask(const base::Closure& task); 118 void RunOnePendingTask(); 119 120 void AddStoredCache(AppCache* cache); 121 void RemoveStoredCache(AppCache* cache); 122 void RemoveStoredCaches(const AppCacheGroup::Caches& caches); 123 bool IsCacheStored(const AppCache* cache) { 124 return stored_caches_.find(cache->cache_id()) != stored_caches_.end(); 125 } 126 127 void AddStoredGroup(AppCacheGroup* group); 128 void RemoveStoredGroup(AppCacheGroup* group); 129 bool IsGroupStored(const AppCacheGroup* group) { 130 return IsGroupForManifestStored(group->manifest_url()); 131 } 132 bool IsGroupForManifestStored(const GURL& manifest_url) { 133 return stored_groups_.find(manifest_url) != stored_groups_.end(); 134 } 135 136 // These helpers determine when certain operations should complete 137 // asynchronously vs synchronously to faithfully mimic, or mock, 138 // the behavior of the real implemenation of the AppCacheStorage 139 // interface. 140 bool ShouldGroupLoadAppearAsync(const AppCacheGroup* group); 141 bool ShouldCacheLoadAppearAsync(const AppCache* cache); 142 143 // Lazily constructed in-memory disk cache. 144 AppCacheDiskCache* disk_cache() { 145 if (!disk_cache_) { 146 const int kMaxCacheSize = 10 * 1024 * 1024; 147 disk_cache_.reset(new AppCacheDiskCache); 148 disk_cache_->InitWithMemBackend(kMaxCacheSize, net::CompletionCallback()); 149 } 150 return disk_cache_.get(); 151 } 152 153 // Simulate failures for testing. Once set all subsequent calls 154 // to MakeGroupObsolete or StorageGroupAndNewestCache will fail. 155 void SimulateMakeGroupObsoleteFailure() { 156 simulate_make_group_obsolete_failure_ = true; 157 } 158 void SimulateStoreGroupAndNewestCacheFailure() { 159 simulate_store_group_and_newest_cache_failure_ = true; 160 } 161 162 // Simulate FindResponseFor results for testing. These 163 // provided values will be return on the next call to 164 // the corresponding Find method, subsequent calls are 165 // unaffected. 166 void SimulateFindMainResource( 167 const AppCacheEntry& entry, 168 const GURL& fallback_url, 169 const AppCacheEntry& fallback_entry, 170 int64 cache_id, 171 int64 group_id, 172 const GURL& manifest_url) { 173 simulate_find_main_resource_ = true; 174 simulate_find_sub_resource_ = false; 175 simulated_found_entry_ = entry; 176 simulated_found_fallback_url_ = fallback_url; 177 simulated_found_fallback_entry_ = fallback_entry; 178 simulated_found_cache_id_ = cache_id; 179 simulated_found_group_id_ = group_id; 180 simulated_found_manifest_url_ = manifest_url, 181 simulated_found_network_namespace_ = false; // N/A to main resource loads 182 } 183 void SimulateFindSubResource( 184 const AppCacheEntry& entry, 185 const AppCacheEntry& fallback_entry, 186 bool network_namespace) { 187 simulate_find_main_resource_ = false; 188 simulate_find_sub_resource_ = true; 189 simulated_found_entry_ = entry; 190 simulated_found_fallback_entry_ = fallback_entry; 191 simulated_found_cache_id_ = kAppCacheNoCacheId; // N/A to sub resource loads 192 simulated_found_manifest_url_ = GURL(); // N/A to sub resource loads 193 simulated_found_group_id_ = 0; // N/A to sub resource loads 194 simulated_found_network_namespace_ = network_namespace; 195 } 196 197 void SimulateGetAllInfo(AppCacheInfoCollection* info) { 198 simulated_appcache_info_ = info; 199 } 200 201 void SimulateResponseReader(AppCacheResponseReader* reader) { 202 simulated_reader_.reset(reader); 203 } 204 205 StoredCacheMap stored_caches_; 206 StoredGroupMap stored_groups_; 207 DoomedResponseIds doomed_response_ids_; 208 scoped_ptr<AppCacheDiskCache> disk_cache_; 209 std::deque<base::Closure> pending_tasks_; 210 211 bool simulate_make_group_obsolete_failure_; 212 bool simulate_store_group_and_newest_cache_failure_; 213 214 bool simulate_find_main_resource_; 215 bool simulate_find_sub_resource_; 216 AppCacheEntry simulated_found_entry_; 217 AppCacheEntry simulated_found_fallback_entry_; 218 int64 simulated_found_cache_id_; 219 int64 simulated_found_group_id_; 220 GURL simulated_found_fallback_url_; 221 GURL simulated_found_manifest_url_; 222 bool simulated_found_network_namespace_; 223 scoped_refptr<AppCacheInfoCollection> simulated_appcache_info_; 224 scoped_ptr<AppCacheResponseReader> simulated_reader_; 225 226 base::WeakPtrFactory<MockAppCacheStorage> weak_factory_; 227 228 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 229 BasicFindMainResponse); 230 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 231 BasicFindMainFallbackResponse); 232 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, CreateGroup); 233 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 234 FindMainResponseExclusions); 235 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 236 FindMainResponseWithMultipleCandidates); 237 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, LoadCache_FarHit); 238 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 239 LoadGroupAndCache_FarHit); 240 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, MakeGroupObsolete); 241 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, StoreNewGroup); 242 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 243 StoreExistingGroup); 244 FRIEND_TEST_ALL_PREFIXES(MockAppCacheStorageTest, 245 StoreExistingGroupExistingCache); 246 FRIEND_TEST_ALL_PREFIXES(AppCacheServiceImplTest, 247 DeleteAppCachesForOrigin); 248 249 DISALLOW_COPY_AND_ASSIGN(MockAppCacheStorage); 250 }; 251 252 } // namespace content 253 254 #endif // CONTENT_BROWSER_APPCACHE_MOCK_APPCACHE_STORAGE_H_ 255