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.
5 #include "base/command_line.h"
6 #include "base/format_macros.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/time/time.h"
11 #include "chrome/browser/prerender/prerender_contents.h"
12 #include "chrome/browser/prerender/prerender_handle.h"
13 #include "chrome/browser/prerender/prerender_link_manager.h"
14 #include "chrome/browser/prerender/prerender_manager.h"
15 #include "chrome/browser/prerender/prerender_origin.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/test/base/testing_browser_process.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/gfx/size.h"
26 using base::TimeDelta;
27 using base::TimeTicks;
28 using content::BrowserThread;
29 using content::Referrer;
33 class UnitTestPrerenderManager;
37 class DummyPrerenderContents : public PrerenderContents {
39 DummyPrerenderContents(UnitTestPrerenderManager* test_prerender_manager,
40 PrerenderTracker* prerender_tracker,
43 FinalStatus expected_final_status);
45 virtual ~DummyPrerenderContents() {
46 EXPECT_EQ(expected_final_status_, final_status());
49 virtual void StartPrerendering(
50 int ALLOW_UNUSED creator_child_id,
51 const gfx::Size& ALLOW_UNUSED size,
52 content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace)
55 virtual bool GetChildId(int* child_id) const OVERRIDE {
56 // Having a default child_id of -1 forces pending prerenders not to fail
57 // on session storage and cross domain checking.
62 virtual bool GetRouteId(int* route_id) const OVERRIDE {
63 *route_id = route_id_;
67 FinalStatus expected_final_status() const { return expected_final_status_; }
69 bool prerendering_has_been_cancelled() const {
70 return PrerenderContents::prerendering_has_been_cancelled();
74 static int g_next_route_id_;
77 UnitTestPrerenderManager* test_prerender_manager_;
78 FinalStatus expected_final_status_;
81 int DummyPrerenderContents::g_next_route_id_ = 0;
83 const gfx::Size kSize(640, 480);
87 class UnitTestPrerenderManager : public PrerenderManager {
89 using PrerenderManager::kMinTimeBetweenPrerendersMs;
90 using PrerenderManager::kNavigationRecordWindowMs;
92 explicit UnitTestPrerenderManager(Profile* profile,
93 PrerenderTracker* prerender_tracker)
94 : PrerenderManager(profile, prerender_tracker),
96 time_ticks_(TimeTicks::Now()),
97 prerender_tracker_(prerender_tracker) {
98 set_rate_limit_enabled(false);
101 virtual ~UnitTestPrerenderManager() {
104 // From BrowserContextKeyedService, via PrererenderManager:
105 virtual void Shutdown() OVERRIDE {
106 if (next_prerender_contents())
107 next_prerender_contents_->Destroy(FINAL_STATUS_MANAGER_SHUTDOWN);
108 PrerenderManager::Shutdown();
111 // From PrerenderManager:
112 virtual void MoveEntryToPendingDelete(PrerenderContents* entry,
113 FinalStatus final_status) OVERRIDE {
114 if (entry == next_prerender_contents_.get())
116 PrerenderManager::MoveEntryToPendingDelete(entry, final_status);
119 PrerenderContents* FindEntry(const GURL& url) {
121 to_delete_prerenders_.clear();
122 if (PrerenderData* data = FindPrerenderData(url, NULL))
123 return data->contents();
127 PrerenderContents* FindAndUseEntry(const GURL& url) {
128 PrerenderData* prerender_data = FindPrerenderData(url, NULL);
131 ScopedVector<PrerenderData>::iterator to_erase =
132 FindIteratorForPrerenderContents(prerender_data->contents());
133 CHECK(to_erase != active_prerenders_.end());
134 PrerenderContents* prerender_contents = prerender_data->ReleaseContents();
135 active_prerenders_.erase(to_erase);
137 prerender_contents->SetFinalStatus(FINAL_STATUS_USED);
138 prerender_contents->PrepareForUse();
139 return prerender_contents;
142 void AdvanceTime(TimeDelta delta) {
146 void AdvanceTimeTicks(TimeDelta delta) {
147 time_ticks_ += delta;
150 DummyPrerenderContents* CreateNextPrerenderContents(
152 FinalStatus expected_final_status) {
153 DummyPrerenderContents* prerender_contents =
154 new DummyPrerenderContents(this, prerender_tracker_, url,
155 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
156 expected_final_status);
157 SetNextPrerenderContents(prerender_contents);
158 return prerender_contents;
161 DummyPrerenderContents* CreateNextPrerenderContents(
164 FinalStatus expected_final_status) {
165 DummyPrerenderContents* prerender_contents =
166 new DummyPrerenderContents(this, prerender_tracker_, url,
167 origin, expected_final_status);
168 SetNextPrerenderContents(prerender_contents);
169 return prerender_contents;
172 DummyPrerenderContents* CreateNextPrerenderContents(
174 const std::vector<GURL>& alias_urls,
175 FinalStatus expected_final_status) {
176 DummyPrerenderContents* prerender_contents =
177 new DummyPrerenderContents(this, prerender_tracker_, url,
178 ORIGIN_LINK_REL_PRERENDER_CROSSDOMAIN,
179 expected_final_status);
180 for (std::vector<GURL>::const_iterator it = alias_urls.begin();
181 it != alias_urls.end();
183 EXPECT_TRUE(prerender_contents->AddAliasURL(*it));
185 SetNextPrerenderContents(prerender_contents);
186 return prerender_contents;
189 void set_rate_limit_enabled(bool enabled) {
190 mutable_config().rate_limit_enabled = enabled;
193 PrerenderContents* next_prerender_contents() {
194 return next_prerender_contents_.get();
197 // from PrerenderManager
198 virtual Time GetCurrentTime() const OVERRIDE {
202 virtual TimeTicks GetCurrentTimeTicks() const OVERRIDE {
207 void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
208 CHECK(!next_prerender_contents_.get());
209 next_prerender_contents_.reset(prerender_contents);
210 if (prerender_contents->expected_final_status() == FINAL_STATUS_USED)
211 used_prerender_contents_.push_back(prerender_contents);
215 virtual PrerenderContents* CreatePrerenderContents(
217 const Referrer& referrer,
219 uint8 experiment_id) OVERRIDE {
220 CHECK(next_prerender_contents_.get());
221 EXPECT_EQ(url, next_prerender_contents_->prerender_url());
222 EXPECT_EQ(origin, next_prerender_contents_->origin());
223 return next_prerender_contents_.release();
227 TimeTicks time_ticks_;
228 scoped_ptr<PrerenderContents> next_prerender_contents_;
229 // PrerenderContents with an |expected_final_status| of FINAL_STATUS_USED,
230 // tracked so they will be automatically deleted.
231 ScopedVector<PrerenderContents> used_prerender_contents_;
233 PrerenderTracker* prerender_tracker_;
236 class RestorePrerenderMode {
238 RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
241 ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
243 PrerenderManager::PrerenderManagerMode prev_mode_;
246 DummyPrerenderContents::DummyPrerenderContents(
247 UnitTestPrerenderManager* test_prerender_manager,
248 PrerenderTracker* prerender_tracker,
251 FinalStatus expected_final_status)
252 : PrerenderContents(test_prerender_manager,
253 NULL, url, Referrer(), origin,
254 PrerenderManager::kNoExperiment),
255 route_id_(g_next_route_id_++),
256 test_prerender_manager_(test_prerender_manager),
257 expected_final_status_(expected_final_status) {
260 void DummyPrerenderContents::StartPrerendering(
261 int ALLOW_UNUSED creator_child_id,
262 const gfx::Size& ALLOW_UNUSED size,
263 content::SessionStorageNamespace* ALLOW_UNUSED session_storage_namespace) {
264 // In the base PrerenderContents implementation, StartPrerendering will
265 // be called even when the PrerenderManager is part of the control group,
266 // but it will early exit before actually creating a new RenderView if
267 // |is_control_group| is true;
268 load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
269 if (!test_prerender_manager_->IsControlGroup(experiment_id())) {
270 prerendering_has_started_ = true;
271 NotifyPrerenderStart();
275 class PrerenderTest : public testing::Test {
277 static const int kDefaultChildId = -1;
278 static const int kDefaultRenderViewRouteId = -1;
280 PrerenderTest() : ui_thread_(BrowserThread::UI, &message_loop_),
281 prerender_manager_(new UnitTestPrerenderManager(
282 &profile_, prerender_tracker())),
283 prerender_link_manager_(
284 new PrerenderLinkManager(prerender_manager_.get())),
285 last_prerender_id_(0) {
286 // Enable omnibox prerendering.
287 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
288 switches::kPrerenderFromOmnibox,
289 switches::kPrerenderFromOmniboxSwitchValueEnabled);
292 virtual ~PrerenderTest() {
293 prerender_link_manager_->OnChannelClosing(kDefaultChildId);
294 prerender_link_manager_->Shutdown();
295 prerender_manager_->Shutdown();
298 UnitTestPrerenderManager* prerender_manager() {
299 return prerender_manager_.get();
302 PrerenderLinkManager* prerender_link_manager() {
303 return prerender_link_manager_.get();
306 void SetConcurrency(size_t concurrency) {
307 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
309 prerender_manager()->mutable_config().max_link_concurrency =
310 std::max(prerender_manager()->mutable_config().max_link_concurrency,
314 bool IsEmptyPrerenderLinkManager() const {
315 return prerender_link_manager_->IsEmpty();
318 int last_prerender_id() const {
319 return last_prerender_id_;
322 int GetNextPrerenderID() {
323 return ++last_prerender_id_;
326 bool LauncherHasRunningPrerender(int child_id, int prerender_id) {
327 PrerenderLinkManager::LinkPrerender* prerender =
328 prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
329 child_id, prerender_id);
330 return prerender && prerender->handle;
333 // Shorthand to add a simple prerender with a reasonable source. Returns
334 // true iff the prerender has been added to the PrerenderManager by the
335 // PrerenderLinkManager and the PrerenderManager returned a handle.
336 bool AddSimplePrerender(const GURL& url) {
337 prerender_link_manager()->OnAddPrerender(kDefaultChildId,
338 GetNextPrerenderID(),
339 url, content::Referrer(),
340 kSize, kDefaultRenderViewRouteId);
341 return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id());
345 PrerenderTracker* prerender_tracker() {
346 return g_browser_process->prerender_tracker();
349 // Needed to pass PrerenderManager's DCHECKs.
350 TestingProfile profile_;
351 base::MessageLoop message_loop_;
352 content::TestBrowserThread ui_thread_;
353 scoped_ptr<UnitTestPrerenderManager> prerender_manager_;
354 scoped_ptr<PrerenderLinkManager> prerender_link_manager_;
355 int last_prerender_id_;
358 TEST_F(PrerenderTest, FoundTest) {
359 GURL url("http://www.google.com/");
360 DummyPrerenderContents* prerender_contents =
361 prerender_manager()->CreateNextPrerenderContents(
364 EXPECT_TRUE(AddSimplePrerender(url));
365 EXPECT_TRUE(prerender_contents->prerendering_has_started());
366 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
369 // Make sure that if queue a request, and a second prerender request for the
370 // same URL comes in, that the second request attaches to the first prerender,
371 // and we don't use the second prerender contents.
372 TEST_F(PrerenderTest, DuplicateTest) {
374 GURL url("http://www.google.com/");
375 DummyPrerenderContents* prerender_contents =
376 prerender_manager()->CreateNextPrerenderContents(
379 DummyPrerenderContents* null = NULL;
380 EXPECT_TRUE(AddSimplePrerender(url));
381 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
382 EXPECT_TRUE(prerender_contents->prerendering_has_started());
384 DummyPrerenderContents* prerender_contents1 =
385 prerender_manager()->CreateNextPrerenderContents(
387 FINAL_STATUS_MANAGER_SHUTDOWN);
388 EXPECT_TRUE(AddSimplePrerender(url));
389 EXPECT_EQ(prerender_contents1,
390 prerender_manager()->next_prerender_contents());
391 EXPECT_FALSE(prerender_contents1->prerendering_has_started());
393 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
396 // Ensure that we expire a prerendered page after the max. permitted time.
397 TEST_F(PrerenderTest, ExpireTest) {
398 GURL url("http://www.google.com/");
399 DummyPrerenderContents* prerender_contents =
400 prerender_manager()->CreateNextPrerenderContents(
402 FINAL_STATUS_TIMED_OUT);
403 DummyPrerenderContents* null = NULL;
404 EXPECT_TRUE(AddSimplePrerender(url));
405 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
406 EXPECT_TRUE(prerender_contents->prerendering_has_started());
407 prerender_manager()->AdvanceTimeTicks(
408 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
409 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
412 // Ensure that we don't launch prerenders of bad urls (in this case, a mailto:
414 TEST_F(PrerenderTest, BadURLTest) {
415 GURL url("mailto:test@gmail.com");
416 DummyPrerenderContents* prerender_contents =
417 prerender_manager()->CreateNextPrerenderContents(
419 FINAL_STATUS_UNSUPPORTED_SCHEME);
420 EXPECT_FALSE(AddSimplePrerender(url));
421 EXPECT_FALSE(prerender_contents->prerendering_has_started());
422 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
423 DummyPrerenderContents* null = NULL;
424 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
427 // When the user navigates away from a page, the prerenders it launched should
428 // have their time to expiry shortened from the default time to live.
429 TEST_F(PrerenderTest, LinkManagerNavigateAwayExpire) {
430 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
431 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
432 const TimeDelta test_advance = TimeDelta::FromSeconds(22);
433 ASSERT_LT(test_advance, time_to_live);
434 ASSERT_LT(abandon_time_to_live, test_advance);
436 prerender_manager()->mutable_config().time_to_live = time_to_live;
437 prerender_manager()->mutable_config().abandon_time_to_live =
438 abandon_time_to_live;
440 GURL url("http://example.com");
441 DummyPrerenderContents* prerender_contents =
442 prerender_manager()->CreateNextPrerenderContents(url,
443 FINAL_STATUS_TIMED_OUT);
444 EXPECT_TRUE(AddSimplePrerender(url));
445 EXPECT_TRUE(prerender_contents->prerendering_has_started());
446 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
447 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
448 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
449 last_prerender_id());
450 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
451 DummyPrerenderContents* null = NULL;
452 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
453 prerender_manager()->AdvanceTimeTicks(test_advance);
455 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
458 // But when we navigate away very close to the original expiry of a prerender,
459 // we shouldn't expect it to be extended.
460 TEST_F(PrerenderTest, LinkManagerNavigateAwayNearExpiry) {
461 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
462 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
464 // We will expect the prerender to still be alive after advancing the clock
465 // by first_advance. But, after second_advance, we expect it to have timed
466 // out, demonstrating that you can't extend a prerender by navigating away
467 // from its launcher.
468 const TimeDelta first_advance = TimeDelta::FromSeconds(298);
469 const TimeDelta second_advance = TimeDelta::FromSeconds(4);
470 ASSERT_LT(first_advance, time_to_live);
471 ASSERT_LT(time_to_live - first_advance, abandon_time_to_live);
472 ASSERT_LT(time_to_live, first_advance + second_advance);
474 prerender_manager()->mutable_config().time_to_live = time_to_live;
475 prerender_manager()->mutable_config().abandon_time_to_live =
476 abandon_time_to_live;
478 GURL url("http://example2.com");
479 DummyPrerenderContents* prerender_contents =
480 prerender_manager()->CreateNextPrerenderContents(url,
481 FINAL_STATUS_TIMED_OUT);
482 EXPECT_TRUE(AddSimplePrerender(url));
483 EXPECT_TRUE(prerender_contents->prerendering_has_started());
484 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
485 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
487 prerender_manager()->AdvanceTimeTicks(first_advance);
488 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
490 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
491 last_prerender_id());
492 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
494 DummyPrerenderContents* null = NULL;
495 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
497 prerender_manager()->AdvanceTimeTicks(second_advance);
498 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
501 // When the user navigates away from a page, and then launches a new prerender,
502 // the new prerender should preempt the abandoned prerender even if the
503 // abandoned prerender hasn't expired.
504 TEST_F(PrerenderTest, LinkManagerNavigateAwayLaunchAnother) {
505 const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
506 const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
507 const TimeDelta test_advance = TimeDelta::FromSeconds(5);
508 ASSERT_LT(test_advance, time_to_live);
509 ASSERT_GT(abandon_time_to_live, test_advance);
511 prerender_manager()->mutable_config().time_to_live = time_to_live;
512 prerender_manager()->mutable_config().abandon_time_to_live =
513 abandon_time_to_live;
515 GURL url("http://example.com");
516 prerender_manager()->CreateNextPrerenderContents(url, FINAL_STATUS_CANCELLED);
517 EXPECT_TRUE(AddSimplePrerender(url));
518 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
519 last_prerender_id());
521 prerender_manager()->AdvanceTimeTicks(test_advance);
523 GURL second_url("http://example2.com");
524 DummyPrerenderContents* second_prerender_contents =
525 prerender_manager()->CreateNextPrerenderContents(
526 second_url, FINAL_STATUS_MANAGER_SHUTDOWN);
527 EXPECT_TRUE(AddSimplePrerender(second_url));
528 EXPECT_EQ(second_prerender_contents,
529 prerender_manager()->FindEntry(second_url));
533 // Make sure that if we prerender more requests than we support, that we launch
534 // them in the order given up until we reach MaxConcurrency, at which point we
535 // queue them and launch them in the order given. As well, insure that limits
536 // are enforced for the system as a whole and on a per launcher basis.
537 TEST_F(PrerenderTest, MaxConcurrencyTest) {
538 struct TestConcurrency {
539 size_t max_link_concurrency;
540 size_t max_link_concurrency_per_launcher;
543 TestConcurrency concurrencies_to_test[] = {
544 { prerender_manager()->config().max_link_concurrency,
545 prerender_manager()->config().max_link_concurrency_per_launcher},
547 // With the system limit higher than the per launcher limit, the per
548 // launcher limit should be in effect.
551 // With the per launcher limit higher than system limit, the system limit
552 // should be in effect.
556 DummyPrerenderContents* null = NULL;
557 GURL url_to_delay("http://www.google.com/delayme");
559 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(concurrencies_to_test); ++i) {
560 prerender_manager()->mutable_config().max_link_concurrency =
561 concurrencies_to_test[i].max_link_concurrency;
562 prerender_manager()->mutable_config().max_link_concurrency_per_launcher =
563 concurrencies_to_test[i].max_link_concurrency_per_launcher;
565 const size_t effective_max_link_concurrency =
566 std::min(concurrencies_to_test[i].max_link_concurrency,
567 concurrencies_to_test[i].max_link_concurrency_per_launcher);
569 std::vector<GURL> urls;
570 std::vector<PrerenderContents*> prerender_contentses;
572 // Launch prerenders up to the maximum this launcher can support.
573 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
575 GURL(base::StringPrintf("http://google.com/use#%" PRIuS, j)));
576 prerender_contentses.push_back(
577 prerender_manager()->CreateNextPrerenderContents(urls.back(),
579 EXPECT_TRUE(AddSimplePrerender(urls.back()));
580 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
581 EXPECT_TRUE(prerender_contentses.back()->prerendering_has_started());
584 if (concurrencies_to_test[i].max_link_concurrency >
585 effective_max_link_concurrency) {
586 // We should be able to launch more prerenders on this system, but not for
587 // our current launcher.
590 ASSERT_TRUE(prerender_contentses.back()->GetChildId(&child_id));
591 ASSERT_TRUE(prerender_contentses.back()->GetRouteId(&route_id));
593 GURL extra_url("http://google.com/extraurl");
594 prerender_link_manager()->OnAddPrerender(child_id,
595 GetNextPrerenderID(),
596 extra_url, content::Referrer(),
598 const int prerender_id = last_prerender_id();
599 EXPECT_TRUE(LauncherHasRunningPrerender(child_id, prerender_id));
600 prerender_link_manager()->OnCancelPrerender(child_id, prerender_id);
601 EXPECT_FALSE(LauncherHasRunningPrerender(child_id, prerender_id));
604 DummyPrerenderContents* prerender_contents_to_delay =
605 prerender_manager()->CreateNextPrerenderContents(url_to_delay,
607 EXPECT_FALSE(AddSimplePrerender(url_to_delay));
608 EXPECT_FALSE(prerender_contents_to_delay->prerendering_has_started());
609 EXPECT_NE(null, prerender_manager()->next_prerender_contents());
610 EXPECT_EQ(null, prerender_manager()->FindEntry(url_to_delay));
611 for (size_t j = 0; j < effective_max_link_concurrency; ++j) {
612 EXPECT_EQ(prerender_contentses[j],
613 prerender_manager()->FindAndUseEntry(urls[j]));
614 EXPECT_TRUE(prerender_contents_to_delay->prerendering_has_started());
617 EXPECT_EQ(prerender_contents_to_delay,
618 prerender_manager()->FindAndUseEntry(url_to_delay));
619 EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
623 TEST_F(PrerenderTest, AliasURLTest) {
626 GURL url("http://www.google.com/");
627 GURL alias_url1("http://www.google.com/index.html");
628 GURL alias_url2("http://google.com/");
629 GURL not_an_alias_url("http://google.com/index.html");
630 std::vector<GURL> alias_urls;
631 alias_urls.push_back(alias_url1);
632 alias_urls.push_back(alias_url2);
634 // Test that all of the aliases work, but not_an_alias_url does not.
635 DummyPrerenderContents* prerender_contents =
636 prerender_manager()->CreateNextPrerenderContents(
637 url, alias_urls, FINAL_STATUS_USED);
638 EXPECT_TRUE(AddSimplePrerender(url));
639 ASSERT_EQ(NULL, prerender_manager()->FindEntry(not_an_alias_url));
640 ASSERT_EQ(prerender_contents,
641 prerender_manager()->FindAndUseEntry(alias_url1));
642 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
643 url, alias_urls, FINAL_STATUS_USED);
644 EXPECT_TRUE(AddSimplePrerender(url));
645 ASSERT_EQ(prerender_contents,
646 prerender_manager()->FindAndUseEntry(alias_url2));
647 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
648 url, alias_urls, FINAL_STATUS_USED);
649 EXPECT_TRUE(AddSimplePrerender(url));
650 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
652 // Test that alias URLs can not be added.
653 prerender_contents = prerender_manager()->CreateNextPrerenderContents(
654 url, alias_urls, FINAL_STATUS_USED);
655 EXPECT_TRUE(AddSimplePrerender(url));
656 EXPECT_TRUE(AddSimplePrerender(url));
657 EXPECT_TRUE(AddSimplePrerender(alias_url1));
658 EXPECT_TRUE(AddSimplePrerender(alias_url2));
659 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
662 TEST_F(PrerenderTest, PendingPrerenderTest) {
663 GURL url("http://www.google.com/");
664 DummyPrerenderContents* prerender_contents =
665 prerender_manager()->CreateNextPrerenderContents(
668 EXPECT_TRUE(AddSimplePrerender(url));
672 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
673 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
675 GURL pending_url("http://news.google.com/");
677 DummyPrerenderContents* pending_prerender_contents =
678 prerender_manager()->CreateNextPrerenderContents(
680 ORIGIN_GWS_PRERENDER,
682 scoped_ptr<PrerenderHandle> pending_prerender_handle(
683 prerender_manager()->AddPrerenderFromLinkRelPrerender(
684 child_id, route_id, pending_url,
685 Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
686 CHECK(pending_prerender_handle.get());
687 EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
689 EXPECT_TRUE(prerender_contents->prerendering_has_started());
690 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
692 EXPECT_TRUE(pending_prerender_handle->IsPrerendering());
693 ASSERT_EQ(pending_prerender_contents,
694 prerender_manager()->FindAndUseEntry(pending_url));
695 EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
698 TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
699 GURL url("http://www.google.com/");
700 DummyPrerenderContents* prerender_contents =
701 prerender_manager()->CreateNextPrerenderContents(
704 EXPECT_TRUE(AddSimplePrerender(url));
708 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
709 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
711 // This pending URL has an unsupported scheme, and won't be able
713 GURL pending_url("ftp://news.google.com/");
715 prerender_manager()->CreateNextPrerenderContents(
717 ORIGIN_GWS_PRERENDER,
718 FINAL_STATUS_UNSUPPORTED_SCHEME);
719 scoped_ptr<PrerenderHandle> pending_prerender_handle(
720 prerender_manager()->AddPrerenderFromLinkRelPrerender(
721 child_id, route_id, pending_url,
722 Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
723 DCHECK(pending_prerender_handle.get());
724 EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
726 EXPECT_TRUE(prerender_contents->prerendering_has_started());
727 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
729 EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
732 TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
733 GURL url("http://www.google.com/");
734 DummyPrerenderContents* prerender_contents =
735 prerender_manager()->CreateNextPrerenderContents(
738 EXPECT_TRUE(AddSimplePrerender(url));
742 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
743 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
745 GURL pending_url("http://news.google.com/");
747 scoped_ptr<PrerenderHandle> pending_prerender_handle(
748 prerender_manager()->AddPrerenderFromLinkRelPrerender(
749 child_id, route_id, pending_url,
750 Referrer(url, WebKit::WebReferrerPolicyDefault), kSize));
751 CHECK(pending_prerender_handle.get());
752 EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
754 EXPECT_TRUE(prerender_contents->prerendering_has_started());
756 pending_prerender_handle.reset();
758 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
761 // Tests that a PrerenderManager created for a browser session in the control
762 // group works as expected.
763 TEST_F(PrerenderTest, ControlGroup) {
764 RestorePrerenderMode restore_prerender_mode;
765 PrerenderManager::SetMode(
766 PrerenderManager::PRERENDER_MODE_EXPERIMENT_CONTROL_GROUP);
767 GURL url("http://www.google.com/");
768 DummyPrerenderContents* prerender_contents =
769 prerender_manager()->CreateNextPrerenderContents(
771 FINAL_STATUS_MANAGER_SHUTDOWN);
772 EXPECT_TRUE(AddSimplePrerender(url));
773 EXPECT_FALSE(prerender_contents->prerendering_has_started());
776 // Tests that prerendering is cancelled when the source render view does not
777 // exist. On failure, the DCHECK in CreatePrerenderContents() above should be
779 TEST_F(PrerenderTest, SourceRenderViewClosed) {
780 GURL url("http://www.google.com/");
781 prerender_manager()->CreateNextPrerenderContents(
783 FINAL_STATUS_MANAGER_SHUTDOWN);
784 prerender_link_manager()->OnAddPrerender(100, GetNextPrerenderID(), url,
785 Referrer(), kSize, 200);
786 EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id()));
789 // Tests that prerendering is cancelled when we launch a second prerender of
790 // the same target within a short time interval.
791 TEST_F(PrerenderTest, RecentlyVisited) {
792 GURL url("http://www.google.com/");
794 prerender_manager()->RecordNavigation(url);
796 DummyPrerenderContents* prerender_contents =
797 prerender_manager()->CreateNextPrerenderContents(
798 url, FINAL_STATUS_RECENTLY_VISITED);
799 EXPECT_FALSE(AddSimplePrerender(url));
800 EXPECT_FALSE(prerender_contents->prerendering_has_started());
803 TEST_F(PrerenderTest, NotSoRecentlyVisited) {
804 GURL url("http://www.google.com/");
806 prerender_manager()->RecordNavigation(url);
807 prerender_manager()->AdvanceTimeTicks(
808 TimeDelta::FromMilliseconds(
809 UnitTestPrerenderManager::kNavigationRecordWindowMs + 500));
811 DummyPrerenderContents* prerender_contents =
812 prerender_manager()->CreateNextPrerenderContents(
813 url, FINAL_STATUS_USED);
814 EXPECT_TRUE(AddSimplePrerender(url));
815 EXPECT_TRUE(prerender_contents->prerendering_has_started());
816 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
819 // Tests that our PPLT dummy prerender gets created properly.
820 TEST_F(PrerenderTest, PPLTDummy) {
821 GURL url("http://www.google.com/");
822 DummyPrerenderContents* prerender_contents =
823 prerender_manager()->CreateNextPrerenderContents(
824 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
825 EXPECT_TRUE(AddSimplePrerender(url));
826 EXPECT_TRUE(prerender_contents->prerendering_has_started());
827 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
829 DummyPrerenderContents* pplt_dummy_contents =
830 prerender_manager()->CreateNextPrerenderContents(url,
832 GURL ftp_url("ftp://ftp.google.com/");
833 // Adding this ftp URL will force the expected unsupported scheme error.
834 prerender_contents->AddAliasURL(ftp_url);
835 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
837 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
838 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
841 // Tests that our PPLT dummy prerender gets created properly, even
842 // when navigating to a page that has been recently navigated to.
843 TEST_F(PrerenderTest, RecentlyVisitedPPLTDummy) {
844 GURL url("http://www.google.com/");
845 DummyPrerenderContents* prerender_contents =
846 prerender_manager()->CreateNextPrerenderContents(
847 url, FINAL_STATUS_UNSUPPORTED_SCHEME);
848 EXPECT_TRUE(AddSimplePrerender(url));
849 EXPECT_TRUE(prerender_contents->prerendering_has_started());
851 DummyPrerenderContents* pplt_dummy_contents =
852 prerender_manager()->CreateNextPrerenderContents(url,
854 prerender_manager()->RecordNavigation(url);
855 GURL ftp_url("ftp://ftp.google.com/");
856 prerender_contents->AddAliasURL(ftp_url);
858 ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
861 TEST_F(PrerenderTest, PPLTLateCancel) {
862 GURL url("http://www.google.com");
863 DummyPrerenderContents* prerender_contents =
864 prerender_manager()->CreateNextPrerenderContents(
865 url, FINAL_STATUS_JAVASCRIPT_ALERT);
866 EXPECT_TRUE(AddSimplePrerender(url));
867 EXPECT_TRUE(prerender_contents->prerendering_has_started());
868 // Force the creation of a match complete dummy.
869 DummyPrerenderContents* duplicate_prerender_contents =
870 prerender_manager()->CreateNextPrerenderContents(url,
871 FINAL_STATUS_CANCELLED);
872 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
873 prerender_contents->Destroy(FINAL_STATUS_JAVASCRIPT_ALERT);
874 ASSERT_EQ(duplicate_prerender_contents, prerender_manager()->FindEntry(url));
876 // Make sure that events on prerender handles propogate to the match
877 // complete replacement.
878 DummyPrerenderContents* null = NULL;
879 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
880 last_prerender_id());
881 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
884 // Tests that the prerender manager matches include the fragment.
885 TEST_F(PrerenderTest, FragmentMatchesTest) {
886 GURL fragment_url("http://www.google.com/#test");
888 DummyPrerenderContents* prerender_contents =
889 prerender_manager()->CreateNextPrerenderContents(fragment_url,
891 EXPECT_TRUE(AddSimplePrerender(fragment_url));
892 EXPECT_TRUE(prerender_contents->prerendering_has_started());
893 ASSERT_EQ(prerender_contents,
894 prerender_manager()->FindAndUseEntry(fragment_url));
897 // Tests that the prerender manager uses fragment references when matching
898 // prerender URLs in the case a different fragment is in both URLs.
899 TEST_F(PrerenderTest, FragmentsDifferTest) {
900 GURL fragment_url("http://www.google.com/#test");
901 GURL other_fragment_url("http://www.google.com/#other_test");
903 DummyPrerenderContents* prerender_contents =
904 prerender_manager()->CreateNextPrerenderContents(fragment_url,
906 EXPECT_TRUE(AddSimplePrerender(fragment_url));
907 EXPECT_TRUE(prerender_contents->prerendering_has_started());
909 DummyPrerenderContents* null = NULL;
910 ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url));
912 ASSERT_EQ(prerender_contents,
913 prerender_manager()->FindAndUseEntry(fragment_url));
916 // Make sure that clearing works as expected.
917 TEST_F(PrerenderTest, ClearTest) {
918 GURL url("http://www.google.com/");
919 DummyPrerenderContents* prerender_contents =
920 prerender_manager()->CreateNextPrerenderContents(
922 FINAL_STATUS_CACHE_OR_HISTORY_CLEARED);
923 EXPECT_TRUE(AddSimplePrerender(url));
924 EXPECT_TRUE(prerender_contents->prerendering_has_started());
925 prerender_manager()->ClearData(PrerenderManager::CLEAR_PRERENDER_CONTENTS);
926 DummyPrerenderContents* null = NULL;
927 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
930 // Make sure canceling works as expected.
931 TEST_F(PrerenderTest, CancelAllTest) {
932 GURL url("http://www.google.com/");
933 DummyPrerenderContents* prerender_contents =
934 prerender_manager()->CreateNextPrerenderContents(
935 url, FINAL_STATUS_CANCELLED);
936 EXPECT_TRUE(AddSimplePrerender(url));
937 EXPECT_TRUE(prerender_contents->prerendering_has_started());
938 prerender_manager()->CancelAllPrerenders();
939 const DummyPrerenderContents* null = NULL;
940 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
943 TEST_F(PrerenderTest, OmniboxNotAllowedWhenDisabled) {
944 prerender_manager()->set_enabled(false);
945 EXPECT_FALSE(prerender_manager()->AddPrerenderFromOmnibox(
946 GURL("http://www.example.com"), NULL, gfx::Size()));
949 TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) {
950 prerender_manager()->set_enabled(false);
951 EXPECT_FALSE(AddSimplePrerender(
952 GURL("http://www.example.com")));
955 TEST_F(PrerenderTest, LinkManagerCancel) {
956 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
957 GURL url("http://www.myexample.com");
958 DummyPrerenderContents* prerender_contents =
959 prerender_manager()->CreateNextPrerenderContents(
960 url, FINAL_STATUS_CANCELLED);
962 EXPECT_TRUE(AddSimplePrerender(url));
964 EXPECT_TRUE(prerender_contents->prerendering_has_started());
965 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
966 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
967 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
968 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
969 last_prerender_id());
971 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
972 DummyPrerenderContents* null = NULL;
973 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
974 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
977 TEST_F(PrerenderTest, LinkManagerCancelThenAbandon) {
978 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
979 GURL url("http://www.myexample.com");
980 DummyPrerenderContents* prerender_contents =
981 prerender_manager()->CreateNextPrerenderContents(
982 url, FINAL_STATUS_CANCELLED);
984 EXPECT_TRUE(AddSimplePrerender(url));
986 EXPECT_TRUE(prerender_contents->prerendering_has_started());
987 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
988 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
989 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
990 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
991 last_prerender_id());
993 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
994 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
995 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
996 last_prerender_id());
998 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
999 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1000 DummyPrerenderContents* null = NULL;
1001 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1004 TEST_F(PrerenderTest, LinkManagerAbandon) {
1005 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1006 GURL url("http://www.myexample.com");
1007 DummyPrerenderContents* prerender_contents =
1008 prerender_manager()->CreateNextPrerenderContents(
1009 url, FINAL_STATUS_USED);
1011 EXPECT_TRUE(AddSimplePrerender(url));
1013 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1014 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1015 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1016 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1017 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1018 last_prerender_id());
1020 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1021 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1024 TEST_F(PrerenderTest, LinkManagerAbandonThenCancel) {
1025 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1026 GURL url("http://www.myexample.com");
1027 DummyPrerenderContents* prerender_contents =
1028 prerender_manager()->CreateNextPrerenderContents(
1029 url, FINAL_STATUS_CANCELLED);
1031 EXPECT_TRUE(AddSimplePrerender(url));
1033 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1034 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1035 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1036 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1037 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1038 last_prerender_id());
1040 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1041 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1043 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1044 last_prerender_id());
1045 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1046 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1047 DummyPrerenderContents* null = NULL;
1048 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1051 TEST_F(PrerenderTest, LinkManagerCancelTwice) {
1052 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1053 GURL url("http://www.myexample.com");
1054 DummyPrerenderContents* prerender_contents =
1055 prerender_manager()->CreateNextPrerenderContents(
1056 url, FINAL_STATUS_CANCELLED);
1058 EXPECT_TRUE(AddSimplePrerender(url));
1059 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1060 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1061 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1062 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1063 last_prerender_id());
1065 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1066 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1067 DummyPrerenderContents* null = NULL;
1068 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1069 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1070 last_prerender_id());
1073 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwice) {
1075 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1076 GURL url("http://www.myexample.com");
1077 DummyPrerenderContents* prerender_contents =
1078 prerender_manager()->CreateNextPrerenderContents(
1079 url, FINAL_STATUS_CANCELLED);
1081 EXPECT_TRUE(AddSimplePrerender(url));
1083 const int first_prerender_id = last_prerender_id();
1084 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1085 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1086 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1087 EXPECT_TRUE(AddSimplePrerender(url));
1089 const int second_prerender_id = last_prerender_id();
1090 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1091 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1092 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1093 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1094 first_prerender_id);
1096 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1097 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1098 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1099 second_prerender_id);
1101 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1102 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1103 DummyPrerenderContents* null = NULL;
1104 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1107 TEST_F(PrerenderTest, LinkManagerAddTwiceCancelTwiceThenAbandonTwice) {
1109 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1110 GURL url("http://www.myexample.com");
1111 DummyPrerenderContents* prerender_contents =
1112 prerender_manager()->CreateNextPrerenderContents(
1113 url, FINAL_STATUS_CANCELLED);
1115 EXPECT_TRUE(AddSimplePrerender(url));
1117 const int first_prerender_id = last_prerender_id();
1118 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1119 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1120 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1121 EXPECT_TRUE(AddSimplePrerender(url));
1123 const int second_prerender_id = last_prerender_id();
1124 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1125 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1126 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1127 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1128 first_prerender_id);
1130 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1131 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1132 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1133 second_prerender_id);
1135 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1136 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1137 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1138 first_prerender_id);
1140 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1141 EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1142 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1143 second_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 // TODO(gavinp): Update this test after abandon has an effect on Prerenders,
1152 // like shortening the timeouts.
1153 TEST_F(PrerenderTest, LinkManagerAddTwiceAbandonTwiceUseTwice) {
1155 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1156 GURL url("http://www.myexample.com");
1157 DummyPrerenderContents* prerender_contents =
1158 prerender_manager()->CreateNextPrerenderContents(
1159 url, FINAL_STATUS_USED);
1161 EXPECT_TRUE(AddSimplePrerender(url));
1163 const int first_prerender_id = last_prerender_id();
1164 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1165 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1166 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1167 EXPECT_TRUE(AddSimplePrerender(url));
1169 const int second_prerender_id = last_prerender_id();
1170 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1171 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1172 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1173 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1174 first_prerender_id);
1176 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1177 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1178 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1179 second_prerender_id);
1181 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1182 ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1183 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1186 // TODO(gavinp): After abandon shortens the expire time on a Prerender,
1187 // add a series of tests testing advancing the time by either the abandon
1188 // or normal expire, and verifying the expected behaviour with groups
1190 TEST_F(PrerenderTest, LinkManagerExpireThenCancel) {
1191 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1192 GURL url("http://www.myexample.com");
1193 DummyPrerenderContents* prerender_contents =
1194 prerender_manager()->CreateNextPrerenderContents(
1195 url, FINAL_STATUS_TIMED_OUT);
1197 EXPECT_TRUE(AddSimplePrerender(url));
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 prerender_manager()->AdvanceTimeTicks(
1203 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1205 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1206 DummyPrerenderContents* null = NULL;
1207 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1208 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1209 last_prerender_id());
1211 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1212 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1215 TEST_F(PrerenderTest, LinkManagerExpireThenAddAgain) {
1216 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1217 GURL url("http://www.myexample.com");
1218 DummyPrerenderContents* first_prerender_contents =
1219 prerender_manager()->CreateNextPrerenderContents(
1220 url, FINAL_STATUS_TIMED_OUT);
1221 EXPECT_TRUE(AddSimplePrerender(url));
1222 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1223 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1224 ASSERT_EQ(first_prerender_contents,
1225 prerender_manager()->FindEntry(url));
1226 prerender_manager()->AdvanceTimeTicks(
1227 prerender_manager()->config().time_to_live + TimeDelta::FromSeconds(1));
1228 DummyPrerenderContents* null = NULL;
1229 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1230 DummyPrerenderContents* second_prerender_contents =
1231 prerender_manager()->CreateNextPrerenderContents(
1232 url, FINAL_STATUS_USED);
1233 EXPECT_TRUE(AddSimplePrerender(url));
1234 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1235 ASSERT_EQ(second_prerender_contents,
1236 prerender_manager()->FindAndUseEntry(url));
1239 TEST_F(PrerenderTest, LinkManagerCancelThenAddAgain) {
1240 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1241 GURL url("http://www.myexample.com");
1242 DummyPrerenderContents* first_prerender_contents =
1243 prerender_manager()->CreateNextPrerenderContents(
1244 url, FINAL_STATUS_CANCELLED);
1245 EXPECT_TRUE(AddSimplePrerender(url));
1246 EXPECT_TRUE(first_prerender_contents->prerendering_has_started());
1247 EXPECT_FALSE(first_prerender_contents->prerendering_has_been_cancelled());
1248 ASSERT_EQ(first_prerender_contents, prerender_manager()->FindEntry(url));
1249 prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
1250 last_prerender_id());
1251 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1252 EXPECT_TRUE(first_prerender_contents->prerendering_has_been_cancelled());
1253 DummyPrerenderContents* null = NULL;
1254 ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1255 DummyPrerenderContents* second_prerender_contents =
1256 prerender_manager()->CreateNextPrerenderContents(
1257 url, FINAL_STATUS_USED);
1258 EXPECT_TRUE(AddSimplePrerender(url));
1259 EXPECT_TRUE(second_prerender_contents->prerendering_has_started());
1260 ASSERT_EQ(second_prerender_contents,
1261 prerender_manager()->FindAndUseEntry(url));
1264 TEST_F(PrerenderTest, LinkManagerChannelClosing) {
1265 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1266 GURL url("http://www.myexample.com");
1267 DummyPrerenderContents* prerender_contents =
1268 prerender_manager()->CreateNextPrerenderContents(
1269 url, FINAL_STATUS_TIMED_OUT);
1271 EXPECT_TRUE(AddSimplePrerender(url));
1272 EXPECT_TRUE(prerender_contents->prerendering_has_started());
1273 EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1274 ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1276 prerender_link_manager()->OnChannelClosing(kDefaultChildId);
1278 prerender_manager()->AdvanceTimeTicks(
1279 prerender_manager()->config().abandon_time_to_live +
1280 TimeDelta::FromSeconds(1));
1282 DummyPrerenderContents* null = NULL;
1283 EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1284 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1287 // Creates two prerenders, one of which should be blocked by the
1288 // max_link_concurrency; abandons both of them and waits to make sure both
1289 // are cleared from the PrerenderLinkManager.
1290 TEST_F(PrerenderTest, LinkManagerAbandonInactivePrerender) {
1292 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1293 prerender_manager()->config().time_to_live);
1294 GURL first_url("http://www.myexample.com");
1295 DummyPrerenderContents* prerender_contents =
1296 prerender_manager()->CreateNextPrerenderContents(
1297 first_url, FINAL_STATUS_TIMED_OUT);
1298 EXPECT_TRUE(AddSimplePrerender(first_url));
1299 const int first_prerender_id = last_prerender_id();
1301 GURL second_url("http://www.neverlaunched.com");
1302 EXPECT_FALSE(AddSimplePrerender(second_url));
1303 const int second_prerender_id = last_prerender_id();
1305 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1307 DummyPrerenderContents* null = NULL;
1308 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1309 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1311 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1312 first_prerender_id);
1313 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1314 second_prerender_id);
1316 prerender_manager()->AdvanceTimeTicks(
1317 prerender_manager()->config().abandon_time_to_live +
1318 TimeDelta::FromSeconds(1));
1319 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1320 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1321 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1324 // Creates two prerenders, the second one started by the first, both of which
1325 // should be blocked by max_concurrency; abandons both of them and waits to make
1326 // sure both are cleared from the PrerenderLinkManager.
1327 TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) {
1329 ASSERT_LT(prerender_manager()->config().abandon_time_to_live,
1330 prerender_manager()->config().time_to_live);
1331 GURL first_url("http://www.myexample.com");
1332 DummyPrerenderContents* prerender_contents =
1333 prerender_manager()->CreateNextPrerenderContents(
1334 first_url, FINAL_STATUS_TIMED_OUT);
1335 EXPECT_TRUE(AddSimplePrerender(first_url));
1336 const int first_prerender_id = last_prerender_id();
1340 ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
1341 ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
1343 GURL pending_url("http://www.neverlaunched.com");
1344 prerender_link_manager()->OnAddPrerender(child_id,
1345 GetNextPrerenderID(),
1346 pending_url, content::Referrer(),
1348 const int second_prerender_id = last_prerender_id();
1350 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1352 DummyPrerenderContents* null = NULL;
1353 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1354 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1356 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1357 first_prerender_id);
1358 prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1359 second_prerender_id);
1361 prerender_manager()->AdvanceTimeTicks(
1362 prerender_manager()->config().abandon_time_to_live +
1363 TimeDelta::FromSeconds(1));
1364 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1365 EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1366 EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1369 // Creates two prerenders, one of which should be blocked by the
1370 // max_link_concurrency; uses one after the max wait to launch, and
1371 // ensures the second prerender does not start.
1372 TEST_F(PrerenderTest, LinkManagerWaitToLaunchNotLaunched) {
1374 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1375 prerender_manager()->config().time_to_live);
1376 GURL first_url("http://www.myexample.com");
1377 DummyPrerenderContents* prerender_contents =
1378 prerender_manager()->CreateNextPrerenderContents(
1379 first_url, FINAL_STATUS_USED);
1380 EXPECT_TRUE(AddSimplePrerender(first_url));
1382 GURL second_url("http://www.neverlaunched.com");
1383 EXPECT_FALSE(AddSimplePrerender(second_url));
1385 EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1387 DummyPrerenderContents* null = NULL;
1388 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1389 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1391 prerender_manager()->AdvanceTimeTicks(
1392 prerender_manager()->config().max_wait_to_launch +
1393 TimeDelta::FromSeconds(1));
1394 EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1395 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1397 EXPECT_EQ(prerender_contents,
1398 prerender_manager()->FindAndUseEntry(first_url));
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, one of which should start when the first one expires.
1406 TEST_F(PrerenderTest, LinkManagerExpireRevealingLaunch) {
1408 ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1409 prerender_manager()->config().time_to_live);
1411 GURL first_url("http://www.willexpire.com");
1412 DummyPrerenderContents* first_prerender_contents =
1413 prerender_manager()->CreateNextPrerenderContents(
1414 first_url, FINAL_STATUS_TIMED_OUT);
1415 EXPECT_TRUE(AddSimplePrerender(first_url));
1416 EXPECT_EQ(first_prerender_contents,
1417 prerender_manager()->FindEntry(first_url));
1419 // Insert the second prerender so it will be still be launchable when the
1421 const TimeDelta wait_to_launch_second_prerender =
1422 prerender_manager()->config().time_to_live -
1423 prerender_manager()->config().max_wait_to_launch +
1424 TimeDelta::FromSeconds(2);
1425 const TimeDelta wait_for_first_prerender_to_expire =
1426 prerender_manager()->config().time_to_live -
1427 wait_to_launch_second_prerender +
1428 TimeDelta::FromSeconds(1);
1429 ASSERT_LT(prerender_manager()->config().time_to_live,
1430 wait_to_launch_second_prerender +
1431 wait_for_first_prerender_to_expire);
1432 ASSERT_GT(prerender_manager()->config().max_wait_to_launch.InSeconds(),
1433 wait_for_first_prerender_to_expire.InSeconds());
1435 prerender_manager()->AdvanceTimeTicks(wait_to_launch_second_prerender);
1436 GURL second_url("http://www.willlaunch.com");
1437 DummyPrerenderContents* second_prerender_contents =
1438 prerender_manager()->CreateNextPrerenderContents(
1439 second_url, FINAL_STATUS_USED);
1440 EXPECT_FALSE(AddSimplePrerender(second_url));
1442 // The first prerender is still running, but the second has not yet launched.
1443 EXPECT_EQ(first_prerender_contents,
1444 prerender_manager()->FindEntry(first_url));
1445 PrerenderContents* null = NULL;
1446 EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1448 // The first prerender should have died, giving life to the second one.
1449 prerender_manager()->AdvanceTimeTicks(wait_for_first_prerender_to_expire);
1450 EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1451 EXPECT_EQ(second_prerender_contents,
1452 prerender_manager()->FindAndUseEntry(second_url));
1455 } // namespace prerender