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