blob: aaa538c05863b0b764c0b987a0eec6ef774fa42f [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
rspangler@google.com49fdf182009-10-10 00:57:34 +000016
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070017#include <netinet/in.h>
18#include <netinet/ip.h>
19#include <sys/socket.h>
rspangler@google.com49fdf182009-10-10 00:57:34 +000020#include <unistd.h>
Darin Petkov41c2fcf2010-08-25 13:14:48 -070021
Ben Chan02f7c1d2014-10-18 15:18:02 -070022#include <memory>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000023#include <string>
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070024#include <utility>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000025#include <vector>
Darin Petkov41c2fcf2010-08-25 13:14:48 -070026
Alex Deymo706a5ab2015-11-23 17:48:30 -030027#include <base/bind.h>
Alex Deymo60ca1a72015-06-18 18:19:15 -070028#include <base/location.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080029#include <base/logging.h>
Alex Deymo535f3b72015-08-07 10:51:32 -070030#include <base/message_loop/message_loop.h>
31#include <base/strings/string_number_conversions.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070032#include <base/strings/string_util.h>
33#include <base/strings/stringprintf.h>
34#include <base/time/time.h>
Alex Deymo706a5ab2015-11-23 17:48:30 -030035#include <brillo/bind_lambda.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070036#include <brillo/message_loops/base_message_loop.h>
37#include <brillo/message_loops/message_loop.h>
38#include <brillo/message_loops/message_loop_utils.h>
39#include <brillo/process.h>
40#include <brillo/streams/file_stream.h>
41#include <brillo/streams/stream.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080042#include <gtest/gtest.h>
43
Alex Deymoc1c17b42015-11-23 03:53:15 -030044#include "update_engine/common/fake_hardware.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080045#include "update_engine/common/http_common.h"
46#include "update_engine/common/libcurl_http_fetcher.h"
47#include "update_engine/common/mock_http_fetcher.h"
48#include "update_engine/common/multi_range_http_fetcher.h"
49#include "update_engine/common/test_utils.h"
50#include "update_engine/common/utils.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080051#include "update_engine/proxy_resolver.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000052
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070053using brillo::MessageLoop;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070054using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080055using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000056using std::string;
Ben Chan02f7c1d2014-10-18 15:18:02 -070057using std::unique_ptr;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000058using std::vector;
59
Gilad Arnold9bedeb52011-11-17 16:19:57 -080060namespace {
61
62const int kBigLength = 100000;
63const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080064const int kFlakyTruncateLength = 29000;
65const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080066const int kFlakySleepSecs = 10;
67
68} // namespace
69
rspangler@google.com49fdf182009-10-10 00:57:34 +000070namespace chromeos_update_engine {
71
Gilad Arnold9bedeb52011-11-17 16:19:57 -080072static const char *kUnusedUrl = "unused://unused";
73
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070074static inline string LocalServerUrlForPath(in_port_t port,
75 const string& path) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070076 string port_str = (port ? base::StringPrintf(":%hu", port) : "");
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070077 return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
78 path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000079}
80
Gilad Arnold9bedeb52011-11-17 16:19:57 -080081//
82// Class hierarchy for HTTP server implementations.
83//
84
85class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000086 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080087 // This makes it an abstract class (dirty but works).
88 virtual ~HttpServer() = 0;
89
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070090 virtual in_port_t GetPort() const {
91 return 0;
92 }
93
rspangler@google.com49fdf182009-10-10 00:57:34 +000094 bool started_;
95};
96
Gilad Arnold9bedeb52011-11-17 16:19:57 -080097HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000098
Gilad Arnold9bedeb52011-11-17 16:19:57 -080099
100class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000101 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800102 NullHttpServer() {
103 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000104 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000105};
106
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800107
108class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000109 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700110 PythonHttpServer() : port_(0) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000111 started_ = false;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700112
113 // Spawn the server process.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700114 unique_ptr<brillo::Process> http_server(new brillo::ProcessImpl());
Alex Deymo535f3b72015-08-07 10:51:32 -0700115 base::FilePath test_server_path =
116 test_utils::GetBuildArtifactsPath().Append("test_http_server");
117 http_server->AddArg(test_server_path.value());
118 http_server->RedirectUsingPipe(STDOUT_FILENO, false);
119
120 if (!http_server->Start()) {
121 ADD_FAILURE() << "failed to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000122 return;
123 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700124 LOG(INFO) << "started http server with pid " << http_server->pid();
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700125
126 // Wait for server to begin accepting connections, obtain its port.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700127 brillo::StreamPtr stdout = brillo::FileStream::FromFileDescriptor(
Alex Deymo535f3b72015-08-07 10:51:32 -0700128 http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr);
129 if (!stdout)
130 return;
131
132 vector<char> buf(128);
133 string line;
134 while (line.find('\n') == string::npos) {
135 size_t read;
136 if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) {
137 ADD_FAILURE() << "error reading http server stdout";
138 return;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700139 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700140 line.append(buf.data(), read);
141 if (read == 0)
142 break;
143 }
144 // Parse the port from the output line.
145 const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
146 if (line.size() < listening_msg_prefix_len) {
147 ADD_FAILURE() << "server output too short";
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700148 return;
149 }
150
Alex Deymo535f3b72015-08-07 10:51:32 -0700151 EXPECT_EQ(kServerListeningMsgPrefix,
152 line.substr(0, listening_msg_prefix_len));
153 string port_str = line.substr(listening_msg_prefix_len);
154 port_str.resize(port_str.find('\n'));
155 EXPECT_TRUE(base::StringToUint(port_str, &port_));
156
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700157 started_ = true;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700158 LOG(INFO) << "server running, listening on port " << port_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700159
160 // Any failure before this point will SIGKILL the test server if started
161 // when the |http_server| goes out of scope.
162 http_server_ = std::move(http_server);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000163 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800164
rspangler@google.com49fdf182009-10-10 00:57:34 +0000165 ~PythonHttpServer() {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700166 // If there's no process, do nothing.
Alex Deymo535f3b72015-08-07 10:51:32 -0700167 if (!http_server_)
rspangler@google.com49fdf182009-10-10 00:57:34 +0000168 return;
Alex Deymo535f3b72015-08-07 10:51:32 -0700169 // Wait up to 10 seconds for the process to finish. Destroying the process
170 // will kill it with a SIGKILL otherwise.
171 http_server_->Kill(SIGTERM, 10);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000172 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800173
Alex Deymo610277e2014-11-11 21:18:11 -0800174 in_port_t GetPort() const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700175 return port_;
176 }
177
178 private:
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700179 static const char* kServerListeningMsgPrefix;
180
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700181 unique_ptr<brillo::Process> http_server_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700182 unsigned int port_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000183};
184
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700185const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
186
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800187//
188// Class hierarchy for HTTP fetcher test wrappers.
189//
190
191class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000192 public:
Chris Sosa77f79e82014-06-02 18:16:24 -0700193 AnyHttpFetcherTest() {}
Alex Deymoc4acdf42014-05-28 21:07:10 -0700194 virtual ~AnyHttpFetcherTest() {}
Jay Srinivasan43488792012-06-19 00:25:31 -0700195
Alex Deymo7984bf02014-04-02 20:41:57 -0700196 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800197 HttpFetcher* NewLargeFetcher() {
198 return NewLargeFetcher(1);
199 }
200
201 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
202 HttpFetcher* NewSmallFetcher() {
203 return NewSmallFetcher(1);
204 }
205
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700206 virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
207 virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
208 virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800209
210 virtual bool IsMock() const = 0;
211 virtual bool IsMulti() const = 0;
212
213 virtual void IgnoreServerAborting(HttpServer* server) const {}
214
Alex Deymo60ca1a72015-06-18 18:19:15 -0700215 virtual HttpServer* CreateServer() = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800216
Alex Deymoc1c17b42015-11-23 03:53:15 -0300217 FakeHardware* fake_hardware() {
Alex Deymo706a5ab2015-11-23 17:48:30 -0300218 return &fake_hardware_;
Alex Deymoc1c17b42015-11-23 03:53:15 -0300219 }
220
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800221 protected:
222 DirectProxyResolver proxy_resolver_;
Alex Deymo706a5ab2015-11-23 17:48:30 -0300223 FakeHardware fake_hardware_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800224};
225
226class MockHttpFetcherTest : public AnyHttpFetcherTest {
227 public:
228 // Necessary to unhide the definition in the base class.
229 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800230 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700231 brillo::Blob big_data(1000000);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700232 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800233 proxy_resolver_.set_num_proxies(num_proxies);
234 return new MockHttpFetcher(
235 big_data.data(),
236 big_data.size(),
237 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
238 }
239
240 // Necessary to unhide the definition in the base class.
241 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800242 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700243 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800244 proxy_resolver_.set_num_proxies(num_proxies);
245 return new MockHttpFetcher(
246 "x",
247 1,
248 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
249 }
250
Alex Deymo610277e2014-11-11 21:18:11 -0800251 bool IsMock() const override { return true; }
252 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800253
Alex Deymo60ca1a72015-06-18 18:19:15 -0700254 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800255 return new NullHttpServer;
256 }
257};
258
259class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
260 public:
261 // Necessary to unhide the definition in the base class.
262 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800263 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700264 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800265 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800266 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700267 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Alex Deymo706a5ab2015-11-23 17:48:30 -0300268 &fake_hardware_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700269 // Speed up test execution.
270 ret->set_idle_seconds(1);
271 ret->set_retry_seconds(1);
Alex Deymo706a5ab2015-11-23 17:48:30 -0300272 fake_hardware_.SetIsOfficialBuild(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000273 return ret;
274 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800275
276 // Necessary to unhide the definition in the base class.
277 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800278 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800279 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000280 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800281
Alex Deymo610277e2014-11-11 21:18:11 -0800282 string BigUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700283 return LocalServerUrlForPath(port,
284 base::StringPrintf("/download/%d",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800285 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000286 }
Alex Deymo610277e2014-11-11 21:18:11 -0800287 string SmallUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700288 return LocalServerUrlForPath(port, "/foo");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000289 }
Alex Deymo610277e2014-11-11 21:18:11 -0800290 string ErrorUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700291 return LocalServerUrlForPath(port, "/error");
Gilad Arnold48085ba2011-11-16 09:36:08 -0800292 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800293
Alex Deymo610277e2014-11-11 21:18:11 -0800294 bool IsMock() const override { return false; }
295 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800296
Alex Deymo610277e2014-11-11 21:18:11 -0800297 void IgnoreServerAborting(HttpServer* server) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700298 // Nothing to do.
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700299 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800300
Alex Deymo60ca1a72015-06-18 18:19:15 -0700301 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800302 return new PythonHttpServer;
303 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000304};
305
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800306class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700307 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800308 // Necessary to unhide the definition in the base class.
309 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800310 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700311 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800312 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800313 ProxyResolver* resolver =
314 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700315 MultiRangeHttpFetcher *ret =
316 new MultiRangeHttpFetcher(
Alex Deymo706a5ab2015-11-23 17:48:30 -0300317 new LibcurlHttpFetcher(resolver, &fake_hardware_));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800318 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800319 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700320 // Speed up test execution.
321 ret->set_idle_seconds(1);
322 ret->set_retry_seconds(1);
Alex Deymo706a5ab2015-11-23 17:48:30 -0300323 fake_hardware_.SetIsOfficialBuild(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700324 return ret;
325 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800326
327 // Necessary to unhide the definition in the base class.
328 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800329 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800330 return NewLargeFetcher(num_proxies);
331 }
332
Alex Deymo610277e2014-11-11 21:18:11 -0800333 bool IsMulti() const override { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700334};
335
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800336
337//
338// Infrastructure for type tests of HTTP fetcher.
339// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
340//
341
342// Fixture class template. We use an explicit constraint to guarantee that it
343// can only be instantiated with an AnyHttpFetcherTest type, see:
344// http://www2.research.att.com/~bs/bs_faq2.html#constraints
345template <typename T>
346class HttpFetcherTest : public ::testing::Test {
347 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700348 base::MessageLoopForIO base_loop_;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700349 brillo::BaseMessageLoop loop_{&base_loop_};
Alex Deymo60ca1a72015-06-18 18:19:15 -0700350
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800351 T test_;
352
Alex Deymo60ca1a72015-06-18 18:19:15 -0700353 protected:
354 HttpFetcherTest() {
355 loop_.SetAsCurrent();
356 }
357
358 void TearDown() override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700359 EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1));
Alex Deymo60ca1a72015-06-18 18:19:15 -0700360 }
361
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800362 private:
Alex Deymo60ca1a72015-06-18 18:19:15 -0700363 static void TypeConstraint(T* a) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800364 AnyHttpFetcherTest *b = a;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700365 if (b == 0) // Silence compiler warning of unused variable.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700366 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800367 }
368};
369
370// Test case types list.
371typedef ::testing::Types<LibcurlHttpFetcherTest,
372 MockHttpFetcherTest,
373 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000374TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
375
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800376
rspangler@google.com49fdf182009-10-10 00:57:34 +0000377namespace {
378class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000379 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800380 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800381 is_expect_error_(false), times_transfer_complete_called_(0),
382 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
383
Alex Deymo610277e2014-11-11 21:18:11 -0800384 void ReceivedBytes(HttpFetcher* /* fetcher */,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800385 const void* /* bytes */, size_t /* length */) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800386 // Update counters
387 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000388 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800389
Alex Deymo610277e2014-11-11 21:18:11 -0800390 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800391 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800392 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800393 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800394 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700395 MessageLoop::current()->BreakLoop();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800396
397 // Update counter
398 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000399 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800400
Alex Deymo610277e2014-11-11 21:18:11 -0800401 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800402 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800403 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800404 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800405
Gilad Arnold48085ba2011-11-16 09:36:08 -0800406 // Are we expecting an error response? (default: no)
407 bool is_expect_error_;
408
409 // Counters for callback invocations.
410 int times_transfer_complete_called_;
411 int times_transfer_terminated_called_;
412 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000413};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000414
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000415
Alex Deymo60ca1a72015-06-18 18:19:15 -0700416void StartTransfer(HttpFetcher* http_fetcher, const string& url) {
417 http_fetcher->BeginTransfer(url);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000418}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700419} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000420
421TYPED_TEST(HttpFetcherTest, SimpleTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700422 HttpFetcherTestDelegate delegate;
423 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
424 fetcher->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000425
Alex Deymo60ca1a72015-06-18 18:19:15 -0700426 unique_ptr<HttpServer> server(this->test_.CreateServer());
427 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000428
Alex Deymo60ca1a72015-06-18 18:19:15 -0700429 this->loop_.PostTask(FROM_HERE, base::Bind(
430 StartTransfer,
431 fetcher.get(),
432 this->test_.SmallUrl(server->GetPort())));
433 this->loop_.Run();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000434}
435
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700436TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700437 HttpFetcherTestDelegate delegate;
438 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
439 fetcher->set_delegate(&delegate);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700440
Alex Deymo60ca1a72015-06-18 18:19:15 -0700441 unique_ptr<HttpServer> server(this->test_.CreateServer());
442 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700443
Alex Deymo60ca1a72015-06-18 18:19:15 -0700444 this->loop_.PostTask(FROM_HERE, base::Bind(
445 StartTransfer,
446 fetcher.get(),
447 this->test_.BigUrl(server->GetPort())));
448 this->loop_.Run();
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700449}
450
Gilad Arnold48085ba2011-11-16 09:36:08 -0800451// Issue #9648: when server returns an error HTTP response, the fetcher needs to
452// terminate transfer prematurely, rather than try to process the error payload.
453TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800454 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800455 return;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700456 HttpFetcherTestDelegate delegate;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800457
Alex Deymo60ca1a72015-06-18 18:19:15 -0700458 // Delegate should expect an error response.
459 delegate.is_expect_error_ = true;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800460
Alex Deymo60ca1a72015-06-18 18:19:15 -0700461 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
462 fetcher->set_delegate(&delegate);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800463
Alex Deymo60ca1a72015-06-18 18:19:15 -0700464 unique_ptr<HttpServer> server(this->test_.CreateServer());
465 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800466
Alex Deymo60ca1a72015-06-18 18:19:15 -0700467 this->loop_.PostTask(FROM_HERE, base::Bind(
468 StartTransfer,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800469 fetcher.get(),
Alex Deymo60ca1a72015-06-18 18:19:15 -0700470 this->test_.ErrorUrl(server->GetPort())));
471 this->loop_.Run();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800472
Alex Deymo60ca1a72015-06-18 18:19:15 -0700473 // Make sure that no bytes were received.
474 CHECK_EQ(delegate.times_received_bytes_called_, 0);
475 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800476
Alex Deymo60ca1a72015-06-18 18:19:15 -0700477 // Make sure that transfer completion was signaled once, and no termination
478 // was signaled.
479 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
480 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800481}
482
rspangler@google.com49fdf182009-10-10 00:57:34 +0000483namespace {
484class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
485 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800486 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800487 const void* /* bytes */, size_t /* length */) override {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000488 CHECK(!paused_);
489 paused_ = true;
490 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000491 }
Alex Deymo610277e2014-11-11 21:18:11 -0800492 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700493 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000494 }
Alex Deymo610277e2014-11-11 21:18:11 -0800495 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800496 ADD_FAILURE();
497 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000498 void Unpause() {
499 CHECK(paused_);
500 paused_ = false;
501 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000502 }
503 bool paused_;
504 HttpFetcher* fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000505};
506
Alex Deymo60ca1a72015-06-18 18:19:15 -0700507void UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate,
508 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000509 if (delegate->paused_)
510 delegate->Unpause();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700511 // Update the task id with the new scheduled callback.
512 *my_id = MessageLoop::current()->PostDelayedTask(
513 FROM_HERE,
514 base::Bind(&UnpausingTimeoutCallback, delegate, my_id),
515 base::TimeDelta::FromMilliseconds(200));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000516}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700517} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000518
519TYPED_TEST(HttpFetcherTest, PauseTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000520 {
521 PausingHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700522 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000523 delegate.paused_ = false;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000524 delegate.fetcher_ = fetcher.get();
525 fetcher->set_delegate(&delegate);
526
Ben Chan02f7c1d2014-10-18 15:18:02 -0700527 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800528 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800529
Alex Deymo60ca1a72015-06-18 18:19:15 -0700530 MessageLoop::TaskId callback_id;
531 callback_id = this->loop_.PostDelayedTask(
532 FROM_HERE,
533 base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
534 base::TimeDelta::FromMilliseconds(200));
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700535 fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000536
Alex Deymo60ca1a72015-06-18 18:19:15 -0700537 this->loop_.Run();
538 EXPECT_TRUE(this->loop_.CancelTask(callback_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000539 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000540}
541
542namespace {
543class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
544 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800545 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800546 const void* bytes, size_t length) override {}
Alex Deymo610277e2014-11-11 21:18:11 -0800547 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800548 ADD_FAILURE(); // We should never get here
Alex Deymo60ca1a72015-06-18 18:19:15 -0700549 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000550 }
Alex Deymo610277e2014-11-11 21:18:11 -0800551 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800552 EXPECT_EQ(fetcher, fetcher_.get());
553 EXPECT_FALSE(once_);
554 EXPECT_TRUE(callback_once_);
555 callback_once_ = false;
Alex Deymoc4acdf42014-05-28 21:07:10 -0700556 // The fetcher could have a callback scheduled on the ProxyResolver that
557 // can fire after this callback. We wait until the end of the test to
558 // delete the fetcher.
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800559 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000560 void TerminateTransfer() {
561 CHECK(once_);
562 once_ = false;
563 fetcher_->TerminateTransfer();
564 }
565 void EndLoop() {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700566 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000567 }
568 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800569 bool callback_once_;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700570 unique_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000571};
572
Alex Deymo60ca1a72015-06-18 18:19:15 -0700573void AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate,
574 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000575 if (delegate->once_) {
576 delegate->TerminateTransfer();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700577 *my_id = MessageLoop::current()->PostTask(
578 FROM_HERE,
579 base::Bind(AbortingTimeoutCallback, delegate, my_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000580 } else {
581 delegate->EndLoop();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700582 *my_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000583 }
584}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700585} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000586
587TYPED_TEST(HttpFetcherTest, AbortTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700588 AbortingHttpFetcherTestDelegate delegate;
589 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
590 delegate.once_ = true;
591 delegate.callback_once_ = true;
592 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000593
Alex Deymo60ca1a72015-06-18 18:19:15 -0700594 unique_ptr<HttpServer> server(this->test_.CreateServer());
595 this->test_.IgnoreServerAborting(server.get());
596 ASSERT_TRUE(server->started_);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800597
Alex Deymo60ca1a72015-06-18 18:19:15 -0700598 MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000599
Alex Deymo60ca1a72015-06-18 18:19:15 -0700600 task_id = this->loop_.PostTask(
601 FROM_HERE,
602 base::Bind(AbortingTimeoutCallback, &delegate, &task_id));
603 delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
604
605 this->loop_.Run();
606 CHECK(!delegate.once_);
607 CHECK(!delegate.callback_once_);
608 this->loop_.CancelTask(task_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000609}
610
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000611namespace {
612class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
613 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800614 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800615 const void* bytes, size_t length) override {
616 data.append(reinterpret_cast<const char*>(bytes), length);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000617 }
Alex Deymo610277e2014-11-11 21:18:11 -0800618 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700619 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800620 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700621 MessageLoop::current()->BreakLoop();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000622 }
Alex Deymo610277e2014-11-11 21:18:11 -0800623 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800624 ADD_FAILURE();
625 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000626 string data;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000627};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700628} // namespace
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000629
630TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800631 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000632 return;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000633 {
634 FlakyHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700635 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000636 fetcher->set_delegate(&delegate);
637
Ben Chan02f7c1d2014-10-18 15:18:02 -0700638 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800639 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000640
Alex Deymo60ca1a72015-06-18 18:19:15 -0700641 this->loop_.PostTask(FROM_HERE, base::Bind(
642 &StartTransfer,
643 fetcher.get(),
644 LocalServerUrlForPath(server->GetPort(),
645 base::StringPrintf("/flaky/%d/%d/%d/%d",
646 kBigLength,
647 kFlakyTruncateLength,
648 kFlakySleepEvery,
649 kFlakySleepSecs))));
650 this->loop_.Run();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000651
652 // verify the data we get back
Alex Deymo80f70ff2016-02-10 16:08:11 -0800653 ASSERT_EQ(kBigLength, static_cast<int>(delegate.data.size()));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800654 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000655 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
656 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
657 }
658 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000659}
660
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700661namespace {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700662// This delegate kills the server attached to it after receiving any bytes.
663// This can be used for testing what happens when you try to fetch data and
664// the server dies.
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700665class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
666 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700667 explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
Alex Deymo60ca1a72015-06-18 18:19:15 -0700668 : server_(server) {}
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700669
Alex Deymo610277e2014-11-11 21:18:11 -0800670 ~FailureHttpFetcherTestDelegate() override {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700671 if (server_) {
672 LOG(INFO) << "Stopping server in destructor";
673 delete server_;
674 LOG(INFO) << "server stopped";
675 }
676 }
677
Alex Deymo610277e2014-11-11 21:18:11 -0800678 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800679 const void* bytes, size_t length) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700680 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700681 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700682 delete server_;
683 LOG(INFO) << "server stopped";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700684 server_ = nullptr;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700685 }
686 }
Alex Deymo610277e2014-11-11 21:18:11 -0800687 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700688 EXPECT_FALSE(successful);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700689 EXPECT_EQ(0, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700690 MessageLoop::current()->BreakLoop();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700691 }
Alex Deymo610277e2014-11-11 21:18:11 -0800692 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800693 ADD_FAILURE();
694 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700695 PythonHttpServer* server_;
696};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700697} // namespace
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700698
699
700TYPED_TEST(HttpFetcherTest, FailureTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700701 // This test ensures that a fetcher responds correctly when a server isn't
702 // available at all.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800703 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700704 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700705 {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700706 FailureHttpFetcherTestDelegate delegate(nullptr);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700707 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700708 fetcher->set_delegate(&delegate);
709
Alex Deymo60ca1a72015-06-18 18:19:15 -0700710 this->loop_.PostTask(FROM_HERE,
711 base::Bind(StartTransfer,
712 fetcher.get(),
713 "http://host_doesnt_exist99999999"));
714 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700715
716 // Exiting and testing happens in the delegate
717 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700718}
719
Alex Deymof123ae22015-09-24 14:59:43 -0700720TYPED_TEST(HttpFetcherTest, NoResponseTest) {
721 // This test starts a new http server but the server doesn't respond and just
722 // closes the connection.
723 if (this->test_.IsMock())
724 return;
725
726 PythonHttpServer* server = new PythonHttpServer();
727 int port = server->GetPort();
728 ASSERT_TRUE(server->started_);
729
730 // Handles destruction and claims ownership.
731 FailureHttpFetcherTestDelegate delegate(server);
732 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
733 fetcher->set_delegate(&delegate);
734 // The server will not reply at all, so we can limit the execution time of the
735 // test by reducing the low-speed timeout to something small. The test will
736 // finish once the TimeoutCallback() triggers (every second) and the timeout
737 // expired.
738 fetcher->set_low_speed_limit(kDownloadLowSpeedLimitBps, 1);
739
740 this->loop_.PostTask(FROM_HERE, base::Bind(
741 StartTransfer,
742 fetcher.get(),
743 LocalServerUrlForPath(port, "/hang")));
744 this->loop_.Run();
745
746 // Check that no other callback runs in the next two seconds. That would
747 // indicate a leaked callback.
748 bool timeout = false;
749 auto callback = base::Bind([&timeout]{ timeout = true;});
750 this->loop_.PostDelayedTask(FROM_HERE, callback,
751 base::TimeDelta::FromSeconds(2));
752 EXPECT_TRUE(this->loop_.RunOnce(true));
753 EXPECT_TRUE(timeout);
754}
755
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700756TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700757 // This test starts a new http server and kills it after receiving its first
758 // set of bytes. It test whether or not our fetcher eventually gives up on
759 // retries and aborts correctly.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800760 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700761 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700762 {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700763 PythonHttpServer* server = new PythonHttpServer();
764 int port = server->GetPort();
765 ASSERT_TRUE(server->started_);
766
767 // Handles destruction and claims ownership.
768 FailureHttpFetcherTestDelegate delegate(server);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700769 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700770 fetcher->set_delegate(&delegate);
771
Alex Deymo60ca1a72015-06-18 18:19:15 -0700772 this->loop_.PostTask(FROM_HERE, base::Bind(
773 StartTransfer,
774 fetcher.get(),
775 LocalServerUrlForPath(port,
776 base::StringPrintf("/flaky/%d/%d/%d/%d",
777 kBigLength,
778 kFlakyTruncateLength,
779 kFlakySleepEvery,
780 kFlakySleepSecs))));
781 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700782
783 // Exiting and testing happens in the delegate
784 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700785}
786
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700787namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800788const HttpResponseCode kRedirectCodes[] = {
789 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
790 kHttpResponseTempRedirect
791};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700792
793class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
794 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700795 explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700796 : expected_successful_(expected_successful) {}
Alex Deymo610277e2014-11-11 21:18:11 -0800797 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800798 const void* bytes, size_t length) override {
799 data.append(reinterpret_cast<const char*>(bytes), length);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700800 }
Alex Deymo610277e2014-11-11 21:18:11 -0800801 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700802 EXPECT_EQ(expected_successful_, successful);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700803 if (expected_successful_) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800804 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700805 } else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800806 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
807 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700808 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700809 MessageLoop::current()->BreakLoop();
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700810 }
Alex Deymo610277e2014-11-11 21:18:11 -0800811 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800812 ADD_FAILURE();
813 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700814 bool expected_successful_;
815 string data;
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700816};
817
818// RedirectTest takes ownership of |http_fetcher|.
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700819void RedirectTest(const HttpServer* server,
820 bool expected_successful,
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700821 const string& url,
822 HttpFetcher* http_fetcher) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700823 RedirectHttpFetcherTestDelegate delegate(expected_successful);
824 unique_ptr<HttpFetcher> fetcher(http_fetcher);
825 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700826
Alex Deymo60ca1a72015-06-18 18:19:15 -0700827 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
828 StartTransfer,
829 fetcher.get(),
830 LocalServerUrlForPath(server->GetPort(), url)));
831 MessageLoop::current()->Run();
832 if (expected_successful) {
833 // verify the data we get back
Alex Deymo80f70ff2016-02-10 16:08:11 -0800834 ASSERT_EQ(static_cast<size_t>(kMediumLength), delegate.data.size());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700835 for (int i = 0; i < kMediumLength; i += 10) {
836 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
837 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700838 }
839 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700840}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700841} // namespace
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700842
843TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800844 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700845 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800846
Ben Chan02f7c1d2014-10-18 15:18:02 -0700847 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800848 ASSERT_TRUE(server->started_);
849
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700850 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800851 const string url = base::StringPrintf("/redirect/%d/download/%d",
852 kRedirectCodes[c],
853 kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700854 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700855 }
856}
857
858TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800859 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700860 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800861
Ben Chan02f7c1d2014-10-18 15:18:02 -0700862 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800863 ASSERT_TRUE(server->started_);
864
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700865 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700866 for (int r = 0; r < kDownloadMaxRedirects; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700867 url += base::StringPrintf("/redirect/%d",
868 kRedirectCodes[r % arraysize(kRedirectCodes)]);
869 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800870 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700871 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700872}
873
874TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800875 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700876 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800877
Ben Chan02f7c1d2014-10-18 15:18:02 -0700878 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800879 ASSERT_TRUE(server->started_);
880
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700881 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700882 for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700883 url += base::StringPrintf("/redirect/%d",
884 kRedirectCodes[r % arraysize(kRedirectCodes)]);
885 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800886 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700887 RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700888}
889
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700890namespace {
891class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
892 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700893 explicit MultiHttpFetcherTestDelegate(int expected_response_code)
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700894 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800895
Alex Deymo610277e2014-11-11 21:18:11 -0800896 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800897 const void* bytes, size_t length) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800898 EXPECT_EQ(fetcher, fetcher_.get());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800899 data.append(reinterpret_cast<const char*>(bytes), length);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700900 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800901
Alex Deymo610277e2014-11-11 21:18:11 -0800902 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800903 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800904 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700905 if (expected_response_code_ != 0)
906 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800907 // Destroy the fetcher (because we're allowed to).
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700908 fetcher_.reset(nullptr);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700909 MessageLoop::current()->BreakLoop();
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700910 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800911
Alex Deymo610277e2014-11-11 21:18:11 -0800912 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800913 ADD_FAILURE();
914 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800915
Ben Chan02f7c1d2014-10-18 15:18:02 -0700916 unique_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700917 int expected_response_code_;
918 string data;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700919};
920
921void MultiTest(HttpFetcher* fetcher_in,
Alex Deymoc1c17b42015-11-23 03:53:15 -0300922 FakeHardware* fake_hardware,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700923 const string& url,
Ben Chanf9cb98c2014-09-21 18:31:30 -0700924 const vector<pair<off_t, off_t>>& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700925 const string& expected_prefix,
Alex Deymo5fe0c4e2016-02-16 18:46:24 -0800926 size_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800927 HttpResponseCode expected_response_code) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700928 MultiHttpFetcherTestDelegate delegate(expected_response_code);
929 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700930
Alex Deymo60ca1a72015-06-18 18:19:15 -0700931 MultiRangeHttpFetcher* multi_fetcher =
Alex Deymo80f70ff2016-02-10 16:08:11 -0800932 static_cast<MultiRangeHttpFetcher*>(fetcher_in);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700933 ASSERT_TRUE(multi_fetcher);
934 multi_fetcher->ClearRanges();
935 for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
936 e = ranges.end(); it != e; ++it) {
937 string tmp_str = base::StringPrintf("%jd+", it->first);
938 if (it->second > 0) {
939 base::StringAppendF(&tmp_str, "%jd", it->second);
940 multi_fetcher->AddRange(it->first, it->second);
941 } else {
942 base::StringAppendF(&tmp_str, "?");
943 multi_fetcher->AddRange(it->first);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800944 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700945 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700946 }
Alex Deymoc1c17b42015-11-23 03:53:15 -0300947 fake_hardware->SetIsOfficialBuild(false);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700948 multi_fetcher->set_delegate(&delegate);
949
950 MessageLoop::current()->PostTask(
951 FROM_HERE,
952 base::Bind(StartTransfer, multi_fetcher, url));
953 MessageLoop::current()->Run();
954
955 EXPECT_EQ(expected_size, delegate.data.size());
956 EXPECT_EQ(expected_prefix,
957 string(delegate.data.data(), expected_prefix.size()));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700958}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700959} // namespace
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700960
Darin Petkov9ce452b2010-11-17 14:33:28 -0800961TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800962 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700963 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800964
Ben Chan02f7c1d2014-10-18 15:18:02 -0700965 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800966 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700967
Ben Chanf9cb98c2014-09-21 18:31:30 -0700968 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700969 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800970 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800971 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -0300972 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700973 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700974 ranges,
975 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800976 kBigLength - (99 - 25),
977 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700978}
979
980TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800981 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700982 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800983
Ben Chan02f7c1d2014-10-18 15:18:02 -0700984 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800985 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700986
Ben Chanf9cb98c2014-09-21 18:31:30 -0700987 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700988 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800989 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -0300990 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700991 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700992 ranges,
993 "abcdefghijabcdefghijabcd",
994 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800995 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700996}
997
998TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800999 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001000 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001001
Ben Chan02f7c1d2014-10-18 15:18:02 -07001002 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001003 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001004
Ben Chanf9cb98c2014-09-21 18:31:30 -07001005 vector<pair<off_t, off_t>> ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001006 ranges.push_back(make_pair(kBigLength - 2, 0));
1007 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001008 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001009 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001010 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001011 ranges,
1012 "ijhij",
1013 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001014 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001015}
1016
1017TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001018 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001019 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001020
Ben Chan02f7c1d2014-10-18 15:18:02 -07001021 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001022 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001023
Ben Chanf9cb98c2014-09-21 18:31:30 -07001024 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001025 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001026 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001027 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001028 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001029 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001030 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001031 ranges,
1032 "ij",
1033 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001034 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001035 ranges.push_back(make_pair(0, 5));
1036 }
1037}
1038
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001039// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1040// should retry with other proxies listed before giving up.
1041//
1042// (1) successful recovery: The offset fetch will fail twice but succeed with
1043// the third proxy.
1044TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1045 if (!this->test_.IsMulti())
1046 return;
1047
Ben Chan02f7c1d2014-10-18 15:18:02 -07001048 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001049 ASSERT_TRUE(server->started_);
1050
Ben Chanf9cb98c2014-09-21 18:31:30 -07001051 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001052 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001053 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001054 MultiTest(this->test_.NewLargeFetcher(3),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001055 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001056 LocalServerUrlForPath(server->GetPort(),
1057 base::StringPrintf("/error-if-offset/%d/2",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001058 kBigLength)),
1059 ranges,
1060 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1061 kBigLength - (99 - 25),
1062 kHttpResponsePartialContent);
1063}
1064
1065// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1066// fetcher will signal a (failed) completed transfer to the delegate.
1067TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1068 if (!this->test_.IsMulti())
1069 return;
1070
Ben Chan02f7c1d2014-10-18 15:18:02 -07001071 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001072 ASSERT_TRUE(server->started_);
1073
Ben Chanf9cb98c2014-09-21 18:31:30 -07001074 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001075 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001076 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001077 MultiTest(this->test_.NewLargeFetcher(2),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001078 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001079 LocalServerUrlForPath(server->GetPort(),
1080 base::StringPrintf("/error-if-offset/%d/3",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001081 kBigLength)),
1082 ranges,
1083 "abcdefghijabcdefghijabcde", // only received the first chunk
1084 25,
1085 kHttpResponseUndefined);
1086}
1087
1088
1089
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001090namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001091class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001092 public:
Alex Deymo610277e2014-11-11 21:18:11 -08001093 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -08001094 const void* bytes, size_t length) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001095 ADD_FAILURE();
1096 }
Alex Deymo610277e2014-11-11 21:18:11 -08001097 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001098 EXPECT_FALSE(successful);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001099 MessageLoop::current()->BreakLoop();
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001100 }
Alex Deymo610277e2014-11-11 21:18:11 -08001101 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001102 ADD_FAILURE();
1103 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001104};
1105
Alex Deymo60ca1a72015-06-18 18:19:15 -07001106void BlockedTransferTestHelper(AnyHttpFetcherTest* fetcher_test,
1107 bool is_official_build) {
1108 if (fetcher_test->IsMock() || fetcher_test->IsMulti())
1109 return;
1110
1111 unique_ptr<HttpServer> server(fetcher_test->CreateServer());
1112 ASSERT_TRUE(server->started_);
1113
1114 BlockedTransferTestDelegate delegate;
1115 unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher());
1116 LOG(INFO) << "is_official_build: " << is_official_build;
1117 // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
Alex Deymoc1c17b42015-11-23 03:53:15 -03001118 fetcher_test->fake_hardware()->SetIsOfficialBuild(is_official_build);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001119 fetcher->set_delegate(&delegate);
1120
1121 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1122 StartTransfer,
1123 fetcher.get(),
1124 LocalServerUrlForPath(server->GetPort(),
1125 fetcher_test->SmallUrl(server->GetPort()))));
1126 MessageLoop::current()->Run();
1127}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001128} // namespace
1129
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001130TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001131 BlockedTransferTestHelper(&this->test_, false);
1132}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001133
Alex Deymo60ca1a72015-06-18 18:19:15 -07001134TYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) {
1135 BlockedTransferTestHelper(&this->test_, true);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001136}
1137
rspangler@google.com49fdf182009-10-10 00:57:34 +00001138} // namespace chromeos_update_engine