blob: 654cb1dd4bc321859f0960f868f146c0d37d983b [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 Deymo60ca1a72015-06-18 18:19:15 -070027#include <base/location.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080028#include <base/logging.h>
Alex Deymo535f3b72015-08-07 10:51:32 -070029#include <base/message_loop/message_loop.h>
30#include <base/strings/string_number_conversions.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070031#include <base/strings/string_util.h>
32#include <base/strings/stringprintf.h>
33#include <base/time/time.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070034#include <brillo/message_loops/base_message_loop.h>
35#include <brillo/message_loops/message_loop.h>
36#include <brillo/message_loops/message_loop_utils.h>
37#include <brillo/process.h>
38#include <brillo/streams/file_stream.h>
39#include <brillo/streams/stream.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080040#include <gtest/gtest.h>
41
Alex Deymoc1c17b42015-11-23 03:53:15 -030042#include "update_engine/common/fake_hardware.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080043#include "update_engine/common/http_common.h"
44#include "update_engine/common/libcurl_http_fetcher.h"
45#include "update_engine/common/mock_http_fetcher.h"
46#include "update_engine/common/multi_range_http_fetcher.h"
47#include "update_engine/common/test_utils.h"
48#include "update_engine/common/utils.h"
Gilad Arnold5bb4c902014-04-10 12:32:13 -070049#include "update_engine/fake_system_state.h"
Andrew de los Reyes45168102010-11-22 11:13:50 -080050#include "update_engine/proxy_resolver.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +000051
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070052using brillo::MessageLoop;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -070053using std::make_pair;
Andrew de los Reyes819fef22010-12-17 11:33:58 -080054using std::pair;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000055using std::string;
Ben Chan02f7c1d2014-10-18 15:18:02 -070056using std::unique_ptr;
adlr@google.comc98a7ed2009-12-04 18:54:03 +000057using std::vector;
58
Gilad Arnold9bedeb52011-11-17 16:19:57 -080059namespace {
60
61const int kBigLength = 100000;
62const int kMediumLength = 1000;
Gilad Arnold34bf1ee2012-02-09 16:16:02 -080063const int kFlakyTruncateLength = 29000;
64const int kFlakySleepEvery = 3;
Gilad Arnold9bedeb52011-11-17 16:19:57 -080065const int kFlakySleepSecs = 10;
66
67} // namespace
68
rspangler@google.com49fdf182009-10-10 00:57:34 +000069namespace chromeos_update_engine {
70
Gilad Arnold9bedeb52011-11-17 16:19:57 -080071static const char *kUnusedUrl = "unused://unused";
72
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070073static inline string LocalServerUrlForPath(in_port_t port,
74 const string& path) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070075 string port_str = (port ? base::StringPrintf(":%hu", port) : "");
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070076 return base::StringPrintf("http://127.0.0.1%s%s", port_str.c_str(),
77 path.c_str());
rspangler@google.com49fdf182009-10-10 00:57:34 +000078}
79
Gilad Arnold9bedeb52011-11-17 16:19:57 -080080//
81// Class hierarchy for HTTP server implementations.
82//
83
84class HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +000085 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -080086 // This makes it an abstract class (dirty but works).
87 virtual ~HttpServer() = 0;
88
Gilad Arnoldb6c562a2013-07-01 02:19:26 -070089 virtual in_port_t GetPort() const {
90 return 0;
91 }
92
rspangler@google.com49fdf182009-10-10 00:57:34 +000093 bool started_;
94};
95
Gilad Arnold9bedeb52011-11-17 16:19:57 -080096HttpServer::~HttpServer() {}
rspangler@google.com49fdf182009-10-10 00:57:34 +000097
Gilad Arnold9bedeb52011-11-17 16:19:57 -080098
99class NullHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000100 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800101 NullHttpServer() {
102 started_ = true;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000103 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000104};
105
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800106
107class PythonHttpServer : public HttpServer {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000108 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700109 PythonHttpServer() : port_(0) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000110 started_ = false;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700111
112 // Spawn the server process.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700113 unique_ptr<brillo::Process> http_server(new brillo::ProcessImpl());
Alex Deymo535f3b72015-08-07 10:51:32 -0700114 base::FilePath test_server_path =
115 test_utils::GetBuildArtifactsPath().Append("test_http_server");
116 http_server->AddArg(test_server_path.value());
117 http_server->RedirectUsingPipe(STDOUT_FILENO, false);
118
119 if (!http_server->Start()) {
120 ADD_FAILURE() << "failed to spawn http server process";
rspangler@google.com49fdf182009-10-10 00:57:34 +0000121 return;
122 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700123 LOG(INFO) << "started http server with pid " << http_server->pid();
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700124
125 // Wait for server to begin accepting connections, obtain its port.
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700126 brillo::StreamPtr stdout = brillo::FileStream::FromFileDescriptor(
Alex Deymo535f3b72015-08-07 10:51:32 -0700127 http_server->GetPipe(STDOUT_FILENO), false /* own */, nullptr);
128 if (!stdout)
129 return;
130
131 vector<char> buf(128);
132 string line;
133 while (line.find('\n') == string::npos) {
134 size_t read;
135 if (!stdout->ReadBlocking(buf.data(), buf.size(), &read, nullptr)) {
136 ADD_FAILURE() << "error reading http server stdout";
137 return;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700138 }
Alex Deymo535f3b72015-08-07 10:51:32 -0700139 line.append(buf.data(), read);
140 if (read == 0)
141 break;
142 }
143 // Parse the port from the output line.
144 const size_t listening_msg_prefix_len = strlen(kServerListeningMsgPrefix);
145 if (line.size() < listening_msg_prefix_len) {
146 ADD_FAILURE() << "server output too short";
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700147 return;
148 }
149
Alex Deymo535f3b72015-08-07 10:51:32 -0700150 EXPECT_EQ(kServerListeningMsgPrefix,
151 line.substr(0, listening_msg_prefix_len));
152 string port_str = line.substr(listening_msg_prefix_len);
153 port_str.resize(port_str.find('\n'));
154 EXPECT_TRUE(base::StringToUint(port_str, &port_));
155
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700156 started_ = true;
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700157 LOG(INFO) << "server running, listening on port " << port_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700158
159 // Any failure before this point will SIGKILL the test server if started
160 // when the |http_server| goes out of scope.
161 http_server_ = std::move(http_server);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000162 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800163
rspangler@google.com49fdf182009-10-10 00:57:34 +0000164 ~PythonHttpServer() {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700165 // If there's no process, do nothing.
Alex Deymo535f3b72015-08-07 10:51:32 -0700166 if (!http_server_)
rspangler@google.com49fdf182009-10-10 00:57:34 +0000167 return;
Alex Deymo535f3b72015-08-07 10:51:32 -0700168 // Wait up to 10 seconds for the process to finish. Destroying the process
169 // will kill it with a SIGKILL otherwise.
170 http_server_->Kill(SIGTERM, 10);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000171 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800172
Alex Deymo610277e2014-11-11 21:18:11 -0800173 in_port_t GetPort() const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700174 return port_;
175 }
176
177 private:
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700178 static const char* kServerListeningMsgPrefix;
179
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700180 unique_ptr<brillo::Process> http_server_;
Alex Deymo535f3b72015-08-07 10:51:32 -0700181 unsigned int port_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000182};
183
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700184const char* PythonHttpServer::kServerListeningMsgPrefix = "listening on port ";
185
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800186//
187// Class hierarchy for HTTP fetcher test wrappers.
188//
189
190class AnyHttpFetcherTest {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000191 public:
Chris Sosa77f79e82014-06-02 18:16:24 -0700192 AnyHttpFetcherTest() {}
Alex Deymoc4acdf42014-05-28 21:07:10 -0700193 virtual ~AnyHttpFetcherTest() {}
Jay Srinivasan43488792012-06-19 00:25:31 -0700194
Alex Deymo7984bf02014-04-02 20:41:57 -0700195 virtual HttpFetcher* NewLargeFetcher(size_t num_proxies) = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800196 HttpFetcher* NewLargeFetcher() {
197 return NewLargeFetcher(1);
198 }
199
200 virtual HttpFetcher* NewSmallFetcher(size_t num_proxies) = 0;
201 HttpFetcher* NewSmallFetcher() {
202 return NewSmallFetcher(1);
203 }
204
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700205 virtual string BigUrl(in_port_t port) const { return kUnusedUrl; }
206 virtual string SmallUrl(in_port_t port) const { return kUnusedUrl; }
207 virtual string ErrorUrl(in_port_t port) const { return kUnusedUrl; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800208
209 virtual bool IsMock() const = 0;
210 virtual bool IsMulti() const = 0;
211
212 virtual void IgnoreServerAborting(HttpServer* server) const {}
213
Alex Deymo60ca1a72015-06-18 18:19:15 -0700214 virtual HttpServer* CreateServer() = 0;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800215
Alex Deymoc1c17b42015-11-23 03:53:15 -0300216 FakeHardware* fake_hardware() {
217 return fake_system_state_.fake_hardware();
218 }
219
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800220 protected:
221 DirectProxyResolver proxy_resolver_;
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700222 FakeSystemState fake_system_state_;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800223};
224
225class MockHttpFetcherTest : public AnyHttpFetcherTest {
226 public:
227 // Necessary to unhide the definition in the base class.
228 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800229 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700230 brillo::Blob big_data(1000000);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700231 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800232 proxy_resolver_.set_num_proxies(num_proxies);
233 return new MockHttpFetcher(
234 big_data.data(),
235 big_data.size(),
236 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
237 }
238
239 // Necessary to unhide the definition in the base class.
240 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800241 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700242 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800243 proxy_resolver_.set_num_proxies(num_proxies);
244 return new MockHttpFetcher(
245 "x",
246 1,
247 reinterpret_cast<ProxyResolver*>(&proxy_resolver_));
248 }
249
Alex Deymo610277e2014-11-11 21:18:11 -0800250 bool IsMock() const override { return true; }
251 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800252
Alex Deymo60ca1a72015-06-18 18:19:15 -0700253 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800254 return new NullHttpServer;
255 }
256};
257
258class LibcurlHttpFetcherTest : public AnyHttpFetcherTest {
259 public:
260 // Necessary to unhide the definition in the base class.
261 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800262 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700263 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800264 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes45168102010-11-22 11:13:50 -0800265 LibcurlHttpFetcher *ret = new
Jay Srinivasan08fce042012-06-07 16:31:01 -0700266 LibcurlHttpFetcher(reinterpret_cast<ProxyResolver*>(&proxy_resolver_),
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700267 &fake_system_state_);
Darin Petkovb83371f2010-08-17 09:34:49 -0700268 // Speed up test execution.
269 ret->set_idle_seconds(1);
270 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700271 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000272 return ret;
273 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800274
275 // Necessary to unhide the definition in the base class.
276 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800277 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800278 return NewLargeFetcher(num_proxies);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000279 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800280
Alex Deymo610277e2014-11-11 21:18:11 -0800281 string BigUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700282 return LocalServerUrlForPath(port,
283 base::StringPrintf("/download/%d",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800284 kBigLength));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000285 }
Alex Deymo610277e2014-11-11 21:18:11 -0800286 string SmallUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700287 return LocalServerUrlForPath(port, "/foo");
rspangler@google.com49fdf182009-10-10 00:57:34 +0000288 }
Alex Deymo610277e2014-11-11 21:18:11 -0800289 string ErrorUrl(in_port_t port) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700290 return LocalServerUrlForPath(port, "/error");
Gilad Arnold48085ba2011-11-16 09:36:08 -0800291 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800292
Alex Deymo610277e2014-11-11 21:18:11 -0800293 bool IsMock() const override { return false; }
294 bool IsMulti() const override { return false; }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800295
Alex Deymo610277e2014-11-11 21:18:11 -0800296 void IgnoreServerAborting(HttpServer* server) const override {
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700297 // Nothing to do.
Andrew de los Reyes08c4e272010-04-15 14:02:17 -0700298 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800299
Alex Deymo60ca1a72015-06-18 18:19:15 -0700300 HttpServer* CreateServer() override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800301 return new PythonHttpServer;
302 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000303};
304
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800305class MultiRangeHttpFetcherTest : public LibcurlHttpFetcherTest {
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700306 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800307 // Necessary to unhide the definition in the base class.
308 using AnyHttpFetcherTest::NewLargeFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800309 HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700310 CHECK_GT(num_proxies, 0u);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800311 proxy_resolver_.set_num_proxies(num_proxies);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800312 ProxyResolver* resolver =
313 reinterpret_cast<ProxyResolver*>(&proxy_resolver_);
Gilad Arnold7c04e762012-05-23 10:54:02 -0700314 MultiRangeHttpFetcher *ret =
315 new MultiRangeHttpFetcher(
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700316 new LibcurlHttpFetcher(resolver, &fake_system_state_));
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800317 ret->ClearRanges();
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800318 ret->AddRange(0);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700319 // Speed up test execution.
320 ret->set_idle_seconds(1);
321 ret->set_retry_seconds(1);
Gilad Arnold5bb4c902014-04-10 12:32:13 -0700322 fake_system_state_.fake_hardware()->SetIsOfficialBuild(false);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700323 return ret;
324 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800325
326 // Necessary to unhide the definition in the base class.
327 using AnyHttpFetcherTest::NewSmallFetcher;
Alex Deymo610277e2014-11-11 21:18:11 -0800328 HttpFetcher* NewSmallFetcher(size_t num_proxies) override {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800329 return NewLargeFetcher(num_proxies);
330 }
331
Alex Deymo610277e2014-11-11 21:18:11 -0800332 bool IsMulti() const override { return true; }
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700333};
334
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800335
336//
337// Infrastructure for type tests of HTTP fetcher.
338// See: http://code.google.com/p/googletest/wiki/AdvancedGuide#Typed_Tests
339//
340
341// Fixture class template. We use an explicit constraint to guarantee that it
342// can only be instantiated with an AnyHttpFetcherTest type, see:
343// http://www2.research.att.com/~bs/bs_faq2.html#constraints
344template <typename T>
345class HttpFetcherTest : public ::testing::Test {
346 public:
Alex Deymo535f3b72015-08-07 10:51:32 -0700347 base::MessageLoopForIO base_loop_;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700348 brillo::BaseMessageLoop loop_{&base_loop_};
Alex Deymo60ca1a72015-06-18 18:19:15 -0700349
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800350 T test_;
351
Alex Deymo60ca1a72015-06-18 18:19:15 -0700352 protected:
353 HttpFetcherTest() {
354 loop_.SetAsCurrent();
355 }
356
357 void TearDown() override {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -0700358 EXPECT_EQ(0, brillo::MessageLoopRunMaxIterations(&loop_, 1));
Alex Deymo60ca1a72015-06-18 18:19:15 -0700359 }
360
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800361 private:
Alex Deymo60ca1a72015-06-18 18:19:15 -0700362 static void TypeConstraint(T* a) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800363 AnyHttpFetcherTest *b = a;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700364 if (b == 0) // Silence compiler warning of unused variable.
Yunlian Jiang2dac5762013-04-12 09:53:09 -0700365 *b = a;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800366 }
367};
368
369// Test case types list.
370typedef ::testing::Types<LibcurlHttpFetcherTest,
371 MockHttpFetcherTest,
372 MultiRangeHttpFetcherTest> HttpFetcherTestTypes;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000373TYPED_TEST_CASE(HttpFetcherTest, HttpFetcherTestTypes);
374
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800375
rspangler@google.com49fdf182009-10-10 00:57:34 +0000376namespace {
377class HttpFetcherTestDelegate : public HttpFetcherDelegate {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000378 public:
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800379 HttpFetcherTestDelegate() :
Gilad Arnold48085ba2011-11-16 09:36:08 -0800380 is_expect_error_(false), times_transfer_complete_called_(0),
381 times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
382
Alex Deymo610277e2014-11-11 21:18:11 -0800383 void ReceivedBytes(HttpFetcher* /* fetcher */,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800384 const void* /* bytes */, size_t /* length */) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800385 // Update counters
386 times_received_bytes_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000387 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800388
Alex Deymo610277e2014-11-11 21:18:11 -0800389 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Gilad Arnold48085ba2011-11-16 09:36:08 -0800390 if (is_expect_error_)
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800391 EXPECT_EQ(kHttpResponseNotFound, fetcher->http_response_code());
Gilad Arnold48085ba2011-11-16 09:36:08 -0800392 else
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800393 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700394 MessageLoop::current()->BreakLoop();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800395
396 // Update counter
397 times_transfer_complete_called_++;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000398 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800399
Alex Deymo610277e2014-11-11 21:18:11 -0800400 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800401 ADD_FAILURE();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800402 times_transfer_terminated_called_++;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800403 }
Gilad Arnold48085ba2011-11-16 09:36:08 -0800404
Gilad Arnold48085ba2011-11-16 09:36:08 -0800405 // Are we expecting an error response? (default: no)
406 bool is_expect_error_;
407
408 // Counters for callback invocations.
409 int times_transfer_complete_called_;
410 int times_transfer_terminated_called_;
411 int times_received_bytes_called_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000412};
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000413
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000414
Alex Deymo60ca1a72015-06-18 18:19:15 -0700415void StartTransfer(HttpFetcher* http_fetcher, const string& url) {
416 http_fetcher->BeginTransfer(url);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000417}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700418} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000419
420TYPED_TEST(HttpFetcherTest, SimpleTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700421 HttpFetcherTestDelegate delegate;
422 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
423 fetcher->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000424
Alex Deymo60ca1a72015-06-18 18:19:15 -0700425 unique_ptr<HttpServer> server(this->test_.CreateServer());
426 ASSERT_TRUE(server->started_);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000427
Alex Deymo60ca1a72015-06-18 18:19:15 -0700428 this->loop_.PostTask(FROM_HERE, base::Bind(
429 StartTransfer,
430 fetcher.get(),
431 this->test_.SmallUrl(server->GetPort())));
432 this->loop_.Run();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000433}
434
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700435TYPED_TEST(HttpFetcherTest, SimpleBigTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700436 HttpFetcherTestDelegate delegate;
437 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
438 fetcher->set_delegate(&delegate);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700439
Alex Deymo60ca1a72015-06-18 18:19:15 -0700440 unique_ptr<HttpServer> server(this->test_.CreateServer());
441 ASSERT_TRUE(server->started_);
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700442
Alex Deymo60ca1a72015-06-18 18:19:15 -0700443 this->loop_.PostTask(FROM_HERE, base::Bind(
444 StartTransfer,
445 fetcher.get(),
446 this->test_.BigUrl(server->GetPort())));
447 this->loop_.Run();
Andrew de los Reyes3270f742010-07-15 22:28:14 -0700448}
449
Gilad Arnold48085ba2011-11-16 09:36:08 -0800450// Issue #9648: when server returns an error HTTP response, the fetcher needs to
451// terminate transfer prematurely, rather than try to process the error payload.
452TYPED_TEST(HttpFetcherTest, ErrorTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800453 if (this->test_.IsMock() || this->test_.IsMulti())
Gilad Arnold48085ba2011-11-16 09:36:08 -0800454 return;
Alex Deymo60ca1a72015-06-18 18:19:15 -0700455 HttpFetcherTestDelegate delegate;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800456
Alex Deymo60ca1a72015-06-18 18:19:15 -0700457 // Delegate should expect an error response.
458 delegate.is_expect_error_ = true;
Gilad Arnold48085ba2011-11-16 09:36:08 -0800459
Alex Deymo60ca1a72015-06-18 18:19:15 -0700460 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
461 fetcher->set_delegate(&delegate);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800462
Alex Deymo60ca1a72015-06-18 18:19:15 -0700463 unique_ptr<HttpServer> server(this->test_.CreateServer());
464 ASSERT_TRUE(server->started_);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800465
Alex Deymo60ca1a72015-06-18 18:19:15 -0700466 this->loop_.PostTask(FROM_HERE, base::Bind(
467 StartTransfer,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800468 fetcher.get(),
Alex Deymo60ca1a72015-06-18 18:19:15 -0700469 this->test_.ErrorUrl(server->GetPort())));
470 this->loop_.Run();
Gilad Arnold48085ba2011-11-16 09:36:08 -0800471
Alex Deymo60ca1a72015-06-18 18:19:15 -0700472 // Make sure that no bytes were received.
473 CHECK_EQ(delegate.times_received_bytes_called_, 0);
474 CHECK_EQ(fetcher->GetBytesDownloaded(), static_cast<size_t>(0));
Gilad Arnold48085ba2011-11-16 09:36:08 -0800475
Alex Deymo60ca1a72015-06-18 18:19:15 -0700476 // Make sure that transfer completion was signaled once, and no termination
477 // was signaled.
478 CHECK_EQ(delegate.times_transfer_complete_called_, 1);
479 CHECK_EQ(delegate.times_transfer_terminated_called_, 0);
Gilad Arnold48085ba2011-11-16 09:36:08 -0800480}
481
rspangler@google.com49fdf182009-10-10 00:57:34 +0000482namespace {
483class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
484 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800485 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800486 const void* /* bytes */, size_t /* length */) override {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000487 CHECK(!paused_);
488 paused_ = true;
489 fetcher->Pause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000490 }
Alex Deymo610277e2014-11-11 21:18:11 -0800491 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700492 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000493 }
Alex Deymo610277e2014-11-11 21:18:11 -0800494 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800495 ADD_FAILURE();
496 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000497 void Unpause() {
498 CHECK(paused_);
499 paused_ = false;
500 fetcher_->Unpause();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000501 }
502 bool paused_;
503 HttpFetcher* fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000504};
505
Alex Deymo60ca1a72015-06-18 18:19:15 -0700506void UnpausingTimeoutCallback(PausingHttpFetcherTestDelegate* delegate,
507 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000508 if (delegate->paused_)
509 delegate->Unpause();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700510 // Update the task id with the new scheduled callback.
511 *my_id = MessageLoop::current()->PostDelayedTask(
512 FROM_HERE,
513 base::Bind(&UnpausingTimeoutCallback, delegate, my_id),
514 base::TimeDelta::FromMilliseconds(200));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000515}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700516} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000517
518TYPED_TEST(HttpFetcherTest, PauseTest) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000519 {
520 PausingHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700521 unique_ptr<HttpFetcher> fetcher(this->test_.NewLargeFetcher());
rspangler@google.com49fdf182009-10-10 00:57:34 +0000522 delegate.paused_ = false;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000523 delegate.fetcher_ = fetcher.get();
524 fetcher->set_delegate(&delegate);
525
Ben Chan02f7c1d2014-10-18 15:18:02 -0700526 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800527 ASSERT_TRUE(server->started_);
Andrew de los Reyesf3ed8e72011-02-16 10:35:46 -0800528
Alex Deymo60ca1a72015-06-18 18:19:15 -0700529 MessageLoop::TaskId callback_id;
530 callback_id = this->loop_.PostDelayedTask(
531 FROM_HERE,
532 base::Bind(&UnpausingTimeoutCallback, &delegate, &callback_id),
533 base::TimeDelta::FromMilliseconds(200));
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700534 fetcher->BeginTransfer(this->test_.BigUrl(server->GetPort()));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000535
Alex Deymo60ca1a72015-06-18 18:19:15 -0700536 this->loop_.Run();
537 EXPECT_TRUE(this->loop_.CancelTask(callback_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000538 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000539}
540
541namespace {
542class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
543 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800544 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800545 const void* bytes, size_t length) override {}
Alex Deymo610277e2014-11-11 21:18:11 -0800546 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800547 ADD_FAILURE(); // We should never get here
Alex Deymo60ca1a72015-06-18 18:19:15 -0700548 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000549 }
Alex Deymo610277e2014-11-11 21:18:11 -0800550 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800551 EXPECT_EQ(fetcher, fetcher_.get());
552 EXPECT_FALSE(once_);
553 EXPECT_TRUE(callback_once_);
554 callback_once_ = false;
Alex Deymoc4acdf42014-05-28 21:07:10 -0700555 // The fetcher could have a callback scheduled on the ProxyResolver that
556 // can fire after this callback. We wait until the end of the test to
557 // delete the fetcher.
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800558 }
rspangler@google.com49fdf182009-10-10 00:57:34 +0000559 void TerminateTransfer() {
560 CHECK(once_);
561 once_ = false;
562 fetcher_->TerminateTransfer();
563 }
564 void EndLoop() {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700565 MessageLoop::current()->BreakLoop();
rspangler@google.com49fdf182009-10-10 00:57:34 +0000566 }
567 bool once_;
Darin Petkov9ce452b2010-11-17 14:33:28 -0800568 bool callback_once_;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700569 unique_ptr<HttpFetcher> fetcher_;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000570};
571
Alex Deymo60ca1a72015-06-18 18:19:15 -0700572void AbortingTimeoutCallback(AbortingHttpFetcherTestDelegate* delegate,
573 MessageLoop::TaskId* my_id) {
rspangler@google.com49fdf182009-10-10 00:57:34 +0000574 if (delegate->once_) {
575 delegate->TerminateTransfer();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700576 *my_id = MessageLoop::current()->PostTask(
577 FROM_HERE,
578 base::Bind(AbortingTimeoutCallback, delegate, my_id));
rspangler@google.com49fdf182009-10-10 00:57:34 +0000579 } else {
580 delegate->EndLoop();
Alex Deymo60ca1a72015-06-18 18:19:15 -0700581 *my_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000582 }
583}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700584} // namespace
rspangler@google.com49fdf182009-10-10 00:57:34 +0000585
586TYPED_TEST(HttpFetcherTest, AbortTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700587 AbortingHttpFetcherTestDelegate delegate;
588 delegate.fetcher_.reset(this->test_.NewLargeFetcher());
589 delegate.once_ = true;
590 delegate.callback_once_ = true;
591 delegate.fetcher_->set_delegate(&delegate);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000592
Alex Deymo60ca1a72015-06-18 18:19:15 -0700593 unique_ptr<HttpServer> server(this->test_.CreateServer());
594 this->test_.IgnoreServerAborting(server.get());
595 ASSERT_TRUE(server->started_);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800596
Alex Deymo60ca1a72015-06-18 18:19:15 -0700597 MessageLoop::TaskId task_id = MessageLoop::kTaskIdNull;
rspangler@google.com49fdf182009-10-10 00:57:34 +0000598
Alex Deymo60ca1a72015-06-18 18:19:15 -0700599 task_id = this->loop_.PostTask(
600 FROM_HERE,
601 base::Bind(AbortingTimeoutCallback, &delegate, &task_id));
602 delegate.fetcher_->BeginTransfer(this->test_.BigUrl(server->GetPort()));
603
604 this->loop_.Run();
605 CHECK(!delegate.once_);
606 CHECK(!delegate.callback_once_);
607 this->loop_.CancelTask(task_id);
rspangler@google.com49fdf182009-10-10 00:57:34 +0000608}
609
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000610namespace {
611class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
612 public:
Alex Deymo610277e2014-11-11 21:18:11 -0800613 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800614 const void* bytes, size_t length) override {
615 data.append(reinterpret_cast<const char*>(bytes), length);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000616 }
Alex Deymo610277e2014-11-11 21:18:11 -0800617 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesfb4ad7d2010-07-19 10:43:46 -0700618 EXPECT_TRUE(successful);
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800619 EXPECT_EQ(kHttpResponsePartialContent, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700620 MessageLoop::current()->BreakLoop();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000621 }
Alex Deymo610277e2014-11-11 21:18:11 -0800622 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800623 ADD_FAILURE();
624 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000625 string data;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000626};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700627} // namespace
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000628
629TYPED_TEST(HttpFetcherTest, FlakyTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800630 if (this->test_.IsMock())
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000631 return;
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000632 {
633 FlakyHttpFetcherTestDelegate delegate;
Ben Chan02f7c1d2014-10-18 15:18:02 -0700634 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000635 fetcher->set_delegate(&delegate);
636
Ben Chan02f7c1d2014-10-18 15:18:02 -0700637 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800638 ASSERT_TRUE(server->started_);
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000639
Alex Deymo60ca1a72015-06-18 18:19:15 -0700640 this->loop_.PostTask(FROM_HERE, base::Bind(
641 &StartTransfer,
642 fetcher.get(),
643 LocalServerUrlForPath(server->GetPort(),
644 base::StringPrintf("/flaky/%d/%d/%d/%d",
645 kBigLength,
646 kFlakyTruncateLength,
647 kFlakySleepEvery,
648 kFlakySleepSecs))));
649 this->loop_.Run();
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000650
651 // verify the data we get back
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800652 ASSERT_EQ(kBigLength, delegate.data.size());
653 for (int i = 0; i < kBigLength; i += 10) {
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000654 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
655 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
656 }
657 }
adlr@google.comc98a7ed2009-12-04 18:54:03 +0000658}
659
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700660namespace {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700661// This delegate kills the server attached to it after receiving any bytes.
662// This can be used for testing what happens when you try to fetch data and
663// the server dies.
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700664class FailureHttpFetcherTestDelegate : public HttpFetcherDelegate {
665 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700666 explicit FailureHttpFetcherTestDelegate(PythonHttpServer* server)
Alex Deymo60ca1a72015-06-18 18:19:15 -0700667 : server_(server) {}
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700668
Alex Deymo610277e2014-11-11 21:18:11 -0800669 ~FailureHttpFetcherTestDelegate() override {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700670 if (server_) {
671 LOG(INFO) << "Stopping server in destructor";
672 delete server_;
673 LOG(INFO) << "server stopped";
674 }
675 }
676
Alex Deymo610277e2014-11-11 21:18:11 -0800677 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800678 const void* bytes, size_t length) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700679 if (server_) {
Jay Srinivasan135a58b2012-07-13 12:46:49 -0700680 LOG(INFO) << "Stopping server in ReceivedBytes";
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700681 delete server_;
682 LOG(INFO) << "server stopped";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700683 server_ = nullptr;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700684 }
685 }
Alex Deymo610277e2014-11-11 21:18:11 -0800686 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700687 EXPECT_FALSE(successful);
Chris Sosa0a364bb2014-06-10 18:18:24 -0700688 EXPECT_EQ(0, fetcher->http_response_code());
Alex Deymo60ca1a72015-06-18 18:19:15 -0700689 MessageLoop::current()->BreakLoop();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700690 }
Alex Deymo610277e2014-11-11 21:18:11 -0800691 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800692 ADD_FAILURE();
693 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700694 PythonHttpServer* server_;
695};
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700696} // namespace
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700697
698
699TYPED_TEST(HttpFetcherTest, FailureTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700700 // This test ensures that a fetcher responds correctly when a server isn't
701 // available at all.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800702 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700703 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700704 {
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700705 FailureHttpFetcherTestDelegate delegate(nullptr);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700706 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700707 fetcher->set_delegate(&delegate);
708
Alex Deymo60ca1a72015-06-18 18:19:15 -0700709 this->loop_.PostTask(FROM_HERE,
710 base::Bind(StartTransfer,
711 fetcher.get(),
712 "http://host_doesnt_exist99999999"));
713 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700714
715 // Exiting and testing happens in the delegate
716 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700717}
718
Alex Deymof123ae22015-09-24 14:59:43 -0700719TYPED_TEST(HttpFetcherTest, NoResponseTest) {
720 // This test starts a new http server but the server doesn't respond and just
721 // closes the connection.
722 if (this->test_.IsMock())
723 return;
724
725 PythonHttpServer* server = new PythonHttpServer();
726 int port = server->GetPort();
727 ASSERT_TRUE(server->started_);
728
729 // Handles destruction and claims ownership.
730 FailureHttpFetcherTestDelegate delegate(server);
731 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
732 fetcher->set_delegate(&delegate);
733 // The server will not reply at all, so we can limit the execution time of the
734 // test by reducing the low-speed timeout to something small. The test will
735 // finish once the TimeoutCallback() triggers (every second) and the timeout
736 // expired.
737 fetcher->set_low_speed_limit(kDownloadLowSpeedLimitBps, 1);
738
739 this->loop_.PostTask(FROM_HERE, base::Bind(
740 StartTransfer,
741 fetcher.get(),
742 LocalServerUrlForPath(port, "/hang")));
743 this->loop_.Run();
744
745 // Check that no other callback runs in the next two seconds. That would
746 // indicate a leaked callback.
747 bool timeout = false;
748 auto callback = base::Bind([&timeout]{ timeout = true;});
749 this->loop_.PostDelayedTask(FROM_HERE, callback,
750 base::TimeDelta::FromSeconds(2));
751 EXPECT_TRUE(this->loop_.RunOnce(true));
752 EXPECT_TRUE(timeout);
753}
754
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700755TYPED_TEST(HttpFetcherTest, ServerDiesTest) {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700756 // This test starts a new http server and kills it after receiving its first
757 // set of bytes. It test whether or not our fetcher eventually gives up on
758 // retries and aborts correctly.
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800759 if (this->test_.IsMock())
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700760 return;
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700761 {
Chris Sosa0a364bb2014-06-10 18:18:24 -0700762 PythonHttpServer* server = new PythonHttpServer();
763 int port = server->GetPort();
764 ASSERT_TRUE(server->started_);
765
766 // Handles destruction and claims ownership.
767 FailureHttpFetcherTestDelegate delegate(server);
Ben Chan02f7c1d2014-10-18 15:18:02 -0700768 unique_ptr<HttpFetcher> fetcher(this->test_.NewSmallFetcher());
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700769 fetcher->set_delegate(&delegate);
770
Alex Deymo60ca1a72015-06-18 18:19:15 -0700771 this->loop_.PostTask(FROM_HERE, base::Bind(
772 StartTransfer,
773 fetcher.get(),
774 LocalServerUrlForPath(port,
775 base::StringPrintf("/flaky/%d/%d/%d/%d",
776 kBigLength,
777 kFlakyTruncateLength,
778 kFlakySleepEvery,
779 kFlakySleepSecs))));
780 this->loop_.Run();
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700781
782 // Exiting and testing happens in the delegate
783 }
Andrew de los Reyes9bbd1872010-07-16 14:52:29 -0700784}
785
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700786namespace {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800787const HttpResponseCode kRedirectCodes[] = {
788 kHttpResponseMovedPermanently, kHttpResponseFound, kHttpResponseSeeOther,
789 kHttpResponseTempRedirect
790};
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700791
792class RedirectHttpFetcherTestDelegate : public HttpFetcherDelegate {
793 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700794 explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700795 : expected_successful_(expected_successful) {}
Alex Deymo610277e2014-11-11 21:18:11 -0800796 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800797 const void* bytes, size_t length) override {
798 data.append(reinterpret_cast<const char*>(bytes), length);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700799 }
Alex Deymo610277e2014-11-11 21:18:11 -0800800 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700801 EXPECT_EQ(expected_successful_, successful);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700802 if (expected_successful_) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800803 EXPECT_EQ(kHttpResponseOk, fetcher->http_response_code());
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700804 } else {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800805 EXPECT_GE(fetcher->http_response_code(), kHttpResponseMovedPermanently);
806 EXPECT_LE(fetcher->http_response_code(), kHttpResponseTempRedirect);
Darin Petkovcb466212010-08-26 09:40:11 -0700807 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700808 MessageLoop::current()->BreakLoop();
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700809 }
Alex Deymo610277e2014-11-11 21:18:11 -0800810 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800811 ADD_FAILURE();
812 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700813 bool expected_successful_;
814 string data;
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700815};
816
817// RedirectTest takes ownership of |http_fetcher|.
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700818void RedirectTest(const HttpServer* server,
819 bool expected_successful,
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700820 const string& url,
821 HttpFetcher* http_fetcher) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700822 RedirectHttpFetcherTestDelegate delegate(expected_successful);
823 unique_ptr<HttpFetcher> fetcher(http_fetcher);
824 fetcher->set_delegate(&delegate);
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700825
Alex Deymo60ca1a72015-06-18 18:19:15 -0700826 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
827 StartTransfer,
828 fetcher.get(),
829 LocalServerUrlForPath(server->GetPort(), url)));
830 MessageLoop::current()->Run();
831 if (expected_successful) {
832 // verify the data we get back
833 ASSERT_EQ(kMediumLength, delegate.data.size());
834 for (int i = 0; i < kMediumLength; i += 10) {
835 // Assert so that we don't flood the screen w/ EXPECT errors on failure.
836 ASSERT_EQ(delegate.data.substr(i, 10), "abcdefghij");
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700837 }
838 }
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700839}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700840} // namespace
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700841
842TYPED_TEST(HttpFetcherTest, SimpleRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800843 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700844 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800845
Ben Chan02f7c1d2014-10-18 15:18:02 -0700846 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800847 ASSERT_TRUE(server->started_);
848
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700849 for (size_t c = 0; c < arraysize(kRedirectCodes); ++c) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800850 const string url = base::StringPrintf("/redirect/%d/download/%d",
851 kRedirectCodes[c],
852 kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700853 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700854 }
855}
856
857TYPED_TEST(HttpFetcherTest, MaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800858 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700859 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800860
Ben Chan02f7c1d2014-10-18 15:18:02 -0700861 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800862 ASSERT_TRUE(server->started_);
863
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700864 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700865 for (int r = 0; r < kDownloadMaxRedirects; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700866 url += base::StringPrintf("/redirect/%d",
867 kRedirectCodes[r % arraysize(kRedirectCodes)]);
868 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800869 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700870 RedirectTest(server.get(), true, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700871}
872
873TYPED_TEST(HttpFetcherTest, BeyondMaxRedirectTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800874 if (this->test_.IsMock())
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700875 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800876
Ben Chan02f7c1d2014-10-18 15:18:02 -0700877 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800878 ASSERT_TRUE(server->started_);
879
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700880 string url;
David Zeuthen34135a92013-08-06 11:16:16 -0700881 for (int r = 0; r < kDownloadMaxRedirects + 1; r++) {
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700882 url += base::StringPrintf("/redirect/%d",
883 kRedirectCodes[r % arraysize(kRedirectCodes)]);
884 }
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800885 url += base::StringPrintf("/download/%d", kMediumLength);
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700886 RedirectTest(server.get(), false, url, this->test_.NewLargeFetcher());
Darin Petkov41c2fcf2010-08-25 13:14:48 -0700887}
888
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700889namespace {
890class MultiHttpFetcherTestDelegate : public HttpFetcherDelegate {
891 public:
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700892 explicit MultiHttpFetcherTestDelegate(int expected_response_code)
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700893 : expected_response_code_(expected_response_code) {}
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800894
Alex Deymo610277e2014-11-11 21:18:11 -0800895 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800896 const void* bytes, size_t length) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800897 EXPECT_EQ(fetcher, fetcher_.get());
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -0800898 data.append(reinterpret_cast<const char*>(bytes), length);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700899 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800900
Alex Deymo610277e2014-11-11 21:18:11 -0800901 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800902 EXPECT_EQ(fetcher, fetcher_.get());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800903 EXPECT_EQ(expected_response_code_ != kHttpResponseUndefined, successful);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700904 if (expected_response_code_ != 0)
905 EXPECT_EQ(expected_response_code_, fetcher->http_response_code());
Darin Petkov9ce452b2010-11-17 14:33:28 -0800906 // Destroy the fetcher (because we're allowed to).
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700907 fetcher_.reset(nullptr);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700908 MessageLoop::current()->BreakLoop();
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700909 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800910
Alex Deymo610277e2014-11-11 21:18:11 -0800911 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -0800912 ADD_FAILURE();
913 }
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800914
Ben Chan02f7c1d2014-10-18 15:18:02 -0700915 unique_ptr<HttpFetcher> fetcher_;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700916 int expected_response_code_;
917 string data;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700918};
919
920void MultiTest(HttpFetcher* fetcher_in,
Alex Deymoc1c17b42015-11-23 03:53:15 -0300921 FakeHardware* fake_hardware,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700922 const string& url,
Ben Chanf9cb98c2014-09-21 18:31:30 -0700923 const vector<pair<off_t, off_t>>& ranges,
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700924 const string& expected_prefix,
925 off_t expected_size,
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800926 HttpResponseCode expected_response_code) {
Alex Deymo60ca1a72015-06-18 18:19:15 -0700927 MultiHttpFetcherTestDelegate delegate(expected_response_code);
928 delegate.fetcher_.reset(fetcher_in);
Jay Srinivasan43488792012-06-19 00:25:31 -0700929
Alex Deymo60ca1a72015-06-18 18:19:15 -0700930 MultiRangeHttpFetcher* multi_fetcher =
931 dynamic_cast<MultiRangeHttpFetcher*>(fetcher_in);
932 ASSERT_TRUE(multi_fetcher);
933 multi_fetcher->ClearRanges();
934 for (vector<pair<off_t, off_t>>::const_iterator it = ranges.begin(),
935 e = ranges.end(); it != e; ++it) {
936 string tmp_str = base::StringPrintf("%jd+", it->first);
937 if (it->second > 0) {
938 base::StringAppendF(&tmp_str, "%jd", it->second);
939 multi_fetcher->AddRange(it->first, it->second);
940 } else {
941 base::StringAppendF(&tmp_str, "?");
942 multi_fetcher->AddRange(it->first);
Andrew de los Reyes819fef22010-12-17 11:33:58 -0800943 }
Alex Deymo60ca1a72015-06-18 18:19:15 -0700944 LOG(INFO) << "added range: " << tmp_str;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700945 }
Alex Deymoc1c17b42015-11-23 03:53:15 -0300946 fake_hardware->SetIsOfficialBuild(false);
Alex Deymo60ca1a72015-06-18 18:19:15 -0700947 multi_fetcher->set_delegate(&delegate);
948
949 MessageLoop::current()->PostTask(
950 FROM_HERE,
951 base::Bind(StartTransfer, multi_fetcher, url));
952 MessageLoop::current()->Run();
953
954 EXPECT_EQ(expected_size, delegate.data.size());
955 EXPECT_EQ(expected_prefix,
956 string(delegate.data.data(), expected_prefix.size()));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700957}
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700958} // namespace
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700959
Darin Petkov9ce452b2010-11-17 14:33:28 -0800960TYPED_TEST(HttpFetcherTest, MultiHttpFetcherSimpleTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800961 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700962 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800963
Ben Chan02f7c1d2014-10-18 15:18:02 -0700964 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800965 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700966
Ben Chanf9cb98c2014-09-21 18:31:30 -0700967 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700968 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800969 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800970 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -0300971 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700972 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700973 ranges,
974 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800975 kBigLength - (99 - 25),
976 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700977}
978
979TYPED_TEST(HttpFetcherTest, MultiHttpFetcherLengthLimitTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800980 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700981 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800982
Ben Chan02f7c1d2014-10-18 15:18:02 -0700983 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800984 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700985
Ben Chanf9cb98c2014-09-21 18:31:30 -0700986 vector<pair<off_t, off_t>> ranges;
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700987 ranges.push_back(make_pair(0, 24));
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800988 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -0300989 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -0700990 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700991 ranges,
992 "abcdefghijabcdefghijabcd",
993 24,
Gilad Arnolde4ad2502011-12-29 17:08:54 -0800994 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700995}
996
997TYPED_TEST(HttpFetcherTest, MultiHttpFetcherMultiEndTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -0800998 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -0700999 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001000
Ben Chan02f7c1d2014-10-18 15:18:02 -07001001 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001002 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001003
Ben Chanf9cb98c2014-09-21 18:31:30 -07001004 vector<pair<off_t, off_t>> ranges;
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001005 ranges.push_back(make_pair(kBigLength - 2, 0));
1006 ranges.push_back(make_pair(kBigLength - 3, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001007 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001008 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001009 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001010 ranges,
1011 "ijhij",
1012 5,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001013 kHttpResponsePartialContent);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001014}
1015
1016TYPED_TEST(HttpFetcherTest, MultiHttpFetcherInsufficientTest) {
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001017 if (!this->test_.IsMulti())
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001018 return;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001019
Ben Chan02f7c1d2014-10-18 15:18:02 -07001020 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001021 ASSERT_TRUE(server->started_);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001022
Ben Chanf9cb98c2014-09-21 18:31:30 -07001023 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001024 ranges.push_back(make_pair(kBigLength - 2, 4));
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001025 for (int i = 0; i < 2; ++i) {
Andrew de los Reyes819fef22010-12-17 11:33:58 -08001026 LOG(INFO) << "i = " << i;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001027 MultiTest(this->test_.NewLargeFetcher(),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001028 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001029 this->test_.BigUrl(server->GetPort()),
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001030 ranges,
1031 "ij",
1032 2,
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001033 kHttpResponseUndefined);
Andrew de los Reyes3fd5d302010-10-07 20:07:18 -07001034 ranges.push_back(make_pair(0, 5));
1035 }
1036}
1037
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001038// Issue #18143: when a fetch of a secondary chunk out of a chain, then it
1039// should retry with other proxies listed before giving up.
1040//
1041// (1) successful recovery: The offset fetch will fail twice but succeed with
1042// the third proxy.
1043TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetRecoverableTest) {
1044 if (!this->test_.IsMulti())
1045 return;
1046
Ben Chan02f7c1d2014-10-18 15:18:02 -07001047 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001048 ASSERT_TRUE(server->started_);
1049
Ben Chanf9cb98c2014-09-21 18:31:30 -07001050 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001051 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001052 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001053 MultiTest(this->test_.NewLargeFetcher(3),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001054 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001055 LocalServerUrlForPath(server->GetPort(),
1056 base::StringPrintf("/error-if-offset/%d/2",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001057 kBigLength)),
1058 ranges,
1059 "abcdefghijabcdefghijabcdejabcdefghijabcdef",
1060 kBigLength - (99 - 25),
1061 kHttpResponsePartialContent);
1062}
1063
1064// (2) unsuccessful recovery: The offset fetch will fail repeatedly. The
1065// fetcher will signal a (failed) completed transfer to the delegate.
1066TYPED_TEST(HttpFetcherTest, MultiHttpFetcherErrorIfOffsetUnrecoverableTest) {
1067 if (!this->test_.IsMulti())
1068 return;
1069
Ben Chan02f7c1d2014-10-18 15:18:02 -07001070 unique_ptr<HttpServer> server(this->test_.CreateServer());
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001071 ASSERT_TRUE(server->started_);
1072
Ben Chanf9cb98c2014-09-21 18:31:30 -07001073 vector<pair<off_t, off_t>> ranges;
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001074 ranges.push_back(make_pair(0, 25));
Gilad Arnolde4ad2502011-12-29 17:08:54 -08001075 ranges.push_back(make_pair(99, 0));
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001076 MultiTest(this->test_.NewLargeFetcher(2),
Alex Deymoc1c17b42015-11-23 03:53:15 -03001077 this->test_.fake_hardware(),
Gilad Arnoldb6c562a2013-07-01 02:19:26 -07001078 LocalServerUrlForPath(server->GetPort(),
1079 base::StringPrintf("/error-if-offset/%d/3",
Gilad Arnold9bedeb52011-11-17 16:19:57 -08001080 kBigLength)),
1081 ranges,
1082 "abcdefghijabcdefghijabcde", // only received the first chunk
1083 25,
1084 kHttpResponseUndefined);
1085}
1086
1087
1088
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001089namespace {
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001090class BlockedTransferTestDelegate : public HttpFetcherDelegate {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001091 public:
Alex Deymo610277e2014-11-11 21:18:11 -08001092 void ReceivedBytes(HttpFetcher* fetcher,
Alex Vakulenkof68bbbc2015-02-09 12:53:18 -08001093 const void* bytes, size_t length) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001094 ADD_FAILURE();
1095 }
Alex Deymo610277e2014-11-11 21:18:11 -08001096 void TransferComplete(HttpFetcher* fetcher, bool successful) override {
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001097 EXPECT_FALSE(successful);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001098 MessageLoop::current()->BreakLoop();
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001099 }
Alex Deymo610277e2014-11-11 21:18:11 -08001100 void TransferTerminated(HttpFetcher* fetcher) override {
Darin Petkov9ce452b2010-11-17 14:33:28 -08001101 ADD_FAILURE();
1102 }
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001103};
1104
Alex Deymo60ca1a72015-06-18 18:19:15 -07001105void BlockedTransferTestHelper(AnyHttpFetcherTest* fetcher_test,
1106 bool is_official_build) {
1107 if (fetcher_test->IsMock() || fetcher_test->IsMulti())
1108 return;
1109
1110 unique_ptr<HttpServer> server(fetcher_test->CreateServer());
1111 ASSERT_TRUE(server->started_);
1112
1113 BlockedTransferTestDelegate delegate;
1114 unique_ptr<HttpFetcher> fetcher(fetcher_test->NewLargeFetcher());
1115 LOG(INFO) << "is_official_build: " << is_official_build;
1116 // NewLargeFetcher creates the HttpFetcher* with a FakeSystemState.
Alex Deymoc1c17b42015-11-23 03:53:15 -03001117 fetcher_test->fake_hardware()->SetIsOfficialBuild(is_official_build);
Alex Deymo60ca1a72015-06-18 18:19:15 -07001118 fetcher->set_delegate(&delegate);
1119
1120 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
1121 StartTransfer,
1122 fetcher.get(),
1123 LocalServerUrlForPath(server->GetPort(),
1124 fetcher_test->SmallUrl(server->GetPort()))));
1125 MessageLoop::current()->Run();
1126}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001127} // namespace
1128
Darin Petkovfc7a0ce2010-10-25 10:38:37 -07001129TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
Alex Deymo60ca1a72015-06-18 18:19:15 -07001130 BlockedTransferTestHelper(&this->test_, false);
1131}
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001132
Alex Deymo60ca1a72015-06-18 18:19:15 -07001133TYPED_TEST(HttpFetcherTest, BlockedTransferOfficialBuildTest) {
1134 BlockedTransferTestHelper(&this->test_, true);
Andrew de los Reyesd57d1472010-10-21 13:34:08 -07001135}
1136
rspangler@google.com49fdf182009-10-10 00:57:34 +00001137} // namespace chromeos_update_engine