Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prerender / prerender_unittest.cc
index 59fbd42..484c09d 100644 (file)
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <map>
+#include <utility>
+
 #include "base/command_line.h"
 #include "base/format_macros.h"
 #include "base/memory/scoped_vector.h"
@@ -15,6 +18,7 @@
 #include "chrome/browser/prerender/prerender_manager.h"
 #include "chrome/browser/prerender/prerender_origin.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/prerender_types.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/browser/render_view_host.h"
@@ -43,9 +47,7 @@ class DummyPrerenderContents : public PrerenderContents {
                          Origin origin,
                          FinalStatus expected_final_status);
 
-  virtual ~DummyPrerenderContents() {
-    EXPECT_EQ(expected_final_status_, final_status());
-  }
+  virtual ~DummyPrerenderContents();
 
   virtual void StartPrerendering(
       int ALLOW_UNUSED creator_child_id,
@@ -83,6 +85,8 @@ int DummyPrerenderContents::g_next_route_id_ = 0;
 
 const gfx::Size kSize(640, 480);
 
+const uint32 kDefaultRelTypes = PrerenderRelTypePrerender;
+
 }  // namespace
 
 class UnitTestPrerenderManager : public PrerenderManager {
@@ -135,7 +139,6 @@ class UnitTestPrerenderManager : public PrerenderManager {
     PrerenderContents* prerender_contents = prerender_data->ReleaseContents();
     active_prerenders_.erase(to_erase);
 
-    prerender_contents->SetFinalStatus(FINAL_STATUS_USED);
     prerender_contents->PrepareForUse();
     return prerender_contents;
   }
@@ -204,6 +207,28 @@ class UnitTestPrerenderManager : public PrerenderManager {
     return time_ticks_;
   }
 
+  virtual PrerenderContents* GetPrerenderContentsForRoute(
+      int child_id, int route_id) const OVERRIDE {
+    // Overridden for the PrerenderLinkManager's pending prerender logic.
+    PrerenderContentsMap::const_iterator iter = prerender_contents_map_.find(
+        std::make_pair(child_id, route_id));
+    if (iter == prerender_contents_map_.end())
+      return NULL;
+    return iter->second;
+  }
+
+  void DummyPrerenderContentsStarted(int child_id,
+                                     int route_id,
+                                     PrerenderContents* prerender_contents) {
+    prerender_contents_map_[std::make_pair(child_id, route_id)] =
+        prerender_contents;
+  }
+
+  void DummyPrerenderContentsDestroyed(int child_id,
+                                       int route_id) {
+    prerender_contents_map_.erase(std::make_pair(child_id, route_id));
+  }
+
  private:
   void SetNextPrerenderContents(DummyPrerenderContents* prerender_contents) {
     CHECK(!next_prerender_contents_.get());
@@ -224,6 +249,11 @@ class UnitTestPrerenderManager : public PrerenderManager {
     return next_prerender_contents_.release();
   }
 
+  // Maintain a map from route pairs to PrerenderContents for
+  // GetPrerenderContentsForRoute.
+  typedef std::map<std::pair<int,int>, PrerenderContents*> PrerenderContentsMap;
+  PrerenderContentsMap prerender_contents_map_;
+
   Time time_;
   TimeTicks time_ticks_;
   scoped_ptr<PrerenderContents> next_prerender_contents_;
@@ -258,6 +288,11 @@ DummyPrerenderContents::DummyPrerenderContents(
       expected_final_status_(expected_final_status) {
 }
 
+DummyPrerenderContents::~DummyPrerenderContents() {
+  EXPECT_EQ(expected_final_status_, final_status());
+  test_prerender_manager_->DummyPrerenderContentsDestroyed(-1, route_id_);
+}
+
 void DummyPrerenderContents::StartPrerendering(
     int ALLOW_UNUSED creator_child_id,
     const gfx::Size& ALLOW_UNUSED size,
@@ -269,6 +304,7 @@ void DummyPrerenderContents::StartPrerendering(
   load_start_time_ = test_prerender_manager_->GetCurrentTimeTicks();
   if (!test_prerender_manager_->IsControlGroup(experiment_id())) {
     prerendering_has_started_ = true;
+    test_prerender_manager_->DummyPrerenderContentsStarted(-1, route_id_, this);
     NotifyPrerenderStart();
   }
 }
@@ -332,14 +368,20 @@ class PrerenderTest : public testing::Test {
     return prerender && prerender->handle;
   }
 
+  bool LauncherHasScheduledPrerender(int child_id, int prerender_id) {
+    PrerenderLinkManager::LinkPrerender* prerender =
+        prerender_link_manager()->FindByLauncherChildIdAndPrerenderId(
+            child_id, prerender_id);
+    return prerender != NULL;
+  }
+
   // Shorthand to add a simple prerender with a reasonable source. Returns
   // true iff the prerender has been added to the PrerenderManager by the
   // PrerenderLinkManager and the PrerenderManager returned a handle.
   bool AddSimplePrerender(const GURL& url) {
-    prerender_link_manager()->OnAddPrerender(kDefaultChildId,
-                                             GetNextPrerenderID(),
-                                             url, content::Referrer(),
-                                             kSize, kDefaultRenderViewRouteId);
+    prerender_link_manager()->OnAddPrerender(
+        kDefaultChildId, GetNextPrerenderID(), url, kDefaultRelTypes,
+        content::Referrer(), kSize, kDefaultRenderViewRouteId);
     return LauncherHasRunningPrerender(kDefaultChildId, last_prerender_id());
   }
 
@@ -587,21 +629,16 @@ TEST_F(PrerenderTest, MaxConcurrencyTest) {
     if (concurrencies_to_test[i].max_link_concurrency >
             effective_max_link_concurrency) {
       // We should be able to launch more prerenders on this system, but not for
-      // our current launcher.
-      int child_id;
-      int route_id;
-      ASSERT_TRUE(prerender_contentses.back()->GetChildId(&child_id));
-      ASSERT_TRUE(prerender_contentses.back()->GetRouteId(&route_id));
-
+      // the default launcher.
       GURL extra_url("http://google.com/extraurl");
-      prerender_link_manager()->OnAddPrerender(child_id,
-                                               GetNextPrerenderID(),
-                                               extra_url, content::Referrer(),
-                                               kSize, route_id);
+      EXPECT_FALSE(AddSimplePrerender(extra_url));
       const int prerender_id = last_prerender_id();
-      EXPECT_TRUE(LauncherHasRunningPrerender(child_id, prerender_id));
-      prerender_link_manager()->OnCancelPrerender(child_id, prerender_id);
-      EXPECT_FALSE(LauncherHasRunningPrerender(child_id, prerender_id));
+      EXPECT_TRUE(LauncherHasScheduledPrerender(kDefaultChildId,
+                                                prerender_id));
+      prerender_link_manager()->OnCancelPrerender(kDefaultChildId,
+                                                  prerender_id);
+      EXPECT_FALSE(LauncherHasScheduledPrerender(kDefaultChildId,
+                                                 prerender_id));
     }
 
     DummyPrerenderContents* prerender_contents_to_delay =
@@ -677,25 +714,28 @@ TEST_F(PrerenderTest, PendingPrerenderTest) {
 
   GURL pending_url("http://news.google.com/");
 
+  // Schedule a pending prerender launched from the prerender.
   DummyPrerenderContents* pending_prerender_contents =
       prerender_manager()->CreateNextPrerenderContents(
           pending_url,
           ORIGIN_GWS_PRERENDER,
           FINAL_STATUS_USED);
-  scoped_ptr<PrerenderHandle> pending_prerender_handle(
-      prerender_manager()->AddPrerenderFromLinkRelPrerender(
-          child_id, route_id, pending_url,
-          Referrer(url, blink::WebReferrerPolicyDefault), kSize));
-  CHECK(pending_prerender_handle.get());
-  EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
-
+  prerender_link_manager()->OnAddPrerender(
+      child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
+      Referrer(url, blink::WebReferrerPolicyDefault),
+      kSize, route_id);
+  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
+  EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
+
+  // Use the referring prerender.
   EXPECT_TRUE(prerender_contents->prerendering_has_started());
   ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
 
-  EXPECT_TRUE(pending_prerender_handle->IsPrerendering());
+  // The pending prerender should start now.
+  EXPECT_TRUE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
+  EXPECT_TRUE(pending_prerender_contents->prerendering_has_started());
   ASSERT_EQ(pending_prerender_contents,
             prerender_manager()->FindAndUseEntry(pending_url));
-  EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
 }
 
 TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
@@ -715,21 +755,26 @@ TEST_F(PrerenderTest, InvalidPendingPrerenderTest) {
   // to start.
   GURL pending_url("ftp://news.google.com/");
 
-  prerender_manager()->CreateNextPrerenderContents(
-      pending_url,
-      ORIGIN_GWS_PRERENDER,
-      FINAL_STATUS_UNSUPPORTED_SCHEME);
-  scoped_ptr<PrerenderHandle> pending_prerender_handle(
-      prerender_manager()->AddPrerenderFromLinkRelPrerender(
-          child_id, route_id, pending_url,
-          Referrer(url, blink::WebReferrerPolicyDefault), kSize));
-  DCHECK(pending_prerender_handle.get());
-  EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
-
+  // Schedule a pending prerender launched from the prerender.
+  DummyPrerenderContents* pending_prerender_contents =
+      prerender_manager()->CreateNextPrerenderContents(
+          pending_url,
+          ORIGIN_GWS_PRERENDER,
+          FINAL_STATUS_UNSUPPORTED_SCHEME);
+  prerender_link_manager()->OnAddPrerender(
+      child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
+      Referrer(url, blink::WebReferrerPolicyDefault),
+      kSize, route_id);
+  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
+  EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
+
+  // Use the referring prerender.
   EXPECT_TRUE(prerender_contents->prerendering_has_started());
   ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
 
-  EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
+  // The pending prerender still doesn't start.
+  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
+  EXPECT_FALSE(pending_prerender_contents->prerendering_has_started());
 }
 
 TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
@@ -747,18 +792,22 @@ TEST_F(PrerenderTest, CancelPendingPrerenderTest) {
 
   GURL pending_url("http://news.google.com/");
 
-  scoped_ptr<PrerenderHandle> pending_prerender_handle(
-      prerender_manager()->AddPrerenderFromLinkRelPrerender(
-          child_id, route_id, pending_url,
-          Referrer(url, blink::WebReferrerPolicyDefault), kSize));
-  CHECK(pending_prerender_handle.get());
-  EXPECT_FALSE(pending_prerender_handle->IsPrerendering());
+  // Schedule a pending prerender launched from the prerender.
+  prerender_link_manager()->OnAddPrerender(
+      child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
+      Referrer(url, blink::WebReferrerPolicyDefault),
+      kSize, route_id);
+  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
 
-  EXPECT_TRUE(prerender_contents->prerendering_has_started());
-
-  pending_prerender_handle.reset();
+  // Cancel the pending prerender.
+  prerender_link_manager()->OnCancelPrerender(child_id, last_prerender_id());
 
+  // Use the referring prerender.
+  EXPECT_TRUE(prerender_contents->prerendering_has_started());
   ASSERT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+
+  // The pending prerender doesn't start.
+  EXPECT_FALSE(LauncherHasRunningPrerender(child_id, last_prerender_id()));
 }
 
 // Tests that a PrerenderManager created for a browser session in the control
@@ -784,11 +833,40 @@ TEST_F(PrerenderTest, SourceRenderViewClosed) {
   prerender_manager()->CreateNextPrerenderContents(
       url,
       FINAL_STATUS_MANAGER_SHUTDOWN);
-  prerender_link_manager()->OnAddPrerender(100, GetNextPrerenderID(), url,
-                                           Referrer(), kSize, 200);
+  prerender_link_manager()->OnAddPrerender(
+      100, GetNextPrerenderID(), url, kDefaultRelTypes, Referrer(), kSize, 200);
   EXPECT_FALSE(LauncherHasRunningPrerender(100, last_prerender_id()));
 }
 
+// Tests that prerendering doesn't launch rel=next prerenders without the field
+// trial.
+TEST_F(PrerenderTest, NoRelNextByDefault) {
+  GURL url("http://www.google.com/");
+  prerender_manager()->CreateNextPrerenderContents(
+      url, FINAL_STATUS_MANAGER_SHUTDOWN);
+  DummyPrerenderContents* null = NULL;
+
+  prerender_link_manager()->OnAddPrerender(
+      kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
+      Referrer(), kSize, kDefaultRenderViewRouteId);
+  EXPECT_EQ(null, prerender_manager()->FindEntry(url));
+}
+
+// Tests that prerendering does launch rel=next prerenders with the field trial.
+TEST_F(PrerenderTest, RelNextByFieldTrial) {
+  ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("PrerenderRelNextTrial",
+                                                     "Yes"));
+  GURL url("http://www.google.com/");
+  DummyPrerenderContents* prerender_contents =
+      prerender_manager()->CreateNextPrerenderContents(
+          url, ORIGIN_LINK_REL_NEXT, FINAL_STATUS_USED);
+
+  prerender_link_manager()->OnAddPrerender(
+      kDefaultChildId, GetNextPrerenderID(), url, PrerenderRelTypeNext,
+      Referrer(), kSize, kDefaultRenderViewRouteId);
+  EXPECT_EQ(prerender_contents, prerender_manager()->FindAndUseEntry(url));
+}
+
 // Tests that prerendering is cancelled when we launch a second prerender of
 // the same target within a short time interval.
 TEST_F(PrerenderTest, RecentlyVisited) {
@@ -1344,10 +1422,9 @@ TEST_F(PrerenderTest, LinkManagerClearOnPendingAbandon) {
   ASSERT_TRUE(prerender_contents->GetRouteId(&route_id));
 
   GURL pending_url("http://www.neverlaunched.com");
-  prerender_link_manager()->OnAddPrerender(child_id,
-                                           GetNextPrerenderID(),
-                                           pending_url, content::Referrer(),
-                                           kSize, route_id);
+  prerender_link_manager()->OnAddPrerender(
+      child_id, GetNextPrerenderID(), pending_url, kDefaultRelTypes,
+      content::Referrer(), kSize, route_id);
   const int second_prerender_id = last_prerender_id();
 
   EXPECT_FALSE(IsEmptyPrerenderLinkManager());