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