Index: chrome/browser/prefetch/prefetch_browsertest.cc |
diff --git a/chrome/browser/prefetch/prefetch_browsertest.cc b/chrome/browser/prefetch/prefetch_browsertest.cc |
index a870be6ffe72a269d4fb5bddb755f2206f67826c..bd24ad21bd61570f3a1efb0cc1e0dada25206071 100644 |
--- a/chrome/browser/prefetch/prefetch_browsertest.cc |
+++ b/chrome/browser/prefetch/prefetch_browsertest.cc |
@@ -4,15 +4,23 @@ |
#include "base/command_line.h" |
#include "base/prefs/pref_service.h" |
+#include "base/run_loop.h" |
#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/common/pref_names.h" |
+#include "chrome/common/prefetch_messages.h" |
#include "chrome/test/base/in_process_browser_test.h" |
#include "chrome/test/base/ui_test_utils.h" |
+#include "content/public/browser/render_frame_host.h" |
+#include "content/public/browser/web_contents.h" |
#include "content/public/test/browser_test_utils.h" |
+#include "net/url_request/url_request_filter.h" |
+#include "net/url_request/url_request_job.h" |
+ |
+using content::BrowserThread; |
namespace { |
@@ -27,13 +35,11 @@ class PrefetchBrowserTestBase : public InProcessBrowserTest { |
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
if (do_prefetch_field_trial_) { |
- command_line->AppendSwitchASCII( |
- switches::kForceFieldTrials, |
- "Prefetch/ExperimentYes/"); |
+ command_line->AppendSwitchASCII(switches::kForceFieldTrials, |
+ "Prefetch/ExperimentYes/"); |
} else { |
- command_line->AppendSwitchASCII( |
- switches::kForceFieldTrials, |
- "Prefetch/ExperimentNo/"); |
+ command_line->AppendSwitchASCII(switches::kForceFieldTrials, |
+ "Prefetch/ExperimentNo/"); |
} |
} |
@@ -84,6 +90,50 @@ class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase { |
: PrefetchBrowserTestBase(false, false) {} |
}; |
+// URLRequestJob (and associated handler) which hangs. |
+class HangingURLRequestJob : public net::URLRequestJob { |
+ public: |
+ HangingURLRequestJob(net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) |
+ : net::URLRequestJob(request, network_delegate) {} |
+ |
+ // net::URLRequestJob implementation |
+ virtual void Start() OVERRIDE {} |
+ |
+ private: |
+ virtual ~HangingURLRequestJob() {} |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HangingURLRequestJob); |
+}; |
+ |
+class HangingRequestInterceptor : public net::URLRequestInterceptor { |
+ public: |
+ explicit HangingRequestInterceptor(const base::Closure& callback) |
+ : callback_(callback) {} |
+ |
+ virtual ~HangingRequestInterceptor() {} |
+ |
+ virtual net::URLRequestJob* MaybeInterceptRequest( |
+ net::URLRequest* request, |
+ net::NetworkDelegate* network_delegate) const OVERRIDE { |
+ if (!callback_.is_null()) |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback_); |
+ return new HangingURLRequestJob(request, network_delegate); |
+ } |
+ |
+ private: |
+ base::Closure callback_; |
+}; |
+ |
+void CreateHangingRequestInterceptorOnIO(const GURL& url, |
+ base::Closure callback) { |
+ CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ scoped_ptr<net::URLRequestInterceptor> never_respond_handler( |
+ new HangingRequestInterceptor(callback)); |
+ net::URLRequestFilter::GetInstance()->AddUrlInterceptor( |
+ url, never_respond_handler.Pass()); |
+} |
+ |
// Privacy option is on, experiment is on. Prefetch should succeed. |
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) { |
EXPECT_TRUE(RunPrefetchExperiment(true, browser())); |
@@ -118,5 +168,25 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, IncognitoTest) { |
EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser)); |
} |
-} // namespace |
+// This test will verify the following: |
+// - that prefetches from the browser are actually launched |
+// - if a prefetch is in progress, but the originating renderer is destroyed, |
+// that the pending prefetch request is cleaned up cleanly and does not |
+// result in a crash. |
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, |
+ PrefetchFromBrowser) { |
+ const GURL kHangingUrl("http://hanging-url.com"); |
+ base::RunLoop loop_; |
+ BrowserThread::PostTask(BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&CreateHangingRequestInterceptorOnIO, |
+ kHangingUrl, |
+ loop_.QuitClosure())); |
+ ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); |
+ content::RenderFrameHost* rfh = |
+ browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); |
+ rfh->Send(new PrefetchMsg_Prefetch(rfh->GetRoutingID(), kHangingUrl)); |
+ loop_.Run(); |
+} |
+} // namespace |