blob: 00ea12868c9662a7f7192de4a73fd7d1f88efb7d [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
Tao Bao642b32b2019-01-02 15:33:42 -080022#include <algorithm>
Ben Chan02f7c1d2014-10-18 15:18:02 -070023#include <memory>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000024#include <string>
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070025#include <utility>
adlr@google.comc98a7ed2009-12-04 18:54:03 +000026#include <vector>
Darin Petkov41c2fcf2010-08-25 13:14:48 -070027
Alex Deymo706a5ab2015-11-23 17:48:30 -030028#include <base/bind.h>
Alex Deymo60ca1a72015-06-18 18:19:15 -070029#include <base/location.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080030#include <base/logging.h>
Alex Deymo535f3b72015-08-07 10:51:32 -070031#include <base/message_loop/message_loop.h>
32#include <base/strings/string_number_conversions.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070033#include <base/strings/string_util.h>
34#include <base/strings/stringprintf.h>
35#include <base/time/time.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 Deymo2c131bb2016-05-26 16:43:13 -070045#include "update_engine/common/file_fetcher.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080046#include "update_engine/common/http_common.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080047#include "update_engine/common/mock_http_fetcher.h"
Sen Jiangd8be4b52018-09-18 16:06:57 -070048#include "update_engine/common/mock_proxy_resolver.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080049#include "update_engine/common/multi_range_http_fetcher.h"
Sen Jiangd8be4b52018-09-18 16:06:57 -070050#include "update_engine/common/proxy_resolver.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080051#include "update_engine/common/test_utils.h"
52#include "update_engine/common/utils.h"
Alex Deymo14c0da82016-07-20 16:45:45 -070053#include "update_engine/libcurl_http_fetcher.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000054
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070055using brillo::MessageLoop;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070056using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080057using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000058using std::string;
Ben Chan02f7c1d2014-10-18 15:18:02 -070059using std::unique_ptr;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000060using std::vector;
Alex Deymof2858572016-02-25 11:20:13 -080061using testing::DoAll;
62using testing::Return;
63using testing::SaveArg;
64using testing::_;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000065
Gilad Arnold9bedeb52011-11-17 16:19:57 -080066namespace {
67
68const int kBigLength = 100000;
69const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080070const int kFlakyTruncateLength = 29000;
71const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080072const int kFlakySleepSecs = 10;
73
74} // namespace
75
rspangler@google.com49fdf182009-10-10 00:57:34 +000076namespace chromeos_update_engine {
77
Gilad Arnold9bedeb52011-11-17 16:19:57 -080078static const char *kUnusedUrl = "unused://unused";
79
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070080static inline string LocalServerUrlForPath(in_port_t port,
81 const string& path) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070082 string port_str = (port ? base::StringPrintf(":%hu", port) : "");
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070083 return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
84 path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000085}
86
Gilad Arnold9bedeb52011-11-17 16:19:57 -080087//
88// Class hierarchy for HTTP server implementations.
89//
90
91class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000092 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080093 // This makes it an abstract class (dirty but works).
94 virtual ~HttpServer() = 0;
95
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070096 virtual in_port_t GetPort() const {
97 return 0;
98 }
99
rspangler@google.com49fdf182009-10-10 00:57:34 +0000100 bool started_;
101};
102
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800103HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +0000104
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800105
106class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000107 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800108 NullHttpServer() {
109 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000110 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000111};
112
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800113
114class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000115 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700116 PythonHttpServer() : port_(0) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000117 started_ = false;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700118
119 // Spawn the server process.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700120 unique_ptr<brillo::Process> http_server(new brillo::ProcessImpl());
Sen Jiang260f03b2016-03-21 15:34:58 -0700121 http_server->AddArg(test_utils::GetBuildArtifactsPath("test_http_server"));
Alex Deymo535f3b72015-08-07 10:51:32 -0700122 http_server->RedirectUsingPipe(STDOUT_FILENO, false);
123
124 if (!http_server->Start()) {
125 ADD_FAILURE() << "failed to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000126 return;
127 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700128 LOG(INFO) << "started http server with pid " << http_server->pid();
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700129
130 // Wait for server to begin accepting connections, obtain its port.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700131 brillo::StreamPtr stdout = brillo::FileStream::FromFileDescriptor(
Alex Deymo535f3b72015-08-07 10:51:32 -0700132 http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr);
133 if (!stdout)
134 return;
135
136 vector<char> buf(128);
137 string line;
138 while (line.find('\n') == string::npos) {
139 size_t read;
140 if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) {
141 ADD_FAILURE() << "error reading http server stdout";
142 return;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700143 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700144 line.append(buf.data(), read);
145 if (read == 0)
146 break;
147 }
148 // Parse the port from the output line.
149 const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
150 if (line.size() < listening_msg_prefix_len) {
151 ADD_FAILURE() << "server output too short";
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700152 return;
153 }
154
Alex Deymo535f3b72015-08-07 10:51:32 -0700155 EXPECT_EQ(kServerListeningMsgPrefix,
156 line.substr(0, listening_msg_prefix_len));
157 string port_str = line.substr(listening_msg_prefix_len);
158 port_str.resize(port_str.find('\n'));
159 EXPECT_TRUE(base::StringToUint(port_str, &port_));
160
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700161 started_ = true;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700162 LOG(INFO) << "server running, listening on port " << port_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700163
164 // Any failure before this point will SIGKILL the test server if started
165 // when the |http_server| goes out of scope.
166 http_server_ = std::move(http_server);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800168
rspangler@google.com49fdf182009-10-10 00:57:34 +0000169 ~PythonHttpServer() {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700170 // If there's no process, do nothing.
Alex Deymo535f3b72015-08-07 10:51:32 -0700171 if (!http_server_)
rspangler@google.com49fdf182009-10-10 00:57:34 +0000172 return;
Alex Deymo535f3b72015-08-07 10:51:32 -0700173 // Wait up to 10 seconds for the process to finish. Destroying the process
174 // will kill it with a SIGKILL otherwise.
175 http_server_->Kill(SIGTERM, 10);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000176 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800177
Alex Deymo610277e2014-11-11 21:18:11 -0800178 in_port_t GetPort() const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700179 return port_;
180 }
181
182 private:
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700183 static const char* kServerListeningMsgPrefix;
184
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700185 unique_ptr<brillo::Process> http_server_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700186 unsigned int port_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000187};
188
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700189const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
190
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800191//
192// Class hierarchy for HTTP fetcher test wrappers.
193//
194
195class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000196 public:
Chris Sosa77f79e82014-06-02 18:16:24 -0700197 AnyHttpFetcherTest() {}
Alex Deymoc4acdf42014-05-28 21:07:10 -0700198 virtual ~AnyHttpFetcherTest() {}
Jay Srinivasan43488792012-06-19 00:25:31 -0700199
Alex Deymof2858572016-02-25 11:20:13 -0800200 virtual HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) = 0;
201 HttpFetcher* NewLargeFetcher(size_t num_proxies) {
202 proxy_resolver_.set_num_proxies(num_proxies);
203 return NewLargeFetcher(&proxy_resolver_);
204 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800205 HttpFetcher* NewLargeFetcher() {
206 return NewLargeFetcher(1);
207 }
208
Alex Deymof2858572016-02-25 11:20:13 -0800209 virtual HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800210 HttpFetcher* NewSmallFetcher() {
Alex Deymof2858572016-02-25 11:20:13 -0800211 proxy_resolver_.set_num_proxies(1);
212 return NewSmallFetcher(&proxy_resolver_);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800213 }
214
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700215 virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
216 virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
217 virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800218
219 virtual bool IsMock() const = 0;
220 virtual bool IsMulti() const = 0;
Alex Deymo2c131bb2016-05-26 16:43:13 -0700221 virtual bool IsHttpSupported() const = 0;
Tao Bao642b32b2019-01-02 15:33:42 -0800222 virtual bool IsFileFetcher() const = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800223
224 virtual void IgnoreServerAborting(HttpServer* server) const {}
225
Alex Deymo60ca1a72015-06-18 18:19:15 -0700226 virtual HttpServer* CreateServer() = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800227
Alex Deymoc1c17b42015-11-23 03:53:15 -0300228 FakeHardware* fake_hardware() {
Alex Deymo706a5ab2015-11-23 17:48:30 -0300229 return &fake_hardware_;
Alex Deymoc1c17b42015-11-23 03:53:15 -0300230 }
231
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800232 protected:
233 DirectProxyResolver proxy_resolver_;
Alex Deymo706a5ab2015-11-23 17:48:30 -0300234 FakeHardware fake_hardware_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800235};
236
237class MockHttpFetcherTest : public AnyHttpFetcherTest {
238 public:
239 // Necessary to unhide the definition in the base class.
240 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800241 HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700242 brillo::Blob big_data(1000000);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800243 return new MockHttpFetcher(
Alex Deymof2858572016-02-25 11:20:13 -0800244 big_data.data(), big_data.size(), proxy_resolver);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800245 }
246
247 // Necessary to unhide the definition in the base class.
248 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800249 HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
250 return new MockHttpFetcher("x", 1, proxy_resolver);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800251 }
252
Alex Deymo610277e2014-11-11 21:18:11 -0800253 bool IsMock() const override { return true; }
254 bool IsMulti() const override { return false; }
Alex Deymo2c131bb2016-05-26 16:43:13 -0700255 bool IsHttpSupported() const override { return true; }
Tao Bao642b32b2019-01-02 15:33:42 -0800256 bool IsFileFetcher() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800257
Alex Deymo60ca1a72015-06-18 18:19:15 -0700258 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800259 return new NullHttpServer;
260 }
261};
262
263class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
264 public:
265 // Necessary to unhide the definition in the base class.
266 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800267 HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
268 LibcurlHttpFetcher* ret =
269 new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700270 // Speed up test execution.
271 ret->set_idle_seconds(1);
272 ret->set_retry_seconds(1);
Alex Deymo706a5ab2015-11-23 17:48:30 -0300273 fake_hardware_.SetIsOfficialBuild(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000274 return ret;
275 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800276
277 // Necessary to unhide the definition in the base class.
278 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800279 HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
280 return NewLargeFetcher(proxy_resolver);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000281 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800282
Alex Deymo610277e2014-11-11 21:18:11 -0800283 string BigUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700284 return LocalServerUrlForPath(port,
285 base::StringPrintf("/download/%d",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800286 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000287 }
Alex Deymo610277e2014-11-11 21:18:11 -0800288 string SmallUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700289 return LocalServerUrlForPath(port, "/foo");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000290 }
Alex Deymo610277e2014-11-11 21:18:11 -0800291 string ErrorUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700292 return LocalServerUrlForPath(port, "/error");
Gilad Arnold48085ba2011-11-16 09:36:08 -0800293 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800294
Alex Deymo610277e2014-11-11 21:18:11 -0800295 bool IsMock() const override { return false; }
296 bool IsMulti() const override { return false; }
Alex Deymo2c131bb2016-05-26 16:43:13 -0700297 bool IsHttpSupported() const override { return true; }
Tao Bao642b32b2019-01-02 15:33:42 -0800298 bool IsFileFetcher() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800299
Alex Deymo610277e2014-11-11 21:18:11 -0800300 void IgnoreServerAborting(HttpServer* server) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700301 // Nothing to do.
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700302 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800303
Alex Deymo60ca1a72015-06-18 18:19:15 -0700304 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800305 return new PythonHttpServer;
306 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000307};
308
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800309class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700310 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800311 // Necessary to unhide the definition in the base class.
312 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800313 HttpFetcher* NewLargeFetcher(ProxyResolver* proxy_resolver) override {
314 MultiRangeHttpFetcher* ret = new MultiRangeHttpFetcher(
315 new LibcurlHttpFetcher(proxy_resolver, &fake_hardware_));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800316 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800317 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700318 // Speed up test execution.
319 ret->set_idle_seconds(1);
320 ret->set_retry_seconds(1);
Alex Deymo706a5ab2015-11-23 17:48:30 -0300321 fake_hardware_.SetIsOfficialBuild(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700322 return ret;
323 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800324
325 // Necessary to unhide the definition in the base class.
326 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymof2858572016-02-25 11:20:13 -0800327 HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
328 return NewLargeFetcher(proxy_resolver);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800329 }
330
Alex Deymo610277e2014-11-11 21:18:11 -0800331 bool IsMulti() const override { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700332};
333
Alex Deymo2c131bb2016-05-26 16:43:13 -0700334class FileFetcherTest : public AnyHttpFetcherTest {
335 public:
336 // Necessary to unhide the definition in the base class.
337 using AnyHttpFetcherTest::NewLargeFetcher;
338 HttpFetcher* NewLargeFetcher(ProxyResolver* /* proxy_resolver */) override {
339 return new FileFetcher();
340 }
341
342 // Necessary to unhide the definition in the base class.
343 using AnyHttpFetcherTest::NewSmallFetcher;
344 HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
345 return NewLargeFetcher(proxy_resolver);
346 }
347
348 string BigUrl(in_port_t port) const override {
Tao Bao642b32b2019-01-02 15:33:42 -0800349 static string big_contents = []() {
350 string buf;
351 buf.reserve(kBigLength);
352 constexpr const char* kBigUrlContent = "abcdefghij";
353 for (size_t i = 0; i < kBigLength; i += strlen(kBigUrlContent)) {
354 buf.append(kBigUrlContent,
355 std::min(kBigLength - i, strlen(kBigUrlContent)));
356 }
357 return buf;
358 }();
359 test_utils::WriteFileString(temp_file_.path(), big_contents);
Alex Deymo2c131bb2016-05-26 16:43:13 -0700360 return "file://" + temp_file_.path();
361 }
362 string SmallUrl(in_port_t port) const override {
363 test_utils::WriteFileString(temp_file_.path(), "small contents");
364 return "file://" + temp_file_.path();
365 }
366 string ErrorUrl(in_port_t port) const override {
367 return "file:///path/to/non-existing-file";
368 }
369
370 bool IsMock() const override { return false; }
371 bool IsMulti() const override { return false; }
372 bool IsHttpSupported() const override { return false; }
Tao Bao642b32b2019-01-02 15:33:42 -0800373 bool IsFileFetcher() const override { return true; }
Alex Deymo2c131bb2016-05-26 16:43:13 -0700374
375 void IgnoreServerAborting(HttpServer* server) const override {}
376
377 HttpServer* CreateServer() override { return new NullHttpServer; }
378
379 private:
380 test_utils::ScopedTempFile temp_file_{"ue_file_fetcher.XXXXXX"};
381};
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800382
Tao Bao642b32b2019-01-02 15:33:42 -0800383class MultiRangeHttpFetcherOverFileFetcherTest : public FileFetcherTest {
384 public:
385 // Necessary to unhide the definition in the base class.
386 using AnyHttpFetcherTest::NewLargeFetcher;
387 HttpFetcher* NewLargeFetcher(ProxyResolver* /* proxy_resolver */) override {
388 MultiRangeHttpFetcher* ret = new MultiRangeHttpFetcher(new FileFetcher());
389 ret->ClearRanges();
390 // FileFetcher doesn't support range with unspecified length.
391 ret->AddRange(0, 1);
392 // Speed up test execution.
393 ret->set_idle_seconds(1);
394 ret->set_retry_seconds(1);
395 fake_hardware_.SetIsOfficialBuild(false);
396 return ret;
397 }
398
399 // Necessary to unhide the definition in the base class.
400 using AnyHttpFetcherTest::NewSmallFetcher;
401 HttpFetcher* NewSmallFetcher(ProxyResolver* proxy_resolver) override {
402 return NewLargeFetcher(proxy_resolver);
403 }
404
405 bool IsMulti() const override { return true; }
406};
407
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800408//
409// Infrastructure for type tests of HTTP fetcher.
410// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
411//
412
413// Fixture class template. We use an explicit constraint to guarantee that it
414// can only be instantiated with an AnyHttpFetcherTest type, see:
415// http://www2.research.att.com/~bs/bs_faq2.html#constraints
416template <typename T>
417class HttpFetcherTest : public ::testing::Test {
418 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700419 base::MessageLoopForIO base_loop_;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700420 brillo::BaseMessageLoop loop_{&base_loop_};
Alex Deymo60ca1a72015-06-18 18:19:15 -0700421
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800422 T test_;
423
Alex Deymo60ca1a72015-06-18 18:19:15 -0700424 protected:
425 HttpFetcherTest() {
426 loop_.SetAsCurrent();
427 }
428
429 void TearDown() override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700430 EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1));
Alex Deymo60ca1a72015-06-18 18:19:15 -0700431 }
432
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800433 private:
Alex Deymo60ca1a72015-06-18 18:19:15 -0700434 static void TypeConstraint(T* a) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800435 AnyHttpFetcherTest *b = a;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700436 if (b == 0) // Silence compiler warning of unused variable.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700437 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800438 }
439};
440
441// Test case types list.
442typedef ::testing::Types<LibcurlHttpFetcherTest,
443 MockHttpFetcherTest,
Alex Deymo2c131bb2016-05-26 16:43:13 -0700444 MultiRangeHttpFetcherTest,
Tao Bao642b32b2019-01-02 15:33:42 -0800445 FileFetcherTest,
446 MultiRangeHttpFetcherOverFileFetcherTest>
Alex Deymo2c131bb2016-05-26 16:43:13 -0700447 HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000448TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
449
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800450
rspangler@google.com49fdf182009-10-10 00:57:34 +0000451namespace {
452class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000453 public:
Alex Deymofdd6dec2016-03-03 22:35:43 -0800454 HttpFetcherTestDelegate() = default;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800455
Amin Hassani0cd9d772018-07-31 23:55:43 -0700456 bool ReceivedBytes(HttpFetcher* /* fetcher */,
Alex Deymofdd6dec2016-03-03 22:35:43 -0800457 const void* bytes,
458 size_t length) override {
459 data.append(reinterpret_cast<const char*>(bytes), length);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800460 // Update counters
461 times_received_bytes_called_++;
Amin Hassani0cd9d772018-07-31 23:55:43 -0700462 return true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000463 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800464
Alex Deymo610277e2014-11-11 21:18:11 -0800465 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800466 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800467 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800468 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800469 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700470 MessageLoop::current()->BreakLoop();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800471
472 // Update counter
473 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000474 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800475
Alex Deymo610277e2014-11-11 21:18:11 -0800476 void TransferTerminated(HttpFetcher* fetcher) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800477 times_transfer_terminated_called_++;
Alex Deymo2c131bb2016-05-26 16:43:13 -0700478 MessageLoop::current()->BreakLoop();
Darin Petkov9ce452b2010-11-17 14:33:28 -0800479 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800480
Gilad Arnold48085ba2011-11-16 09:36:08 -0800481 // Are we expecting an error response? (default: no)
Alex Deymofdd6dec2016-03-03 22:35:43 -0800482 bool is_expect_error_{false};
Gilad Arnold48085ba2011-11-16 09:36:08 -0800483
484 // Counters for callback invocations.
Alex Deymofdd6dec2016-03-03 22:35:43 -0800485 int times_transfer_complete_called_{0};
486 int times_transfer_terminated_called_{0};
487 int times_received_bytes_called_{0};
488
489 // The received data bytes.
490 string data;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000491};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000492
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000493
Alex Deymo60ca1a72015-06-18 18:19:15 -0700494void StartTransfer(HttpFetcher* http_fetcher, const string& url) {
495 http_fetcher->BeginTransfer(url);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000496}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700497} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000498
499TYPED_TEST(HttpFetcherTest, SimpleTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700500 HttpFetcherTestDelegate delegate;
501 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
502 fetcher->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000503
Alex Deymo60ca1a72015-06-18 18:19:15 -0700504 unique_ptr<HttpServer> server(this->test_.CreateServer());
505 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000506
Alex Deymo60ca1a72015-06-18 18:19:15 -0700507 this->loop_.PostTask(FROM_HERE, base::Bind(
508 StartTransfer,
509 fetcher.get(),
510 this->test_.SmallUrl(server->GetPort())));
511 this->loop_.Run();
Alex Deymo71f67622017-02-03 21:30:24 -0800512 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000513}
514
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700515TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700516 HttpFetcherTestDelegate delegate;
517 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
518 fetcher->set_delegate(&delegate);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700519
Alex Deymo60ca1a72015-06-18 18:19:15 -0700520 unique_ptr<HttpServer> server(this->test_.CreateServer());
521 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700522
Alex Deymo60ca1a72015-06-18 18:19:15 -0700523 this->loop_.PostTask(FROM_HERE, base::Bind(
524 StartTransfer,
525 fetcher.get(),
526 this->test_.BigUrl(server->GetPort())));
527 this->loop_.Run();
Alex Deymo71f67622017-02-03 21:30:24 -0800528 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700529}
530
Gilad Arnold48085ba2011-11-16 09:36:08 -0800531// Issue #9648: when server returns an error HTTP response, the fetcher needs to
532// terminate transfer prematurely, rather than try to process the error payload.
533TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800534 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800535 return;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700536 HttpFetcherTestDelegate delegate;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800537
Alex Deymo60ca1a72015-06-18 18:19:15 -0700538 // Delegate should expect an error response.
539 delegate.is_expect_error_ = true;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800540
Alex Deymo60ca1a72015-06-18 18:19:15 -0700541 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
542 fetcher->set_delegate(&delegate);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800543
Alex Deymo60ca1a72015-06-18 18:19:15 -0700544 unique_ptr<HttpServer> server(this->test_.CreateServer());
545 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800546
Alex Deymo60ca1a72015-06-18 18:19:15 -0700547 this->loop_.PostTask(FROM_HERE, base::Bind(
548 StartTransfer,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800549 fetcher.get(),
Alex Deymo60ca1a72015-06-18 18:19:15 -0700550 this->test_.ErrorUrl(server->GetPort())));
551 this->loop_.Run();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800552
Alex Deymo60ca1a72015-06-18 18:19:15 -0700553 // Make sure that no bytes were received.
Alex Deymo71f67622017-02-03 21:30:24 -0800554 EXPECT_EQ(0, delegate.times_received_bytes_called_);
555 EXPECT_EQ(0U, fetcher->GetBytesDownloaded());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800556
Alex Deymo60ca1a72015-06-18 18:19:15 -0700557 // Make sure that transfer completion was signaled once, and no termination
558 // was signaled.
Alex Deymo71f67622017-02-03 21:30:24 -0800559 EXPECT_EQ(1, delegate.times_transfer_complete_called_);
560 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800561}
562
Alex Deymofdd6dec2016-03-03 22:35:43 -0800563TYPED_TEST(HttpFetcherTest, ExtraHeadersInRequestTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -0700564 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
Alex Deymofdd6dec2016-03-03 22:35:43 -0800565 return;
566
567 HttpFetcherTestDelegate delegate;
568 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
569 fetcher->set_delegate(&delegate);
570 fetcher->SetHeader("User-Agent", "MyTest");
571 fetcher->SetHeader("user-agent", "Override that header");
572 fetcher->SetHeader("Authorization", "Basic user:passwd");
573
574 // Invalid headers.
575 fetcher->SetHeader("X-Foo", "Invalid\nHeader\nIgnored");
576 fetcher->SetHeader("X-Bar: ", "I do not know how to parse");
577
578 // Hide Accept header normally added by default.
579 fetcher->SetHeader("Accept", "");
580
581 PythonHttpServer server;
582 int port = server.GetPort();
583 ASSERT_TRUE(server.started_);
584
Alex Deymo2c131bb2016-05-26 16:43:13 -0700585 this->loop_.PostTask(
586 FROM_HERE,
587 base::Bind(StartTransfer,
588 fetcher.get(),
589 LocalServerUrlForPath(port, "/echo-headers")));
Alex Deymofdd6dec2016-03-03 22:35:43 -0800590 this->loop_.Run();
591
592 EXPECT_NE(string::npos,
593 delegate.data.find("user-agent: Override that header\r\n"));
594 EXPECT_NE(string::npos,
595 delegate.data.find("Authorization: Basic user:passwd\r\n"));
596
597 EXPECT_EQ(string::npos, delegate.data.find("\nAccept:"));
598 EXPECT_EQ(string::npos, delegate.data.find("X-Foo: Invalid"));
599 EXPECT_EQ(string::npos, delegate.data.find("X-Bar: I do not"));
600}
601
rspangler@google.com49fdf182009-10-10 00:57:34 +0000602namespace {
603class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
604 public:
Amin Hassani0cd9d772018-07-31 23:55:43 -0700605 bool ReceivedBytes(HttpFetcher* fetcher,
606 const void* /* bytes */,
607 size_t /* length */) override {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000608 CHECK(!paused_);
609 paused_ = true;
610 fetcher->Pause();
Amin Hassani0cd9d772018-07-31 23:55:43 -0700611 return true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000612 }
Alex Deymo610277e2014-11-11 21:18:11 -0800613 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700614 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000615 }
Alex Deymo610277e2014-11-11 21:18:11 -0800616 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800617 ADD_FAILURE();
618 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000619 void Unpause() {
620 CHECK(paused_);
621 paused_ = false;
622 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000623 }
624 bool paused_;
625 HttpFetcher* fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000626};
627
Alex Deymo60ca1a72015-06-18 18:19:15 -0700628void UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate,
629 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000630 if (delegate->paused_)
631 delegate->Unpause();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700632 // Update the task id with the new scheduled callback.
633 *my_id = MessageLoop::current()->PostDelayedTask(
634 FROM_HERE,
635 base::Bind(&UnpausingTimeoutCallback, delegate, my_id),
636 base::TimeDelta::FromMilliseconds(200));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000637}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700638} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000639
640TYPED_TEST(HttpFetcherTest, PauseTest) {
Alex Deymof2858572016-02-25 11:20:13 -0800641 PausingHttpFetcherTestDelegate delegate;
642 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
643 delegate.paused_ = false;
644 delegate.fetcher_ = fetcher.get();
645 fetcher->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000646
Alex Deymof2858572016-02-25 11:20:13 -0800647 unique_ptr<HttpServer> server(this->test_.CreateServer());
648 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800649
Alex Deymof2858572016-02-25 11:20:13 -0800650 MessageLoop::TaskId callback_id;
651 callback_id = this->loop_.PostDelayedTask(
652 FROM_HERE,
653 base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
654 base::TimeDelta::FromMilliseconds(200));
655 fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000656
Alex Deymof2858572016-02-25 11:20:13 -0800657 this->loop_.Run();
658 EXPECT_TRUE(this->loop_.CancelTask(callback_id));
659}
660
661// This test will pause the fetcher while the download is not yet started
662// because it is waiting for the proxy to be resolved.
663TYPED_TEST(HttpFetcherTest, PauseWhileResolvingProxyTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -0700664 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
Alex Deymof2858572016-02-25 11:20:13 -0800665 return;
666 MockProxyResolver mock_resolver;
667 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher(&mock_resolver));
668
669 // Saved arguments from the proxy call.
Alex Deymo35821942017-02-05 04:36:02 +0000670 ProxiesResolvedFn proxy_callback;
671 EXPECT_CALL(mock_resolver, GetProxiesForUrl("http://fake_url", _))
672 .WillOnce(DoAll(SaveArg<1>(&proxy_callback), Return(true)));
Alex Deymof2858572016-02-25 11:20:13 -0800673 fetcher->BeginTransfer("http://fake_url");
674 testing::Mock::VerifyAndClearExpectations(&mock_resolver);
675
676 // Pausing and unpausing while resolving the proxy should not affect anything.
677 fetcher->Pause();
678 fetcher->Unpause();
679 fetcher->Pause();
680 // Proxy resolver comes back after we paused the fetcher.
Alex Deymoc00ec562017-02-05 04:36:02 +0000681 ASSERT_FALSE(proxy_callback.is_null());
Alex Deymo35821942017-02-05 04:36:02 +0000682 proxy_callback.Run({1, kNoProxy});
rspangler@google.com49fdf182009-10-10 00:57:34 +0000683}
684
685namespace {
686class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
687 public:
Amin Hassani0cd9d772018-07-31 23:55:43 -0700688 bool ReceivedBytes(HttpFetcher* fetcher,
689 const void* bytes,
690 size_t length) override {
691 return true;
692 }
Alex Deymo610277e2014-11-11 21:18:11 -0800693 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800694 ADD_FAILURE(); // We should never get here
Alex Deymo60ca1a72015-06-18 18:19:15 -0700695 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000696 }
Alex Deymo610277e2014-11-11 21:18:11 -0800697 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800698 EXPECT_EQ(fetcher, fetcher_.get());
699 EXPECT_FALSE(once_);
700 EXPECT_TRUE(callback_once_);
701 callback_once_ = false;
Alex Deymoc4acdf42014-05-28 21:07:10 -0700702 // The fetcher could have a callback scheduled on the ProxyResolver that
703 // can fire after this callback. We wait until the end of the test to
704 // delete the fetcher.
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800705 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000706 void TerminateTransfer() {
707 CHECK(once_);
708 once_ = false;
709 fetcher_->TerminateTransfer();
710 }
711 void EndLoop() {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700712 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000713 }
714 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800715 bool callback_once_;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700716 unique_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000717};
718
Alex Deymo60ca1a72015-06-18 18:19:15 -0700719void AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate,
720 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000721 if (delegate->once_) {
722 delegate->TerminateTransfer();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700723 *my_id = MessageLoop::current()->PostTask(
724 FROM_HERE,
725 base::Bind(AbortingTimeoutCallback, delegate, my_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000726 } else {
727 delegate->EndLoop();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700728 *my_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000729 }
730}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700731} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000732
733TYPED_TEST(HttpFetcherTest, AbortTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700734 AbortingHttpFetcherTestDelegate delegate;
735 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
736 delegate.once_ = true;
737 delegate.callback_once_ = true;
738 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000739
Alex Deymo60ca1a72015-06-18 18:19:15 -0700740 unique_ptr<HttpServer> server(this->test_.CreateServer());
741 this->test_.IgnoreServerAborting(server.get());
742 ASSERT_TRUE(server->started_);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800743
Alex Deymo60ca1a72015-06-18 18:19:15 -0700744 MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000745
Alex Deymo60ca1a72015-06-18 18:19:15 -0700746 task_id = this->loop_.PostTask(
747 FROM_HERE,
748 base::Bind(AbortingTimeoutCallback, &delegate, &task_id));
749 delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
750
751 this->loop_.Run();
752 CHECK(!delegate.once_);
753 CHECK(!delegate.callback_once_);
754 this->loop_.CancelTask(task_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000755}
756
Alex Deymo71f67622017-02-03 21:30:24 -0800757TYPED_TEST(HttpFetcherTest, TerminateTransferWhileResolvingProxyTest) {
758 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
759 return;
760 MockProxyResolver mock_resolver;
761 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher(&mock_resolver));
762
763 HttpFetcherTestDelegate delegate;
764 fetcher->set_delegate(&delegate);
765
766 EXPECT_CALL(mock_resolver, GetProxiesForUrl(_, _)).WillOnce(Return(123));
767 fetcher->BeginTransfer("http://fake_url");
768 // Run the message loop until idle. This must call the MockProxyResolver with
769 // the request.
770 while (this->loop_.RunOnce(false)) {
771 }
772 testing::Mock::VerifyAndClearExpectations(&mock_resolver);
773
774 EXPECT_CALL(mock_resolver, CancelProxyRequest(123)).WillOnce(Return(true));
775
776 // Terminate the transfer right before the proxy resolution response.
777 fetcher->TerminateTransfer();
778 EXPECT_EQ(0, delegate.times_received_bytes_called_);
779 EXPECT_EQ(0, delegate.times_transfer_complete_called_);
780 EXPECT_EQ(1, delegate.times_transfer_terminated_called_);
781}
782
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000783namespace {
784class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
785 public:
Amin Hassani0cd9d772018-07-31 23:55:43 -0700786 bool ReceivedBytes(HttpFetcher* fetcher,
787 const void* bytes,
788 size_t length) override {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800789 data.append(reinterpret_cast<const char*>(bytes), length);
Amin Hassani0cd9d772018-07-31 23:55:43 -0700790 return true;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000791 }
Alex Deymo610277e2014-11-11 21:18:11 -0800792 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700793 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800794 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700795 MessageLoop::current()->BreakLoop();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000796 }
Alex Deymo610277e2014-11-11 21:18:11 -0800797 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800798 ADD_FAILURE();
799 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000800 string data;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000801};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700802} // namespace
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000803
804TYPED_TEST(HttpFetcherTest, FlakyTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -0700805 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000806 return;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000807 {
808 FlakyHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700809 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000810 fetcher->set_delegate(&delegate);
811
Ben Chan02f7c1d2014-10-18 15:18:02 -0700812 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800813 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000814
Alex Deymo60ca1a72015-06-18 18:19:15 -0700815 this->loop_.PostTask(FROM_HERE, base::Bind(
816 &StartTransfer,
817 fetcher.get(),
818 LocalServerUrlForPath(server->GetPort(),
819 base::StringPrintf("/flaky/%d/%d/%d/%d",
820 kBigLength,
821 kFlakyTruncateLength,
822 kFlakySleepEvery,
823 kFlakySleepSecs))));
824 this->loop_.Run();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000825
826 // verify the data we get back
Alex Deymo80f70ff2016-02-10 16:08:11 -0800827 ASSERT_EQ(kBigLength, static_cast<int>(delegate.data.size()));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800828 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000829 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
830 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
831 }
832 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000833}
834
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700835namespace {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700836// This delegate kills the server attached to it after receiving any bytes.
837// This can be used for testing what happens when you try to fetch data and
838// the server dies.
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700839class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
840 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700841 explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
Alex Deymo60ca1a72015-06-18 18:19:15 -0700842 : server_(server) {}
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700843
Alex Deymo610277e2014-11-11 21:18:11 -0800844 ~FailureHttpFetcherTestDelegate() override {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700845 if (server_) {
846 LOG(INFO) << "Stopping server in destructor";
Alex Deymob20de692017-02-05 07:47:37 +0000847 server_.reset();
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700848 LOG(INFO) << "server stopped";
849 }
850 }
851
Amin Hassani0cd9d772018-07-31 23:55:43 -0700852 bool ReceivedBytes(HttpFetcher* fetcher,
853 const void* bytes,
854 size_t length) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700855 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700856 LOG(INFO) << "Stopping server in ReceivedBytes";
Alex Deymob20de692017-02-05 07:47:37 +0000857 server_.reset();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700858 LOG(INFO) << "server stopped";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700859 }
Amin Hassani0cd9d772018-07-31 23:55:43 -0700860 return true;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700861 }
Alex Deymo610277e2014-11-11 21:18:11 -0800862 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700863 EXPECT_FALSE(successful);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700864 EXPECT_EQ(0, fetcher->http_response_code());
Alex Deymob20de692017-02-05 07:47:37 +0000865 times_transfer_complete_called_++;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700866 MessageLoop::current()->BreakLoop();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700867 }
Alex Deymo610277e2014-11-11 21:18:11 -0800868 void TransferTerminated(HttpFetcher* fetcher) override {
Alex Deymob20de692017-02-05 07:47:37 +0000869 times_transfer_terminated_called_++;
870 MessageLoop::current()->BreakLoop();
Darin Petkov9ce452b2010-11-17 14:33:28 -0800871 }
Alex Deymob20de692017-02-05 07:47:37 +0000872 unique_ptr<PythonHttpServer> server_;
873 int times_transfer_terminated_called_{0};
874 int times_transfer_complete_called_{0};
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700875};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700876} // namespace
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700877
878
879TYPED_TEST(HttpFetcherTest, FailureTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700880 // This test ensures that a fetcher responds correctly when a server isn't
881 // available at all.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800882 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700883 return;
Alex Deymob20de692017-02-05 07:47:37 +0000884 FailureHttpFetcherTestDelegate delegate(nullptr);
885 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
886 fetcher->set_delegate(&delegate);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700887
Alex Deymob20de692017-02-05 07:47:37 +0000888 this->loop_.PostTask(
889 FROM_HERE,
890 base::Bind(
891 StartTransfer, fetcher.get(), "http://host_doesnt_exist99999999"));
892 this->loop_.Run();
893 EXPECT_EQ(1, delegate.times_transfer_complete_called_);
894 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700895
Alex Deymob20de692017-02-05 07:47:37 +0000896 // Exiting and testing happens in the delegate
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700897}
898
Alex Deymof123ae22015-09-24 14:59:43 -0700899TYPED_TEST(HttpFetcherTest, NoResponseTest) {
900 // This test starts a new http server but the server doesn't respond and just
901 // closes the connection.
902 if (this->test_.IsMock())
903 return;
904
905 PythonHttpServer* server = new PythonHttpServer();
906 int port = server->GetPort();
907 ASSERT_TRUE(server->started_);
908
909 // Handles destruction and claims ownership.
910 FailureHttpFetcherTestDelegate delegate(server);
911 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
912 fetcher->set_delegate(&delegate);
913 // The server will not reply at all, so we can limit the execution time of the
914 // test by reducing the low-speed timeout to something small. The test will
915 // finish once the TimeoutCallback() triggers (every second) and the timeout
916 // expired.
917 fetcher->set_low_speed_limit(kDownloadLowSpeedLimitBps, 1);
918
919 this->loop_.PostTask(FROM_HERE, base::Bind(
920 StartTransfer,
921 fetcher.get(),
922 LocalServerUrlForPath(port, "/hang")));
923 this->loop_.Run();
Alex Deymob20de692017-02-05 07:47:37 +0000924 EXPECT_EQ(1, delegate.times_transfer_complete_called_);
925 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
Alex Deymof123ae22015-09-24 14:59:43 -0700926
927 // Check that no other callback runs in the next two seconds. That would
928 // indicate a leaked callback.
929 bool timeout = false;
Luis Hector Chavezf1cf3482016-07-19 14:29:19 -0700930 auto callback = base::Bind([](bool* timeout) { *timeout = true; },
931 base::Unretained(&timeout));
Alex Deymof123ae22015-09-24 14:59:43 -0700932 this->loop_.PostDelayedTask(FROM_HERE, callback,
933 base::TimeDelta::FromSeconds(2));
934 EXPECT_TRUE(this->loop_.RunOnce(true));
935 EXPECT_TRUE(timeout);
936}
937
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700938TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700939 // This test starts a new http server and kills it after receiving its first
940 // set of bytes. It test whether or not our fetcher eventually gives up on
941 // retries and aborts correctly.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800942 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700943 return;
Alex Deymob20de692017-02-05 07:47:37 +0000944 PythonHttpServer* server = new PythonHttpServer();
945 int port = server->GetPort();
946 ASSERT_TRUE(server->started_);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700947
Alex Deymob20de692017-02-05 07:47:37 +0000948 // Handles destruction and claims ownership.
949 FailureHttpFetcherTestDelegate delegate(server);
950 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
951 fetcher->set_delegate(&delegate);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700952
Alex Deymob20de692017-02-05 07:47:37 +0000953 this->loop_.PostTask(
954 FROM_HERE,
955 base::Bind(StartTransfer,
956 fetcher.get(),
957 LocalServerUrlForPath(port,
958 base::StringPrintf("/flaky/%d/%d/%d/%d",
959 kBigLength,
960 kFlakyTruncateLength,
961 kFlakySleepEvery,
962 kFlakySleepSecs))));
963 this->loop_.Run();
964 EXPECT_EQ(1, delegate.times_transfer_complete_called_);
965 EXPECT_EQ(0, delegate.times_transfer_terminated_called_);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700966
Alex Deymob20de692017-02-05 07:47:37 +0000967 // Exiting and testing happens in the delegate
968}
969
970// Test that we can cancel a transfer while it is still trying to connect to the
971// server. This test kills the server after a few bytes are received.
972TYPED_TEST(HttpFetcherTest, TerminateTransferWhenServerDiedTest) {
973 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
974 return;
975
976 PythonHttpServer* server = new PythonHttpServer();
977 int port = server->GetPort();
978 ASSERT_TRUE(server->started_);
979
980 // Handles destruction and claims ownership.
981 FailureHttpFetcherTestDelegate delegate(server);
982 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
983 fetcher->set_delegate(&delegate);
984
985 this->loop_.PostTask(
986 FROM_HERE,
987 base::Bind(StartTransfer,
988 fetcher.get(),
989 LocalServerUrlForPath(port,
990 base::StringPrintf("/flaky/%d/%d/%d/%d",
991 kBigLength,
992 kFlakyTruncateLength,
993 kFlakySleepEvery,
994 kFlakySleepSecs))));
995 // Terminating the transfer after 3 seconds gives it a chance to contact the
996 // server and enter the retry loop.
997 this->loop_.PostDelayedTask(FROM_HERE,
998 base::Bind(&HttpFetcher::TerminateTransfer,
999 base::Unretained(fetcher.get())),
1000 base::TimeDelta::FromSeconds(3));
1001
1002 // Exiting and testing happens in the delegate.
1003 this->loop_.Run();
1004 EXPECT_EQ(0, delegate.times_transfer_complete_called_);
1005 EXPECT_EQ(1, delegate.times_transfer_terminated_called_);
1006
1007 // Check that no other callback runs in the next two seconds. That would
1008 // indicate a leaked callback.
1009 bool timeout = false;
1010 auto callback = base::Bind([](bool* timeout) { *timeout = true; },
1011 base::Unretained(&timeout));
1012 this->loop_.PostDelayedTask(
1013 FROM_HERE, callback, base::TimeDelta::FromSeconds(2));
1014 EXPECT_TRUE(this->loop_.RunOnce(true));
1015 EXPECT_TRUE(timeout);
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -07001016}
1017
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001018namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001019const HttpResponseCode kRedirectCodes[] = {
1020 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
1021 kHttpResponseTempRedirect
1022};
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001023
1024class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
1025 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001026 explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001027 : expected_successful_(expected_successful) {}
Amin Hassani0cd9d772018-07-31 23:55:43 -07001028 bool ReceivedBytes(HttpFetcher* fetcher,
1029 const void* bytes,
1030 size_t length) override {
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -08001031 data.append(reinterpret_cast<const char*>(bytes), length);
Amin Hassani0cd9d772018-07-31 23:55:43 -07001032 return true;
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001033 }
Alex Deymo610277e2014-11-11 21:18:11 -08001034 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001035 EXPECT_EQ(expected_successful_, successful);
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001036 if (expected_successful_) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001037 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001038 } else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001039 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
1040 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -07001041 }
Alex Deymo60ca1a72015-06-18 18:19:15 -07001042 MessageLoop::current()->BreakLoop();
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001043 }
Alex Deymo610277e2014-11-11 21:18:11 -08001044 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001045 ADD_FAILURE();
1046 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001047 bool expected_successful_;
1048 string data;
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001049};
1050
1051// RedirectTest takes ownership of |http_fetcher|.
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001052void RedirectTest(const HttpServer* server,
1053 bool expected_successful,
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001054 const string& url,
1055 HttpFetcher* http_fetcher) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001056 RedirectHttpFetcherTestDelegate delegate(expected_successful);
1057 unique_ptr<HttpFetcher> fetcher(http_fetcher);
1058 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001059
Alex Deymo60ca1a72015-06-18 18:19:15 -07001060 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1061 StartTransfer,
1062 fetcher.get(),
1063 LocalServerUrlForPath(server->GetPort(), url)));
1064 MessageLoop::current()->Run();
1065 if (expected_successful) {
1066 // verify the data we get back
Alex Deymo80f70ff2016-02-10 16:08:11 -08001067 ASSERT_EQ(static_cast<size_t>(kMediumLength), delegate.data.size());
Alex Deymo60ca1a72015-06-18 18:19:15 -07001068 for (int i = 0; i < kMediumLength; i += 10) {
1069 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
1070 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001071 }
1072 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001073}
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001074} // namespace
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001075
1076TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -07001077 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001078 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001079
Ben Chan02f7c1d2014-10-18 15:18:02 -07001080 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001081 ASSERT_TRUE(server->started_);
1082
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001083 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001084 const string url = base::StringPrintf("/redirect/%d/download/%d",
1085 kRedirectCodes[c],
1086 kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001087 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001088 }
1089}
1090
1091TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -07001092 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001093 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001094
Ben Chan02f7c1d2014-10-18 15:18:02 -07001095 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001096 ASSERT_TRUE(server->started_);
1097
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001098 string url;
David Zeuthen34135a92013-08-06 11:16:16 -07001099 for (int r = 0; r < kDownloadMaxRedirects; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001100 url += base::StringPrintf("/redirect/%d",
1101 kRedirectCodes[r % arraysize(kRedirectCodes)]);
1102 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001103 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001104 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001105}
1106
1107TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Alex Deymo2c131bb2016-05-26 16:43:13 -07001108 if (this->test_.IsMock() || !this->test_.IsHttpSupported())
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001109 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001110
Ben Chan02f7c1d2014-10-18 15:18:02 -07001111 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001112 ASSERT_TRUE(server->started_);
1113
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001114 string url;
David Zeuthen34135a92013-08-06 11:16:16 -07001115 for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001116 url += base::StringPrintf("/redirect/%d",
1117 kRedirectCodes[r % arraysize(kRedirectCodes)]);
1118 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001119 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001120 RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -07001121}
1122
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001123namespace {
1124class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
1125 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001126 explicit MultiHttpFetcherTestDelegate(int expected_response_code)
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001127 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001128
Amin Hassani0cd9d772018-07-31 23:55:43 -07001129 bool ReceivedBytes(HttpFetcher* fetcher,
1130 const void* bytes,
1131 size_t length) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001132 EXPECT_EQ(fetcher, fetcher_.get());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -08001133 data.append(reinterpret_cast<const char*>(bytes), length);
Amin Hassani0cd9d772018-07-31 23:55:43 -07001134 return true;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001135 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001136
Alex Deymo610277e2014-11-11 21:18:11 -08001137 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001138 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001139 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001140 if (expected_response_code_ != 0)
1141 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -08001142 // Destroy the fetcher (because we're allowed to).
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001143 fetcher_.reset(nullptr);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001144 MessageLoop::current()->BreakLoop();
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001145 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001146
Alex Deymo610277e2014-11-11 21:18:11 -08001147 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001148 ADD_FAILURE();
1149 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001150
Ben Chan02f7c1d2014-10-18 15:18:02 -07001151 unique_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001152 int expected_response_code_;
1153 string data;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001154};
1155
1156void MultiTest(HttpFetcher* fetcher_in,
Alex Deymoc1c17b42015-11-23 03:53:15 -03001157 FakeHardware* fake_hardware,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001158 const string& url,
Ben Chanf9cb98c2014-09-21 18:31:30 -07001159 const vector<pair<off_t, off_t>>& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001160 const string& expected_prefix,
Alex Deymo5fe0c4e2016-02-16 18:46:24 -08001161 size_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001162 HttpResponseCode expected_response_code) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001163 MultiHttpFetcherTestDelegate delegate(expected_response_code);
1164 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -07001165
Alex Deymo60ca1a72015-06-18 18:19:15 -07001166 MultiRangeHttpFetcher* multi_fetcher =
Alex Deymo80f70ff2016-02-10 16:08:11 -08001167 static_cast<MultiRangeHttpFetcher*>(fetcher_in);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001168 ASSERT_TRUE(multi_fetcher);
1169 multi_fetcher->ClearRanges();
1170 for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
1171 e = ranges.end(); it != e; ++it) {
1172 string tmp_str = base::StringPrintf("%jd+", it->first);
1173 if (it->second > 0) {
1174 base::StringAppendF(&tmp_str, "%jd", it->second);
1175 multi_fetcher->AddRange(it->first, it->second);
1176 } else {
1177 base::StringAppendF(&tmp_str, "?");
1178 multi_fetcher->AddRange(it->first);
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001179 }
Alex Deymo60ca1a72015-06-18 18:19:15 -07001180 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001181 }
Alex Deymoc1c17b42015-11-23 03:53:15 -03001182 fake_hardware->SetIsOfficialBuild(false);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001183 multi_fetcher->set_delegate(&delegate);
1184
1185 MessageLoop::current()->PostTask(
1186 FROM_HERE,
1187 base::Bind(StartTransfer, multi_fetcher, url));
1188 MessageLoop::current()->Run();
1189
1190 EXPECT_EQ(expected_size, delegate.data.size());
1191 EXPECT_EQ(expected_prefix,
1192 string(delegate.data.data(), expected_prefix.size()));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001193}
Alex Vakulenkod2779df2014-06-16 13:19:00 -07001194} // namespace
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001195
Darin Petkov9ce452b2010-11-17 14:33:28 -08001196TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001197 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001198 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001199
Ben Chan02f7c1d2014-10-18 15:18:02 -07001200 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001201 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001202
Ben Chanf9cb98c2014-09-21 18:31:30 -07001203 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001204 ranges.push_back(make_pair(0, 25));
Tao Bao642b32b2019-01-02 15:33:42 -08001205 ranges.push_back(make_pair(99, 17));
1206 MultiTest(this->test_.NewLargeFetcher(),
1207 this->test_.fake_hardware(),
1208 this->test_.BigUrl(server->GetPort()),
1209 ranges,
1210 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1211 25 + 17,
1212 this->test_.IsFileFetcher() ? kHttpResponseOk
1213 : kHttpResponsePartialContent);
1214}
1215
1216TYPED_TEST(HttpFetcherTest, MultiHttpFetcherUnspecifiedEndTest) {
1217 if (!this->test_.IsMulti() || this->test_.IsFileFetcher())
1218 return;
1219
1220 unique_ptr<HttpServer> server(this->test_.CreateServer());
1221 ASSERT_TRUE(server->started_);
1222
1223 vector<pair<off_t, off_t>> ranges;
1224 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001225 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001226 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001227 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001228 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001229 ranges,
1230 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001231 kBigLength - (99 - 25),
1232 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001233}
1234
1235TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001236 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001237 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001238
Ben Chan02f7c1d2014-10-18 15:18:02 -07001239 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001240 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001241
Ben Chanf9cb98c2014-09-21 18:31:30 -07001242 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001243 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001244 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001245 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001246 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001247 ranges,
1248 "abcdefghijabcdefghijabcd",
1249 24,
Tao Bao642b32b2019-01-02 15:33:42 -08001250 this->test_.IsFileFetcher() ? kHttpResponseOk
1251 : kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001252}
1253
1254TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Tao Bao642b32b2019-01-02 15:33:42 -08001255 if (!this->test_.IsMulti() || this->test_.IsFileFetcher())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001256 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001257
Ben Chan02f7c1d2014-10-18 15:18:02 -07001258 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001259 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001260
Ben Chanf9cb98c2014-09-21 18:31:30 -07001261 vector<pair<off_t, off_t>> ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001262 ranges.push_back(make_pair(kBigLength - 2, 0));
1263 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001264 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001265 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001266 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001267 ranges,
1268 "ijhij",
1269 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001270 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001271}
1272
1273TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001274 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001275 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001276
Ben Chan02f7c1d2014-10-18 15:18:02 -07001277 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001278 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001279
Ben Chanf9cb98c2014-09-21 18:31:30 -07001280 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001281 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001282 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001283 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001284 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001285 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001286 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001287 ranges,
1288 "ij",
1289 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001290 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001291 ranges.push_back(make_pair(0, 5));
1292 }
1293}
1294
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001295// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1296// should retry with other proxies listed before giving up.
1297//
1298// (1) successful recovery: The offset fetch will fail twice but succeed with
1299// the third proxy.
1300TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
Tao Bao642b32b2019-01-02 15:33:42 -08001301 if (!this->test_.IsMulti() || this->test_.IsFileFetcher())
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001302 return;
1303
Ben Chan02f7c1d2014-10-18 15:18:02 -07001304 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001305 ASSERT_TRUE(server->started_);
1306
Ben Chanf9cb98c2014-09-21 18:31:30 -07001307 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001308 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001309 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001310 MultiTest(this->test_.NewLargeFetcher(3),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001311 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001312 LocalServerUrlForPath(server->GetPort(),
1313 base::StringPrintf("/error-if-offset/%d/2",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001314 kBigLength)),
1315 ranges,
1316 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1317 kBigLength - (99 - 25),
1318 kHttpResponsePartialContent);
1319}
1320
1321// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1322// fetcher will signal a (failed) completed transfer to the delegate.
1323TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
Tao Bao642b32b2019-01-02 15:33:42 -08001324 if (!this->test_.IsMulti() || this->test_.IsFileFetcher())
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001325 return;
1326
Ben Chan02f7c1d2014-10-18 15:18:02 -07001327 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001328 ASSERT_TRUE(server->started_);
1329
Ben Chanf9cb98c2014-09-21 18:31:30 -07001330 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001331 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001332 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001333 MultiTest(this->test_.NewLargeFetcher(2),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001334 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001335 LocalServerUrlForPath(server->GetPort(),
1336 base::StringPrintf("/error-if-offset/%d/3",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001337 kBigLength)),
1338 ranges,
1339 "abcdefghijabcdefghijabcde", // only received the first chunk
1340 25,
1341 kHttpResponseUndefined);
1342}
1343
Alex Deymo4ea2d922017-02-05 07:35:32 +00001344namespace {
1345// This HttpFetcherDelegate calls TerminateTransfer at a configurable point.
1346class MultiHttpFetcherTerminateTestDelegate : public HttpFetcherDelegate {
1347 public:
1348 explicit MultiHttpFetcherTerminateTestDelegate(size_t terminate_trigger_bytes)
1349 : terminate_trigger_bytes_(terminate_trigger_bytes) {}
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001350
Amin Hassani0cd9d772018-07-31 23:55:43 -07001351 bool ReceivedBytes(HttpFetcher* fetcher,
Alex Deymo4ea2d922017-02-05 07:35:32 +00001352 const void* bytes,
1353 size_t length) override {
1354 LOG(INFO) << "ReceivedBytes, " << length << " bytes.";
1355 EXPECT_EQ(fetcher, fetcher_.get());
Tao Bao642b32b2019-01-02 15:33:42 -08001356 bool should_terminate = false;
Alex Deymo4ea2d922017-02-05 07:35:32 +00001357 if (bytes_downloaded_ < terminate_trigger_bytes_ &&
1358 bytes_downloaded_ + length >= terminate_trigger_bytes_) {
1359 MessageLoop::current()->PostTask(
1360 FROM_HERE,
1361 base::Bind(&HttpFetcher::TerminateTransfer,
1362 base::Unretained(fetcher_.get())));
Tao Bao642b32b2019-01-02 15:33:42 -08001363 should_terminate = true;
Alex Deymo4ea2d922017-02-05 07:35:32 +00001364 }
1365 bytes_downloaded_ += length;
Tao Bao642b32b2019-01-02 15:33:42 -08001366 return !should_terminate;
Alex Deymo4ea2d922017-02-05 07:35:32 +00001367 }
1368
1369 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
1370 ADD_FAILURE() << "TransferComplete called but expected a failure";
1371 // Destroy the fetcher (because we're allowed to).
1372 fetcher_.reset(nullptr);
1373 MessageLoop::current()->BreakLoop();
1374 }
1375
1376 void TransferTerminated(HttpFetcher* fetcher) override {
1377 // Destroy the fetcher (because we're allowed to).
1378 fetcher_.reset(nullptr);
1379 MessageLoop::current()->BreakLoop();
1380 }
1381
1382 unique_ptr<HttpFetcher> fetcher_;
1383 size_t bytes_downloaded_{0};
1384 size_t terminate_trigger_bytes_;
1385};
1386} // namespace
1387
1388TYPED_TEST(HttpFetcherTest, MultiHttpFetcherTerminateBetweenRangesTest) {
1389 if (!this->test_.IsMulti())
1390 return;
1391 const size_t kRangeTrigger = 1000;
1392 MultiHttpFetcherTerminateTestDelegate delegate(kRangeTrigger);
1393
1394 unique_ptr<HttpServer> server(this->test_.CreateServer());
1395 ASSERT_TRUE(server->started_);
1396
1397 MultiRangeHttpFetcher* multi_fetcher =
1398 static_cast<MultiRangeHttpFetcher*>(this->test_.NewLargeFetcher());
1399 ASSERT_TRUE(multi_fetcher);
1400 // Transfer ownership of the fetcher to the delegate.
1401 delegate.fetcher_.reset(multi_fetcher);
1402 multi_fetcher->set_delegate(&delegate);
1403
1404 multi_fetcher->ClearRanges();
1405 multi_fetcher->AddRange(45, kRangeTrigger);
1406 multi_fetcher->AddRange(2000, 100);
1407
1408 this->test_.fake_hardware()->SetIsOfficialBuild(false);
1409
1410 StartTransfer(multi_fetcher, this->test_.BigUrl(server->GetPort()));
1411 MessageLoop::current()->Run();
1412
1413 // Check that the delegate made it to the trigger point.
1414 EXPECT_EQ(kRangeTrigger, delegate.bytes_downloaded_);
1415}
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001416
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001417namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001418class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001419 public:
Amin Hassani0cd9d772018-07-31 23:55:43 -07001420 bool ReceivedBytes(HttpFetcher* fetcher,
1421 const void* bytes,
1422 size_t length) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001423 ADD_FAILURE();
Amin Hassani0cd9d772018-07-31 23:55:43 -07001424 return true;
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001425 }
Alex Deymo610277e2014-11-11 21:18:11 -08001426 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001427 EXPECT_FALSE(successful);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001428 MessageLoop::current()->BreakLoop();
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001429 }
Alex Deymo610277e2014-11-11 21:18:11 -08001430 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001431 ADD_FAILURE();
1432 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001433};
1434
Alex Deymo60ca1a72015-06-18 18:19:15 -07001435void BlockedTransferTestHelper(AnyHttpFetcherTest* fetcher_test,
1436 bool is_official_build) {
1437 if (fetcher_test->IsMock() || fetcher_test->IsMulti())
1438 return;
1439
1440 unique_ptr<HttpServer> server(fetcher_test->CreateServer());
1441 ASSERT_TRUE(server->started_);
1442
1443 BlockedTransferTestDelegate delegate;
1444 unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher());
1445 LOG(INFO) << "is_official_build: " << is_official_build;
1446 // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
Alex Deymoc1c17b42015-11-23 03:53:15 -03001447 fetcher_test->fake_hardware()->SetIsOfficialBuild(is_official_build);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001448 fetcher->set_delegate(&delegate);
1449
1450 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1451 StartTransfer,
1452 fetcher.get(),
1453 LocalServerUrlForPath(server->GetPort(),
1454 fetcher_test->SmallUrl(server->GetPort()))));
1455 MessageLoop::current()->Run();
1456}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001457} // namespace
1458
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001459TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001460 BlockedTransferTestHelper(&this->test_, false);
1461}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001462
Alex Deymo60ca1a72015-06-18 18:19:15 -07001463TYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) {
1464 BlockedTransferTestHelper(&this->test_, true);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001465}
1466
rspangler@google.com49fdf182009-10-10 00:57:34 +00001467} // namespace chromeos_update_engine