prerender_manager_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 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 "base/time.h" 6#include "chrome/browser/prerender/prerender_contents.h" 7#include "chrome/browser/prerender/prerender_manager.h" 8#include "content/browser/browser_thread.h" 9#include "googleurl/src/gurl.h" 10#include "testing/gtest/include/gtest/gtest.h" 11 12namespace prerender { 13 14namespace { 15 16class DummyPrerenderContents : public PrerenderContents { 17 public: 18 DummyPrerenderContents(PrerenderManager* prerender_manager, 19 const GURL& url, 20 FinalStatus expected_final_status) 21 : PrerenderContents(prerender_manager, NULL, url, 22 std::vector<GURL>(), GURL()), 23 has_started_(false), 24 expected_final_status_(expected_final_status) { 25 } 26 27 DummyPrerenderContents(PrerenderManager* prerender_manager, 28 const GURL& url, 29 const std::vector<GURL> alias_urls, 30 FinalStatus expected_final_status) 31 : PrerenderContents(prerender_manager, NULL, url, alias_urls, GURL()), 32 has_started_(false), 33 expected_final_status_(expected_final_status) { 34 } 35 36 virtual ~DummyPrerenderContents() { 37 EXPECT_EQ(expected_final_status_, final_status()); 38 } 39 40 virtual void StartPrerendering() OVERRIDE { 41 has_started_ = true; 42 } 43 44 bool has_started() const { return has_started_; } 45 46 private: 47 bool has_started_; 48 FinalStatus expected_final_status_; 49}; 50 51class TestPrerenderManager : public PrerenderManager { 52 public: 53 TestPrerenderManager() 54 : PrerenderManager(NULL), 55 time_(base::Time::Now()), 56 next_pc_(NULL) { 57 } 58 59 void AdvanceTime(base::TimeDelta delta) { 60 time_ += delta; 61 } 62 63 void SetNextPrerenderContents(PrerenderContents* pc) { 64 next_pc_.reset(pc); 65 } 66 67 // Shorthand to add a simple preload with no aliases. 68 bool AddSimplePreload(const GURL& url) { 69 return AddPreload(url, std::vector<GURL>(), GURL()); 70 } 71 72 PrerenderContents* next_pc() { return next_pc_.get(); } 73 74 protected: 75 virtual ~TestPrerenderManager() { 76 if (next_pc()) { 77 next_pc()->set_final_status( 78 FINAL_STATUS_MANAGER_SHUTDOWN); 79 } 80 } 81 82 private: 83 virtual base::Time GetCurrentTime() const OVERRIDE { 84 return time_; 85 } 86 87 virtual PrerenderContents* CreatePrerenderContents( 88 const GURL& url, 89 const std::vector<GURL>& alias_urls, 90 const GURL& referrer) OVERRIDE { 91 DCHECK(next_pc_.get()); 92 return next_pc_.release(); 93 } 94 95 base::Time time_; 96 scoped_ptr<PrerenderContents> next_pc_; 97}; 98 99} // namespace 100 101class PrerenderManagerTest : public testing::Test { 102 public: 103 PrerenderManagerTest() : prerender_manager_(new TestPrerenderManager()), 104 ui_thread_(BrowserThread::UI, &message_loop_) { 105 } 106 107 protected: 108 scoped_refptr<TestPrerenderManager> prerender_manager_; 109 110 private: 111 // Needed to pass PrerenderManager's DCHECKs. 112 MessageLoop message_loop_; 113 BrowserThread ui_thread_; 114}; 115 116TEST_F(PrerenderManagerTest, EmptyTest) { 117 GURL url("http://www.google.com/"); 118 EXPECT_FALSE(prerender_manager_->MaybeUsePreloadedPage(NULL, url)); 119} 120 121TEST_F(PrerenderManagerTest, FoundTest) { 122 GURL url("http://www.google.com/"); 123 DummyPrerenderContents* pc = 124 new DummyPrerenderContents(prerender_manager_.get(), 125 url, 126 FINAL_STATUS_USED); 127 prerender_manager_->SetNextPrerenderContents(pc); 128 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url)); 129 EXPECT_TRUE(pc->has_started()); 130 ASSERT_EQ(pc, prerender_manager_->GetEntry(url)); 131 pc->set_final_status(FINAL_STATUS_USED); 132 delete pc; 133} 134 135// Make sure that if queue a request, and a second prerender request for the 136// same URL comes in, that we drop the second request and keep the first one. 137TEST_F(PrerenderManagerTest, DropSecondRequestTest) { 138 GURL url("http://www.google.com/"); 139 DummyPrerenderContents* pc = 140 new DummyPrerenderContents(prerender_manager_.get(), url, 141 FINAL_STATUS_USED); 142 DummyPrerenderContents* null = NULL; 143 prerender_manager_->SetNextPrerenderContents(pc); 144 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url)); 145 EXPECT_EQ(null, prerender_manager_->next_pc()); 146 EXPECT_TRUE(pc->has_started()); 147 DummyPrerenderContents* pc1 = 148 new DummyPrerenderContents( 149 prerender_manager_.get(), url, 150 FINAL_STATUS_MANAGER_SHUTDOWN); 151 prerender_manager_->SetNextPrerenderContents(pc1); 152 EXPECT_FALSE(prerender_manager_->AddSimplePreload(url)); 153 EXPECT_EQ(pc1, prerender_manager_->next_pc()); 154 EXPECT_FALSE(pc1->has_started()); 155 ASSERT_EQ(pc, prerender_manager_->GetEntry(url)); 156 pc->set_final_status(FINAL_STATUS_USED); 157 delete pc; 158} 159 160// Ensure that we expire a prerendered page after the max. permitted time. 161TEST_F(PrerenderManagerTest, ExpireTest) { 162 GURL url("http://www.google.com/"); 163 DummyPrerenderContents* pc = 164 new DummyPrerenderContents(prerender_manager_.get(), url, 165 FINAL_STATUS_TIMED_OUT); 166 DummyPrerenderContents* null = NULL; 167 prerender_manager_->SetNextPrerenderContents(pc); 168 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url)); 169 EXPECT_EQ(null, prerender_manager_->next_pc()); 170 EXPECT_TRUE(pc->has_started()); 171 prerender_manager_->AdvanceTime(prerender_manager_->max_prerender_age() 172 + base::TimeDelta::FromSeconds(1)); 173 ASSERT_EQ(null, prerender_manager_->GetEntry(url)); 174} 175 176// LRU Test. Make sure that if we prerender more than one request, that 177// the oldest one will be dropped. 178TEST_F(PrerenderManagerTest, DropOldestRequestTest) { 179 GURL url("http://www.google.com/"); 180 DummyPrerenderContents* pc = 181 new DummyPrerenderContents(prerender_manager_.get(), url, 182 FINAL_STATUS_EVICTED); 183 DummyPrerenderContents* null = NULL; 184 prerender_manager_->SetNextPrerenderContents(pc); 185 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url)); 186 EXPECT_EQ(null, prerender_manager_->next_pc()); 187 EXPECT_TRUE(pc->has_started()); 188 GURL url1("http://news.google.com/"); 189 DummyPrerenderContents* pc1 = 190 new DummyPrerenderContents(prerender_manager_.get(), url1, 191 FINAL_STATUS_USED); 192 prerender_manager_->SetNextPrerenderContents(pc1); 193 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url1)); 194 EXPECT_EQ(null, prerender_manager_->next_pc()); 195 EXPECT_TRUE(pc1->has_started()); 196 ASSERT_EQ(null, prerender_manager_->GetEntry(url)); 197 ASSERT_EQ(pc1, prerender_manager_->GetEntry(url1)); 198 pc1->set_final_status(FINAL_STATUS_USED); 199 delete pc1; 200} 201 202// Two element prerender test. Ensure that the LRU operates correctly if we 203// permit 2 elements to be kept prerendered. 204TEST_F(PrerenderManagerTest, TwoElementPrerenderTest) { 205 prerender_manager_->set_max_elements(2); 206 GURL url("http://www.google.com/"); 207 DummyPrerenderContents* pc = 208 new DummyPrerenderContents(prerender_manager_.get(), url, 209 FINAL_STATUS_EVICTED); 210 DummyPrerenderContents* null = NULL; 211 prerender_manager_->SetNextPrerenderContents(pc); 212 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url)); 213 EXPECT_EQ(null, prerender_manager_->next_pc()); 214 EXPECT_TRUE(pc->has_started()); 215 GURL url1("http://news.google.com/"); 216 DummyPrerenderContents* pc1 = 217 new DummyPrerenderContents(prerender_manager_.get(), url1, 218 FINAL_STATUS_USED); 219 prerender_manager_->SetNextPrerenderContents(pc1); 220 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url1)); 221 EXPECT_EQ(null, prerender_manager_->next_pc()); 222 EXPECT_TRUE(pc1->has_started()); 223 GURL url2("http://images.google.com/"); 224 DummyPrerenderContents* pc2 = 225 new DummyPrerenderContents(prerender_manager_.get(), url2, 226 FINAL_STATUS_USED); 227 prerender_manager_->SetNextPrerenderContents(pc2); 228 EXPECT_TRUE(prerender_manager_->AddSimplePreload(url2)); 229 EXPECT_EQ(null, prerender_manager_->next_pc()); 230 EXPECT_TRUE(pc2->has_started()); 231 ASSERT_EQ(null, prerender_manager_->GetEntry(url)); 232 ASSERT_EQ(pc1, prerender_manager_->GetEntry(url1)); 233 ASSERT_EQ(pc2, prerender_manager_->GetEntry(url2)); 234 pc1->set_final_status(FINAL_STATUS_USED); 235 delete pc1; 236 pc2->set_final_status(FINAL_STATUS_USED); 237 delete pc2; 238} 239 240TEST_F(PrerenderManagerTest, AliasURLTest) { 241 GURL url("http://www.google.com/"); 242 GURL alias_url1("http://www.google.com/index.html"); 243 GURL alias_url2("http://google.com/"); 244 GURL not_an_alias_url("http://google.com/index.html"); 245 std::vector<GURL> alias_urls; 246 alias_urls.push_back(alias_url1); 247 alias_urls.push_back(alias_url2); 248 DummyPrerenderContents* pc = 249 new DummyPrerenderContents(prerender_manager_.get(), url, alias_urls, 250 FINAL_STATUS_USED); 251 // Test that all of the aliases work, but nont_an_alias_url does not. 252 prerender_manager_->SetNextPrerenderContents(pc); 253 EXPECT_TRUE(prerender_manager_->AddPreload(url, alias_urls, GURL())); 254 ASSERT_EQ(NULL, prerender_manager_->GetEntry(not_an_alias_url)); 255 ASSERT_EQ(pc, prerender_manager_->GetEntry(alias_url1)); 256 prerender_manager_->SetNextPrerenderContents(pc); 257 EXPECT_TRUE(prerender_manager_->AddPreload(url, alias_urls, GURL())); 258 ASSERT_EQ(pc, prerender_manager_->GetEntry(alias_url2)); 259 prerender_manager_->SetNextPrerenderContents(pc); 260 EXPECT_TRUE(prerender_manager_->AddPreload(url, alias_urls, GURL())); 261 ASSERT_EQ(pc, prerender_manager_->GetEntry(url)); 262 263 // Test that alias URLs can not be added. 264 prerender_manager_->SetNextPrerenderContents(pc); 265 EXPECT_TRUE(prerender_manager_->AddPreload(url, alias_urls, GURL())); 266 EXPECT_FALSE(prerender_manager_->AddSimplePreload(url)); 267 EXPECT_FALSE(prerender_manager_->AddSimplePreload(alias_url1)); 268 EXPECT_FALSE(prerender_manager_->AddSimplePreload(alias_url2)); 269 ASSERT_EQ(pc, prerender_manager_->GetEntry(url)); 270 271 pc->set_final_status(FINAL_STATUS_USED); 272 delete pc; 273} 274 275} // naemspace prerender 276