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/prefs/pref_service.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/net/prediction_options.h"
17 #include "chrome/browser/prerender/prerender_contents.h"
18 #include "chrome/browser/prerender/prerender_handle.h"
19 #include "chrome/browser/prerender/prerender_link_manager.h"
20 #include "chrome/browser/prerender/prerender_manager.h"
21 #include "chrome/browser/prerender/prerender_origin.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/common/prerender_types.h"
25 #include "chrome/test/base/testing_browser_process.h"
26 #include "chrome/test/base/testing_profile.h"
27 #include "content/public/browser/render_view_host.h"
28 #include "content/public/test/test_browser_thread.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30 #include "ui/gfx/size.h"
34 using base::TimeDelta;
35 using base::TimeTicks;
36 using content::BrowserThread;
37 using content::Referrer;
41 class UnitTestPrerenderManager;
45 class DummyPrerenderContents : public PrerenderContents {
47 DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager,
48 PrerenderTracker* prerender_tracker,
51 FinalStatus expected_final_status);
53 ~DummyPrerenderContents() override;
55 void StartPrerendering(
57 const gfx::Size& size,
58 content::SessionStorageNamespace* session_storage_namespace,
59 net::URLRequestContextGetter* request_context) override;
61 bool GetChildId(int* child_id) const override {
62 // Having a default child_id of -1 forces pending prerenders not to fail
63 // on session storage and cross domain checking.
68 bool GetRouteId(int* route_id) const override {
69 *route_id = route_id_;
73 FinalStatus expected_final_status() const { return expected_final_status_; }
75 bool prerendering_has_been_cancelled() const {
76 return PrerenderContents::prerendering_has_been_cancelled();
80 static int g_next_route_id_;
83 UnitTestPrerenderManager* test_prerender_manager_;
84 FinalStatus expected_final_status_;
87 int DummyPrerenderContents::g_next_route_id_ = 0;
89 const gfx::Size kSize(640, 480);
91 const uint32 kDefaultRelTypes = PrerenderRelTypePrerender;
95 class UnitTestPrerenderManager : public PrerenderManager {
97 using PrerenderManager::kMinTimeBetweenPrerendersMs;
98 using PrerenderManager::kNavigationRecordWindowMs;
100 explicit UnitTestPrerenderManager(Profile* profile,
101 PrerenderTracker* prerender_tracker)
102 : PrerenderManager(profile, prerender_tracker),
104 time_ticks_(TimeTicks::Now()),
105 prerender_tracker_(prerender_tracker) {
106 set_rate_limit_enabled(false);
107 OnCookieStoreLoaded();
110 ~UnitTestPrerenderManager() override {}
112 // From KeyedService, via PrererenderManager:
113 void Shutdown() override {
114 if (next_prerender_contents())
115 next_prerender_contents_->Destroy(FINAL_STATUS_MANAGER_SHUTDOWN);
116 PrerenderManager::Shutdown();
119 // From PrerenderManager:
120 void MoveEntryToPendingDelete(PrerenderContents* entry,
121 FinalStatus final_status) override {
122 if (entry == next_prerender_contents_.get())
124 PrerenderManager::MoveEntryToPendingDelete(entry, final_status);
127 PrerenderContents* FindEntry(const GURL& url) {
129 to_delete_prerenders_.clear();
130 if (PrerenderData* data = FindPrerenderData(url, NULL))
131 return data->contents();
135 PrerenderContents* FindAndUseEntry(const GURL& url) {
136 PrerenderData* prerender_data = FindPrerenderData(url, NULL);
139 ScopedVector<PrerenderData>::iterator to_erase =
140 FindIteratorForPrerenderContents(prerender_data->contents());
141 CHECK(to_erase != active_prerenders_.end());
142 PrerenderContents* prerender_contents = prerender_data->ReleaseContents();
143 active_prerenders_.erase(to_erase);
145 prerender_contents->PrepareForUse();
146 return prerender_contents;
149 void AdvanceTime(TimeDelta delta) {
153 void AdvanceTimeTicks(TimeDelta delta) {
154 time_ticks_ += delta;
157 DummyPrerenderContents* CreateNextPrerenderContents(
159 FinalStatus expected_final_status) {
160 DummyPrerenderContents* prerender_contents =
161 new DummyPrerenderContents(this, prerender_tracker_, url,
162 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
163 expected_final_status);
164 SetNextPrerenderContents(prerender_contents);
165 return prerender_contents;
168 DummyPrerenderContents* CreateNextPrerenderContents(
171 FinalStatus expected_final_status) {
172 DummyPrerenderContents* prerender_contents =
173 new DummyPrerenderContents(this, prerender_tracker_, url,
174 origin, expected_final_status);
175 SetNextPrerenderContents(prerender_contents);
176 return prerender_contents;
179 DummyPrerenderContents* CreateNextPrerenderContents(
181 const std::vector<GURL>& alias_urls,
182 FinalStatus expected_final_status) {
183 DummyPrerenderContents* prerender_contents =
184 new DummyPrerenderContents(this, prerender_tracker_, url,
185 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
186 expected_final_status);
187 for (std::vector<GURL>::const_iterator it = alias_urls.begin();
188 it != alias_urls.end();
190 EXPECT_TRUE(prerender_contents->AddAliasURL(*it));
192 SetNextPrerenderContents(prerender_contents);
193 return prerender_contents;
196 void set_rate_limit_enabled(bool enabled) {
197 mutable_config().rate_limit_enabled = enabled;
200 PrerenderContents* next_prerender_contents() {
201 return next_prerender_contents_.get();
204 // from PrerenderManager
205 Time GetCurrentTime() const override { return time_; }
207 TimeTicks GetCurrentTimeTicks() const override { return time_ticks_; }
209 PrerenderContents* GetPrerenderContentsForRoute(int child_id,
210 int route_id) const override {
211 // Overridden for the PrerenderLinkManager's pending prerender logic.
212 PrerenderContentsMap::const_iterator iter = prerender_contents_map_.find(
213 std::make_pair(child_id, route_id));
214 if (iter == prerender_contents_map_.end())
219 void DummyPrerenderContentsStarted(int child_id,
221 PrerenderContents* prerender_contents) {
222 prerender_contents_map_[std::make_pair(child_id, route_id)] =
226 void DummyPrerenderContentsDestroyed(int child_id,
228 prerender_contents_map_.erase(std::make_pair(child_id, route_id));
232 net::URLRequestContextGetter* GetURLRequestContext() override { return NULL; }
235 void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
236 CHECK(!next_prerender_contents_.get());
237 next_prerender_contents_.reset(prerender_contents);
238 if (prerender_contents->expected_final_status() == FINAL_STATUS_USED)
239 used_prerender_contents_.push_back(prerender_contents);
242 PrerenderContents* CreatePrerenderContents(const GURL& url,
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 creator_child_id,
298 const gfx::Size& size,
299 content::SessionStorageNamespace* session_storage_namespace,
300 net::URLRequestContextGetter* request_context) {
301 // In the base PrerenderContents implementation, StartPrerendering will
302 // be called even when the PrerenderManager is part of the control group,
303 // but it will early exit before actually creating a new RenderView if
304 // |is_control_group| is true;
305 load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
306 if (!test_prerender_manager_->IsControlGroup(experiment_id())) {
307 prerendering_has_started_ = true;
308 test_prerender_manager_->DummyPrerenderContentsStarted(-1, route_id_, this);
309 NotifyPrerenderStart();
313 class PrerenderTest : public testing::Test {
315 static const int kDefaultChildId = -1;
316 static const int kDefaultRenderViewRouteId = -1;
318 PrerenderTest() : ui_thread_(BrowserThread::UI, &message_loop_),
319 prerender_manager_(new UnitTestPrerenderManager(
320 &profile_, prerender_tracker())),
321 prerender_link_manager_(
322 new PrerenderLinkManager(prerender_manager_.get())),
323 last_prerender_id_(0),
324 field_trial_list_(NULL) {
325 // Enable omnibox prerendering.
326 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
327 switches::kPrerenderFromOmnibox,
328 switches::kPrerenderFromOmniboxSwitchValueEnabled);
331 ~PrerenderTest() override {
332 prerender_link_manager_->OnChannelClosing(kDefaultChildId);
333 prerender_link_manager_->Shutdown();
334 prerender_manager_->Shutdown();
337 UnitTestPrerenderManager* prerender_manager() {
338 return prerender_manager_.get();
341 PrerenderLinkManager* prerender_link_manager() {
342 return prerender_link_manager_.get();
345 void SetConcurrency(size_t concurrency) {
346 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
348 prerender_manager()->mutable_config().max_link_concurrency =
349 std::max(prerender_manager()->mutable_config().max_link_concurrency,
353 bool IsEmptyPrerenderLinkManager() const {
354 return prerender_link_manager_->IsEmpty();
357 int last_prerender_id() const {
358 return last_prerender_id_;
361 int GetNextPrerenderID() {
362 return ++last_prerender_id_;
365 bool LauncherHasRunningPrerender(int child_id, int prerender_id) {
366 PrerenderLinkManager::LinkPrerender* prerender =
367 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
368 child_id, prerender_id);
369 return prerender && prerender->handle;
372 bool LauncherHasScheduledPrerender(int child_id, int prerender_id) {
373 PrerenderLinkManager::LinkPrerender* prerender =
374 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
375 child_id, prerender_id);
376 return prerender != NULL;
379 // Shorthand to add a simple prerender with a reasonable source. Returns
380 // true iff the prerender has been added to the PrerenderManager by the
381 // PrerenderLinkManager and the PrerenderManager returned a handle.
382 bool AddSimplePrerender(const GURL& url) {
383 prerender_link_manager()->OnAddPrerender(
384 kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes,
385 content::Referrer(), kSize, kDefaultRenderViewRouteId);
386 return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id());
389 void DisablePrerender() {
390 profile_.GetPrefs()->SetInteger(
391 prefs::kNetworkPredictionOptions,
392 chrome_browser_net::NETWORK_PREDICTION_NEVER);
396 PrerenderTracker* prerender_tracker() {
397 return g_browser_process->prerender_tracker();
400 // Needed to pass PrerenderManager's DCHECKs.
401 TestingProfile profile_;
402 base::MessageLoop message_loop_;
403 content::TestBrowserThread ui_thread_;
404 scoped_ptr<UnitTestPrerenderManager> prerender_manager_;
405 scoped_ptr<PrerenderLinkManager> prerender_link_manager_;
406 int last_prerender_id_;
407 base::FieldTrialList field_trial_list_;
410 TEST_F(PrerenderTest, FoundTest) {
411 GURL url("http://www.google.com/");
412 DummyPrerenderContents* prerender_contents =
413 prerender_manager()->CreateNextPrerenderContents(
416 EXPECT_TRUE(AddSimplePrerender(url));
417 EXPECT_TRUE(prerender_contents->prerendering_has_started());
418 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
421 // Make sure that if queue a request, and a second prerender request for the
422 // same URL comes in, that the second request attaches to the first prerender,
423 // and we don't use the second prerender contents.
424 TEST_F(PrerenderTest, DuplicateTest) {
426 GURL url("http://www.google.com/");
427 DummyPrerenderContents* prerender_contents =
428 prerender_manager()->CreateNextPrerenderContents(
431 DummyPrerenderContents* null = NULL;
432 EXPECT_TRUE(AddSimplePrerender(url));
433 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
434 EXPECT_TRUE(prerender_contents->prerendering_has_started());
436 DummyPrerenderContents* prerender_contents1 =
437 prerender_manager()->CreateNextPrerenderContents(
439 FINAL_STATUS_MANAGER_SHUTDOWN);
440 EXPECT_TRUE(AddSimplePrerender(url));
441 EXPECT_EQ(prerender_contents1,
442 prerender_manager()->next_prerender_contents());
443 EXPECT_FALSE(prerender_contents1->prerendering_has_started());
445 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
448 // Ensure that we expire a prerendered page after the max. permitted time.
449 TEST_F(PrerenderTest, ExpireTest) {
450 GURL url("http://www.google.com/");
451 DummyPrerenderContents* prerender_contents =
452 prerender_manager()->CreateNextPrerenderContents(
454 FINAL_STATUS_TIMED_OUT);
455 DummyPrerenderContents* null = NULL;
456 EXPECT_TRUE(AddSimplePrerender(url));
457 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
458 EXPECT_TRUE(prerender_contents->prerendering_has_started());
459 prerender_manager()->AdvanceTimeTicks(
460 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
461 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
464 // Ensure that we don't launch prerenders of bad urls (in this case, a mailto:
466 TEST_F(PrerenderTest, BadURLTest) {
467 GURL url("mailto:test@gmail.com");
468 DummyPrerenderContents* prerender_contents =
469 prerender_manager()->CreateNextPrerenderContents(
471 FINAL_STATUS_UNSUPPORTED_SCHEME);
472 EXPECT_FALSE(AddSimplePrerender(url));
473 EXPECT_FALSE(prerender_contents->prerendering_has_started());
474 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
475 DummyPrerenderContents* null = NULL;
476 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
479 // When the user navigates away from a page, the prerenders it launched should
480 // have their time to expiry shortened from the default time to live.
481 TEST_F(PrerenderTest, LinkManagerNavigateAwayExpire) {
482 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
483 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
484 const TimeDelta test_advance = TimeDelta::FromSeconds(22);
485 ASSERT_LT(test_advance, time_to_live);
486 ASSERT_LT(abandon_time_to_live, test_advance);
488 prerender_manager()->mutable_config().time_to_live = time_to_live;
489 prerender_manager()->mutable_config().abandon_time_to_live =
490 abandon_time_to_live;
492 GURL url("http://example.com");
493 DummyPrerenderContents* prerender_contents =
494 prerender_manager()->CreateNextPrerenderContents(url,
495 FINAL_STATUS_TIMED_OUT);
496 EXPECT_TRUE(AddSimplePrerender(url));
497 EXPECT_TRUE(prerender_contents->prerendering_has_started());
498 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
499 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
500 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
501 last_prerender_id());
502 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
503 DummyPrerenderContents* null = NULL;
504 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
505 prerender_manager()->AdvanceTimeTicks(test_advance);
507 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
510 // But when we navigate away very close to the original expiry of a prerender,
511 // we shouldn't expect it to be extended.
512 TEST_F(PrerenderTest, LinkManagerNavigateAwayNearExpiry) {
513 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
514 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
516 // We will expect the prerender to still be alive after advancing the clock
517 // by first_advance. But, after second_advance, we expect it to have timed
518 // out, demonstrating that you can't extend a prerender by navigating away
519 // from its launcher.
520 const TimeDelta first_advance = TimeDelta::FromSeconds(298);
521 const TimeDelta second_advance = TimeDelta::FromSeconds(4);
522 ASSERT_LT(first_advance, time_to_live);
523 ASSERT_LT(time_to_live - first_advance, abandon_time_to_live);
524 ASSERT_LT(time_to_live, first_advance + second_advance);
526 prerender_manager()->mutable_config().time_to_live = time_to_live;
527 prerender_manager()->mutable_config().abandon_time_to_live =
528 abandon_time_to_live;
530 GURL url("http://example2.com");
531 DummyPrerenderContents* prerender_contents =
532 prerender_manager()->CreateNextPrerenderContents(url,
533 FINAL_STATUS_TIMED_OUT);
534 EXPECT_TRUE(AddSimplePrerender(url));
535 EXPECT_TRUE(prerender_contents->prerendering_has_started());
536 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
537 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
539 prerender_manager()->AdvanceTimeTicks(first_advance);
540 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
542 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
543 last_prerender_id());
544 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
546 DummyPrerenderContents* null = NULL;
547 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
549 prerender_manager()->AdvanceTimeTicks(second_advance);
550 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
553 // When the user navigates away from a page, and then launches a new prerender,
554 // the new prerender should preempt the abandoned prerender even if the
555 // abandoned prerender hasn't expired.
556 TEST_F(PrerenderTest, LinkManagerNavigateAwayLaunchAnother) {
557 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
558 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
559 const TimeDelta test_advance = TimeDelta::FromSeconds(5);
560 ASSERT_LT(test_advance, time_to_live);
561 ASSERT_GT(abandon_time_to_live, test_advance);
563 prerender_manager()->mutable_config().time_to_live = time_to_live;
564 prerender_manager()->mutable_config().abandon_time_to_live =
565 abandon_time_to_live;
567 GURL url("http://example.com");
568 prerender_manager()->CreateNextPrerenderContents(url, FINAL_STATUS_CANCELLED);
569 EXPECT_TRUE(AddSimplePrerender(url));
570 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
571 last_prerender_id());
573 prerender_manager()->AdvanceTimeTicks(test_advance);
575 GURL second_url("http://example2.com");
576 DummyPrerenderContents* second_prerender_contents =
577 prerender_manager()->CreateNextPrerenderContents(
578 second_url, FINAL_STATUS_MANAGER_SHUTDOWN);
579 EXPECT_TRUE(AddSimplePrerender(second_url));
580 EXPECT_EQ(second_prerender_contents,
581 prerender_manager()->FindEntry(second_url));
585 // Make sure that if we prerender more requests than we support, that we launch
586 // them in the order given up until we reach MaxConcurrency, at which point we
587 // queue them and launch them in the order given. As well, insure that limits
588 // are enforced for the system as a whole and on a per launcher basis.
589 TEST_F(PrerenderTest, MaxConcurrencyTest) {
590 struct TestConcurrency {
591 size_t max_link_concurrency;
592 size_t max_link_concurrency_per_launcher;
595 TestConcurrency concurrencies_to_test[] = {
596 { prerender_manager()->config().max_link_concurrency,
597 prerender_manager()->config().max_link_concurrency_per_launcher},
599 // With the system limit higher than the per launcher limit, the per
600 // launcher limit should be in effect.
603 // With the per launcher limit higher than system limit, the system limit
604 // should be in effect.
608 DummyPrerenderContents* null = NULL;
609 GURL url_to_delay("http://www.google.com/delayme");
611 for (size_t i = 0; i < arraysize(concurrencies_to_test); ++i) {
612 prerender_manager()->mutable_config().max_link_concurrency =
613 concurrencies_to_test[i].max_link_concurrency;
614 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
615 concurrencies_to_test[i].max_link_concurrency_per_launcher;
617 const size_t effective_max_link_concurrency =
618 std::min(concurrencies_to_test[i].max_link_concurrency,
619 concurrencies_to_test[i].max_link_concurrency_per_launcher);
621 std::vector<GURL> urls;
622 std::vector<PrerenderContents*> prerender_contentses;
624 // Launch prerenders up to the maximum this launcher can support.
625 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
627 GURL(base::StringPrintf("http://google.com/use#%" PRIuS, j)));
628 prerender_contentses.push_back(
629 prerender_manager()->CreateNextPrerenderContents(urls.back(),
631 EXPECT_TRUE(AddSimplePrerender(urls.back()));
632 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
633 EXPECT_TRUE(prerender_contentses.back()->prerendering_has_started());
636 if (concurrencies_to_test[i].max_link_concurrency >
637 effective_max_link_concurrency) {
638 // We should be able to launch more prerenders on this system, but not for
639 // the default launcher.
640 GURL extra_url("http://google.com/extraurl");
641 EXPECT_FALSE(AddSimplePrerender(extra_url));
642 const int prerender_id = last_prerender_id();
643 EXPECT_TRUE(LauncherHasScheduledPrerender(kDefaultChildId,
645 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
647 EXPECT_FALSE(LauncherHasScheduledPrerender(kDefaultChildId,
651 DummyPrerenderContents* prerender_contents_to_delay =
652 prerender_manager()->CreateNextPrerenderContents(url_to_delay,
654 EXPECT_FALSE(AddSimplePrerender(url_to_delay));
655 EXPECT_FALSE(prerender_contents_to_delay->prerendering_has_started());
656 EXPECT_NE(null, prerender_manager()->next_prerender_contents());
657 EXPECT_EQ(null, prerender_manager()->FindEntry(url_to_delay));
658 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
659 EXPECT_EQ(prerender_contentses[j],
660 prerender_manager()->FindAndUseEntry(urls[j]));
661 EXPECT_TRUE(prerender_contents_to_delay->prerendering_has_started());
664 EXPECT_EQ(prerender_contents_to_delay,
665 prerender_manager()->FindAndUseEntry(url_to_delay));
666 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
670 TEST_F(PrerenderTest, AliasURLTest) {
673 GURL url("http://www.google.com/");
674 GURL alias_url1("http://www.google.com/index.html");
675 GURL alias_url2("http://google.com/");
676 GURL not_an_alias_url("http://google.com/index.html");
677 std::vector<GURL> alias_urls;
678 alias_urls.push_back(alias_url1);
679 alias_urls.push_back(alias_url2);
681 // Test that all of the aliases work, but not_an_alias_url does not.
682 DummyPrerenderContents* prerender_contents =
683 prerender_manager()->CreateNextPrerenderContents(
684 url, alias_urls, FINAL_STATUS_USED);
685 EXPECT_TRUE(AddSimplePrerender(url));
686 ASSERT_EQ(NULL, prerender_manager()->FindEntry(not_an_alias_url));
687 ASSERT_EQ(prerender_contents,
688 prerender_manager()->FindAndUseEntry(alias_url1));
689 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
690 url, alias_urls, FINAL_STATUS_USED);
691 EXPECT_TRUE(AddSimplePrerender(url));
692 ASSERT_EQ(prerender_contents,
693 prerender_manager()->FindAndUseEntry(alias_url2));
694 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
695 url, alias_urls, FINAL_STATUS_USED);
696 EXPECT_TRUE(AddSimplePrerender(url));
697 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
699 // Test that alias URLs can not be added.
700 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
701 url, alias_urls, FINAL_STATUS_USED);
702 EXPECT_TRUE(AddSimplePrerender(url));
703 EXPECT_TRUE(AddSimplePrerender(url));
704 EXPECT_TRUE(AddSimplePrerender(alias_url1));
705 EXPECT_TRUE(AddSimplePrerender(alias_url2));
706 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
709 TEST_F(PrerenderTest, PendingPrerenderTest) {
710 GURL url("http://www.google.com/");
711 DummyPrerenderContents* prerender_contents =
712 prerender_manager()->CreateNextPrerenderContents(
715 EXPECT_TRUE(AddSimplePrerender(url));
719 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
720 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
722 GURL pending_url("http://news.google.com/");
724 // Schedule a pending prerender launched from the prerender.
725 DummyPrerenderContents* pending_prerender_contents =
726 prerender_manager()->CreateNextPrerenderContents(
728 ORIGIN_GWS_PRERENDER,
730 prerender_link_manager()->OnAddPrerender(
731 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
732 Referrer(url, blink::WebReferrerPolicyDefault),
734 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
735 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
737 // Use the referring prerender.
738 EXPECT_TRUE(prerender_contents->prerendering_has_started());
739 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
741 // The pending prerender should start now.
742 EXPECT_TRUE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
743 EXPECT_TRUE(pending_prerender_contents->prerendering_has_started());
744 ASSERT_EQ(pending_prerender_contents,
745 prerender_manager()->FindAndUseEntry(pending_url));
748 TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
749 GURL url("http://www.google.com/");
750 DummyPrerenderContents* prerender_contents =
751 prerender_manager()->CreateNextPrerenderContents(
754 EXPECT_TRUE(AddSimplePrerender(url));
758 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
759 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
761 // This pending URL has an unsupported scheme, and won't be able
763 GURL pending_url("ftp://news.google.com/");
765 // Schedule a pending prerender launched from the prerender.
766 DummyPrerenderContents* pending_prerender_contents =
767 prerender_manager()->CreateNextPrerenderContents(
769 ORIGIN_GWS_PRERENDER,
770 FINAL_STATUS_UNSUPPORTED_SCHEME);
771 prerender_link_manager()->OnAddPrerender(
772 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
773 Referrer(url, blink::WebReferrerPolicyDefault),
775 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
776 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
778 // Use the referring prerender.
779 EXPECT_TRUE(prerender_contents->prerendering_has_started());
780 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
782 // The pending prerender still doesn't start.
783 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
784 EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
787 TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
788 GURL url("http://www.google.com/");
789 DummyPrerenderContents* prerender_contents =
790 prerender_manager()->CreateNextPrerenderContents(
793 EXPECT_TRUE(AddSimplePrerender(url));
797 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
798 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
800 GURL pending_url("http://news.google.com/");
802 // Schedule a pending prerender launched from the prerender.
803 prerender_link_manager()->OnAddPrerender(
804 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
805 Referrer(url, blink::WebReferrerPolicyDefault),
807 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
809 // Cancel the pending prerender.
810 prerender_link_manager()->OnCancelPrerender(child_id, last_prerender_id());
812 // Use the referring prerender.
813 EXPECT_TRUE(prerender_contents->prerendering_has_started());
814 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
816 // The pending prerender doesn't start.
817 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
820 // Tests that a PrerenderManager created for a browser session in the control
821 // group works as expected.
822 TEST_F(PrerenderTest, ControlGroup) {
823 RestorePrerenderMode restore_prerender_mode;
824 PrerenderManager::SetMode(
825 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
826 GURL url("http://www.google.com/");
827 DummyPrerenderContents* prerender_contents =
828 prerender_manager()->CreateNextPrerenderContents(
830 FINAL_STATUS_MANAGER_SHUTDOWN);
831 EXPECT_TRUE(AddSimplePrerender(url));
832 EXPECT_FALSE(prerender_contents->prerendering_has_started());
835 // Tests that prerendering is cancelled when the source render view does not
836 // exist. On failure, the DCHECK in CreatePrerenderContents() above should be
838 TEST_F(PrerenderTest, SourceRenderViewClosed) {
839 GURL url("http://www.google.com/");
840 prerender_manager()->CreateNextPrerenderContents(
842 FINAL_STATUS_MANAGER_SHUTDOWN);
843 prerender_link_manager()->OnAddPrerender(
844 100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200);
845 EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id()));
848 // Tests that prerendering doesn't launch rel=next prerenders without the field
850 TEST_F(PrerenderTest, NoRelNextByDefault) {
851 GURL url("http://www.google.com/");
852 prerender_manager()->CreateNextPrerenderContents(
853 url, FINAL_STATUS_MANAGER_SHUTDOWN);
854 DummyPrerenderContents* null = NULL;
856 prerender_link_manager()->OnAddPrerender(
857 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
858 Referrer(), kSize, kDefaultRenderViewRouteId);
859 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
862 // Tests that prerendering does launch rel=next prerenders with the field trial.
863 TEST_F(PrerenderTest, RelNextByFieldTrial) {
864 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("PrerenderRelNextTrial",
866 GURL url("http://www.google.com/");
867 DummyPrerenderContents* prerender_contents =
868 prerender_manager()->CreateNextPrerenderContents(
869 url, ORIGIN_LINK_REL_NEXT, FINAL_STATUS_USED);
871 prerender_link_manager()->OnAddPrerender(
872 kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
873 Referrer(), kSize, kDefaultRenderViewRouteId);
874 EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
877 // Tests that prerendering is cancelled when we launch a second prerender of
878 // the same target within a short time interval.
879 TEST_F(PrerenderTest, RecentlyVisited) {
880 GURL url("http://www.google.com/");
882 prerender_manager()->RecordNavigation(url);
884 DummyPrerenderContents* prerender_contents =
885 prerender_manager()->CreateNextPrerenderContents(
886 url, FINAL_STATUS_RECENTLY_VISITED);
887 EXPECT_FALSE(AddSimplePrerender(url));
888 EXPECT_FALSE(prerender_contents->prerendering_has_started());
891 TEST_F(PrerenderTest, NotSoRecentlyVisited) {
892 GURL url("http://www.google.com/");
894 prerender_manager()->RecordNavigation(url);
895 prerender_manager()->AdvanceTimeTicks(
896 TimeDelta::FromMilliseconds(
897 UnitTestPrerenderManager::kNavigationRecordWindowMs + 500));
899 DummyPrerenderContents* prerender_contents =
900 prerender_manager()->CreateNextPrerenderContents(
901 url, FINAL_STATUS_USED);
902 EXPECT_TRUE(AddSimplePrerender(url));
903 EXPECT_TRUE(prerender_contents->prerendering_has_started());
904 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
907 // Tests that our PPLT dummy prerender gets created properly.
908 TEST_F(PrerenderTest, PPLTDummy) {
909 RestorePrerenderMode restore_prerender_mode;
910 PrerenderManager::SetMode(
911 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
913 GURL url("http://www.google.com/");
914 DummyPrerenderContents* prerender_contents =
915 prerender_manager()->CreateNextPrerenderContents(
916 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
917 EXPECT_TRUE(AddSimplePrerender(url));
918 EXPECT_TRUE(prerender_contents->prerendering_has_started());
919 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
921 DummyPrerenderContents* pplt_dummy_contents =
922 prerender_manager()->CreateNextPrerenderContents(url,
924 GURL ftp_url("ftp://ftp.google.com/");
925 // Adding this ftp URL will force the expected unsupported scheme error.
926 prerender_contents->AddAliasURL(ftp_url);
927 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
929 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
930 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
933 // Tests that our PPLT dummy prerender gets created properly, even
934 // when navigating to a page that has been recently navigated to.
935 TEST_F(PrerenderTest, RecentlyVisitedPPLTDummy) {
936 RestorePrerenderMode restore_prerender_mode;
937 PrerenderManager::SetMode(
938 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
940 GURL url("http://www.google.com/");
941 DummyPrerenderContents* prerender_contents =
942 prerender_manager()->CreateNextPrerenderContents(
943 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
944 EXPECT_TRUE(AddSimplePrerender(url));
945 EXPECT_TRUE(prerender_contents->prerendering_has_started());
947 DummyPrerenderContents* pplt_dummy_contents =
948 prerender_manager()->CreateNextPrerenderContents(url,
950 prerender_manager()->RecordNavigation(url);
951 GURL ftp_url("ftp://ftp.google.com/");
952 prerender_contents->AddAliasURL(ftp_url);
954 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
957 TEST_F(PrerenderTest, PPLTLateCancel) {
958 RestorePrerenderMode restore_prerender_mode;
959 PrerenderManager::SetMode(
960 PrerenderManager::PRERENDER_MODE_EXPERIMENT_MATCH_COMPLETE_GROUP);
962 GURL url("http://www.google.com");
963 DummyPrerenderContents* prerender_contents =
964 prerender_manager()->CreateNextPrerenderContents(
965 url, FINAL_STATUS_JAVASCRIPT_ALERT);
966 EXPECT_TRUE(AddSimplePrerender(url));
967 EXPECT_TRUE(prerender_contents->prerendering_has_started());
968 // Force the creation of a match complete dummy.
969 DummyPrerenderContents* duplicate_prerender_contents =
970 prerender_manager()->CreateNextPrerenderContents(url,
971 FINAL_STATUS_CANCELLED);
972 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
973 prerender_contents->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT);
974 ASSERT_EQ(duplicate_prerender_contents, prerender_manager()->FindEntry(url));
976 // Make sure that events on prerender handles propogate to the match
977 // complete replacement.
978 DummyPrerenderContents* null = NULL;
979 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
980 last_prerender_id());
981 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
984 // Tests that the prerender manager matches include the fragment.
985 TEST_F(PrerenderTest, FragmentMatchesTest) {
986 GURL fragment_url("http://www.google.com/#test");
988 DummyPrerenderContents* prerender_contents =
989 prerender_manager()->CreateNextPrerenderContents(fragment_url,
991 EXPECT_TRUE(AddSimplePrerender(fragment_url));
992 EXPECT_TRUE(prerender_contents->prerendering_has_started());
993 ASSERT_EQ(prerender_contents,
994 prerender_manager()->FindAndUseEntry(fragment_url));
997 // Tests that the prerender manager uses fragment references when matching
998 // prerender URLs in the case a different fragment is in both URLs.
999 TEST_F(PrerenderTest, FragmentsDifferTest) {
1000 GURL fragment_url("http://www.google.com/#test");
1001 GURL other_fragment_url("http://www.google.com/#other_test");
1003 DummyPrerenderContents* prerender_contents =
1004 prerender_manager()->CreateNextPrerenderContents(fragment_url,
1006 EXPECT_TRUE(AddSimplePrerender(fragment_url));
1007 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1009 DummyPrerenderContents* null = NULL;
1010 ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url));
1012 ASSERT_EQ(prerender_contents,
1013 prerender_manager()->FindAndUseEntry(fragment_url));
1016 // Make sure that clearing works as expected.
1017 TEST_F(PrerenderTest, ClearTest) {
1018 GURL url("http://www.google.com/");
1019 DummyPrerenderContents* prerender_contents =
1020 prerender_manager()->CreateNextPrerenderContents(
1022 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED);
1023 EXPECT_TRUE(AddSimplePrerender(url));
1024 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1025 prerender_manager()->ClearData(PrerenderManager::CLEAR_PRERENDER_CONTENTS);
1026 DummyPrerenderContents* null = NULL;
1027 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1030 // Make sure canceling works as expected.
1031 TEST_F(PrerenderTest, CancelAllTest) {
1032 GURL url("http://www.google.com/");
1033 DummyPrerenderContents* prerender_contents =
1034 prerender_manager()->CreateNextPrerenderContents(
1035 url, FINAL_STATUS_CANCELLED);
1036 EXPECT_TRUE(AddSimplePrerender(url));
1037 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1038 prerender_manager()->CancelAllPrerenders();
1039 const DummyPrerenderContents* null = NULL;
1040 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1043 TEST_F(PrerenderTest, OmniboxNotAllowedWhenDisabled) {
1045 EXPECT_FALSE(prerender_manager()->AddPrerenderFromOmnibox(
1046 GURL("http://www.example.com"), NULL, gfx::Size()));
1049 TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) {
1051 EXPECT_FALSE(AddSimplePrerender(
1052 GURL("http://www.example.com")));
1055 TEST_F(PrerenderTest, LinkManagerCancel) {
1056 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1057 GURL url("http://www.myexample.com");
1058 DummyPrerenderContents* prerender_contents =
1059 prerender_manager()->CreateNextPrerenderContents(
1060 url, FINAL_STATUS_CANCELLED);
1062 EXPECT_TRUE(AddSimplePrerender(url));
1064 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1065 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1066 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1067 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1068 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1069 last_prerender_id());
1071 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1072 DummyPrerenderContents* null = NULL;
1073 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1074 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1077 TEST_F(PrerenderTest, LinkManagerCancelThenAbandon) {
1078 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1079 GURL url("http://www.myexample.com");
1080 DummyPrerenderContents* prerender_contents =
1081 prerender_manager()->CreateNextPrerenderContents(
1082 url, FINAL_STATUS_CANCELLED);
1084 EXPECT_TRUE(AddSimplePrerender(url));
1086 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1087 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1088 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1089 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1090 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1091 last_prerender_id());
1093 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1094 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1095 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1096 last_prerender_id());
1098 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1099 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1100 DummyPrerenderContents* null = NULL;
1101 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1104 TEST_F(PrerenderTest, LinkManagerAbandon) {
1105 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1106 GURL url("http://www.myexample.com");
1107 DummyPrerenderContents* prerender_contents =
1108 prerender_manager()->CreateNextPrerenderContents(
1109 url, FINAL_STATUS_USED);
1111 EXPECT_TRUE(AddSimplePrerender(url));
1113 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1114 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1115 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1116 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1117 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1118 last_prerender_id());
1120 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1121 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1124 TEST_F(PrerenderTest, LinkManagerAbandonThenCancel) {
1125 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1126 GURL url("http://www.myexample.com");
1127 DummyPrerenderContents* prerender_contents =
1128 prerender_manager()->CreateNextPrerenderContents(
1129 url, FINAL_STATUS_CANCELLED);
1131 EXPECT_TRUE(AddSimplePrerender(url));
1133 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1134 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1135 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1136 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1137 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1138 last_prerender_id());
1140 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1141 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1143 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1144 last_prerender_id());
1145 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1146 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1147 DummyPrerenderContents* null = NULL;
1148 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1151 TEST_F(PrerenderTest, LinkManagerCancelTwice) {
1152 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1153 GURL url("http://www.myexample.com");
1154 DummyPrerenderContents* prerender_contents =
1155 prerender_manager()->CreateNextPrerenderContents(
1156 url, FINAL_STATUS_CANCELLED);
1158 EXPECT_TRUE(AddSimplePrerender(url));
1159 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1160 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1161 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1162 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1163 last_prerender_id());
1165 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1166 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1167 DummyPrerenderContents* null = NULL;
1168 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1169 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1170 last_prerender_id());
1173 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwice) {
1175 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1176 GURL url("http://www.myexample.com");
1177 DummyPrerenderContents* prerender_contents =
1178 prerender_manager()->CreateNextPrerenderContents(
1179 url, FINAL_STATUS_CANCELLED);
1181 EXPECT_TRUE(AddSimplePrerender(url));
1183 const int first_prerender_id = last_prerender_id();
1184 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1185 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1186 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1187 EXPECT_TRUE(AddSimplePrerender(url));
1189 const int second_prerender_id = last_prerender_id();
1190 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1191 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1192 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1193 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1194 first_prerender_id);
1196 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1197 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1198 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1199 second_prerender_id);
1201 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1202 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1203 DummyPrerenderContents* null = NULL;
1204 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1207 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) {
1209 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1210 GURL url("http://www.myexample.com");
1211 DummyPrerenderContents* prerender_contents =
1212 prerender_manager()->CreateNextPrerenderContents(
1213 url, FINAL_STATUS_CANCELLED);
1215 EXPECT_TRUE(AddSimplePrerender(url));
1217 const int first_prerender_id = last_prerender_id();
1218 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1219 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1220 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1221 EXPECT_TRUE(AddSimplePrerender(url));
1223 const int second_prerender_id = last_prerender_id();
1224 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1225 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1226 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1227 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1228 first_prerender_id);
1230 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1231 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1232 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1233 second_prerender_id);
1235 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1236 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1237 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1238 first_prerender_id);
1240 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1241 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1242 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1243 second_prerender_id);
1245 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1246 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1247 DummyPrerenderContents* null = NULL;
1248 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1251 // TODO(gavinp): Update this test after abandon has an effect on Prerenders,
1252 // like shortening the timeouts.
1253 TEST_F(PrerenderTest, LinkManagerAddTwiceAbandonTwiceUseTwice) {
1255 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1256 GURL url("http://www.myexample.com");
1257 DummyPrerenderContents* prerender_contents =
1258 prerender_manager()->CreateNextPrerenderContents(
1259 url, FINAL_STATUS_USED);
1261 EXPECT_TRUE(AddSimplePrerender(url));
1263 const int first_prerender_id = last_prerender_id();
1264 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1265 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1266 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1267 EXPECT_TRUE(AddSimplePrerender(url));
1269 const int second_prerender_id = last_prerender_id();
1270 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1271 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1272 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1273 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1274 first_prerender_id);
1276 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1277 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1278 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1279 second_prerender_id);
1281 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1282 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1283 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1286 // TODO(gavinp): After abandon shortens the expire time on a Prerender,
1287 // add a series of tests testing advancing the time by either the abandon
1288 // or normal expire, and verifying the expected behaviour with groups
1290 TEST_F(PrerenderTest, LinkManagerExpireThenCancel) {
1291 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1292 GURL url("http://www.myexample.com");
1293 DummyPrerenderContents* prerender_contents =
1294 prerender_manager()->CreateNextPrerenderContents(
1295 url, FINAL_STATUS_TIMED_OUT);
1297 EXPECT_TRUE(AddSimplePrerender(url));
1299 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1300 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1301 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1302 prerender_manager()->AdvanceTimeTicks(
1303 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1305 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1306 DummyPrerenderContents* null = NULL;
1307 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1308 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1309 last_prerender_id());
1311 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1312 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1315 TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) {
1316 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1317 GURL url("http://www.myexample.com");
1318 DummyPrerenderContents* first_prerender_contents =
1319 prerender_manager()->CreateNextPrerenderContents(
1320 url, FINAL_STATUS_TIMED_OUT);
1321 EXPECT_TRUE(AddSimplePrerender(url));
1322 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1323 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1324 ASSERT_EQ(first_prerender_contents,
1325 prerender_manager()->FindEntry(url));
1326 prerender_manager()->AdvanceTimeTicks(
1327 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1328 DummyPrerenderContents* null = NULL;
1329 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1330 DummyPrerenderContents* second_prerender_contents =
1331 prerender_manager()->CreateNextPrerenderContents(
1332 url, FINAL_STATUS_USED);
1333 EXPECT_TRUE(AddSimplePrerender(url));
1334 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1335 ASSERT_EQ(second_prerender_contents,
1336 prerender_manager()->FindAndUseEntry(url));
1339 TEST_F(PrerenderTest, LinkManagerCancelThenAddAgain) {
1340 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1341 GURL url("http://www.myexample.com");
1342 DummyPrerenderContents* first_prerender_contents =
1343 prerender_manager()->CreateNextPrerenderContents(
1344 url, FINAL_STATUS_CANCELLED);
1345 EXPECT_TRUE(AddSimplePrerender(url));
1346 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1347 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1348 ASSERT_EQ(first_prerender_contents, prerender_manager()->FindEntry(url));
1349 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1350 last_prerender_id());
1351 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1352 EXPECT_TRUE(first_prerender_contents->prerendering_has_been_cancelled());
1353 DummyPrerenderContents* null = NULL;
1354 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1355 DummyPrerenderContents* second_prerender_contents =
1356 prerender_manager()->CreateNextPrerenderContents(
1357 url, FINAL_STATUS_USED);
1358 EXPECT_TRUE(AddSimplePrerender(url));
1359 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1360 ASSERT_EQ(second_prerender_contents,
1361 prerender_manager()->FindAndUseEntry(url));
1364 TEST_F(PrerenderTest, LinkManagerChannelClosing) {
1365 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1366 GURL url("http://www.myexample.com");
1367 DummyPrerenderContents* prerender_contents =
1368 prerender_manager()->CreateNextPrerenderContents(
1369 url, FINAL_STATUS_TIMED_OUT);
1371 EXPECT_TRUE(AddSimplePrerender(url));
1372 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1373 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1374 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1376 prerender_link_manager()->OnChannelClosing(kDefaultChildId);
1378 prerender_manager()->AdvanceTimeTicks(
1379 prerender_manager()->config().abandon_time_to_live +
1380 TimeDelta::FromSeconds(1));
1382 DummyPrerenderContents* null = NULL;
1383 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1384 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1387 // Creates two prerenders, one of which should be blocked by the
1388 // max_link_concurrency; abandons both of them and waits to make sure both
1389 // are cleared from the PrerenderLinkManager.
1390 TEST_F(PrerenderTest, LinkManagerAbandonInactivePrerender) {
1392 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1393 prerender_manager()->config().time_to_live);
1394 GURL first_url("http://www.myexample.com");
1395 DummyPrerenderContents* prerender_contents =
1396 prerender_manager()->CreateNextPrerenderContents(
1397 first_url, FINAL_STATUS_TIMED_OUT);
1398 EXPECT_TRUE(AddSimplePrerender(first_url));
1399 const int first_prerender_id = last_prerender_id();
1401 GURL second_url("http://www.neverlaunched.com");
1402 EXPECT_FALSE(AddSimplePrerender(second_url));
1403 const int second_prerender_id = last_prerender_id();
1405 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1407 DummyPrerenderContents* null = NULL;
1408 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1409 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1411 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1412 first_prerender_id);
1413 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1414 second_prerender_id);
1416 prerender_manager()->AdvanceTimeTicks(
1417 prerender_manager()->config().abandon_time_to_live +
1418 TimeDelta::FromSeconds(1));
1419 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1420 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1421 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1424 // Creates two prerenders, the second one started by the first, both of which
1425 // should be blocked by max_concurrency; abandons both of them and waits to make
1426 // sure both are cleared from the PrerenderLinkManager.
1427 TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) {
1429 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1430 prerender_manager()->config().time_to_live);
1431 GURL first_url("http://www.myexample.com");
1432 DummyPrerenderContents* prerender_contents =
1433 prerender_manager()->CreateNextPrerenderContents(
1434 first_url, FINAL_STATUS_TIMED_OUT);
1435 EXPECT_TRUE(AddSimplePrerender(first_url));
1436 const int first_prerender_id = last_prerender_id();
1440 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
1441 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
1443 GURL pending_url("http://www.neverlaunched.com");
1444 prerender_link_manager()->OnAddPrerender(
1445 child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
1446 content::Referrer(), kSize, route_id);
1447 const int second_prerender_id = last_prerender_id();
1449 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1451 DummyPrerenderContents* null = NULL;
1452 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1453 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1455 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1456 first_prerender_id);
1457 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1458 second_prerender_id);
1460 prerender_manager()->AdvanceTimeTicks(
1461 prerender_manager()->config().abandon_time_to_live +
1462 TimeDelta::FromSeconds(1));
1463 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1464 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1465 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1468 // Creates two prerenders, one of which should be blocked by the
1469 // max_link_concurrency; uses one after the max wait to launch, and
1470 // ensures the second prerender does not start.
1471 TEST_F(PrerenderTest, LinkManagerWaitToLaunchNotLaunched) {
1473 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1474 prerender_manager()->config().time_to_live);
1475 GURL first_url("http://www.myexample.com");
1476 DummyPrerenderContents* prerender_contents =
1477 prerender_manager()->CreateNextPrerenderContents(
1478 first_url, FINAL_STATUS_USED);
1479 EXPECT_TRUE(AddSimplePrerender(first_url));
1481 GURL second_url("http://www.neverlaunched.com");
1482 EXPECT_FALSE(AddSimplePrerender(second_url));
1484 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1486 DummyPrerenderContents* null = NULL;
1487 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1488 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1490 prerender_manager()->AdvanceTimeTicks(
1491 prerender_manager()->config().max_wait_to_launch +
1492 TimeDelta::FromSeconds(1));
1493 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1494 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1496 EXPECT_EQ(prerender_contents,
1497 prerender_manager()->FindAndUseEntry(first_url));
1499 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1500 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1501 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1504 // Creates two prerenders, one of which should start when the first one expires.
1505 TEST_F(PrerenderTest, LinkManagerExpireRevealingLaunch) {
1507 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1508 prerender_manager()->config().time_to_live);
1510 GURL first_url("http://www.willexpire.com");
1511 DummyPrerenderContents* first_prerender_contents =
1512 prerender_manager()->CreateNextPrerenderContents(
1513 first_url, FINAL_STATUS_TIMED_OUT);
1514 EXPECT_TRUE(AddSimplePrerender(first_url));
1515 EXPECT_EQ(first_prerender_contents,
1516 prerender_manager()->FindEntry(first_url));
1518 // Insert the second prerender so it will be still be launchable when the
1520 const TimeDelta wait_to_launch_second_prerender =
1521 prerender_manager()->config().time_to_live -
1522 prerender_manager()->config().max_wait_to_launch +
1523 TimeDelta::FromSeconds(2);
1524 const TimeDelta wait_for_first_prerender_to_expire =
1525 prerender_manager()->config().time_to_live -
1526 wait_to_launch_second_prerender +
1527 TimeDelta::FromSeconds(1);
1528 ASSERT_LT(prerender_manager()->config().time_to_live,
1529 wait_to_launch_second_prerender +
1530 wait_for_first_prerender_to_expire);
1531 ASSERT_GT(prerender_manager()->config().max_wait_to_launch.InSeconds(),
1532 wait_for_first_prerender_to_expire.InSeconds());
1534 prerender_manager()->AdvanceTimeTicks(wait_to_launch_second_prerender);
1535 GURL second_url("http://www.willlaunch.com");
1536 DummyPrerenderContents* second_prerender_contents =
1537 prerender_manager()->CreateNextPrerenderContents(
1538 second_url, FINAL_STATUS_USED);
1539 EXPECT_FALSE(AddSimplePrerender(second_url));
1541 // The first prerender is still running, but the second has not yet launched.
1542 EXPECT_EQ(first_prerender_contents,
1543 prerender_manager()->FindEntry(first_url));
1544 PrerenderContents* null = NULL;
1545 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1547 // The first prerender should have died, giving life to the second one.
1548 prerender_manager()->AdvanceTimeTicks(wait_for_first_prerender_to_expire);
1549 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1550 EXPECT_EQ(second_prerender_contents,
1551 prerender_manager()->FindAndUseEntry(second_url));
1554 TEST_F(PrerenderTest, InstantSearchNotAllowedWhenDisabled) {
1555 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1557 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1"));
1559 EXPECT_FALSE(prerender_manager()->AddPrerenderForInstant(
1560 GURL("http://www.example.com/instant_search"), NULL, gfx::Size()));
1563 TEST_F(PrerenderTest, PrerenderContentsForInstantSearch) {
1564 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
1566 "Group82 espv:8 use_cacheable_ntp:1 prefetch_results:1"));
1567 GURL url("http://www.example.com/instant_search");
1568 DummyPrerenderContents* prerender_contents =
1569 prerender_manager()->CreateNextPrerenderContents(url, ORIGIN_INSTANT,
1571 scoped_ptr<PrerenderHandle> prerender_handle(
1572 prerender_manager()->AddPrerenderForInstant(url, NULL, kSize));
1573 CHECK(prerender_handle.get());
1574 EXPECT_TRUE(prerender_handle->IsPrerendering());
1575 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1576 EXPECT_EQ(prerender_contents, prerender_handle->contents());
1577 EXPECT_EQ(ORIGIN_INSTANT, prerender_handle->contents()->origin());
1578 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1579 EXPECT_FALSE(prerender_handle->IsPrerendering());
1582 } // namespace prerender