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.
7 #include "base/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"
13 using base::TimeDelta
;
14 using content::BrowserThread
;
15 using WebKit::WebCache
;
17 class WebCacheManagerTest
: public testing::Test
{
19 typedef WebCacheManager::StatsMap StatsMap
;
20 typedef WebCacheManager::Allocation Allocation
;
21 typedef WebCacheManager::AllocationStrategy AllocationStrategy
;
23 static const int kRendererID
;
24 static const int kRendererID2
;
25 static const WebCache::UsageStats kStats
;
26 static const WebCache::UsageStats kStats2
;
29 : ui_thread_(BrowserThread::UI
, &message_loop_
) {
32 // Thunks to access protected members of WebCacheManager
33 static std::map
<int, WebCacheManager::RendererInfo
>& stats(
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();
44 static std::set
<int>& active_renderers(WebCacheManager
* h
) {
45 return h
->active_renderers_
;
47 static std::set
<int>& inactive_renderers(WebCacheManager
* h
) {
48 return h
->inactive_renderers_
;
50 static void GatherStats(WebCacheManager
* h
,
51 std::set
<int> renderers
,
52 WebCache::UsageStats
* stats
) {
53 h
->GatherStats(renderers
, stats
);
55 static size_t GetSize(int tactic
,
56 const WebCache::UsageStats
& stats
) {
57 return WebCacheManager::GetSize(
58 static_cast<WebCacheManager::AllocationTactic
>(tactic
), stats
);
60 static bool AttemptTactic(WebCacheManager
* h
,
62 const WebCache::UsageStats
& active_stats
,
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
),
69 static_cast<WebCacheManager::AllocationTactic
>(inactive_tactic
),
73 static void AddToStrategy(WebCacheManager
* h
,
74 std::set
<int> renderers
,
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
,
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
,
92 WebCacheManager
* manager() { return &manager_
; }
95 WebCacheManager manager_
;
96 MessageLoop message_loop_
;
97 content::TestBrowserThread ui_thread_
;
101 const int WebCacheManagerTest::kRendererID
= 146;
104 const int WebCacheManagerTest::kRendererID2
= 245;
107 const WebCache::UsageStats
WebCacheManagerTest::kStats
= {
116 const WebCache::UsageStats
WebCacheManagerTest::kStats2
= {
124 static bool operator==(const WebCache::UsageStats
& lhs
,
125 const WebCache::UsageStats
& rhs
) {
126 return !::memcmp(&lhs
, &rhs
, sizeof(WebCache::UsageStats
));
129 TEST_F(WebCacheManagerTest
, AddRemoveRendererTest
) {
130 EXPECT_EQ(0U, active_renderers(manager()).size());
131 EXPECT_EQ(0U, inactive_renderers(manager()).size());
133 manager()->Add(kRendererID
);
134 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID
));
135 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID
));
137 manager()->Remove(kRendererID
);
138 EXPECT_EQ(0U, active_renderers(manager()).size());
139 EXPECT_EQ(0U, inactive_renderers(manager()).size());
142 TEST_F(WebCacheManagerTest
, ActiveInactiveTest
) {
143 manager()->Add(kRendererID
);
145 manager()->ObserveActivity(kRendererID
);
146 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID
));
147 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID
));
149 SimulateInactivity(manager(), kRendererID
);
150 EXPECT_EQ(0U, active_renderers(manager()).count(kRendererID
));
151 EXPECT_EQ(1U, inactive_renderers(manager()).count(kRendererID
));
153 manager()->ObserveActivity(kRendererID
);
154 EXPECT_EQ(1U, active_renderers(manager()).count(kRendererID
));
155 EXPECT_EQ(0U, inactive_renderers(manager()).count(kRendererID
));
157 manager()->Remove(kRendererID
);
160 TEST_F(WebCacheManagerTest
, ObserveStatsTest
) {
161 manager()->Add(kRendererID
);
163 EXPECT_EQ(1U, stats(manager()).size());
165 manager()->ObserveStats(kRendererID
, kStats
);
167 EXPECT_EQ(1U, stats(manager()).size());
168 EXPECT_TRUE(kStats
== stats(manager())[kRendererID
]);
170 manager()->Remove(kRendererID
);
173 TEST_F(WebCacheManagerTest
, SetGlobalSizeLimitTest
) {
174 size_t limit
= manager()->GetDefaultGlobalSizeLimit();
175 manager()->SetGlobalSizeLimit(limit
);
176 EXPECT_EQ(limit
, manager()->global_size_limit());
178 manager()->SetGlobalSizeLimit(0);
179 EXPECT_EQ(0U, manager()->global_size_limit());
182 TEST_F(WebCacheManagerTest
, GatherStatsTest
) {
183 manager()->Add(kRendererID
);
184 manager()->Add(kRendererID2
);
186 manager()->ObserveStats(kRendererID
, kStats
);
187 manager()->ObserveStats(kRendererID2
, kStats2
);
189 std::set
<int> renderer_set
;
190 renderer_set
.insert(kRendererID
);
192 WebCache::UsageStats stats
;
193 GatherStats(manager(), renderer_set
, &stats
);
195 EXPECT_TRUE(kStats
== stats
);
197 renderer_set
.insert(kRendererID2
);
198 GatherStats(manager(), renderer_set
, &stats
);
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
;
207 EXPECT_TRUE(expected_stats
== stats
);
209 manager()->Remove(kRendererID
);
210 manager()->Remove(kRendererID2
);
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
));
221 TEST_F(WebCacheManagerTest
, AttemptTacticTest
) {
222 manager()->Add(kRendererID
);
223 manager()->Add(kRendererID2
);
225 manager()->ObserveActivity(kRendererID
);
226 SimulateInactivity(manager(), kRendererID2
);
228 manager()->ObserveStats(kRendererID
, kStats
);
229 manager()->ObserveStats(kRendererID2
, kStats2
);
231 manager()->SetGlobalSizeLimit(kStats
.liveSize
+ kStats
.deadSize
+
232 kStats2
.liveSize
+ kStats2
.deadSize
/2);
234 AllocationStrategy strategy
;
236 EXPECT_FALSE(AttemptTactic(manager(),
242 EXPECT_TRUE(strategy
.empty());
244 EXPECT_TRUE(AttemptTactic(manager(),
250 EXPECT_EQ(2U, strategy
.size());
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
);
259 ADD_FAILURE(); // Unexpected entry in strategy.
263 manager()->Remove(kRendererID
);
264 manager()->Remove(kRendererID2
);
267 TEST_F(WebCacheManagerTest
, AddToStrategyTest
) {
268 manager()->Add(kRendererID
);
269 manager()->Add(kRendererID2
);
271 std::set
<int> renderer_set
;
272 renderer_set
.insert(kRendererID
);
273 renderer_set
.insert(kRendererID2
);
275 manager()->ObserveStats(kRendererID
, kStats
);
276 manager()->ObserveStats(kRendererID2
, kStats2
);
278 const size_t kExtraBytesToAllocate
= 10 * 1024;
280 AllocationStrategy strategy
;
281 AddToStrategy(manager(),
284 kExtraBytesToAllocate
,
287 EXPECT_EQ(2U, strategy
.size());
289 size_t total_bytes
= 0;
290 AllocationStrategy::iterator iter
= strategy
.begin();
291 while (iter
!= strategy
.end()) {
292 total_bytes
+= iter
->second
;
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
);
299 ADD_FAILURE(); // Unexpected entry in strategy.
303 size_t expected_total_bytes
= kExtraBytesToAllocate
+
304 kStats
.liveSize
+ kStats
.deadSize
+
305 kStats2
.liveSize
+ kStats2
.deadSize
;
307 EXPECT_GE(expected_total_bytes
, total_bytes
);
309 manager()->Remove(kRendererID
);
310 manager()->Remove(kRendererID2
);