1 // Copyright (c) 2012 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 <map> 6 #include <utility> 7 8 #include "base/command_line.h" 9 #include "base/format_macros.h" 10 #include "base/memory/scoped_vector.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/metrics/field_trial.h" 13 #include "base/prefs/pref_service.h" 14 #include "base/strings/stringprintf.h" 15 #include "base/time/time.h" 16 #include "chrome/browser/net/prediction_options.h" 17 #include "chrome/browser/prerender/prerender_contents.h" 18 #include "chrome/browser/prerender/prerender_handle.h" 19 #include "chrome/browser/prerender/prerender_link_manager.h" 20 #include "chrome/browser/prerender/prerender_manager.h" 21 #include "chrome/browser/prerender/prerender_origin.h" 22 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/pref_names.h" 24 #include "chrome/common/prerender_types.h" 25 #include "chrome/test/base/testing_browser_process.h" 26 #include "chrome/test/base/testing_profile.h" 27 #include "content/public/browser/render_view_host.h" 28 #include "content/public/test/test_browser_thread.h" 29 #include "testing/gtest/include/gtest/gtest.h" 30 #include "ui/gfx/size.h" 31 #include "url/gurl.h" 32 33 using base::Time; 34 using base::TimeDelta; 35 using base::TimeTicks; 36 using content::BrowserThread; 37 using content::Referrer; 38 39 namespace prerender { 40 41 class UnitTestPrerenderManager; 42 43 namespace { 44 45 class DummyPrerenderContents : public PrerenderContents { 46 public: 47 DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager, 48 PrerenderTracker* prerender_tracker, 49 const GURL& url, 50 Origin origin, 51 FinalStatus expected_final_status); 52 53 virtual ~DummyPrerenderContents(); 54 55 virtual void StartPrerendering( 56 int ALLOW_UNUSED creator_child_id, 57 const gfx::Size& ALLOW_UNUSED size, 58 content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace, 59 net::URLRequestContextGetter* ALLOW_UNUSED request_context) 60 OVERRIDE; 61 62 virtual bool GetChildId(int* child_id) const OVERRIDE { 63 // Having a default child_id of -1 forces pending prerenders not to fail 64 // on session storage and cross domain checking. 65 *child_id = -1; 66 return true; 67 } 68 69 virtual bool GetRouteId(int* route_id) const OVERRIDE { 70 *route_id = route_id_; 71 return true; 72 } 73 74 FinalStatus expected_final_status() const { return expected_final_status_; } 75 76 bool prerendering_has_been_cancelled() const { 77 return PrerenderContents::prerendering_has_been_cancelled(); 78 } 79 80 private: 81 static int g_next_route_id_; 82 int route_id_; 83 84 UnitTestPrerenderManager* test_prerender_manager_; 85 FinalStatus expected_final_status_; 86 }; 87 88 int DummyPrerenderContents::g_next_route_id_ = 0; 89 90 const gfx::Size kSize(640, 480); 91 92 const uint32 kDefaultRelTypes = PrerenderRelTypePrerender; 93 94 } // namespace 95 96 class UnitTestPrerenderManager : public PrerenderManager { 97 public: 98 using PrerenderManager::kMinTimeBetweenPrerendersMs; 99 using PrerenderManager::kNavigationRecordWindowMs; 100 101 explicit UnitTestPrerenderManager(Profile* profile, 102 PrerenderTracker* prerender_tracker) 103 : PrerenderManager(profile, prerender_tracker), 104 time_(Time::Now()), 105 time_ticks_(TimeTicks::Now()), 106 prerender_tracker_(prerender_tracker) { 107 set_rate_limit_enabled(false); 108 OnCookieStoreLoaded(); 109 } 110 111 virtual ~UnitTestPrerenderManager() { 112 } 113 114 // From KeyedService, via PrererenderManager: 115 virtual void Shutdown() OVERRIDE { 116 if (next_prerender_contents()) 117 next_prerender_contents_->Destroy(FINAL_STATUS_MANAGER_SHUTDOWN); 118 PrerenderManager::Shutdown(); 119 } 120 121 // From PrerenderManager: 122 virtual void MoveEntryToPendingDelete(PrerenderContents* entry, 123 FinalStatus final_status) OVERRIDE { 124 if (entry == next_prerender_contents_.get()) 125 return; 126 PrerenderManager::MoveEntryToPendingDelete(entry, final_status); 127 } 128 129 PrerenderContents* FindEntry(const GURL& url) { 130 DeleteOldEntries(); 131 to_delete_prerenders_.clear(); 132 if (PrerenderData* data = FindPrerenderData(url, NULL)) 133 return data->contents(); 134 return NULL; 135 } 136 137 PrerenderContents* FindAndUseEntry(const GURL& url) { 138 PrerenderData* prerender_data = FindPrerenderData(url, NULL); 139 if (!prerender_data) 140 return NULL; 141 ScopedVector<PrerenderData>::iterator to_erase = 142 FindIteratorForPrerenderContents(prerender_data->contents()); 143 CHECK(to_erase != active_prerenders_.end()); 144 PrerenderContents* prerender_contents = prerender_data->ReleaseContents(); 145 active_prerenders_.erase(to_erase); 146 147 prerender_contents->PrepareForUse(); 148 return prerender_contents; 149 } 150 151 void AdvanceTime(TimeDelta delta) { 152 time_ += delta; 153 } 154 155 void AdvanceTimeTicks(TimeDelta delta) { 156 time_ticks_ += delta; 157 } 158 159 DummyPrerenderContents* CreateNextPrerenderContents( 160 const GURL& url, 161 FinalStatus expected_final_status) { 162 DummyPrerenderContents* prerender_contents = 163 new DummyPrerenderContents(this, prerender_tracker_, url, 164 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, 165 expected_final_status); 166 SetNextPrerenderContents(prerender_contents); 167 return prerender_contents; 168 } 169 170 DummyPrerenderContents* CreateNextPrerenderContents( 171 const GURL& url, 172 Origin origin, 173 FinalStatus expected_final_status) { 174 DummyPrerenderContents* prerender_contents = 175 new DummyPrerenderContents(this, prerender_tracker_, url, 176 origin, expected_final_status); 177 SetNextPrerenderContents(prerender_contents); 178 return prerender_contents; 179 } 180 181 DummyPrerenderContents* CreateNextPrerenderContents( 182 const GURL& url, 183 const std::vector<GURL>& alias_urls, 184 FinalStatus expected_final_status) { 185 DummyPrerenderContents* prerender_contents = 186 new DummyPrerenderContents(this, prerender_tracker_, url, 187 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN, 188 expected_final_status); 189 for (std::vector<GURL>::const_iterator it = alias_urls.begin(); 190 it != alias_urls.end(); 191 ++it) { 192 EXPECT_TRUE(prerender_contents->AddAliasURL(*it)); 193 } 194 SetNextPrerenderContents(prerender_contents); 195 return prerender_contents; 196 } 197 198 void set_rate_limit_enabled(bool enabled) { 199 mutable_config().rate_limit_enabled = enabled; 200 } 201 202 PrerenderContents* next_prerender_contents() { 203 return next_prerender_contents_.get(); 204 } 205 206 // from PrerenderManager 207 virtual Time GetCurrentTime() const OVERRIDE { 208 return time_; 209 } 210 211 virtual TimeTicks GetCurrentTimeTicks() const OVERRIDE { 212 return time_ticks_; 213 } 214 215 virtual PrerenderContents* GetPrerenderContentsForRoute( 216 int child_id, int route_id) const OVERRIDE { 217 // Overridden for the PrerenderLinkManager's pending prerender logic. 218 PrerenderContentsMap::const_iterator iter = prerender_contents_map_.find( 219 std::make_pair(child_id, route_id)); 220 if (iter == prerender_contents_map_.end()) 221 return NULL; 222 return iter->second; 223 } 224 225 void DummyPrerenderContentsStarted(int child_id, 226 int route_id, 227 PrerenderContents* prerender_contents) { 228 prerender_contents_map_[std::make_pair(child_id, route_id)] = 229 prerender_contents; 230 } 231 232 void DummyPrerenderContentsDestroyed(int child_id, 233 int route_id) { 234 prerender_contents_map_.erase(std::make_pair(child_id, route_id)); 235 } 236 237 protected: 238 virtual net::URLRequestContextGetter* GetURLRequestContext() OVERRIDE { 239 return NULL; 240 } 241 242 private: 243 void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) { 244 CHECK(!next_prerender_contents_.get()); 245 next_prerender_contents_.reset(prerender_contents); 246 if (prerender_contents->expected_final_status() == FINAL_STATUS_USED) 247 used_prerender_contents_.push_back(prerender_contents); 248 } 249 250 251 virtual PrerenderContents* CreatePrerenderContents( 252 const GURL& url, 253 const Referrer& referrer, 254 Origin origin, 255 uint8 experiment_id) OVERRIDE { 256 CHECK(next_prerender_contents_.get()); 257 EXPECT_EQ(url, next_prerender_contents_->prerender_url()); 258 EXPECT_EQ(origin, next_prerender_contents_->origin()); 259 return next_prerender_contents_.release(); 260 } 261 262 // Maintain a map from route pairs to PrerenderContents for 263 // GetPrerenderContentsForRoute. 264 typedef std::map<std::pair<int,int>, PrerenderContents*> PrerenderContentsMap; 265 PrerenderContentsMap prerender_contents_map_; 266 267 Time time_; 268 TimeTicks time_ticks_; 269 scoped_ptr<PrerenderContents> next_prerender_contents_; 270 // PrerenderContents with an |expected_final_status| of FINAL_STATUS_USED, 271 // tracked so they will be automatically deleted. 272 ScopedVector<PrerenderContents> used_prerender_contents_; 273 274 PrerenderTracker* prerender_tracker_; 275 }; 276 277 class RestorePrerenderMode { 278 public: 279 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) { 280 } 281 282 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); } 283 private: 284 PrerenderManager::PrerenderManagerMode prev_mode_; 285 }; 286 287 DummyPrerenderContents::DummyPrerenderContents( 288 UnitTestPrerenderManager* test_prerender_manager, 289 PrerenderTracker* prerender_tracker, 290 const GURL& url, 291 Origin origin, 292 FinalStatus expected_final_status) 293 : PrerenderContents(test_prerender_manager, 294 NULL, url, Referrer(), origin, 295 PrerenderManager::kNoExperiment), 296 route_id_(g_next_route_id_++), 297 test_prerender_manager_(test_prerender_manager), 298 expected_final_status_(expected_final_status) { 299 } 300 301 DummyPrerenderContents::~DummyPrerenderContents() { 302 EXPECT_EQ(expected_final_status_, final_status()); 303 test_prerender_manager_->DummyPrerenderContentsDestroyed(-1, route_id_); 304 } 305 306 void DummyPrerenderContents::StartPrerendering( 307 int ALLOW_UNUSED creator_child_id, 308 const gfx::Size& ALLOW_UNUSED size, 309 content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace, 310 net::URLRequestContextGetter* ALLOW_UNUSED request_context) { 311 // In the base PrerenderContents implementation, StartPrerendering will 312 // be called even when the PrerenderManager is part of the control group, 313 // but it will early exit before actually creating a new RenderView if 314 // |is_control_group| is true; 315 load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks(); 316 if (!test_prerender_manager_->IsControlGroup(experiment_id())) { 317 prerendering_has_started_ = true; 318 test_prerender_manager_->DummyPrerenderContentsStarted(-1, route_id_, this); 319 NotifyPrerenderStart(); 320 } 321 } 322 323 class PrerenderTest : public testing::Test { 324 public: 325 static const int kDefaultChildId = -1; 326 static const int kDefaultRenderViewRouteId = -1; 327 328 PrerenderTest() : ui_thread_(BrowserThread::UI, &message_loop_), 329 prerender_manager_(new UnitTestPrerenderManager( 330 &profile_, prerender_tracker())), 331 prerender_link_manager_( 332 new PrerenderLinkManager(prerender_manager_.get())), 333 last_prerender_id_(0), 334 field_trial_list_(NULL) { 335 // Enable omnibox prerendering. 336 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 337 switches::kPrerenderFromOmnibox, 338 switches::kPrerenderFromOmniboxSwitchValueEnabled); 339 } 340 341 virtual ~PrerenderTest() { 342 prerender_link_manager_->OnChannelClosing(kDefaultChildId); 343 prerender_link_manager_->Shutdown(); 344 prerender_manager_->Shutdown(); 345 } 346 347 UnitTestPrerenderManager* prerender_manager() { 348 return prerender_manager_.get(); 349 } 350 351 PrerenderLinkManager* prerender_link_manager() { 352 return prerender_link_manager_.get(); 353 } 354 355 void SetConcurrency(size_t concurrency) { 356 prerender_manager()->mutable_config().max_link_concurrency_per_launcher = 357 concurrency; 358 prerender_manager()->mutable_config().max_link_concurrency = 359 std::max(prerender_manager()->mutable_config().max_link_concurrency, 360 concurrency); 361 } 362 363 bool IsEmptyPrerenderLinkManager() const { 364 return prerender_link_manager_->IsEmpty(); 365 } 366 367 int last_prerender_id() const { 368 return last_prerender_id_; 369 } 370 371 int GetNextPrerenderID() { 372 return ++last_prerender_id_; 373 } 374 375 bool LauncherHasRunningPrerender(int child_id, int prerender_id) { 376 PrerenderLinkManager::LinkPrerender* prerender = 377 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId( 378 child_id, prerender_id); 379 return prerender && prerender->handle; 380 } 381 382 bool LauncherHasScheduledPrerender(int child_id, int prerender_id) { 383 PrerenderLinkManager::LinkPrerender* prerender = 384 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId( 385 child_id, prerender_id); 386 return prerender != NULL; 387 } 388 389 // Shorthand to add a simple prerender with a reasonable source. Returns 390 // true iff the prerender has been added to the PrerenderManager by the 391 // PrerenderLinkManager and the PrerenderManager returned a handle. 392 bool AddSimplePrerender(const GURL& url) { 393 prerender_link_manager()->OnAddPrerender( 394 kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes, 395 content::Referrer(), kSize, kDefaultRenderViewRouteId); 396 return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id()); 397 } 398 399 void DisablePrerender() { 400 profile_.GetPrefs()->SetInteger( 401 prefs::kNetworkPredictionOptions, 402 chrome_browser_net::NETWORK_PREDICTION_NEVER); 403 } 404 405 private: 406 PrerenderTracker* prerender_tracker() { 407 return g_browser_process->prerender_tracker(); 408 } 409 410 // Needed to pass PrerenderManager's DCHECKs. 411 TestingProfile profile_; 412 base::MessageLoop message_loop_; 413 content::TestBrowserThread ui_thread_; 414 scoped_ptr<UnitTestPrerenderManager> prerender_manager_; 415 scoped_ptr<PrerenderLinkManager> prerender_link_manager_; 416 int last_prerender_id_; 417 base::FieldTrialList field_trial_list_; 418 }; 419 420 TEST_F(PrerenderTest, FoundTest) { 421 GURL url("http://www.google.com/"); 422 DummyPrerenderContents* prerender_contents = 423 prerender_manager()->CreateNextPrerenderContents( 424 url, 425 FINAL_STATUS_USED); 426 EXPECT_TRUE(AddSimplePrerender(url)); 427 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 428 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 429 } 430 431 // Make sure that if queue a request, and a second prerender request for the 432 // same URL comes in, that the second request attaches to the first prerender, 433 // and we don't use the second prerender contents. 434 TEST_F(PrerenderTest, DuplicateTest) { 435 SetConcurrency(2); 436 GURL url("http://www.google.com/"); 437 DummyPrerenderContents* prerender_contents = 438 prerender_manager()->CreateNextPrerenderContents( 439 url, 440 FINAL_STATUS_USED); 441 DummyPrerenderContents* null = NULL; 442 EXPECT_TRUE(AddSimplePrerender(url)); 443 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 444 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 445 446 DummyPrerenderContents* prerender_contents1 = 447 prerender_manager()->CreateNextPrerenderContents( 448 url, 449 FINAL_STATUS_MANAGER_SHUTDOWN); 450 EXPECT_TRUE(AddSimplePrerender(url)); 451 EXPECT_EQ(prerender_contents1, 452 prerender_manager()->next_prerender_contents()); 453 EXPECT_FALSE(prerender_contents1->prerendering_has_started()); 454 455 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 456 } 457 458 // Ensure that we expire a prerendered page after the max. permitted time. 459 TEST_F(PrerenderTest, ExpireTest) { 460 GURL url("http://www.google.com/"); 461 DummyPrerenderContents* prerender_contents = 462 prerender_manager()->CreateNextPrerenderContents( 463 url, 464 FINAL_STATUS_TIMED_OUT); 465 DummyPrerenderContents* null = NULL; 466 EXPECT_TRUE(AddSimplePrerender(url)); 467 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 468 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 469 prerender_manager()->AdvanceTimeTicks( 470 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1)); 471 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 472 } 473 474 // Ensure that we don't launch prerenders of bad urls (in this case, a mailto: 475 // url) 476 TEST_F(PrerenderTest, BadURLTest) { 477 GURL url("mailto:test (at) gmail.com"); 478 DummyPrerenderContents* prerender_contents = 479 prerender_manager()->CreateNextPrerenderContents( 480 url, 481 FINAL_STATUS_UNSUPPORTED_SCHEME); 482 EXPECT_FALSE(AddSimplePrerender(url)); 483 EXPECT_FALSE(prerender_contents->prerendering_has_started()); 484 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 485 DummyPrerenderContents* null = NULL; 486 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 487 } 488 489 // When the user navigates away from a page, the prerenders it launched should 490 // have their time to expiry shortened from the default time to live. 491 TEST_F(PrerenderTest, LinkManagerNavigateAwayExpire) { 492 const TimeDelta time_to_live = TimeDelta::FromSeconds(300); 493 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20); 494 const TimeDelta test_advance = TimeDelta::FromSeconds(22); 495 ASSERT_LT(test_advance, time_to_live); 496 ASSERT_LT(abandon_time_to_live, test_advance); 497 498 prerender_manager()->mutable_config().time_to_live = time_to_live; 499 prerender_manager()->mutable_config().abandon_time_to_live = 500 abandon_time_to_live; 501 502 GURL url("http://example.com"); 503 DummyPrerenderContents* prerender_contents = 504 prerender_manager()->CreateNextPrerenderContents(url, 505 FINAL_STATUS_TIMED_OUT); 506 EXPECT_TRUE(AddSimplePrerender(url)); 507 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 508 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 509 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 510 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 511 last_prerender_id()); 512 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 513 DummyPrerenderContents* null = NULL; 514 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 515 prerender_manager()->AdvanceTimeTicks(test_advance); 516 517 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 518 } 519 520 // But when we navigate away very close to the original expiry of a prerender, 521 // we shouldn't expect it to be extended. 522 TEST_F(PrerenderTest, LinkManagerNavigateAwayNearExpiry) { 523 const TimeDelta time_to_live = TimeDelta::FromSeconds(300); 524 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20); 525 526 // We will expect the prerender to still be alive after advancing the clock 527 // by first_advance. But, after second_advance, we expect it to have timed 528 // out, demonstrating that you can't extend a prerender by navigating away 529 // from its launcher. 530 const TimeDelta first_advance = TimeDelta::FromSeconds(298); 531 const TimeDelta second_advance = TimeDelta::FromSeconds(4); 532 ASSERT_LT(first_advance, time_to_live); 533 ASSERT_LT(time_to_live - first_advance, abandon_time_to_live); 534 ASSERT_LT(time_to_live, first_advance + second_advance); 535 536 prerender_manager()->mutable_config().time_to_live = time_to_live; 537 prerender_manager()->mutable_config().abandon_time_to_live = 538 abandon_time_to_live; 539 540 GURL url("http://example2.com"); 541 DummyPrerenderContents* prerender_contents = 542 prerender_manager()->CreateNextPrerenderContents(url, 543 FINAL_STATUS_TIMED_OUT); 544 EXPECT_TRUE(AddSimplePrerender(url)); 545 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 546 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 547 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 548 549 prerender_manager()->AdvanceTimeTicks(first_advance); 550 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 551 552 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 553 last_prerender_id()); 554 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 555 556 DummyPrerenderContents* null = NULL; 557 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 558 559 prerender_manager()->AdvanceTimeTicks(second_advance); 560 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 561 } 562 563 // When the user navigates away from a page, and then launches a new prerender, 564 // the new prerender should preempt the abandoned prerender even if the 565 // abandoned prerender hasn't expired. 566 TEST_F(PrerenderTest, LinkManagerNavigateAwayLaunchAnother) { 567 const TimeDelta time_to_live = TimeDelta::FromSeconds(300); 568 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20); 569 const TimeDelta test_advance = TimeDelta::FromSeconds(5); 570 ASSERT_LT(test_advance, time_to_live); 571 ASSERT_GT(abandon_time_to_live, test_advance); 572 573 prerender_manager()->mutable_config().time_to_live = time_to_live; 574 prerender_manager()->mutable_config().abandon_time_to_live = 575 abandon_time_to_live; 576 577 GURL url("http://example.com"); 578 prerender_manager()->CreateNextPrerenderContents(url, FINAL_STATUS_CANCELLED); 579 EXPECT_TRUE(AddSimplePrerender(url)); 580 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 581 last_prerender_id()); 582 583 prerender_manager()->AdvanceTimeTicks(test_advance); 584 585 GURL second_url("http://example2.com"); 586 DummyPrerenderContents* second_prerender_contents = 587 prerender_manager()->CreateNextPrerenderContents( 588 second_url, FINAL_STATUS_MANAGER_SHUTDOWN); 589 EXPECT_TRUE(AddSimplePrerender(second_url)); 590 EXPECT_EQ(second_prerender_contents, 591 prerender_manager()->FindEntry(second_url)); 592 } 593 594 595 // Make sure that if we prerender more requests than we support, that we launch 596 // them in the order given up until we reach MaxConcurrency, at which point we 597 // queue them and launch them in the order given. As well, insure that limits 598 // are enforced for the system as a whole and on a per launcher basis. 599 TEST_F(PrerenderTest, MaxConcurrencyTest) { 600 struct TestConcurrency { 601 size_t max_link_concurrency; 602 size_t max_link_concurrency_per_launcher; 603 }; 604 605 TestConcurrency concurrencies_to_test[] = { 606 { prerender_manager()->config().max_link_concurrency, 607 prerender_manager()->config().max_link_concurrency_per_launcher}, 608 609 // With the system limit higher than the per launcher limit, the per 610 // launcher limit should be in effect. 611 { 2, 1 }, 612 613 // With the per launcher limit higher than system limit, the system limit 614 // should be in effect. 615 { 2, 4 }, 616 }; 617 618 DummyPrerenderContents* null = NULL; 619 GURL url_to_delay("http://www.google.com/delayme"); 620 621 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(concurrencies_to_test); ++i) { 622 prerender_manager()->mutable_config().max_link_concurrency = 623 concurrencies_to_test[i].max_link_concurrency; 624 prerender_manager()->mutable_config().max_link_concurrency_per_launcher = 625 concurrencies_to_test[i].max_link_concurrency_per_launcher; 626 627 const size_t effective_max_link_concurrency = 628 std::min(concurrencies_to_test[i].max_link_concurrency, 629 concurrencies_to_test[i].max_link_concurrency_per_launcher); 630 631 std::vector<GURL> urls; 632 std::vector<PrerenderContents*> prerender_contentses; 633 634 // Launch prerenders up to the maximum this launcher can support. 635 for (size_t j = 0; j < effective_max_link_concurrency; ++j) { 636 urls.push_back( 637 GURL(base::StringPrintf("http://google.com/use#%" PRIuS, j))); 638 prerender_contentses.push_back( 639 prerender_manager()->CreateNextPrerenderContents(urls.back(), 640 FINAL_STATUS_USED)); 641 EXPECT_TRUE(AddSimplePrerender(urls.back())); 642 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 643 EXPECT_TRUE(prerender_contentses.back()->prerendering_has_started()); 644 } 645 646 if (concurrencies_to_test[i].max_link_concurrency > 647 effective_max_link_concurrency) { 648 // We should be able to launch more prerenders on this system, but not for 649 // the default launcher. 650 GURL extra_url("http://google.com/extraurl"); 651 EXPECT_FALSE(AddSimplePrerender(extra_url)); 652 const int prerender_id = last_prerender_id(); 653 EXPECT_TRUE(LauncherHasScheduledPrerender(kDefaultChildId, 654 prerender_id)); 655 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 656 prerender_id); 657 EXPECT_FALSE(LauncherHasScheduledPrerender(kDefaultChildId, 658 prerender_id)); 659 } 660 661 DummyPrerenderContents* prerender_contents_to_delay = 662 prerender_manager()->CreateNextPrerenderContents(url_to_delay, 663 FINAL_STATUS_USED); 664 EXPECT_FALSE(AddSimplePrerender(url_to_delay)); 665 EXPECT_FALSE(prerender_contents_to_delay->prerendering_has_started()); 666 EXPECT_NE(null, prerender_manager()->next_prerender_contents()); 667 EXPECT_EQ(null, prerender_manager()->FindEntry(url_to_delay)); 668 for (size_t j = 0; j < effective_max_link_concurrency; ++j) { 669 EXPECT_EQ(prerender_contentses[j], 670 prerender_manager()->FindAndUseEntry(urls[j])); 671 EXPECT_TRUE(prerender_contents_to_delay->prerendering_has_started()); 672 } 673 674 EXPECT_EQ(prerender_contents_to_delay, 675 prerender_manager()->FindAndUseEntry(url_to_delay)); 676 EXPECT_EQ(null, prerender_manager()->next_prerender_contents()); 677 } 678 } 679 680 TEST_F(PrerenderTest, AliasURLTest) { 681 SetConcurrency(7); 682 683 GURL url("http://www.google.com/"); 684 GURL alias_url1("http://www.google.com/index.html"); 685 GURL alias_url2("http://google.com/"); 686 GURL not_an_alias_url("http://google.com/index.html"); 687 std::vector<GURL> alias_urls; 688 alias_urls.push_back(alias_url1); 689 alias_urls.push_back(alias_url2); 690 691 // Test that all of the aliases work, but not_an_alias_url does not. 692 DummyPrerenderContents* prerender_contents = 693 prerender_manager()->CreateNextPrerenderContents( 694 url, alias_urls, FINAL_STATUS_USED); 695 EXPECT_TRUE(AddSimplePrerender(url)); 696 ASSERT_EQ(NULL, prerender_manager()->FindEntry(not_an_alias_url)); 697 ASSERT_EQ(prerender_contents, 698 prerender_manager()->FindAndUseEntry(alias_url1)); 699 prerender_contents = prerender_manager()->CreateNextPrerenderContents( 700 url, alias_urls, FINAL_STATUS_USED); 701 EXPECT_TRUE(AddSimplePrerender(url)); 702 ASSERT_EQ(prerender_contents, 703 prerender_manager()->FindAndUseEntry(alias_url2)); 704 prerender_contents = prerender_manager()->CreateNextPrerenderContents( 705 url, alias_urls, FINAL_STATUS_USED); 706 EXPECT_TRUE(AddSimplePrerender(url)); 707 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 708 709 // Test that alias URLs can not be added. 710 prerender_contents = prerender_manager()->CreateNextPrerenderContents( 711 url, alias_urls, FINAL_STATUS_USED); 712 EXPECT_TRUE(AddSimplePrerender(url)); 713 EXPECT_TRUE(AddSimplePrerender(url)); 714 EXPECT_TRUE(AddSimplePrerender(alias_url1)); 715 EXPECT_TRUE(AddSimplePrerender(alias_url2)); 716 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 717 } 718 719 TEST_F(PrerenderTest, PendingPrerenderTest) { 720 GURL url("http://www.google.com/"); 721 DummyPrerenderContents* prerender_contents = 722 prerender_manager()->CreateNextPrerenderContents( 723 url, 724 FINAL_STATUS_USED); 725 EXPECT_TRUE(AddSimplePrerender(url)); 726 727 int child_id; 728 int route_id; 729 ASSERT_TRUE(prerender_contents->GetChildId(&child_id)); 730 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id)); 731 732 GURL pending_url("http://news.google.com/"); 733 734 // Schedule a pending prerender launched from the prerender. 735 DummyPrerenderContents* pending_prerender_contents = 736 prerender_manager()->CreateNextPrerenderContents( 737 pending_url, 738 ORIGIN_GWS_PRERENDER, 739 FINAL_STATUS_USED); 740 prerender_link_manager()->OnAddPrerender( 741 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, 742 Referrer(url, blink::WebReferrerPolicyDefault), 743 kSize, route_id); 744 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 745 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started()); 746 747 // Use the referring prerender. 748 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 749 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 750 751 // The pending prerender should start now. 752 EXPECT_TRUE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 753 EXPECT_TRUE(pending_prerender_contents->prerendering_has_started()); 754 ASSERT_EQ(pending_prerender_contents, 755 prerender_manager()->FindAndUseEntry(pending_url)); 756 } 757 758 TEST_F(PrerenderTest, InvalidPendingPrerenderTest) { 759 GURL url("http://www.google.com/"); 760 DummyPrerenderContents* prerender_contents = 761 prerender_manager()->CreateNextPrerenderContents( 762 url, 763 FINAL_STATUS_USED); 764 EXPECT_TRUE(AddSimplePrerender(url)); 765 766 int child_id; 767 int route_id; 768 ASSERT_TRUE(prerender_contents->GetChildId(&child_id)); 769 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id)); 770 771 // This pending URL has an unsupported scheme, and won't be able 772 // to start. 773 GURL pending_url("ftp://news.google.com/"); 774 775 // Schedule a pending prerender launched from the prerender. 776 DummyPrerenderContents* pending_prerender_contents = 777 prerender_manager()->CreateNextPrerenderContents( 778 pending_url, 779 ORIGIN_GWS_PRERENDER, 780 FINAL_STATUS_UNSUPPORTED_SCHEME); 781 prerender_link_manager()->OnAddPrerender( 782 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, 783 Referrer(url, blink::WebReferrerPolicyDefault), 784 kSize, route_id); 785 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 786 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started()); 787 788 // Use the referring prerender. 789 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 790 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 791 792 // The pending prerender still doesn't start. 793 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 794 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started()); 795 } 796 797 TEST_F(PrerenderTest, CancelPendingPrerenderTest) { 798 GURL url("http://www.google.com/"); 799 DummyPrerenderContents* prerender_contents = 800 prerender_manager()->CreateNextPrerenderContents( 801 url, 802 FINAL_STATUS_USED); 803 EXPECT_TRUE(AddSimplePrerender(url)); 804 805 int child_id; 806 int route_id; 807 ASSERT_TRUE(prerender_contents->GetChildId(&child_id)); 808 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id)); 809 810 GURL pending_url("http://news.google.com/"); 811 812 // Schedule a pending prerender launched from the prerender. 813 prerender_link_manager()->OnAddPrerender( 814 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, 815 Referrer(url, blink::WebReferrerPolicyDefault), 816 kSize, route_id); 817 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 818 819 // Cancel the pending prerender. 820 prerender_link_manager()->OnCancelPrerender(child_id, last_prerender_id()); 821 822 // Use the referring prerender. 823 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 824 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 825 826 // The pending prerender doesn't start. 827 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id())); 828 } 829 830 // Tests that a PrerenderManager created for a browser session in the control 831 // group works as expected. 832 TEST_F(PrerenderTest, ControlGroup) { 833 RestorePrerenderMode restore_prerender_mode; 834 PrerenderManager::SetMode( 835 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP); 836 GURL url("http://www.google.com/"); 837 DummyPrerenderContents* prerender_contents = 838 prerender_manager()->CreateNextPrerenderContents( 839 url, 840 FINAL_STATUS_MANAGER_SHUTDOWN); 841 EXPECT_TRUE(AddSimplePrerender(url)); 842 EXPECT_FALSE(prerender_contents->prerendering_has_started()); 843 } 844 845 // Tests that prerendering is cancelled when the source render view does not 846 // exist. On failure, the DCHECK in CreatePrerenderContents() above should be 847 // triggered. 848 TEST_F(PrerenderTest, SourceRenderViewClosed) { 849 GURL url("http://www.google.com/"); 850 prerender_manager()->CreateNextPrerenderContents( 851 url, 852 FINAL_STATUS_MANAGER_SHUTDOWN); 853 prerender_link_manager()->OnAddPrerender( 854 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200); 855 EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id())); 856 } 857 858 // Tests that prerendering doesn't launch rel=next prerenders without the field 859 // trial. 860 TEST_F(PrerenderTest, NoRelNextByDefault) { 861 GURL url("http://www.google.com/"); 862 prerender_manager()->CreateNextPrerenderContents( 863 url, FINAL_STATUS_MANAGER_SHUTDOWN); 864 DummyPrerenderContents* null = NULL; 865 866 prerender_link_manager()->OnAddPrerender( 867 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext, 868 Referrer(), kSize, kDefaultRenderViewRouteId); 869 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 870 } 871 872 // Tests that prerendering does launch rel=next prerenders with the field trial. 873 TEST_F(PrerenderTest, RelNextByFieldTrial) { 874 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("PrerenderRelNextTrial", 875 "Yes")); 876 GURL url("http://www.google.com/"); 877 DummyPrerenderContents* prerender_contents = 878 prerender_manager()->CreateNextPrerenderContents( 879 url, ORIGIN_LINK_REL_NEXT, FINAL_STATUS_USED); 880 881 prerender_link_manager()->OnAddPrerender( 882 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext, 883 Referrer(), kSize, kDefaultRenderViewRouteId); 884 EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 885 } 886 887 // Tests that prerendering is cancelled when we launch a second prerender of 888 // the same target within a short time interval. 889 TEST_F(PrerenderTest, RecentlyVisited) { 890 GURL url("http://www.google.com/"); 891 892 prerender_manager()->RecordNavigation(url); 893 894 DummyPrerenderContents* prerender_contents = 895 prerender_manager()->CreateNextPrerenderContents( 896 url, FINAL_STATUS_RECENTLY_VISITED); 897 EXPECT_FALSE(AddSimplePrerender(url)); 898 EXPECT_FALSE(prerender_contents->prerendering_has_started()); 899 } 900 901 TEST_F(PrerenderTest, NotSoRecentlyVisited) { 902 GURL url("http://www.google.com/"); 903 904 prerender_manager()->RecordNavigation(url); 905 prerender_manager()->AdvanceTimeTicks( 906 TimeDelta::FromMilliseconds( 907 UnitTestPrerenderManager::kNavigationRecordWindowMs + 500)); 908 909 DummyPrerenderContents* prerender_contents = 910 prerender_manager()->CreateNextPrerenderContents( 911 url, FINAL_STATUS_USED); 912 EXPECT_TRUE(AddSimplePrerender(url)); 913 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 914 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 915 } 916 917 // Tests that our PPLT dummy prerender gets created properly. 918 TEST_F(PrerenderTest, PPLTDummy) { 919 RestorePrerenderMode restore_prerender_mode; 920 PrerenderManager::SetMode( 921 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP); 922 923 GURL url("http://www.google.com/"); 924 DummyPrerenderContents* prerender_contents = 925 prerender_manager()->CreateNextPrerenderContents( 926 url, FINAL_STATUS_UNSUPPORTED_SCHEME); 927 EXPECT_TRUE(AddSimplePrerender(url)); 928 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 929 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 930 931 DummyPrerenderContents* pplt_dummy_contents = 932 prerender_manager()->CreateNextPrerenderContents(url, 933 FINAL_STATUS_USED); 934 GURL ftp_url("ftp://ftp.google.com/"); 935 // Adding this ftp URL will force the expected unsupported scheme error. 936 prerender_contents->AddAliasURL(ftp_url); 937 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 938 939 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url)); 940 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 941 } 942 943 // Tests that our PPLT dummy prerender gets created properly, even 944 // when navigating to a page that has been recently navigated to. 945 TEST_F(PrerenderTest, RecentlyVisitedPPLTDummy) { 946 RestorePrerenderMode restore_prerender_mode; 947 PrerenderManager::SetMode( 948 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP); 949 950 GURL url("http://www.google.com/"); 951 DummyPrerenderContents* prerender_contents = 952 prerender_manager()->CreateNextPrerenderContents( 953 url, FINAL_STATUS_UNSUPPORTED_SCHEME); 954 EXPECT_TRUE(AddSimplePrerender(url)); 955 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 956 957 DummyPrerenderContents* pplt_dummy_contents = 958 prerender_manager()->CreateNextPrerenderContents(url, 959 FINAL_STATUS_USED); 960 prerender_manager()->RecordNavigation(url); 961 GURL ftp_url("ftp://ftp.google.com/"); 962 prerender_contents->AddAliasURL(ftp_url); 963 964 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url)); 965 } 966 967 TEST_F(PrerenderTest, PPLTLateCancel) { 968 RestorePrerenderMode restore_prerender_mode; 969 PrerenderManager::SetMode( 970 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP); 971 972 GURL url("http://www.google.com"); 973 DummyPrerenderContents* prerender_contents = 974 prerender_manager()->CreateNextPrerenderContents( 975 url, FINAL_STATUS_JAVASCRIPT_ALERT); 976 EXPECT_TRUE(AddSimplePrerender(url)); 977 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 978 // Force the creation of a match complete dummy. 979 DummyPrerenderContents* duplicate_prerender_contents = 980 prerender_manager()->CreateNextPrerenderContents(url, 981 FINAL_STATUS_CANCELLED); 982 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 983 prerender_contents->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT); 984 ASSERT_EQ(duplicate_prerender_contents, prerender_manager()->FindEntry(url)); 985 986 // Make sure that events on prerender handles propogate to the match 987 // complete replacement. 988 DummyPrerenderContents* null = NULL; 989 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 990 last_prerender_id()); 991 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 992 } 993 994 // Tests that the prerender manager matches include the fragment. 995 TEST_F(PrerenderTest, FragmentMatchesTest) { 996 GURL fragment_url("http://www.google.com/#test"); 997 998 DummyPrerenderContents* prerender_contents = 999 prerender_manager()->CreateNextPrerenderContents(fragment_url, 1000 FINAL_STATUS_USED); 1001 EXPECT_TRUE(AddSimplePrerender(fragment_url)); 1002 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1003 ASSERT_EQ(prerender_contents, 1004 prerender_manager()->FindAndUseEntry(fragment_url)); 1005 } 1006 1007 // Tests that the prerender manager uses fragment references when matching 1008 // prerender URLs in the case a different fragment is in both URLs. 1009 TEST_F(PrerenderTest, FragmentsDifferTest) { 1010 GURL fragment_url("http://www.google.com/#test"); 1011 GURL other_fragment_url("http://www.google.com/#other_test"); 1012 1013 DummyPrerenderContents* prerender_contents = 1014 prerender_manager()->CreateNextPrerenderContents(fragment_url, 1015 FINAL_STATUS_USED); 1016 EXPECT_TRUE(AddSimplePrerender(fragment_url)); 1017 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1018 1019 DummyPrerenderContents* null = NULL; 1020 ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url)); 1021 1022 ASSERT_EQ(prerender_contents, 1023 prerender_manager()->FindAndUseEntry(fragment_url)); 1024 } 1025 1026 // Make sure that clearing works as expected. 1027 TEST_F(PrerenderTest, ClearTest) { 1028 GURL url("http://www.google.com/"); 1029 DummyPrerenderContents* prerender_contents = 1030 prerender_manager()->CreateNextPrerenderContents( 1031 url, 1032 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED); 1033 EXPECT_TRUE(AddSimplePrerender(url)); 1034 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1035 prerender_manager()->ClearData(PrerenderManager::CLEAR_PRERENDER_CONTENTS); 1036 DummyPrerenderContents* null = NULL; 1037 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 1038 } 1039 1040 // Make sure canceling works as expected. 1041 TEST_F(PrerenderTest, CancelAllTest) { 1042 GURL url("http://www.google.com/"); 1043 DummyPrerenderContents* prerender_contents = 1044 prerender_manager()->CreateNextPrerenderContents( 1045 url, FINAL_STATUS_CANCELLED); 1046 EXPECT_TRUE(AddSimplePrerender(url)); 1047 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1048 prerender_manager()->CancelAllPrerenders(); 1049 const DummyPrerenderContents* null = NULL; 1050 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 1051 } 1052 1053 TEST_F(PrerenderTest, OmniboxNotAllowedWhenDisabled) { 1054 DisablePrerender(); 1055 EXPECT_FALSE(prerender_manager()->AddPrerenderFromOmnibox( 1056 GURL("http://www.example.com"), NULL, gfx::Size())); 1057 } 1058 1059 TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) { 1060 DisablePrerender(); 1061 EXPECT_FALSE(AddSimplePrerender( 1062 GURL("http://www.example.com"))); 1063 } 1064 1065 TEST_F(PrerenderTest, LinkManagerCancel) { 1066 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1067 GURL url("http://www.myexample.com"); 1068 DummyPrerenderContents* prerender_contents = 1069 prerender_manager()->CreateNextPrerenderContents( 1070 url, FINAL_STATUS_CANCELLED); 1071 1072 EXPECT_TRUE(AddSimplePrerender(url)); 1073 1074 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1075 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1076 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1077 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1078 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1079 last_prerender_id()); 1080 1081 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1082 DummyPrerenderContents* null = NULL; 1083 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1084 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1085 } 1086 1087 TEST_F(PrerenderTest, LinkManagerCancelThenAbandon) { 1088 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1089 GURL url("http://www.myexample.com"); 1090 DummyPrerenderContents* prerender_contents = 1091 prerender_manager()->CreateNextPrerenderContents( 1092 url, FINAL_STATUS_CANCELLED); 1093 1094 EXPECT_TRUE(AddSimplePrerender(url)); 1095 1096 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1097 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1098 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1099 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1100 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1101 last_prerender_id()); 1102 1103 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1104 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1105 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1106 last_prerender_id()); 1107 1108 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1109 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1110 DummyPrerenderContents* null = NULL; 1111 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1112 } 1113 1114 TEST_F(PrerenderTest, LinkManagerAbandon) { 1115 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1116 GURL url("http://www.myexample.com"); 1117 DummyPrerenderContents* prerender_contents = 1118 prerender_manager()->CreateNextPrerenderContents( 1119 url, FINAL_STATUS_USED); 1120 1121 EXPECT_TRUE(AddSimplePrerender(url)); 1122 1123 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1124 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1125 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1126 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1127 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1128 last_prerender_id()); 1129 1130 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1131 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 1132 } 1133 1134 TEST_F(PrerenderTest, LinkManagerAbandonThenCancel) { 1135 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1136 GURL url("http://www.myexample.com"); 1137 DummyPrerenderContents* prerender_contents = 1138 prerender_manager()->CreateNextPrerenderContents( 1139 url, FINAL_STATUS_CANCELLED); 1140 1141 EXPECT_TRUE(AddSimplePrerender(url)); 1142 1143 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1144 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1145 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1146 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1147 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1148 last_prerender_id()); 1149 1150 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1151 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1152 1153 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1154 last_prerender_id()); 1155 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1156 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1157 DummyPrerenderContents* null = NULL; 1158 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1159 } 1160 1161 TEST_F(PrerenderTest, LinkManagerCancelTwice) { 1162 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1163 GURL url("http://www.myexample.com"); 1164 DummyPrerenderContents* prerender_contents = 1165 prerender_manager()->CreateNextPrerenderContents( 1166 url, FINAL_STATUS_CANCELLED); 1167 1168 EXPECT_TRUE(AddSimplePrerender(url)); 1169 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1170 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1171 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1172 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1173 last_prerender_id()); 1174 1175 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1176 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1177 DummyPrerenderContents* null = NULL; 1178 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1179 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1180 last_prerender_id()); 1181 } 1182 1183 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwice) { 1184 SetConcurrency(2); 1185 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1186 GURL url("http://www.myexample.com"); 1187 DummyPrerenderContents* prerender_contents = 1188 prerender_manager()->CreateNextPrerenderContents( 1189 url, FINAL_STATUS_CANCELLED); 1190 1191 EXPECT_TRUE(AddSimplePrerender(url)); 1192 1193 const int first_prerender_id = last_prerender_id(); 1194 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1195 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1196 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1197 EXPECT_TRUE(AddSimplePrerender(url)); 1198 1199 const int second_prerender_id = last_prerender_id(); 1200 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1201 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1202 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1203 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1204 first_prerender_id); 1205 1206 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1207 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1208 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1209 second_prerender_id); 1210 1211 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1212 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1213 DummyPrerenderContents* null = NULL; 1214 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1215 } 1216 1217 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) { 1218 SetConcurrency(2); 1219 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1220 GURL url("http://www.myexample.com"); 1221 DummyPrerenderContents* prerender_contents = 1222 prerender_manager()->CreateNextPrerenderContents( 1223 url, FINAL_STATUS_CANCELLED); 1224 1225 EXPECT_TRUE(AddSimplePrerender(url)); 1226 1227 const int first_prerender_id = last_prerender_id(); 1228 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1229 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1230 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1231 EXPECT_TRUE(AddSimplePrerender(url)); 1232 1233 const int second_prerender_id = last_prerender_id(); 1234 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1235 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1236 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1237 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1238 first_prerender_id); 1239 1240 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1241 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1242 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1243 second_prerender_id); 1244 1245 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1246 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1247 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1248 first_prerender_id); 1249 1250 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1251 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1252 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1253 second_prerender_id); 1254 1255 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1256 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled()); 1257 DummyPrerenderContents* null = NULL; 1258 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1259 } 1260 1261 // TODO(gavinp): Update this test after abandon has an effect on Prerenders, 1262 // like shortening the timeouts. 1263 TEST_F(PrerenderTest, LinkManagerAddTwiceAbandonTwiceUseTwice) { 1264 SetConcurrency(2); 1265 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1266 GURL url("http://www.myexample.com"); 1267 DummyPrerenderContents* prerender_contents = 1268 prerender_manager()->CreateNextPrerenderContents( 1269 url, FINAL_STATUS_USED); 1270 1271 EXPECT_TRUE(AddSimplePrerender(url)); 1272 1273 const int first_prerender_id = last_prerender_id(); 1274 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1275 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1276 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1277 EXPECT_TRUE(AddSimplePrerender(url)); 1278 1279 const int second_prerender_id = last_prerender_id(); 1280 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1281 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1282 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1283 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1284 first_prerender_id); 1285 1286 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1287 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1288 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1289 second_prerender_id); 1290 1291 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1292 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 1293 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1294 } 1295 1296 // TODO(gavinp): After abandon shortens the expire time on a Prerender, 1297 // add a series of tests testing advancing the time by either the abandon 1298 // or normal expire, and verifying the expected behaviour with groups 1299 // of links. 1300 TEST_F(PrerenderTest, LinkManagerExpireThenCancel) { 1301 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1302 GURL url("http://www.myexample.com"); 1303 DummyPrerenderContents* prerender_contents = 1304 prerender_manager()->CreateNextPrerenderContents( 1305 url, FINAL_STATUS_TIMED_OUT); 1306 1307 EXPECT_TRUE(AddSimplePrerender(url)); 1308 1309 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1310 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1311 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1312 prerender_manager()->AdvanceTimeTicks( 1313 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1)); 1314 1315 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1316 DummyPrerenderContents* null = NULL; 1317 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1318 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1319 last_prerender_id()); 1320 1321 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1322 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1323 } 1324 1325 TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) { 1326 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1327 GURL url("http://www.myexample.com"); 1328 DummyPrerenderContents* first_prerender_contents = 1329 prerender_manager()->CreateNextPrerenderContents( 1330 url, FINAL_STATUS_TIMED_OUT); 1331 EXPECT_TRUE(AddSimplePrerender(url)); 1332 EXPECT_TRUE(first_prerender_contents->prerendering_has_started()); 1333 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled()); 1334 ASSERT_EQ(first_prerender_contents, 1335 prerender_manager()->FindEntry(url)); 1336 prerender_manager()->AdvanceTimeTicks( 1337 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1)); 1338 DummyPrerenderContents* null = NULL; 1339 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1340 DummyPrerenderContents* second_prerender_contents = 1341 prerender_manager()->CreateNextPrerenderContents( 1342 url, FINAL_STATUS_USED); 1343 EXPECT_TRUE(AddSimplePrerender(url)); 1344 EXPECT_TRUE(second_prerender_contents->prerendering_has_started()); 1345 ASSERT_EQ(second_prerender_contents, 1346 prerender_manager()->FindAndUseEntry(url)); 1347 } 1348 1349 TEST_F(PrerenderTest, LinkManagerCancelThenAddAgain) { 1350 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1351 GURL url("http://www.myexample.com"); 1352 DummyPrerenderContents* first_prerender_contents = 1353 prerender_manager()->CreateNextPrerenderContents( 1354 url, FINAL_STATUS_CANCELLED); 1355 EXPECT_TRUE(AddSimplePrerender(url)); 1356 EXPECT_TRUE(first_prerender_contents->prerendering_has_started()); 1357 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled()); 1358 ASSERT_EQ(first_prerender_contents, prerender_manager()->FindEntry(url)); 1359 prerender_link_manager()->OnCancelPrerender(kDefaultChildId, 1360 last_prerender_id()); 1361 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1362 EXPECT_TRUE(first_prerender_contents->prerendering_has_been_cancelled()); 1363 DummyPrerenderContents* null = NULL; 1364 ASSERT_EQ(null, prerender_manager()->FindEntry(url)); 1365 DummyPrerenderContents* second_prerender_contents = 1366 prerender_manager()->CreateNextPrerenderContents( 1367 url, FINAL_STATUS_USED); 1368 EXPECT_TRUE(AddSimplePrerender(url)); 1369 EXPECT_TRUE(second_prerender_contents->prerendering_has_started()); 1370 ASSERT_EQ(second_prerender_contents, 1371 prerender_manager()->FindAndUseEntry(url)); 1372 } 1373 1374 TEST_F(PrerenderTest, LinkManagerChannelClosing) { 1375 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1376 GURL url("http://www.myexample.com"); 1377 DummyPrerenderContents* prerender_contents = 1378 prerender_manager()->CreateNextPrerenderContents( 1379 url, FINAL_STATUS_TIMED_OUT); 1380 1381 EXPECT_TRUE(AddSimplePrerender(url)); 1382 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1383 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled()); 1384 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url)); 1385 1386 prerender_link_manager()->OnChannelClosing(kDefaultChildId); 1387 1388 prerender_manager()->AdvanceTimeTicks( 1389 prerender_manager()->config().abandon_time_to_live + 1390 TimeDelta::FromSeconds(1)); 1391 1392 DummyPrerenderContents* null = NULL; 1393 EXPECT_EQ(null, prerender_manager()->FindEntry(url)); 1394 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1395 } 1396 1397 // Creates two prerenders, one of which should be blocked by the 1398 // max_link_concurrency; abandons both of them and waits to make sure both 1399 // are cleared from the PrerenderLinkManager. 1400 TEST_F(PrerenderTest, LinkManagerAbandonInactivePrerender) { 1401 SetConcurrency(1); 1402 ASSERT_LT(prerender_manager()->config().abandon_time_to_live, 1403 prerender_manager()->config().time_to_live); 1404 GURL first_url("http://www.myexample.com"); 1405 DummyPrerenderContents* prerender_contents = 1406 prerender_manager()->CreateNextPrerenderContents( 1407 first_url, FINAL_STATUS_TIMED_OUT); 1408 EXPECT_TRUE(AddSimplePrerender(first_url)); 1409 const int first_prerender_id = last_prerender_id(); 1410 1411 GURL second_url("http://www.neverlaunched.com"); 1412 EXPECT_FALSE(AddSimplePrerender(second_url)); 1413 const int second_prerender_id = last_prerender_id(); 1414 1415 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1416 1417 DummyPrerenderContents* null = NULL; 1418 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url)); 1419 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1420 1421 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1422 first_prerender_id); 1423 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1424 second_prerender_id); 1425 1426 prerender_manager()->AdvanceTimeTicks( 1427 prerender_manager()->config().abandon_time_to_live + 1428 TimeDelta::FromSeconds(1)); 1429 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url)); 1430 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1431 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1432 } 1433 1434 // Creates two prerenders, the second one started by the first, both of which 1435 // should be blocked by max_concurrency; abandons both of them and waits to make 1436 // sure both are cleared from the PrerenderLinkManager. 1437 TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) { 1438 SetConcurrency(1); 1439 ASSERT_LT(prerender_manager()->config().abandon_time_to_live, 1440 prerender_manager()->config().time_to_live); 1441 GURL first_url("http://www.myexample.com"); 1442 DummyPrerenderContents* prerender_contents = 1443 prerender_manager()->CreateNextPrerenderContents( 1444 first_url, FINAL_STATUS_TIMED_OUT); 1445 EXPECT_TRUE(AddSimplePrerender(first_url)); 1446 const int first_prerender_id = last_prerender_id(); 1447 1448 int child_id; 1449 int route_id; 1450 ASSERT_TRUE(prerender_contents->GetChildId(&child_id)); 1451 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id)); 1452 1453 GURL pending_url("http://www.neverlaunched.com"); 1454 prerender_link_manager()->OnAddPrerender( 1455 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes, 1456 content::Referrer(), kSize, route_id); 1457 const int second_prerender_id = last_prerender_id(); 1458 1459 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1460 1461 DummyPrerenderContents* null = NULL; 1462 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url)); 1463 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url)); 1464 1465 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1466 first_prerender_id); 1467 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId, 1468 second_prerender_id); 1469 1470 prerender_manager()->AdvanceTimeTicks( 1471 prerender_manager()->config().abandon_time_to_live + 1472 TimeDelta::FromSeconds(1)); 1473 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url)); 1474 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url)); 1475 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1476 } 1477 1478 // Creates two prerenders, one of which should be blocked by the 1479 // max_link_concurrency; uses one after the max wait to launch, and 1480 // ensures the second prerender does not start. 1481 TEST_F(PrerenderTest, LinkManagerWaitToLaunchNotLaunched) { 1482 SetConcurrency(1); 1483 ASSERT_LT(prerender_manager()->config().max_wait_to_launch, 1484 prerender_manager()->config().time_to_live); 1485 GURL first_url("http://www.myexample.com"); 1486 DummyPrerenderContents* prerender_contents = 1487 prerender_manager()->CreateNextPrerenderContents( 1488 first_url, FINAL_STATUS_USED); 1489 EXPECT_TRUE(AddSimplePrerender(first_url)); 1490 1491 GURL second_url("http://www.neverlaunched.com"); 1492 EXPECT_FALSE(AddSimplePrerender(second_url)); 1493 1494 EXPECT_FALSE(IsEmptyPrerenderLinkManager()); 1495 1496 DummyPrerenderContents* null = NULL; 1497 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url)); 1498 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1499 1500 prerender_manager()->AdvanceTimeTicks( 1501 prerender_manager()->config().max_wait_to_launch + 1502 TimeDelta::FromSeconds(1)); 1503 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url)); 1504 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1505 1506 EXPECT_EQ(prerender_contents, 1507 prerender_manager()->FindAndUseEntry(first_url)); 1508 1509 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url)); 1510 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1511 EXPECT_TRUE(IsEmptyPrerenderLinkManager()); 1512 } 1513 1514 // Creates two prerenders, one of which should start when the first one expires. 1515 TEST_F(PrerenderTest, LinkManagerExpireRevealingLaunch) { 1516 SetConcurrency(1); 1517 ASSERT_LT(prerender_manager()->config().max_wait_to_launch, 1518 prerender_manager()->config().time_to_live); 1519 1520 GURL first_url("http://www.willexpire.com"); 1521 DummyPrerenderContents* first_prerender_contents = 1522 prerender_manager()->CreateNextPrerenderContents( 1523 first_url, FINAL_STATUS_TIMED_OUT); 1524 EXPECT_TRUE(AddSimplePrerender(first_url)); 1525 EXPECT_EQ(first_prerender_contents, 1526 prerender_manager()->FindEntry(first_url)); 1527 1528 // Insert the second prerender so it will be still be launchable when the 1529 // first expires. 1530 const TimeDelta wait_to_launch_second_prerender = 1531 prerender_manager()->config().time_to_live - 1532 prerender_manager()->config().max_wait_to_launch + 1533 TimeDelta::FromSeconds(2); 1534 const TimeDelta wait_for_first_prerender_to_expire = 1535 prerender_manager()->config().time_to_live - 1536 wait_to_launch_second_prerender + 1537 TimeDelta::FromSeconds(1); 1538 ASSERT_LT(prerender_manager()->config().time_to_live, 1539 wait_to_launch_second_prerender + 1540 wait_for_first_prerender_to_expire); 1541 ASSERT_GT(prerender_manager()->config().max_wait_to_launch.InSeconds(), 1542 wait_for_first_prerender_to_expire.InSeconds()); 1543 1544 prerender_manager()->AdvanceTimeTicks(wait_to_launch_second_prerender); 1545 GURL second_url("http://www.willlaunch.com"); 1546 DummyPrerenderContents* second_prerender_contents = 1547 prerender_manager()->CreateNextPrerenderContents( 1548 second_url, FINAL_STATUS_USED); 1549 EXPECT_FALSE(AddSimplePrerender(second_url)); 1550 1551 // The first prerender is still running, but the second has not yet launched. 1552 EXPECT_EQ(first_prerender_contents, 1553 prerender_manager()->FindEntry(first_url)); 1554 PrerenderContents* null = NULL; 1555 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url)); 1556 1557 // The first prerender should have died, giving life to the second one. 1558 prerender_manager()->AdvanceTimeTicks(wait_for_first_prerender_to_expire); 1559 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url)); 1560 EXPECT_EQ(second_prerender_contents, 1561 prerender_manager()->FindAndUseEntry(second_url)); 1562 } 1563 1564 TEST_F(PrerenderTest, InstantSearchNotAllowedWhenDisabled) { 1565 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 1566 "EmbeddedSearch", 1567 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1")); 1568 DisablePrerender(); 1569 EXPECT_FALSE(prerender_manager()->AddPrerenderForInstant( 1570 GURL("http://www.example.com/instant_search"), NULL, gfx::Size())); 1571 } 1572 1573 TEST_F(PrerenderTest, PrerenderContentsForInstantSearch) { 1574 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 1575 "EmbeddedSearch", 1576 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1")); 1577 GURL url("http://www.example.com/instant_search"); 1578 DummyPrerenderContents* prerender_contents = 1579 prerender_manager()->CreateNextPrerenderContents(url, ORIGIN_INSTANT, 1580 FINAL_STATUS_USED); 1581 scoped_ptr<PrerenderHandle> prerender_handle( 1582 prerender_manager()->AddPrerenderForInstant(url, NULL, kSize)); 1583 CHECK(prerender_handle.get()); 1584 EXPECT_TRUE(prerender_handle->IsPrerendering()); 1585 EXPECT_TRUE(prerender_contents->prerendering_has_started()); 1586 EXPECT_EQ(prerender_contents, prerender_handle->contents()); 1587 EXPECT_EQ(ORIGIN_INSTANT, prerender_handle->contents()->origin()); 1588 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url)); 1589 EXPECT_FALSE(prerender_handle->IsPrerendering()); 1590 } 1591 1592 } // namespace prerender 1593