bd8ba5b0a89f37e40af0e911094ae62e55b4807c
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefetch / prefetch_browsertest.cc
1 // Copyright 2013 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 "base/command_line.h"
6 #include "base/prefs/pref_service.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/common/prefetch_messages.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "content/public/browser/render_frame_host.h"
18 #include "content/public/browser/web_contents.h"
19 #include "content/public/test/browser_test_utils.h"
20 #include "net/url_request/url_request_filter.h"
21 #include "net/url_request/url_request_job.h"
22
23 using content::BrowserThread;
24
25 namespace {
26
27 const char kPrefetchPage[] = "files/prerender/simple_prefetch.html";
28
29 class PrefetchBrowserTestBase : public InProcessBrowserTest {
30  public:
31   explicit PrefetchBrowserTestBase(bool do_predictive_networking,
32                                    bool do_prefetch_field_trial)
33       : do_predictive_networking_(do_predictive_networking),
34         do_prefetch_field_trial_(do_prefetch_field_trial) {}
35
36   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
37     if (do_prefetch_field_trial_) {
38       command_line->AppendSwitchASCII(switches::kForceFieldTrials,
39                                       "Prefetch/ExperimentDisabled/");
40     } else {
41       command_line->AppendSwitchASCII(switches::kForceFieldTrials,
42                                       "Prefetch/ExperimentEnabled/");
43     }
44   }
45
46   virtual void SetUpOnMainThread() OVERRIDE {
47     browser()->profile()->GetPrefs()->SetBoolean(
48         prefs::kNetworkPredictionEnabled, do_predictive_networking_);
49   }
50
51   bool RunPrefetchExperiment(bool expect_success, Browser* browser) {
52     CHECK(test_server()->Start());
53     GURL url = test_server()->GetURL(kPrefetchPage);
54
55     const base::string16 expected_title =
56         expect_success ? base::ASCIIToUTF16("link onload")
57                        : base::ASCIIToUTF16("link onerror");
58     content::TitleWatcher title_watcher(
59         browser->tab_strip_model()->GetActiveWebContents(), expected_title);
60     ui_test_utils::NavigateToURL(browser, url);
61     return expected_title == title_watcher.WaitAndGetTitle();
62   }
63
64  private:
65   bool do_predictive_networking_;
66   bool do_prefetch_field_trial_;
67 };
68
69 class PrefetchBrowserTestPredictionOnExpOn : public PrefetchBrowserTestBase {
70  public:
71   PrefetchBrowserTestPredictionOnExpOn()
72       : PrefetchBrowserTestBase(true, true) {}
73 };
74
75 class PrefetchBrowserTestPredictionOnExpOff : public PrefetchBrowserTestBase {
76  public:
77   PrefetchBrowserTestPredictionOnExpOff()
78       : PrefetchBrowserTestBase(true, false) {}
79 };
80
81 class PrefetchBrowserTestPredictionOffExpOn : public PrefetchBrowserTestBase {
82  public:
83   PrefetchBrowserTestPredictionOffExpOn()
84       : PrefetchBrowserTestBase(false, true) {}
85 };
86
87 class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase {
88  public:
89   PrefetchBrowserTestPredictionOffExpOff()
90       : PrefetchBrowserTestBase(false, false) {}
91 };
92
93 // URLRequestJob (and associated handler) which hangs.
94 class HangingURLRequestJob : public net::URLRequestJob {
95  public:
96   HangingURLRequestJob(net::URLRequest* request,
97                        net::NetworkDelegate* network_delegate)
98       : net::URLRequestJob(request, network_delegate) {}
99
100   // net::URLRequestJob implementation
101   virtual void Start() OVERRIDE {}
102
103  private:
104   virtual ~HangingURLRequestJob() {}
105
106   DISALLOW_COPY_AND_ASSIGN(HangingURLRequestJob);
107 };
108
109 class HangingRequestInterceptor : public net::URLRequestInterceptor {
110  public:
111   explicit HangingRequestInterceptor(const base::Closure& callback)
112       : callback_(callback) {}
113
114   virtual ~HangingRequestInterceptor() {}
115
116   virtual net::URLRequestJob* MaybeInterceptRequest(
117       net::URLRequest* request,
118       net::NetworkDelegate* network_delegate) const OVERRIDE {
119     if (!callback_.is_null())
120       BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback_);
121     return new HangingURLRequestJob(request, network_delegate);
122   }
123
124  private:
125   base::Closure callback_;
126 };
127
128 void CreateHangingRequestInterceptorOnIO(const GURL& url,
129                                          base::Closure callback) {
130   CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
131   scoped_ptr<net::URLRequestInterceptor> never_respond_handler(
132       new HangingRequestInterceptor(callback));
133   net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
134       url, never_respond_handler.Pass());
135 }
136
137 // Privacy option is on, experiment is on.  Prefetch should succeed.
138 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) {
139   EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
140 }
141
142 // Privacy option is on, experiment is off.  Prefetch should be dropped.
143 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff, PredOnExpOff) {
144   EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
145 }
146
147 // Privacy option is off, experiment is on.  Prefetch should be dropped.
148 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOffExpOn, PredOffExpOn) {
149   EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
150 }
151
152 // Privacy option is off, experiment is off.  Prefetch should be dropped.
153 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOffExpOff, PredOffExpOff) {
154   EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
155 }
156
157 // Bug 339909: When in incognito mode the browser crashed due to an
158 // uninitialized preference member. Verify that it no longer does.
159 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff, IncognitoTest) {
160   Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
161   Browser* incognito_browser = new Browser(
162       Browser::CreateParams(incognito_profile, browser()->host_desktop_type()));
163
164   // Navigate just to have a tab in this window, otherwise there is no
165   // WebContents for the incognito browser.
166   ui_test_utils::OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
167
168   EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser));
169 }
170
171 // This test will verify the following:
172 // - that prefetches from the browser are actually launched
173 // - if a prefetch is in progress, but the originating renderer is destroyed,
174 //   that the pending prefetch request is cleaned up cleanly and does not
175 //   result in a crash.
176 IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff,
177                        PrefetchFromBrowser) {
178   const GURL kHangingUrl("http://hanging-url.com");
179   base::RunLoop loop_;
180   BrowserThread::PostTask(BrowserThread::IO,
181                           FROM_HERE,
182                           base::Bind(&CreateHangingRequestInterceptorOnIO,
183                                      kHangingUrl,
184                                      loop_.QuitClosure()));
185   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
186   content::RenderFrameHost* rfh =
187       browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();
188   rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), kHangingUrl));
189   loop_.Run();
190 }
191
192 }  // namespace