| OLD | NEW |
| (Empty) |
| 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 #include <string> | |
| 6 | |
| 7 #include "base/message_loop/message_loop.h" | |
| 8 #include "chrome/browser/renderer_host/web_cache_manager.h" | |
| 9 #include "content/public/test/test_browser_thread.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 using base::Time; | |
| 13 using base::TimeDelta; | |
| 14 using content::BrowserThread; | |
| 15 using blink::WebCache; | |
| 16 | |
| 17 class WebCacheManagerTest : public testing::Test { | |
| 18 protected: | |
| 19 typedef WebCacheManager::StatsMap StatsMap; | |
| 20 typedef WebCacheManager::Allocation Allocation; | |
| 21 typedef WebCacheManager::AllocationStrategy AllocationStrategy; | |
| 22 | |
| 23 static const int kRendererID; | |
| 24 static const int kRendererID2; | |
| 25 static const WebCache::UsageStats kStats; | |
| 26 static const WebCache::UsageStats kStats2; | |
| 27 | |
| 28 WebCacheManagerTest() | |
| 29 : ui_thread_(BrowserThread::UI, &message_loop_) { | |
| 30 } | |
| 31 | |
| 32 // Thunks to access protected members of WebCacheManager | |
| 33 static std::map<int, WebCacheManager::RendererInfo>& stats( | |
| 34 WebCacheManager* h) { | |
| 35 return h->stats_; | |
| 36 } | |
| 37 | |
| 38 static void SimulateInactivity(WebCacheManager* h, int renderer_id) { | |
| 39 stats(h)[renderer_id].access = Time::Now() - TimeDelta::FromMinutes( | |
| 40 WebCacheManager::kRendererInactiveThresholdMinutes); | |
| 41 h->FindInactiveRenderers(); | |
| 42 } | |
| 43 | |
| 44 static std::set<int>& active_renderers(WebCacheManager* h) { | |
| 45 return h->active_renderers_; | |
| 46 } | |
| 47 static std::set<int>& inactive_renderers(WebCacheManager* h) { | |
| 48 return h->inactive_renderers_; | |
| 49 } | |
| 50 static void GatherStats(WebCacheManager* h, | |
| 51 std::set<int> renderers, | |
| 52 WebCache::UsageStats* stats) { | |
| 53 h->GatherStats(renderers, stats); | |
| 54 } | |
| 55 static size_t GetSize(int tactic, | |
| 56 const WebCache::UsageStats& stats) { | |
| 57 return WebCacheManager::GetSize( | |
| 58 static_cast<WebCacheManager::AllocationTactic>(tactic), stats); | |
| 59 } | |
| 60 static bool AttemptTactic(WebCacheManager* h, | |
| 61 int active_tactic, | |
| 62 const WebCache::UsageStats& active_stats, | |
| 63 int inactive_tactic, | |
| 64 const WebCache::UsageStats& inactive_stats, | |
| 65 std::list< std::pair<int,size_t> >* strategy) { | |
| 66 return h->AttemptTactic( | |
| 67 static_cast<WebCacheManager::AllocationTactic>(active_tactic), | |
| 68 active_stats, | |
| 69 static_cast<WebCacheManager::AllocationTactic>(inactive_tactic), | |
| 70 inactive_stats, | |
| 71 strategy); | |
| 72 } | |
| 73 static void AddToStrategy(WebCacheManager* h, | |
| 74 std::set<int> renderers, | |
| 75 int tactic, | |
| 76 size_t extra_bytes_to_allocate, | |
| 77 std::list< std::pair<int,size_t> >* strategy) { | |
| 78 h->AddToStrategy(renderers, | |
| 79 static_cast<WebCacheManager::AllocationTactic>(tactic), | |
| 80 extra_bytes_to_allocate, | |
| 81 strategy); | |
| 82 } | |
| 83 | |
| 84 enum { | |
| 85 DIVIDE_EVENLY = WebCacheManager::DIVIDE_EVENLY, | |
| 86 KEEP_CURRENT_WITH_HEADROOM = WebCacheManager::KEEP_CURRENT_WITH_HEADROOM, | |
| 87 KEEP_CURRENT = WebCacheManager::KEEP_CURRENT, | |
| 88 KEEP_LIVE_WITH_HEADROOM = WebCacheManager::KEEP_LIVE_WITH_HEADROOM, | |
| 89 KEEP_LIVE = WebCacheManager::KEEP_LIVE, | |
| 90 }; | |
| 91 | |
| 92 WebCacheManager* manager() { return &manager_; } | |
| 93 | |
| 94 private: | |
| 95 WebCacheManager manager_; | |
| 96 base::MessageLoop message_loop_; | |
| 97 content::TestBrowserThread ui_thread_; | |
| 98 }; | |
| 99 | |
| 100 // static | |
| 101 const int WebCacheManagerTest::kRendererID = 146; | |
| 102 | |
| 103 // static | |
| 104 const int WebCacheManagerTest::kRendererID2 = 245; | |
| 105 | |
| 106 // static | |
| 107 const WebCache::UsageStats WebCacheManagerTest::kStats = { | |
| 108 0, | |
| 109 1024 * 1024, | |
| 110 1024 * 1024, | |
| 111 256 * 1024, | |
| 112 512, | |
| 113 }; | |
| 114 | |
| 115 // static | |
| 116 const WebCache::UsageStats WebCacheManagerTest::kStats2 = { | |
| 117 0, | |
| 118 2 * 1024 * 1024, | |
| 119 2 * 1024 * 1024, | |
| 120 2 * 256 * 1024, | |
| 121 2 * 512, | |
| 122 }; | |
| 123 | |
| 124 static bool operator==(const WebCache::UsageStats& lhs, | |
| 125 const WebCache::UsageStats& rhs) { | |
| 126 return !::memcmp(&lhs, &rhs, sizeof(WebCache::UsageStats)); | |
| 127 } | |
| 128 | |
| 129 TEST_F(WebCacheManagerTest, AddRemoveRendererTest) { | |
| 130 EXPECT_EQ(0U, active_renderers(manager()).size()); | |
| 131 EXPECT_EQ(0U, inactive_renderers(manager()).size()); | |
| 132 | |
| 133 manager()->Add(kRendererID); | |
| 134 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID)); | |
| 135 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID)); | |
| 136 | |
| 137 manager()->Remove(kRendererID); | |
| 138 EXPECT_EQ(0U, active_renderers(manager()).size()); | |
| 139 EXPECT_EQ(0U, inactive_renderers(manager()).size()); | |
| 140 } | |
| 141 | |
| 142 TEST_F(WebCacheManagerTest, ActiveInactiveTest) { | |
| 143 manager()->Add(kRendererID); | |
| 144 | |
| 145 manager()->ObserveActivity(kRendererID); | |
| 146 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID)); | |
| 147 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID)); | |
| 148 | |
| 149 SimulateInactivity(manager(), kRendererID); | |
| 150 EXPECT_EQ(0U, active_renderers(manager()).count(kRendererID)); | |
| 151 EXPECT_EQ(1U, inactive_renderers(manager()).count(kRendererID)); | |
| 152 | |
| 153 manager()->ObserveActivity(kRendererID); | |
| 154 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID)); | |
| 155 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID)); | |
| 156 | |
| 157 manager()->Remove(kRendererID); | |
| 158 } | |
| 159 | |
| 160 TEST_F(WebCacheManagerTest, ObserveStatsTest) { | |
| 161 manager()->Add(kRendererID); | |
| 162 | |
| 163 EXPECT_EQ(1U, stats(manager()).size()); | |
| 164 | |
| 165 manager()->ObserveStats(kRendererID, kStats); | |
| 166 | |
| 167 EXPECT_EQ(1U, stats(manager()).size()); | |
| 168 EXPECT_TRUE(kStats == stats(manager())[kRendererID]); | |
| 169 | |
| 170 manager()->Remove(kRendererID); | |
| 171 } | |
| 172 | |
| 173 TEST_F(WebCacheManagerTest, SetGlobalSizeLimitTest) { | |
| 174 size_t limit = manager()->GetDefaultGlobalSizeLimit(); | |
| 175 manager()->SetGlobalSizeLimit(limit); | |
| 176 EXPECT_EQ(limit, manager()->global_size_limit()); | |
| 177 | |
| 178 manager()->SetGlobalSizeLimit(0); | |
| 179 EXPECT_EQ(0U, manager()->global_size_limit()); | |
| 180 } | |
| 181 | |
| 182 TEST_F(WebCacheManagerTest, GatherStatsTest) { | |
| 183 manager()->Add(kRendererID); | |
| 184 manager()->Add(kRendererID2); | |
| 185 | |
| 186 manager()->ObserveStats(kRendererID, kStats); | |
| 187 manager()->ObserveStats(kRendererID2, kStats2); | |
| 188 | |
| 189 std::set<int> renderer_set; | |
| 190 renderer_set.insert(kRendererID); | |
| 191 | |
| 192 WebCache::UsageStats stats; | |
| 193 GatherStats(manager(), renderer_set, &stats); | |
| 194 | |
| 195 EXPECT_TRUE(kStats == stats); | |
| 196 | |
| 197 renderer_set.insert(kRendererID2); | |
| 198 GatherStats(manager(), renderer_set, &stats); | |
| 199 | |
| 200 WebCache::UsageStats expected_stats = kStats; | |
| 201 expected_stats.minDeadCapacity += kStats2.minDeadCapacity; | |
| 202 expected_stats.maxDeadCapacity += kStats2.maxDeadCapacity; | |
| 203 expected_stats.capacity += kStats2.capacity; | |
| 204 expected_stats.liveSize += kStats2.liveSize; | |
| 205 expected_stats.deadSize += kStats2.deadSize; | |
| 206 | |
| 207 EXPECT_TRUE(expected_stats == stats); | |
| 208 | |
| 209 manager()->Remove(kRendererID); | |
| 210 manager()->Remove(kRendererID2); | |
| 211 } | |
| 212 | |
| 213 TEST_F(WebCacheManagerTest, GetSizeTest) { | |
| 214 EXPECT_EQ(0U, GetSize(DIVIDE_EVENLY, kStats)); | |
| 215 EXPECT_LT(256 * 1024u + 512, GetSize(KEEP_CURRENT_WITH_HEADROOM, kStats)); | |
| 216 EXPECT_EQ(256 * 1024u + 512, GetSize(KEEP_CURRENT, kStats)); | |
| 217 EXPECT_LT(256 * 1024u, GetSize(KEEP_LIVE_WITH_HEADROOM, kStats)); | |
| 218 EXPECT_EQ(256 * 1024u, GetSize(KEEP_LIVE, kStats)); | |
| 219 } | |
| 220 | |
| 221 TEST_F(WebCacheManagerTest, AttemptTacticTest) { | |
| 222 manager()->Add(kRendererID); | |
| 223 manager()->Add(kRendererID2); | |
| 224 | |
| 225 manager()->ObserveActivity(kRendererID); | |
| 226 SimulateInactivity(manager(), kRendererID2); | |
| 227 | |
| 228 manager()->ObserveStats(kRendererID, kStats); | |
| 229 manager()->ObserveStats(kRendererID2, kStats2); | |
| 230 | |
| 231 manager()->SetGlobalSizeLimit(kStats.liveSize + kStats.deadSize + | |
| 232 kStats2.liveSize + kStats2.deadSize/2); | |
| 233 | |
| 234 AllocationStrategy strategy; | |
| 235 | |
| 236 EXPECT_FALSE(AttemptTactic(manager(), | |
| 237 KEEP_CURRENT, | |
| 238 kStats, | |
| 239 KEEP_CURRENT, | |
| 240 kStats2, | |
| 241 &strategy)); | |
| 242 EXPECT_TRUE(strategy.empty()); | |
| 243 | |
| 244 EXPECT_TRUE(AttemptTactic(manager(), | |
| 245 KEEP_CURRENT, | |
| 246 kStats, | |
| 247 KEEP_LIVE, | |
| 248 kStats2, | |
| 249 &strategy)); | |
| 250 EXPECT_EQ(2U, strategy.size()); | |
| 251 | |
| 252 AllocationStrategy::iterator iter = strategy.begin(); | |
| 253 while (iter != strategy.end()) { | |
| 254 if (iter->first == kRendererID) | |
| 255 EXPECT_LE(kStats.liveSize + kStats.deadSize, iter->second); | |
| 256 else if (iter->first == kRendererID2) | |
| 257 EXPECT_LE(kStats2.liveSize, iter->second); | |
| 258 else | |
| 259 ADD_FAILURE(); // Unexpected entry in strategy. | |
| 260 ++iter; | |
| 261 } | |
| 262 | |
| 263 manager()->Remove(kRendererID); | |
| 264 manager()->Remove(kRendererID2); | |
| 265 } | |
| 266 | |
| 267 TEST_F(WebCacheManagerTest, AddToStrategyTest) { | |
| 268 manager()->Add(kRendererID); | |
| 269 manager()->Add(kRendererID2); | |
| 270 | |
| 271 std::set<int> renderer_set; | |
| 272 renderer_set.insert(kRendererID); | |
| 273 renderer_set.insert(kRendererID2); | |
| 274 | |
| 275 manager()->ObserveStats(kRendererID, kStats); | |
| 276 manager()->ObserveStats(kRendererID2, kStats2); | |
| 277 | |
| 278 const size_t kExtraBytesToAllocate = 10 * 1024; | |
| 279 | |
| 280 AllocationStrategy strategy; | |
| 281 AddToStrategy(manager(), | |
| 282 renderer_set, | |
| 283 KEEP_CURRENT, | |
| 284 kExtraBytesToAllocate, | |
| 285 &strategy); | |
| 286 | |
| 287 EXPECT_EQ(2U, strategy.size()); | |
| 288 | |
| 289 size_t total_bytes = 0; | |
| 290 AllocationStrategy::iterator iter = strategy.begin(); | |
| 291 while (iter != strategy.end()) { | |
| 292 total_bytes += iter->second; | |
| 293 | |
| 294 if (iter->first == kRendererID) | |
| 295 EXPECT_LE(kStats.liveSize + kStats.deadSize, iter->second); | |
| 296 else if (iter->first == kRendererID2) | |
| 297 EXPECT_LE(kStats2.liveSize + kStats2.deadSize, iter->second); | |
| 298 else | |
| 299 ADD_FAILURE(); // Unexpected entry in strategy. | |
| 300 ++iter; | |
| 301 } | |
| 302 | |
| 303 size_t expected_total_bytes = kExtraBytesToAllocate + | |
| 304 kStats.liveSize + kStats.deadSize + | |
| 305 kStats2.liveSize + kStats2.deadSize; | |
| 306 | |
| 307 EXPECT_GE(expected_total_bytes, total_bytes); | |
| 308 | |
| 309 manager()->Remove(kRendererID); | |
| 310 manager()->Remove(kRendererID2); | |
| 311 } | |
| OLD | NEW |