resource_fetcher_unittest.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/resource_fetcher.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/message_loop.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "third_party/WebKit/WebKit/chromium/public/WebView.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/unittest_test_server.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/tools/test_shell/test_shell_test.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(TOOLKIT_USES_GTK)
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebFrame;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLResponse;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::ResourceFetcher;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::ResourceFetcherWithTimeout;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ResourceFetcherTests : public TestShellTest {
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick protected:
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UnittestTestServer test_server_;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kMaxWaitTimeMs = 5000;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kWaitIntervalMs = 100;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FetcherDelegate {
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FetcherDelegate()
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : timer_id_(0), completed_(false), time_elapsed_ms_(0) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Start a repeating timer waiting for the download to complete.  The
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // callback has to be a static function, so we hold on to our instance.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FetcherDelegate::instance_ = this;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CreateTimer(kWaitIntervalMs);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceFetcher::Callback* NewCallback() {
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ::NewCallback(this, &FetcherDelegate::OnURLFetchComplete);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void OnURLFetchComplete(const WebURLResponse& response,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const std::string& data) {
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response_ = response;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_ = data;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    completed_ = true;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DestroyTimer();
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Quit();
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool completed() const { return completed_; }
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool timed_out() const { return time_elapsed_ms_ > kMaxWaitTimeMs; }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int time_elapsed_ms() const { return time_elapsed_ms_; }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data() const { return data_; }
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const WebURLResponse& response() const { return response_; }
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the request to complete or timeout.  We use a loop here b/c the
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // testing infrastructure (test_shell) can generate spurious calls to the
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // MessageLoop's Quit method.
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void WaitForResponse() {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (!completed() && !timed_out())
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->Run();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void CreateTimer(int interval) {
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timer_id_ = ::SetTimer(NULL, NULL, interval,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           &FetcherDelegate::TimerCallback);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timer_id_ = g_timeout_add(interval, &FetcherDelegate::TimerCallback, NULL);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // CFAbsoluteTime is in seconds and |interval| is in ms, so make sure we
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // keep the units correct.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CFTimeInterval interval_in_seconds = static_cast<double>(interval) / 1000.0;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CFAbsoluteTime fire_date =
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CFAbsoluteTimeGetCurrent() + interval_in_seconds;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    timer_id_ = CFRunLoopTimerCreate(NULL, fire_date, interval_in_seconds, 0,
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     0, FetcherDelegate::TimerCallback, NULL);
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer_id_, kCFRunLoopCommonModes);
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void DestroyTimer() {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ::KillTimer(NULL, timer_id_);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    g_source_remove(timer_id_);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer_id_,
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         kCFRunLoopCommonModes);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CFRelease(timer_id_);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Static timer callback, just passes through to instance version.
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static VOID CALLBACK TimerCallback(HWND hwnd, UINT msg, UINT_PTR timer_id,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     DWORD ms) {
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    instance_->TimerFired();
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static gboolean TimerCallback(gpointer data) {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    instance_->TimerFired();
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TimerCallback(CFRunLoopTimerRef timer, void* info) {
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    instance_->TimerFired();
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TimerFired() {
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(completed_);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (timed_out()) {
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DestroyTimer();
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->Quit();
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FAIL() << "fetch timed out";
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return;
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    time_elapsed_ms_ += kWaitIntervalMs;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static FetcherDelegate* instance_;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UINT_PTR timer_id_;
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(TOOLKIT_USES_GTK)
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  guint timer_id_;
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CFRunLoopTimerRef timer_id_;
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool completed_;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int time_elapsed_ms_;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response_;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data_;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFetcherDelegate* FetcherDelegate::instance_ = NULL;
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test a fetch from the test server.
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Flaky, http://crbug.com/51622.
153731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDownload) {
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(test_server_.GetURL("files/test_shell/index.html"));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url, frame, delegate->NewCallback()));
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(delegate->completed());
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->response().httpStatusCode(), 200);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string text = delegate->data();
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(text.find("What is this page?") != std::string::npos);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test 404 response.
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url = test_server_.GetURL("files/thisfiledoesntexist.html");
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.reset(new FetcherDelegate);
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  fetcher.reset(new ResourceFetcher(url, frame, delegate->NewCallback()));
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(delegate->completed());
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->response().httpStatusCode(), 404);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Flaky, http://crbug.com/51622.
183731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDidFail) {
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to fetch a page on a site that doesn't exist.
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("http://localhost:1339/doesnotexist");
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url, frame, delegate->NewCallback()));
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we fail, we still call the Delegate callback but we pass in empty
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // values.
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->completed());
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->response().isNull());
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->data(), std::string());
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->time_elapsed_ms() < kMaxWaitTimeMs);
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab a page that takes at least 1 sec to respond, but set the fetcher to
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // timeout in 0 sec.
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(test_server_.GetURL("slow?1"));
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout(
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url, frame, 0, delegate->NewCallback()));
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we timeout, we still call the Delegate callback but we pass in empty
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // values.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->completed());
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->response().isNull());
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->data(), std::string());
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->time_elapsed_ms() < kMaxWaitTimeMs);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
227