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