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.
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"
31 using base::TimeDelta;
32 using base::TimeTicks;
33 using content::BrowserThread;
34 using content::Referrer;
38 class UnitTestPrerenderManager;
42 class DummyPrerenderContents : public PrerenderContents {
44 DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager,
45 PrerenderTracker* prerender_tracker,
48 FinalStatus expected_final_status);
50 virtual ~DummyPrerenderContents();
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)
58 virtual bool GetChildId(int* child_id) const OVERRIDE {
59 // Having a default child_id of -1 forces pending prerenders not to fail
60 // on session storage and cross domain checking.
65 virtual bool GetRouteId(int* route_id) const OVERRIDE {
66 *route_id = route_id_;
70 FinalStatus expected_final_status() const { return expected_final_status_; }
72 bool prerendering_has_been_cancelled() const {
73 return PrerenderContents::prerendering_has_been_cancelled();
77 static int g_next_route_id_;
80 UnitTestPrerenderManager* test_prerender_manager_;
81 FinalStatus expected_final_status_;
84 int DummyPrerenderContents::g_next_route_id_ = 0;
86 const gfx::Size kSize(640, 480);
88 const uint32 kDefaultRelTypes = PrerenderRelTypePrerender;
92 class UnitTestPrerenderManager : public PrerenderManager {
94 using PrerenderManager::kMinTimeBetweenPrerendersMs;
95 using PrerenderManager::kNavigationRecordWindowMs;
97 explicit UnitTestPrerenderManager(Profile* profile,
98 PrerenderTracker* prerender_tracker)
99 : PrerenderManager(profile, prerender_tracker),
101 time_ticks_(TimeTicks::Now()),
102 prerender_tracker_(prerender_tracker) {
103 set_rate_limit_enabled(false);
106 virtual ~UnitTestPrerenderManager() {
109 // From BrowserContextKeyedService, via PrererenderManager:
110 virtual void Shutdown() OVERRIDE {
111 if (next_prerender_contents())
112 next_prerender_contents_->Destroy(FINAL_STATUS_MANAGER_SHUTDOWN);
113 PrerenderManager::Shutdown();
116 // From PrerenderManager:
117 virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
118 FinalStatus final_status) OVERRIDE {
119 if (entry == next_prerender_contents_.get())
121 PrerenderManager::MoveEntryToPendingDelete(entry, final_status);
124 PrerenderContents* FindEntry(const GURL& url) {
126 to_delete_prerenders_.clear();
127 if (PrerenderData* data = FindPrerenderData(url, NULL))
128 return data->contents();
132 PrerenderContents* FindAndUseEntry(const GURL& url) {
133 PrerenderData* prerender_data = FindPrerenderData(url, NULL);
136 ScopedVector<PrerenderData>::iterator to_erase =
137 FindIteratorForPrerenderContents(prerender_data->contents());
138 CHECK(to_erase != active_prerenders_.end());
139 PrerenderContents* prerender_contents = prerender_data->ReleaseContents();
140 active_prerenders_.erase(to_erase);
142 prerender_contents->PrepareForUse();
143 return prerender_contents;
146 void AdvanceTime(TimeDelta delta) {
150 void AdvanceTimeTicks(TimeDelta delta) {
151 time_ticks_ += delta;
154 DummyPrerenderContents* CreateNextPrerenderContents(
156 FinalStatus expected_final_status) {
157 DummyPrerenderContents* prerender_contents =
158 new DummyPrerenderContents(this, prerender_tracker_, url,
159 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
160 expected_final_status);
161 SetNextPrerenderContents(prerender_contents);
162 return prerender_contents;
165 DummyPrerenderContents* CreateNextPrerenderContents(
168 FinalStatus expected_final_status) {
169 DummyPrerenderContents* prerender_contents =
170 new DummyPrerenderContents(this, prerender_tracker_, url,
171 origin, expected_final_status);
172 SetNextPrerenderContents(prerender_contents);
173 return prerender_contents;
176 DummyPrerenderContents* CreateNextPrerenderContents(
178 const std::vector<GURL>& alias_urls,
179 FinalStatus expected_final_status) {
180 DummyPrerenderContents* prerender_contents =
181 new DummyPrerenderContents(this, prerender_tracker_, url,
182 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
183 expected_final_status);
184 for (std::vector<GURL>::const_iterator it = alias_urls.begin();
185 it != alias_urls.end();
187 EXPECT_TRUE(prerender_contents->AddAliasURL(*it));
189 SetNextPrerenderContents(prerender_contents);
190 return prerender_contents;
193 void set_rate_limit_enabled(bool enabled) {
194 mutable_config().rate_limit_enabled = enabled;
197 PrerenderContents* next_prerender_contents() {
198 return next_prerender_contents_.get();
201 // from PrerenderManager
202 virtual Time GetCurrentTime() const OVERRIDE {
206 virtual TimeTicks GetCurrentTimeTicks() const OVERRIDE {
210 virtual PrerenderContents* GetPrerenderContentsForRoute(
211 int child_id, int route_id) const OVERRIDE {
212 // Overridden for the PrerenderLinkManager's pending prerender logic.
213 PrerenderContentsMap::const_iterator iter = prerender_contents_map_.find(
214 std::make_pair(child_id, route_id));
215 if (iter == prerender_contents_map_.end())
220 void DummyPrerenderContentsStarted(int child_id,
222 PrerenderContents* prerender_contents) {
223 prerender_contents_map_[std::make_pair(child_id, route_id)] =
227 void DummyPrerenderContentsDestroyed(int child_id,
229 prerender_contents_map_.erase(std::make_pair(child_id, route_id));
233 void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
234 CHECK(!next_prerender_contents_.get());
235 next_prerender_contents_.reset(prerender_contents);
236 if (prerender_contents->expected_final_status() == FINAL_STATUS_USED)
237 used_prerender_contents_.push_back(prerender_contents);
241 virtual PrerenderContents* CreatePrerenderContents(
243 const Referrer& referrer,
245 uint8 experiment_id) OVERRIDE {
246 CHECK(next_prerender_contents_.get());
247 EXPECT_EQ(url, next_prerender_contents_->prerender_url());
248 EXPECT_EQ(origin, next_prerender_contents_->origin());
249 return next_prerender_contents_.release();
252 // Maintain a map from route pairs to PrerenderContents for
253 // GetPrerenderContentsForRoute.
254 typedef std::map<std::pair<int,int>, PrerenderContents*> PrerenderContentsMap;
255 PrerenderContentsMap prerender_contents_map_;
258 TimeTicks time_ticks_;
259 scoped_ptr<PrerenderContents> next_prerender_contents_;
260 // PrerenderContents with an |expected_final_status| of FINAL_STATUS_USED,
261 // tracked so they will be automatically deleted.
262 ScopedVector<PrerenderContents> used_prerender_contents_;
264 PrerenderTracker* prerender_tracker_;
267 class RestorePrerenderMode {
269 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
272 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
274 PrerenderManager::PrerenderManagerMode prev_mode_;
277 DummyPrerenderContents::DummyPrerenderContents(
278 UnitTestPrerenderManager* test_prerender_manager,
279 PrerenderTracker* prerender_tracker,
282 FinalStatus expected_final_status)
283 : PrerenderContents(test_prerender_manager,
284 NULL, url, Referrer(), origin,
285 PrerenderManager::kNoExperiment),
286 route_id_(g_next_route_id_++),
287 test_prerender_manager_(test_prerender_manager),
288 expected_final_status_(expected_final_status) {
291 DummyPrerenderContents::~DummyPrerenderContents() {
292 EXPECT_EQ(expected_final_status_, final_status());
293 test_prerender_manager_->DummyPrerenderContentsDestroyed(-1, route_id_);
296 void DummyPrerenderContents::StartPrerendering(
297 int ALLOW_UNUSED creator_child_id,
298 const gfx::Size& ALLOW_UNUSED size,
299 content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace) {
300 // In the base PrerenderContents implementation, StartPrerendering will
301 // be called even when the PrerenderManager is part of the control group,
302 // but it will early exit before actually creating a new RenderView if
303 // |is_control_group| is true;
304 load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
305 if (!test_prerender_manager_->IsControlGroup(experiment_id())) {
306 prerendering_has_started_ = true;
307 test_prerender_manager_->DummyPrerenderContentsStarted(-1, route_id_, this);
308 NotifyPrerenderStart();
312 class PrerenderTest : public testing::Test {
314 static const int kDefaultChildId = -1;
315 static const int kDefaultRenderViewRouteId = -1;
317 PrerenderTest() : ui_thread_(BrowserThread::UI, &message_loop_),
318 prerender_manager_(new UnitTestPrerenderManager(
319 &profile_, prerender_tracker())),
320 prerender_link_manager_(
321 new PrerenderLinkManager(prerender_manager_.get())),
322 last_prerender_id_(0),
323 field_trial_list_(NULL) {
324 // Enable omnibox prerendering.
325 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
326 switches::kPrerenderFromOmnibox,
327 switches::kPrerenderFromOmniboxSwitchValueEnabled);
330 virtual ~PrerenderTest() {
331 prerender_link_manager_->OnChannelClosing(kDefaultChildId);
332 prerender_link_manager_->Shutdown();
333 prerender_manager_->Shutdown();
336 UnitTestPrerenderManager* prerender_manager() {
337 return prerender_manager_.get();
340 PrerenderLinkManager* prerender_link_manager() {
341 return prerender_link_manager_.get();
344 void SetConcurrency(size_t concurrency) {
345 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
347 prerender_manager()->mutable_config().max_link_concurrency =
348 std::max(prerender_manager()->mutable_config().max_link_concurrency,
352 bool IsEmptyPrerenderLinkManager() const {
353 return prerender_link_manager_->IsEmpty();
356 int last_prerender_id() const {
357 return last_prerender_id_;
360 int GetNextPrerenderID() {
361 return ++last_prerender_id_;
364 bool LauncherHasRunningPrerender(int child_id, int prerender_id) {
365 PrerenderLinkManager::LinkPrerender* prerender =
366 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
367 child_id, prerender_id);
368 return prerender && prerender->handle;
371 bool LauncherHasScheduledPrerender(int child_id, int prerender_id) {
372 PrerenderLinkManager::LinkPrerender* prerender =
373 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
374 child_id, prerender_id);
375 return prerender != NULL;
378 // Shorthand to add a simple prerender with a reasonable source. Returns
379 // true iff the prerender has been added to the PrerenderManager by the
380 // PrerenderLinkManager and the PrerenderManager returned a handle.
381 bool AddSimplePrerender(const GURL& url) {
382 prerender_link_manager()->OnAddPrerender(
383 kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes,
384 content::Referrer(), kSize, kDefaultRenderViewRouteId);
385 return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id());
389 PrerenderTracker* prerender_tracker() {
390 return g_browser_process->prerender_tracker();
393 // Needed to pass PrerenderManager's DCHECKs.
394 TestingProfile profile_;
395 base::MessageLoop message_loop_;
396 content::TestBrowserThread ui_thread_;
397 scoped_ptr<UnitTestPrerenderManager> prerender_manager_;
398 scoped_ptr<PrerenderLinkManager> prerender_link_manager_;
399 int last_prerender_id_;
400 base::FieldTrialList field_trial_list_;
403 TEST_F(PrerenderTest, FoundTest) {
404 GURL url("http://www.google.com/");
405 DummyPrerenderContents* prerender_contents =
406 prerender_manager()->CreateNextPrerenderContents(
409 EXPECT_TRUE(AddSimplePrerender(url));
410 EXPECT_TRUE(prerender_contents->prerendering_has_started());
411 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
414 // Make sure that if queue a request, and a second prerender request for the
415 // same URL comes in, that the second request attaches to the first prerender,
416 // and we don't use the second prerender contents.
417 TEST_F(PrerenderTest, DuplicateTest) {
419 GURL url("http://www.google.com/");
420 DummyPrerenderContents* prerender_contents =
421 prerender_manager()->CreateNextPrerenderContents(
424 DummyPrerenderContents* null = NULL;
425 EXPECT_TRUE(AddSimplePrerender(url));
426 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
427 EXPECT_TRUE(prerender_contents->prerendering_has_started());
429 DummyPrerenderContents* prerender_contents1 =
430 prerender_manager()->CreateNextPrerenderContents(
432 FINAL_STATUS_MANAGER_SHUTDOWN);
433 EXPECT_TRUE(AddSimplePrerender(url));
434 EXPECT_EQ(prerender_contents1,
435 prerender_manager()->next_prerender_contents());
436 EXPECT_FALSE(prerender_contents1->prerendering_has_started());
438 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
441 // Ensure that we expire a prerendered page after the max. permitted time.
442 TEST_F(PrerenderTest, ExpireTest) {
443 GURL url("http://www.google.com/");
444 DummyPrerenderContents* prerender_contents =
445 prerender_manager()->CreateNextPrerenderContents(
447 FINAL_STATUS_TIMED_OUT);
448 DummyPrerenderContents* null = NULL;
449 EXPECT_TRUE(AddSimplePrerender(url));
450 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
451 EXPECT_TRUE(prerender_contents->prerendering_has_started());
452 prerender_manager()->AdvanceTimeTicks(
453 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
454 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
457 // Ensure that we don't launch prerenders of bad urls (in this case, a mailto:
459 TEST_F(PrerenderTest, BadURLTest) {
460 GURL url("mailto:test@gmail.com");
461 DummyPrerenderContents* prerender_contents =
462 prerender_manager()->CreateNextPrerenderContents(
464 FINAL_STATUS_UNSUPPORTED_SCHEME);
465 EXPECT_FALSE(AddSimplePrerender(url));
466 EXPECT_FALSE(prerender_contents->prerendering_has_started());
467 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
468 DummyPrerenderContents* null = NULL;
469 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
472 // When the user navigates away from a page, the prerenders it launched should
473 // have their time to expiry shortened from the default time to live.
474 TEST_F(PrerenderTest, LinkManagerNavigateAwayExpire) {
475 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
476 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
477 const TimeDelta test_advance = TimeDelta::FromSeconds(22);
478 ASSERT_LT(test_advance, time_to_live);
479 ASSERT_LT(abandon_time_to_live, test_advance);
481 prerender_manager()->mutable_config().time_to_live = time_to_live;
482 prerender_manager()->mutable_config().abandon_time_to_live =
483 abandon_time_to_live;
485 GURL url("http://example.com");
486 DummyPrerenderContents* prerender_contents =
487 prerender_manager()->CreateNextPrerenderContents(url,
488 FINAL_STATUS_TIMED_OUT);
489 EXPECT_TRUE(AddSimplePrerender(url));
490 EXPECT_TRUE(prerender_contents->prerendering_has_started());
491 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
492 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
493 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
494 last_prerender_id());
495 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
496 DummyPrerenderContents* null = NULL;
497 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
498 prerender_manager()->AdvanceTimeTicks(test_advance);
500 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
503 // But when we navigate away very close to the original expiry of a prerender,
504 // we shouldn't expect it to be extended.
505 TEST_F(PrerenderTest, LinkManagerNavigateAwayNearExpiry) {
506 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
507 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
509 // We will expect the prerender to still be alive after advancing the clock
510 // by first_advance. But, after second_advance, we expect it to have timed
511 // out, demonstrating that you can't extend a prerender by navigating away
512 // from its launcher.
513 const TimeDelta first_advance = TimeDelta::FromSeconds(298);
514 const TimeDelta second_advance = TimeDelta::FromSeconds(4);
515 ASSERT_LT(first_advance, time_to_live);
516 ASSERT_LT(time_to_live - first_advance, abandon_time_to_live);
517 ASSERT_LT(time_to_live, first_advance + second_advance);
519 prerender_manager()->mutable_config().time_to_live = time_to_live;
520 prerender_manager()->mutable_config().abandon_time_to_live =
521 abandon_time_to_live;
523 GURL url("http://example2.com");
524 DummyPrerenderContents* prerender_contents =
525 prerender_manager()->CreateNextPrerenderContents(url,
526 FINAL_STATUS_TIMED_OUT);
527 EXPECT_TRUE(AddSimplePrerender(url));
528 EXPECT_TRUE(prerender_contents->prerendering_has_started());
529 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
530 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
532 prerender_manager()->AdvanceTimeTicks(first_advance);
533 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
535 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
536 last_prerender_id());
537 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
539 DummyPrerenderContents* null = NULL;
540 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
542 prerender_manager()->AdvanceTimeTicks(second_advance);
543 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
546 // When the user navigates away from a page, and then launches a new prerender,
547 // the new prerender should preempt the abandoned prerender even if the
548 // abandoned prerender hasn't expired.
549 TEST_F(PrerenderTest, LinkManagerNavigateAwayLaunchAnother) {
550 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
551 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
552 const TimeDelta test_advance = TimeDelta::FromSeconds(5);
553 ASSERT_LT(test_advance, time_to_live);
554 ASSERT_GT(abandon_time_to_live, test_advance);
556 prerender_manager()->mutable_config().time_to_live = time_to_live;
557 prerender_manager()->mutable_config().abandon_time_to_live =
558 abandon_time_to_live;
560 GURL url("http://example.com");
561 prerender_manager()->CreateNextPrerenderContents(url, FINAL_STATUS_CANCELLED);
562 EXPECT_TRUE(AddSimplePrerender(url));
563 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
564 last_prerender_id());
566 prerender_manager()->AdvanceTimeTicks(test_advance);
568 GURL second_url("http://example2.com");
569 DummyPrerenderContents* second_prerender_contents =
570 prerender_manager()->CreateNextPrerenderContents(
571 second_url, FINAL_STATUS_MANAGER_SHUTDOWN);
572 EXPECT_TRUE(AddSimplePrerender(second_url));
573 EXPECT_EQ(second_prerender_contents,
574 prerender_manager()->FindEntry(second_url));
578 // Make sure that if we prerender more requests than we support, that we launch
579 // them in the order given up until we reach MaxConcurrency, at which point we
580 // queue them and launch them in the order given. As well, insure that limits
581 // are enforced for the system as a whole and on a per launcher basis.
582 TEST_F(PrerenderTest, MaxConcurrencyTest) {
583 struct TestConcurrency {
584 size_t max_link_concurrency;
585 size_t max_link_concurrency_per_launcher;
588 TestConcurrency concurrencies_to_test[] = {
589 { prerender_manager()->config().max_link_concurrency,
590 prerender_manager()->config().max_link_concurrency_per_launcher},
592 // With the system limit higher than the per launcher limit, the per
593 // launcher limit should be in effect.
596 // With the per launcher limit higher than system limit, the system limit
597 // should be in effect.
601 DummyPrerenderContents* null = NULL;
602 GURL url_to_delay("http://www.google.com/delayme");
604 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(concurrencies_to_test); ++i) {
605 prerender_manager()->mutable_config().max_link_concurrency =
606 concurrencies_to_test[i].max_link_concurrency;
607 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
608 concurrencies_to_test[i].max_link_concurrency_per_launcher;
610 const size_t effective_max_link_concurrency =
611 std::min(concurrencies_to_test[i].max_link_concurrency,
612 concurrencies_to_test[i].max_link_concurrency_per_launcher);
614 std::vector<GURL> urls;
615 std::vector<PrerenderContents*> prerender_contentses;
617 // Launch prerenders up to the maximum this launcher can support.
618 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
620 GURL(base::StringPrintf("http://google.com/use#%" PRIuS, j)));
621 prerender_contentses.push_back(
622 prerender_manager()->CreateNextPrerenderContents(urls.back(),
624 EXPECT_TRUE(AddSimplePrerender(urls.back()));
625 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
626 EXPECT_TRUE(prerender_contentses.back()->prerendering_has_started());
629 if (concurrencies_to_test[i].max_link_concurrency >
630 effective_max_link_concurrency) {
631 // We should be able to launch more prerenders on this system, but not for
632 // the default launcher.
633 GURL extra_url("http://google.com/extraurl");
634 EXPECT_FALSE(AddSimplePrerender(extra_url));
635 const int prerender_id = last_prerender_id();
636 EXPECT_TRUE(LauncherHasScheduledPrerender(kDefaultChildId,
638 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
640 EXPECT_FALSE(LauncherHasScheduledPrerender(kDefaultChildId,
644 DummyPrerenderContents* prerender_contents_to_delay =
645 prerender_manager()->CreateNextPrerenderContents(url_to_delay,
647 EXPECT_FALSE(AddSimplePrerender(url_to_delay));
648 EXPECT_FALSE(prerender_contents_to_delay->prerendering_has_started());
649 EXPECT_NE(null, prerender_manager()->next_prerender_contents());
650 EXPECT_EQ(null, prerender_manager()->FindEntry(url_to_delay));
651 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
652 EXPECT_EQ(prerender_contentses[j],
653 prerender_manager()->FindAndUseEntry(urls[j]));
654 EXPECT_TRUE(prerender_contents_to_delay->prerendering_has_started());
657 EXPECT_EQ(prerender_contents_to_delay,
658 prerender_manager()->FindAndUseEntry(url_to_delay));
659 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
663 TEST_F(PrerenderTest, AliasURLTest) {
666 GURL url("http://www.google.com/");
667 GURL alias_url1("http://www.google.com/index.html");
668 GURL alias_url2("http://google.com/");
669 GURL not_an_alias_url("http://google.com/index.html");
670 std::vector<GURL> alias_urls;
671 alias_urls.push_back(alias_url1);
672 alias_urls.push_back(alias_url2);
674 // Test that all of the aliases work, but not_an_alias_url does not.
675 DummyPrerenderContents* prerender_contents =
676 prerender_manager()->CreateNextPrerenderContents(
677 url, alias_urls, FINAL_STATUS_USED);
678 EXPECT_TRUE(AddSimplePrerender(url));
679 ASSERT_EQ(NULL, prerender_manager()->FindEntry(not_an_alias_url));
680 ASSERT_EQ(prerender_contents,
681 prerender_manager()->FindAndUseEntry(alias_url1));
682 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
683 url, alias_urls, FINAL_STATUS_USED);
684 EXPECT_TRUE(AddSimplePrerender(url));
685 ASSERT_EQ(prerender_contents,
686 prerender_manager()->FindAndUseEntry(alias_url2));
687 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
688 url, alias_urls, FINAL_STATUS_USED);
689 EXPECT_TRUE(AddSimplePrerender(url));
690 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
692 // Test that alias URLs can not be added.
693 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
694 url, alias_urls, FINAL_STATUS_USED);
695 EXPECT_TRUE(AddSimplePrerender(url));
696 EXPECT_TRUE(AddSimplePrerender(url));
697 EXPECT_TRUE(AddSimplePrerender(alias_url1));
698 EXPECT_TRUE(AddSimplePrerender(alias_url2));
699 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
702 TEST_F(PrerenderTest, PendingPrerenderTest) {
703 GURL url("http://www.google.com/");
704 DummyPrerenderContents* prerender_contents =
705 prerender_manager()->CreateNextPrerenderContents(
708 EXPECT_TRUE(AddSimplePrerender(url));
712 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
713 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
715 GURL pending_url("http://news.google.com/");
717 // Schedule a pending prerender launched from the prerender.
718 DummyPrerenderContents* pending_prerender_contents =
719 prerender_manager()->CreateNextPrerenderContents(
721 ORIGIN_GWS_PRERENDER,
723 prerender_link_manager()->OnAddPrerender(
724 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
725 Referrer(url, blink::WebReferrerPolicyDefault),
727 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
728 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
730 // Use the referring prerender.
731 EXPECT_TRUE(prerender_contents->prerendering_has_started());
732 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
734 // The pending prerender should start now.
735 EXPECT_TRUE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
736 EXPECT_TRUE(pending_prerender_contents->prerendering_has_started());
737 ASSERT_EQ(pending_prerender_contents,
738 prerender_manager()->FindAndUseEntry(pending_url));
741 TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
742 GURL url("http://www.google.com/");
743 DummyPrerenderContents* prerender_contents =
744 prerender_manager()->CreateNextPrerenderContents(
747 EXPECT_TRUE(AddSimplePrerender(url));
751 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
752 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
754 // This pending URL has an unsupported scheme, and won't be able
756 GURL pending_url("ftp://news.google.com/");
758 // Schedule a pending prerender launched from the prerender.
759 DummyPrerenderContents* pending_prerender_contents =
760 prerender_manager()->CreateNextPrerenderContents(
762 ORIGIN_GWS_PRERENDER,
763 FINAL_STATUS_UNSUPPORTED_SCHEME);
764 prerender_link_manager()->OnAddPrerender(
765 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
766 Referrer(url, blink::WebReferrerPolicyDefault),
768 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
769 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
771 // Use the referring prerender.
772 EXPECT_TRUE(prerender_contents->prerendering_has_started());
773 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
775 // The pending prerender still doesn't start.
776 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
777 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
780 TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
781 GURL url("http://www.google.com/");
782 DummyPrerenderContents* prerender_contents =
783 prerender_manager()->CreateNextPrerenderContents(
786 EXPECT_TRUE(AddSimplePrerender(url));
790 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
791 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
793 GURL pending_url("http://news.google.com/");
795 // Schedule a pending prerender launched from the prerender.
796 prerender_link_manager()->OnAddPrerender(
797 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
798 Referrer(url, blink::WebReferrerPolicyDefault),
800 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
802 // Cancel the pending prerender.
803 prerender_link_manager()->OnCancelPrerender(child_id, last_prerender_id());
805 // Use the referring prerender.
806 EXPECT_TRUE(prerender_contents->prerendering_has_started());
807 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
809 // The pending prerender doesn't start.
810 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
813 // Tests that a PrerenderManager created for a browser session in the control
814 // group works as expected.
815 TEST_F(PrerenderTest, ControlGroup) {
816 RestorePrerenderMode restore_prerender_mode;
817 PrerenderManager::SetMode(
818 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
819 GURL url("http://www.google.com/");
820 DummyPrerenderContents* prerender_contents =
821 prerender_manager()->CreateNextPrerenderContents(
823 FINAL_STATUS_MANAGER_SHUTDOWN);
824 EXPECT_TRUE(AddSimplePrerender(url));
825 EXPECT_FALSE(prerender_contents->prerendering_has_started());
828 // Tests that prerendering is cancelled when the source render view does not
829 // exist. On failure, the DCHECK in CreatePrerenderContents() above should be
831 TEST_F(PrerenderTest, SourceRenderViewClosed) {
832 GURL url("http://www.google.com/");
833 prerender_manager()->CreateNextPrerenderContents(
835 FINAL_STATUS_MANAGER_SHUTDOWN);
836 prerender_link_manager()->OnAddPrerender(
837 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200);
838 EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id()));
841 // Tests that prerendering doesn't launch rel=next prerenders without the field
843 TEST_F(PrerenderTest, NoRelNextByDefault) {
844 GURL url("http://www.google.com/");
845 prerender_manager()->CreateNextPrerenderContents(
846 url, FINAL_STATUS_MANAGER_SHUTDOWN);
847 DummyPrerenderContents* null = NULL;
849 prerender_link_manager()->OnAddPrerender(
850 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
851 Referrer(), kSize, kDefaultRenderViewRouteId);
852 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
855 // Tests that prerendering does launch rel=next prerenders with the field trial.
856 TEST_F(PrerenderTest, RelNextByFieldTrial) {
857 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("PrerenderRelNextTrial",
859 GURL url("http://www.google.com/");
860 DummyPrerenderContents* prerender_contents =
861 prerender_manager()->CreateNextPrerenderContents(
862 url, ORIGIN_LINK_REL_NEXT, FINAL_STATUS_USED);
864 prerender_link_manager()->OnAddPrerender(
865 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
866 Referrer(), kSize, kDefaultRenderViewRouteId);
867 EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
870 // Tests that prerendering is cancelled when we launch a second prerender of
871 // the same target within a short time interval.
872 TEST_F(PrerenderTest, RecentlyVisited) {
873 GURL url("http://www.google.com/");
875 prerender_manager()->RecordNavigation(url);
877 DummyPrerenderContents* prerender_contents =
878 prerender_manager()->CreateNextPrerenderContents(
879 url, FINAL_STATUS_RECENTLY_VISITED);
880 EXPECT_FALSE(AddSimplePrerender(url));
881 EXPECT_FALSE(prerender_contents->prerendering_has_started());
884 TEST_F(PrerenderTest, NotSoRecentlyVisited) {
885 GURL url("http://www.google.com/");
887 prerender_manager()->RecordNavigation(url);
888 prerender_manager()->AdvanceTimeTicks(
889 TimeDelta::FromMilliseconds(
890 UnitTestPrerenderManager::kNavigationRecordWindowMs + 500));
892 DummyPrerenderContents* prerender_contents =
893 prerender_manager()->CreateNextPrerenderContents(
894 url, FINAL_STATUS_USED);
895 EXPECT_TRUE(AddSimplePrerender(url));
896 EXPECT_TRUE(prerender_contents->prerendering_has_started());
897 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
900 // Tests that our PPLT dummy prerender gets created properly.
901 TEST_F(PrerenderTest, PPLTDummy) {
902 GURL url("http://www.google.com/");
903 DummyPrerenderContents* prerender_contents =
904 prerender_manager()->CreateNextPrerenderContents(
905 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
906 EXPECT_TRUE(AddSimplePrerender(url));
907 EXPECT_TRUE(prerender_contents->prerendering_has_started());
908 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
910 DummyPrerenderContents* pplt_dummy_contents =
911 prerender_manager()->CreateNextPrerenderContents(url,
913 GURL ftp_url("ftp://ftp.google.com/");
914 // Adding this ftp URL will force the expected unsupported scheme error.
915 prerender_contents->AddAliasURL(ftp_url);
916 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
918 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
919 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
922 // Tests that our PPLT dummy prerender gets created properly, even
923 // when navigating to a page that has been recently navigated to.
924 TEST_F(PrerenderTest, RecentlyVisitedPPLTDummy) {
925 GURL url("http://www.google.com/");
926 DummyPrerenderContents* prerender_contents =
927 prerender_manager()->CreateNextPrerenderContents(
928 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
929 EXPECT_TRUE(AddSimplePrerender(url));
930 EXPECT_TRUE(prerender_contents->prerendering_has_started());
932 DummyPrerenderContents* pplt_dummy_contents =
933 prerender_manager()->CreateNextPrerenderContents(url,
935 prerender_manager()->RecordNavigation(url);
936 GURL ftp_url("ftp://ftp.google.com/");
937 prerender_contents->AddAliasURL(ftp_url);
939 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
942 TEST_F(PrerenderTest, PPLTLateCancel) {
943 GURL url("http://www.google.com");
944 DummyPrerenderContents* prerender_contents =
945 prerender_manager()->CreateNextPrerenderContents(
946 url, FINAL_STATUS_JAVASCRIPT_ALERT);
947 EXPECT_TRUE(AddSimplePrerender(url));
948 EXPECT_TRUE(prerender_contents->prerendering_has_started());
949 // Force the creation of a match complete dummy.
950 DummyPrerenderContents* duplicate_prerender_contents =
951 prerender_manager()->CreateNextPrerenderContents(url,
952 FINAL_STATUS_CANCELLED);
953 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
954 prerender_contents->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT);
955 ASSERT_EQ(duplicate_prerender_contents, prerender_manager()->FindEntry(url));
957 // Make sure that events on prerender handles propogate to the match
958 // complete replacement.
959 DummyPrerenderContents* null = NULL;
960 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
961 last_prerender_id());
962 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
965 // Tests that the prerender manager matches include the fragment.
966 TEST_F(PrerenderTest, FragmentMatchesTest) {
967 GURL fragment_url("http://www.google.com/#test");
969 DummyPrerenderContents* prerender_contents =
970 prerender_manager()->CreateNextPrerenderContents(fragment_url,
972 EXPECT_TRUE(AddSimplePrerender(fragment_url));
973 EXPECT_TRUE(prerender_contents->prerendering_has_started());
974 ASSERT_EQ(prerender_contents,
975 prerender_manager()->FindAndUseEntry(fragment_url));
978 // Tests that the prerender manager uses fragment references when matching
979 // prerender URLs in the case a different fragment is in both URLs.
980 TEST_F(PrerenderTest, FragmentsDifferTest) {
981 GURL fragment_url("http://www.google.com/#test");
982 GURL other_fragment_url("http://www.google.com/#other_test");
984 DummyPrerenderContents* prerender_contents =
985 prerender_manager()->CreateNextPrerenderContents(fragment_url,
987 EXPECT_TRUE(AddSimplePrerender(fragment_url));
988 EXPECT_TRUE(prerender_contents->prerendering_has_started());
990 DummyPrerenderContents* null = NULL;
991 ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url));
993 ASSERT_EQ(prerender_contents,
994 prerender_manager()->FindAndUseEntry(fragment_url));
997 // Make sure that clearing works as expected.
998 TEST_F(PrerenderTest, ClearTest) {
999 GURL url("http://www.google.com/");
1000 DummyPrerenderContents* prerender_contents =
1001 prerender_manager()->CreateNextPrerenderContents(
1003 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED);
1004 EXPECT_TRUE(AddSimplePrerender(url));
1005 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1006 prerender_manager()->ClearData(PrerenderManager::CLEAR_PRERENDER_CONTENTS);
1007 DummyPrerenderContents* null = NULL;
1008 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1011 // Make sure canceling works as expected.
1012 TEST_F(PrerenderTest, CancelAllTest) {
1013 GURL url("http://www.google.com/");
1014 DummyPrerenderContents* prerender_contents =
1015 prerender_manager()->CreateNextPrerenderContents(
1016 url, FINAL_STATUS_CANCELLED);
1017 EXPECT_TRUE(AddSimplePrerender(url));
1018 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1019 prerender_manager()->CancelAllPrerenders();
1020 const DummyPrerenderContents* null = NULL;
1021 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1024 TEST_F(PrerenderTest, OmniboxNotAllowedWhenDisabled) {
1025 prerender_manager()->set_enabled(false);
1026 EXPECT_FALSE(prerender_manager()->AddPrerenderFromOmnibox(
1027 GURL("http://www.example.com"), NULL, gfx::Size()));
1030 TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) {
1031 prerender_manager()->set_enabled(false);
1032 EXPECT_FALSE(AddSimplePrerender(
1033 GURL("http://www.example.com")));
1036 TEST_F(PrerenderTest, LinkManagerCancel) {
1037 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1038 GURL url("http://www.myexample.com");
1039 DummyPrerenderContents* prerender_contents =
1040 prerender_manager()->CreateNextPrerenderContents(
1041 url, FINAL_STATUS_CANCELLED);
1043 EXPECT_TRUE(AddSimplePrerender(url));
1045 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1046 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1047 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1048 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1049 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1050 last_prerender_id());
1052 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1053 DummyPrerenderContents* null = NULL;
1054 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1055 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1058 TEST_F(PrerenderTest, LinkManagerCancelThenAbandon) {
1059 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1060 GURL url("http://www.myexample.com");
1061 DummyPrerenderContents* prerender_contents =
1062 prerender_manager()->CreateNextPrerenderContents(
1063 url, FINAL_STATUS_CANCELLED);
1065 EXPECT_TRUE(AddSimplePrerender(url));
1067 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1068 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1069 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1070 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1071 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1072 last_prerender_id());
1074 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1075 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1076 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1077 last_prerender_id());
1079 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1080 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1081 DummyPrerenderContents* null = NULL;
1082 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1085 TEST_F(PrerenderTest, LinkManagerAbandon) {
1086 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1087 GURL url("http://www.myexample.com");
1088 DummyPrerenderContents* prerender_contents =
1089 prerender_manager()->CreateNextPrerenderContents(
1090 url, FINAL_STATUS_USED);
1092 EXPECT_TRUE(AddSimplePrerender(url));
1094 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1095 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1096 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1097 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1098 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1099 last_prerender_id());
1101 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1102 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1105 TEST_F(PrerenderTest, LinkManagerAbandonThenCancel) {
1106 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1107 GURL url("http://www.myexample.com");
1108 DummyPrerenderContents* prerender_contents =
1109 prerender_manager()->CreateNextPrerenderContents(
1110 url, FINAL_STATUS_CANCELLED);
1112 EXPECT_TRUE(AddSimplePrerender(url));
1114 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1115 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1116 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1117 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1118 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1119 last_prerender_id());
1121 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1122 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1124 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1125 last_prerender_id());
1126 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1127 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1128 DummyPrerenderContents* null = NULL;
1129 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1132 TEST_F(PrerenderTest, LinkManagerCancelTwice) {
1133 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1134 GURL url("http://www.myexample.com");
1135 DummyPrerenderContents* prerender_contents =
1136 prerender_manager()->CreateNextPrerenderContents(
1137 url, FINAL_STATUS_CANCELLED);
1139 EXPECT_TRUE(AddSimplePrerender(url));
1140 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1141 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1142 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1143 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1144 last_prerender_id());
1146 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1147 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1148 DummyPrerenderContents* null = NULL;
1149 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1150 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1151 last_prerender_id());
1154 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwice) {
1156 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1157 GURL url("http://www.myexample.com");
1158 DummyPrerenderContents* prerender_contents =
1159 prerender_manager()->CreateNextPrerenderContents(
1160 url, FINAL_STATUS_CANCELLED);
1162 EXPECT_TRUE(AddSimplePrerender(url));
1164 const int first_prerender_id = last_prerender_id();
1165 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1166 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1167 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1168 EXPECT_TRUE(AddSimplePrerender(url));
1170 const int second_prerender_id = last_prerender_id();
1171 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1172 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1173 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1174 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1175 first_prerender_id);
1177 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1178 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1179 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1180 second_prerender_id);
1182 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1183 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1184 DummyPrerenderContents* null = NULL;
1185 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1188 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) {
1190 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1191 GURL url("http://www.myexample.com");
1192 DummyPrerenderContents* prerender_contents =
1193 prerender_manager()->CreateNextPrerenderContents(
1194 url, FINAL_STATUS_CANCELLED);
1196 EXPECT_TRUE(AddSimplePrerender(url));
1198 const int first_prerender_id = last_prerender_id();
1199 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1200 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1201 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1202 EXPECT_TRUE(AddSimplePrerender(url));
1204 const int second_prerender_id = last_prerender_id();
1205 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1206 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1207 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1208 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1209 first_prerender_id);
1211 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1212 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1213 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1214 second_prerender_id);
1216 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1217 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1218 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1219 first_prerender_id);
1221 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1222 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1223 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1224 second_prerender_id);
1226 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1227 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1228 DummyPrerenderContents* null = NULL;
1229 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1232 // TODO(gavinp): Update this test after abandon has an effect on Prerenders,
1233 // like shortening the timeouts.
1234 TEST_F(PrerenderTest, LinkManagerAddTwiceAbandonTwiceUseTwice) {
1236 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1237 GURL url("http://www.myexample.com");
1238 DummyPrerenderContents* prerender_contents =
1239 prerender_manager()->CreateNextPrerenderContents(
1240 url, FINAL_STATUS_USED);
1242 EXPECT_TRUE(AddSimplePrerender(url));
1244 const int first_prerender_id = last_prerender_id();
1245 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1246 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1247 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1248 EXPECT_TRUE(AddSimplePrerender(url));
1250 const int second_prerender_id = last_prerender_id();
1251 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1252 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1253 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1254 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1255 first_prerender_id);
1257 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1258 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1259 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1260 second_prerender_id);
1262 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1263 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1264 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1267 // TODO(gavinp): After abandon shortens the expire time on a Prerender,
1268 // add a series of tests testing advancing the time by either the abandon
1269 // or normal expire, and verifying the expected behaviour with groups
1271 TEST_F(PrerenderTest, LinkManagerExpireThenCancel) {
1272 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1273 GURL url("http://www.myexample.com");
1274 DummyPrerenderContents* prerender_contents =
1275 prerender_manager()->CreateNextPrerenderContents(
1276 url, FINAL_STATUS_TIMED_OUT);
1278 EXPECT_TRUE(AddSimplePrerender(url));
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_manager()->AdvanceTimeTicks(
1284 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1286 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1287 DummyPrerenderContents* null = NULL;
1288 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1289 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1290 last_prerender_id());
1292 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1293 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1296 TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) {
1297 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1298 GURL url("http://www.myexample.com");
1299 DummyPrerenderContents* first_prerender_contents =
1300 prerender_manager()->CreateNextPrerenderContents(
1301 url, FINAL_STATUS_TIMED_OUT);
1302 EXPECT_TRUE(AddSimplePrerender(url));
1303 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1304 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1305 ASSERT_EQ(first_prerender_contents,
1306 prerender_manager()->FindEntry(url));
1307 prerender_manager()->AdvanceTimeTicks(
1308 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1309 DummyPrerenderContents* null = NULL;
1310 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1311 DummyPrerenderContents* second_prerender_contents =
1312 prerender_manager()->CreateNextPrerenderContents(
1313 url, FINAL_STATUS_USED);
1314 EXPECT_TRUE(AddSimplePrerender(url));
1315 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1316 ASSERT_EQ(second_prerender_contents,
1317 prerender_manager()->FindAndUseEntry(url));
1320 TEST_F(PrerenderTest, LinkManagerCancelThenAddAgain) {
1321 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1322 GURL url("http://www.myexample.com");
1323 DummyPrerenderContents* first_prerender_contents =
1324 prerender_manager()->CreateNextPrerenderContents(
1325 url, FINAL_STATUS_CANCELLED);
1326 EXPECT_TRUE(AddSimplePrerender(url));
1327 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1328 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1329 ASSERT_EQ(first_prerender_contents, prerender_manager()->FindEntry(url));
1330 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1331 last_prerender_id());
1332 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1333 EXPECT_TRUE(first_prerender_contents->prerendering_has_been_cancelled());
1334 DummyPrerenderContents* null = NULL;
1335 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1336 DummyPrerenderContents* second_prerender_contents =
1337 prerender_manager()->CreateNextPrerenderContents(
1338 url, FINAL_STATUS_USED);
1339 EXPECT_TRUE(AddSimplePrerender(url));
1340 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1341 ASSERT_EQ(second_prerender_contents,
1342 prerender_manager()->FindAndUseEntry(url));
1345 TEST_F(PrerenderTest, LinkManagerChannelClosing) {
1346 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1347 GURL url("http://www.myexample.com");
1348 DummyPrerenderContents* prerender_contents =
1349 prerender_manager()->CreateNextPrerenderContents(
1350 url, FINAL_STATUS_TIMED_OUT);
1352 EXPECT_TRUE(AddSimplePrerender(url));
1353 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1354 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1355 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1357 prerender_link_manager()->OnChannelClosing(kDefaultChildId);
1359 prerender_manager()->AdvanceTimeTicks(
1360 prerender_manager()->config().abandon_time_to_live +
1361 TimeDelta::FromSeconds(1));
1363 DummyPrerenderContents* null = NULL;
1364 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1365 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1368 // Creates two prerenders, one of which should be blocked by the
1369 // max_link_concurrency; abandons both of them and waits to make sure both
1370 // are cleared from the PrerenderLinkManager.
1371 TEST_F(PrerenderTest, LinkManagerAbandonInactivePrerender) {
1373 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1374 prerender_manager()->config().time_to_live);
1375 GURL first_url("http://www.myexample.com");
1376 DummyPrerenderContents* prerender_contents =
1377 prerender_manager()->CreateNextPrerenderContents(
1378 first_url, FINAL_STATUS_TIMED_OUT);
1379 EXPECT_TRUE(AddSimplePrerender(first_url));
1380 const int first_prerender_id = last_prerender_id();
1382 GURL second_url("http://www.neverlaunched.com");
1383 EXPECT_FALSE(AddSimplePrerender(second_url));
1384 const int second_prerender_id = last_prerender_id();
1386 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1388 DummyPrerenderContents* null = NULL;
1389 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1390 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1392 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1393 first_prerender_id);
1394 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1395 second_prerender_id);
1397 prerender_manager()->AdvanceTimeTicks(
1398 prerender_manager()->config().abandon_time_to_live +
1399 TimeDelta::FromSeconds(1));
1400 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1401 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1402 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1405 // Creates two prerenders, the second one started by the first, both of which
1406 // should be blocked by max_concurrency; abandons both of them and waits to make
1407 // sure both are cleared from the PrerenderLinkManager.
1408 TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) {
1410 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1411 prerender_manager()->config().time_to_live);
1412 GURL first_url("http://www.myexample.com");
1413 DummyPrerenderContents* prerender_contents =
1414 prerender_manager()->CreateNextPrerenderContents(
1415 first_url, FINAL_STATUS_TIMED_OUT);
1416 EXPECT_TRUE(AddSimplePrerender(first_url));
1417 const int first_prerender_id = last_prerender_id();
1421 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
1422 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
1424 GURL pending_url("http://www.neverlaunched.com");
1425 prerender_link_manager()->OnAddPrerender(
1426 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
1427 content::Referrer(), kSize, route_id);
1428 const int second_prerender_id = last_prerender_id();
1430 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1432 DummyPrerenderContents* null = NULL;
1433 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1434 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1436 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1437 first_prerender_id);
1438 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1439 second_prerender_id);
1441 prerender_manager()->AdvanceTimeTicks(
1442 prerender_manager()->config().abandon_time_to_live +
1443 TimeDelta::FromSeconds(1));
1444 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1445 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1446 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1449 // Creates two prerenders, one of which should be blocked by the
1450 // max_link_concurrency; uses one after the max wait to launch, and
1451 // ensures the second prerender does not start.
1452 TEST_F(PrerenderTest, LinkManagerWaitToLaunchNotLaunched) {
1454 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1455 prerender_manager()->config().time_to_live);
1456 GURL first_url("http://www.myexample.com");
1457 DummyPrerenderContents* prerender_contents =
1458 prerender_manager()->CreateNextPrerenderContents(
1459 first_url, FINAL_STATUS_USED);
1460 EXPECT_TRUE(AddSimplePrerender(first_url));
1462 GURL second_url("http://www.neverlaunched.com");
1463 EXPECT_FALSE(AddSimplePrerender(second_url));
1465 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1467 DummyPrerenderContents* null = NULL;
1468 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1469 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1471 prerender_manager()->AdvanceTimeTicks(
1472 prerender_manager()->config().max_wait_to_launch +
1473 TimeDelta::FromSeconds(1));
1474 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1475 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1477 EXPECT_EQ(prerender_contents,
1478 prerender_manager()->FindAndUseEntry(first_url));
1480 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1481 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1482 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1485 // Creates two prerenders, one of which should start when the first one expires.
1486 TEST_F(PrerenderTest, LinkManagerExpireRevealingLaunch) {
1488 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1489 prerender_manager()->config().time_to_live);
1491 GURL first_url("http://www.willexpire.com");
1492 DummyPrerenderContents* first_prerender_contents =
1493 prerender_manager()->CreateNextPrerenderContents(
1494 first_url, FINAL_STATUS_TIMED_OUT);
1495 EXPECT_TRUE(AddSimplePrerender(first_url));
1496 EXPECT_EQ(first_prerender_contents,
1497 prerender_manager()->FindEntry(first_url));
1499 // Insert the second prerender so it will be still be launchable when the
1501 const TimeDelta wait_to_launch_second_prerender =
1502 prerender_manager()->config().time_to_live -
1503 prerender_manager()->config().max_wait_to_launch +
1504 TimeDelta::FromSeconds(2);
1505 const TimeDelta wait_for_first_prerender_to_expire =
1506 prerender_manager()->config().time_to_live -
1507 wait_to_launch_second_prerender +
1508 TimeDelta::FromSeconds(1);
1509 ASSERT_LT(prerender_manager()->config().time_to_live,
1510 wait_to_launch_second_prerender +
1511 wait_for_first_prerender_to_expire);
1512 ASSERT_GT(prerender_manager()->config().max_wait_to_launch.InSeconds(),
1513 wait_for_first_prerender_to_expire.InSeconds());
1515 prerender_manager()->AdvanceTimeTicks(wait_to_launch_second_prerender);
1516 GURL second_url("http://www.willlaunch.com");
1517 DummyPrerenderContents* second_prerender_contents =
1518 prerender_manager()->CreateNextPrerenderContents(
1519 second_url, FINAL_STATUS_USED);
1520 EXPECT_FALSE(AddSimplePrerender(second_url));
1522 // The first prerender is still running, but the second has not yet launched.
1523 EXPECT_EQ(first_prerender_contents,
1524 prerender_manager()->FindEntry(first_url));
1525 PrerenderContents* null = NULL;
1526 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1528 // The first prerender should have died, giving life to the second one.
1529 prerender_manager()->AdvanceTimeTicks(wait_for_first_prerender_to_expire);
1530 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1531 EXPECT_EQ(second_prerender_contents,
1532 prerender_manager()->FindAndUseEntry(second_url));
1535 TEST_F(PrerenderTest, InstantSearchNotAllowedWhenDisabled) {
1536 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1538 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1"));
1539 prerender_manager()->set_enabled(false);
1540 EXPECT_FALSE(prerender_manager()->AddPrerenderForInstant(
1541 GURL("http://www.example.com/instant_search"), NULL, gfx::Size()));
1544 TEST_F(PrerenderTest, PrerenderContentsForInstantSearch) {
1545 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1547 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1"));
1548 GURL url("http://www.example.com/instant_search");
1549 DummyPrerenderContents* prerender_contents =
1550 prerender_manager()->CreateNextPrerenderContents(url, ORIGIN_INSTANT,
1552 scoped_ptr<PrerenderHandle> prerender_handle(
1553 prerender_manager()->AddPrerenderForInstant(url, NULL, kSize));
1554 CHECK(prerender_handle.get());
1555 EXPECT_TRUE(prerender_handle->IsPrerendering());
1556 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1557 EXPECT_EQ(prerender_contents, prerender_handle->contents());
1558 EXPECT_EQ(ORIGIN_INSTANT, prerender_handle->contents()->origin());
1559 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1560 EXPECT_FALSE(prerender_handle->IsPrerendering());
1563 } // namespace prerender