1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 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"
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/timer.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/unittest_test_server.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/tools/test_shell/simple_resource_loader_bridge.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/tools/test_shell/test_shell_test.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebFrame;
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing WebKit::WebURLRequest;
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLResponse;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::ResourceFetcher;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::ResourceFetcherWithTimeout;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ResourceFetcherTests : public TestShellTest {
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick protected:
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UnittestTestServer test_server_;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kMaxWaitTimeMs = 5000;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FetcherDelegate {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FetcherDelegate()
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      : completed_(false),
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        timed_out_(false) {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Start a repeating timer waiting for the download to complete.  The
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // callback has to be a static function, so we hold on to our instance.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FetcherDelegate::instance_ = this;
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    StartTimer();
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceFetcher::Callback* NewCallback() {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ::NewCallback(this, &FetcherDelegate::OnURLFetchComplete);
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void OnURLFetchComplete(const WebURLResponse& response,
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  const std::string& data) {
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    response_ = response;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_ = data;
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    completed_ = true;
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    timer_.Stop();
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Quit();
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool completed() const { return completed_; }
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool timed_out() const { return timed_out_; }
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data() const { return data_; }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const WebURLResponse& response() const { return response_; }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the request to complete or timeout.  We use a loop here b/c the
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // testing infrastructure (test_shell) can generate spurious calls to the
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // MessageLoop's Quit method.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void WaitForResponse() {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    while (!completed() && !timed_out())
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MessageLoop::current()->Run();
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void StartTimer() {
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    timer_.Start(base::TimeDelta::FromMilliseconds(kMaxWaitTimeMs),
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 this,
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                 &FetcherDelegate::TimerFired);
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TimerFired() {
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(completed_);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    timed_out_ = true;
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    MessageLoop::current()->Quit();
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    FAIL() << "fetch timed out";
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static FetcherDelegate* instance_;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  base::OneShotTimer<FetcherDelegate> timer_;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool completed_;
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool timed_out_;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebURLResponse response_;
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string data_;
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFetcherDelegate* FetcherDelegate::instance_ = NULL;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test a fetch from the test server.
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Flaky, http://crbug.com/51622.
98731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDownload) {
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(test_server_.GetURL("files/test_shell/index.html"));
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(delegate->completed());
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->response().httpStatusCode(), 200);
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string text = delegate->data();
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(text.find("What is this page?") != std::string::npos);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test 404 response.
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  url = test_server_.GetURL("files/thisfiledoesntexist.html");
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate.reset(new FetcherDelegate);
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetcher.reset(new ResourceFetcher(url, frame,
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    WebURLRequest::TargetIsMainFrame,
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                    delegate->NewCallback()));
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(delegate->completed());
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->response().httpStatusCode(), 404);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Flaky, http://crbug.com/51622.
130731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDidFail) {
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to fetch a page on a site that doesn't exist.
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL url("http://localhost:1339/doesnotexist");
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcher(
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url, frame, WebURLRequest::TargetIsMainFrame, delegate->NewCallback()));
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we fail, we still call the Delegate callback but we pass in empty
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // values.
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->completed());
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->response().isNull());
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->data(), std::string());
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(delegate->timed_out());
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(ResourceFetcherTests, ResourceFetcherTimeout) {
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(test_server_.Start());
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WebFrame* frame = test_shell_->webView()->mainFrame();
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Grab a page that takes at least 1 sec to respond, but set the fetcher to
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // timeout in 0 sec.
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GURL url(test_server_.GetURL("slow?1"));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<FetcherDelegate> delegate(new FetcherDelegate);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout(
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url, frame, WebURLRequest::TargetIsMainFrame,
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      0, delegate->NewCallback()));
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delegate->WaitForResponse();
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we timeout, we still call the Delegate callback but we pass in empty
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // values.
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->completed());
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(delegate->response().isNull());
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(delegate->data(), std::string());
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(delegate->timed_out());
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass EvilFetcherDelegate : public FetcherDelegate {
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void SetFetcher(ResourceFetcher* fetcher) {
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    fetcher_.reset(fetcher);
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void OnURLFetchComplete(const WebURLResponse& response,
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          const std::string& data) {
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Destroy the ResourceFetcher here.  We are testing that upon returning
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // to the ResourceFetcher that it does not crash.
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    fetcher_.reset();
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    FetcherDelegate::OnURLFetchComplete(response, data);
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private:
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<ResourceFetcher> fetcher_;
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen};
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(ResourceFetcherTests, ResourceFetcherDeletedInCallback) {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(test_server_.Start());
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WebFrame* frame = test_shell_->webView()->mainFrame();
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Grab a page that takes at least 1 sec to respond, but set the fetcher to
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // timeout in 0 sec.
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(test_server_.GetURL("slow?1"));
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<EvilFetcherDelegate> delegate(new EvilFetcherDelegate);
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<ResourceFetcher> fetcher(new ResourceFetcherWithTimeout(
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      url, frame, WebURLRequest::TargetIsMainFrame,
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      0, delegate->NewCallback()));
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delegate->SetFetcher(fetcher.release());
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delegate->WaitForResponse();
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(delegate->timed_out());
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
211