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