Home | History | Annotate | Download | only in renderer_host
      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 
     27   WebCacheManagerTest()
     28       : ui_thread_(BrowserThread::UI, &message_loop_) {
     29   }
     30 
     31   // Thunks to access protected members of WebCacheManager
     32   static std::map<int, WebCacheManager::RendererInfo>& stats(
     33         WebCacheManager* h) {
     34     return h->stats_;
     35   }
     36 
     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 
     43   static std::set<int>& active_renderers(WebCacheManager* h) {
     44     return h->active_renderers_;
     45   }
     46   static std::set<int>& inactive_renderers(WebCacheManager* h) {
     47     return h->inactive_renderers_;
     48   }
     49   static void GatherStats(WebCacheManager* h,
     50                           std::set<int> renderers,
     51                           WebCache::UsageStats* stats) {
     52     h->GatherStats(renderers, stats);
     53   }
     54   static size_t GetSize(int tactic,
     55                         const WebCache::UsageStats& stats) {
     56     return WebCacheManager::GetSize(
     57         static_cast<WebCacheManager::AllocationTactic>(tactic), stats);
     58   }
     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   }
     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 
     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 
    123 static bool operator==(const WebCache::UsageStats& lhs,
    124                        const WebCache::UsageStats& rhs) {
    125   return !::memcmp(&lhs, &rhs, sizeof(WebCache::UsageStats));
    126 }
    127 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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