Home | History | Annotate | Download | only in renderer_host
      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 WebKit::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 }
    312