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/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"
29
30using base::Time;
31using base::TimeDelta;
32using base::TimeTicks;
33using content::BrowserThread;
34using content::Referrer;
35
36namespace prerender {
37
38class UnitTestPrerenderManager;
39
40namespace {
41
42class 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);
49
50  virtual ~DummyPrerenderContents();
51
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;
58
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;
64  }
65
66  virtual bool GetRouteId(int* route_id) const OVERRIDE {
67    *route_id = route_id_;
68    return true;
69  }
70
71  FinalStatus expected_final_status() const { return expected_final_status_; }
72
73  bool prerendering_has_been_cancelled() const {
74    return PrerenderContents::prerendering_has_been_cancelled();
75  }
76
77 private:
78  static int g_next_route_id_;
79  int route_id_;
80
81  UnitTestPrerenderManager* test_prerender_manager_;
82  FinalStatus expected_final_status_;
83};
84
85int DummyPrerenderContents::g_next_route_id_ = 0;
86
87const gfx::Size kSize(640, 480);
88
89const uint32 kDefaultRelTypes = PrerenderRelTypePrerender;
90
91}  // namespace
92
93class UnitTestPrerenderManager : public PrerenderManager {
94 public:
95  using PrerenderManager::kMinTimeBetweenPrerendersMs;
96  using PrerenderManager::kNavigationRecordWindowMs;
97
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();
106  }
107
108  virtual ~UnitTestPrerenderManager() {
109  }
110
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();
116  }
117
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);
124  }
125
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;
132  }
133
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);
143
144    prerender_contents->PrepareForUse();
145    return prerender_contents;
146  }
147
148  void AdvanceTime(TimeDelta delta) {
149    time_ += delta;
150  }
151
152  void AdvanceTimeTicks(TimeDelta delta) {
153    time_ticks_ += delta;
154  }
155
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;
165  }
166
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;
176  }
177
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));
190    }
191    SetNextPrerenderContents(prerender_contents);
192    return prerender_contents;
193  }
194
195  void set_rate_limit_enabled(bool enabled) {
196    mutable_config().rate_limit_enabled = enabled;
197  }
198
199  PrerenderContents* next_prerender_contents() {
200    return next_prerender_contents_.get();
201  }
202
203  // from PrerenderManager
204  virtual Time GetCurrentTime() const OVERRIDE {
205    return time_;
206  }
207
208  virtual TimeTicks GetCurrentTimeTicks() const OVERRIDE {
209    return time_ticks_;
210  }
211
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;
220  }
221
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;
227  }
228
229  void DummyPrerenderContentsDestroyed(int child_id,
230                                       int route_id) {
231    prerender_contents_map_.erase(std::make_pair(child_id, route_id));
232  }
233
234 protected:
235  virtual net::URLRequestContextGetter* GetURLRequestContext() OVERRIDE {
236    return NULL;
237  }
238
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);
245  }
246
247
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();
257  }
258
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_;
263
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_;
270
271  PrerenderTracker* prerender_tracker_;
272};
273
274class RestorePrerenderMode {
275 public:
276  RestorePrerenderMode() : prev_mode_(PrerenderManager::GetMode()) {
277  }
278
279  ~RestorePrerenderMode() { PrerenderManager::SetMode(prev_mode_); }
280 private:
281  PrerenderManager::PrerenderManagerMode prev_mode_;
282};
283
284DummyPrerenderContents::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) {
296}
297
298DummyPrerenderContents::~DummyPrerenderContents() {
299  EXPECT_EQ(expected_final_status_, final_status());
300  test_prerender_manager_->DummyPrerenderContentsDestroyed(-1, route_id_);
301}
302
303void 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();
317  }
318}
319
320class PrerenderTest : public testing::Test {
321 public:
322  static const int kDefaultChildId = -1;
323  static const int kDefaultRenderViewRouteId = -1;
324
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);
336  }
337
338  virtual ~PrerenderTest() {
339    prerender_link_manager_->OnChannelClosing(kDefaultChildId);
340    prerender_link_manager_->Shutdown();
341    prerender_manager_->Shutdown();
342  }
343
344  UnitTestPrerenderManager* prerender_manager() {
345    return prerender_manager_.get();
346  }
347
348  PrerenderLinkManager* prerender_link_manager() {
349    return prerender_link_manager_.get();
350  }
351
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);
358  }
359
360  bool IsEmptyPrerenderLinkManager() const {
361    return prerender_link_manager_->IsEmpty();
362  }
363
364  int last_prerender_id() const {
365    return last_prerender_id_;
366  }
367
368  int GetNextPrerenderID() {
369    return ++last_prerender_id_;
370  }
371
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;
377  }
378
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;
384  }
385
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());
394  }
395
396 private:
397  PrerenderTracker* prerender_tracker() {
398    return g_browser_process->prerender_tracker();
399  }
400
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_;
409};
410
411TEST_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));
420}
421
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.
425TEST_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());
436
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());
445
446  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
447}
448
449// Ensure that we expire a prerendered page after the max. permitted time.
450TEST_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));
463}
464
465// Ensure that we don't launch prerenders of bad urls (in this case, a mailto:
466// url)
467TEST_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));
478}
479
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.
482TEST_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);
488
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;
492
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);
507
508  EXPECT_EQ(null, prerender_manager()->FindEntry(url));
509}
510
511// But when we navigate away very close to the original expiry of a prerender,
512// we shouldn't expect it to be extended.
513TEST_F(PrerenderTest, LinkManagerNavigateAwayNearExpiry) {
514  const TimeDelta time_to_live = TimeDelta::FromSeconds(300);
515  const TimeDelta abandon_time_to_live = TimeDelta::FromSeconds(20);
516
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);
526
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;
530
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));
539
540  prerender_manager()->AdvanceTimeTicks(first_advance);
541  EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
542
543  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
544                                               last_prerender_id());
545  EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
546
547  DummyPrerenderContents* null = NULL;
548  EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
549
550  prerender_manager()->AdvanceTimeTicks(second_advance);
551  EXPECT_EQ(null, prerender_manager()->FindEntry(url));
552}
553
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.
557TEST_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);
563
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;
567
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());
573
574  prerender_manager()->AdvanceTimeTicks(test_advance);
575
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));
583}
584
585
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.
590TEST_F(PrerenderTest, MaxConcurrencyTest) {
591  struct TestConcurrency {
592    size_t max_link_concurrency;
593    size_t max_link_concurrency_per_launcher;
594  };
595
596  TestConcurrency concurrencies_to_test[] = {
597    { prerender_manager()->config().max_link_concurrency,
598      prerender_manager()->config().max_link_concurrency_per_launcher},
599
600    // With the system limit higher than the per launcher limit, the per
601    // launcher limit should be in effect.
602    { 2, 1 },
603
604    // With the per launcher limit higher than system limit, the system limit
605    // should be in effect.
606    { 2, 4 },
607  };
608
609  DummyPrerenderContents* null = NULL;
610  GURL url_to_delay("http://www.google.com/delayme");
611
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;
617
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);
621
622    std::vector<GURL> urls;
623    std::vector<PrerenderContents*> prerender_contentses;
624
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());
635    }
636
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));
650    }
651
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());
663    }
664
665    EXPECT_EQ(prerender_contents_to_delay,
666              prerender_manager()->FindAndUseEntry(url_to_delay));
667    EXPECT_EQ(null, prerender_manager()->next_prerender_contents());
668  }
669}
670
671TEST_F(PrerenderTest, AliasURLTest) {
672  SetConcurrency(7);
673
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);
681
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));
699
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));
708}
709
710TEST_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));
717
718  int child_id;
719  int route_id;
720  ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
721  ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
722
723  GURL pending_url("http://news.google.com/");
724
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());
737
738  // Use the referring prerender.
739  EXPECT_TRUE(prerender_contents->prerendering_has_started());
740  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
741
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));
747}
748
749TEST_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));
756
757  int child_id;
758  int route_id;
759  ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
760  ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
761
762  // This pending URL has an unsupported scheme, and won't be able
763  // to start.
764  GURL pending_url("ftp://news.google.com/");
765
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());
778
779  // Use the referring prerender.
780  EXPECT_TRUE(prerender_contents->prerendering_has_started());
781  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
782
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());
786}
787
788TEST_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));
795
796  int child_id;
797  int route_id;
798  ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
799  ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
800
801  GURL pending_url("http://news.google.com/");
802
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()));
809
810  // Cancel the pending prerender.
811  prerender_link_manager()->OnCancelPrerender(child_id, last_prerender_id());
812
813  // Use the referring prerender.
814  EXPECT_TRUE(prerender_contents->prerendering_has_started());
815  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
816
817  // The pending prerender doesn't start.
818  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
819}
820
821// Tests that a PrerenderManager created for a browser session in the control
822// group works as expected.
823TEST_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());
834}
835
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.
839TEST_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()));
847}
848
849// Tests that prerendering doesn't launch rel=next prerenders without the field
850// trial.
851TEST_F(PrerenderTest, NoRelNextByDefault) {
852  GURL url("http://www.google.com/");
853  prerender_manager()->CreateNextPrerenderContents(
854      url, FINAL_STATUS_MANAGER_SHUTDOWN);
855  DummyPrerenderContents* null = NULL;
856
857  prerender_link_manager()->OnAddPrerender(
858      kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
859      Referrer(), kSize, kDefaultRenderViewRouteId);
860  EXPECT_EQ(null, prerender_manager()->FindEntry(url));
861}
862
863// Tests that prerendering does launch rel=next prerenders with the field trial.
864TEST_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);
871
872  prerender_link_manager()->OnAddPrerender(
873      kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
874      Referrer(), kSize, kDefaultRenderViewRouteId);
875  EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
876}
877
878// Tests that prerendering is cancelled when we launch a second prerender of
879// the same target within a short time interval.
880TEST_F(PrerenderTest, RecentlyVisited) {
881  GURL url("http://www.google.com/");
882
883  prerender_manager()->RecordNavigation(url);
884
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());
890}
891
892TEST_F(PrerenderTest, NotSoRecentlyVisited) {
893  GURL url("http://www.google.com/");
894
895  prerender_manager()->RecordNavigation(url);
896  prerender_manager()->AdvanceTimeTicks(
897      TimeDelta::FromMilliseconds(
898          UnitTestPrerenderManager::kNavigationRecordWindowMs + 500));
899
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));
906}
907
908// Tests that our PPLT dummy prerender gets created properly.
909TEST_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());
917
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());
925
926  ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
927  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
928}
929
930// Tests that our PPLT dummy prerender gets created properly, even
931// when navigating to a page that has been recently navigated to.
932TEST_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());
939
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);
946
947  ASSERT_EQ(pplt_dummy_contents, prerender_manager()->FindAndUseEntry(url));
948}
949
950TEST_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));
964
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));
971}
972
973// Tests that the prerender manager matches include the fragment.
974TEST_F(PrerenderTest, FragmentMatchesTest) {
975  GURL fragment_url("http://www.google.com/#test");
976
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));
984}
985
986// Tests that the prerender manager uses fragment references when matching
987// prerender URLs in the case a different fragment is in both URLs.
988TEST_F(PrerenderTest, FragmentsDifferTest) {
989  GURL fragment_url("http://www.google.com/#test");
990  GURL other_fragment_url("http://www.google.com/#other_test");
991
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());
997
998  DummyPrerenderContents* null = NULL;
999  ASSERT_EQ(null, prerender_manager()->FindEntry(other_fragment_url));
1000
1001  ASSERT_EQ(prerender_contents,
1002            prerender_manager()->FindAndUseEntry(fragment_url));
1003}
1004
1005// Make sure that clearing works as expected.
1006TEST_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));
1017}
1018
1019// Make sure canceling works as expected.
1020TEST_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));
1030}
1031
1032TEST_F(PrerenderTest, OmniboxNotAllowedWhenDisabled) {
1033  prerender_manager()->set_enabled(false);
1034  EXPECT_FALSE(prerender_manager()->AddPrerenderFromOmnibox(
1035      GURL("http://www.example.com"), NULL, gfx::Size()));
1036}
1037
1038TEST_F(PrerenderTest, LinkRelNotAllowedWhenDisabled) {
1039  prerender_manager()->set_enabled(false);
1040  EXPECT_FALSE(AddSimplePrerender(
1041      GURL("http://www.example.com")));
1042}
1043
1044TEST_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);
1050
1051  EXPECT_TRUE(AddSimplePrerender(url));
1052
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());
1059
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());
1064}
1065
1066TEST_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);
1072
1073  EXPECT_TRUE(AddSimplePrerender(url));
1074
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());
1081
1082  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1083  EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1084  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1085                                               last_prerender_id());
1086
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));
1091}
1092
1093TEST_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);
1099
1100  EXPECT_TRUE(AddSimplePrerender(url));
1101
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());
1108
1109  EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1110  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1111}
1112
1113TEST_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);
1119
1120  EXPECT_TRUE(AddSimplePrerender(url));
1121
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());
1128
1129  EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1130  ASSERT_EQ(prerender_contents, prerender_manager()->FindEntry(url));
1131
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));
1138}
1139
1140TEST_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);
1146
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());
1153
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());
1160}
1161
1162TEST_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);
1169
1170  EXPECT_TRUE(AddSimplePrerender(url));
1171
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));
1177
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);
1184
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);
1189
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));
1194}
1195
1196TEST_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);
1203
1204  EXPECT_TRUE(AddSimplePrerender(url));
1205
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));
1211
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);
1218
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);
1223
1224  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1225  EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1226  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1227                                               first_prerender_id);
1228
1229  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1230  EXPECT_TRUE(prerender_contents->prerendering_has_been_cancelled());
1231  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1232                                               second_prerender_id);
1233
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));
1238}
1239
1240// TODO(gavinp): Update this test after abandon has an effect on Prerenders,
1241// like shortening the timeouts.
1242TEST_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);
1249
1250  EXPECT_TRUE(AddSimplePrerender(url));
1251
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));
1257
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);
1264
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);
1269
1270  EXPECT_FALSE(prerender_contents->prerendering_has_been_cancelled());
1271  ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
1272  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1273}
1274
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.
1279TEST_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);
1285
1286  EXPECT_TRUE(AddSimplePrerender(url));
1287
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));
1293
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());
1299
1300  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1301  ASSERT_EQ(null, prerender_manager()->FindEntry(url));
1302}
1303
1304TEST_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));
1326}
1327
1328TEST_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));
1351}
1352
1353TEST_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);
1359
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));
1364
1365  prerender_link_manager()->OnChannelClosing(kDefaultChildId);
1366
1367  prerender_manager()->AdvanceTimeTicks(
1368      prerender_manager()->config().abandon_time_to_live +
1369      TimeDelta::FromSeconds(1));
1370
1371  DummyPrerenderContents* null = NULL;
1372  EXPECT_EQ(null, prerender_manager()->FindEntry(url));
1373  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1374}
1375
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.
1379TEST_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();
1389
1390  GURL second_url("http://www.neverlaunched.com");
1391  EXPECT_FALSE(AddSimplePrerender(second_url));
1392  const int second_prerender_id = last_prerender_id();
1393
1394  EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1395
1396  DummyPrerenderContents* null = NULL;
1397  EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1398  EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1399
1400  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1401                                               first_prerender_id);
1402  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1403                                               second_prerender_id);
1404
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());
1411}
1412
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.
1416TEST_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();
1426
1427  int child_id;
1428  int route_id;
1429  ASSERT_TRUE(prerender_contents->GetChildId(&child_id));
1430  ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
1431
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();
1437
1438  EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1439
1440  DummyPrerenderContents* null = NULL;
1441  EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1442  EXPECT_EQ(null, prerender_manager()->FindEntry(pending_url));
1443
1444  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1445                                               first_prerender_id);
1446  prerender_link_manager()->OnAbandonPrerender(kDefaultChildId,
1447                                               second_prerender_id);
1448
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());
1455}
1456
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.
1460TEST_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));
1469
1470  GURL second_url("http://www.neverlaunched.com");
1471  EXPECT_FALSE(AddSimplePrerender(second_url));
1472
1473  EXPECT_FALSE(IsEmptyPrerenderLinkManager());
1474
1475  DummyPrerenderContents* null = NULL;
1476  EXPECT_EQ(prerender_contents, prerender_manager()->FindEntry(first_url));
1477  EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1478
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));
1484
1485  EXPECT_EQ(prerender_contents,
1486            prerender_manager()->FindAndUseEntry(first_url));
1487
1488  EXPECT_EQ(null, prerender_manager()->FindEntry(first_url));
1489  EXPECT_EQ(null, prerender_manager()->FindEntry(second_url));
1490  EXPECT_TRUE(IsEmptyPrerenderLinkManager());
1491}
1492
1493// Creates two prerenders, one of which should start when the first one expires.
1494TEST_F(PrerenderTest, LinkManagerExpireRevealingLaunch) {
1495  SetConcurrency(1);
1496  ASSERT_LT(prerender_manager()->config().max_wait_to_launch,
1497            prerender_manager()->config().time_to_live);
1498
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));
1506
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());
1522
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));
1529
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));
1535
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));
1541}
1542
1543TEST_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()));
1550}
1551
1552TEST_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());
1569}
1570
1571}  // namespace prerender
1572