blob: ec074d754fb97b4d8ca80df67801e3195028e4f1 [file] [log] [blame]
Mike Frysinger8155d082012-04-06 15:23:18 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
rspangler@google.com49fdf182009-10-10 00:57:34 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07005#include <netinet/in.h>
6#include <netinet/ip.h>
7#include <sys/socket.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +00008#include <unistd.h>
Darin Petkov41c2fcf2010-08-25 13:14:48 -07009
adlr@google.comc98a7ed2009-12-04 18:54:03 +000010#include <string>
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070011#include <utility>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000012#include <vector>
Darin Petkov41c2fcf2010-08-25 13:14:48 -070013
Andrew de los Reyes45168102010-11-22 11:13:50 -080014#include <base/logging.h>
Chris Masoned903c3b2011-05-12 15:35:46 -070015#include <base/memory/scoped_ptr.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070016#include <base/strings/string_util.h>
17#include <base/strings/stringprintf.h>
18#include <base/time/time.h>
Jay Srinivasan43488792012-06-19 00:25:31 -070019#include <chromeos/dbus/service_constants.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080020#include <glib.h>
21#include <gtest/gtest.h>
22
Gilad Arnold5bb4c902014-04-10 12:32:13 -070023#include "update_engine/fake_system_state.h"
Gilad Arnold9bedeb52011-11-17 16:19:57 -080024#include "update_engine/http_common.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000025#include "update_engine/libcurl_http_fetcher.h"
26#include "update_engine/mock_http_fetcher.h"
Andrew de los Reyes819fef22010-12-17 11:33:58 -080027#include "update_engine/multi_range_http_fetcher.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080028#include "update_engine/proxy_resolver.h"
Jay Srinivasan08fce042012-06-07 16:31:01 -070029#include "update_engine/utils.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000030
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070031using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080032using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000033using std::string;
34using std::vector;
35
Gilad Arnold8e3f1262013-01-08 14:59:54 -080036using base::TimeDelta;
Jay Srinivasan43488792012-06-19 00:25:31 -070037using testing::DoAll;
38using testing::Return;
Alex Deymoc4acdf42014-05-28 21:07:10 -070039using testing::SetArgumentPointee;
40using testing::_;
Jay Srinivasan43488792012-06-19 00:25:31 -070041
Gilad Arnold9bedeb52011-11-17 16:19:57 -080042namespace {
43
44const int kBigLength = 100000;
45const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080046const int kFlakyTruncateLength = 29000;
47const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080048const int kFlakySleepSecs = 10;
49
50} // namespace
51
rspangler@google.com49fdf182009-10-10 00:57:34 +000052namespace chromeos_update_engine {
53
Gilad Arnold9bedeb52011-11-17 16:19:57 -080054static const char *kUnusedUrl = "unused://unused";
55
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070056static inline string LocalServerUrlForPath(in_port_t port,
57 const string& path) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070058 string port_str = (port ? base::StringPrintf(":%hu", port) : "");
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070059 return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
60 path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000061}
62
Gilad Arnold9bedeb52011-11-17 16:19:57 -080063//
64// Class hierarchy for HTTP server implementations.
65//
66
67class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000068 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080069 // This makes it an abstract class (dirty but works).
70 virtual ~HttpServer() = 0;
71
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070072 virtual in_port_t GetPort() const {
73 return 0;
74 }
75
rspangler@google.com49fdf182009-10-10 00:57:34 +000076 bool started_;
77};
78
Gilad Arnold9bedeb52011-11-17 16:19:57 -080079HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000080
Gilad Arnold9bedeb52011-11-17 16:19:57 -080081
82class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000083 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080084 NullHttpServer() {
85 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +000086 }
rspangler@google.com49fdf182009-10-10 00:57:34 +000087};
88
Gilad Arnold9bedeb52011-11-17 16:19:57 -080089
90class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000091 public:
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070092 PythonHttpServer() : pid_(-1), port_(0) {
rspangler@google.com49fdf182009-10-10 00:57:34 +000093 started_ = false;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070094
95 // Spawn the server process.
96 gchar *argv[] = {
97 const_cast<gchar*>("./test_http_server"),
Alex Vakulenko88b591f2014-08-28 16:48:57 -070098 nullptr
99 };
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700100 GError *err;
101 gint server_stdout = -1;
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700102 if (!g_spawn_async_with_pipes(nullptr, argv, nullptr,
103 G_SPAWN_DO_NOT_REAP_CHILD, nullptr, nullptr,
104 &pid_, nullptr, &server_stdout, nullptr,
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700105 &err)) {
106 LOG(ERROR) << "failed to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000107 return;
108 }
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700109 CHECK_GT(pid_, 0);
110 CHECK_GE(server_stdout, 0);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700111 LOG(INFO) << "started http server with pid " << pid_;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700112
113 // Wait for server to begin accepting connections, obtain its port.
114 char line[80];
115 const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
116 CHECK_GT(sizeof(line), listening_msg_prefix_len);
117 int line_len = read(server_stdout, line, sizeof(line) - 1);
118 if (line_len <= static_cast<int>(listening_msg_prefix_len)) {
119 if (line_len < 0) {
120 LOG(ERROR) << "error reading http server stdout: "
121 << strerror(errno);
122 } else {
123 LOG(ERROR) << "server output too short";
124 }
125 Terminate(true);
126 return;
127 }
128
129 line[line_len] = '\0';
130 CHECK_EQ(strstr(line, kServerListeningMsgPrefix), line);
131 const char* listening_port_str = line + listening_msg_prefix_len;
132 char* end_ptr;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700133 long raw_port = strtol(listening_port_str, // NOLINT(runtime/int)
134 &end_ptr, 10);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700135 CHECK(!*end_ptr || *end_ptr == '\n');
136 port_ = static_cast<in_port_t>(raw_port);
137 CHECK_GT(port_, 0);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700138 started_ = true;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700139 LOG(INFO) << "server running, listening on port " << port_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700140 LOG(INFO) << "gdb attach now!";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000141 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800142
rspangler@google.com49fdf182009-10-10 00:57:34 +0000143 ~PythonHttpServer() {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700144 // If there's no process, do nothing.
145 if (pid_ == -1)
rspangler@google.com49fdf182009-10-10 00:57:34 +0000146 return;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700147
148 // If server is responsive, request that it gracefully terminate.
149 bool do_kill = false;
150 if (started_) {
151 LOG(INFO) << "running wget to exit";
152 if (system((string("wget -t 1 --output-document=/dev/null ") +
153 LocalServerUrlForPath(port_, "/quitquitquit")).c_str())) {
154 LOG(WARNING) << "wget failed, resorting to brute force";
155 do_kill = true;
156 }
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700157 }
158
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700159 // Server not responding or wget failed, kill the process.
160 Terminate(do_kill);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000161 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800162
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700163 virtual in_port_t GetPort() const {
164 return port_;
165 }
166
167 private:
168 void Terminate(bool do_kill) {
169 ASSERT_GT(pid_, 0);
170
171 if (do_kill) {
172 LOG(INFO) << "terminating (SIGKILL) server process with pid " << pid_;
173 kill(pid_, SIGKILL);
174 }
175
176 LOG(INFO) << "waiting for http server with pid " << pid_ << " to terminate";
177 int status;
178 pid_t killed_pid = waitpid(pid_, &status, 0);
179 ASSERT_EQ(killed_pid, pid_);
180 LOG(INFO) << "http server with pid " << pid_
181 << " terminated with status " << status;
182 pid_ = -1;
183 }
184
185 static const char* kServerListeningMsgPrefix;
186
rspangler@google.com49fdf182009-10-10 00:57:34 +0000187 GPid pid_;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700188 in_port_t port_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000189};
190
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700191const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
192
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800193//
194// Class hierarchy for HTTP fetcher test wrappers.
195//
196
197class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000198 public:
Chris Sosa77f79e82014-06-02 18:16:24 -0700199 AnyHttpFetcherTest() {}
Alex Deymoc4acdf42014-05-28 21:07:10 -0700200 virtual ~AnyHttpFetcherTest() {}
Jay Srinivasan43488792012-06-19 00:25:31 -0700201
Alex Deymo7984bf02014-04-02 20:41:57 -0700202 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800203 HttpFetcher* NewLargeFetcher() {
204 return NewLargeFetcher(1);
205 }
206
207 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
208 HttpFetcher* NewSmallFetcher() {
209 return NewSmallFetcher(1);
210 }
211
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700212 virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
213 virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
214 virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800215
216 virtual bool IsMock() const = 0;
217 virtual bool IsMulti() const = 0;
218
219 virtual void IgnoreServerAborting(HttpServer* server) const {}
220
221 virtual HttpServer *CreateServer() = 0;
222
223 protected:
224 DirectProxyResolver proxy_resolver_;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700225 FakeSystemState fake_system_state_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800226};
227
228class MockHttpFetcherTest : public AnyHttpFetcherTest {
229 public:
230 // Necessary to unhide the definition in the base class.
231 using AnyHttpFetcherTest::NewLargeFetcher;
232 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
233 vector<char> big_data(1000000);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700234 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800235 proxy_resolver_.set_num_proxies(num_proxies);
236 return new MockHttpFetcher(
237 big_data.data(),
238 big_data.size(),
239 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
240 }
241
242 // Necessary to unhide the definition in the base class.
243 using AnyHttpFetcherTest::NewSmallFetcher;
244 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700245 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800246 proxy_resolver_.set_num_proxies(num_proxies);
247 return new MockHttpFetcher(
248 "x",
249 1,
250 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
251 }
252
253 virtual bool IsMock() const { return true; }
254 virtual bool IsMulti() const { return false; }
255
256 virtual HttpServer *CreateServer() {
257 return new NullHttpServer;
258 }
259};
260
261class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
262 public:
263 // Necessary to unhide the definition in the base class.
264 using AnyHttpFetcherTest::NewLargeFetcher;
265 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700266 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800267 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800268 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700269 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700270 &fake_system_state_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700271 // Speed up test execution.
272 ret->set_idle_seconds(1);
273 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700274 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000275 return ret;
276 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800277
278 // Necessary to unhide the definition in the base class.
279 using AnyHttpFetcherTest::NewSmallFetcher;
280 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
281 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000282 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800283
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700284 virtual string BigUrl(in_port_t port) const {
285 return LocalServerUrlForPath(port,
286 base::StringPrintf("/download/%d",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800287 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000288 }
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700289 virtual string SmallUrl(in_port_t port) const {
290 return LocalServerUrlForPath(port, "/foo");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000291 }
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700292 virtual string ErrorUrl(in_port_t port) const {
293 return LocalServerUrlForPath(port, "/error");
Gilad Arnold48085ba2011-11-16 09:36:08 -0800294 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800295
296 virtual bool IsMock() const { return false; }
297 virtual bool IsMulti() const { return false; }
298
299 virtual void IgnoreServerAborting(HttpServer* server) const {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700300 // Nothing to do.
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700301 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800302
303 virtual HttpServer *CreateServer() {
304 return new PythonHttpServer;
305 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000306};
307
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800308class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700309 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800310 // Necessary to unhide the definition in the base class.
311 using AnyHttpFetcherTest::NewLargeFetcher;
312 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700313 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800314 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800315 ProxyResolver* resolver =
316 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700317 MultiRangeHttpFetcher *ret =
318 new MultiRangeHttpFetcher(
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700319 new LibcurlHttpFetcher(resolver, &fake_system_state_));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800320 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800321 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700322 // Speed up test execution.
323 ret->set_idle_seconds(1);
324 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700325 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700326 return ret;
327 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800328
329 // Necessary to unhide the definition in the base class.
330 using AnyHttpFetcherTest::NewSmallFetcher;
331 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) {
332 return NewLargeFetcher(num_proxies);
333 }
334
335 virtual bool IsMulti() const { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700336};
337
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800338
339//
340// Infrastructure for type tests of HTTP fetcher.
341// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
342//
343
344// Fixture class template. We use an explicit constraint to guarantee that it
345// can only be instantiated with an AnyHttpFetcherTest type, see:
346// http://www2.research.att.com/~bs/bs_faq2.html#constraints
347template <typename T>
348class HttpFetcherTest : public ::testing::Test {
349 public:
350 T test_;
351
352 private:
353 static void TypeConstraint(T *a) {
354 AnyHttpFetcherTest *b = a;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700355 if (b == 0) // Silence compiler warning of unused variable.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700356 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800357 }
358};
359
360// Test case types list.
361typedef ::testing::Types<LibcurlHttpFetcherTest,
362 MockHttpFetcherTest,
363 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000364TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
365
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800366
rspangler@google.com49fdf182009-10-10 00:57:34 +0000367namespace {
368class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000369 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800370 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800371 is_expect_error_(false), times_transfer_complete_called_(0),
372 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
373
Alex Deymof9c59992014-04-02 21:16:59 -0700374 virtual void ReceivedBytes(HttpFetcher* /* fetcher */,
375 const char* /* bytes */, int /* length */) {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800376 // Update counters
377 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000378 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800379
rspangler@google.com49fdf182009-10-10 00:57:34 +0000380 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800381 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800382 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800383 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800384 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000385 g_main_loop_quit(loop_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800386
387 // Update counter
388 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000389 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800390
Darin Petkov9ce452b2010-11-17 14:33:28 -0800391 virtual void TransferTerminated(HttpFetcher* fetcher) {
392 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800393 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800394 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800395
rspangler@google.com49fdf182009-10-10 00:57:34 +0000396 GMainLoop* loop_;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800397
398 // Are we expecting an error response? (default: no)
399 bool is_expect_error_;
400
401 // Counters for callback invocations.
402 int times_transfer_complete_called_;
403 int times_transfer_terminated_called_;
404 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000405};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000406
407struct StartTransferArgs {
408 HttpFetcher *http_fetcher;
409 string url;
410};
411
412gboolean StartTransfer(gpointer data) {
413 StartTransferArgs *args = reinterpret_cast<StartTransferArgs*>(data);
414 args->http_fetcher->BeginTransfer(args->url);
415 return FALSE;
416}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700417} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000418
419TYPED_TEST(HttpFetcherTest, SimpleTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700420 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000421 {
422 HttpFetcherTestDelegate delegate;
423 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800424 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000425 fetcher->set_delegate(&delegate);
426
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800427 scoped_ptr<HttpServer> server(this->test_.CreateServer());
428 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000429
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700430 StartTransferArgs start_xfer_args = {
431 fetcher.get(), this->test_.SmallUrl(server->GetPort())};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000432
433 g_timeout_add(0, StartTransfer, &start_xfer_args);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000434 g_main_loop_run(loop);
435 }
436 g_main_loop_unref(loop);
437}
438
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700439TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700440 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700441 {
442 HttpFetcherTestDelegate delegate;
443 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800444 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700445 fetcher->set_delegate(&delegate);
446
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800447 scoped_ptr<HttpServer> server(this->test_.CreateServer());
448 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700449
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700450 StartTransferArgs start_xfer_args = {
451 fetcher.get(), this->test_.BigUrl(server->GetPort())};
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700452
453 g_timeout_add(0, StartTransfer, &start_xfer_args);
454 g_main_loop_run(loop);
455 }
456 g_main_loop_unref(loop);
457}
458
Gilad Arnold48085ba2011-11-16 09:36:08 -0800459// Issue #9648: when server returns an error HTTP response, the fetcher needs to
460// terminate transfer prematurely, rather than try to process the error payload.
461TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800462 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800463 return;
464 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
465 {
466 HttpFetcherTestDelegate delegate;
467 delegate.loop_ = loop;
468
469 // Delegate should expect an error response.
470 delegate.is_expect_error_ = true;
471
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800472 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800473 fetcher->set_delegate(&delegate);
474
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800475 scoped_ptr<HttpServer> server(this->test_.CreateServer());
476 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800477
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800478 StartTransferArgs start_xfer_args = {
479 fetcher.get(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700480 this->test_.ErrorUrl(server->GetPort())
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800481 };
Gilad Arnold48085ba2011-11-16 09:36:08 -0800482
483 g_timeout_add(0, StartTransfer, &start_xfer_args);
484 g_main_loop_run(loop);
485
486 // Make sure that no bytes were received.
487 CHECK_EQ(delegate.times_received_bytes_called_, 0);
Mike Frysinger0f9547d2012-02-16 12:11:37 -0500488 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800489
490 // Make sure that transfer completion was signaled once, and no termination
491 // was signaled.
492 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
493 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
494 }
495 g_main_loop_unref(loop);
496}
497
rspangler@google.com49fdf182009-10-10 00:57:34 +0000498namespace {
499class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
500 public:
501 virtual void ReceivedBytes(HttpFetcher* fetcher,
Alex Deymof9c59992014-04-02 21:16:59 -0700502 const char* /* bytes */, int /* length */) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000503 CHECK(!paused_);
504 paused_ = true;
505 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000506 }
507 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
508 g_main_loop_quit(loop_);
509 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800510 virtual void TransferTerminated(HttpFetcher* fetcher) {
511 ADD_FAILURE();
512 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000513 void Unpause() {
514 CHECK(paused_);
515 paused_ = false;
516 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000517 }
518 bool paused_;
519 HttpFetcher* fetcher_;
520 GMainLoop* loop_;
521};
522
523gboolean UnpausingTimeoutCallback(gpointer data) {
524 PausingHttpFetcherTestDelegate *delegate =
525 reinterpret_cast<PausingHttpFetcherTestDelegate*>(data);
526 if (delegate->paused_)
527 delegate->Unpause();
528 return TRUE;
529}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700530} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000531
532TYPED_TEST(HttpFetcherTest, PauseTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700533 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000534 {
535 PausingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800536 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000537 delegate.paused_ = false;
538 delegate.loop_ = loop;
539 delegate.fetcher_ = fetcher.get();
540 fetcher->set_delegate(&delegate);
541
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800542 scoped_ptr<HttpServer> server(this->test_.CreateServer());
543 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800544
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800545 guint callback_id = g_timeout_add(kHttpResponseInternalServerError,
546 UnpausingTimeoutCallback, &delegate);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700547 fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000548
549 g_main_loop_run(loop);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800550 g_source_remove(callback_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000551 }
552 g_main_loop_unref(loop);
553}
554
555namespace {
556class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
557 public:
558 virtual void ReceivedBytes(HttpFetcher* fetcher,
559 const char* bytes, int length) {}
560 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800561 ADD_FAILURE(); // We should never get here
rspangler@google.com49fdf182009-10-10 00:57:34 +0000562 g_main_loop_quit(loop_);
563 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800564 virtual void TransferTerminated(HttpFetcher* fetcher) {
565 EXPECT_EQ(fetcher, fetcher_.get());
566 EXPECT_FALSE(once_);
567 EXPECT_TRUE(callback_once_);
568 callback_once_ = false;
Alex Deymoc4acdf42014-05-28 21:07:10 -0700569 // The fetcher could have a callback scheduled on the ProxyResolver that
570 // can fire after this callback. We wait until the end of the test to
571 // delete the fetcher.
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800572 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000573 void TerminateTransfer() {
574 CHECK(once_);
575 once_ = false;
576 fetcher_->TerminateTransfer();
577 }
578 void EndLoop() {
579 g_main_loop_quit(loop_);
580 }
581 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800582 bool callback_once_;
583 scoped_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000584 GMainLoop* loop_;
585};
586
587gboolean AbortingTimeoutCallback(gpointer data) {
588 AbortingHttpFetcherTestDelegate *delegate =
589 reinterpret_cast<AbortingHttpFetcherTestDelegate*>(data);
590 if (delegate->once_) {
591 delegate->TerminateTransfer();
592 return TRUE;
593 } else {
594 delegate->EndLoop();
595 return FALSE;
596 }
597}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700598} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000599
600TYPED_TEST(HttpFetcherTest, AbortTest) {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700601 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000602 {
603 AbortingHttpFetcherTestDelegate delegate;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800604 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000605 delegate.once_ = true;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800606 delegate.callback_once_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000607 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800608 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000609
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800610 scoped_ptr<HttpServer> server(this->test_.CreateServer());
611 this->test_.IgnoreServerAborting(server.get());
612 ASSERT_TRUE(server->started_);
613
rspangler@google.com49fdf182009-10-10 00:57:34 +0000614 GSource* timeout_source_;
615 timeout_source_ = g_timeout_source_new(0); // ms
616 g_source_set_callback(timeout_source_, AbortingTimeoutCallback, &delegate,
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700617 nullptr);
618 g_source_attach(timeout_source_, nullptr);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700619 delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000620
621 g_main_loop_run(loop);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800622 CHECK(!delegate.once_);
623 CHECK(!delegate.callback_once_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000624 g_source_destroy(timeout_source_);
625 }
626 g_main_loop_unref(loop);
627}
628
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000629namespace {
630class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
631 public:
632 virtual void ReceivedBytes(HttpFetcher* fetcher,
633 const char* bytes, int length) {
634 data.append(bytes, length);
635 }
636 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700637 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800638 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000639 g_main_loop_quit(loop_);
640 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800641 virtual void TransferTerminated(HttpFetcher* fetcher) {
642 ADD_FAILURE();
643 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000644 string data;
645 GMainLoop* loop_;
646};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700647} // namespace
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000648
649TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800650 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000651 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700652 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000653 {
654 FlakyHttpFetcherTestDelegate delegate;
655 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800656 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000657 fetcher->set_delegate(&delegate);
658
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800659 scoped_ptr<HttpServer> server(this->test_.CreateServer());
660 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000661
662 StartTransferArgs start_xfer_args = {
663 fetcher.get(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700664 LocalServerUrlForPath(server->GetPort(),
Alex Vakulenko75039d72014-03-25 12:36:28 -0700665 base::StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
666 kFlakyTruncateLength,
667 kFlakySleepEvery,
668 kFlakySleepSecs))
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000669 };
670
671 g_timeout_add(0, StartTransfer, &start_xfer_args);
672 g_main_loop_run(loop);
673
674 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800675 ASSERT_EQ(kBigLength, delegate.data.size());
676 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000677 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
678 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
679 }
680 }
681 g_main_loop_unref(loop);
682}
683
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700684namespace {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700685// This delegate kills the server attached to it after receiving any bytes.
686// This can be used for testing what happens when you try to fetch data and
687// the server dies.
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700688class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
689 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700690 explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700691 : loop_(nullptr),
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700692 server_(server) {}
693
694 virtual ~FailureHttpFetcherTestDelegate() {
695 if (server_) {
696 LOG(INFO) << "Stopping server in destructor";
697 delete server_;
698 LOG(INFO) << "server stopped";
699 }
700 }
701
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700702 virtual void ReceivedBytes(HttpFetcher* fetcher,
703 const char* bytes, int length) {
704 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700705 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700706 delete server_;
707 LOG(INFO) << "server stopped";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700708 server_ = nullptr;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700709 }
710 }
711 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
712 EXPECT_FALSE(successful);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700713 EXPECT_EQ(0, fetcher->http_response_code());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700714 g_main_loop_quit(loop_);
715 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800716 virtual void TransferTerminated(HttpFetcher* fetcher) {
717 ADD_FAILURE();
718 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700719 GMainLoop* loop_;
720 PythonHttpServer* server_;
721};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700722} // namespace
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700723
724
725TYPED_TEST(HttpFetcherTest, FailureTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700726 // This test ensures that a fetcher responds correctly when a server isn't
727 // available at all.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800728 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700729 return;
730 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
731 {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700732 FailureHttpFetcherTestDelegate delegate(nullptr);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700733 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800734 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700735 fetcher->set_delegate(&delegate);
736
737 StartTransferArgs start_xfer_args = {
738 fetcher.get(),
Chris Sosa0a364bb2014-06-10 18:18:24 -0700739 "http://host_doesnt_exist99999999",
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700740 };
741
742 g_timeout_add(0, StartTransfer, &start_xfer_args);
743 g_main_loop_run(loop);
744
745 // Exiting and testing happens in the delegate
746 }
747 g_main_loop_unref(loop);
748}
749
750TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700751 // This test starts a new http server and kills it after receiving its first
752 // set of bytes. It test whether or not our fetcher eventually gives up on
753 // retries and aborts correctly.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800754 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700755 return;
756 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
757 {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700758 PythonHttpServer* server = new PythonHttpServer();
759 int port = server->GetPort();
760 ASSERT_TRUE(server->started_);
761
762 // Handles destruction and claims ownership.
763 FailureHttpFetcherTestDelegate delegate(server);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700764 delegate.loop_ = loop;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800765 scoped_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700766 fetcher->set_delegate(&delegate);
767
768 StartTransferArgs start_xfer_args = {
769 fetcher.get(),
Chris Sosa0a364bb2014-06-10 18:18:24 -0700770 LocalServerUrlForPath(port,
Alex Vakulenko75039d72014-03-25 12:36:28 -0700771 base::StringPrintf("/flaky/%d/%d/%d/%d", kBigLength,
772 kFlakyTruncateLength,
773 kFlakySleepEvery,
774 kFlakySleepSecs))
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700775 };
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700776 g_timeout_add(0, StartTransfer, &start_xfer_args);
777 g_main_loop_run(loop);
778
779 // Exiting and testing happens in the delegate
780 }
781 g_main_loop_unref(loop);
782}
783
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700784namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800785const HttpResponseCode kRedirectCodes[] = {
786 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
787 kHttpResponseTempRedirect
788};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700789
790class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
791 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700792 explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700793 : expected_successful_(expected_successful) {}
794 virtual void ReceivedBytes(HttpFetcher* fetcher,
795 const char* bytes, int length) {
796 data.append(bytes, length);
797 }
798 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
799 EXPECT_EQ(expected_successful_, successful);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700800 if (expected_successful_) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800801 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700802 } else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800803 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
804 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700805 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700806 g_main_loop_quit(loop_);
807 }
Darin Petkov9ce452b2010-11-17 14:33:28 -0800808 virtual void TransferTerminated(HttpFetcher* fetcher) {
809 ADD_FAILURE();
810 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700811 bool expected_successful_;
812 string data;
813 GMainLoop* loop_;
814};
815
816// RedirectTest takes ownership of |http_fetcher|.
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700817void RedirectTest(const HttpServer* server,
818 bool expected_successful,
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700819 const string& url,
820 HttpFetcher* http_fetcher) {
821 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700822 {
823 RedirectHttpFetcherTestDelegate delegate(expected_successful);
824 delegate.loop_ = loop;
825 scoped_ptr<HttpFetcher> fetcher(http_fetcher);
826 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700827
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700828 StartTransferArgs start_xfer_args =
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700829 { fetcher.get(), LocalServerUrlForPath(server->GetPort(), url) };
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700830
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700831 g_timeout_add(0, StartTransfer, &start_xfer_args);
832 g_main_loop_run(loop);
833 if (expected_successful) {
834 // verify the data we get back
835 ASSERT_EQ(kMediumLength, delegate.data.size());
836 for (int i = 0; i < kMediumLength; i += 10) {
837 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
838 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
839 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700840 }
841 }
842 g_main_loop_unref(loop);
843}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700844} // namespace
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700845
846TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800847 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700848 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800849
850 scoped_ptr<HttpServer> server(this->test_.CreateServer());
851 ASSERT_TRUE(server->started_);
852
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700853 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800854 const string url = base::StringPrintf("/redirect/%d/download/%d",
855 kRedirectCodes[c],
856 kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700857 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700858 }
859}
860
861TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800862 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700863 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800864
865 scoped_ptr<HttpServer> server(this->test_.CreateServer());
866 ASSERT_TRUE(server->started_);
867
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700868 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700869 for (int r = 0; r < kDownloadMaxRedirects; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700870 url += base::StringPrintf("/redirect/%d",
871 kRedirectCodes[r % arraysize(kRedirectCodes)]);
872 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800873 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700874 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700875}
876
877TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800878 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700879 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800880
881 scoped_ptr<HttpServer> server(this->test_.CreateServer());
882 ASSERT_TRUE(server->started_);
883
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700884 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700885 for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700886 url += base::StringPrintf("/redirect/%d",
887 kRedirectCodes[r % arraysize(kRedirectCodes)]);
888 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800889 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700890 RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700891}
892
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700893namespace {
894class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
895 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700896 explicit MultiHttpFetcherTestDelegate(int expected_response_code)
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700897 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800898
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700899 virtual void ReceivedBytes(HttpFetcher* fetcher,
900 const char* bytes, int length) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800901 EXPECT_EQ(fetcher, fetcher_.get());
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700902 data.append(bytes, length);
903 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800904
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700905 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800906 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800907 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700908 if (expected_response_code_ != 0)
909 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800910 // Destroy the fetcher (because we're allowed to).
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700911 fetcher_.reset(nullptr);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700912 g_main_loop_quit(loop_);
913 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800914
Darin Petkov9ce452b2010-11-17 14:33:28 -0800915 virtual void TransferTerminated(HttpFetcher* fetcher) {
916 ADD_FAILURE();
917 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800918
Darin Petkov9ce452b2010-11-17 14:33:28 -0800919 scoped_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700920 int expected_response_code_;
921 string data;
922 GMainLoop* loop_;
923};
924
925void MultiTest(HttpFetcher* fetcher_in,
926 const string& url,
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800927 const vector<pair<off_t, off_t> >& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700928 const string& expected_prefix,
929 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800930 HttpResponseCode expected_response_code) {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700931 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
932 {
933 MultiHttpFetcherTestDelegate delegate(expected_response_code);
934 delegate.loop_ = loop;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800935 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700936
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800937 MultiRangeHttpFetcher* multi_fetcher =
938 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700939 ASSERT_TRUE(multi_fetcher);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800940 multi_fetcher->ClearRanges();
941 for (vector<pair<off_t, off_t> >::const_iterator it = ranges.begin(),
942 e = ranges.end(); it != e; ++it) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700943 std::string tmp_str = base::StringPrintf("%jd+", it->first);
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800944 if (it->second > 0) {
945 base::StringAppendF(&tmp_str, "%jd", it->second);
946 multi_fetcher->AddRange(it->first, it->second);
947 } else {
948 base::StringAppendF(&tmp_str, "?");
949 multi_fetcher->AddRange(it->first);
950 }
951 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800952 }
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700953 dynamic_cast<FakeSystemState*>(fetcher_in->GetSystemState())
Gilad Arnold1f847232014-04-07 12:07:49 -0700954 ->fake_hardware()->SetIsOfficialBuild(false);
Darin Petkov9ce452b2010-11-17 14:33:28 -0800955 multi_fetcher->set_delegate(&delegate);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700956
Darin Petkov9ce452b2010-11-17 14:33:28 -0800957 StartTransferArgs start_xfer_args = {multi_fetcher, url};
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700958
959 g_timeout_add(0, StartTransfer, &start_xfer_args);
960 g_main_loop_run(loop);
961
962 EXPECT_EQ(expected_size, delegate.data.size());
963 EXPECT_EQ(expected_prefix,
964 string(delegate.data.data(), expected_prefix.size()));
965 }
966 g_main_loop_unref(loop);
967}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700968} // namespace
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700969
Darin Petkov9ce452b2010-11-17 14:33:28 -0800970TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800971 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700972 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800973
974 scoped_ptr<HttpServer> server(this->test_.CreateServer());
975 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700976
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800977 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700978 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800979 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800980 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700981 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700982 ranges,
983 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800984 kBigLength - (99 - 25),
985 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700986}
987
988TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800989 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700990 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800991
992 scoped_ptr<HttpServer> server(this->test_.CreateServer());
993 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700994
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800995 vector<pair<off_t, off_t> > ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700996 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800997 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700998 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700999 ranges,
1000 "abcdefghijabcdefghijabcd",
1001 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001002 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001003}
1004
1005TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001006 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001007 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001008
1009 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1010 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001011
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001012 vector<pair<off_t, off_t> > ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001013 ranges.push_back(make_pair(kBigLength - 2, 0));
1014 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001015 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001016 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001017 ranges,
1018 "ijhij",
1019 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001020 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001021}
1022
1023TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001024 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001025 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001026
1027 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1028 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001029
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001030 vector<pair<off_t, off_t> > ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001031 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001032 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001033 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001034 MultiTest(this->test_.NewLargeFetcher(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001035 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001036 ranges,
1037 "ij",
1038 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001039 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001040 ranges.push_back(make_pair(0, 5));
1041 }
1042}
1043
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001044// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1045// should retry with other proxies listed before giving up.
1046//
1047// (1) successful recovery: The offset fetch will fail twice but succeed with
1048// the third proxy.
1049TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1050 if (!this->test_.IsMulti())
1051 return;
1052
1053 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1054 ASSERT_TRUE(server->started_);
1055
1056 vector<pair<off_t, off_t> > ranges;
1057 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001058 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001059 MultiTest(this->test_.NewLargeFetcher(3),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001060 LocalServerUrlForPath(server->GetPort(),
1061 base::StringPrintf("/error-if-offset/%d/2",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001062 kBigLength)),
1063 ranges,
1064 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1065 kBigLength - (99 - 25),
1066 kHttpResponsePartialContent);
1067}
1068
1069// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1070// fetcher will signal a (failed) completed transfer to the delegate.
1071TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1072 if (!this->test_.IsMulti())
1073 return;
1074
1075 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1076 ASSERT_TRUE(server->started_);
1077
1078 vector<pair<off_t, off_t> > ranges;
1079 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001080 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001081 MultiTest(this->test_.NewLargeFetcher(2),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001082 LocalServerUrlForPath(server->GetPort(),
1083 base::StringPrintf("/error-if-offset/%d/3",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001084 kBigLength)),
1085 ranges,
1086 "abcdefghijabcdefghijabcde", // only received the first chunk
1087 25,
1088 kHttpResponseUndefined);
1089}
1090
1091
1092
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001093namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001094class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001095 public:
1096 virtual void ReceivedBytes(HttpFetcher* fetcher,
1097 const char* bytes, int length) {
1098 ADD_FAILURE();
1099 }
1100 virtual void TransferComplete(HttpFetcher* fetcher, bool successful) {
1101 EXPECT_FALSE(successful);
1102 g_main_loop_quit(loop_);
1103 }
Darin Petkov9ce452b2010-11-17 14:33:28 -08001104 virtual void TransferTerminated(HttpFetcher* fetcher) {
1105 ADD_FAILURE();
1106 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001107 GMainLoop* loop_;
1108};
1109
1110} // namespace
1111
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001112TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001113 if (this->test_.IsMock() || this->test_.IsMulti())
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001114 return;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001115
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001116 for (int i = 0; i < 2; i++) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001117 scoped_ptr<HttpServer> server(this->test_.CreateServer());
1118 ASSERT_TRUE(server->started_);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001119
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001120 GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001121 {
1122 BlockedTransferTestDelegate delegate;
1123 delegate.loop_ = loop;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001124
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001125 bool is_allowed = (i != 0);
1126 scoped_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
Jay Srinivasan43488792012-06-19 00:25:31 -07001127
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001128 bool is_official_build = (i == 1);
1129 LOG(INFO) << "is_update_allowed_over_connection: " << is_allowed;
1130 LOG(INFO) << "is_official_build: " << is_official_build;
Gilad Arnold5bb4c902014-04-10 12:32:13 -07001131 // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
1132 dynamic_cast<FakeSystemState*>(fetcher->GetSystemState())
Gilad Arnold1f847232014-04-07 12:07:49 -07001133 ->fake_hardware()->SetIsOfficialBuild(is_official_build);
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001134 fetcher->set_delegate(&delegate);
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001135
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001136 StartTransferArgs start_xfer_args =
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001137 {fetcher.get(),
1138 LocalServerUrlForPath(server->GetPort(),
1139 this->test_.SmallUrl(server->GetPort()))};
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001140
Jay Srinivasan135a58b2012-07-13 12:46:49 -07001141 g_timeout_add(0, StartTransfer, &start_xfer_args);
1142 g_main_loop_run(loop);
1143 }
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001144 g_main_loop_unref(loop);
1145 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001146}
1147
rspangler@google.com49fdf182009-10-10 00:57:34 +00001148} // namespace chromeos_update_engine