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